diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-01 20:14:19 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-01 20:14:19 +0300 |
| commit | 74c2e0982f336ab135d8b63d26fa49bcd58e57a9 (patch) | |
| tree | 689b764fadd7d6ca35598c131d0552b3d9374e3d /internal/service/media_access.go | |
| parent | 4e35889c33491be33f8d557affb1c9d822372e7a (diff) | |
service: split media.go (745 lines) into 5 focused files
Split the monolithic media.go into cohesive files to fix KISS/SRP violation:
- media_access.go: permission verification helpers (verifyAccess, verifyModifyAccess, verifySetModifyAccess)
- media_browse.go: browsing, listing, streaming, thumbnails, set cover, tags and favorites
- media_write.go: upload, create, soft-delete, restore
- media_share.go: share token creation, validation, revocation, streaming via token
- media_notes.go: note get/upsert/delete
The shared mediaService struct, NewMediaService constructor, and common helpers
(supported extensions, type guessing, thumbnail generation) remain in media.go.
No functional changes — all tests pass.
Diffstat (limited to 'internal/service/media_access.go')
| -rw-r--r-- | internal/service/media_access.go | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/internal/service/media_access.go b/internal/service/media_access.go new file mode 100644 index 0000000..7320c94 --- /dev/null +++ b/internal/service/media_access.go @@ -0,0 +1,121 @@ +package service + +import ( + "context" + "fmt" + + "codeberg.org/snonux/player/internal/model" +) + +func (s *mediaService) verifyAccess(ctx context.Context, mediaID, userID int64) (*model.Media, error) { + media, err := s.store.GetMediaByID(ctx, mediaID) + if err != nil { + return nil, fmt.Errorf("get media: %w", err) + } + if media == nil || media.DeletedAt != nil { + return nil, ErrNotFound + } + + user, err := s.store.GetUserByID(ctx, userID) + if err != nil { + return nil, fmt.Errorf("get user: %w", err) + } + if user != nil && user.IsAdmin { + return media, nil + } + + set, err := s.store.GetSetByID(ctx, media.SetID) + if err != nil { + return nil, fmt.Errorf("get set: %w", err) + } + if set == nil { + return nil, ErrNotFound + } + + for _, p := range set.Permissions { + if p.UserID == userID { + return media, nil + } + } + + perm, err := s.store.GetPermission(ctx, media.SetID, userID) + if err != nil { + return nil, fmt.Errorf("get permission: %w", err) + } + if perm != nil { + return media, nil + } + + return nil, ErrForbidden +} + +// verifyModifyAccess checks that the user has access to the media and is an owner or admin. +func (s *mediaService) verifyModifyAccess(ctx context.Context, mediaID, userID int64) (*model.Media, error) { + media, err := s.verifyAccess(ctx, mediaID, userID) + if err != nil { + return nil, err + } + + user, err := s.store.GetUserByID(ctx, userID) + if err != nil { + return nil, fmt.Errorf("get user: %w", err) + } + if user != nil && user.IsAdmin { + return media, nil + } + + perm, err := s.store.GetPermission(ctx, media.SetID, userID) + if err != nil { + return nil, fmt.Errorf("get permission: %w", err) + } + if perm != nil && perm.Role == model.RoleOwner { + return media, nil + } + + set, err := s.store.GetSetByID(ctx, media.SetID) + if err != nil { + return nil, fmt.Errorf("get set: %w", err) + } + if set != nil { + for _, p := range set.Permissions { + if p.UserID == userID && p.Role == model.RoleOwner { + return media, nil + } + } + } + + return nil, ErrForbidden +} + +// verifySetModifyAccess checks that the user is an owner or admin for a set. +func (s *mediaService) verifySetModifyAccess(ctx context.Context, setID, userID int64) error { + user, err := s.store.GetUserByID(ctx, userID) + if err != nil { + return fmt.Errorf("get user: %w", err) + } + if user != nil && user.IsAdmin { + return nil + } + + perm, err := s.store.GetPermission(ctx, setID, userID) + if err != nil { + return fmt.Errorf("get permission: %w", err) + } + if perm != nil && perm.Role == model.RoleOwner { + return nil + } + + set, err := s.store.GetSetByID(ctx, setID) + if err != nil { + return fmt.Errorf("get set: %w", err) + } + if set != nil { + for _, p := range set.Permissions { + if p.UserID == userID && p.Role == model.RoleOwner { + return nil + } + } + } + + return ErrForbidden +} |
