eintopf.info@v0.13.16/service/action/authorizer.go (about) 1 // Copyright (C) 2024 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package action 17 18 import ( 19 "context" 20 21 "eintopf.info/internal/crud" 22 "eintopf.info/service/auth" 23 ) 24 25 type Authorizer struct { 26 store Storer 27 } 28 29 // NewAuthorizer wraps the given store with authorization methods. 30 func NewAuthorizer(store Storer) *Authorizer { 31 return &Authorizer{store: store} 32 } 33 34 // Create is allowed by 35 // - internally 36 func (a *Authorizer) Create(ctx context.Context, action *Action) (*Action, error) { 37 role, err := auth.RoleFromContext(ctx) 38 if err != nil { 39 return nil, auth.ErrUnauthorized 40 } 41 if role != auth.RoleInternal { 42 return nil, auth.ErrUnauthorized 43 } 44 return a.store.Create(ctx, action) 45 } 46 47 // Update is allowed by 48 // - an admin 49 // - internally 50 func (a *Authorizer) Update(ctx context.Context, action *Action) (*Action, error) { 51 role, err := auth.RoleFromContext(ctx) 52 if err != nil { 53 return nil, auth.ErrUnauthorized 54 } 55 if role != auth.RoleInternal && role != auth.RoleAdmin { 56 return nil, auth.ErrUnauthorized 57 } 58 return a.store.Update(ctx, action) 59 } 60 61 // Delete is allowed by 62 // - the user owning the action 63 // - an admin 64 // - internally 65 func (a *Authorizer) Delete(ctx context.Context, id string) error { 66 role, err := auth.RoleFromContext(ctx) 67 if err != nil { 68 return auth.ErrUnauthorized 69 } 70 if role != auth.RoleInternal && role != auth.RoleAdmin { 71 return auth.ErrUnauthorized 72 } 73 return a.store.Delete(ctx, id) 74 } 75 76 // FindByID is allowed by 77 // - an admin 78 // - internally 79 func (a *Authorizer) FindByID(ctx context.Context, id string) (*Action, error) { 80 role, err := auth.RoleFromContext(ctx) 81 if err != nil { 82 return nil, auth.ErrUnauthorized 83 } 84 if role != auth.RoleInternal && role != auth.RoleAdmin { 85 return nil, auth.ErrUnauthorized 86 } 87 return a.store.FindByID(ctx, id) 88 } 89 90 // Find is allowed by 91 // - an admin 92 // - internally 93 func (a *Authorizer) Find(ctx context.Context, params *crud.FindParams[Filters]) ([]*Action, int, error) { 94 role, err := auth.RoleFromContext(ctx) 95 if err != nil { 96 return nil, 0, auth.ErrUnauthorized 97 } 98 if role != auth.RoleInternal && role != auth.RoleAdmin { 99 return nil, 0, auth.ErrUnauthorized 100 } 101 return a.store.Find(ctx, params) 102 }