mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-20 20:39:08 +02:00
OpenAPI specification and API Adjusts (#356)
Introduced an OpenAPI specification. Updated API handlers to use the specification types. Added patch operation for rules and groups and methods to the account manager. HTTP PUT operations require id, fail if not provided. Use snake_case for HTTP request and response body
This commit is contained in:
@@ -2,56 +2,34 @@ package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/netbirdio/netbird/management/server"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
"github.com/netbirdio/netbird/management/server/http/api"
|
||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SetupKeys is a handler that returns a list of setup keys of the account
|
||||
type SetupKeys struct {
|
||||
accountManager server.AccountManager
|
||||
jwtExtractor jwtclaims.ClaimsExtractor
|
||||
authAudience string
|
||||
}
|
||||
|
||||
// SetupKeyResponse is a response sent to the client
|
||||
type SetupKeyResponse struct {
|
||||
Id string
|
||||
Key string
|
||||
Name string
|
||||
Expires time.Time
|
||||
Type server.SetupKeyType
|
||||
Valid bool
|
||||
Revoked bool
|
||||
UsedTimes int
|
||||
LastUsed time.Time
|
||||
State string
|
||||
}
|
||||
|
||||
// SetupKeyRequest is a request sent by client. This object contains fields that can be modified
|
||||
type SetupKeyRequest struct {
|
||||
Name string
|
||||
Type server.SetupKeyType
|
||||
ExpiresIn *util.Duration
|
||||
Revoked bool
|
||||
}
|
||||
|
||||
func NewSetupKeysHandler(accountManager server.AccountManager, authAudience string) *SetupKeys {
|
||||
return &SetupKeys{
|
||||
accountManager: accountManager,
|
||||
authAudience: authAudience,
|
||||
jwtExtractor: *jwtclaims.NewClaimsExtractor(nil),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SetupKeys) updateKey(accountId string, keyId string, w http.ResponseWriter, r *http.Request) {
|
||||
req := &SetupKeyRequest{}
|
||||
req := &api.PutApiSetupKeysIdJSONRequestBody{}
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
@@ -96,19 +74,28 @@ func (h *SetupKeys) getKey(accountId string, keyId string, w http.ResponseWriter
|
||||
}
|
||||
|
||||
func (h *SetupKeys) createKey(accountId string, w http.ResponseWriter, r *http.Request) {
|
||||
req := &SetupKeyRequest{}
|
||||
req := &api.PostApiSetupKeysJSONRequestBody{}
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !(req.Type == server.SetupKeyReusable || req.Type == server.SetupKeyOneOff) {
|
||||
if req.Name == "" {
|
||||
http.Error(w, "Setup key name shouldn't be empty", http.StatusUnprocessableEntity)
|
||||
return
|
||||
}
|
||||
|
||||
if !(server.SetupKeyType(req.Type) == server.SetupKeyReusable ||
|
||||
server.SetupKeyType(req.Type) == server.SetupKeyOneOff) {
|
||||
|
||||
http.Error(w, "unknown setup key type "+string(req.Type), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
setupKey, err := h.accountManager.AddSetupKey(accountId, req.Name, req.Type, req.ExpiresIn)
|
||||
expiresIn := time.Duration(req.ExpiresIn) * time.Second
|
||||
|
||||
setupKey, err := h.accountManager.AddSetupKey(accountId, req.Name, server.SetupKeyType(req.Type), expiresIn)
|
||||
if err != nil {
|
||||
errStatus, ok := status.FromError(err)
|
||||
if ok && errStatus.Code() == codes.NotFound {
|
||||
@@ -122,20 +109,8 @@ func (h *SetupKeys) createKey(accountId string, w http.ResponseWriter, r *http.R
|
||||
writeSuccess(w, setupKey)
|
||||
}
|
||||
|
||||
func (h *SetupKeys) getSetupKeyAccount(r *http.Request) (*server.Account, error) {
|
||||
extractor := jwtclaims.NewClaimsExtractor(nil)
|
||||
jwtClaims := extractor.ExtractClaimsFromRequestContext(r, h.authAudience)
|
||||
|
||||
account, err := h.accountManager.GetAccountWithAuthorizationClaims(jwtClaims)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed getting account of a user %s: %v", jwtClaims.UserId, err)
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
||||
func (h *SetupKeys) HandleKey(w http.ResponseWriter, r *http.Request) {
|
||||
account, err := h.getSetupKeyAccount(r)
|
||||
account, err := getJWTAccount(h.accountManager, h.jwtExtractor, h.authAudience, r)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
http.Redirect(w, r, "/", http.StatusInternalServerError)
|
||||
@@ -163,7 +138,7 @@ func (h *SetupKeys) HandleKey(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (h *SetupKeys) GetKeys(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, err := h.getSetupKeyAccount(r)
|
||||
account, err := getJWTAccount(h.accountManager, h.jwtExtractor, h.authAudience, r)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
http.Redirect(w, r, "/", http.StatusInternalServerError)
|
||||
@@ -178,7 +153,7 @@ func (h *SetupKeys) GetKeys(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(200)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
respBody := []*SetupKeyResponse{}
|
||||
respBody := []*api.SetupKey{}
|
||||
for _, key := range account.SetupKeys {
|
||||
respBody = append(respBody, toResponseBody(key))
|
||||
}
|
||||
@@ -204,7 +179,7 @@ func writeSuccess(w http.ResponseWriter, key *server.SetupKey) {
|
||||
}
|
||||
}
|
||||
|
||||
func toResponseBody(key *server.SetupKey) *SetupKeyResponse {
|
||||
func toResponseBody(key *server.SetupKey) *api.SetupKey {
|
||||
var state string
|
||||
if key.IsExpired() {
|
||||
state = "expired"
|
||||
@@ -215,12 +190,12 @@ func toResponseBody(key *server.SetupKey) *SetupKeyResponse {
|
||||
} else {
|
||||
state = "valid"
|
||||
}
|
||||
return &SetupKeyResponse{
|
||||
return &api.SetupKey{
|
||||
Id: key.Id,
|
||||
Key: key.Key,
|
||||
Name: key.Name,
|
||||
Expires: key.ExpiresAt,
|
||||
Type: key.Type,
|
||||
Type: string(key.Type),
|
||||
Valid: key.IsValid(),
|
||||
Revoked: key.Revoked,
|
||||
UsedTimes: key.UsedTimes,
|
||||
|
||||
Reference in New Issue
Block a user