2023-08-04 11:34:18 +00:00
|
|
|
package domain
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2025-01-11 17:44:55 +00:00
|
|
|
|
2024-01-31 20:14:36 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2023-08-04 11:34:18 +00:00
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
|
|
|
const CtxUserInfo = "userInfo"
|
|
|
|
|
|
|
|
const (
|
|
|
|
CtxSystemAdminId = "_WG_SYS_ADMIN_"
|
|
|
|
CtxUnknownUserId = "_WG_SYS_UNKNOWN_"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ContextUserInfo struct {
|
|
|
|
Id UserIdentifier
|
|
|
|
IsAdmin bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *ContextUserInfo) String() string {
|
|
|
|
return fmt.Sprintf("%s|%t", u.Id, u.IsAdmin)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *ContextUserInfo) UserId() string {
|
|
|
|
return string(u.Id)
|
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// DefaultContextUserInfo returns a default context user info.
|
2023-08-04 11:34:18 +00:00
|
|
|
func DefaultContextUserInfo() *ContextUserInfo {
|
|
|
|
return &ContextUserInfo{
|
|
|
|
Id: CtxUnknownUserId,
|
|
|
|
IsAdmin: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// SystemAdminContextUserInfo returns a context user info for the system admin.
|
2023-08-04 11:34:18 +00:00
|
|
|
func SystemAdminContextUserInfo() *ContextUserInfo {
|
|
|
|
return &ContextUserInfo{
|
|
|
|
Id: CtxSystemAdminId,
|
|
|
|
IsAdmin: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// SetUserInfoFromGin sets the user info from the gin context to the request context.
|
2023-08-04 11:34:18 +00:00
|
|
|
func SetUserInfoFromGin(c *gin.Context) context.Context {
|
|
|
|
ginUserInfo, exists := c.Get(CtxUserInfo)
|
|
|
|
|
|
|
|
info := DefaultContextUserInfo()
|
|
|
|
if exists {
|
|
|
|
if ginInfo, ok := ginUserInfo.(*ContextUserInfo); ok {
|
|
|
|
info = ginInfo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := SetUserInfo(c.Request.Context(), info)
|
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// SetUserInfo sets the user info in the context.
|
2023-08-04 11:34:18 +00:00
|
|
|
func SetUserInfo(ctx context.Context, info *ContextUserInfo) context.Context {
|
|
|
|
ctx = context.WithValue(ctx, CtxUserInfo, info)
|
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// GetUserInfo returns the user info from the context.
|
2023-08-04 11:34:18 +00:00
|
|
|
func GetUserInfo(ctx context.Context) *ContextUserInfo {
|
|
|
|
rawInfo := ctx.Value(CtxUserInfo)
|
|
|
|
if rawInfo == nil {
|
|
|
|
return DefaultContextUserInfo()
|
|
|
|
}
|
|
|
|
|
|
|
|
if info, ok := rawInfo.(*ContextUserInfo); ok {
|
|
|
|
return info
|
|
|
|
}
|
|
|
|
|
|
|
|
return DefaultContextUserInfo()
|
|
|
|
}
|
2024-01-31 20:14:36 +00:00
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// ValidateUserAccessRights checks if the current user has access rights to the requested user.
|
|
|
|
// If the user is an admin, access is granted.
|
2024-01-31 20:14:36 +00:00
|
|
|
func ValidateUserAccessRights(ctx context.Context, requiredUser UserIdentifier) error {
|
|
|
|
sessionUser := GetUserInfo(ctx)
|
|
|
|
|
|
|
|
if sessionUser.IsAdmin {
|
|
|
|
return nil // Admins can do everything
|
|
|
|
}
|
|
|
|
|
|
|
|
if sessionUser.Id == requiredUser {
|
|
|
|
return nil // User can access own data
|
|
|
|
}
|
|
|
|
|
|
|
|
logrus.Warnf("insufficient permissions for %s (want %s), stack: %s", sessionUser.Id, requiredUser, GetStackTrace())
|
2025-01-11 17:44:55 +00:00
|
|
|
return ErrNoPermission
|
2024-01-31 20:14:36 +00:00
|
|
|
}
|
|
|
|
|
2025-01-11 17:44:55 +00:00
|
|
|
// ValidateAdminAccessRights checks if the current user has admin access rights.
|
2024-01-31 20:14:36 +00:00
|
|
|
func ValidateAdminAccessRights(ctx context.Context) error {
|
|
|
|
sessionUser := GetUserInfo(ctx)
|
|
|
|
|
|
|
|
if sessionUser.IsAdmin {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
logrus.Warnf("insufficient admin permissions for %s, stack: %s", sessionUser.Id, GetStackTrace())
|
2025-01-11 17:44:55 +00:00
|
|
|
return ErrNoPermission
|
2024-01-31 20:14:36 +00:00
|
|
|
}
|