dndex/server/auth/scope.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, "/entity/") {
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
}