mirror of https://github.com/h44z/wg-portal.git
				
				
				
			
		
			
				
	
	
		
			158 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
	
| package backend
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 
 | |
| 	"github.com/h44z/wg-portal/internal/config"
 | |
| 	"github.com/h44z/wg-portal/internal/domain"
 | |
| )
 | |
| 
 | |
| type PeerServicePeerManagerRepo interface {
 | |
| 	GetPeer(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error)
 | |
| 	GetUserPeers(ctx context.Context, id domain.UserIdentifier) ([]domain.Peer, error)
 | |
| 	GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Interface, []domain.Peer, error)
 | |
| 	PreparePeer(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error)
 | |
| 	CreatePeer(ctx context.Context, peer *domain.Peer) (*domain.Peer, error)
 | |
| 	UpdatePeer(ctx context.Context, peer *domain.Peer) (*domain.Peer, error)
 | |
| 	DeletePeer(ctx context.Context, id domain.PeerIdentifier) error
 | |
| }
 | |
| 
 | |
| type PeerServiceUserManagerRepo interface {
 | |
| 	GetUser(ctx context.Context, id domain.UserIdentifier) (*domain.User, error)
 | |
| }
 | |
| 
 | |
| type PeerService struct {
 | |
| 	cfg *config.Config
 | |
| 
 | |
| 	peers PeerServicePeerManagerRepo
 | |
| 	users PeerServiceUserManagerRepo
 | |
| }
 | |
| 
 | |
| func NewPeerService(
 | |
| 	cfg *config.Config,
 | |
| 	peers PeerServicePeerManagerRepo,
 | |
| 	users PeerServiceUserManagerRepo,
 | |
| ) *PeerService {
 | |
| 	return &PeerService{
 | |
| 		cfg:   cfg,
 | |
| 		peers: peers,
 | |
| 		users: users,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (s PeerService) GetForInterface(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.Peer, error) {
 | |
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	_, interfacePeers, err := s.peers.GetInterfaceAndPeers(ctx, id)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return interfacePeers, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) GetForUser(ctx context.Context, id domain.UserIdentifier) ([]domain.Peer, error) {
 | |
| 	if err := domain.ValidateUserAccessRights(ctx, id); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if s.cfg.Advanced.ApiAdminOnly && !domain.GetUserInfo(ctx).IsAdmin {
 | |
| 		return nil, errors.Join(errors.New("only admins can access this endpoint"), domain.ErrNoPermission)
 | |
| 	}
 | |
| 
 | |
| 	user, err := s.users.GetUser(ctx, id)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	userPeers, err := s.peers.GetUserPeers(ctx, user.Identifier)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return userPeers, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) GetById(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error) {
 | |
| 	if s.cfg.Advanced.ApiAdminOnly && !domain.GetUserInfo(ctx).IsAdmin {
 | |
| 		return nil, errors.Join(errors.New("only admins can access this endpoint"), domain.ErrNoPermission)
 | |
| 	}
 | |
| 
 | |
| 	peer, err := s.peers.GetPeer(ctx, id)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	// Check if the user has access rights to the requested peer.
 | |
| 	// If the peer is not linked to any user, access is granted only for admins.
 | |
| 	if err := domain.ValidateUserAccessRights(ctx, peer.UserIdentifier); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return peer, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) Prepare(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error) {
 | |
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	peer, err := s.peers.PreparePeer(ctx, id)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return peer, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) Create(ctx context.Context, peer *domain.Peer) (*domain.Peer, error) {
 | |
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if peer.Identifier != domain.PeerIdentifier(peer.Interface.PublicKey) {
 | |
| 		return nil, fmt.Errorf("peer id mismatch: %s != %s: %w",
 | |
| 			peer.Identifier, peer.Interface.PublicKey, domain.ErrInvalidData)
 | |
| 	}
 | |
| 
 | |
| 	createdPeer, err := s.peers.CreatePeer(ctx, peer)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return createdPeer, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) Update(ctx context.Context, _ domain.PeerIdentifier, peer *domain.Peer) (
 | |
| 	*domain.Peer,
 | |
| 	error,
 | |
| ) {
 | |
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	updatedPeer, err := s.peers.UpdatePeer(ctx, peer)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return updatedPeer, nil
 | |
| }
 | |
| 
 | |
| func (s PeerService) Delete(ctx context.Context, id domain.PeerIdentifier) error {
 | |
| 	if err := domain.ValidateAdminAccessRights(ctx); err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	err := s.peers.DeletePeer(ctx, id)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |