From 8255643ddf94b0127e7c44736b692b2560571ab2 Mon Sep 17 00:00:00 2001 From: Matthew R Kasun Date: Sat, 25 Feb 2023 09:49:04 -0500 Subject: [PATCH 1/5] skip legacy nodes when setting node.Action --- logic/networks.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/logic/networks.go b/logic/networks.go index 9f16c424..65606ab5 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -603,6 +603,10 @@ func networkNodesUpdateAction(networkName string, action string) error { var node models.Node err := json.Unmarshal([]byte(value), &node) if err != nil { + if strings.Contains(err.Error(), "parsing time") { + // ignore legacy nodes + continue + } fmt.Println("error in node address assignment!") return err } From 0b7df753f75f179c9cbb17cc5e8b4094c7ea7ff1 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Mon, 13 Mar 2023 16:02:44 -0400 Subject: [PATCH 2/5] removed references to AccessKey model --- auth/nodecallback.go | 82 ++++++------ auth/nodesession.go | 9 +- cli/cmd/keys/create.go | 35 ----- cli/cmd/keys/delete.go | 23 ---- cli/cmd/keys/list.go | 20 --- cli/cmd/keys/root.go | 28 ---- cli/cmd/root.go | 2 - cli/functions/keys.go | 23 ---- controllers/docs.go | 24 ---- controllers/migrate.go | 157 ++++++++++------------ controllers/network.go | 127 +----------------- controllers/network_test.go | 112 ---------------- controllers/node.go | 260 ------------------------------------ controllers/user.go | 2 +- logic/accesskeys.go | 229 ------------------------------- logic/accesskeys_test.go | 21 --- logic/networks.go | 1 - models/network.go | 1 - models/structs.go | 10 -- 19 files changed, 119 insertions(+), 1047 deletions(-) delete mode 100644 cli/cmd/keys/create.go delete mode 100644 cli/cmd/keys/delete.go delete mode 100644 cli/cmd/keys/list.go delete mode 100644 cli/cmd/keys/root.go delete mode 100644 cli/functions/keys.go delete mode 100644 logic/accesskeys.go delete mode 100644 logic/accesskeys_test.go diff --git a/auth/nodecallback.go b/auth/nodecallback.go index 299c4861..aad1e202 100644 --- a/auth/nodecallback.go +++ b/auth/nodecallback.go @@ -106,12 +106,12 @@ func HandleNodeSSOCallback(w http.ResponseWriter, r *http.Request) { var answer string // The registation logic is starting here: // we request access key with 1 use for the required network - accessToken, err := requestAccessKey(reqKeyIf.Network, 1, userClaims.getUserName()) - if err != nil { - answer = fmt.Sprintf("Error from the netmaker controller %s", err.Error()) - } else { - answer = fmt.Sprintf("AccessToken: %s", accessToken) - } + // accessToken, err := requestAccessKey(reqKeyIf.Network, 1, userClaims.getUserName()) + // if err != nil { + // answer = fmt.Sprintf("Error from the netmaker controller %s", err.Error()) + // } else { + // answer = fmt.Sprintf("AccessToken: %s", accessToken) + // } logger.Log(0, "Updating the token for the client request ... ") // Give the user the access token via Pass in the DB reqKeyIf.Pass = answer @@ -184,44 +184,44 @@ func RegisterNodeSSO(w http.ResponseWriter, r *http.Request) { // == private == // API to create an access key for a given network with a given name -func requestAccessKey(network string, uses int, name string) (accessKey string, err error) { +// func requestAccessKey(network string, uses int, name string) (accessKey string, err error) { - var sAccessKey models.AccessKey - var sNetwork models.Network +// var sAccessKey models.AccessKey +// var sNetwork models.Network - sNetwork, err = logic.GetParentNetwork(network) - if err != nil { - logger.Log(0, "err calling GetParentNetwork API=%s", err.Error()) - return "", fmt.Errorf("internal controller error %s", err.Error()) - } - // If a key already exists, we recreate it. - // @TODO Is that a preferred handling ? We could also trying to re-use. - // can happen if user started log in but did not finish - for _, currentkey := range sNetwork.AccessKeys { - if currentkey.Name == name { - logger.Log(0, "erasing existing AccessKey for: ", name) - err = logic.DeleteKey(currentkey.Name, network) - if err != nil { - logger.Log(0, "err calling CreateAccessKey API ", err.Error()) - return "", fmt.Errorf("key already exists. Contact admin to resolve") - } - break - } - } - // Only one usage is needed - for the next time new access key will be required - // it will be created next time after another IdP approval - sAccessKey.Uses = 1 - sAccessKey.Name = name +// sNetwork, err = logic.GetParentNetwork(network) +// if err != nil { +// logger.Log(0, "err calling GetParentNetwork API=%s", err.Error()) +// return "", fmt.Errorf("internal controller error %s", err.Error()) +// } +// // If a key already exists, we recreate it. +// // @TODO Is that a preferred handling ? We could also trying to re-use. +// // can happen if user started log in but did not finish +// for _, currentkey := range sNetwork.AccessKeys { +// if currentkey.Name == name { +// logger.Log(0, "erasing existing AccessKey for: ", name) +// err = logic.DeleteKey(currentkey.Name, network) +// if err != nil { +// logger.Log(0, "err calling CreateAccessKey API ", err.Error()) +// return "", fmt.Errorf("key already exists. Contact admin to resolve") +// } +// break +// } +// } +// // Only one usage is needed - for the next time new access key will be required +// // it will be created next time after another IdP approval +// sAccessKey.Uses = 1 +// sAccessKey.Name = name - accessToken, err := logic.CreateAccessKey(sAccessKey, sNetwork) - if err != nil { - logger.Log(0, "err calling CreateAccessKey API ", err.Error()) - return "", fmt.Errorf("error from the netmaker controller %s", err.Error()) - } else { - logger.Log(1, "created access key", sAccessKey.Name, "on", network) - } - return accessToken.AccessString, nil -} +// accessToken, err := logic.CreateAccessKey(sAccessKey, sNetwork) +// if err != nil { +// logger.Log(0, "err calling CreateAccessKey API ", err.Error()) +// return "", fmt.Errorf("error from the netmaker controller %s", err.Error()) +// } else { +// logger.Log(1, "created access key", sAccessKey.Name, "on", network) +// } +// return accessToken.AccessString, nil +// } func isUserIsAllowed(username, network string, shouldAddUser bool) (*models.User, error) { diff --git a/auth/nodesession.go b/auth/nodesession.go index e82a87f8..cc4dd2b4 100644 --- a/auth/nodesession.go +++ b/auth/nodesession.go @@ -85,7 +85,7 @@ func SessionHandler(conn *websocket.Conn) { } return } - user, err := isUserIsAllowed(loginMessage.User, loginMessage.Network, false) + _, err = isUserIsAllowed(loginMessage.User, loginMessage.Network, false) if err != nil { err = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { @@ -93,12 +93,7 @@ func SessionHandler(conn *websocket.Conn) { } return } - accessToken, err := requestAccessKey(loginMessage.Network, 1, user.UserName) - if err != nil { - req.Pass = fmt.Sprintf("Error from the netmaker controller %s", err.Error()) - } else { - req.Pass = fmt.Sprintf("AccessToken: %s", accessToken) - } + // Give the user the access token via Pass in the DB if err = netcache.Set(stateStr, req); err != nil { logger.Log(0, "machine failed to complete join on network,", loginMessage.Network, "-", err.Error()) diff --git a/cli/cmd/keys/create.go b/cli/cmd/keys/create.go deleted file mode 100644 index 2c2c6149..00000000 --- a/cli/cmd/keys/create.go +++ /dev/null @@ -1,35 +0,0 @@ -package keys - -import ( - "log" - "strconv" - - "github.com/gravitl/netmaker/cli/functions" - "github.com/gravitl/netmaker/models" - "github.com/spf13/cobra" -) - -var keyName string - -var keysCreateCmd = &cobra.Command{ - Use: "create [NETWORK NAME] [NUM USES]", - Args: cobra.ExactArgs(2), - Short: "Create an access key", - Long: `Create an access key`, - Run: func(cmd *cobra.Command, args []string) { - keyUses, err := strconv.ParseInt(args[1], 10, 64) - if err != nil { - log.Fatal(err) - } - key := &models.AccessKey{Uses: int(keyUses)} - if keyName != "" { - key.Name = keyName - } - functions.PrettyPrint(functions.CreateKey(args[0], key)) - }, -} - -func init() { - keysCreateCmd.Flags().StringVar(&keyName, "name", "", "Name of the key") - rootCmd.AddCommand(keysCreateCmd) -} diff --git a/cli/cmd/keys/delete.go b/cli/cmd/keys/delete.go deleted file mode 100644 index ab8cd5b3..00000000 --- a/cli/cmd/keys/delete.go +++ /dev/null @@ -1,23 +0,0 @@ -package keys - -import ( - "fmt" - - "github.com/gravitl/netmaker/cli/functions" - "github.com/spf13/cobra" -) - -var keysDeleteCmd = &cobra.Command{ - Use: "delete [NETWORK NAME] [KEY NAME]", - Args: cobra.ExactArgs(2), - Short: "Delete a key", - Long: `Delete a key`, - Run: func(cmd *cobra.Command, args []string) { - functions.DeleteKey(args[0], args[1]) - fmt.Println("Success") - }, -} - -func init() { - rootCmd.AddCommand(keysDeleteCmd) -} diff --git a/cli/cmd/keys/list.go b/cli/cmd/keys/list.go deleted file mode 100644 index c1550017..00000000 --- a/cli/cmd/keys/list.go +++ /dev/null @@ -1,20 +0,0 @@ -package keys - -import ( - "github.com/gravitl/netmaker/cli/functions" - "github.com/spf13/cobra" -) - -var keysListCmd = &cobra.Command{ - Use: "list [NETWORK NAME]", - Args: cobra.ExactArgs(1), - Short: "List all keys associated with a network", - Long: `List all keys associated with a network`, - Run: func(cmd *cobra.Command, args []string) { - functions.PrettyPrint(functions.GetKeys(args[0])) - }, -} - -func init() { - rootCmd.AddCommand(keysListCmd) -} diff --git a/cli/cmd/keys/root.go b/cli/cmd/keys/root.go deleted file mode 100644 index 6d5761ce..00000000 --- a/cli/cmd/keys/root.go +++ /dev/null @@ -1,28 +0,0 @@ -package keys - -import ( - "os" - - "github.com/spf13/cobra" -) - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "keys", - Short: "Manage access keys associated with a network", - Long: `Manage access keys associated with a network`, -} - -// GetRoot returns the root subcommand -func GetRoot() *cobra.Command { - return rootCmd -} - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - err := rootCmd.Execute() - if err != nil { - os.Exit(1) - } -} diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 6b8a0c65..ff6c54f1 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -10,7 +10,6 @@ import ( "github.com/gravitl/netmaker/cli/cmd/enrollment_key" "github.com/gravitl/netmaker/cli/cmd/ext_client" "github.com/gravitl/netmaker/cli/cmd/host" - "github.com/gravitl/netmaker/cli/cmd/keys" "github.com/gravitl/netmaker/cli/cmd/metrics" "github.com/gravitl/netmaker/cli/cmd/network" "github.com/gravitl/netmaker/cli/cmd/network_user" @@ -47,7 +46,6 @@ func init() { // Bind subcommands here rootCmd.AddCommand(network.GetRoot()) rootCmd.AddCommand(context.GetRoot()) - rootCmd.AddCommand(keys.GetRoot()) rootCmd.AddCommand(acl.GetRoot()) rootCmd.AddCommand(node.GetRoot()) rootCmd.AddCommand(dns.GetRoot()) diff --git a/cli/functions/keys.go b/cli/functions/keys.go deleted file mode 100644 index 6a39b979..00000000 --- a/cli/functions/keys.go +++ /dev/null @@ -1,23 +0,0 @@ -package functions - -import ( - "fmt" - "net/http" - - "github.com/gravitl/netmaker/models" -) - -// GetKeys - fetch all access keys of a network -func GetKeys(networkName string) *[]models.AccessKey { - return request[[]models.AccessKey](http.MethodGet, fmt.Sprintf("/api/networks/%s/keys", networkName), nil) -} - -// CreateKey - create an access key -func CreateKey(networkName string, key *models.AccessKey) *models.AccessKey { - return request[models.AccessKey](http.MethodPost, fmt.Sprintf("/api/networks/%s/keys", networkName), key) -} - -// DeleteKey - delete an access key -func DeleteKey(networkName, keyName string) { - request[string](http.MethodDelete, fmt.Sprintf("/api/networks/%s/keys/%s", networkName, keyName), nil) -} diff --git a/controllers/docs.go b/controllers/docs.go index 36c02949..411fb395 100644 --- a/controllers/docs.go +++ b/controllers/docs.go @@ -203,27 +203,6 @@ type networkBodyResponse struct { Network models.Network `json:"network"` } -// swagger:parameters createAccessKey -type accessKeyBodyParam struct { - // Access Key - // in: body - AccessKey models.AccessKey `json:"access_key"` -} - -// swagger:response accessKeyBodyResponse -type accessKeyBodyResponse struct { - // Access Key - // in: body - AccessKey models.AccessKey `json:"access_key"` -} - -// swagger:response accessKeySliceBodyResponse -type accessKeySliceBodyResponse struct { - // Access Keys - // in: body - AccessKey []models.AccessKey `json:"access_key"` -} - // swagger:parameters updateNetworkACL getNetworkACL type aclContainerBodyParam struct { // ACL Container @@ -373,9 +352,6 @@ func useUnused() bool { _ = networkPathParam{} _ = networkAccessKeyNamePathParam{} _ = networkBodyResponse{} - _ = accessKeyBodyParam{} - _ = accessKeyBodyResponse{} - _ = accessKeySliceBodyResponse{} _ = aclContainerBodyParam{} _ = aclContainerResponse{} _ = nodeSliceResponse{} diff --git a/controllers/migrate.go b/controllers/migrate.go index 736a2a35..116df762 100644 --- a/controllers/migrate.go +++ b/controllers/migrate.go @@ -1,17 +1,7 @@ package controller import ( - "encoding/json" - "io" "net/http" - "strings" - - "github.com/gorilla/mux" - "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/logger" - "github.com/gravitl/netmaker/logic" - "github.com/gravitl/netmaker/models" - "golang.org/x/crypto/bcrypt" ) // swagger:route PUT /api/nodes/{network}/{nodeid}/migrate nodes migrateNode @@ -26,78 +16,79 @@ import ( // Responses: // 200: nodeJoinResponse func migrate(w http.ResponseWriter, r *http.Request) { + // TODO adapt with enrollment-keys or re-think how this works // we decode our body request params - data := models.MigrationData{} - err := json.NewDecoder(r.Body).Decode(&data) - if err != nil { - logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - params := mux.Vars(r) - //check authorization - record, err := database.FetchRecord(database.NODES_TABLE_NAME, data.LegacyNodeID) - if err != nil { - logger.Log(0, "no record for legacy node", data.LegacyNodeID, err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - var legacyNode models.LegacyNode - if err = json.Unmarshal([]byte(record), &legacyNode); err != nil { - logger.Log(0, "error decoding legacy node", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - if err := bcrypt.CompareHashAndPassword([]byte(legacyNode.Password), []byte(data.Password)); err != nil { - logger.Log(0, "error decoding legacy password", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "unauthorized")) - return - } - network, err := logic.GetNetwork(params["network"]) - if err != nil { - logger.Log(0, "error retrieving network: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - key, err := logic.CreateAccessKey(models.AccessKey{}, network) - if err != nil { - logger.Log(0, "error creating key: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - data.JoinData.Key = key.Value - payload, err := json.Marshal(data.JoinData) - if err != nil { - logger.Log(0, "error encoding data: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - r.Body = io.NopCloser(strings.NewReader(string(payload))) - r.ContentLength = int64(len(string(payload))) - logger.Log(3, "deleteing legacy node", data.LegacyNodeID, legacyNode.ID, legacyNode.Name) - if err := database.DeleteRecord(database.NODES_TABLE_NAME, data.LegacyNodeID); err != nil { - logger.Log(0, "error deleting legacy node", legacyNode.Name, err.Error()) - } - createNode(w, r) - //newly created node has same node id as legacy node allowing using legacyNode.ID in gateway creation - logger.Log(3, "re-creating legacy gateways") - if legacyNode.IsIngressGateway == "yes" { - if _, err := logic.CreateIngressGateway(legacyNode.Network, legacyNode.ID, false); err != nil { - logger.Log(0, "error creating ingress gateway during migration", err.Error()) - } - } - if legacyNode.IsEgressGateway == "yes" { - if _, err := logic.CreateEgressGateway(legacyNode.EgressGatewayRequest); err != nil { - logger.Log(0, "error creating egress gateway during migration", err.Error()) - } - } - if legacyNode.IsRelay == "yes" { - if _, _, err := logic.CreateRelay(models.RelayRequest{ - NodeID: legacyNode.ID, - NetID: legacyNode.Network, - RelayAddrs: legacyNode.RelayAddrs, - }); err != nil { - logger.Log(0, "error creating relay during migration", err.Error()) - } - } + // data := models.MigrationData{} + // err := json.NewDecoder(r.Body).Decode(&data) + // if err != nil { + // logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // params := mux.Vars(r) + // //check authorization + // record, err := database.FetchRecord(database.NODES_TABLE_NAME, data.LegacyNodeID) + // if err != nil { + // logger.Log(0, "no record for legacy node", data.LegacyNodeID, err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // var legacyNode models.LegacyNode + // if err = json.Unmarshal([]byte(record), &legacyNode); err != nil { + // logger.Log(0, "error decoding legacy node", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // if err := bcrypt.CompareHashAndPassword([]byte(legacyNode.Password), []byte(data.Password)); err != nil { + // logger.Log(0, "error decoding legacy password", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "unauthorized")) + // return + // } + // network, err := logic.GetNetwork(params["network"]) + // if err != nil { + // logger.Log(0, "error retrieving network: ", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // key, err := logic.CreateAccessKey(models.AccessKey{}, network) + // if err != nil { + // logger.Log(0, "error creating key: ", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // data.JoinData.Key = key.Value + // payload, err := json.Marshal(data.JoinData) + // if err != nil { + // logger.Log(0, "error encoding data: ", err.Error()) + // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + // return + // } + // r.Body = io.NopCloser(strings.NewReader(string(payload))) + // r.ContentLength = int64(len(string(payload))) + // logger.Log(3, "deleteing legacy node", data.LegacyNodeID, legacyNode.ID, legacyNode.Name) + // if err := database.DeleteRecord(database.NODES_TABLE_NAME, data.LegacyNodeID); err != nil { + // logger.Log(0, "error deleting legacy node", legacyNode.Name, err.Error()) + // } + // // createNode(w, r) should not have been tied to another handler func + // //newly created node has same node id as legacy node allowing using legacyNode.ID in gateway creation + // logger.Log(3, "re-creating legacy gateways") + // if legacyNode.IsIngressGateway == "yes" { + // if _, err := logic.CreateIngressGateway(legacyNode.Network, legacyNode.ID, false); err != nil { + // logger.Log(0, "error creating ingress gateway during migration", err.Error()) + // } + // } + // if legacyNode.IsEgressGateway == "yes" { + // if _, err := logic.CreateEgressGateway(legacyNode.EgressGatewayRequest); err != nil { + // logger.Log(0, "error creating egress gateway during migration", err.Error()) + // } + // } + // if legacyNode.IsRelay == "yes" { + // if _, _, err := logic.CreateRelay(models.RelayRequest{ + // NodeID: legacyNode.ID, + // NetID: legacyNode.Network, + // RelayAddrs: legacyNode.RelayAddrs, + // }); err != nil { + // logger.Log(0, "error creating relay during migration", err.Error()) + // } + // } } diff --git a/controllers/network.go b/controllers/network.go index bed8dbd0..8ab08a5b 100644 --- a/controllers/network.go +++ b/controllers/network.go @@ -25,9 +25,6 @@ func networkHandlers(r *mux.Router) { r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(false, http.HandlerFunc(updateNetwork))).Methods(http.MethodPut) r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).Methods(http.MethodDelete) r.HandleFunc("/api/networks/{networkname}/keyupdate", logic.SecurityCheck(true, http.HandlerFunc(keyUpdate))).Methods(http.MethodPost) - r.HandleFunc("/api/networks/{networkname}/keys", logic.SecurityCheck(false, http.HandlerFunc(createAccessKey))).Methods(http.MethodPost) - r.HandleFunc("/api/networks/{networkname}/keys", logic.SecurityCheck(false, http.HandlerFunc(getAccessKeys))).Methods(http.MethodGet) - r.HandleFunc("/api/networks/{networkname}/keys/{name}", logic.SecurityCheck(false, http.HandlerFunc(deleteAccessKey))).Methods(http.MethodDelete) // ACLs r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACL))).Methods(http.MethodPut) r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))).Methods(http.MethodGet) @@ -72,12 +69,6 @@ func getNetworks(w http.ResponseWriter, r *http.Request) { } } } - if !servercfg.IsDisplayKeys() { - for i, net := range allnetworks { - net.AccessKeys = logic.RemoveKeySensitiveInfo(net.AccessKeys) - allnetworks[i] = net - } - } logger.Log(2, r.Header.Get("user"), "fetched networks.") w.WriteHeader(http.StatusOK) @@ -107,9 +98,7 @@ func getNetwork(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } - if !servercfg.IsDisplayKeys() { - network.AccessKeys = logic.RemoveKeySensitiveInfo(network.AccessKeys) - } + logger.Log(2, r.Header.Get("user"), "fetched network", netname) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(network) @@ -426,117 +415,3 @@ func createNetwork(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(network) } - -// swagger:route POST /api/networks/{networkname}/keys networks createAccessKey -// -// Create a network access key. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: accessKeyBodyResponse -// -// BEGIN KEY MANAGEMENT SECTION -func createAccessKey(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var params = mux.Vars(r) - var accesskey models.AccessKey - // start here - netname := params["networkname"] - network, err := logic.GetParentNetwork(netname) - if err != nil { - logger.Log(0, r.Header.Get("user"), "failed to get network info: ", - err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - err = json.NewDecoder(r.Body).Decode(&accesskey) - if err != nil { - logger.Log(0, r.Header.Get("user"), "error decoding request body: ", - err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - key, err := logic.CreateAccessKey(accesskey, network) - if err != nil { - logger.Log(0, r.Header.Get("user"), "failed to create access key: ", - err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - - // do not allow access key creations view API with user names - if _, err = logic.GetUser(key.Name); err == nil { - logger.Log(0, "access key creation with invalid name attempted by", r.Header.Get("user")) - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("cannot create access key with user name"), "badrequest")) - logic.DeleteKey(key.Name, network.NetID) - return - } - - logger.Log(1, r.Header.Get("user"), "created access key", accesskey.Name, "on", netname) - w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(key) -} - -// swagger:route GET /api/networks/{networkname}/keys networks getAccessKeys -// -// Get network access keys for a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: accessKeySliceBodyResponse -func getAccessKeys(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var params = mux.Vars(r) - network := params["networkname"] - keys, err := logic.GetKeys(network) - if err != nil { - logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to get keys for network [%s]: %v", - network, err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - if !servercfg.IsDisplayKeys() { - keys = logic.RemoveKeySensitiveInfo(keys) - } - logger.Log(2, r.Header.Get("user"), "fetched access keys on network", network) - w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(keys) -} - -// swagger:route DELETE /api/networks/{networkname}/keys/{name} networks deleteAccessKey -// -// Delete a network access key. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: -// *: stringJSONResponse -// -// delete key. Has to do a little funky logic since it's not a collection item -func deleteAccessKey(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - var params = mux.Vars(r) - keyname := params["name"] - netname := params["networkname"] - err := logic.DeleteKey(keyname, netname) - if err != nil { - logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to delete key [%s] for network [%s]: %v", - keyname, netname, err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - logger.Log(1, r.Header.Get("user"), "deleted access key", keyname, "on network,", netname) - w.WriteHeader(http.StatusOK) -} diff --git a/controllers/network_test.go b/controllers/network_test.go index 0d19c7df..efb883f0 100644 --- a/controllers/network_test.go +++ b/controllers/network_test.go @@ -84,118 +84,6 @@ func TestDeleteNetwork(t *testing.T) { }) } -func TestCreateKey(t *testing.T) { - createNet() - keys, _ := logic.GetKeys("skynet") - for _, key := range keys { - logic.DeleteKey(key.Name, "skynet") - } - var accesskey models.AccessKey - var network models.Network - network.NetID = "skynet" - t.Run("NameTooLong", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Name = "ThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfailThisisareallylongkeynamethatwillfail" - _, err = logic.CreateAccessKey(accesskey, network) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag") - }) - t.Run("BlankName", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Name = "" - key, err := logic.CreateAccessKey(accesskey, network) - assert.Nil(t, err) - assert.NotEqual(t, "", key.Name) - }) - t.Run("InvalidValue", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Value = "bad-value" - _, err = logic.CreateAccessKey(accesskey, network) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Field validation for 'Value' failed on the 'alphanum' tag") - }) - t.Run("BlankValue", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Name = "mykey" - accesskey.Value = "" - key, err := logic.CreateAccessKey(accesskey, network) - assert.Nil(t, err) - assert.NotEqual(t, "", key.Value) - assert.Equal(t, accesskey.Name, key.Name) - }) - t.Run("ValueTooLong", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Name = "keyname" - accesskey.Value = "AccessKeyValuethatistoolong" - _, err = logic.CreateAccessKey(accesskey, network) - assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Field validation for 'Value' failed on the 'max' tag") - }) - t.Run("BlankUses", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Uses = 0 - accesskey.Value = "" - key, err := logic.CreateAccessKey(accesskey, network) - assert.Nil(t, err) - assert.Equal(t, 1, key.Uses) - }) - t.Run("DuplicateKey", func(t *testing.T) { - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - accesskey.Name = "mykey" - _, err = logic.CreateAccessKey(accesskey, network) - assert.NotNil(t, err) - assert.EqualError(t, err, "duplicate AccessKey Name") - }) -} - -func TestGetKeys(t *testing.T) { - deleteAllNetworks() - createNet() - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - var key models.AccessKey - key.Name = "mykey" - _, err = logic.CreateAccessKey(key, network) - assert.Nil(t, err) - t.Run("KeyExists", func(t *testing.T) { - keys, err := logic.GetKeys(network.NetID) - assert.Nil(t, err) - assert.NotEqual(t, models.AccessKey{}, keys) - }) - t.Run("NonExistantKey", func(t *testing.T) { - err := logic.DeleteKey("mykey", "skynet") - assert.Nil(t, err) - keys, err := logic.GetKeys(network.NetID) - assert.Nil(t, err) - assert.Equal(t, []models.AccessKey(nil), keys) - }) -} -func TestDeleteKey(t *testing.T) { - createNet() - network, err := logic.GetNetwork("skynet") - assert.Nil(t, err) - var key models.AccessKey - key.Name = "mykey" - _, err = logic.CreateAccessKey(key, network) - assert.Nil(t, err) - t.Run("ExistingKey", func(t *testing.T) { - err := logic.DeleteKey("mykey", "skynet") - assert.Nil(t, err) - }) - t.Run("NonExistantKey", func(t *testing.T) { - err := logic.DeleteKey("mykey", "skynet") - assert.NotNil(t, err) - assert.Equal(t, "key mykey does not exist", err.Error()) - }) -} - func TestSecurityCheck(t *testing.T) { //these seem to work but not sure it the tests are really testing the functionality diff --git a/controllers/node.go b/controllers/node.go index 9afde637..cb9d7cb2 100644 --- a/controllers/node.go +++ b/controllers/node.go @@ -3,7 +3,6 @@ package controller import ( "context" "encoding/json" - "errors" "fmt" "net/http" "strings" @@ -35,7 +34,6 @@ func nodeHandlers(r *mux.Router) { r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(false, http.HandlerFunc(createIngressGateway))).Methods(http.MethodPost) r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods(http.MethodDelete) r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, true, "node", http.HandlerFunc(updateNode))).Methods(http.MethodPost) - r.HandleFunc("/api/nodes/{network}", nodeauth(checkFreeTierLimits(node_l, http.HandlerFunc(createNode)))).Methods(http.MethodPost) r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost) } @@ -147,52 +145,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { response.Write(successJSONResponse) } -// auth middleware for api calls from nodes where node is has not yet joined the server (register, join) -func nodeauth(next http.Handler) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - bearerToken := r.Header.Get("Authorization") - var tokenSplit = strings.Split(bearerToken, " ") - var token = "" - if len(tokenSplit) < 2 { - errorResponse := models.ErrorResponse{ - Code: http.StatusUnauthorized, Message: "W1R3: You are unauthorized to access this endpoint.", - } - logic.ReturnErrorResponse(w, r, errorResponse) - return - } else { - token = tokenSplit[1] - } - found := false - networks, err := logic.GetNetworks() - if err != nil { - logger.Log(0, "no networks", err.Error()) - errorResponse := models.ErrorResponse{ - Code: http.StatusNotFound, Message: "no networks", - } - logic.ReturnErrorResponse(w, r, errorResponse) - return - } - for _, network := range networks { - for _, key := range network.AccessKeys { - if key.Value == token { - found = true - break - } - } - } - if !found { - logger.Log(0, "valid access key not found") - errorResponse := models.ErrorResponse{ - Code: http.StatusUnauthorized, Message: "You are unauthorized to access this endpoint.", - } - logic.ReturnErrorResponse(w, r, errorResponse) - return - } - - next.ServeHTTP(w, r) - } -} - // The middleware for most requests to the API // They all pass through here first // This will validate the JWT (or check for master token) @@ -462,218 +414,6 @@ func getNode(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(response) } -// swagger:route POST /api/nodes/{network} nodes createNode -// -// Create a node on a network. -// -// Schemes: https -// -// Security: -// oauth -// -// Responses: -// 200: nodeGetResponse -func createNode(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - - var params = mux.Vars(r) - - var errorResponse = models.ErrorResponse{ - Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.", - } - networkName := params["network"] - networkexists, err := logic.NetworkExists(networkName) - - if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to fetch network [%s] info: %v", networkName, err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } else if !networkexists { - errorResponse = models.ErrorResponse{ - Code: http.StatusNotFound, Message: "W1R3: Network does not exist! ", - } - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("network [%s] does not exist", networkName)) - logic.ReturnErrorResponse(w, r, errorResponse) - return - } - - //get data from body of request - data := models.JoinData{} - err = json.NewDecoder(r.Body).Decode(&data) - if err != nil { - logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - - if !logic.IsVersionComptatible(data.Host.Version) { - err := errors.New("incompatible netclient version") - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - - data.Node.Network = networkName - - networkSettings, err := logic.GetNetworkSettings(networkName) - if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to get network [%s] settings: %v", networkName, err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - data.Node.NetworkSettings(networkSettings) - keyName, validKey := logic.IsKeyValid(networkName, data.Key) - if !validKey { - errorResponse = models.ErrorResponse{ - Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.", - } - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to create node on network [%s]: %s", - data.Node.Network, errorResponse.Message)) - logic.ReturnErrorResponse(w, r, errorResponse) - return - } - logic.DecrimentKey(networkName, data.Key) - user, err := pro.GetNetworkUser(networkName, promodels.NetworkUserID(keyName)) - if err == nil { - if user.ID != "" { - logger.Log(1, "associating new node with user", keyName) - data.Node.OwnerID = string(user.ID) - } - } - - key, keyErr := logic.RetrievePublicTrafficKey() - if keyErr != nil { - logger.Log(0, "error retrieving key: ", keyErr.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - if key == nil { - logger.Log(0, "error: server traffic key is nil") - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - if data.Host.TrafficKeyPublic == nil { - logger.Log(0, "error: node traffic key is nil") - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - server := servercfg.GetServerInfo() - server.TrafficKey = key - data.Node.Server = servercfg.GetServer() - if !logic.HostExists(&data.Host) { - logic.CheckHostPorts(&data.Host) - if servercfg.GetBrokerType() == servercfg.EmqxBrokerType { - // create EMQX credentials for host if it doesn't exists - if err := mq.CreateEmqxUser(data.Host.ID.String(), data.Host.HostPass, false); err != nil { - logger.Log(0, "failed to add host credentials to EMQX: ", data.Host.ID.String(), err.Error()) - return - } - } - } - if err := logic.CreateHost(&data.Host); err != nil { - if errors.Is(err, logic.ErrHostExists) { - logger.Log(3, "host exists .. no need to create") - host, err := logic.GetHost(data.Host.ID.String()) - if err != nil { - logger.Log(0, r.Header.Get("user"), "failed to find host:", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - logic.UpdateHostFromClient(&data.Host, host) // update the in memory struct values - err = logic.UpsertHost(host) - if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to update host [ %s ]: %v", host.ID.String(), err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - data.Host = *host - } else { - logger.Log(0, "error creating host", err.Error()) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) - return - } - } - err = logic.AssociateNodeToHost(&data.Node, &data.Host) - if err != nil { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("failed to create node on network [%s]: %s", - networkName, err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - - // check if key belongs to a user - // if so add to their netuser data - // if it fails remove the node and fail request - if user != nil { - var updatedUserNode bool - user.Nodes = append(user.Nodes, data.Node.ID.String()) // add new node to user - if err = pro.UpdateNetworkUser(networkName, user); err == nil { - logger.Log(1, "added node", data.Node.ID.String(), data.Host.Name, "to user", string(user.ID)) - updatedUserNode = true - } - if !updatedUserNode { // user was found but not updated, so delete node - logger.Log(0, "failed to add node to user", keyName) - logic.DeleteNode(&data.Node, true) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - } - hostPeerUpdate, err := logic.GetPeerUpdateForHost(context.Background(), networkName, &data.Host, nil) - if err != nil && !database.IsEmptyRecord(err) { - logger.Log(0, r.Header.Get("user"), - fmt.Sprintf("error fetching wg peers config for host [ %s ]: %v", data.Host.ID.String(), err)) - logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - return - } - data.Host.HostPass = "" // client should not change password after join - // concealing hash - response := models.NodeJoinResponse{ - Node: data.Node, - ServerConfig: server, - Host: data.Host, - Peers: hostPeerUpdate.Peers, - } - logger.Log(1, r.Header.Get("user"), "created new node", data.Host.Name, data.Node.ID.String(), "on network", networkName) - w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(response) - - go func() { - if err := mq.PublishPeerUpdate(); err != nil { - logger.Log(1, "failed a peer update after creation of node", data.Host.Name) - } - }() - //runForceServerUpdate(&data.Node, true) - go func() { - dns := models.DNSUpdate{ - Action: models.DNSInsert, - Name: data.Host.Name + "." + data.Node.Network, - } - if data.Node.Address.IP != nil { - dns.Address = data.Node.Address.IP.String() - //publish new node dns entry to all nodes on network - if err := mq.PublishDNSUpdate(data.Node.Network, dns); err != nil { - logger.Log(1, "failed to publish dns update on node creation", err.Error()) - } - } - if data.Node.Address6.IP != nil { - dns.Address = data.Node.Address6.IP.String() - //publish new node dns entry to all nodes on network - if err := mq.PublishDNSUpdate(data.Node.Network, dns); err != nil { - logger.Log(1, "failed to publish dns update on node creation", err.Error()) - } - } - //publish add dns records for network to new node - if err := mq.PublishAllDNS(&data.Node); err != nil { - logger.Log(1, "failed to publish dns update on node creation", err.Error()) - } - }() -} - // == EGRESS == // swagger:route POST /api/nodes/{network}/{nodeid}/creategateway nodes createEgressGateway diff --git a/controllers/user.go b/controllers/user.go index 6a3cba5a..254ea806 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -467,5 +467,5 @@ func socketHandler(w http.ResponseWriter, r *http.Request) { return } // Start handling the session - go auth.SessionHandler(conn) + // go auth.SessionHandler(conn) } diff --git a/logic/accesskeys.go b/logic/accesskeys.go deleted file mode 100644 index 376d633f..00000000 --- a/logic/accesskeys.go +++ /dev/null @@ -1,229 +0,0 @@ -package logic - -import ( - "crypto/rand" - "encoding/base64" - "encoding/json" - "errors" - "math/big" - "strings" - "sync" - - validator "github.com/go-playground/validator/v10" - "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/logger" - "github.com/gravitl/netmaker/models" - "github.com/gravitl/netmaker/servercfg" -) - -// CreateAccessKey - create access key -func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models.AccessKey, error) { - - if accesskey.Name == "" { - accesskey.Name = genKeyName() - } - - if accesskey.Value == "" { - accesskey.Value = GenKey() - } - if accesskey.Uses == 0 { - accesskey.Uses = 1 - } - - checkkeys, err := GetKeys(network.NetID) - if err != nil { - return models.AccessKey{}, errors.New("could not retrieve network keys") - } - - for _, key := range checkkeys { - if key.Name == accesskey.Name { - return models.AccessKey{}, errors.New("duplicate AccessKey Name") - } - } - - netID := network.NetID - - var accessToken models.AccessToken - - accessToken.APIConnString = servercfg.GetAPIConnString() - accessToken.ClientConfig.Network = netID - accessToken.ClientConfig.Key = accesskey.Value - - tokenjson, err := json.Marshal(accessToken) - if err != nil { - return accesskey, err - } - - accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(tokenjson)) - - //validate accesskey - v := validator.New() - err = v.Struct(accesskey) - if err != nil { - for _, e := range err.(validator.ValidationErrors) { - logger.Log(1, "validator", e.Error()) - } - return models.AccessKey{}, err - } - - network.AccessKeys = append(network.AccessKeys, accesskey) - data, err := json.Marshal(&network) - if err != nil { - return models.AccessKey{}, err - } - if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil { - return models.AccessKey{}, err - } - - return accesskey, nil -} - -// DeleteKey - deletes a key -func DeleteKey(keyname, netname string) error { - network, err := GetParentNetwork(netname) - if err != nil { - return err - } - //basically, turn the list of access keys into the list of access keys before and after the item - //have not done any error handling for if there's like...1 item. I think it works? need to test. - found := false - var updatedKeys []models.AccessKey - for _, currentkey := range network.AccessKeys { - if currentkey.Name == keyname { - found = true - } else { - updatedKeys = append(updatedKeys, currentkey) - } - } - if !found { - return errors.New("key " + keyname + " does not exist") - } - network.AccessKeys = updatedKeys - data, err := json.Marshal(&network) - if err != nil { - return err - } - if err := database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil { - return err - } - - return nil -} - -// GetKeys - fetches keys for network -func GetKeys(net string) ([]models.AccessKey, error) { - - record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, net) - if err != nil { - return []models.AccessKey{}, err - } - network, err := ParseNetwork(record) - if err != nil { - return []models.AccessKey{}, err - } - return network.AccessKeys, nil -} - -// DecrimentKey - decriments key uses -func DecrimentKey(networkName string, keyvalue string) { - - var network models.Network - - network, err := GetParentNetwork(networkName) - if err != nil { - return - } - - for i := len(network.AccessKeys) - 1; i >= 0; i-- { - - currentkey := network.AccessKeys[i] - if currentkey.Value == keyvalue { - network.AccessKeys[i].Uses-- - if network.AccessKeys[i].Uses < 1 { - network.AccessKeys = append(network.AccessKeys[:i], - network.AccessKeys[i+1:]...) - break - } - } - } - - if newNetworkData, err := json.Marshal(&network); err != nil { - logger.Log(2, "failed to decrement key") - return - } else { - database.Insert(network.NetID, string(newNetworkData), database.NETWORKS_TABLE_NAME) - } -} - -// IsKeyValid - check if key is valid -func IsKeyValid(networkname string, keyvalue string) (string, bool) { - - network, err := GetParentNetwork(networkname) - if err != nil { - return "", false - } - accesskeys := network.AccessKeys - - var key models.AccessKey - foundkey := false - isvalid := false - - for i := len(accesskeys) - 1; i >= 0; i-- { - currentkey := accesskeys[i] - if currentkey.Value == keyvalue { - key = currentkey - foundkey = true - } - } - if foundkey { - if key.Uses > 0 { - isvalid = true - } - } - return key.Name, isvalid -} - -// RemoveKeySensitiveInfo - remove sensitive key info -func RemoveKeySensitiveInfo(keys []models.AccessKey) []models.AccessKey { - var returnKeys []models.AccessKey - for _, key := range keys { - key.Value = models.PLACEHOLDER_KEY_TEXT - key.AccessString = models.PLACEHOLDER_TOKEN_TEXT - returnKeys = append(returnKeys, key) - } - return returnKeys -} - -const ( - maxr string = "ff578f57c15bb743beaa77d27637e02b598dffa9aebd15889187fe6eb3bdca516c3fa1a52eabef31f33b4b8c2e5b5524f1aa4f3329393912f40dbbe23d7f39723e0be05b6696b11f8eea0abe365a11d9f2735ac7e5b4e015ab19b35b84893685b37a9a0a62a566d6571d7e00d4241687f5c804f37cde9bf311c0781f51cc007c5a01a94f6cfcecea640b8e9ab7bd43e73e5df5d0e1eeb4d9b6cc44be67b7cad80808b17869561b579ffe0bbdeca5c83139e458000000000000000000000000000000000000000000000000000000000000000" -) - -var ( - uno sync.Once - maxentropy *big.Int -) - -func init() { - uno.Do(func() { - maxentropy, _ = new(big.Int).SetString(maxr, 16) - }) -} - -// == private methods == - -func genKeyName() string { - entropy, _ := rand.Int(rand.Reader, maxentropy) - return strings.Join([]string{"key", entropy.Text(16)[:16]}, "-") -} - -// GenKey - generates random key of length 16 -func GenKey() string { - entropy, _ := rand.Int(rand.Reader, maxentropy) - return entropy.Text(16)[:16] -} - -// GenPassWord - generates random password of length 64 -func GenPassWord() string { - entropy, _ := rand.Int(rand.Reader, maxentropy) - return entropy.Text(62)[:64] -} diff --git a/logic/accesskeys_test.go b/logic/accesskeys_test.go deleted file mode 100644 index fe5443fc..00000000 --- a/logic/accesskeys_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package logic - -import "testing" - -func Test_genKeyName(t *testing.T) { - for i := 0; i < 100; i++ { - kname := genKeyName() - if len(kname) != 20 { - t.Fatalf("improper length of key name, expected 20 got :%d", len(kname)) - } - } -} - -func Test_genKey(t *testing.T) { - for i := 0; i < 100; i++ { - kname := GenKey() - if len(kname) != 16 { - t.Fatalf("improper length of key name, expected 16 got :%d", len(kname)) - } - } -} diff --git a/logic/networks.go b/logic/networks.go index 9f16c424..cb23d29b 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -159,7 +159,6 @@ func GetNetworkSettings(networkname string) (models.Network, error) { if err = json.Unmarshal([]byte(networkData), &network); err != nil { return models.Network{}, err } - network.AccessKeys = []models.AccessKey{} return network, nil } diff --git a/models/network.go b/models/network.go index 636e5355..87e9bfb1 100644 --- a/models/network.go +++ b/models/network.go @@ -19,7 +19,6 @@ type Network struct { NodeLimit int32 `json:"nodelimit" bson:"nodelimit"` DefaultPostDown string `json:"defaultpostdown" bson:"defaultpostdown"` DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"` - AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"` AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"` IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"` IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"` diff --git a/models/structs.go b/models/structs.go index f186484f..6d1215fb 100644 --- a/models/structs.go +++ b/models/structs.go @@ -2,7 +2,6 @@ package models import ( "strings" - "time" jwt "github.com/golang-jwt/jwt/v4" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" @@ -102,15 +101,6 @@ type SuccessResponse struct { Response interface{} } -// AccessKey - access key struct -type AccessKey struct { - Name string `json:"name" bson:"name" validate:"omitempty,max=345"` - Value string `json:"value" bson:"value" validate:"omitempty,alphanum,max=16"` - AccessString string `json:"accessstring" bson:"accessstring"` - Uses int `json:"uses" bson:"uses" validate:"numeric,min=0"` - Expiration *time.Time `json:"expiration" bson:"expiration"` -} - // DisplayKey - what is displayed for key type DisplayKey struct { Name string `json:"name" bson:"name"` From 0e9c549d1b487b0dbea4a8d92f1648659d135eb7 Mon Sep 17 00:00:00 2001 From: Anish Mukherjee Date: Thu, 16 Mar 2023 16:39:41 +0530 Subject: [PATCH 3/5] add server name to common topics --- mq/mq.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mq/mq.go b/mq/mq.go index b8e0d458..066927de 100644 --- a/mq/mq.go +++ b/mq/mq.go @@ -2,6 +2,7 @@ package mq import ( "context" + "fmt" "log" "time" @@ -53,23 +54,24 @@ func SetupMQTT() { opts := mqtt.NewClientOptions() setMqOptions(servercfg.GetMqUserName(), servercfg.GetMqPassword(), opts) opts.SetOnConnectHandler(func(client mqtt.Client) { - if token := client.Subscribe("ping/#", 2, mqtt.MessageHandler(Ping)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { + serverName := servercfg.GetServer() + if token := client.Subscribe(fmt.Sprintf("ping/%s/#", serverName), 2, mqtt.MessageHandler(Ping)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { client.Disconnect(240) logger.Log(0, "ping subscription failed") } - if token := client.Subscribe("update/#", 0, mqtt.MessageHandler(UpdateNode)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { + if token := client.Subscribe(fmt.Sprintf("update/%s/#", serverName), 0, mqtt.MessageHandler(UpdateNode)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { client.Disconnect(240) logger.Log(0, "node update subscription failed") } - if token := client.Subscribe("host/serverupdate/#", 0, mqtt.MessageHandler(UpdateHost)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { + if token := client.Subscribe(fmt.Sprintf("host/serverupdate/%s/#", serverName), 0, mqtt.MessageHandler(UpdateHost)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { client.Disconnect(240) logger.Log(0, "host update subscription failed") } - if token := client.Subscribe("signal/#", 0, mqtt.MessageHandler(ClientPeerUpdate)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { + if token := client.Subscribe(fmt.Sprintf("signal/%s/#", serverName), 0, mqtt.MessageHandler(ClientPeerUpdate)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { client.Disconnect(240) logger.Log(0, "node client subscription failed") } - if token := client.Subscribe("metrics/#", 0, mqtt.MessageHandler(UpdateMetrics)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { + if token := client.Subscribe(fmt.Sprintf("metrics/%s/#", serverName), 0, mqtt.MessageHandler(UpdateMetrics)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { client.Disconnect(240) logger.Log(0, "node metrics subscription failed") } From 796289a071f98be834dab548478b5b5a4004182d Mon Sep 17 00:00:00 2001 From: Matthew R Kasun Date: Mon, 20 Mar 2023 10:19:36 -0400 Subject: [PATCH 4/5] set default proxy mode to off --- compose/docker-compose-emqx.yml | 2 +- compose/docker-compose.ee.yml | 2 +- compose/docker-compose.reference.yml | 2 +- compose/docker-compose.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compose/docker-compose-emqx.yml b/compose/docker-compose-emqx.yml index d661f5eb..2522bf5a 100644 --- a/compose/docker-compose-emqx.yml +++ b/compose/docker-compose-emqx.yml @@ -30,7 +30,7 @@ services: VERBOSITY: "1" MQ_PASSWORD: "REPLACE_MQ_PASSWORD" MQ_USERNAME: "REPLACE_MQ_USERNAME" - DEFAULT_PROXY_MODE: "auto" + DEFAULT_PROXY_MODE: "off" ports: - "3478:3478/udp" netmaker-ui: diff --git a/compose/docker-compose.ee.yml b/compose/docker-compose.ee.yml index 9c5cc3fb..0417633d 100644 --- a/compose/docker-compose.ee.yml +++ b/compose/docker-compose.ee.yml @@ -33,7 +33,7 @@ services: METRICS_EXPORTER: "on" LICENSE_KEY: "YOUR_LICENSE_KEY" NETMAKER_ACCOUNT_ID: "YOUR_ACCOUNT_ID" - DEFAULT_PROXY_MODE: "auto" + DEFAULT_PROXY_MODE: "off" ports: - "3478:3478/udp" netmaker-ui: diff --git a/compose/docker-compose.reference.yml b/compose/docker-compose.reference.yml index 77cab1ce..17c9a5d0 100644 --- a/compose/docker-compose.reference.yml +++ b/compose/docker-compose.reference.yml @@ -38,7 +38,7 @@ services: FRONTEND_URL: "" # "https://dashboard." AZURE_TENANT: "" # "" OIDC_ISSUER: "" # https://oidc.yourprovider.com - URL of oidc provider - DEFAULT_PROXY_MODE: "auto" # if ON, all new clients will enable proxy by default if OFF, all new clients will disable proxy by default, if AUTO, stick with the existing logic for NAT detection + DEFAULT_PROXY_MODE: "off" # if ON, all new clients will enable proxy by default if OFF, all new clients will disable proxy by default, if AUTO, stick with the existing logic for NAT detection ports: - "3478:3478/udp" # the stun port netmaker-ui: # The Netmaker UI Component diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 9b1d7b49..d27ae1ef 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -28,7 +28,7 @@ services: MQ_PASSWORD: "REPLACE_MQ_PASSWORD" MQ_USERNAME: "REPLACE_MQ_USERNAME" STUN_PORT: "3478" - DEFAULT_PROXY_MODE: "auto" + DEFAULT_PROXY_MODE: "off" ports: - "3478:3478/udp" netmaker-ui: From 578609ff78b55db6a4a5081a9d76491615768609 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Mon, 20 Mar 2023 15:03:12 -0400 Subject: [PATCH 5/5] added legacy update --- logic/networks.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/logic/networks.go b/logic/networks.go index 65606ab5..0dd008e2 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -599,12 +599,11 @@ func networkNodesUpdateAction(networkName string, action string) error { return err } - for _, value := range collections { + for k, value := range collections { var node models.Node err := json.Unmarshal([]byte(value), &node) if err != nil { - if strings.Contains(err.Error(), "parsing time") { - // ignore legacy nodes + if IsLegacyNode(k) { // ignore legacy nodes continue } fmt.Println("error in node address assignment!")