3
0

Add federation pairing routes

This commit is contained in:
Tomaž Jerman 2020-09-06 11:51:33 +02:00 committed by Peter Grlica
parent b0d2b24cc5
commit 07a8cec570
11 changed files with 770 additions and 4 deletions

View File

@ -5,6 +5,80 @@
# Next step: swagger.
endpoints:
- title: Node identity
path: "/node/identity"
entrypoint: identity
authentication: []
apis:
- name: generate node identity
method: POST
title: Generate an origin node identity
path: "/generate"
parameters:
post:
- name: domain
type: string
required: true
title: Domain of the destination node
- name: register origin node
method: POST
title: Register a new origin node
path: "/register"
parameters:
post:
- name: identifier
type: string
required: true
title: Origin node identifier
- title: Federation node pair request
path: "/node/pair/request"
entrypoint: pairRequest
authentication: []
apis:
- name: request pairing
method: POST
title: Handle destination node pair request
path: "/"
parameters:
post:
- name: identifier
type: string
required: true
title: Origin node identifier
- name: token
type: string
required: true
title: Destination node token
- title: Federation node pairing
path: "/node/pair"
entrypoint: pair
authentication: []
apis:
- name: approve pairing
method: POST
title: Approve the destination node pair request
path: "/approve"
parameters:
get:
- name: requestID
type: uint64
required: true
title: Pair requestID
- name: complete pairing
method: POST
title: Complete pairing with the origin
path: "/complete"
parameters:
post:
- name: token
type: string
required: true
title: Auth token of the origin node
- title: Foobar
entrypoint: foobar
path: "/foobar"

View File

