package services import ( "code.tczkiot.com/wlw/ai-agent/identity" "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "github.com/gin-gonic/gin" ) const authPrincipalContextKey = "externalAuthPrincipal" // AuthService adapts identity data authenticated by the host application and // delegates every operation authorization back to that host. var AuthService = &externalPrincipalService{} type externalPrincipalService struct{} func (s *externalPrincipalService) GetAuthPrincipal(ctx *gin.Context) *dto.AuthPrincipal { if ctx == nil { return nil } value, _ := ctx.Get(authPrincipalContextKey) principal, _ := value.(*dto.AuthPrincipal) return principal } func (s *externalPrincipalService) Authenticate(ctx *gin.Context) (*dto.AuthPrincipal, error) { if principal := s.GetAuthPrincipal(ctx); principal != nil { return principal, nil } if ctx == nil || ctx.Request == nil { return nil, errorsx.UnauthorizedI18n("error.auth.expired") } subject, err := SubjectService.Current(ctx.Request.Context()) if err != nil || subject == nil || subject.Type != identity.SubjectAdmin || subject.Category != identity.CategorySystem || !subject.Enabled { return nil, errorsx.UnauthorizedI18n("error.auth.expired") } principal := &dto.AuthPrincipal{ SubjectType: subject.Type, UserID: subject.ID, Username: subject.Username, Nickname: subject.Name, Avatar: subject.Avatar, Status: enums.StatusOk, Roles: []string{string(subject.Type)}, } ctx.Set(authPrincipalContextKey, principal) return principal, nil } func (s *externalPrincipalService) RequirePermission(ctx *gin.Context, permission constants.Permission) (*dto.AuthPrincipal, error) { principal, err := s.Authenticate(ctx) if err != nil { return nil, err } if err := SubjectService.Authorize(ctx.Request.Context(), permission.Code); err != nil { return nil, errorsx.ForbiddenI18n("error.auth.forbidden") } return principal, nil } func (s *externalPrincipalService) HasPermission(ctx *gin.Context, operation string) bool { if _, err := s.Authenticate(ctx); err != nil { return false } return SubjectService.Authorize(ctx.Request.Context(), operation) == nil }