package authz import ( "context" "tercul/internal/domain" "tercul/internal/domain/work" platform_auth "tercul/internal/platform/auth" ) // Service provides authorization checks for the application. type Service struct { workRepo work.WorkRepository translationRepo domain.TranslationRepository } // NewService creates a new authorization service. func NewService(workRepo work.WorkRepository, translationRepo domain.TranslationRepository) *Service { return &Service{ workRepo: workRepo, translationRepo: translationRepo, } } // CanEditWork checks if a user has permission to edit a work. // For now, we'll implement a simple rule: only an admin or the work's author can edit it. func (s *Service) CanEditWork(ctx context.Context, userID uint, work *work.Work) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } // Admins can do anything. if claims.Role == string(domain.UserRoleAdmin) { return true, nil } // Check if the user is an author of the work. isAuthor, err := s.workRepo.IsAuthor(ctx, work.ID, userID) if err != nil { return false, err } if isAuthor { return true, nil } return false, domain.ErrForbidden } // CanDeleteWork checks if a user has permission to delete a work. func (s *Service) CanDeleteWork(ctx context.Context) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } if claims.Role == string(domain.UserRoleAdmin) { return true, nil } return false, domain.ErrForbidden } // CanDeleteTranslation checks if a user can delete a translation. func (s *Service) CanDeleteTranslation(ctx context.Context) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } // Admins can do anything. if claims.Role == string(domain.UserRoleAdmin) { return true, nil } return false, domain.ErrForbidden } // CanUpdateUser checks if a user has permission to update another user's profile. func (s *Service) CanCreateWork(ctx context.Context) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } if claims.Role == string(domain.UserRoleAdmin) { return true, nil } return false, domain.ErrForbidden } func (s *Service) CanCreateTranslation(ctx context.Context) (bool, error) { _, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } return true, nil } func (s *Service) CanEditTranslation(ctx context.Context, userID uint, translationID uint) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } // Admins can do anything. if claims.Role == string(domain.UserRoleAdmin) { return true, nil } // Check if the user is the translator of the translation. translation, err := s.translationRepo.GetByID(ctx, translationID) if err != nil { return false, err } if translation.TranslatorID != nil && *translation.TranslatorID == userID { return true, nil } return false, domain.ErrForbidden } func (s *Service) CanCreateBook(ctx context.Context) (bool, error) { _, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } return true, nil } func (s *Service) CanUpdateBook(ctx context.Context) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } if claims.Role == string(domain.UserRoleAdmin) { return true, nil } return false, domain.ErrForbidden } func (s *Service) CanDeleteBook(ctx context.Context) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } if claims.Role == string(domain.UserRoleAdmin) { return true, nil } return false, domain.ErrForbidden } func (s *Service) CanUpdateUser(ctx context.Context, actorID, targetUserID uint) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } // Admins can do anything. if claims.Role == string(domain.UserRoleAdmin) { return true, nil } // Users can update their own profile. if actorID == targetUserID { return true, nil } return false, domain.ErrForbidden } // CanDeleteComment checks if a user has permission to delete a comment. // For now, we'll implement a simple rule: only an admin or the comment's author can delete it. func (s *Service) CanDeleteComment(ctx context.Context, userID uint, comment *domain.Comment) (bool, error) { claims, ok := platform_auth.GetClaimsFromContext(ctx) if !ok { return false, domain.ErrUnauthorized } // Admins can do anything. if claims.Role == string(domain.UserRoleAdmin) { return true, nil } // Check if the user is the author of the comment. if comment.UserID == userID { return true, nil } return false, domain.ErrForbidden }