go-doc/backend/auth/auth.go

95 lines
2.2 KiB
Go
Raw Permalink Normal View History

2026-10-07 15:03:50 +02:00
package auth
import (
"context"
"net/http"
"go-doc/go-loose/client"
)
// User represents an authenticated user from go-loose
type User struct {
ID string
Email string
DisplayName string
AvatarURL string
TenantID string
TenantSlug string
ApplicationID string
Application string
Role string
Permissions []string
}
func (u User) Can(permission string) bool {
for _, granted := range u.Permissions {
if granted == permission {
return true
}
}
return false
}
func (u User) IsAdmin() bool {
return u.Role == "admin" || u.Role == "owner" || u.Can("console.read")
}
type contextKey string
const userContextKey = contextKey("go-doc-user")
func WithUser(ctx context.Context, user User) context.Context {
return context.WithValue(ctx, userContextKey, user)
}
func UserFromContext(ctx context.Context) (User, bool) {
user, ok := ctx.Value(userContextKey).(User)
return user, ok
}
func TenantIDFromContext(ctx context.Context) (string, bool) {
user, ok := UserFromContext(ctx)
if !ok {
return "", false
}
return user.TenantID, true
}
func UserIDFromContext(ctx context.Context) (string, bool) {
user, ok := UserFromContext(ctx)
if !ok {
return "", false
}
return user.ID, true
}
func ConvertUser(looseUser client.User) User {
return User{
ID: looseUser.ID,
Email: looseUser.Email,
DisplayName: looseUser.DisplayName,
AvatarURL: looseUser.AvatarURL,
TenantID: looseUser.TenantID,
TenantSlug: looseUser.TenantSlug,
ApplicationID: looseUser.ApplicationID,
Application: looseUser.Application,
Role: looseUser.Role,
Permissions: looseUser.Permissions,
}
}
func BrowserAuthMiddleware(browserAuth *client.BrowserAuth) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
if browserAuth == nil {
return next
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
browserAuth.Middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if user, ok := client.UserFromContext(r.Context()); ok {
r = r.WithContext(WithUser(r.Context(), ConvertUser(user)))
}
next.ServeHTTP(w, r)
})).ServeHTTP(w, r)
})
}
}