eintopf.info@v0.13.16/service/place/authorizer.go (about) 1 // Copyright (C) 2022 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 place 17 18 import ( 19 "context" 20 "fmt" 21 22 "eintopf.info/internal/crud" 23 "eintopf.info/service/auth" 24 ) 25 26 type Authorizer struct { 27 service Service 28 } 29 30 func NewAuthorizer(service Service) *Authorizer { 31 return &Authorizer{service} 32 } 33 34 // Create can only be called by loggedin users. 35 func (a *Authorizer) Create(ctx context.Context, newPlace *NewPlace) (*Place, error) { 36 _, err := auth.UserIDFromContext(ctx) 37 if err != nil { 38 return nil, auth.ErrUnauthorized 39 } 40 return a.service.Create(ctx, newPlace) 41 } 42 43 // Update can only be called 44 // - if the loggedin user is in the OwnedBy field 45 // - if the loggedin user is a moderator or admin 46 func (a *Authorizer) Update(ctx context.Context, place *Place) (*Place, error) { 47 role, err := auth.RoleFromContext(ctx) 48 if err != nil { 49 return nil, auth.ErrUnauthorized 50 } 51 if role == auth.RoleNormal { 52 userID, err := auth.UserIDFromContext(ctx) 53 if err != nil { 54 return nil, auth.ErrUnauthorized 55 } 56 if !place.IsOwned(userID) { 57 return nil, auth.ErrUnauthorized 58 } 59 oldPlace, err := a.service.FindByID(ctx, place.ID) 60 if err != nil { 61 return nil, err 62 } 63 if oldPlace == nil { 64 return nil, fmt.Errorf("cant find place with id: %s", place.ID) 65 } 66 if oldPlace.Deactivated != oldPlace.Deactivated { 67 return nil, auth.ErrUnauthorized 68 } 69 } 70 return a.service.Update(ctx, place) 71 } 72 73 // Update can only be called 74 // - if the loggedin user is in the OwnedBy field 75 // - if the loggedin user is an admin 76 func (a *Authorizer) Delete(ctx context.Context, id string) error { 77 role, err := auth.RoleFromContext(ctx) 78 if err != nil { 79 return auth.ErrUnauthorized 80 } 81 if role == auth.RoleNormal || role == auth.RoleModerator { 82 userID, err := auth.UserIDFromContext(ctx) 83 if err != nil { 84 return auth.ErrUnauthorized 85 } 86 place, err := a.service.FindByID(ctx, id) 87 if err != nil { 88 return err 89 } 90 if place == nil { 91 return nil 92 } 93 if !place.IsOwned(userID) { 94 return auth.ErrUnauthorized 95 } 96 } 97 return a.service.Delete(ctx, id) 98 } 99 100 func (a *Authorizer) FindByID(ctx context.Context, id string) (*Place, error) { 101 return a.service.FindByID(ctx, id) 102 } 103 104 func (a *Authorizer) Find(ctx context.Context, params *crud.FindParams[FindFilters]) ([]*Place, int, error) { 105 return a.service.Find(ctx, params) 106 }