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  }