74 lines
1.9 KiB
Go
74 lines
1.9 KiB
Go
package auth
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
|
)
|
|
|
|
var (
|
|
ErrUnknownScope = errors.New("unknown scope")
|
|
ErrParamRequired = errors.New("scope requires parameter")
|
|
ErrNoParam = errors.New("scope does not take parameter")
|
|
)
|
|
|
|
// Scopes returns a map of all available scopes
|
|
func (auth *Auth) Scopes() map[component.Scope]component.ScopeInfo {
|
|
scopes := auth.getScopeMap()
|
|
mp := make(map[component.Scope]component.ScopeInfo, len(scopes))
|
|
for scope, entry := range scopes {
|
|
mp[scope] = entry.Info
|
|
}
|
|
return mp
|
|
}
|
|
|
|
// getScopeMap return a (cached version of) all scopes
|
|
func (auth *Auth) getScopeMap() map[component.Scope]scopeMapEntry {
|
|
return auth.scopeMap.Get(func() map[component.Scope]scopeMapEntry {
|
|
mp := make(map[component.Scope]scopeMapEntry, len(auth.dependencies.ScopeProviders))
|
|
for _, p := range auth.dependencies.ScopeProviders {
|
|
info := p.Scope()
|
|
mp[info.Scope] = scopeMapEntry{
|
|
Provider: p,
|
|
Info: info,
|
|
}
|
|
}
|
|
return mp
|
|
})
|
|
}
|
|
|
|
// CheckScope checks if the given request is associated with the given request.
|
|
// A request can be one of two types:
|
|
// - A signed in user with an implicitly associated set of scopes
|
|
// - A session authorized with a token only
|
|
// If the request is denied a scope, the error will be of type AccessDeniedError.
|
|
func (auth *Auth) CheckScope(param string, scope component.Scope, r *http.Request) error {
|
|
// the empty scope is always permitted implicitly
|
|
if scope == "" {
|
|
return nil
|
|
}
|
|
|
|
entry, ok := auth.getScopeMap()[scope]
|
|
if !ok {
|
|
return ErrUnknownScope
|
|
}
|
|
|
|
// check that we take a parameter
|
|
if entry.Info.TakesParam && param == "" {
|
|
return ErrParamRequired
|
|
}
|
|
if !entry.Info.TakesParam && param != "" {
|
|
return ErrNoParam
|
|
}
|
|
|
|
// call the checker and return an error
|
|
ok, err := entry.Provider.HasScope(param, r)
|
|
if err != nil {
|
|
return entry.Info.CheckError(err)
|
|
}
|
|
if ok {
|
|
return nil
|
|
}
|
|
return entry.Info.DeniedError()
|
|
}
|