@ -0,0 +1,86 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/go-chi/chi"
"github.com/titpetric/factory/resputil"
"net/http"
"github.com/cortezaproject/corteza-server/federation/rest/request"
"github.com/cortezaproject/corteza-server/pkg/logger"
)
type (
// Internal API interface
IdentityAPI interface {
GenerateNodeIdentity(context.Context, *request.IdentityGenerateNodeIdentity) (interface{}, error)
RegisterOriginNode(context.Context, *request.IdentityRegisterOriginNode) (interface{}, error)
}
// HTTP API interface
Identity struct {
GenerateNodeIdentity func(http.ResponseWriter, *http.Request)
RegisterOriginNode func(http.ResponseWriter, *http.Request)
}
)
func NewIdentity(h IdentityAPI) *Identity {
return &Identity{
GenerateNodeIdentity: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewIdentityGenerateNodeIdentity()
if err := params.Fill(r); err != nil {
logger.LogParamError("Identity.GenerateNodeIdentity", r, err)
resputil.JSON(w, err)
return
}
value, err := h.GenerateNodeIdentity(r.Context(), params)
if err != nil {
logger.LogControllerError("Identity.GenerateNodeIdentity", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("Identity.GenerateNodeIdentity", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
RegisterOriginNode: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewIdentityRegisterOriginNode()
if err := params.Fill(r); err != nil {
logger.LogParamError("Identity.RegisterOriginNode", r, err)
resputil.JSON(w, err)
return
}
value, err := h.RegisterOriginNode(r.Context(), params)
if err != nil {
logger.LogControllerError("Identity.RegisterOriginNode", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("Identity.RegisterOriginNode", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
}
}
func (h Identity) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Post("/node/identity/generate", h.GenerateNodeIdentity)
r.Post("/node/identity/register", h.RegisterOriginNode)
})
}

View File

@ -0,0 +1,86 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/go-chi/chi"
"github.com/titpetric/factory/resputil"
"net/http"
"github.com/cortezaproject/corteza-server/federation/rest/request"
"github.com/cortezaproject/corteza-server/pkg/logger"
)
type (
// Internal API interface
PairAPI interface {
ApprovePairing(context.Context, *request.PairApprovePairing) (interface{}, error)
CompletePairing(context.Context, *request.PairCompletePairing) (interface{}, error)
}
// HTTP API interface
Pair struct {
ApprovePairing func(http.ResponseWriter, *http.Request)
CompletePairing func(http.ResponseWriter, *http.Request)
}
)
func NewPair(h PairAPI) *Pair {
return &Pair{
ApprovePairing: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPairApprovePairing()
if err := params.Fill(r); err != nil {
logger.LogParamError("Pair.ApprovePairing", r, err)
resputil.JSON(w, err)
return
}
value, err := h.ApprovePairing(r.Context(), params)
if err != nil {
logger.LogControllerError("Pair.ApprovePairing", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("Pair.ApprovePairing", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
CompletePairing: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPairCompletePairing()
if err := params.Fill(r); err != nil {
logger.LogParamError("Pair.CompletePairing", r, err)
resputil.JSON(w, err)
return
}
value, err := h.CompletePairing(r.Context(), params)
if err != nil {
logger.LogControllerError("Pair.CompletePairing", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("Pair.CompletePairing", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
}
}
func (h Pair) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Post("/node/pair/approve", h.ApprovePairing)
r.Post("/node/pair/complete", h.CompletePairing)
})
}

View File

@ -0,0 +1,63 @@
package handlers
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"context"
"github.com/go-chi/chi"
"github.com/titpetric/factory/resputil"
"net/http"
"github.com/cortezaproject/corteza-server/federation/rest/request"
"github.com/cortezaproject/corteza-server/pkg/logger"
)
type (
// Internal API interface
PairRequestAPI interface {
RequestPairing(context.Context, *request.PairRequestRequestPairing) (interface{}, error)
}
// HTTP API interface
PairRequest struct {
RequestPairing func(http.ResponseWriter, *http.Request)
}
)
func NewPairRequest(h PairRequestAPI) *PairRequest {
return &PairRequest{
RequestPairing: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewPairRequestRequestPairing()
if err := params.Fill(r); err != nil {
logger.LogParamError("PairRequest.RequestPairing", r, err)
resputil.JSON(w, err)
return
}
value, err := h.RequestPairing(r.Context(), params)
if err != nil {
logger.LogControllerError("PairRequest.RequestPairing", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("PairRequest.RequestPairing", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
}
}
func (h PairRequest) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http.Handler) {
r.Group(func(r chi.Router) {
r.Use(middlewares...)
r.Post("/node/pair/request/", h.RequestPairing)
})
}

View File

@ -0,0 +1,26 @@
package rest
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/federation/rest/request"
)
type (
NodeIdentity struct{}
)
func (NodeIdentity) New() *NodeIdentity {
return &NodeIdentity{}
}
func (ctrl NodeIdentity) GenerateNodeIdentity(ctx context.Context, r *request.IdentityGenerateNodeIdentity) (interface{}, error) {
fmt.Println("GenerateNOdeIdentity")
return nil, nil
}
func (ctrl NodeIdentity) RegisterOriginNode(ctx context.Context, r *request.IdentityRegisterOriginNode) (interface{}, error) {
fmt.Println("RegisterORiginNode")
return nil, nil
}

View File

@ -0,0 +1,25 @@
package rest
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/federation/rest/request"
)
type (
NodePair struct{}
)
func (NodePair) New() *NodePair {
return &NodePair{}
}
func (ctrl NodePair) ApprovePairing(ctx context.Context, r *request.PairApprovePairing) (interface{}, error) {
fmt.Println("ApprovePairing")
return nil, nil
}
func (ctrl NodePair) CompletePairing(ctx context.Context, r *request.PairCompletePairing) (interface{}, error) {
fmt.Println("CompletePairing")
return nil, nil
}

View File

@ -0,0 +1,21 @@
package rest
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/federation/rest/request"
)
type (
NodePairRequest struct{}
)
func (NodePairRequest) New() *NodePairRequest {
return &NodePairRequest{}
}
func (ctrl NodePairRequest) RequestPairing(ctx context.Context, r *request.PairRequestRequestPairing) (interface{}, error) {
fmt.Println("RequestPairing")
return nil, nil
}

View File

@ -0,0 +1,141 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/payload"
"github.com/go-chi/chi"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
)
type (
// Internal API interface
IdentityGenerateNodeIdentity struct {
// Domain POST parameter
//
// Domain of the destination node
Domain string
}
IdentityRegisterOriginNode struct {
// Identifier POST parameter
//
// Origin node identifier
Identifier string
}
)
// NewIdentityGenerateNodeIdentity request
func NewIdentityGenerateNodeIdentity() *IdentityGenerateNodeIdentity {
return &IdentityGenerateNodeIdentity{}
}
// Auditable returns all auditable/loggable parameters
func (r IdentityGenerateNodeIdentity) Auditable() map[string]interface{} {
return map[string]interface{}{
"domain": r.Domain,
}
}
// Auditable returns all auditable/loggable parameters
func (r IdentityGenerateNodeIdentity) GetDomain() string {
return r.Domain
}
// Fill processes request and fills internal variables
func (r *IdentityGenerateNodeIdentity) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
if val, ok := req.Form["domain"]; ok && len(val) > 0 {
r.Domain, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}
// NewIdentityRegisterOriginNode request
func NewIdentityRegisterOriginNode() *IdentityRegisterOriginNode {
return &IdentityRegisterOriginNode{}
}
// Auditable returns all auditable/loggable parameters
func (r IdentityRegisterOriginNode) Auditable() map[string]interface{} {
return map[string]interface{}{
"identifier": r.Identifier,
}
}
// Auditable returns all auditable/loggable parameters
func (r IdentityRegisterOriginNode) GetIdentifier() string {
return r.Identifier
}
// Fill processes request and fills internal variables
func (r *IdentityRegisterOriginNode) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
if val, ok := req.Form["identifier"]; ok && len(val) > 0 {
r.Identifier, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}

View File

@ -0,0 +1,138 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/payload"
"github.com/go-chi/chi"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
)
type (
// Internal API interface
PairApprovePairing struct {
// RequestID GET parameter
//
// Pair requestID
RequestID uint64 `json:",string"`
}
PairCompletePairing struct {
// Token POST parameter
//
// Auth token of the origin node
Token string
}
)
// NewPairApprovePairing request
func NewPairApprovePairing() *PairApprovePairing {
return &PairApprovePairing{}
}
// Auditable returns all auditable/loggable parameters
func (r PairApprovePairing) Auditable() map[string]interface{} {
return map[string]interface{}{
"requestID": r.RequestID,
}
}
// Auditable returns all auditable/loggable parameters
func (r PairApprovePairing) GetRequestID() uint64 {
return r.RequestID
}
// Fill processes request and fills internal variables
func (r *PairApprovePairing) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
// GET params
tmp := req.URL.Query()
if val, ok := tmp["requestID"]; ok && len(val) > 0 {
r.RequestID, err = payload.ParseUint64(val[0]), nil
if err != nil {
return err
}
}
}
return err
}
// NewPairCompletePairing request
func NewPairCompletePairing() *PairCompletePairing {
return &PairCompletePairing{}
}
// Auditable returns all auditable/loggable parameters
func (r PairCompletePairing) Auditable() map[string]interface{} {
return map[string]interface{}{
"token": r.Token,
}
}
// Auditable returns all auditable/loggable parameters
func (r PairCompletePairing) GetToken() string {
return r.Token
}
// Fill processes request and fills internal variables
func (r *PairCompletePairing) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
if val, ok := req.Form["token"]; ok && len(val) > 0 {
r.Token, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}

