wip: peer handlers

This commit is contained in:
Christoph Haas 2023-06-21 22:31:36 +02:00
parent e43647426c
commit d6b32f70f8
2 changed files with 234 additions and 9 deletions

View File

@ -20,27 +20,36 @@ func (e peerEndpoint) GetName() string {
func (e peerEndpoint) RegisterRoutes(g *gin.RouterGroup, authenticator *authenticationHandler) {
apiGroup := g.Group("/peer", e.authenticator.LoggedIn())
apiGroup.GET("/all/:id", e.handlePeersGet())
apiGroup.GET("/iface/:iface/all", e.handleAllGet())
apiGroup.GET("/iface/:iface/prepare", e.handlePrepareGet())
apiGroup.POST("/iface/:iface/new", e.handleCreatePost())
apiGroup.GET("/:id", e.handleSingleGet())
apiGroup.PUT("/:id", e.handleUpdatePut())
apiGroup.DELETE("/:id", e.handleDelete())
}
// handlePeersGet returns a gorm handler function.
// handleAllGet returns a gorm handler function.
//
// @ID peers_handlePeersGet
// @ID peers_handleAllGet
// @Tags Peer
// @Summary Get peers for the given interface.
// @Produce json
// @Param iface path string true "The interface identifier"
// @Success 200 {object} []model.Peer
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/all/{id} [get]
func (e peerEndpoint) handlePeersGet() gin.HandlerFunc {
// @Router /peer/iface/{iface}/all [get]
func (e peerEndpoint) handleAllGet() gin.HandlerFunc {
return func(c *gin.Context) {
interfaceId := c.Param("id")
ctx := domain.SetUserInfoFromGin(c)
interfaceId := c.Param("iface")
if interfaceId == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusInternalServerError, Message: "missing id parameter"})
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing iface parameter"})
return
}
_, peers, err := e.app.GetInterfaceAndPeers(c.Request.Context(), domain.InterfaceIdentifier(interfaceId))
_, peers, err := e.app.GetInterfaceAndPeers(ctx, domain.InterfaceIdentifier(interfaceId))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()})
return
@ -49,3 +58,186 @@ func (e peerEndpoint) handlePeersGet() gin.HandlerFunc {
c.JSON(http.StatusOK, model.NewPeers(peers))
}
}
// handleSingleGet returns a gorm handler function.
//
// @ID peers_handleSingleGet
// @Tags Peer
// @Summary Get peer for the given identifier.
// @Produce json
// @Param id path string true "The peer identifier"
// @Success 200 {object} model.Peer
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/{id} [get]
func (e peerEndpoint) handleSingleGet() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := domain.SetUserInfoFromGin(c)
peerId := c.Param("id")
if peerId == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing id parameter"})
return
}
peer, err := e.app.GetPeer(ctx, domain.PeerIdentifier(peerId))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()})
return
}
c.JSON(http.StatusOK, model.NewPeer(peer))
}
}
// handlePrepareGet returns a gorm handler function.
//
// @ID peers_handlePrepareGet
// @Tags Peer
// @Summary Prepare a new peer for the given interface.
// @Produce json
// @Param iface path string true "The interface identifier"
// @Success 200 {object} model.Peer
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/iface/{iface}/prepare [get]
func (e peerEndpoint) handlePrepareGet() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := domain.SetUserInfoFromGin(c)
interfaceId := c.Param("iface")
if interfaceId == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing iface parameter"})
return
}
peer, err := e.app.PreparePeer(ctx, domain.InterfaceIdentifier(interfaceId))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()})
return
}
c.JSON(http.StatusOK, model.NewPeer(peer))
}
}
// handleCreatePost returns a gorm handler function.
//
// @ID peers_handleCreatePost
// @Tags Peer
// @Summary Prepare a new peer for the given interface.
// @Produce json
// @Param iface path string true "The interface identifier"
// @Param request body model.Peer true "The peer data"
// @Success 200 {object} model.Peer
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/iface/{iface}/new [post]
func (e peerEndpoint) handleCreatePost() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := domain.SetUserInfoFromGin(c)
interfaceId := c.Param("iface")
if interfaceId == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing iface parameter"})
return
}
var p model.Peer
err := c.BindJSON(&p)
if err != nil {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: err.Error()})
return
}
if p.InterfaceIdentifier != interfaceId {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "interface id mismatch"})
return
}
newPeer, err := e.app.CreatePeer(ctx, model.NewDomainPeer(&p))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()})
return
}
c.JSON(http.StatusOK, model.NewPeer(newPeer))
}
}
// handleUpdatePut returns a gorm handler function.
//
// @ID peers_handleUpdatePut
// @Tags Peer
// @Summary Update the given peer record.
// @Produce json
// @Param id path string true "The peer identifier"
// @Param request body model.Peer true "The peer data"
// @Success 200 {object} model.Peer
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/{id} [post]
func (e peerEndpoint) handleUpdatePut() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := domain.SetUserInfoFromGin(c)
peerId := c.Param("id")
if peerId == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing id parameter"})
return
}
var p model.Peer
err := c.BindJSON(&p)
if err != nil {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: err.Error()})
return
}
if p.InterfaceIdentifier != peerId {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "peer id mismatch"})
return
}
updatedPeer, err := e.app.UpdateInterface(ctx, model.NewDomainPeer(&p))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()})
return
}
c.JSON(http.StatusOK, model.NewPeer(updatedPeer))
}
}
// handleDelete returns a gorm handler function.
//
// @ID peers_handleDelete
// @Tags Peer
// @Summary Delete the peer record.
// @Produce json
// @Param id path string true "The peer identifier"
// @Success 204 "No content if deletion was successful"
// @Failure 400 {object} model.Error
// @Failure 500 {object} model.Error
// @Router /peer/{id} [delete]
func (e peerEndpoint) handleDelete() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := domain.SetUserInfoFromGin(c)
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, model.Error{Code: http.StatusBadRequest, Message: "missing peer id"})
return
}
err := e.app.DeletePeer(ctx, domain.PeerIdentifier(id))
if err != nil {
c.JSON(http.StatusInternalServerError, model.Error{
Code: http.StatusInternalServerError, Message: err.Error(),
})
return
}
c.Status(http.StatusNoContent)
}
}

View File

@ -1,6 +1,9 @@
package model
import "github.com/h44z/wg-portal/internal/domain"
import (
"github.com/h44z/wg-portal/internal/domain"
"time"
)
type Peer struct {
Identifier string `json:"Identifier" example:"super_nice_peer"` // peer unique identifier
@ -73,3 +76,33 @@ func NewPeers(src []domain.Peer) []Peer {
return results
}
func NewDomainPeer(src *Peer) *domain.Peer {
now := time.Now()
res := &domain.Peer{
BaseModel: domain.BaseModel{},
Endpoint: domain.StringConfigOption{},
EndpointPublicKey: src.EndpointPublicKey,
AllowedIPsStr: domain.StringConfigOption{},
ExtraAllowedIPsStr: "",
PresharedKey: "",
PersistentKeepalive: domain.IntConfigOption{},
DisplayName: "",
Identifier: "",
UserIdentifier: "",
InterfaceIdentifier: "",
Temporary: nil,
Disabled: nil,
DisabledReason: "",
ExpiresAt: nil,
Notes: "",
Interface: domain.PeerInterfaceConfig{},
}
if src.Disabled {
res.Disabled = &now
}
return res
}