late wirering of api

This commit is contained in:
Pascal Fischer
2025-06-11 13:27:16 +02:00
parent 2e80438c51
commit 223569e846
45 changed files with 226 additions and 1611 deletions
@@ -3,12 +3,9 @@ package network_map
import (
nbpeer "github.com/netbirdio/netbird/management/server/peer"
"github.com/netbirdio/management-refactor/internals/modules/accounts"
"github.com/netbirdio/management-refactor/internals/modules/groups"
"github.com/netbirdio/management-refactor/internals/modules/networks"
"github.com/netbirdio/management-refactor/internals/modules/networks/resources"
"github.com/netbirdio/management-refactor/internals/modules/networks/routers"
"github.com/netbirdio/management-refactor/internals/modules/policies"
)
type NetworkMapData struct {
@@ -18,10 +15,7 @@ type NetworkMapData struct {
Domain string `gorm:"index"`
DomainCategory string
IsDomainPrimaryAccount bool
Network *accounts.Network `gorm:"embedded;embeddedPrefix:network_"`
Peers []nbpeer.Peer `json:"-" gorm:"foreignKey:AccountID;references:id"`
Groups []groups.Group `json:"-" gorm:"foreignKey:AccountID;references:id"`
Policies []*policies.Policy `gorm:"foreignKey:AccountID;references:id"`
Peers []nbpeer.Peer `json:"-" gorm:"foreignKey:AccountID;references:id"`
Networks []*networks.Network `gorm:"foreignKey:AccountID;references:id"`
NetworkRouters []*routers.NetworkRouter `gorm:"foreignKey:AccountID;references:id"`
@@ -2,17 +2,10 @@ package network_map
import (
"github.com/netbirdio/netbird/management/proto"
"github.com/netbirdio/netbird/management/server/groups"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/management-refactor/internals/modules/peers"
"github.com/netbirdio/management-refactor/internals/modules/policies"
)
type UpdateMessage struct {
Update *proto.SyncResponse
NetworkMap *types.NetworkMap
PeerManager *peers.Manager
PolicyManager *policies.Manager
GroupManager *groups.Manager
Update *proto.SyncResponse
NetworkMap *types.NetworkMap
}
-18
View File
@@ -1,18 +0,0 @@
package accounts
import (
"context"
"github.com/netbirdio/netbird/management/server/integrations/extra_settings"
"github.com/netbirdio/netbird/management/server/types"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
type Manager interface {
GetExtraSettingsManager() extra_settings.Manager
GetSettings(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) (*types.Settings, error)
GetExtraSettings(ctx context.Context, tx db.Transaction, accountID string) (*types.ExtraSettings, error)
UpdateExtraSettings(ctx context.Context, accountID, userID string, extraSettings *types.ExtraSettings) (bool, error)
UpdateSettings(ctx context.Context, tx db.Transaction, settings *types.Settings) (*types.Settings, error)
}
-112
View File
@@ -1,112 +0,0 @@
package manager
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/management-refactor/management/server/context"
"github.com/netbirdio/management-refactor/management/server/http/util"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/errors"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager *Manager
permissionsManager permissions.Manager
}
func newHandler(manager *Manager, permissionsManager permissions.Manager) *handler {
return &handler{
manager: manager,
permissionsManager: permissionsManager,
}
}
func (h *handler) RegisterEndpoints(router *mux.Router) {
router.HandleFunc("/accounts/{accountId}", h.updateAccount).Methods("PUT", "OPTIONS")
router.HandleFunc("/accounts/{accountId}", h.deleteAccount).Methods("DELETE", "OPTIONS")
router.HandleFunc("/accounts", h.getAllAccounts).Methods("GET", "OPTIONS")
}
func (h *handler) updateAccount(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Accounts, operations.Write)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
vars := mux.Vars(r)
accountId := vars["accountId"]
users, err := h.manager.UpdateAccount(r.Context(), nil, accountId)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(users)
}
func (h *handler) deleteAccount(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Accounts, operations.Write)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
vars := mux.Vars(r)
accountId := vars["accountId"]
user, err := h.manager.DeleteAccount(r.Context(), nil, db.LockingStrengthShare, accountId)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
_ = json.NewEncoder(w).Encode(user)
}
func (h *handler) getAllAccounts(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Accounts, operations.Read)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
accounts, err := h.manager.GetAllAccounts(r.Context(), nil, db.LockingStrengthShare)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(accounts)
}
@@ -1,10 +0,0 @@
package manager
import "github.com/netbirdio/management-refactor/pkg/logging"
var log = logging.LoggerForThisPackage()
type Manager struct {
repo Repository
handler *handler
}
@@ -1,19 +0,0 @@
package manager
import "github.com/netbirdio/management-refactor/internals/shared/db"
type Repository interface {
RunInTx(fn func(tx db.Transaction) error) error
}
type repository struct {
store *db.Store
}
func newRepository(s *db.Store) Repository {
return &repository{store: s}
}
func (r *repository) RunInTx(fn func(tx db.Transaction) error) error {
return r.store.RunInTx(fn)
}
-73
View File
@@ -1,73 +0,0 @@
package accounts
import (
"math/rand"
"net"
"sync"
"time"
"github.com/c-robinson/iplib"
"github.com/rs/xid"
)
const (
// SubnetSize is a size of the subnet of the global network, e.g. 100.77.0.0/16
SubnetSize = 16
// NetSize is a global network size 100.64.0.0/10
NetSize = 10
// AllowedIPsFormat generates Wireguard AllowedIPs format (e.g. 100.64.30.1/32)
AllowedIPsFormat = "%s/32"
)
type Network struct {
Identifier string `json:"id"`
Net net.IPNet `gorm:"serializer:json"`
Dns string
// Serial is an ID that increments by 1 when any change to the network happened (e.g. new peer has been added).
// Used to synchronize state to the client apps.
Serial uint64
Mu sync.Mutex `json:"-" gorm:"-"`
}
// NewNetwork creates a new Network initializing it with a Serial=0
// It takes a random /16 subnet from 100.64.0.0/10 (64 different subnets)
func NewNetwork() *Network {
n := iplib.NewNet4(net.ParseIP("100.64.0.0"), NetSize)
sub, _ := n.Subnet(SubnetSize)
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
intn := r.Intn(len(sub))
return &Network{
Identifier: xid.New().String(),
Net: sub[intn].IPNet,
Dns: "",
Serial: 0}
}
// IncSerial increments Serial by 1 reflecting that the network state has been changed
func (n *Network) IncSerial() {
n.Mu.Lock()
defer n.Mu.Unlock()
n.Serial++
}
// CurrentSerial returns the Network.Serial of the network (latest state id)
func (n *Network) CurrentSerial() uint64 {
n.Mu.Lock()
defer n.Mu.Unlock()
return n.Serial
}
func (n *Network) Copy() *Network {
return &Network{
Identifier: n.Identifier,
Net: n.Net,
Dns: n.Dns,
Serial: n.Serial,
}
}
@@ -1,87 +0,0 @@
package manager
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/management-refactor/management/server/context"
"github.com/netbirdio/management-refactor/management/server/http/util"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/errors"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager *Manager
permissionsManager permissions.Manager
}
func newHandler(manager *Manager, permissionsManager permissions.Manager) *handler {
return &handler{
manager: manager,
permissionsManager: permissionsManager,
}
}
func (h *handler) RegisterEndpoints(router *mux.Router) {
router.HandleFunc("/account/{accountID}/settings", h.getSettings).Methods("GET", "OPTIONS")
router.HandleFunc("/account/{accountID}/settings", h.updateSettings).Methods("PUT", "OPTIONS")
}
func (h *handler) getSettings(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
vars := mux.Vars(r)
accountId := vars["accountID"]
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), accountId, userAuth.UserId, modules.Settings, operations.Read)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
users, err := h.manager.GetSettings(r.Context(), nil, db.LockingStrengthShare, accountId)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(users)
}
func (h *handler) updateSettings(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
vars := mux.Vars(r)
accountId := vars["accountID"]
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), accountId, userAuth.UserId, modules.Settings, operations.Write)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
settings, err := h.manager.UpdateSettings(r.Context(), nil, db.LockingStrengthShare, accountId)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
_ = json.NewEncoder(w).Encode(settings)
}
@@ -1,93 +0,0 @@
package manager
import (
"context"
"fmt"
"github.com/gorilla/mux"
"github.com/netbirdio/management-refactor/management/server/integrations/extra_settings"
types2 "github.com/netbirdio/management-refactor/management/server/types"
"github.com/netbirdio/management-refactor/internals/modules/users"
"github.com/netbirdio/management-refactor/internals/shared/activity"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/pkg/logging"
)
var log = logging.LoggerForThisPackage()
type Manager struct {
repository Repository
extraSettingsManager extra_settings.Manager
userManager *users.Manager
eventManager *activity.Manager
}
func NewManager(store *db.Store, router *mux.Router, eventManager *activity.Manager, permissionsManager permissions.Manager, userManager *users.Manager, extraSettingsManager extra_settings.Manager) *Manager {
repo := newRepository(store)
m := &Manager{
repository: repo,
extraSettingsManager: extraSettingsManager,
userManager: userManager,
eventManager: eventManager,
}
api := newHandler(m, permissionsManager)
api.RegisterEndpoints(router)
return m
}
func (m *Manager) GetExtraSettingsManager() extra_settings.Manager {
return m.extraSettingsManager
}
func (m *Manager) GetSettings(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID string) (*types.Settings, error) {
extraSettings, err := m.extraSettingsManager.GetExtraSettings(ctx, accountID)
if err != nil {
return nil, fmt.Errorf("get extra settings: %w", err)
}
settings, err := m.repository.GetAccountSettings(tx, strength, accountID)
if err != nil {
return nil, fmt.Errorf("get account settings: %w", err)
}
// Once we migrate the peer approval to settings manager this merging is obsolete
if settings.Extra != nil {
settings.Extra.FlowEnabled = extraSettings.FlowEnabled
settings.Extra.FlowPacketCounterEnabled = extraSettings.FlowPacketCounterEnabled
settings.Extra.FlowENCollectionEnabled = extraSettings.FlowENCollectionEnabled
settings.Extra.FlowDnsCollectionEnabled = extraSettings.FlowDnsCollectionEnabled
}
return settings, nil
}
func (m *Manager) GetExtraSettings(ctx context.Context, tx db.Transaction, accountID string) (*types.ExtraSettings, error) {
extraSettings, err := m.extraSettingsManager.GetExtraSettings(ctx, accountID)
if err != nil {
return nil, fmt.Errorf("get extra settings: %w", err)
}
settings, err := m.repository.GetAccountSettings(tx, db.LockingStrengthShare, accountID)
if err != nil {
return nil, fmt.Errorf("get account settings: %w", err)
}
// Once we migrate the peer approval to settings manager this merging is obsolete
if settings.Extra == nil {
settings.Extra = &types.ExtraSettings{}
}
settings.Extra.FlowEnabled = extraSettings.FlowEnabled
return settings.Extra, nil
}
func (m *Manager) UpdateExtraSettings(ctx context.Context, accountID, userID string, extraSettings *types.ExtraSettings) (bool, error) {
return m.extraSettingsManager.UpdateExtraSettings(ctx, accountID, userID, (*types2.ExtraSettings)(extraSettings))
}
func (m *Manager) UpdateSettings(ctx context.Context, tx db.Transaction, settings *types.Settings) (*types.Settings, error) {
return m.repository.UpdateSettings(tx, settings)
}
@@ -1,38 +0,0 @@
package manager
import (
"github.com/netbirdio/management-refactor/internals/modules/accounts/settings"
"github.com/netbirdio/management-refactor/internals/shared/db"
)
type Repository interface {
RunInTx(fn func(tx db.Transaction) error) error
GetAccountSettings(tx db.Transaction, strength db.LockingStrength, accountID string) (*settings.Settings, error)
UpdateSettings(tx db.Transaction, settings *settings.Settings) (*settings.Settings, error)
}
type repository struct {
store *db.Store
}
func newRepository(s *db.Store) Repository {
return &repository{store: s}
}
func (r *repository) RunInTx(fn func(tx db.Transaction) error) error {
return r.store.RunInTx(fn)
}
func (r *repository) GetAccountSettings(tx db.Transaction, strength db.LockingStrength, accountID string) (*settings.Settings, error) {
var settings settings.Settings
err := r.store.GetOne(tx, strength, &settings, "account_id = ?", accountID)
return &settings, err
}
func (r *repository) UpdateSettings(tx db.Transaction, settings *settings.Settings) (*settings.Settings, error) {
err := r.store.Update(tx, settings)
if err != nil {
return nil, err
}
return settings, nil
}
@@ -1,89 +0,0 @@
package settings
import (
"time"
)
// Settings represents Account settings structure that can be modified via API and Dashboard
type Settings struct {
// PeerLoginExpirationEnabled globally enables or disables peer login expiration
PeerLoginExpirationEnabled bool
// PeerLoginExpiration is a setting that indicates when peer login expires.
// Applies to all peers that have Peer.LoginExpirationEnabled set to true.
PeerLoginExpiration time.Duration
// PeerInactivityExpirationEnabled globally enables or disables peer inactivity expiration
PeerInactivityExpirationEnabled bool
// PeerInactivityExpiration is a setting that indicates when peer inactivity expires.
// Applies to all peers that have Peer.PeerInactivityExpirationEnabled set to true.
PeerInactivityExpiration time.Duration
// RegularUsersViewBlocked allows to block regular users from viewing even their own peers and some UI elements
RegularUsersViewBlocked bool
// GroupsPropagationEnabled allows to propagate auto groups from the user to the peer
GroupsPropagationEnabled bool
// JWTGroupsEnabled allows extract groups from JWT claim, which name defined in the JWTGroupsClaimName
// and add it to account groups.
JWTGroupsEnabled bool
// JWTGroupsClaimName from which we extract groups name to add it to account groups
JWTGroupsClaimName string
// JWTAllowGroups list of groups to which users are allowed access
JWTAllowGroups []string `gorm:"serializer:json"`
// RoutingPeerDNSResolutionEnabled enabled the DNS resolution on the routing peers
RoutingPeerDNSResolutionEnabled bool
// Extra is a dictionary of Account settings
Extra *ExtraSettings `gorm:"embedded;embeddedPrefix:extra_"`
}
// Copy copies the Settings struct
func (s *Settings) Copy() *Settings {
settings := &Settings{
PeerLoginExpirationEnabled: s.PeerLoginExpirationEnabled,
PeerLoginExpiration: s.PeerLoginExpiration,
JWTGroupsEnabled: s.JWTGroupsEnabled,
JWTGroupsClaimName: s.JWTGroupsClaimName,
GroupsPropagationEnabled: s.GroupsPropagationEnabled,
JWTAllowGroups: s.JWTAllowGroups,
RegularUsersViewBlocked: s.RegularUsersViewBlocked,
PeerInactivityExpirationEnabled: s.PeerInactivityExpirationEnabled,
PeerInactivityExpiration: s.PeerInactivityExpiration,
RoutingPeerDNSResolutionEnabled: s.RoutingPeerDNSResolutionEnabled,
}
if s.Extra != nil {
settings.Extra = s.Extra.Copy()
}
return settings
}
type ExtraSettings struct {
// PeerApprovalEnabled enables or disables the need for peers bo be approved by an administrator
PeerApprovalEnabled bool
// IntegratedValidatorGroups list of group IDs to be used with integrated approval configurations
IntegratedValidatorGroups []string `gorm:"serializer:json"`
FlowEnabled bool `gorm:"-"`
FlowPacketCounterEnabled bool `gorm:"-"`
FlowENCollectionEnabled bool `gorm:"-"`
FlowDnsCollectionEnabled bool `gorm:"-"`
}
// Copy copies the ExtraSettings struct
func (e *ExtraSettings) Copy() *ExtraSettings {
var cpGroup []string
return &ExtraSettings{
PeerApprovalEnabled: e.PeerApprovalEnabled,
IntegratedValidatorGroups: append(cpGroup, e.IntegratedValidatorGroups...),
}
}
-25
View File
@@ -1,25 +0,0 @@
package groups
import "github.com/netbirdio/netbird/management/server/integration_reference"
type Group struct {
// ID of the group
ID string `gorm:"primaryKey"`
// AccountID is a reference to Account that this object belongs
AccountID string `json:"-" gorm:"index"`
// Name visible in the UI
Name string
// Issued defines how this group was created (enum of "api", "integration" or "jwt")
Issued string
// Peers list of the group
Peers []string `gorm:"serializer:json"`
// Resources contains a list of resources in that group
Resources []Resource `gorm:"serializer:json"`
IntegrationReference integration_reference.IntegrationReference `gorm:"embedded;embeddedPrefix:integration_ref_"`
}
-87
View File
@@ -1,87 +0,0 @@
package manager
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/management-refactor/management/server/context"
"github.com/netbirdio/management-refactor/management/server/http/util"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/errors"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager *Manager
permissionsManager permissions.Manager
}
func newHandler(manager *Manager, permissionsManager permissions.Manager) *handler {
return &handler{
manager: manager,
permissionsManager: permissionsManager,
}
}
func (h *handler) RegisterEndpoints(router *mux.Router) {
router.HandleFunc("/groups", h.getAllGroups).Methods("GET", "OPTIONS")
router.HandleFunc("/groups", h.createGroup).Methods("POST", "OPTIONS")
router.HandleFunc("/groups/{groupId}", h.updateGroup).Methods("PUT", "OPTIONS")
router.HandleFunc("/groups/{groupId}", h.getGroup).Methods("GET", "OPTIONS")
router.HandleFunc("/groups/{groupId}", h.deleteGroup).Methods("DELETE", "OPTIONS")
}
func (h *handler) getAllUsers(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Users, operations.Read)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
users, err := h.manager.GetAllUsers(r.Context(), nil, db.LockingStrengthShare, userAuth.AccountId)
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(users)
}
func (h *handler) getUser(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Users, operations.Read)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
vars := mux.Vars(r)
userId := vars["userId"]
user, err := h.manager.GetUserByID(r.Context(), nil, db.LockingStrengthShare, userId)
if err != nil {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
_ = json.NewEncoder(w).Encode(user)
}
-144
View File
@@ -1,144 +0,0 @@
package manager
import (
"context"
"fmt"
"github.com/gorilla/mux"
"github.com/netbirdio/management-refactor/management/server/http/api"
"github.com/netbirdio/management-refactor/management/server/store"
"github.com/netbirdio/management-refactor/management/server/types"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
)
type Manager struct {
repo Repository
}
func NewManager(store *db.Store, router *mux.Router, permissionsManager permissions.Manager) *Manager {
repo := newRepository(store)
m := &Manager{repo: repo}
api := newHandler(m, permissionsManager)
api.RegisterEndpoints(router)
return m
}
func (m *Manager) GetAllGroups(ctx context.Context, accountID, userID string) ([]*types.Group, error) {
groups, err := m.repo.GetAccountGroups(ctx, store.LockingStrengthShare, accountID)
if err != nil {
return nil, fmt.Errorf("error getting account groups: %w", err)
}
return groups, nil
}
func (m *Manager) GetAllGroupsMap(ctx context.Context, accountID, userID string) (map[string]*types.Group, error) {
groups, err := m.GetAllGroups(ctx, accountID, userID)
if err != nil {
return nil, err
}
groupsMap := make(map[string]*types.Group)
for _, group := range groups {
groupsMap[group.ID] = group
}
return groupsMap, nil
}
func (m *Manager) AddResourceToGroup(ctx context.Context, accountID, userID, groupID string, resource *types.Resource) error {
event, err := m.AddResourceToGroupInTransaction(ctx, m.store, accountID, userID, groupID, resource)
if err != nil {
return fmt.Errorf("error adding resource to group: %w", err)
}
event()
return nil
}
func (m *Manager) AddResourceToGroupInTransaction(ctx context.Context, tx db.Transaction, accountID, userID, groupID string, resource *types.Resource) (func(), error) {
err := transaction.AddResourceToGroup(ctx, accountID, groupID, resource)
if err != nil {
return nil, fmt.Errorf("error adding resource to group: %w", err)
}
group, err := transaction.GetGroupByID(ctx, store.LockingStrengthShare, accountID, groupID)
if err != nil {
return nil, fmt.Errorf("error getting group: %w", err)
}
// TODO: at some point, this will need to become a switch statement
networkResource, err := transaction.GetNetworkResourceByID(ctx, store.LockingStrengthShare, accountID, resource.ID)
if err != nil {
return nil, fmt.Errorf("error getting network resource: %w", err)
}
event := func() {
m.accountManager.StoreEvent(ctx, userID, groupID, accountID, activity.ResourceAddedToGroup, group.EventMetaResource(networkResource))
}
return event, nil
}
func (m *Manager) RemoveResourceFromGroupInTransaction(ctx context.Context, transaction store.Store, accountID, userID, groupID, resourceID string) (func(), error) {
err := transaction.RemoveResourceFromGroup(ctx, accountID, groupID, resourceID)
if err != nil {
return nil, fmt.Errorf("error removing resource from group: %w", err)
}
group, err := transaction.GetGroupByID(ctx, store.LockingStrengthShare, accountID, groupID)
if err != nil {
return nil, fmt.Errorf("error getting group: %w", err)
}
// TODO: at some point, this will need to become a switch statement
networkResource, err := transaction.GetNetworkResourceByID(ctx, store.LockingStrengthShare, accountID, resourceID)
if err != nil {
return nil, fmt.Errorf("error getting network resource: %w", err)
}
event := func() {
m.accountManager.StoreEvent(ctx, userID, groupID, accountID, activity.ResourceRemovedFromGroup, group.EventMetaResource(networkResource))
}
return event, nil
}
func (m *Manager) GetResourceGroupsInTransaction(ctx context.Context, transaction store.Store, lockingStrength store.LockingStrength, accountID, resourceID string) ([]*types.Group, error) {
return transaction.GetResourceGroups(ctx, lockingStrength, accountID, resourceID)
}
func ToGroupsInfoMap(groups []*types.Group, idCount int) map[string][]api.GroupMinimum {
groupsInfoMap := make(map[string][]api.GroupMinimum, idCount)
groupsChecked := make(map[string]struct{}, len(groups)) // not sure why this is needed (left over from old implementation)
for _, group := range groups {
_, ok := groupsChecked[group.ID]
if ok {
continue
}
groupsChecked[group.ID] = struct{}{}
for _, pk := range group.Peers {
info := api.GroupMinimum{
Id: group.ID,
Name: group.Name,
PeersCount: len(group.Peers),
ResourcesCount: len(group.Resources),
}
groupsInfoMap[pk] = append(groupsInfoMap[pk], info)
}
for _, rk := range group.Resources {
info := api.GroupMinimum{
Id: group.ID,
Name: group.Name,
PeersCount: len(group.Peers),
ResourcesCount: len(group.Resources),
}
groupsInfoMap[rk.ID] = append(groupsInfoMap[rk.ID], info)
}
}
return groupsInfoMap
}
@@ -1,21 +0,0 @@
package manager
import (
"github.com/netbirdio/management-refactor/internals/shared/db"
)
type Repository interface {
RunInTx(fn func(tx db.Transaction) error) error
}
type repository struct {
store *db.Store
}
func newRepository(s *db.Store) Repository {
return &repository{store: s}
}
func (r *repository) RunInTx(fn func(tx db.Transaction) error) error {
return r.store.RunInTx(fn)
}
-28
View File
@@ -1,28 +0,0 @@
package groups
import "github.com/netbirdio/netbird/management/server/http/api"
type Resource struct {
ID string
Type string
}
func (r *Resource) ToAPIResponse() *api.Resource {
if r.ID == "" && r.Type == "" {
return nil
}
return &api.Resource{
Id: r.ID,
Type: api.ResourceType(r.Type),
}
}
func (r *Resource) FromAPIRequest(req *api.Resource) {
if req == nil {
return
}
r.ID = req.Id
r.Type = string(req.Type)
}
+8 -29
View File
@@ -5,48 +5,27 @@ import (
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/netbird/management/server/context"
"github.com/netbirdio/netbird/management/server/http/util"
"github.com/netbirdio/management-refactor/internals/modules/networks"
"github.com/netbirdio/management-refactor/internals/shared/errors"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager networks.Manager
permissionsManager permissions.Manager
manager networks.Manager
}
func newHandler(manager networks.Manager, permissionsManager permissions.Manager) *handler {
return &handler{
manager: manager,
permissionsManager: permissionsManager,
func RegisterEndpoints(router *mux.Router, permissionsManager permissions.Manager, manager networks.Manager) {
h := &handler{
manager: manager,
}
router.HandleFunc("/networks/{id}", permissionsManager.WithPermission(modules.Networks, operations.Write, h.deleteNetwork)).Methods("DELETE", "OPTIONS")
}
func (h *handler) RegisterEndpoints(router *mux.Router) {
router.HandleFunc("/networks/{id}", h.deleteNetwork).Methods("DELETE", "OPTIONS")
}
func (h *handler) deleteNetwork(w http.ResponseWriter, r *http.Request) {
userAuth, err := nbcontext.GetUserAuthFromContext(r.Context())
if err != nil {
util.WriteError(r.Context(), err, w)
return
}
allowed, err := h.permissionsManager.ValidateUserPermissions(r.Context(), userAuth.AccountId, userAuth.UserId, modules.Networks, operations.Write)
if err != nil {
util.WriteError(r.Context(), errors.NewPermissionValidationError(err), w)
return
}
if !allowed {
util.WriteError(r.Context(), errors.NewPermissionDeniedError(), w)
}
err = h.manager.DeleteNetwork(r.Context(), nil, userAuth.AccountId, userAuth.UserId, mux.Vars(r)["id"])
func (h *handler) deleteNetwork(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
err := h.manager.DeleteNetwork(r.Context(), nil, userAuth.AccountId, userAuth.UserId, mux.Vars(r)["id"])
if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
+3 -11
View File
@@ -4,13 +4,11 @@ import (
"context"
"fmt"
"github.com/gorilla/mux"
"github.com/rs/xid"
"github.com/netbirdio/management-refactor/internals/modules/networks"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/hook"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
)
type managerImpl struct {
@@ -19,16 +17,10 @@ type managerImpl struct {
onNetworkDelete *hook.Hook[*networks.NetworkEvent]
}
func NewManager(store *db.Store, router *mux.Router, permissionsManager permissions.Manager) networks.Manager {
repo := newRepository(store)
m := &managerImpl{
repo: repo,
onNetworkDelete: &hook.Hook[*networks.NetworkEvent]{},
func NewManager(store *db.Store) networks.Manager {
return &managerImpl{
repo: newRepository(store),
}
api := newHandler(m, permissionsManager)
api.RegisterEndpoints(router)
return m
}
func (m *managerImpl) GetAllNetworks(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID, userID string) ([]*networks.Network, error) {
+22 -18
View File
@@ -4,44 +4,48 @@ import (
"net/http"
"github.com/gorilla/mux"
nbcontext "github.com/netbirdio/netbird/management/server/context"
"github.com/netbirdio/netbird/management/server/http/util"
"github.com/netbirdio/management-refactor/internals/modules/peers"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/internals/shared/permissions/modules"
"github.com/netbirdio/management-refactor/internals/shared/permissions/operations"
)
type handler struct {
manager *Manager
permissionsManager permissions.Manager
manager peers.Manager
}
func newHandler(manager *Manager, permissionsManager permissions.Manager) *handler {
return &handler{
manager: manager,
permissionsManager: permissionsManager,
func RegisterEndpoints(router *mux.Router, permissionsManager permissions.Manager, manager peers.Manager) {
h := &handler{
manager: manager,
}
router.HandleFunc("/peers", permissionsManager.WithPermission(modules.Peers, operations.Read, h.getAllPeers)).Methods("GET", "OPTIONS")
router.HandleFunc("/peers/{peerId}", permissionsManager.WithPermission(modules.Peers, operations.Read, h.getPeer)).Methods("GET", "OPTIONS")
router.HandleFunc("/peers/{peerId}", permissionsManager.WithPermission(modules.Peers, operations.Write, h.updatePeer)).Methods("PUT", "OPTIONS")
router.HandleFunc("/peers/{peerId}", permissionsManager.WithPermission(modules.Peers, operations.Write, h.deletePeer)).Methods("DELETE", "OPTIONS")
router.HandleFunc("/peers/{peerId}/accessible-peers", permissionsManager.WithPermission(modules.Peers, operations.Read, h.getAccessiblePeers)).Methods("GET", "OPTIONS")
}
func (h *handler) RegisterEndpoints(router *mux.Router) {
router.HandleFunc("/peers", h.getAllPeers).Methods("GET", "OPTIONS")
router.HandleFunc("/peers/{peerId}", h.getPeer).Methods("GET", "OPTIONS")
router.HandleFunc("/peers/{peerId}", h.updatePeer).Methods("PUT", "OPTIONS")
router.HandleFunc("/peers/{peerId}", h.deletePeer).Methods("DELETE", "OPTIONS")
router.HandleFunc("/peers/{peerId}/accessible-peers", h.getAccessiblePeers).Methods("GET", "OPTIONS")
func (h *handler) getAllPeers(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
peers := []peers.Peer{{ID: "peer1"}, {ID: "peer2"}}
util.WriteJSONObject(r.Context(), w, peers)
}
func (h *handler) getAllPeers(w http.ResponseWriter, r *http.Request) {}
func (h *handler) getPeer(w http.ResponseWriter, r *http.Request) {
func (h *handler) getPeer(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
}
func (h *handler) updatePeer(w http.ResponseWriter, r *http.Request) {
func (h *handler) updatePeer(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
}
func (h *handler) deletePeer(w http.ResponseWriter, r *http.Request) {
func (h *handler) deletePeer(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
}
func (h *handler) getAccessiblePeers(w http.ResponseWriter, r *http.Request) {
func (h *handler) getAccessiblePeers(w http.ResponseWriter, r *http.Request, userAuth *nbcontext.UserAuth) {
}
+3 -9
View File
@@ -3,12 +3,9 @@ package manager
import (
"context"
"github.com/gorilla/mux"
"github.com/netbirdio/management-refactor/internals/modules/peers"
"github.com/netbirdio/management-refactor/internals/shared/activity"
"github.com/netbirdio/management-refactor/internals/shared/db"
"github.com/netbirdio/management-refactor/internals/shared/permissions"
"github.com/netbirdio/management-refactor/pkg/logging"
)
@@ -21,12 +18,9 @@ type Manager struct {
eventManager *activity.Manager
}
func NewManager(store *db.Store, router *mux.Router, permissionsManager permissions.Manager) *Manager {
repo := newRepository(store)
m := &Manager{repo: repo}
api := newHandler(m, permissionsManager)
api.RegisterEndpoints(router)
return m
func NewManager(store *db.Store) *Manager {
return &Manager{repo: newRepository(store)}
}
func (m *Manager) GetPeer(ctx context.Context, tx db.Transaction, strength db.LockingStrength, accountID, peerID string) (*peers.Peer, error) {

Some files were not shown because too many files have changed in this diff Show More