95 lines
2.2 KiB
Go
95 lines
2.2 KiB
Go
|
|
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)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|