mirror of
https://github.com/alist-org/gofakes3.git
synced 2025-12-24 12:58:04 +08:00
110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package signature
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"net/http"
|
|
"reflect"
|
|
"regexp"
|
|
"strings"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
const (
|
|
accessKeyMinLen = 3
|
|
// secretKeyMinLen = 8
|
|
)
|
|
|
|
// check if the access key is valid and recognized, additionally
|
|
// also returns if the access key is owner/admin.
|
|
func checkKeyValid(r *http.Request, accessKey string) (Credentials, bool, ErrorCode) {
|
|
|
|
u, ok := credStore.Load(accessKey)
|
|
if !ok {
|
|
return Credentials{}, false, errInvalidAccessKeyID
|
|
}
|
|
return u.(Credentials), true, ErrNone
|
|
}
|
|
|
|
// LoadKeys parse and store accessKey-secretKey pair
|
|
func StoreKeys(pairs map[string]string) {
|
|
for accessKey, secretKey := range pairs {
|
|
credStore.Store(accessKey, Credentials{
|
|
AccessKey: accessKey,
|
|
SecretKey: secretKey,
|
|
})
|
|
}
|
|
}
|
|
|
|
func ReloadKeys(pairs map[string]string) {
|
|
credStore.Range(func(key, value interface{}) bool {
|
|
if _, ok := pairs[key.(string)]; !ok {
|
|
credStore.Delete(key)
|
|
}
|
|
return true
|
|
})
|
|
StoreKeys(pairs)
|
|
}
|
|
|
|
func sumHMAC(key []byte, data []byte) []byte {
|
|
hash := hmac.New(sha256.New, key)
|
|
hash.Write(data)
|
|
return hash.Sum(nil)
|
|
}
|
|
|
|
func contains(slice interface{}, elem interface{}) bool {
|
|
v := reflect.ValueOf(slice)
|
|
if v.Kind() == reflect.Slice {
|
|
for i := 0; i < v.Len(); i++ {
|
|
if v.Index(i).Interface() == elem {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// encodePath from minio/s3utils.EncodePath
|
|
|
|
// if object matches reserved string, no need to encode them
|
|
var reservedObjectNames = regexp.MustCompile("^[a-zA-Z0-9-_.~/]+$")
|
|
|
|
// EncodePath encode the strings from UTF-8 byte representations to HTML hex escape sequences
|
|
//
|
|
// This is necessary since regular url.Parse() and url.Encode() functions do not support UTF-8
|
|
// non english characters cannot be parsed due to the nature in which url.Encode() is written
|
|
//
|
|
// This function on the other hand is a direct replacement for url.Encode() technique to support
|
|
// pretty much every UTF-8 character.
|
|
func encodePath(pathName string) string {
|
|
if reservedObjectNames.MatchString(pathName) {
|
|
return pathName
|
|
}
|
|
var encodedPathname strings.Builder
|
|
for _, s := range pathName {
|
|
if 'A' <= s && s <= 'Z' || 'a' <= s && s <= 'z' || '0' <= s && s <= '9' { // §2.3 Unreserved characters (mark)
|
|
encodedPathname.WriteRune(s)
|
|
continue
|
|
}
|
|
switch s {
|
|
case '-', '_', '.', '~', '/': // §2.3 Unreserved characters (mark)
|
|
encodedPathname.WriteRune(s)
|
|
continue
|
|
default:
|
|
len := utf8.RuneLen(s)
|
|
if len < 0 {
|
|
// if utf8 cannot convert return the same string as is
|
|
return pathName
|
|
}
|
|
u := make([]byte, len)
|
|
utf8.EncodeRune(u, s)
|
|
for _, r := range u {
|
|
hex := hex.EncodeToString([]byte{r})
|
|
encodedPathname.WriteString("%" + strings.ToUpper(hex))
|
|
}
|
|
}
|
|
}
|
|
return encodedPathname.String()
|
|
}
|