71 lines
1.7 KiB
Go
71 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"connectrpc.com/connect"
|
|
types "github.com/OliveTin/OliveTin/internal/auth/authpublic"
|
|
otjwt "github.com/OliveTin/OliveTin/internal/auth/otjwt"
|
|
"github.com/OliveTin/OliveTin/internal/config"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var authChain = []func(*types.AuthCheckingContext) *types.AuthenticatedUser{
|
|
checkUserFromHeaders,
|
|
checkUserFromLocalSession,
|
|
otjwt.CheckUserFromJwtHeader,
|
|
otjwt.CheckUserFromJwtCookie,
|
|
}
|
|
|
|
// Handlers like the OAuth2's handler are "instance methods", so they need to be added to the auth chain after the other handlers.
|
|
func AddAuthChainFunction(check func(*types.AuthCheckingContext) *types.AuthenticatedUser) {
|
|
authChain = append(authChain, check)
|
|
}
|
|
|
|
func runAuthChain[T any](req *connect.Request[T], cfg *config.Config) *types.AuthenticatedUser {
|
|
var user *types.AuthenticatedUser
|
|
|
|
authCtx := &types.AuthCheckingContext{
|
|
Request: &http.Request{Header: req.Header()},
|
|
Config: cfg,
|
|
}
|
|
|
|
for _, check := range authChain {
|
|
user = check(authCtx)
|
|
|
|
if user != nil && user.Username != "" {
|
|
return user
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func UserFromApiCall[T any](ctx context.Context, req *connect.Request[T], cfg *config.Config) *types.AuthenticatedUser {
|
|
user := runAuthChain(req, cfg)
|
|
|
|
log.Tracef("UserFromApiCall Context: %+v", ctx)
|
|
|
|
if user == nil || user.Username == "" {
|
|
user = UserGuest(cfg)
|
|
} else {
|
|
user.BuildUserAcls(cfg)
|
|
}
|
|
|
|
path := ""
|
|
if req != nil {
|
|
path = req.Spec().Procedure
|
|
}
|
|
|
|
log.WithFields(log.Fields{
|
|
"username": user.Username,
|
|
"usergroupLine": user.UsergroupLine,
|
|
"provider": user.Provider,
|
|
"acls": user.Acls,
|
|
"path": path,
|
|
}).Debugf("Authenticated API request")
|
|
|
|
return user
|
|
}
|