feat: restore CHFS JWT session compatibility
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
type PermMask uint8
|
||||
@@ -35,8 +36,10 @@ func ParseMask(s string) PermMask {
|
||||
}
|
||||
|
||||
type PathRule struct {
|
||||
Dir string
|
||||
Mask PermMask
|
||||
Dir string
|
||||
Mask PermMask
|
||||
Deny bool
|
||||
ChildrenOnly bool
|
||||
}
|
||||
type Account struct {
|
||||
Username, Password string
|
||||
@@ -91,9 +94,19 @@ func (a *Account) MaskFor(path string) PermMask {
|
||||
mask := a.Mask
|
||||
for _, r := range a.Rules {
|
||||
d := strings.Trim(r.Dir, "/")
|
||||
if matchPath(d, path) && len(d) > best {
|
||||
if !matchPath(d, path) {
|
||||
continue
|
||||
}
|
||||
if r.ChildrenOnly && matchPathExact(d, path) {
|
||||
continue
|
||||
}
|
||||
if len(d) > best {
|
||||
best = len(d)
|
||||
mask = r.Mask
|
||||
if r.Deny {
|
||||
mask = None
|
||||
} else {
|
||||
mask = r.Mask
|
||||
}
|
||||
}
|
||||
}
|
||||
return mask
|
||||
@@ -143,13 +156,49 @@ func matchSegment(pattern, value string) bool {
|
||||
return dp[len(p)][len(v)]
|
||||
}
|
||||
|
||||
func matchPathExact(pattern, path string) bool {
|
||||
pp := strings.Split(strings.Trim(pattern, "/"), "/")
|
||||
ps := strings.Split(strings.Trim(path, "/"), "/")
|
||||
if len(pp) != len(ps) {
|
||||
return false
|
||||
}
|
||||
return matchPath(pattern, path)
|
||||
}
|
||||
|
||||
func MatchPath(pattern, path string) bool { return matchPath(pattern, path) }
|
||||
|
||||
func NewToken() string {
|
||||
b := make([]byte, 32)
|
||||
if _, e := rand.Read(b); e != nil {
|
||||
h := sha256.Sum256([]byte("fallback"))
|
||||
return hex.EncodeToString(h[:])
|
||||
const jwtSecret = "_pengyichen2015_"
|
||||
|
||||
type jwtClaims struct {
|
||||
Acc string `json:"acc"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
func NewToken(username string) (string, error) {
|
||||
claims := jwtClaims{Acc: username, StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(365 * 24 * time.Hour).Unix()}}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(jwtSecret))
|
||||
}
|
||||
|
||||
func GetAccFromToken(raw string) (string, error) {
|
||||
if raw == "" {
|
||||
return "", fmt.Errorf("empty token")
|
||||
}
|
||||
return hex.EncodeToString(b)
|
||||
var claims jwtClaims
|
||||
token, err := jwt.ParseWithClaims(raw, &claims, func(t *jwt.Token) (interface{}, error) {
|
||||
if t.Method != jwt.SigningMethodHS256 {
|
||||
return nil, fmt.Errorf("unexpected signing method: %s", t.Method.Alg())
|
||||
}
|
||||
return []byte(jwtSecret), nil
|
||||
})
|
||||
if err != nil || token == nil || !token.Valid {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("invalid token")
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if claims.Acc == "" {
|
||||
return "", fmt.Errorf("token missing account")
|
||||
}
|
||||
return claims.Acc, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user