WIP
This commit is contained in:
parent
4b93d7dace
commit
effa79aacd
10 changed files with 56 additions and 20 deletions
2
API.md
2
API.md
|
|
@ -17,7 +17,7 @@ Typically each request takes only a second to execute.
|
|||
NOTE: These routes will be documented using a Swagger / OpenAPI definition in the future.
|
||||
All routes can be found under `/api/v1/http/`
|
||||
|
||||
- `/api/v1/auth`: Returns user information
|
||||
- `/api/v1/auth`: Returns api session information
|
||||
- `/api/v1/systems`: Returns a (publically visible) list of systems
|
||||
- `/api/v1/news`: Returns JSON containing all news items
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func (a *API) HandleRoute(ctx context.Context, path string) (http.Handler, error
|
|||
|
||||
Handler: func(s string, r *http.Request) (ai AuthInfo, err error) {
|
||||
var user *auth.AuthUser
|
||||
user, ai.Token, err = a.Dependencies.Auth.UserOf(r)
|
||||
user, err = a.Dependencies.Auth.SessionOf(r)
|
||||
if user != nil {
|
||||
ai.User = user.User.User
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func (next *Next) HandleRoute(ctx context.Context, path string) (http.Handler, e
|
|||
}
|
||||
|
||||
// get the user
|
||||
user, _, err := next.Dependencies.Auth.UserOf(r)
|
||||
user, _, err := next.Dependencies.Auth.SessionOf(r)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func (auth *Auth) Protect(handler http.Handler, AllowToken bool, scope component
|
|||
|
||||
// load the user in the session
|
||||
// TODO<tokens>: Check if API access is allowed
|
||||
user, token, err := auth.UserOf(r)
|
||||
user, token, err := auth.SessionOf(r)
|
||||
if err != nil {
|
||||
goto err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@ func (*AdminLoggedIn) Scope() component.ScopeInfo {
|
|||
}
|
||||
|
||||
func (al *AdminLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
||||
user, _, err := al.Dependencies.Auth.UserOf(r)
|
||||
user, _, err := al.Dependencies.Auth.SessionOf(r)
|
||||
return user != nil && user.IsAdmin() && user.IsTOTPEnabled(), err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,6 @@ func (*UserLoggedIn) Scope() component.ScopeInfo {
|
|||
}
|
||||
|
||||
func (iu *UserLoggedIn) HasScope(param string, r *http.Request) (bool, error) {
|
||||
user, _, err := iu.Dependencies.Auth.UserOf(r)
|
||||
user, _, err := iu.Dependencies.Auth.SessionOf(r)
|
||||
return user != nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,27 +18,30 @@ import (
|
|||
_ "embed"
|
||||
)
|
||||
|
||||
// UserOf returns the user logged into the provided request.
|
||||
// SessionOf returns the session and user logged into the provided request.
|
||||
// token indicates if the user used a token to authenticate, or a browser session was used.
|
||||
// A token takes priority over a user in a session.
|
||||
//
|
||||
// If there is no user associated with the given request, user and error are nil, and token is false.
|
||||
// An invalid session, expired token, or disabled user all result in user = nil.
|
||||
//
|
||||
// When no UserOf exists in the given session returns nil.
|
||||
func (auth *Auth) UserOf(r *http.Request) (user *AuthUser, token bool, err error) {
|
||||
// When no SessionOf exists in the given session returns nil.
|
||||
func (auth *Auth) SessionOf(r *http.Request) (session component.SessionInfo, user *AuthUser, err error) {
|
||||
// check the user from the token first
|
||||
{
|
||||
user, err := auth.UserOfToken(r)
|
||||
if user != nil && err == nil {
|
||||
return user, true, nil
|
||||
return component.SessionInfo{User: &user.User, Token: true}, user, nil
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to using session
|
||||
{
|
||||
user, err := auth.UserOfSession(r)
|
||||
return user, false, err
|
||||
if err != nil {
|
||||
return component.SessionInfo{}, nil, err
|
||||
}
|
||||
return component.SessionInfo{User: &user.User, Token: false}, user, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
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.
|
||||
|
|
@ -58,6 +61,36 @@ type ScopeProvider interface {
|
|||
// Scopes returns information about the scope
|
||||
Scope() ScopeInfo
|
||||
|
||||
// Check checks if the given session has access to the given scope
|
||||
// Check checks if the given session has access to the given scope.
|
||||
HasScope(param string, r *http.Request) (bool, error)
|
||||
// TODO: move this to a session
|
||||
}
|
||||
|
||||
// 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() != ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func (li *ListInstances) ShouldShowList(r *http.Request) bool {
|
|||
return allowPrivate
|
||||
}
|
||||
|
||||
user, _, _ := li.Dependencies.Auth.UserOf(r)
|
||||
user, _, _ := li.Dependencies.Auth.SessionOf(r)
|
||||
if user == nil {
|
||||
return allowPublic
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ const UserTable = "users"
|
|||
type User struct {
|
||||
Pk uint `gorm:"column:pk;primaryKey"`
|
||||
|
||||
User string `gorm:"column:user;not null;unique"` // name of the user
|
||||
PasswordHash []byte `gorm:"column:password"` // password of the user, hashed
|
||||
User string `gorm:"column:user;not null;unique"` // name of the user
|
||||
|
||||
TOTPEnabled *bool `gorm:"column:totpenabled"` // is totp enabled for the user
|
||||
TOTPURL string `gorm:"column:totp"` // the totp of the user
|
||||
PasswordHash []byte `gorm:"column:password" json:"-"` // password of the user, hashed
|
||||
TOTPEnabled *bool `gorm:"column:totpenabled" json:"-"` // is totp enabled for the user
|
||||
TOTPURL string `gorm:"column:totp" json:"-"` // the totp of the user
|
||||
|
||||
Enabled *bool `gorm:"enabled;not null"`
|
||||
Admin *bool `gorm:"column:admin;not null"`
|
||||
Enabled *bool `gorm:"enabled;not null" json:"enabled"`
|
||||
Admin *bool `gorm:"column:admin;not null" json:"admin"`
|
||||
}
|
||||
|
||||
func (user *User) HasPassword() bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue