467f7b1585
This adds standard OAuth2 client credentials and bearer token support as well as scope-based authorization checks for REST API clients. Note that this initial implementation should not be used in production and that the access token limit has not been implemented yet. Signed-off-by: Michael Mayer <michael@photoprism.app>
107 lines
1.7 KiB
Go
107 lines
1.7 KiB
Go
package list
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// KeyValue represents a key-value attribute.
|
|
type KeyValue struct {
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
// ParseKeyValue creates a new key-value attribute from a string.
|
|
func ParseKeyValue(s string) *KeyValue {
|
|
f := KeyValue{}
|
|
|
|
return f.Parse(s)
|
|
}
|
|
|
|
// Key returns the sanitized attribute key.
|
|
func Key(s string) string {
|
|
var i = 0
|
|
|
|
// Remove non-alphanumeric characters.
|
|
result := strings.Map(func(r rune) rune {
|
|
switch r {
|
|
case '.', '@', '-', '+', '_', '#':
|
|
return r
|
|
case '*':
|
|
i++
|
|
return r
|
|
}
|
|
if r >= '0' && r <= '9' {
|
|
return r
|
|
} else if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') || r == 127 {
|
|
return -1
|
|
}
|
|
i++
|
|
return r
|
|
}, s)
|
|
|
|
if i == 0 {
|
|
return ""
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// Value returns the sanitized attribute value.
|
|
func Value(s string) string {
|
|
// Remove control characters.
|
|
return strings.Map(func(r rune) rune {
|
|
if r <= 32 || r == 127 {
|
|
return -1
|
|
}
|
|
switch r {
|
|
case '(', ')', '<', '>', '\'', '"', '*':
|
|
return r
|
|
}
|
|
return r
|
|
}, s)
|
|
}
|
|
|
|
// Parse parses a string attribute into key and value.
|
|
func (f *KeyValue) Parse(s string) *KeyValue {
|
|
k, v, _ := strings.Cut(s, ":")
|
|
|
|
// Set key.
|
|
if k = Key(k); k == "" {
|
|
return nil
|
|
} else {
|
|
f.Key = k
|
|
}
|
|
|
|
// Default?
|
|
if v = Value(v); v == "" {
|
|
f.Value = True
|
|
return f
|
|
}
|
|
|
|
// Set value.
|
|
if b := Bool[strings.ToLower(v)]; b != "" {
|
|
f.Value = b
|
|
} else {
|
|
f.Value = v
|
|
}
|
|
|
|
return f
|
|
}
|
|
|
|
// String return the attribute as string.
|
|
func (f *KeyValue) String() string {
|
|
if f == nil {
|
|
return ""
|
|
}
|
|
|
|
if Bool[strings.ToLower(f.Value)] == True {
|
|
return f.Key
|
|
}
|
|
|
|
if s := fmt.Sprintf("%s:%s", f.Key, f.Value); len(s) < StringLengthLimit {
|
|
return s
|
|
}
|
|
|
|
return ""
|
|
}
|