mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-13 16:44:52 +08:00
added tokenization + detokenization
This commit is contained in:
parent
0e5e34ef0c
commit
71ce2caabd
4 changed files with 159 additions and 8 deletions
|
@ -29,6 +29,7 @@ var HttpHandlers = []interface{}{
|
|||
ipHandlers,
|
||||
loggerHandlers,
|
||||
hostHandlers,
|
||||
enrollmentKeyHandlers,
|
||||
}
|
||||
|
||||
// HandleRESTRequests - handles the rest requests
|
||||
|
|
96
controllers/enrollmentkeys.go
Normal file
96
controllers/enrollmentkeys.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
func enrollmentKeyHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/v1/enrollment-keys", logic.SecurityCheck(true, http.HandlerFunc(getEnrollmentKeys))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/enrollment-keys/{keyID}", logic.SecurityCheck(true, http.HandlerFunc(deleteEnrollmentKey))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/v1/host/register", logic.SecurityCheck(true, http.HandlerFunc(handleHostRegister))).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
// swagger:route GET /api/v1/enrollment-keys enrollmentKeys getEnrollmentKeys
|
||||
//
|
||||
// Lists all hosts.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: getEnrollmentKeysSlice
|
||||
func getEnrollmentKeys(w http.ResponseWriter, r *http.Request) {
|
||||
currentKeys, err := logic.GetAllEnrollmentKeys()
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to fetch enrollment keys: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
for i := range currentKeys {
|
||||
if err = logic.Tokenize(currentKeys[i], servercfg.GetServer()); err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to get token values for keys:", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
}
|
||||
// return JSON/API formatted hosts
|
||||
logger.Log(2, r.Header.Get("user"), "fetched enrollment keys")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(currentKeys)
|
||||
}
|
||||
|
||||
// swagger:route DELETE /api/v1/enrollment-keys/{keyID} enrollmentKeys deleteEnrollmentKey
|
||||
//
|
||||
// Deletes a Netclient host from Netmaker server.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: deleteEnrollmentKeyResponse
|
||||
func deleteEnrollmentKey(w http.ResponseWriter, r *http.Request) {
|
||||
var params = mux.Vars(r)
|
||||
keyID := params["keyID"]
|
||||
err := logic.DeleteEnrollmentKey(keyID)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to remove enrollment key: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logger.Log(2, r.Header.Get("user"), "deleted enrollment key", keyID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// swagger:route DELETE /api/v1/enrollment-keys/{keyID} enrollmentKeys deleteEnrollmentKey
|
||||
//
|
||||
// Deletes a Netclient host from Netmaker server.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: hostRegisterResponse
|
||||
func handleHostRegister(w http.ResponseWriter, r *http.Request) {
|
||||
var params = mux.Vars(r)
|
||||
keyID := params["keyID"]
|
||||
err := logic.DeleteEnrollmentKey(keyID)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to remove enrollment key: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logger.Log(2, r.Header.Get("user"), "deleted enrollment key", keyID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -13,15 +14,19 @@ import (
|
|||
|
||||
// EnrollmentKeyErrors - struct for holding EnrollmentKey error messages
|
||||
var EnrollmentKeyErrors = struct {
|
||||
InvalidCreate error
|
||||
NoKeyFound error
|
||||
InvalidKey error
|
||||
NoUsesRemaining error
|
||||
InvalidCreate error
|
||||
NoKeyFound error
|
||||
InvalidKey error
|
||||
NoUsesRemaining error
|
||||
FailedToTokenize error
|
||||
FailedToDeTokenize error
|
||||
}{
|
||||
InvalidCreate: fmt.Errorf("invalid enrollment key created"),
|
||||
NoKeyFound: fmt.Errorf("no enrollmentkey found"),
|
||||
InvalidKey: fmt.Errorf("invalid key provided"),
|
||||
NoUsesRemaining: fmt.Errorf("no uses remaining"),
|
||||
InvalidCreate: fmt.Errorf("invalid enrollment key created"),
|
||||
NoKeyFound: fmt.Errorf("no enrollmentkey found"),
|
||||
InvalidKey: fmt.Errorf("invalid key provided"),
|
||||
NoUsesRemaining: fmt.Errorf("no uses remaining"),
|
||||
FailedToTokenize: fmt.Errorf("failed to tokenize"),
|
||||
FailedToDeTokenize: fmt.Errorf("failed to detokenize"),
|
||||
}
|
||||
|
||||
// CreateEnrollmentKey - creates a new enrollment key in db
|
||||
|
@ -109,6 +114,47 @@ func TryToUseEnrollmentKey(k *models.EnrollmentKey) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Tokenize - tokenizes an enrollment key to be used via registration
|
||||
// and attaches it to the Token field on the struct
|
||||
func Tokenize(k *models.EnrollmentKey, serverAddr string) error {
|
||||
if len(serverAddr) == 0 {
|
||||
return EnrollmentKeyErrors.FailedToTokenize
|
||||
}
|
||||
newToken := models.EnrollmentToken{
|
||||
Server: serverAddr,
|
||||
Value: k.Value,
|
||||
}
|
||||
data, err := json.Marshal(&newToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k.Token = b64.StdEncoding.EncodeToString([]byte(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeTokenize - detokenizes a base64 encoded string
|
||||
// and finds the associated enrollment key
|
||||
func DeTokenize(b64Token string) (*models.EnrollmentKey, error) {
|
||||
if len(b64Token) == 0 {
|
||||
return nil, EnrollmentKeyErrors.FailedToDeTokenize
|
||||
}
|
||||
tokenData, err := b64.StdEncoding.DecodeString(b64Token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var newToken models.EnrollmentToken
|
||||
err = json.Unmarshal(tokenData, &newToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k, err := GetEnrollmentKey(newToken.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// == private ==
|
||||
|
||||
// decrementEnrollmentKey - decrements the uses on a key if above 0 remaining
|
||||
|
|
|
@ -4,6 +4,13 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// EnrollmentToken - the tokenized version of an enrollmentkey;
|
||||
// to be used for host registration
|
||||
type EnrollmentToken struct {
|
||||
Server string `json:"value"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// EnrollmentKeyLength - the length of an enrollment key
|
||||
const EnrollmentKeyLength = 32
|
||||
|
||||
|
@ -15,6 +22,7 @@ type EnrollmentKey struct {
|
|||
Networks []string `json:"networks"`
|
||||
Unlimited bool `json:"unlimited"`
|
||||
Tags []string `json:"tags"`
|
||||
Token string `json:"token,omitempty"` // B64 value of EnrollmentToken
|
||||
}
|
||||
|
||||
// EnrollmentKey.IsValid - checks if the key is still valid to use
|
||||
|
|
Loading…
Add table
Reference in a new issue