mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
Public REST API implementation to handle peers, interfaces and users. It also includes some simple provisioning endpoints. The Swagger API documentation is available under /api/v1/doc.html
144 lines
3.6 KiB
Go
144 lines
3.6 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)
|
|
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) 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
|
|
}
|