76 lines
1.4 KiB
Go
76 lines
1.4 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"local/dndex/storage"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type Scope struct {
|
|
Namespace string
|
|
EntityName string
|
|
EntityID string
|
|
}
|
|
|
|
func GetScope(r *http.Request, gs ...storage.RateLimitedGraph) Scope {
|
|
scope := Scope{}
|
|
if ok := scope.fromCtx(r.Context()); ok {
|
|
return scope
|
|
}
|
|
scope.fromToken(r)
|
|
scope.fromPath(r.URL.Path)
|
|
for _, g := range gs {
|
|
scope.fromGraph(r.Context(), g)
|
|
}
|
|
reqWithContextValue(r, ScopeKey, scope)
|
|
return scope
|
|
}
|
|
|
|
func reqWithContextValue(r *http.Request, k string, v interface{}) {
|
|
*r = *(r.WithContext(context.WithValue(r.Context(), k, v)))
|
|
}
|
|
|
|
func (s *Scope) fromCtx(ctx context.Context) bool {
|
|
var ok bool
|
|
*s, ok = ctx.Value(ScopeKey).(Scope)
|
|
return ok
|
|
}
|
|
|
|
func (s *Scope) fromToken(r *http.Request) bool {
|
|
token, ok := getToken(r)
|
|
if ok {
|
|
s.Namespace = token.Namespace
|
|
}
|
|
return ok
|
|
}
|
|
|
|
func (s *Scope) fromPath(path string) bool {
|
|
if !strings.HasPrefix(path, "/entities/") {
|
|
return false
|
|
}
|
|
paths := strings.Split(path, "/")
|
|
if len(paths) < 2 {
|
|
return false
|
|
}
|
|
path = paths[2]
|
|
path = strings.Split(path, "#")[0]
|
|
if len(path) == 0 {
|
|
return false
|
|
}
|
|
s.EntityID = path
|
|
return true
|
|
}
|
|
|
|
func (s *Scope) fromGraph(ctx context.Context, g storage.RateLimitedGraph) bool {
|
|
if s.EntityID == "" {
|
|
return false
|
|
}
|
|
one, err := g.Get(ctx, s.Namespace, s.EntityID)
|
|
ok := err == nil && one.Name != ""
|
|
if ok {
|
|
s.EntityName = one.Name
|
|
}
|
|
return ok
|
|
}
|