View File

@ -0,0 +1,104 @@
package request
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
//
import (
"encoding/json"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/payload"
"github.com/go-chi/chi"
"io"
"mime/multipart"
"net/http"
"strings"
)
// dummy vars to prevent
// unused imports complain
var (
_ = chi.URLParam
_ = multipart.ErrMessageTooLarge
_ = payload.ParseUint64s
)
type (
// Internal API interface
PairRequestRequestPairing struct {
// Identifier POST parameter
//
// Origin node identifier
Identifier string
// Token POST parameter
//
// Destination node token
Token string
}
)
// NewPairRequestRequestPairing request
func NewPairRequestRequestPairing() *PairRequestRequestPairing {
return &PairRequestRequestPairing{}
}
// Auditable returns all auditable/loggable parameters
func (r PairRequestRequestPairing) Auditable() map[string]interface{} {
return map[string]interface{}{
"identifier": r.Identifier,
"token": r.Token,
}
}
// Auditable returns all auditable/loggable parameters
func (r PairRequestRequestPairing) GetIdentifier() string {
return r.Identifier
}
// Auditable returns all auditable/loggable parameters
func (r PairRequestRequestPairing) GetToken() string {
return r.Token
}
// Fill processes request and fills internal variables
func (r *PairRequestRequestPairing) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return fmt.Errorf("error parsing http request body: %w", err)
}
}
{
if err = req.ParseForm(); err != nil {
return err
}
// POST params
if val, ok := req.Form["identifier"]; ok && len(val) > 0 {
r.Identifier, err = val[0], nil
if err != nil {
return err
}
}
if val, ok := req.Form["token"]; ok && len(val) > 0 {
r.Token, err = val[0], nil
if err != nil {
return err
}
}
}
return err
}

View File

@ -8,15 +8,17 @@ import (
)
func MountRoutes(r chi.Router) {
var (
foobar = Foobar{}.New()
)
r.Group(func(r chi.Router) {
handlers.NewPairRequest(NodePairRequest{}.New()).MountRoutes(r)
})
// Protect all _private_ routes
r.Group(func(r chi.Router) {
r.Use(auth.MiddlewareValidOnly)
r.Use(middlewareAllowedAccess)
handlers.NewFoobar(foobar).MountRoutes(r)
handlers.NewIdentity(NodeIdentity{}.New()).MountRoutes(r)
handlers.NewPair(NodePair{}.New()).MountRoutes(r)
handlers.NewFoobar(Foobar{}.New()).MountRoutes(r)
})
}