mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 15:26:04 +08:00
refactoring validation and models
This commit is contained in:
parent
93b0b94788
commit
a982b62445
|
@ -1,4 +1,4 @@
|
|||
default k8scom tester textx comms {
|
||||
comms my-net one-more other-net {
|
||||
reload 15s
|
||||
hosts /root/dnsconfig/netmaker.hosts {
|
||||
fallthrough
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
10.10.0.12 node-nokdw.my-net
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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...")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue