package component import ( "encoding/json" "fmt" "net/http" "github.com/FAU-CDI/wisski-distillery/internal/models" ) // Scope represents a single permit by a session to perform some action. // Scopes consist of two parts: A general name and a specific object. // Scopes are checked by ScopeCheckers. type Scope string type ScopeInfo struct { Scope // Description is a human readable description of the scope Description string // error returned to a user when the permission is denied. // defaults to "missing scope {{ name }}" DeniedMessage string // TakesParam indicates if the scope accepts a parameter TakesParam bool } type CheckError struct { Scope Scope Err error } func (ce CheckError) Unwrap() error { return ce.Err } func (ce CheckError) Error() string { return fmt.Sprintf("unable to check scope %q: %s", string(ce.Scope), ce.Err) } type AccessDeniedError string func (aed AccessDeniedError) Error() string { return string(aed) } // DeniedError returns an AccessDeniedError that indivates the access is denied. func (scope ScopeInfo) DeniedError() error { if scope.DeniedMessage == "" { return AccessDeniedError(fmt.Sprintf("missing scope %q", string(scope.Scope))) } return AccessDeniedError(scope.DeniedMessage) } // CheckError returns a CheckError with the given underlying error. func (scope ScopeInfo) CheckError(err error) error { return CheckError{Scope: scope.Scope, Err: err} } // ScopeProvider is a component that can check a specific scope type ScopeProvider interface { Component // Scopes returns information about the scope Scope() ScopeInfo // Check checks if the given session has access to the given scope. HasScope(param string, r *http.Request) (bool, error) } // SessionInfo provides information about the current session. type SessionInfo struct { // User is the current user associated with the session. User *models.User // Token indicates if the user was authenticated with a Token Token bool } func (si SessionInfo) MarshalJSON() ([]byte, error) { return json.Marshal(struct { User string `json:"user"` Token bool `json:"token"` }{User: si.Username(), Token: si.Token}) } // Username reports the username associated with this session func (si SessionInfo) Username() string { if si.User == nil { return "" } return si.User.User } // Anonymous reports if this Session is associated with a user account func (si SessionInfo) Anonymous() bool { return si.Username() != "" }