mirror of
https://github.com/h44z/wg-portal.git
synced 2025-06-27 16:57:01 +00:00
Option to limit peer count that a normal user can create (#457)
This commit is contained in:
parent
cbf8c5bca9
commit
f0be66aea4
@ -38,6 +38,7 @@ advanced:
|
|||||||
rule_prio_offset: 20000
|
rule_prio_offset: 20000
|
||||||
route_table_offset: 20000
|
route_table_offset: 20000
|
||||||
api_admin_only: true
|
api_admin_only: true
|
||||||
|
limit_additional_user_peers: 0
|
||||||
|
|
||||||
database:
|
database:
|
||||||
debug: false
|
debug: false
|
||||||
@ -215,6 +216,10 @@ Additional or more specialized configuration options for logging and interface c
|
|||||||
- **Default:** `true`
|
- **Default:** `true`
|
||||||
- **Description:** If `true`, the public REST API is accessible only to admin users. The API docs live at [`/api/v1/doc.html`](../rest-api/api-doc.md).
|
- **Description:** If `true`, the public REST API is accessible only to admin users. The API docs live at [`/api/v1/doc.html`](../rest-api/api-doc.md).
|
||||||
|
|
||||||
|
### `limit_additional_user_peers`
|
||||||
|
- **Default:** `0`
|
||||||
|
- **Description:** Limit additional peers a normal user can create. `0` means unlimited.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
@ -188,6 +188,30 @@ func (m Manager) CreatePeer(ctx context.Context, peer *domain.Peer) (*domain.Pee
|
|||||||
|
|
||||||
sessionUser := domain.GetUserInfo(ctx)
|
sessionUser := domain.GetUserInfo(ctx)
|
||||||
|
|
||||||
|
// Enforce peer limit for non-admin users if LimitAdditionalUserPeers is set
|
||||||
|
if m.cfg.Core.SelfProvisioningAllowed && !sessionUser.IsAdmin && m.cfg.Advanced.LimitAdditionalUserPeers > 0 {
|
||||||
|
peers, err := m.db.GetUserPeers(ctx, peer.UserIdentifier)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch peers for user %s: %w", peer.UserIdentifier, err)
|
||||||
|
}
|
||||||
|
// Count enabled peers (disabled IS NULL)
|
||||||
|
peerCount := 0
|
||||||
|
for _, p := range peers {
|
||||||
|
if !p.IsDisabled() {
|
||||||
|
peerCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
totalAllowedPeers := 1 + m.cfg.Advanced.LimitAdditionalUserPeers // 1 default peer + x additional peers
|
||||||
|
if peerCount >= totalAllowedPeers {
|
||||||
|
slog.WarnContext(ctx, "peer creation blocked due to limit",
|
||||||
|
"user", peer.UserIdentifier,
|
||||||
|
"current_count", peerCount,
|
||||||
|
"allowed_count", totalAllowedPeers)
|
||||||
|
return nil, fmt.Errorf("peer limit reached (%d peers allowed): %w", totalAllowedPeers, domain.ErrNoPermission)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
existingPeer, err := m.db.GetPeer(ctx, peer.Identifier)
|
existingPeer, err := m.db.GetPeer(ctx, peer.Identifier)
|
||||||
if err != nil && !errors.Is(err, domain.ErrNotFound) {
|
if err != nil && !errors.Is(err, domain.ErrNotFound) {
|
||||||
return nil, fmt.Errorf("unable to load existing peer %s: %w", peer.Identifier, err)
|
return nil, fmt.Errorf("unable to load existing peer %s: %w", peer.Identifier, err)
|
||||||
|
@ -29,18 +29,19 @@ type Config struct {
|
|||||||
} `yaml:"core"`
|
} `yaml:"core"`
|
||||||
|
|
||||||
Advanced struct {
|
Advanced struct {
|
||||||
LogLevel string `yaml:"log_level"`
|
LogLevel string `yaml:"log_level"`
|
||||||
LogPretty bool `yaml:"log_pretty"`
|
LogPretty bool `yaml:"log_pretty"`
|
||||||
LogJson bool `yaml:"log_json"`
|
LogJson bool `yaml:"log_json"`
|
||||||
StartListenPort int `yaml:"start_listen_port"`
|
StartListenPort int `yaml:"start_listen_port"`
|
||||||
StartCidrV4 string `yaml:"start_cidr_v4"`
|
StartCidrV4 string `yaml:"start_cidr_v4"`
|
||||||
StartCidrV6 string `yaml:"start_cidr_v6"`
|
StartCidrV6 string `yaml:"start_cidr_v6"`
|
||||||
UseIpV6 bool `yaml:"use_ip_v6"`
|
UseIpV6 bool `yaml:"use_ip_v6"`
|
||||||
ConfigStoragePath string `yaml:"config_storage_path"` // keep empty to disable config export to file
|
ConfigStoragePath string `yaml:"config_storage_path"` // keep empty to disable config export to file
|
||||||
ExpiryCheckInterval time.Duration `yaml:"expiry_check_interval"`
|
ExpiryCheckInterval time.Duration `yaml:"expiry_check_interval"`
|
||||||
RulePrioOffset int `yaml:"rule_prio_offset"`
|
RulePrioOffset int `yaml:"rule_prio_offset"`
|
||||||
RouteTableOffset int `yaml:"route_table_offset"`
|
RouteTableOffset int `yaml:"route_table_offset"`
|
||||||
ApiAdminOnly bool `yaml:"api_admin_only"` // if true, only admin users can access the API
|
ApiAdminOnly bool `yaml:"api_admin_only"` // if true, only admin users can access the API
|
||||||
|
LimitAdditionalUserPeers int `yaml:"limit_additional_user_peers"`
|
||||||
} `yaml:"advanced"`
|
} `yaml:"advanced"`
|
||||||
|
|
||||||
Statistics struct {
|
Statistics struct {
|
||||||
@ -76,6 +77,7 @@ func (c *Config) LogStartupValues() {
|
|||||||
"reEnablePeerAfterUserEnable", c.Core.ReEnablePeerAfterUserEnable,
|
"reEnablePeerAfterUserEnable", c.Core.ReEnablePeerAfterUserEnable,
|
||||||
"deletePeerAfterUserDeleted", c.Core.DeletePeerAfterUserDeleted,
|
"deletePeerAfterUserDeleted", c.Core.DeletePeerAfterUserDeleted,
|
||||||
"selfProvisioningAllowed", c.Core.SelfProvisioningAllowed,
|
"selfProvisioningAllowed", c.Core.SelfProvisioningAllowed,
|
||||||
|
"limitAdditionalUserPeers", c.Advanced.LimitAdditionalUserPeers,
|
||||||
"importExisting", c.Core.ImportExisting,
|
"importExisting", c.Core.ImportExisting,
|
||||||
"restoreState", c.Core.RestoreState,
|
"restoreState", c.Core.RestoreState,
|
||||||
"useIpV6", c.Advanced.UseIpV6,
|
"useIpV6", c.Advanced.UseIpV6,
|
||||||
@ -137,6 +139,7 @@ func defaultConfig() *Config {
|
|||||||
cfg.Advanced.RulePrioOffset = 20000
|
cfg.Advanced.RulePrioOffset = 20000
|
||||||
cfg.Advanced.RouteTableOffset = 20000
|
cfg.Advanced.RouteTableOffset = 20000
|
||||||
cfg.Advanced.ApiAdminOnly = true
|
cfg.Advanced.ApiAdminOnly = true
|
||||||
|
cfg.Advanced.LimitAdditionalUserPeers = 0
|
||||||
|
|
||||||
cfg.Statistics.UsePingChecks = true
|
cfg.Statistics.UsePingChecks = true
|
||||||
cfg.Statistics.PingCheckWorkers = 10
|
cfg.Statistics.PingCheckWorkers = 10
|
||||||
|
Loading…
x
Reference in New Issue
Block a user