mirror of
https://github.com/h44z/wg-portal
synced 2025-06-26 18:16:21 +00:00
provisioning endpoints
This commit is contained in:
parent
38838eb4ce
commit
fb19b6c4a8
@ -37,6 +37,7 @@
|
|||||||
"users": "Benutzer",
|
"users": "Benutzer",
|
||||||
"lang": "Sprache ändern",
|
"lang": "Sprache ändern",
|
||||||
"profile": "Mein Profil",
|
"profile": "Mein Profil",
|
||||||
|
"settings": "Einstellungen",
|
||||||
"login": "Anmelden",
|
"login": "Anmelden",
|
||||||
"logout": "Abmelden"
|
"logout": "Abmelden"
|
||||||
},
|
},
|
||||||
@ -167,6 +168,26 @@
|
|||||||
"button-show-peer": "Show Peer",
|
"button-show-peer": "Show Peer",
|
||||||
"button-edit-peer": "Edit Peer"
|
"button-edit-peer": "Edit Peer"
|
||||||
},
|
},
|
||||||
|
"settings": {
|
||||||
|
"headline": "Einstellungen",
|
||||||
|
"abstract": "Hier finden Sie persönliche Einstellungen für WireGuard Portal.",
|
||||||
|
"api": {
|
||||||
|
"headline": "API Einstellungen",
|
||||||
|
"abstract": "Hier können Sie die RESTful API verwalten.",
|
||||||
|
"active-description": "Die API ist derzeit für Ihr Benutzerkonto aktiv. Alle API-Anfragen werden mit Basic Auth authentifiziert. Verwenden Sie zur Authentifizierung die folgenden Anmeldeinformationen.",
|
||||||
|
"inactive-description": "Die API ist derzeit inaktiv. Klicken Sie auf die Schaltfläche unten, um sie zu aktivieren.",
|
||||||
|
"user-label": "API Benutzername:",
|
||||||
|
"user-placeholder": "API Benutzer",
|
||||||
|
"token-label": "API Passwort:",
|
||||||
|
"token-placeholder": "API Token",
|
||||||
|
"token-created-label": "API-Zugriff gewährt seit: ",
|
||||||
|
"button-disable-title": "Deaktivieren Sie die API. Dadurch wird der aktuelle Token ungültig.",
|
||||||
|
"button-disable-text": "API deaktivieren",
|
||||||
|
"button-enable-title": "Aktivieren Sie die API, dadurch wird ein neuer Token generiert.",
|
||||||
|
"button-enable-text": "API aktivieren",
|
||||||
|
"api-link": "API Dokumentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
"modals": {
|
"modals": {
|
||||||
"user-view": {
|
"user-view": {
|
||||||
"headline": "User Account:",
|
"headline": "User Account:",
|
||||||
|
@ -674,6 +674,7 @@
|
|||||||
"/peer/config-qr/{id}": {
|
"/peer/config-qr/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
"image/png",
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -694,7 +695,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"type": "file"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
@ -1964,6 +1965,9 @@
|
|||||||
"model.Settings": {
|
"model.Settings": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"ApiAdminOnly": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"MailLinkOnly": {
|
"MailLinkOnly": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
@ -357,6 +357,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
model.Settings:
|
model.Settings:
|
||||||
properties:
|
properties:
|
||||||
|
ApiAdminOnly:
|
||||||
|
type: boolean
|
||||||
MailLinkOnly:
|
MailLinkOnly:
|
||||||
type: boolean
|
type: boolean
|
||||||
PersistentConfigSupported:
|
PersistentConfigSupported:
|
||||||
@ -943,12 +945,13 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
produces:
|
produces:
|
||||||
|
- image/png
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: file
|
||||||
"400":
|
"400":
|
||||||
description: Bad Request
|
description: Bad Request
|
||||||
schema:
|
schema:
|
||||||
|
@ -867,6 +867,73 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/provisioning/new-peer": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BasicAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Normal users can only create new peers if self provisioning is allowed. Admins can always add new peers.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Provisioning"
|
||||||
|
],
|
||||||
|
"summary": "Create a new peer for the given interface and user.",
|
||||||
|
"operationId": "provisioning_handleNewPeerPost",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Provisioning request model.",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ProvisioningRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Peer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Error"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/user/all": {
|
"/user/all": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -1661,6 +1728,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"models.ProvisioningRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"InterfaceIdentifier"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"InterfaceIdentifier": {
|
||||||
|
"description": "InterfaceIdentifier is the identifier of the WireGuard interface the peer should be linked to.",
|
||||||
|
"type": "string",
|
||||||
|
"example": "wg0"
|
||||||
|
},
|
||||||
|
"PresharedKey": {
|
||||||
|
"description": "PresharedKey is the optional pre-shared key of the peer. If no pre-shared key is set, a new key is generated.",
|
||||||
|
"type": "string",
|
||||||
|
"example": "yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk="
|
||||||
|
},
|
||||||
|
"PublicKey": {
|
||||||
|
"description": "PublicKey is the optional public key of the peer. If no public key is set, a new key pair is generated.",
|
||||||
|
"type": "string",
|
||||||
|
"example": "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg="
|
||||||
|
},
|
||||||
|
"UserIdentifier": {
|
||||||
|
"description": "UserIdentifier is the identifier of the user the peer should be linked to.\nIf no user identifier is set, the authenticated user is used.",
|
||||||
|
"type": "string",
|
||||||
|
"example": "uid-1234567"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"models.User": {
|
"models.User": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@ -1775,16 +1870,19 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"PeerCount": {
|
"PeerCount": {
|
||||||
|
"description": "PeerCount is the number of peers linked to the user.",
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"example": 2
|
"example": 2
|
||||||
},
|
},
|
||||||
"Peers": {
|
"Peers": {
|
||||||
|
"description": "Peers is a list of peers linked to the user.",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/models.UserInformationPeer"
|
"$ref": "#/definitions/models.UserInformationPeer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"UserIdentifier": {
|
"UserIdentifier": {
|
||||||
|
"description": "UserIdentifier is the unique identifier of the user.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "uid-1234567"
|
"example": "uid-1234567"
|
||||||
}
|
}
|
||||||
|
@ -383,6 +383,32 @@ definitions:
|
|||||||
- InterfaceIdentifier
|
- InterfaceIdentifier
|
||||||
- PrivateKey
|
- PrivateKey
|
||||||
type: object
|
type: object
|
||||||
|
models.ProvisioningRequest:
|
||||||
|
properties:
|
||||||
|
InterfaceIdentifier:
|
||||||
|
description: InterfaceIdentifier is the identifier of the WireGuard interface
|
||||||
|
the peer should be linked to.
|
||||||
|
example: wg0
|
||||||
|
type: string
|
||||||
|
PresharedKey:
|
||||||
|
description: PresharedKey is the optional pre-shared key of the peer. If no
|
||||||
|
pre-shared key is set, a new key is generated.
|
||||||
|
example: yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=
|
||||||
|
type: string
|
||||||
|
PublicKey:
|
||||||
|
description: PublicKey is the optional public key of the peer. If no public
|
||||||
|
key is set, a new key pair is generated.
|
||||||
|
example: xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=
|
||||||
|
type: string
|
||||||
|
UserIdentifier:
|
||||||
|
description: |-
|
||||||
|
UserIdentifier is the identifier of the user the peer should be linked to.
|
||||||
|
If no user identifier is set, the authenticated user is used.
|
||||||
|
example: uid-1234567
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- InterfaceIdentifier
|
||||||
|
type: object
|
||||||
models.User:
|
models.User:
|
||||||
properties:
|
properties:
|
||||||
ApiEnabled:
|
ApiEnabled:
|
||||||
@ -478,13 +504,16 @@ definitions:
|
|||||||
models.UserInformation:
|
models.UserInformation:
|
||||||
properties:
|
properties:
|
||||||
PeerCount:
|
PeerCount:
|
||||||
|
description: PeerCount is the number of peers linked to the user.
|
||||||
example: 2
|
example: 2
|
||||||
type: integer
|
type: integer
|
||||||
Peers:
|
Peers:
|
||||||
|
description: Peers is a list of peers linked to the user.
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/models.UserInformationPeer'
|
$ref: '#/definitions/models.UserInformationPeer'
|
||||||
type: array
|
type: array
|
||||||
UserIdentifier:
|
UserIdentifier:
|
||||||
|
description: UserIdentifier is the unique identifier of the user.
|
||||||
example: uid-1234567
|
example: uid-1234567
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
@ -1087,6 +1116,50 @@ paths:
|
|||||||
summary: Get information about all peer records for a given user.
|
summary: Get information about all peer records for a given user.
|
||||||
tags:
|
tags:
|
||||||
- Provisioning
|
- Provisioning
|
||||||
|
/provisioning/new-peer:
|
||||||
|
post:
|
||||||
|
description: Normal users can only create new peers if self provisioning is
|
||||||
|
allowed. Admins can always add new peers.
|
||||||
|
operationId: provisioning_handleNewPeerPost
|
||||||
|
parameters:
|
||||||
|
- description: Provisioning request model.
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ProvisioningRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Peer'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Error'
|
||||||
|
"401":
|
||||||
|
description: Unauthorized
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Error'
|
||||||
|
"403":
|
||||||
|
description: Forbidden
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Error'
|
||||||
|
"404":
|
||||||
|
description: Not Found
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Error'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.Error'
|
||||||
|
security:
|
||||||
|
- BasicAuth: []
|
||||||
|
summary: Create a new peer for the given interface and user.
|
||||||
|
tags:
|
||||||
|
- Provisioning
|
||||||
/user/all:
|
/user/all:
|
||||||
get:
|
get:
|
||||||
operationId: users_handleAllGet
|
operationId: users_handleAllGet
|
||||||
|
@ -345,7 +345,7 @@ func (e peerEndpoint) handleConfigGet() gin.HandlerFunc {
|
|||||||
// @Produce png
|
// @Produce png
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param id path string true "The peer identifier"
|
// @Param id path string true "The peer identifier"
|
||||||
// @Success 200 {object} file
|
// @Success 200 {file} binary
|
||||||
// @Failure 400 {object} model.Error
|
// @Failure 400 {object} model.Error
|
||||||
// @Failure 500 {object} model.Error
|
// @Failure 500 {object} model.Error
|
||||||
// @Router /peer/config-qr/{id} [get]
|
// @Router /peer/config-qr/{id} [get]
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/h44z/wg-portal/internal/app/api/v1/models"
|
||||||
"github.com/h44z/wg-portal/internal/config"
|
"github.com/h44z/wg-portal/internal/config"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
)
|
)
|
||||||
@ -17,6 +18,8 @@ type ProvisioningServiceUserManagerRepo interface {
|
|||||||
type ProvisioningServicePeerManagerRepo interface {
|
type ProvisioningServicePeerManagerRepo interface {
|
||||||
GetPeer(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error)
|
GetPeer(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error)
|
||||||
GetUserPeers(context.Context, domain.UserIdentifier) ([]domain.Peer, error)
|
GetUserPeers(context.Context, domain.UserIdentifier) ([]domain.Peer, error)
|
||||||
|
PreparePeer(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Peer, error)
|
||||||
|
CreatePeer(ctx context.Context, p *domain.Peer) (*domain.Peer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProvisioningServiceConfigFileManagerRepo interface {
|
type ProvisioningServiceConfigFileManagerRepo interface {
|
||||||
@ -128,3 +131,44 @@ func (p ProvisioningService) GetPeerQrPng(ctx context.Context, peerId domain.Pee
|
|||||||
|
|
||||||
return peerCfgQrData, nil
|
return peerCfgQrData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p ProvisioningService) NewPeer(ctx context.Context, req models.ProvisioningRequest) (*domain.Peer, error) {
|
||||||
|
if req.UserIdentifier == "" {
|
||||||
|
req.UserIdentifier = string(domain.GetUserInfo(ctx).Id) // use authenticated user id if not set
|
||||||
|
}
|
||||||
|
|
||||||
|
// check permissions
|
||||||
|
if err := domain.ValidateUserAccessRights(ctx, domain.UserIdentifier(req.UserIdentifier)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !p.cfg.Core.SelfProvisioningAllowed {
|
||||||
|
// only admins can create new peers if self-provisioning is disabled
|
||||||
|
if err := domain.ValidateAdminAccessRights(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare new peer
|
||||||
|
peer, err := p.peers.PreparePeer(ctx, domain.InterfaceIdentifier(req.InterfaceIdentifier))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to prepare new peer: %w", err)
|
||||||
|
}
|
||||||
|
peer.UserIdentifier = domain.UserIdentifier(req.UserIdentifier) // overwrite context user id with the one from the request
|
||||||
|
if req.PublicKey != "" {
|
||||||
|
peer.Identifier = domain.PeerIdentifier(req.PublicKey)
|
||||||
|
peer.Interface.PublicKey = req.PublicKey
|
||||||
|
peer.Interface.PrivateKey = "" // clear private key if public key is set, WireGuard Portal does not know the private key in that case
|
||||||
|
}
|
||||||
|
if req.PresharedKey != "" {
|
||||||
|
peer.PresharedKey = domain.PreSharedKey(req.PresharedKey)
|
||||||
|
}
|
||||||
|
peer.GenerateDisplayName("API")
|
||||||
|
|
||||||
|
// save new peer
|
||||||
|
peer, err = p.peers.CreatePeer(ctx, peer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create new peer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return peer, nil
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ type ProvisioningEndpointProvisioningService interface {
|
|||||||
)
|
)
|
||||||
GetPeerConfig(ctx context.Context, peerId domain.PeerIdentifier) ([]byte, error)
|
GetPeerConfig(ctx context.Context, peerId domain.PeerIdentifier) ([]byte, error)
|
||||||
GetPeerQrPng(ctx context.Context, peerId domain.PeerIdentifier) ([]byte, error)
|
GetPeerQrPng(ctx context.Context, peerId domain.PeerIdentifier) ([]byte, error)
|
||||||
|
NewPeer(ctx context.Context, req models.ProvisioningRequest) (*domain.Peer, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProvisioningEndpoint struct {
|
type ProvisioningEndpoint struct {
|
||||||
@ -40,6 +41,8 @@ func (e ProvisioningEndpoint) RegisterRoutes(g *gin.RouterGroup, authenticator *
|
|||||||
apiGroup.GET("/data/user-info", authenticator.LoggedIn(), e.handleUserInfoGet())
|
apiGroup.GET("/data/user-info", authenticator.LoggedIn(), e.handleUserInfoGet())
|
||||||
apiGroup.GET("/data/peer-config", authenticator.LoggedIn(), e.handlePeerConfigGet())
|
apiGroup.GET("/data/peer-config", authenticator.LoggedIn(), e.handlePeerConfigGet())
|
||||||
apiGroup.GET("/data/peer-qr", authenticator.LoggedIn(), e.handlePeerQrGet())
|
apiGroup.GET("/data/peer-qr", authenticator.LoggedIn(), e.handlePeerQrGet())
|
||||||
|
|
||||||
|
apiGroup.POST("/new-peer", authenticator.LoggedIn(), e.handleNewPeerPost())
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleUserInfoGet returns a gorm Handler function.
|
// handleUserInfoGet returns a gorm Handler function.
|
||||||
@ -153,3 +156,40 @@ func (e ProvisioningEndpoint) handlePeerQrGet() gin.HandlerFunc {
|
|||||||
c.Data(http.StatusOK, "image/png", peerConfigQrCode)
|
c.Data(http.StatusOK, "image/png", peerConfigQrCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleNewPeerPost returns a gorm Handler function.
|
||||||
|
//
|
||||||
|
// @ID provisioning_handleNewPeerPost
|
||||||
|
// @Tags Provisioning
|
||||||
|
// @Summary Create a new peer for the given interface and user.
|
||||||
|
// @Description Normal users can only create new peers if self provisioning is allowed. Admins can always add new peers.
|
||||||
|
// @Param request body models.ProvisioningRequest true "Provisioning request model."
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} models.Peer
|
||||||
|
// @Failure 400 {object} models.Error
|
||||||
|
// @Failure 401 {object} models.Error
|
||||||
|
// @Failure 403 {object} models.Error
|
||||||
|
// @Failure 404 {object} models.Error
|
||||||
|
// @Failure 500 {object} models.Error
|
||||||
|
// @Router /provisioning/new-peer [post]
|
||||||
|
// @Security BasicAuth
|
||||||
|
func (e ProvisioningEndpoint) handleNewPeerPost() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
ctx := domain.SetUserInfoFromGin(c)
|
||||||
|
|
||||||
|
var req models.ProvisioningRequest
|
||||||
|
err := c.BindJSON(&req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, models.Error{Code: http.StatusBadRequest, Message: err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
peer, err := e.provisioning.NewPeer(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(ParseServiceError(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, models.NewPeer(peer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,9 +4,12 @@ import "github.com/h44z/wg-portal/internal/domain"
|
|||||||
|
|
||||||
// UserInformation represents the information about a user and its linked peers.
|
// UserInformation represents the information about a user and its linked peers.
|
||||||
type UserInformation struct {
|
type UserInformation struct {
|
||||||
UserIdentifier string `json:"UserIdentifier" example:"uid-1234567"`
|
// UserIdentifier is the unique identifier of the user.
|
||||||
PeerCount int `json:"PeerCount" example:"2"`
|
UserIdentifier string `json:"UserIdentifier" example:"uid-1234567"`
|
||||||
Peers []UserInformationPeer `json:"Peers"`
|
// PeerCount is the number of peers linked to the user.
|
||||||
|
PeerCount int `json:"PeerCount" example:"2"`
|
||||||
|
// Peers is a list of peers linked to the user.
|
||||||
|
Peers []UserInformationPeer `json:"Peers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserInformationPeer represents the information about a peer.
|
// UserInformationPeer represents the information about a peer.
|
||||||
@ -56,3 +59,17 @@ func NewUserInformationPeer(peer domain.Peer) UserInformationPeer {
|
|||||||
|
|
||||||
return up
|
return up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProvisioningRequest represents a request to provision a new peer.
|
||||||
|
type ProvisioningRequest struct {
|
||||||
|
// InterfaceIdentifier is the identifier of the WireGuard interface the peer should be linked to.
|
||||||
|
InterfaceIdentifier string `json:"InterfaceIdentifier" example:"wg0" binding:"required"`
|
||||||
|
// UserIdentifier is the identifier of the user the peer should be linked to.
|
||||||
|
// If no user identifier is set, the authenticated user is used.
|
||||||
|
UserIdentifier string `json:"UserIdentifier" example:"uid-1234567"`
|
||||||
|
|
||||||
|
// PublicKey is the optional public key of the peer. If no public key is set, a new key pair is generated.
|
||||||
|
PublicKey string `json:"PublicKey" example:"xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=" binding:"omitempty,len=44"`
|
||||||
|
// PresharedKey is the optional pre-shared key of the peer. If no pre-shared key is set, a new key is generated.
|
||||||
|
PresharedKey string `json:"PresharedKey" example:"yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk=" binding:"omitempty,len=44"`
|
||||||
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal"
|
|
||||||
"github.com/h44z/wg-portal/internal/app"
|
"github.com/h44z/wg-portal/internal/app"
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
"github.com/h44z/wg-portal/internal/domain"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -34,9 +33,9 @@ func (m Manager) CreateDefaultPeer(ctx context.Context, userId domain.UserIdenti
|
|||||||
}
|
}
|
||||||
|
|
||||||
peer.UserIdentifier = userId
|
peer.UserIdentifier = userId
|
||||||
peer.DisplayName = fmt.Sprintf("Default Peer %s", internal.TruncateString(string(peer.Identifier), 8))
|
|
||||||
peer.Notes = fmt.Sprintf("Default peer created for user %s", userId)
|
peer.Notes = fmt.Sprintf("Default peer created for user %s", userId)
|
||||||
peer.AutomaticallyCreated = true
|
peer.AutomaticallyCreated = true
|
||||||
|
peer.GenerateDisplayName("Default")
|
||||||
|
|
||||||
newPeers = append(newPeers, *peer)
|
newPeers = append(newPeers, *peer)
|
||||||
}
|
}
|
||||||
@ -108,7 +107,6 @@ func (m Manager) PreparePeer(ctx context.Context, id domain.InterfaceIdentifier)
|
|||||||
ExtraAllowedIPsStr: "",
|
ExtraAllowedIPsStr: "",
|
||||||
PresharedKey: pk,
|
PresharedKey: pk,
|
||||||
PersistentKeepalive: domain.NewConfigOption(iface.PeerDefPersistentKeepalive, true),
|
PersistentKeepalive: domain.NewConfigOption(iface.PeerDefPersistentKeepalive, true),
|
||||||
DisplayName: fmt.Sprintf("Peer %s", internal.TruncateString(string(peerId), 8)),
|
|
||||||
Identifier: peerId,
|
Identifier: peerId,
|
||||||
UserIdentifier: currentUser.Id,
|
UserIdentifier: currentUser.Id,
|
||||||
InterfaceIdentifier: iface.Identifier,
|
InterfaceIdentifier: iface.Identifier,
|
||||||
@ -132,6 +130,7 @@ func (m Manager) PreparePeer(ctx context.Context, id domain.InterfaceIdentifier)
|
|||||||
PostDown: domain.NewConfigOption(iface.PeerDefPostDown, true),
|
PostDown: domain.NewConfigOption(iface.PeerDefPostDown, true),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
freshPeer.GenerateDisplayName("")
|
||||||
|
|
||||||
return freshPeer, nil
|
return freshPeer, nil
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,13 @@ func (p *Peer) ApplyInterfaceDefaults(in *Interface) {
|
|||||||
p.Interface.PostDown.TrySetValue(in.PeerDefPostDown)
|
p.Interface.PostDown.TrySetValue(in.PeerDefPostDown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Peer) GenerateDisplayName(prefix string) {
|
||||||
|
if prefix != "" {
|
||||||
|
prefix = fmt.Sprintf("%s ", strings.TrimSpace(prefix)) // add a space after the prefix
|
||||||
|
}
|
||||||
|
p.DisplayName = fmt.Sprintf("%sPeer %s", prefix, internal.TruncateString(string(p.Identifier), 8))
|
||||||
|
}
|
||||||
|
|
||||||
type PeerInterfaceConfig struct {
|
type PeerInterfaceConfig struct {
|
||||||
KeyPair // private/public Key of the peer
|
KeyPair // private/public Key of the peer
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user