package features import ( "fmt" "net/http" "strings" "github.com/gorilla/mux" "kvs/types" ) // AuthContext holds authentication information for a request type AuthContext struct { UserUUID string `json:"user_uuid"` Scopes []string `json:"scopes"` Groups []string `json:"groups"` } // CheckPermission validates if a user has permission to perform an operation func CheckPermission(permissions int, operation string, isOwner, isGroupMember bool) bool { switch operation { case "create": if isOwner { return (permissions & types.PermOwnerCreate) != 0 } if isGroupMember { return (permissions & types.PermGroupCreate) != 0 } return (permissions & types.PermOthersCreate) != 0 case "delete": if isOwner { return (permissions & types.PermOwnerDelete) != 0 } if isGroupMember { return (permissions & types.PermGroupDelete) != 0 } return (permissions & types.PermOthersDelete) != 0 case "write": if isOwner { return (permissions & types.PermOwnerWrite) != 0 } if isGroupMember { return (permissions & types.PermGroupWrite) != 0 } return (permissions & types.PermOthersWrite) != 0 case "read": if isOwner { return (permissions & types.PermOwnerRead) != 0 } if isGroupMember { return (permissions & types.PermGroupRead) != 0 } return (permissions & types.PermOthersRead) != 0 default: return false } } // CheckUserResourceRelationship determines user relationship to resource func CheckUserResourceRelationship(userUUID string, metadata *types.ResourceMetadata, userGroups []string) (isOwner, isGroupMember bool) { isOwner = (userUUID == metadata.OwnerUUID) if metadata.GroupUUID != "" { for _, groupUUID := range userGroups { if groupUUID == metadata.GroupUUID { isGroupMember = true break } } } return isOwner, isGroupMember } // ExtractTokenFromHeader extracts the Bearer token from the Authorization header func ExtractTokenFromHeader(r *http.Request) (string, error) { authHeader := r.Header.Get("Authorization") if authHeader == "" { return "", fmt.Errorf("missing authorization header") } parts := strings.Split(authHeader, " ") if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" { return "", fmt.Errorf("invalid authorization header format") } return parts[1], nil } // ExtractKVResourceKey extracts KV resource key from request func ExtractKVResourceKey(r *http.Request) string { vars := mux.Vars(r) if path, ok := vars["path"]; ok { return path } return "" }