From a982b62445db5a1e4d9591e783e3b5b32e64355d Mon Sep 17 00:00:00 2001 From: afeiszli Date: Fri, 23 Jul 2021 18:24:34 -0400 Subject: [PATCH] refactoring validation and models --- config/dnsconfig/Corefile | 2 +- config/dnsconfig/netmaker.hosts | 1 + controllers/common.go | 7 +- controllers/dnsHttpController.go | 4 +- controllers/networkHttpController.go | 236 +++--------------- controllers/networkHttpController_test.go | 10 +- controllers/nodeGrpcController.go | 39 +-- controllers/nodeHttpController.go | 42 ++-- controllers/userHttpController.go | 32 ++- database/database.go | 1 + functions/helpers.go | 81 ++----- models/network.go | 276 ++++++++++++++++------ models/node.go | 4 +- models/structs.go | 36 +-- serverctl/serverctl.go | 3 +- test/nodecreate.sh | 4 +- 16 files changed, 363 insertions(+), 415 deletions(-) diff --git a/config/dnsconfig/Corefile b/config/dnsconfig/Corefile index c1dbc014..a9e4e580 100644 --- a/config/dnsconfig/Corefile +++ b/config/dnsconfig/Corefile @@ -1,4 +1,4 @@ -default k8scom tester textx comms { +comms my-net one-more other-net { reload 15s hosts /root/dnsconfig/netmaker.hosts { fallthrough diff --git a/config/dnsconfig/netmaker.hosts b/config/dnsconfig/netmaker.hosts index e69de29b..5560dc89 100644 --- a/config/dnsconfig/netmaker.hosts +++ b/config/dnsconfig/netmaker.hosts @@ -0,0 +1 @@ +10.10.0.12 node-nokdw.my-net diff --git a/controllers/common.go b/controllers/common.go index 136293c9..20c856a4 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -54,6 +54,10 @@ func GetExtPeersList(networkName string, macaddress string) ([]models.ExtPeersRe var peer models.ExtPeersResponse var extClient models.ExtClient err = json.Unmarshal([]byte(value), &peer) + if err != nil { + functions.PrintUserLog("netmaker", "failed to unmarshal peer", 2) + continue + } err = json.Unmarshal([]byte(value), &extClient) if err != nil { functions.PrintUserLog("netmaker", "failed to unmarshal ext client", 2) @@ -193,16 +197,13 @@ func UpdateNode(nodechange models.NodeUpdate, node models.Node) (models.Node, er if err != nil { return models.Node{}, err } - err = database.Insert(newkey, string(value), database.NODES_TABLE_NAME) - if notifynetwork { err = SetNetworkNodesLastModified(node.Network) } if servercfg.IsDNSMode() { err = SetDNS() } - return node, err } diff --git a/controllers/dnsHttpController.go b/controllers/dnsHttpController.go index 5986ffaa..eb0fdd40 100644 --- a/controllers/dnsHttpController.go +++ b/controllers/dnsHttpController.go @@ -59,7 +59,7 @@ func getAllDNS(w http.ResponseWriter, r *http.Request) { func GetAllDNS() ([]models.DNSEntry, error) { var dns []models.DNSEntry - networks, err := functions.ListNetworks() + networks, err := models.GetNetworks() if err != nil { return []models.DNSEntry{}, err } @@ -141,7 +141,7 @@ func GetCustomDNS(network string) ([]models.DNSEntry, error) { func SetDNS() error { hostfile := txeh.Hosts{} var corefilestring string - networks, err := functions.ListNetworks() + networks, err := models.GetNetworks() if err != nil { return err } diff --git a/controllers/networkHttpController.go b/controllers/networkHttpController.go index 37ea5e92..5f785640 100644 --- a/controllers/networkHttpController.go +++ b/controllers/networkHttpController.go @@ -132,7 +132,7 @@ func getNetworks(w http.ResponseWriter, r *http.Request) { allnetworks := []models.Network{} err := errors.New("Networks Error") if networksSlice[0] == ALL_NETWORK_ACCESS { - allnetworks, err = functions.ListNetworks() + allnetworks, err = models.GetNetworks() if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -166,7 +166,7 @@ func RemoveComms(networks []models.Network) []models.Network { return append(returnable, networks[index+1:]...) } -func ValidateNetworkUpdate(network models.NetworkUpdate) error { +func ValidateNetworkUpdate(network models.Network) error { v := validator.New() _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool { @@ -177,71 +177,6 @@ func ValidateNetworkUpdate(network models.NetworkUpdate) error { return inCharSet }) - // _ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool { - // isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String()) - // return isvalid - // }) - //_ = v.RegisterValidation("addressrange6_valid", func(fl validator.FieldLevel) bool { - // isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String()) - // return isvalid - // }) - - // _ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool { - // isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String()) - // return isvalid - // }) - - // _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool { - // return true - // }) - - // _ = v.RegisterValidation("displayname_unique", func(fl validator.FieldLevel) bool { - // return true - // }) - - err := v.Struct(network) - - if err != nil { - for _, e := range err.(validator.ValidationErrors) { - fmt.Println(e) - } - } - return err -} - -func ValidateNetworkCreate(network models.Network) error { - - v := validator.New() - - // _ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool { - // isvalid := functions.IsIpCIDR(fl.Field().String()) - // return isvalid - // }) - _ = v.RegisterValidation("addressrange6_valid", func(fl validator.FieldLevel) bool { - isvalid := true - if *network.IsDualStack { - isvalid = functions.IsIpCIDR(fl.Field().String()) - } - return isvalid - }) - // - // _ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool { - // isvalid := fl.Field().String() == "" || functions.IsIpCIDR(fl.Field().String()) - // return isvalid - // }) - // - _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool { - isFieldUnique, _ := functions.IsNetworkNameUnique(fl.Field().String()) - inCharSet := functions.NameInNetworkCharSet(fl.Field().String()) - return isFieldUnique && inCharSet - }) - // - _ = v.RegisterValidation("displayname_valid", func(fl validator.FieldLevel) bool { - isFieldUnique, _ := functions.IsNetworkDisplayNameUnique(fl.Field().String()) - inCharSet := functions.NameInNetworkCharSet(fl.Field().String()) - return isFieldUnique && inCharSet - }) - err := v.Struct(network) if err != nil { @@ -341,33 +276,36 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) { return } - var networkChange models.NetworkUpdate - - _ = json.NewDecoder(r.Body).Decode(&networkChange) - if networkChange.AddressRange == "" { - networkChange.AddressRange = network.AddressRange - } - if networkChange.AddressRange6 == "" { - networkChange.AddressRange6 = network.AddressRange6 - } - if networkChange.NetID == "" { - networkChange.NetID = network.NetID - } - - err = ValidateNetworkUpdate(networkChange) - if err != nil { - returnErrorResponse(w, r, formatError(err, "badrequest")) - return - } - returnednetwork, err := UpdateNetwork(networkChange, network) + var newNetwork models.Network + err = json.NewDecoder(r.Body).Decode(&newNetwork) if err != nil { returnErrorResponse(w, r, formatError(err, "badrequest")) return } + rangeupdate, localrangeupdate, err := network.Update(&newNetwork) + if err != nil { + returnErrorResponse(w, r, formatError(err, "badrequest")) + return + } + + if rangeupdate { + err = functions.UpdateNetworkNodeAddresses(network.NetID) + if err != nil { + returnErrorResponse(w, r, formatError(err, "internal")) + return + } + } + if localrangeupdate { + err = functions.UpdateNetworkLocalAddresses(network.NetID) + if err != nil { + returnErrorResponse(w, r, formatError(err, "internal")) + return + } + } functions.PrintUserLog(r.Header.Get("user"), "updated network "+netname, 1) w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(returnednetwork) + json.NewEncoder(w).Encode(newNetwork) } func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) { @@ -381,7 +319,7 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) { return } - var networkChange models.NetworkUpdate + var networkChange models.Network _ = json.NewDecoder(r.Body).Decode(&networkChange) @@ -399,98 +337,6 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(network) } -func UpdateNetwork(networkChange models.NetworkUpdate, network models.Network) (models.Network, error) { - //NOTE: Network.NetID is intentionally NOT editable. It acts as a static ID for the network. - //DisplayName can be changed instead, which is what shows on the front end - if networkChange.NetID != network.NetID { - return models.Network{}, errors.New("NetID is not editable") - } - - haschange := false - hasrangeupdate := false - haslocalrangeupdate := false - - if networkChange.AddressRange != "" { - haschange = true - hasrangeupdate = true - network.AddressRange = networkChange.AddressRange - } - if networkChange.LocalRange != "" { - haschange = true - haslocalrangeupdate = true - network.LocalRange = networkChange.LocalRange - } - if networkChange.IsLocal != nil { - network.IsLocal = networkChange.IsLocal - } - if networkChange.IsDualStack != nil { - network.IsDualStack = networkChange.IsDualStack - } - if networkChange.DefaultListenPort != 0 { - network.DefaultListenPort = networkChange.DefaultListenPort - haschange = true - } - if networkChange.DefaultPostDown != "" { - network.DefaultPostDown = networkChange.DefaultPostDown - haschange = true - } - if networkChange.DefaultInterface != "" { - network.DefaultInterface = networkChange.DefaultInterface - haschange = true - } - if networkChange.DefaultPostUp != "" { - network.DefaultPostUp = networkChange.DefaultPostUp - haschange = true - } - if networkChange.DefaultKeepalive != 0 { - network.DefaultKeepalive = networkChange.DefaultKeepalive - haschange = true - } - if networkChange.DisplayName != "" { - network.DisplayName = networkChange.DisplayName - haschange = true - } - if networkChange.DefaultCheckInInterval != 0 { - network.DefaultCheckInInterval = networkChange.DefaultCheckInInterval - haschange = true - } - if networkChange.AllowManualSignUp != nil { - network.AllowManualSignUp = networkChange.AllowManualSignUp - haschange = true - } - - if haschange { - network.SetNetworkLastModified() - } - - data, err := json.Marshal(&network) - if err != nil { - return models.Network{}, err - } - - database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME) - - //Cycles through nodes and gives them new IP's based on the new range - //Pretty cool, but also pretty inefficient currently - if hasrangeupdate { - err = functions.UpdateNetworkNodeAddresses(network.NetID) - if err != nil { - return models.Network{}, err - } - } - if haslocalrangeupdate { - err = functions.UpdateNetworkLocalAddresses(network.NetID) - if err != nil { - return models.Network{}, err - } - } - returnnetwork, err := functions.GetParentNetwork(network.NetID) - if err != nil { - return models.Network{}, err - } - return returnnetwork, nil -} - //Delete a network //Will stop you if there's any nodes associated func deleteNetwork(w http.ResponseWriter, r *http.Request) { @@ -553,28 +399,18 @@ func createNetwork(w http.ResponseWriter, r *http.Request) { } func CreateNetwork(network models.Network) error { - //TODO: Not really doing good validation here. Same as createNode, updateNode, and updateNetwork - //Need to implement some better validation across the board - if network.IsLocal == nil { - falsevar := false - network.IsLocal = &falsevar - } - if network.IsDualStack == nil { - falsevar := false - network.IsDualStack = &falsevar - } - - err := ValidateNetworkCreate(network) - if err != nil { - //returnErrorResponse(w, r, formatError(err, "badrequest")) - return err - } network.SetDefaults() network.SetNodesLastModified() network.SetNetworkLastModified() network.KeyUpdateTimeStamp = time.Now().Unix() + err := network.Validate() + if err != nil { + //returnErrorResponse(w, r, formatError(err, "badrequest")) + return err + } + data, err := json.Marshal(&network) if err != nil { return err @@ -611,7 +447,7 @@ func createAccessKey(w http.ResponseWriter, r *http.Request) { returnErrorResponse(w, r, formatError(err, "badrequest")) return } - functions.PrintUserLog(r.Header.Get("user"), "created access key "+netname, 1) + functions.PrintUserLog(r.Header.Get("user"), "created access key "+accesskey.Name+" on "+netname, 1) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(key) //w.Write([]byte(accesskey.AccessString)) @@ -641,10 +477,8 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models } } privAddr := "" - if network.IsLocal != nil { - if *network.IsLocal { - privAddr = network.LocalRange - } + if network.IsLocal != "" { + privAddr = network.LocalRange } netID := network.NetID diff --git a/controllers/networkHttpController_test.go b/controllers/networkHttpController_test.go index e812a419..864f0be2 100644 --- a/controllers/networkHttpController_test.go +++ b/controllers/networkHttpController_test.go @@ -30,7 +30,7 @@ func deleteNet(t *testing.T) { err := DeleteDNS(entry.Name, entry.Network) assert.Nil(t, err) } - networks, _ := functions.ListNetworks() + networks, _ := models.GetNetworks() for _, network := range networks { t.Log("deleting network", network.NetID) success, err := DeleteNetwork(network.NetID) @@ -54,7 +54,7 @@ func getNet() models.Network { } func TestGetNetworks(t *testing.T) { - //calls functions.ListNetworks --- nothing to be done + //calls models.GetNetworks --- nothing to be done } func TestCreateNetwork(t *testing.T) { deleteNet(t) @@ -108,14 +108,14 @@ func TestUpdateNetwork(t *testing.T) { createNet() network := getNet() t.Run("NetID", func(t *testing.T) { - var networkupdate models.NetworkUpdate + var networkupdate models.Network networkupdate.NetID = "wirecat" _, err := UpdateNetwork(networkupdate, network) assert.NotNil(t, err) assert.Equal(t, "NetID is not editable", err.Error()) }) t.Run("LocalRange", func(t *testing.T) { - var networkupdate models.NetworkUpdate + var networkupdate models.Network //NetID needs to be set as it will be in updateNetwork networkupdate.NetID = "skynet" networkupdate.LocalRange = "192.168.0.1/24" @@ -372,7 +372,7 @@ func TestValidateNetworkUpdate(t *testing.T) { } for _, tc := range cases { t.Run(tc.testname, func(t *testing.T) { - network := models.NetworkUpdate(tc.network) + network := models.Network(tc.network) err := ValidateNetworkUpdate(network) assert.NotNil(t, err) assert.Contains(t, err.Error(), tc.errMessage) diff --git a/controllers/nodeGrpcController.go b/controllers/nodeGrpcController.go index b21e456d..74600577 100644 --- a/controllers/nodeGrpcController.go +++ b/controllers/nodeGrpcController.go @@ -34,14 +34,6 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe } */ // Cast to ReadNodeRes type - dualvar := false - if network.IsDualStack != nil { - dualvar = *network.IsDualStack - } - localvar := false - if network.IsLocal != nil { - localvar = *network.IsLocal - } response := &nodepb.ReadNodeRes{ Node: &nodepb.Node{ @@ -64,8 +56,8 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe Publickey: node.PublicKey, Listenport: node.ListenPort, Keepalive: node.PersistentKeepalive, - Islocal: localvar, - Isdualstack: dualvar, + Islocal: network.IsLocal == "yes", + Isdualstack: network.IsDualStack == "yes", Localrange: network.LocalRange, }, } @@ -165,7 +157,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo if !validKey { //Check to see if network will allow manual sign up //may want to switch this up with the valid key check and avoid a DB call that way. - if *network.AllowManualSignUp { + if network.AllowManualSignUp == "yes" { node.IsPending = true } else { return nil, status.Errorf( @@ -184,14 +176,6 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo fmt.Sprintf("Internal error: %v", err), ) } - dualvar := false - if network.IsDualStack != nil { - dualvar = *network.IsDualStack - } - localvar := false - if network.IsLocal != nil { - localvar = *network.IsLocal - } // return the node in a CreateNodeRes type response := &nodepb.CreateNodeRes{ @@ -210,8 +194,8 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo Publickey: node.PublicKey, Listenport: node.ListenPort, Keepalive: node.PersistentKeepalive, - Islocal: localvar, - Isdualstack: dualvar, + Islocal: network.IsLocal == "yes", + Isdualstack: network.IsDualStack == "yes", Localrange: network.LocalRange, }, } @@ -318,15 +302,6 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNo fmt.Sprintf("Could not find node with supplied Mac Address: %v", err), ) } - dualvar := false - if network.IsDualStack != nil { - dualvar = *network.IsDualStack - } - localvar := false - if network.IsLocal != nil { - localvar = *network.IsLocal - } - return &nodepb.UpdateNodeRes{ Node: &nodepb.Node{ Macaddress: newnode.MacAddress, @@ -345,8 +320,8 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNo Dnsoff: !servercfg.IsDNSMode(), Listenport: newnode.ListenPort, Keepalive: newnode.PersistentKeepalive, - Islocal: localvar, - Isdualstack: dualvar, + Islocal: network.IsLocal == "yes", + Isdualstack: network.IsDualStack == "yes", Localrange: network.LocalRange, }, }, nil diff --git a/controllers/nodeHttpController.go b/controllers/nodeHttpController.go index 3eb133ee..59fb70d5 100644 --- a/controllers/nodeHttpController.go +++ b/controllers/nodeHttpController.go @@ -17,17 +17,17 @@ import ( func nodeHandlers(r *mux.Router) { - r.HandleFunc("/api/nodes", authorize(false, "master", http.HandlerFunc(getAllNodes))).Methods("GET") + r.HandleFunc("/api/nodes", authorize(false, "user", http.HandlerFunc(getAllNodes))).Methods("GET") r.HandleFunc("/api/nodes/{network}", authorize(true, "network", http.HandlerFunc(getNetworkNodes))).Methods("GET") r.HandleFunc("/api/nodes/{network}/{macaddress}", authorize(true, "node", http.HandlerFunc(getNode))).Methods("GET") r.HandleFunc("/api/nodes/{network}/{macaddress}", authorize(true, "node", http.HandlerFunc(updateNode))).Methods("PUT") r.HandleFunc("/api/nodes/{network}/{macaddress}", authorize(true, "node", http.HandlerFunc(deleteNode))).Methods("DELETE") r.HandleFunc("/api/nodes/{network}/{macaddress}/checkin", authorize(true, "node", http.HandlerFunc(checkIn))).Methods("POST") - r.HandleFunc("/api/nodes/{network}/{macaddress}/creategateway", authorize(true, "master", http.HandlerFunc(createEgressGateway))).Methods("POST") - r.HandleFunc("/api/nodes/{network}/{macaddress}/deletegateway", authorize(true, "master", http.HandlerFunc(deleteEgressGateway))).Methods("DELETE") + r.HandleFunc("/api/nodes/{network}/{macaddress}/creategateway", authorize(true, "user", http.HandlerFunc(createEgressGateway))).Methods("POST") + r.HandleFunc("/api/nodes/{network}/{macaddress}/deletegateway", authorize(true, "user", http.HandlerFunc(deleteEgressGateway))).Methods("DELETE") r.HandleFunc("/api/nodes/{network}/{macaddress}/createingress", securityCheck(false, http.HandlerFunc(createIngressGateway))).Methods("POST") r.HandleFunc("/api/nodes/{network}/{macaddress}/deleteingress", securityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods("DELETE") - r.HandleFunc("/api/nodes/{network}/{macaddress}/approve", authorize(true, "master", http.HandlerFunc(uncordonNode))).Methods("POST") + r.HandleFunc("/api/nodes/{network}/{macaddress}/approve", authorize(true, "user", http.HandlerFunc(uncordonNode))).Methods("POST") r.HandleFunc("/api/nodes/{network}", createNode).Methods("POST") r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(true, "network", http.HandlerFunc(getLastModified))).Methods("GET") r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST") @@ -147,7 +147,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { //TODO: Consider better RBAC implementations func authorize(networkCheck bool, authNetwork string, next http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var errorResponse = models.ErrorResponse{ Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.", } @@ -155,7 +154,6 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha var params = mux.Vars(r) networkexists, _ := functions.NetworkExists(params["network"]) - //check that the request is for a valid network //if (networkCheck && !networkexists) || err != nil { if networkCheck && !networkexists { @@ -164,9 +162,7 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha } returnErrorResponse(w, r, errorResponse) return - } else { - w.Header().Set("Content-Type", "application/json") //get the auth token @@ -192,7 +188,6 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha //A: the token is the master password //B: the token corresponds to a mac address, and if so, which one //TODO: There's probably a better way of dealing with the "master token"/master password. Plz Halp. - var isAuthorized = false var macaddress = "" username, networks, isadmin, errN := functions.VerifyUserToken(authToken) @@ -219,7 +214,6 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha //The mastermac (login with masterkey from config) can do everything!! May be dangerous. if macaddress == "mastermac" { isAuthorized = true - //for everyone else, there's poor man's RBAC. The "cases" are defined in the routes in the handlers //So each route defines which access network should be allowed to access it } else { @@ -248,8 +242,8 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha } else { isAuthorized = (macaddress == params["macaddress"]) } - case "master": - isAuthorized = (macaddress == "mastermac") + case "user": + isAuthorized = true default: isAuthorized = false } @@ -316,7 +310,7 @@ func GetNetworkNodes(network string) ([]models.Node, error) { //Not quite sure if this is necessary. Probably necessary based on front end but may want to review after iteration 1 if it's being used or not func getAllNodes(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - nodes, err := functions.GetAllNodes() + nodes, err := getUsersNodes(r.Header.Get("user")) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -327,6 +321,22 @@ func getAllNodes(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(nodes) } +func getUsersNodes(username string) ([]models.Node, error) { + var nodes []models.Node + user, err := functions.GetUser(username) + if err != nil { + return nodes, err + } + for _, networkName := range user.Networks { + tmpNodes, err := GetNetworkNodes(networkName) + if err != nil { + continue + } + nodes = append(nodes, tmpNodes...) + } + return nodes, err +} + //This function get's called when a node "checks in" at check in interval //Honestly I'm not sure what all it should be doing //TODO: Implement the necessary stuff, including the below @@ -460,7 +470,7 @@ func createNode(w http.ResponseWriter, r *http.Request) { if !validKey { //Check to see if network will allow manual sign up //may want to switch this up with the valid key check and avoid a DB call that way. - if *network.AllowManualSignUp { + if network.AllowManualSignUp == "yes" { node.IsPending = true } else { errorResponse = models.ErrorResponse{ @@ -678,6 +688,7 @@ func CreateIngressGateway(netid string, macaddress string) (models.Node, error) log.Println("Could not find network.") return models.Node{}, err } + node.IsIngressGateway = true node.IngressGatewayRange = network.AddressRange postUpCmd := "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A POSTROUTING -o " + node.Interface + " -j MASQUERADE" postDownCmd := "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE" @@ -748,6 +759,7 @@ func DeleteIngressGateway(network, macaddress string) (models.Node, error) { } func updateNode(w http.ResponseWriter, r *http.Request) { + log.Println("update reached.") w.Header().Set("Content-Type", "application/json") var params = mux.Vars(r) @@ -756,7 +768,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) { //id, _ := primitive.ObjectIDFromHex(params["id"]) var node models.Node - + log.Println("Called", params["network"], params["macaddress"]) //start here node, err := functions.GetNodeByMacAddress(params["network"], params["macaddress"]) if err != nil { diff --git a/controllers/userHttpController.go b/controllers/userHttpController.go index 70409dfc..cc587f03 100644 --- a/controllers/userHttpController.go +++ b/controllers/userHttpController.go @@ -152,7 +152,6 @@ func authorizeUserAdm(next http.Handler) http.HandlerFunc { func ValidateUserToken(token string, user string, adminonly bool) error { var tokenSplit = strings.Split(token, " ") - //I put this in in case the user doesn't put in a token at all (in which case it's empty) //There's probably a smarter way of handling this. var authToken = "928rt238tghgwe@TY@$Y@#WQAEGB2FC#@HG#@$Hddd" @@ -213,7 +212,20 @@ func hasAdmin(w http.ResponseWriter, r *http.Request) { } -func GetUser(username string) (models.User, error) { +func GetUser(username string) (models.ReturnUser, error) { + + var user models.ReturnUser + record, err := database.FetchRecord(database.USERS_TABLE_NAME, username) + if err != nil { + return user, err + } + if err = json.Unmarshal([]byte(record), &user); err != nil { + return models.ReturnUser{}, err + } + return user, err +} + +func GetUserInternal(username string) (models.User, error) { var user models.User record, err := database.FetchRecord(database.USERS_TABLE_NAME, username) @@ -226,9 +238,9 @@ func GetUser(username string) (models.User, error) { return user, err } -func GetUsers() ([]models.User, error) { +func GetUsers() ([]models.ReturnUser, error) { - var users []models.User + var users []models.ReturnUser collection, err := database.FetchRecords(database.USERS_TABLE_NAME) @@ -238,7 +250,7 @@ func GetUsers() ([]models.User, error) { for _, value := range collection { - var user models.User + var user models.ReturnUser err = json.Unmarshal([]byte(value), &user) if err != nil { continue // get users @@ -394,7 +406,7 @@ func updateUser(w http.ResponseWriter, r *http.Request) { var user models.User //start here username := params["username"] - user, err := GetUser(username) + user, err := GetUserInternal(username) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -422,7 +434,7 @@ func updateUserAdm(w http.ResponseWriter, r *http.Request) { var user models.User //start here username := params["username"] - user, err := GetUser(username) + user, err := GetUserInternal(username) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -445,6 +457,10 @@ func updateUserAdm(w http.ResponseWriter, r *http.Request) { func DeleteUser(user string) (bool, error) { + if userRecord, err := database.FetchRecord(database.USERS_TABLE_NAME, user); err != nil || len(userRecord) == 0 { + return false, errors.New("user does not exist") + } + err := database.DeleteRecord(database.USERS_TABLE_NAME, user) if err != nil { return false, err @@ -466,7 +482,7 @@ func deleteUser(w http.ResponseWriter, r *http.Request) { returnErrorResponse(w, r, formatError(err, "internal")) return } else if !success { - returnErrorResponse(w, r, formatError(errors.New("Delete unsuccessful."), "badrequest")) + returnErrorResponse(w, r, formatError(errors.New("delete unsuccessful."), "badrequest")) return } diff --git a/database/database.go b/database/database.go index 1811ac26..07f18dd6 100644 --- a/database/database.go +++ b/database/database.go @@ -93,5 +93,6 @@ func FetchRecords(tableName string) (map[string]string, error) { row.Scan(&key, &value) records[key] = value } + // log.Println(records) return records, nil } diff --git a/functions/helpers.go b/functions/helpers.go index e9c27f5e..b1a85da7 100644 --- a/functions/helpers.go +++ b/functions/helpers.go @@ -54,6 +54,19 @@ func ParseIntClient(value string) (models.IntClient, error) { //Takes in an arbitrary field and value for field and checks to see if any other //node has that value for the same field within the network +func GetUser(username string) (models.User, error) { + + var user models.User + record, err := database.FetchRecord(database.USERS_TABLE_NAME, username) + if err != nil { + return user, err + } + if err = json.Unmarshal([]byte(record), &user); err != nil { + return models.User{}, err + } + return user, err +} + func SliceContains(slice []string, item string) bool { set := make(map[string]struct{}, len(slice)) for _, s := range slice { @@ -252,32 +265,11 @@ func UpdateNetworkLocalAddresses(networkName string) error { return nil } -//Checks to see if any other networks have the same name (id) -func IsNetworkNameUnique(name string) (bool, error) { - - isunique := true - - dbs, err := ListNetworks() - - if err != nil { - return false, err - } - - for i := 0; i < len(dbs); i++ { - - if name == dbs[i].NetID { - isunique = false - } - } - - return isunique, nil -} - func IsNetworkDisplayNameUnique(name string) (bool, error) { isunique := true - dbs, err := ListNetworks() + dbs, err := models.GetNetworks() if err != nil { return false, err } @@ -333,30 +325,6 @@ func GetNetworkNodeNumber(networkName string) (int, error) { return count, nil } -// Anyway, returns all the networks -func ListNetworks() ([]models.Network, error) { - - var networks []models.Network - - collection, err := database.FetchRecords(database.NETWORKS_TABLE_NAME) - - if err != nil { - return networks, err - } - - for _, value := range collection { - - var network models.Network - if err := json.Unmarshal([]byte(value), &network); err != nil { - return networks, err - } - // add network our array - networks = append(networks, network) - } - - return networks, err -} - //Checks to see if access key is valid //Does so by checking against all keys and seeing if any have the same value //may want to hash values before comparing...consider this @@ -385,7 +353,7 @@ func IsKeyValid(networkname string, keyvalue string) bool { func IsKeyValidGlobal(keyvalue string) bool { - networks, _ := ListNetworks() + networks, _ := models.GetNetworks() var key models.AccessKey foundkey := false isvalid := false @@ -499,20 +467,21 @@ func GetNodeByMacAddress(network string, macaddress string) (models.Node, error) var node models.Node - records, err := database.FetchRecords(database.NODES_TABLE_NAME) - + key, err := GetRecordKey(macaddress, network) if err != nil { return node, err } - for _, value := range records { - json.Unmarshal([]byte(value), &node) - if node.MacAddress == macaddress && node.Network == network { - return node, nil - } + record, err := database.FetchRecord(database.NODES_TABLE_NAME, key) + if err != nil { + return models.Node{}, err } - return models.Node{}, nil + if err = json.Unmarshal([]byte(record), &node); err != nil { + return models.Node{}, err + } + + return node, nil } func DeleteAllIntClients() error { @@ -614,7 +583,7 @@ func UniqueAddress6(networkName string) (string, error) { fmt.Println("Network Not Found") return "", err } - if network.IsDualStack == nil || *network.IsDualStack == false { + if network.IsDualStack == "no" { if networkName != "comms" { return "", nil } diff --git a/models/network.go b/models/network.go index e60a6b3e..7036f129 100644 --- a/models/network.go +++ b/models/network.go @@ -1,73 +1,183 @@ package models import ( + "encoding/json" + "errors" + "strings" "time" - "go.mongodb.org/mongo-driver/bson/primitive" + "github.com/go-playground/validator/v10" + "github.com/gravitl/netmaker/database" ) //Network Struct //At some point, need to replace all instances of Name with something else like Identifier type Network struct { - ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"` - AddressRange string `json:"addressrange" bson:"addressrange" validate:"required,cidr"` - // bug in validator --- required_with does not work with bools issue#683 - // AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"required_with=isdualstack true,cidrv6"` - AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"addressrange6_valid"` - //can't have min=1 with omitempty - DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,min=1,max=20,displayname_valid"` - NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"` - NodesLastModified int64 `json:"nodeslastmodified" bson:"nodeslastmodified"` - NetworkLastModified int64 `json:"networklastmodified" bson:"networklastmodified"` - DefaultInterface string `json:"defaultinterface" bson:"defaultinterface"` - DefaultListenPort int32 `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"` - NodeLimit int32 `json:"nodelimit" bson:"nodelimit"` - DefaultPostUp string `json:"defaultpostup" bson:"defaultpostup"` - DefaultPostDown string `json:"defaultpostdown" bson:"defaultpostdown"` - KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"` - DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"` - DefaultSaveConfig *bool `json:"defaultsaveconfig" bson:"defaultsaveconfig"` - AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"` - AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"` - IsLocal *bool `json:"islocal" bson:"islocal"` - IsDualStack *bool `json:"isdualstack" bson:"isdualstack"` - IsIPv4 string `json:"isipv4" bson:"isipv4"` - IsIPv6 string `json:"isipv6" bson:"isipv6"` - IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub"` - LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"` - //can't have min=1 with omitempty - DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"` + AddressRange string `json:"addressrange" bson:"addressrange" validate:"required,cidr"` + AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"regexp=^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$"` + DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,min=1,max=20,displayname_valid"` + NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"` + NodesLastModified int64 `json:"nodeslastmodified" bson:"nodeslastmodified"` + NetworkLastModified int64 `json:"networklastmodified" bson:"networklastmodified"` + DefaultInterface string `json:"defaultinterface" bson:"defaultinterface" validate:"min=1,max=15"` + DefaultListenPort int32 `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"` + NodeLimit int32 `json:"nodelimit" bson:"nodelimit"` + DefaultPostUp string `json:"defaultpostup" bson:"defaultpostup"` + DefaultPostDown string `json:"defaultpostdown" bson:"defaultpostdown"` + KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"` + DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"` + DefaultSaveConfig string `json:"defaultsaveconfig" bson:"defaultsaveconfig" validate:"regexp=^(yes|no)$"` + AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"` + AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"regexp=^(yes|no)$"` + IsLocal string `json:"islocal" bson:"islocal" validate:"regexp=^(yes|no)$"` + IsDualStack string `json:"isdualstack" bson:"isdualstack" validate:"regexp=^(yes|no)$"` + IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"regexp=^(yes|no)$"` + IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"regexp=^(yes|no)$"` + IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub" validate:"regexp=^(yes|no)$"` + LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"` + DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"` + DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"regexp=^(yes|no)$"` } -type NetworkUpdate struct { - ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"` - AddressRange string `json:"addressrange" bson:"addressrange" validate:"omitempty,cidr"` - // bug in validator --- required_with does not work with bools issue#683 - // AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"required_with=isdualstack true,cidrv6"` - AddressRange6 string `json:"addressrange6" bson:"addressrange6" validate:"omitempty,cidr"` - //can't have min=1 with omitempty - DisplayName string `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,netid_valid,min=1,max=20"` - NetID string `json:"netid" bson:"netid" validate:"omitempty,netid_valid,min=1,max=15"` - NodesLastModified int64 `json:"nodeslastmodified" bson:"nodeslastmodified"` - NetworkLastModified int64 `json:"networklastmodified" bson:"networklastmodified"` - DefaultInterface string `json:"defaultinterface" bson:"defaultinterface"` - DefaultListenPort int32 `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"` - NodeLimit int32 `json:"nodelimit" bson:"nodelimit"` - DefaultPostUp string `json:"defaultpostup" bson:"defaultpostup"` - DefaultPostDown string `json:"defaultpostdown" bson:"defaultpostdown"` - KeyUpdateTimeStamp int64 `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"` - DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"` - DefaultSaveConfig *bool `json:"defaultsaveconfig" bson:"defaultsaveconfig"` - AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"` - AllowManualSignUp *bool `json:"allowmanualsignup" bson:"allowmanualsignup"` - IsLocal *bool `json:"islocal" bson:"islocal"` - IsDualStack *bool `json:"isdualstack" bson:"isdualstack"` - IsIPv4 string `json:"isipv4" bson:"isipv4"` - IsIPv6 string `json:"isipv6" bson:"isipv6"` - IsGRPCHub string `json:"isgrpchub" bson:"isgrpchub"` - LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"` - //can't have min=1 with omitempty - DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"` +type SaveData struct { // put sensitive fields here + NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"` +} + +var FIELDS = map[string][]string{ + // "id": {"ID", "string"}, + "addressrange": {"AddressRange", "string"}, + "addressrange6": {"AddressRange6", "string"}, + "displayname": {"DisplayName", "string"}, + "netid": {"NetID", "string"}, + "nodeslastmodified": {"NodesLastModified", "int64"}, + "networklastmodified": {"NetworkLastModified", "int64"}, + "defaultinterface": {"DefaultInterface", "string"}, + "defaultlistenport": {"DefaultListenPort", "int32"}, + "nodelimit": {"NodeLimit", "int32"}, + "defaultpostup": {"DefaultPostUp", "string"}, + "defaultpostdown": {"DefaultPostDown", "string"}, + "keyupdatetimestamp": {"KeyUpdateTimeStamp", "int64"}, + "defaultkeepalive": {"DefaultKeepalive", "int32"}, + "defaultsaveconfig": {"DefaultSaveConfig", "string"}, + "accesskeys": {"AccessKeys", "[]AccessKey"}, + "allowmanualsignup": {"AllowManualSignUp", "string"}, + "islocal": {"IsLocal", "string"}, + "isdualstack": {"IsDualStack", "string"}, + "isipv4": {"IsIPv4", "string"}, + "isipv6": {"IsIPv6", "string"}, + "isgrpchub": {"IsGRPCHub", "string"}, + "localrange": {"LocalRange", "string"}, + "checkininterval": {"DefaultCheckInInterval", "int32"}, + "defaultudpholepunch": {"DefaultUDPHolePunch", "string"}, +} + +func (network *Network) FieldExists(field string) bool { + return len(FIELDS[field]) > 0 +} + +func (network *Network) NetIDInNetworkCharSet() bool { + + charset := "abcdefghijklmnopqrstuvwxyz1234567890-_." + + for _, char := range network.NetID { + if !strings.Contains(charset, strings.ToLower(string(char))) { + return false + } + } + return true +} + +func (network *Network) DisplayNameInNetworkCharSet() bool { + + charset := "abcdefghijklmnopqrstuvwxyz1234567890-_./;% ^#()!@$*" + + for _, char := range network.DisplayName { + if !strings.Contains(charset, strings.ToLower(string(char))) { + return false + } + } + return true +} + +// Anyway, returns all the networks +func GetNetworks() ([]Network, error) { + var networks []Network + + collection, err := database.FetchRecords(database.NETWORKS_TABLE_NAME) + + if err != nil { + return networks, err + } + + for _, value := range collection { + var network Network + if err := json.Unmarshal([]byte(value), &network); err != nil { + return networks, err + } + // add network our array + networks = append(networks, network) + } + + return networks, err +} + +func (network *Network) IsNetworkDisplayNameUnique() (bool, error) { + + isunique := true + + records, err := GetNetworks() + + if err != nil { + return false, err + } + + for i := 0; i < len(records); i++ { + + if network.NetID == records[i].DisplayName { + isunique = false + } + } + + return isunique, nil +} + +//Checks to see if any other networks have the same name (id) +func (network *Network) IsNetworkNameUnique() (bool, error) { + + isunique := true + + dbs, err := GetNetworks() + + if err != nil { + return false, err + } + + for i := 0; i < len(dbs); i++ { + + if network.NetID == dbs[i].NetID { + isunique = false + } + } + + return isunique, nil +} + +func (network *Network) Validate() error { + v := validator.New() + _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool { + isFieldUnique, _ := network.IsNetworkNameUnique() + inCharSet := network.NetIDInNetworkCharSet() + return isFieldUnique && inCharSet + }) + // + _ = v.RegisterValidation("displayname_valid", func(fl validator.FieldLevel) bool { + isFieldUnique, _ := network.IsNetworkDisplayNameUnique() + inCharSet := network.DisplayNameInNetworkCharSet() + return isFieldUnique && inCharSet + }) + + err := v.Struct(network) + return err } //TODO: @@ -81,6 +191,15 @@ func (network *Network) SetNetworkLastModified() { } func (network *Network) SetDefaults() { + if network.DefaultUDPHolePunch == "" { + network.DefaultUDPHolePunch = "yes" + } + if network.IsLocal == "" { + network.IsLocal = "no" + } + if network.IsGRPCHub == "" { + network.IsGRPCHub = "no" + } if network.DisplayName == "" { network.DisplayName = network.NetID } @@ -97,31 +216,46 @@ func (network *Network) SetDefaults() { if network.NodeLimit == 0 { network.NodeLimit = 999999999 } - if network.DefaultPostDown == "" { - - } - if network.DefaultSaveConfig == nil { - defaultsave := true - network.DefaultSaveConfig = &defaultsave + if network.DefaultSaveConfig == "" { + network.DefaultSaveConfig = "no" } if network.DefaultKeepalive == 0 { network.DefaultKeepalive = 20 } - if network.DefaultPostUp == "" { - } //Check-In Interval for Nodes, In Seconds if network.DefaultCheckInInterval == 0 { network.DefaultCheckInInterval = 30 } - if network.AllowManualSignUp == nil { - signup := false - network.AllowManualSignUp = &signup + if network.AllowManualSignUp == "" { + network.AllowManualSignUp = "no" } - if (network.IsDualStack != nil) && *network.IsDualStack { + if network.IsDualStack == "" { + network.IsDualStack = "no" + } + if network.IsDualStack == "yes" { network.IsIPv6 = "yes" network.IsIPv4 = "yes" - } else if network.IsGRPCHub != "yes" { + } else { network.IsIPv6 = "no" network.IsIPv4 = "yes" } } + +func (currentNetwork *Network) Update(newNetwork *Network) (bool, bool, error) { + if err := newNetwork.Validate(); err != nil { + return false, false, err + } + if newNetwork.NetID == currentNetwork.NetID { + hasrangeupdate := newNetwork.AddressRange != currentNetwork.AddressRange + localrangeupdate := newNetwork.LocalRange != currentNetwork.LocalRange + if data, err := json.Marshal(newNetwork); err != nil { + return false, false, err + } else { + newNetwork.SetNetworkLastModified() + err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME) + return hasrangeupdate, localrangeupdate, err + } + } + // copy values + return false, false, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.") +} diff --git a/models/node.go b/models/node.go index 927579e1..322df7da 100644 --- a/models/node.go +++ b/models/node.go @@ -145,8 +145,8 @@ func (node *Node) SetDefaults() { //TODO: This is dumb and doesn't work //Need to change if node.SaveConfig == nil { - if parentNetwork.DefaultSaveConfig != nil { - defaultsave := *parentNetwork.DefaultSaveConfig + if parentNetwork.DefaultSaveConfig != "" { + defaultsave := parentNetwork.DefaultSaveConfig == "yes" node.SaveConfig = &defaultsave } } diff --git a/models/structs.go b/models/structs.go index b4603a1a..00258331 100644 --- a/models/structs.go +++ b/models/structs.go @@ -8,10 +8,16 @@ type AuthParams struct { } type User struct { - UserName string `json:"username" bson:"username" validate:"min=3,max=40,regexp=^(([a-zA-Z,\-,\.]*)|([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})){3,40}$"` - Password string `json:"password" bson:"password" validate:"required,min=5"` + UserName string `json:"username" bson:"username" validate:"min=3,max=40,regexp=^(([a-zA-Z,\-,\.]*)|([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})){3,40}$"` + Password string `json:"password" bson:"password" validate:"required,min=5"` Networks []string `json:"networks" bson:"networks"` - IsAdmin bool `json:"isadmin" bson:"isadmin"` + IsAdmin bool `json:"isadmin" bson:"isadmin"` +} + +type ReturnUser struct { + UserName string `json:"username" bson:"username" validate:"min=3,max=40,regexp=^(([a-zA-Z,\-,\.]*)|([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})){3,40}$"` + Networks []string `json:"networks" bson:"networks"` + IsAdmin bool `json:"isadmin" bson:"isadmin"` } type UserAuthParams struct { @@ -92,27 +98,27 @@ type CheckInResponse struct { } type PeersResponse struct { + PublicKey string `json:"publickey" bson:"publickey"` + Endpoint string `json:"endpoint" bson:"endpoint"` + Address string `json:"address" bson:"address"` + Address6 string `json:"address6" bson:"address6"` + LocalAddress string `json:"localaddress" bson:"localaddress"` + IsEgressGateway bool `json:"isegressgateway" bson:"isegressgateway"` + EgressGatewayRange string `json:"egressgatewayrange" bson:"egressgatewayrange"` + ListenPort int32 `json:"listenport" bson:"listenport"` + KeepAlive int32 `json:"persistentkeepalive" bson:"persistentkeepalive"` +} + +type ExtPeersResponse struct { PublicKey string `json:"publickey" bson:"publickey"` Endpoint string `json:"endpoint" bson:"endpoint"` Address string `json:"address" bson:"address"` Address6 string `json:"address6" bson:"address6"` LocalAddress string `json:"localaddress" bson:"localaddress"` - IsEgressGateway bool `json:"isegressgateway" bson:"isegressgateway"` - EgressGatewayRange string `json:"egressgatewayrange" bson:"egressgatewayrange"` ListenPort int32 `json:"listenport" bson:"listenport"` KeepAlive int32 `json:"persistentkeepalive" bson:"persistentkeepalive"` } -type ExtPeersResponse struct { - PublicKey string `json:"publickey" bson:"publickey"` - Endpoint string `json:"endpoint" bson:"endpoint"` - Address string `json:"address" bson:"address"` - Address6 string `json:"address6" bson:"address6"` - LocalAddress string `json:"localaddress" bson:"localaddress"` - ListenPort int32 `json:"listenport" bson:"listenport"` - KeepAlive int32 `json:"persistentkeepalive" bson:"persistentkeepalive"` -} - type EgressGatewayRequest struct { NodeID string `json:"nodeid" bson:"nodeid"` NetID string `json:"netid" bson:"netid"` diff --git a/serverctl/serverctl.go b/serverctl/serverctl.go index fa9f12c1..e9957085 100644 --- a/serverctl/serverctl.go +++ b/serverctl/serverctl.go @@ -51,8 +51,7 @@ func CreateCommsNetwork() (bool, error) { network.SetNodesLastModified() network.SetNetworkLastModified() network.KeyUpdateTimeStamp = time.Now().Unix() - priv := false - network.IsLocal = &priv + network.IsLocal = "no" network.KeyUpdateTimeStamp = time.Now().Unix() log.Println("Creating comms network...") diff --git a/test/nodecreate.sh b/test/nodecreate.sh index 421f31d1..da92a507 100755 --- a/test/nodecreate.sh +++ b/test/nodecreate.sh @@ -3,7 +3,7 @@ PUBKEY="DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=" IPADDR="69.173.21.202" MACADDRESS="59:2a:9c:d4:e2:49" -ACCESSKEY="I6Pc8UFlszO1MWh3" +ACCESSKEY="q5VHqUmamqsfgnpy" PASSWORD="ppppppp" generate_post_json () @@ -22,5 +22,5 @@ EOF POST_JSON=$(generate_post_json) -curl --max-time 5.0 -d "$POST_JSON" -H 'Content-Type: application/json' -H "authorization: Bearer secretkey" localhost:8081/api/nodes/hello +curl --max-time 5.0 -d "$POST_JSON" -H 'Content-Type: application/json' -H "authorization: Bearer secretkey" localhost:8081/api/nodes/my-net