mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-06 17:29:15 +08:00
add validation for node.Address
This commit is contained in:
@@ -62,6 +62,11 @@ func ValidateNode(operation string, networkName string, node models.Node) error
|
||||
|
||||
v := validator.New()
|
||||
|
||||
_ = v.RegisterValidation("address_check", func(fl validator.FieldLevel) bool {
|
||||
isIpv4 := functions.IsIpv4Net(node.Address)
|
||||
notEmptyCheck := node.Address != ""
|
||||
return (notEmptyCheck && isIpv4)
|
||||
})
|
||||
_ = v.RegisterValidation("endpoint_check", func(fl validator.FieldLevel) bool {
|
||||
//var isFieldUnique bool = functions.IsFieldUnique(networkName, "endpoint", node.Endpoint)
|
||||
isIpv4 := functions.IsIpv4Net(node.Endpoint)
|
||||
@@ -193,6 +198,7 @@ func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
|
||||
// prepare update model.
|
||||
update := bson.D{
|
||||
{"$set", bson.D{
|
||||
{"address", node.Address},
|
||||
{"name", node.Name},
|
||||
{"password", node.Password},
|
||||
{"listenport", node.ListenPort},
|
||||
@@ -212,7 +218,6 @@ func UpdateNode(nodechange models.Node, node models.Node) (models.Node, error) {
|
||||
}},
|
||||
}
|
||||
var nodeupdate models.Node
|
||||
|
||||
errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
|
||||
if errN != nil {
|
||||
return nodeupdate, errN
|
||||
|
@@ -765,7 +765,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
|
||||
if nodechange.MacAddress == "" {
|
||||
nodechange.MacAddress = node.MacAddress
|
||||
}
|
||||
|
||||
err = ValidateNode("update", params["network"], nodechange)
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "badrequest"))
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"math/rand"
|
||||
"time"
|
||||
"net"
|
||||
"context"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
@@ -18,7 +19,7 @@ var seededRand *rand.Rand = rand.New(
|
||||
//node struct
|
||||
type Node struct {
|
||||
ID primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
|
||||
Address string `json:"address" bson:"address"`
|
||||
Address string `json:"address" bson:"address" validate:"address_check"`
|
||||
LocalAddress string `json:"localaddress" bson:"localaddress" validate:"localaddress_check"`
|
||||
Name string `json:"name" bson:"name" validate:"omitempty,name_valid,max=12"`
|
||||
ListenPort int32 `json:"listenport" bson:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
|
||||
@@ -46,10 +47,9 @@ type Node struct {
|
||||
PostChanges string `json:"postchanges" bson:"postchanges"`
|
||||
}
|
||||
|
||||
|
||||
//TODO: Contains a fatal error return. Need to change
|
||||
//Used in contexts where it's not the Parent network.
|
||||
func(node *Node) GetNetwork() (Network, error){
|
||||
func (node *Node) GetNetwork() (Network, error) {
|
||||
|
||||
var network Network
|
||||
|
||||
@@ -71,27 +71,25 @@ func(node *Node) GetNetwork() (Network, error){
|
||||
return network, err
|
||||
}
|
||||
|
||||
|
||||
//TODO:
|
||||
//Not sure if below two methods are necessary. May want to revisit
|
||||
func(node *Node) SetLastModified(){
|
||||
func (node *Node) SetLastModified() {
|
||||
node.LastModified = time.Now().Unix()
|
||||
}
|
||||
|
||||
func(node *Node) SetLastCheckIn(){
|
||||
func (node *Node) SetLastCheckIn() {
|
||||
node.LastCheckIn = time.Now().Unix()
|
||||
}
|
||||
|
||||
func(node *Node) SetLastPeerUpdate(){
|
||||
func (node *Node) SetLastPeerUpdate() {
|
||||
node.LastPeerUpdate = time.Now().Unix()
|
||||
}
|
||||
|
||||
func(node *Node) SetExpirationDateTime(){
|
||||
func (node *Node) SetExpirationDateTime() {
|
||||
node.ExpirationDateTime = time.Unix(33174902665, 0).Unix()
|
||||
}
|
||||
|
||||
|
||||
func(node *Node) SetDefaultName(){
|
||||
func (node *Node) SetDefaultName() {
|
||||
if node.Name == "" {
|
||||
nodeid := StringWithCharset(5, charset)
|
||||
nodename := "node-" + nodeid
|
||||
@@ -101,7 +99,7 @@ func(node *Node) SetDefaultName(){
|
||||
|
||||
//TODO: I dont know why this exists
|
||||
//This should exist on the node.go struct. I'm sure there was a reason?
|
||||
func(node *Node) SetDefaults() {
|
||||
func (node *Node) SetDefaults() {
|
||||
|
||||
//TODO: Maybe I should make Network a part of the node struct. Then we can just query the Network object for stuff.
|
||||
parentNetwork, _ := node.GetNetwork()
|
||||
@@ -149,4 +147,3 @@ func StringWithCharset(length int, charset string) string {
|
||||
func IsIpv4Net(host string) bool {
|
||||
return net.ParseIP(host) != nil
|
||||
}
|
||||
|
||||
|
@@ -17,11 +17,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type databaseError struct {
|
||||
Inner *int
|
||||
Errors int
|
||||
}
|
||||
|
||||
//should be use models.SuccessResponse and models.SuccessfulUserLoginResponse
|
||||
//rather than creating new type but having trouble decoding that way
|
||||
type Auth struct {
|
||||
@@ -96,7 +91,6 @@ func api(t *testing.T, data interface{}, method, url, authorization string) (*ht
|
||||
request.Header.Set("authorization", "Bearer "+authorization)
|
||||
}
|
||||
client := http.Client{}
|
||||
//t.Log("api request", request)
|
||||
return client.Do(request)
|
||||
}
|
||||
|
||||
@@ -198,28 +192,6 @@ func deleteKey(t *testing.T, key, network string) {
|
||||
//assert.Equal(t, int64(1), message.DeletedCount)
|
||||
}
|
||||
|
||||
func networkExists(t *testing.T) bool {
|
||||
response, err := api(t, "", http.MethodGet, baseURL+"/api/networks", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
defer response.Body.Close()
|
||||
assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
err = json.NewDecoder(response.Body).Decode(&Networks)
|
||||
assert.Nil(t, err, err)
|
||||
for i, network := range Networks {
|
||||
t.Log(i, network)
|
||||
if network.NetID == "" {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestJunk(t *testing.T) {
|
||||
deleteNetworks(t)
|
||||
}
|
||||
|
||||
func deleteNetworks(t *testing.T) {
|
||||
//delete all node
|
||||
deleteAllNodes(t)
|
||||
@@ -237,21 +209,6 @@ func deleteNetworks(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getNetworkNodes(t *testing.T) []models.ReturnNode {
|
||||
var nodes []models.ReturnNode
|
||||
//var node models.ReturnNode
|
||||
//response, err := api(t, "", http.MethodGet, baseURL+"/api/nodes/skynet", "secretkey")
|
||||
//assert.Nil(t, err, err)
|
||||
//assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
//defer response.Body.Close()
|
||||
//err = json.NewDecoder(response.Body).Decode(&nodes)
|
||||
//assert.Nil(t, err, err)
|
||||
//for _, nodes := range nodes {
|
||||
// nodes = append(nodes, node)
|
||||
//}
|
||||
return nodes
|
||||
}
|
||||
|
||||
func deleteNode(t *testing.T) {
|
||||
response, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
@@ -273,6 +230,7 @@ func deleteAllNodes(t *testing.T) {
|
||||
func createNode(t *testing.T) {
|
||||
var node models.Node
|
||||
key := createAccessKey(t)
|
||||
node.Address = "10.71.0.1"
|
||||
node.AccessKey = key.Value
|
||||
node.MacAddress = "01:02:03:04:05:06"
|
||||
node.Name = "myNode"
|
||||
@@ -296,6 +254,17 @@ func getNode(t *testing.T) models.Node {
|
||||
return node
|
||||
}
|
||||
|
||||
func getNetwork(t *testing.T, network string) models.Network {
|
||||
var net models.Network
|
||||
response, err := api(t, "", http.MethodGet, baseURL+"/api/networks/"+network, "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
defer response.Body.Close()
|
||||
err = json.NewDecoder(response.Body).Decode(&net)
|
||||
assert.Nil(t, err, err)
|
||||
return net
|
||||
}
|
||||
|
||||
func setup(t *testing.T) {
|
||||
deleteNetworks(t)
|
||||
createNetwork(t)
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -15,9 +16,7 @@ func TestCreateNetwork(t *testing.T) {
|
||||
network := models.Network{}
|
||||
network.NetID = "skynet"
|
||||
network.AddressRange = "10.71.0.0/16"
|
||||
if networkExists(t) {
|
||||
deleteNetworks(t)
|
||||
}
|
||||
t.Run("InvalidToken", func(t *testing.T) {
|
||||
response, err := api(t, network, http.MethodPost, baseURL+"/api/networks", "badkey")
|
||||
assert.Nil(t, err, err)
|
||||
@@ -140,8 +139,6 @@ func TestDeleteNetwork(t *testing.T) {
|
||||
})
|
||||
t.Run("NodesExist", func(t *testing.T) {
|
||||
setup(t)
|
||||
node := getNode(t)
|
||||
t.Log(node)
|
||||
response, err := api(t, "", http.MethodDelete, baseURL+"/api/networks/skynet", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusForbidden, response.StatusCode)
|
||||
@@ -523,7 +520,7 @@ func TestUpdateNetwork(t *testing.T) {
|
||||
DefaultKeepAlive int32
|
||||
}
|
||||
var network Network
|
||||
network.DefaultKeepAlive = 1001
|
||||
network.DefaultKeepAlive = 2000
|
||||
response, err := api(t, network, http.MethodPut, baseURL+"/api/networks/skynet", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
var message models.ErrorResponse
|
||||
@@ -534,21 +531,26 @@ func TestUpdateNetwork(t *testing.T) {
|
||||
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
|
||||
})
|
||||
t.Run("UpdateSaveConfig", func(t *testing.T) {
|
||||
t.Skip()
|
||||
//does not appear to be updatable
|
||||
//t.Skip()
|
||||
//not updatable, ensure attempt to change does not result in change
|
||||
type Network struct {
|
||||
DefaultSaveConfig *bool
|
||||
}
|
||||
var network Network
|
||||
value := false
|
||||
var value bool
|
||||
oldnet := getNetwork(t, "skynet")
|
||||
if *oldnet.DefaultSaveConfig == true {
|
||||
value = false
|
||||
} else {
|
||||
value = true
|
||||
}
|
||||
|
||||
network.DefaultSaveConfig = &value
|
||||
response, err := api(t, network, http.MethodPut, baseURL+"/api/networks/skynet", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
defer response.Body.Close()
|
||||
err = json.NewDecoder(response.Body).Decode(&returnedNetwork)
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, *network.DefaultSaveConfig, *returnedNetwork.DefaultSaveConfig)
|
||||
newnet := getNetwork(t, "skynet")
|
||||
assert.Equal(t, oldnet.DefaultSaveConfig, newnet.DefaultSaveConfig)
|
||||
})
|
||||
t.Run("UpdateManualSignUP", func(t *testing.T) {
|
||||
type Network struct {
|
||||
@@ -612,3 +614,15 @@ func TestUpdateNetwork(t *testing.T) {
|
||||
assert.Equal(t, network.DefaultListenPort, returnedNetwork.DefaultListenPort)
|
||||
})
|
||||
}
|
||||
|
||||
func TestKeyUpdate(t *testing.T) {
|
||||
//get current network settings
|
||||
oldnet := getNetwork(t, "skynet")
|
||||
//update key
|
||||
time.Sleep(time.Second * 1)
|
||||
reply, err := api(t, "", http.MethodPost, baseURL+"/api/networks/skynet/keyupdate", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusOK, reply.StatusCode)
|
||||
newnet := getNetwork(t, "skynet")
|
||||
assert.Greater(t, newnet.KeyUpdateTimeStamp, oldnet.KeyUpdateTimeStamp)
|
||||
}
|
@@ -104,6 +104,7 @@ func TestUpdateNode(t *testing.T) {
|
||||
setup(t)
|
||||
|
||||
t.Run("UpdateMulti", func(t *testing.T) {
|
||||
data.Address = "10.1.0.2"
|
||||
data.MacAddress = "01:02:03:04:05:05"
|
||||
data.Name = "NewName"
|
||||
data.PublicKey = "DM5qhLAE20PG9BbfBCgfr+Ac9D2NDOwCtY1rbYDLf34="
|
||||
@@ -115,7 +116,6 @@ func TestUpdateNode(t *testing.T) {
|
||||
assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
defer response.Body.Close()
|
||||
var node models.Node
|
||||
t.Log(response.Body)
|
||||
err = json.NewDecoder(response.Body).Decode(&node)
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, data.Name, node.Name)
|
||||
@@ -125,6 +125,19 @@ func TestUpdateNode(t *testing.T) {
|
||||
assert.Equal(t, data.LocalAddress, node.LocalAddress)
|
||||
assert.Equal(t, data.Endpoint, node.Endpoint)
|
||||
})
|
||||
t.Run("InvalidAddress", func(t *testing.T) {
|
||||
data.Address = "10.300.2.0"
|
||||
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusBadRequest, response.StatusCode)
|
||||
var message models.ErrorResponse
|
||||
defer response.Body.Close()
|
||||
err = json.NewDecoder(response.Body).Decode(&message)
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, http.StatusBadRequest, message.Code)
|
||||
assert.Contains(t, message.Message, "Field validation for 'Address' failed")
|
||||
})
|
||||
|
||||
t.Run("InvalidMacAddress", func(t *testing.T) {
|
||||
data.MacAddress = "10:11:12:13:14:15:16"
|
||||
response, err := api(t, data, http.MethodPut, baseURL+"/api/nodes/skynet/01:02:03:04:05:05", "secretkey")
|
||||
@@ -226,7 +239,6 @@ func TestDeleteNode(t *testing.T) {
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, "01:02:03:04:05:06 deleted.", message.Message)
|
||||
assert.Equal(t, http.StatusOK, message.Code)
|
||||
t.Log(response.Header.Get("Content-Type"))
|
||||
})
|
||||
t.Run("NonExistantNode", func(t *testing.T) {
|
||||
response, err := api(t, "", http.MethodDelete, baseURL+"/api/nodes/skynet/01:02:03:04:05:06", "secretkey")
|
||||
@@ -335,7 +347,6 @@ func TestUncordonNode(t *testing.T) {
|
||||
err = json.NewDecoder(response.Body).Decode(&message)
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, "SUCCESS", message)
|
||||
t.Log(message, string(message))
|
||||
}
|
||||
|
||||
func TestCreateNode(t *testing.T) {
|
||||
@@ -525,9 +536,7 @@ func TestCreateNode(t *testing.T) {
|
||||
err = json.NewDecoder(response.Body).Decode(&message)
|
||||
assert.Nil(t, err, err)
|
||||
assert.Equal(t, node.Name, message.Name)
|
||||
t.Log(message)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestGetLastModified(t *testing.T) {
|
||||
|
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@@ -28,8 +27,6 @@ func TestAdminCreation(t *testing.T) {
|
||||
assert.Equal(t, true, user.IsAdmin)
|
||||
assert.Equal(t, http.StatusOK, response.StatusCode)
|
||||
assert.True(t, adminExists(t), "Admin creation failed")
|
||||
message, _ := ioutil.ReadAll(response.Body)
|
||||
t.Log(string(message))
|
||||
})
|
||||
t.Run("AdminCreationFailure", func(t *testing.T) {
|
||||
if !adminExists(t) {
|
||||
@@ -50,10 +47,7 @@ func TestAdminCreation(t *testing.T) {
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
if !adminExists(t) {
|
||||
t.Log("no admin - creating")
|
||||
addAdmin(t)
|
||||
} else {
|
||||
t.Log("admin exists")
|
||||
}
|
||||
t.Run("GetUserWithValidToken", func(t *testing.T) {
|
||||
token, err := authenticate(t)
|
||||
|
Reference in New Issue
Block a user