first commit

This commit is contained in:
2023-06-27 09:48:33 +02:00
commit 8fc0220e51
29 changed files with 1315 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
package auth
import (
"context"
)
type Provider interface {
ListUsers(ctx context.Context) ([]UserInfo, error)
LoginUser(ctx context.Context, username, password string) (*Result, error)
SetupUser(ctx context.Context, session, username, preferredUsername, newPassword string) (*UserInfo, error)
ValidateToken(ctx context.Context, token string) *UserInfo
}
+64
View File
@@ -0,0 +1,64 @@
package auth
import (
"context"
"sync"
"time"
)
type Service struct {
Provider Provider
userListMutex sync.Mutex
userList []UserInfo
userMap map[string]string
userListTime time.Time
key struct{ Stuff uint64 }
key2 struct{ Stuff2 string }
}
func (s *Service) ValidateUser(ctx context.Context, token string) *UserInfo {
return s.Provider.ValidateToken(ctx, token)
}
func (s *Service) AddContextUser(ctx context.Context, user UserInfo) context.Context {
return context.WithValue(ctx, &s.key, &user)
}
func (s *Service) Users(ctx context.Context) ([]UserInfo, map[string]string, error) {
s.userListMutex.Lock()
if time.Since(s.userListTime) < time.Minute {
m := s.userMap
l := s.userList
s.userListMutex.Unlock()
return l, m, nil
}
s.userListMutex.Unlock()
users, err := s.Provider.ListUsers(ctx)
if err != nil {
return nil, nil, err
}
s.userListMutex.Lock()
s.userList = users
s.userMap = make(map[string]string, len(users))
for _, user := range users {
s.userMap[user.ID] = user.Name
}
m := s.userMap
s.userListTime = time.Now()
s.userListMutex.Unlock()
return users, m, nil
}
func (s *Service) GetUser(ctx context.Context) *UserInfo {
v := ctx.Value(&s.key)
if v == nil {
return nil
}
return v.(*UserInfo)
}
+61
View File
@@ -0,0 +1,61 @@
package auth
import (
"fmt"
)
type User struct {
ID string `json:"id"`
Name string `json:"name"`
}
type UserInfo struct {
User
Permissions []string `json:"permissions"`
}
type Result struct {
User *UserInfo `json:"user"`
Token string `json:"token,omitempty"`
Session string `json:"session,omitempty"`
PasswordChangeRequired bool `json:"passwordChangeRequired"`
}
func (user *UserInfo) HasIDOrPermission(userID, subject, action string) bool {
return user.HasID(userID) || user.HasPermission(subject, action)
}
func (user *UserInfo) HasID(id string) bool {
return user != nil && user.ID == id
}
func (user *UserInfo) HasOpPermission(userID, subject, action string) bool {
if !user.HasID(userID) && !user.HasPermission(subject, "admin") {
return false
}
return user.HasPermission(subject, action)
}
func (user *UserInfo) HasPermission(subject, action string) bool {
if user == nil {
return false
}
anyAll := "*.*"
anyAction := fmt.Sprintf("%s.*", subject)
anySubject := fmt.Sprintf("*.%s", action)
specific := fmt.Sprintf("%s.%s", subject, action)
if action == "admin" {
anyAction = specific
}
for _, perm := range user.Permissions {
if perm == anyAll || perm == anyAction || perm == anySubject || perm == specific {
return true
}
}
return false
}