optimize further

This commit is contained in:
0xdcarns 2021-12-10 21:09:42 -05:00
parent e45a485bce
commit 548997f9ef
18 changed files with 61 additions and 100 deletions

View file

@ -103,7 +103,7 @@ func grpcAuthorize(ctx context.Context) error {
return nil return nil
} }
//Node authenticates using its password and retrieves a JWT for authorization. // Login - node authenticates using its password and retrieves a JWT for authorization.
func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) { func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
//out := new(LoginResponse) //out := new(LoginResponse)
@ -117,15 +117,15 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod
password := reqNode.Password password := reqNode.Password
var result models.NodeAuth var result models.NodeAuth
var err error
err := errors.New("Generic server error.") // err := errors.New("generic server error")
if macaddress == "" { if macaddress == "" {
//TODO: Set Error response //TODO: Set Error response
err = errors.New("Missing Mac Address.") err = errors.New("missing mac address")
return nil, err return nil, err
} else if password == "" { } else if password == "" {
err = errors.New("Missing Password.") err = errors.New("missing password")
return nil, err return nil, err
} else { } else {
//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved). //Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
@ -156,7 +156,7 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod
return nil, err return nil, err
} }
if tokenString == "" { if tokenString == "" {
err = errors.New("Something went wrong. Could not retrieve token.") err = errors.New("something went wrong, could not retrieve token")
return nil, err return nil, err
} }

View file

@ -55,7 +55,7 @@ func TestGetNodeDNS(t *testing.T) {
}) })
t.Run("MultipleNodes", func(t *testing.T) { t.Run("MultipleNodes", func(t *testing.T) {
createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.100.100.3", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet"} createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.100.100.3", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet"}
_, err := logic.CreateNode(createnode, "skynet") err := logic.CreateNode(createnode)
assert.Nil(t, err) assert.Nil(t, err)
dns, err := logic.GetNodeDNS("skynet") dns, err := logic.GetNodeDNS("skynet")
assert.Nil(t, err) assert.Nil(t, err)

View file

@ -232,8 +232,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
} }
err = logic.CreateExtClient(extclient) err = logic.CreateExtClient(&extclient)
if err != nil { if err != nil {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
@ -264,7 +263,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
} }
newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], oldExtClient) newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], &oldExtClient)
if err != nil { if err != nil {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return

View file

@ -350,8 +350,3 @@ func createNet() {
logic.CreateNetwork(network) logic.CreateNetwork(network)
} }
} }
func getNet() models.Network {
network, _ := logic.GetNetwork("skynet")
return network
}

View file

@ -35,20 +35,17 @@ func nodeHandlers(r *mux.Router) {
} }
//Node authenticates using its password and retrieves a JWT for authorization.
func authenticate(response http.ResponseWriter, request *http.Request) { func authenticate(response http.ResponseWriter, request *http.Request) {
var params = mux.Vars(request) var params = mux.Vars(request)
networkname := params["network"] networkname := params["network"]
//Auth request consists of Mac Address and Password (from node that is authorizing
//in case of Master, auth is ignored and mac is set to "mastermac"
var authRequest models.AuthParams var authRequest models.AuthParams
var result models.Node var result models.Node
var errorResponse = models.ErrorResponse{ var errorResponse = models.ErrorResponse{
Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.", Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
} }
//Get password fnd mac rom request
decoder := json.NewDecoder(request.Body) decoder := json.NewDecoder(request.Body)
decoderErr := decoder.Decode(&authRequest) decoderErr := decoder.Decode(&authRequest)
defer request.Body.Close() defer request.Body.Close()
@ -70,7 +67,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
return return
} else { } else {
//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
collection, err := database.FetchRecords(database.NODES_TABLE_NAME) collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
if err != nil { if err != nil {
errorResponse.Code = http.StatusBadRequest errorResponse.Code = http.StatusBadRequest
@ -94,9 +90,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
return return
} }
//compare password from request to stored password in database
//might be able to have a common hash (certificates?) and compare those so that a password isn't passed in in plain text...
//TODO: Consider a way of hashing the password client side before sending, or using certificates
err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password)) err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
if err != nil { if err != nil {
errorResponse.Code = http.StatusBadRequest errorResponse.Code = http.StatusBadRequest
@ -104,7 +97,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
returnErrorResponse(response, request, errorResponse) returnErrorResponse(response, request, errorResponse)
return return
} else { } else {
//Create a new JWT for the node
tokenString, _ := logic.CreateJWT(authRequest.MacAddress, result.Network) tokenString, _ := logic.CreateJWT(authRequest.MacAddress, result.Network)
if tokenString == "" { if tokenString == "" {
@ -122,7 +114,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
MacAddress: authRequest.MacAddress, MacAddress: authRequest.MacAddress,
}, },
} }
//Send back the JWT
successJSONResponse, jsonError := json.Marshal(successResponse) successJSONResponse, jsonError := json.Marshal(successResponse)
if jsonError != nil { if jsonError != nil {
@ -185,10 +176,6 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha
return return
} }
//This checks if
//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 Help.
var isAuthorized = false var isAuthorized = false
var macaddress = "" var macaddress = ""
username, networks, isadmin, errN := logic.VerifyUserToken(authToken) username, networks, isadmin, errN := logic.VerifyUserToken(authToken)
@ -379,10 +366,10 @@ func createNode(w http.ResponseWriter, r *http.Request) {
return return
} }
var node = &models.Node{} var node = models.Node{}
//get node from body of request //get node from body of request
err = json.NewDecoder(r.Body).Decode(node) err = json.NewDecoder(r.Body).Decode(&node)
if err != nil { if err != nil {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
@ -390,14 +377,12 @@ func createNode(w http.ResponseWriter, r *http.Request) {
node.Network = networkName node.Network = networkName
network, err := logic.GetNetworkByNode(node) network, err := logic.GetNetworkByNode(&node)
if err != nil { if err != nil {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
} }
//Check to see if key is valid
//TODO: Triple inefficient!!! This is the third call to the DB we make for networks
validKey := logic.IsKeyValid(networkName, node.AccessKey) validKey := logic.IsKeyValid(networkName, node.AccessKey)
if !validKey { if !validKey {
@ -414,7 +399,7 @@ func createNode(w http.ResponseWriter, r *http.Request) {
} }
} }
node, err = logic.CreateNode(node, networkName) err = logic.CreateNode(&node)
if err != nil { if err != nil {
returnErrorResponse(w, r, formatError(err, "internal")) returnErrorResponse(w, r, formatError(err, "internal"))
return return
@ -476,6 +461,7 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
} }
// == INGRESS == // == INGRESS ==
func createIngressGateway(w http.ResponseWriter, r *http.Request) { func createIngressGateway(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r) var params = mux.Vars(r)
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
@ -562,8 +548,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(newNode) json.NewEncoder(w).Encode(newNode)
} }
//Delete a node
//Pretty straightforward
func deleteNode(w http.ResponseWriter, r *http.Request) { func deleteNode(w http.ResponseWriter, r *http.Request) {
// Set header // Set header
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View file

@ -49,49 +49,42 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*
// NodeServiceServer.CreateNode - creates a node and responds over gRPC // NodeServiceServer.CreateNode - creates a node and responds over gRPC
func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) { func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
// Get the protobuf node type from the protobuf request type var node = models.Node{}
// Essentially doing req.Node to access the struct with a nil check var err error
var node = &models.Node{}
data := req.GetData() data := req.GetData()
if err := json.Unmarshal([]byte(data), node); err != nil { if err := json.Unmarshal([]byte(data), &node); err != nil {
return nil, err return nil, err
} }
//Check to see if key is valid
//TODO: Triple inefficient!!! This is the third call to the DB we make for networks
validKey := logic.IsKeyValid(node.Network, node.AccessKey) validKey := logic.IsKeyValid(node.Network, node.AccessKey)
network, err := logic.GetParentNetwork(node.Network) node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !validKey { if !validKey {
//Check to see if network will allow manual sign up if node.NetworkSettings.AllowManualSignUp == "yes" {
//may want to switch this up with the valid key check and avoid a DB call that way.
if network.AllowManualSignUp == "yes" {
node.IsPending = "yes" node.IsPending = "yes"
} else { } else {
return nil, errors.New("invalid key, and network does not allow no-key signups") return nil, errors.New("invalid key, and network does not allow no-key signups")
} }
} }
node, err = logic.CreateNode(node, node.Network) err = logic.CreateNode(&node)
if err != nil {
return nil, err
}
node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
if err != nil { if err != nil {
return nil, err return nil, err
} }
nodeData, errN := json.Marshal(&node) nodeData, errN := json.Marshal(&node)
if errN != nil { if errN != nil {
return nil, err return nil, err
} }
// return the node in a CreateNodeRes type
response := &nodepb.Object{ response := &nodepb.Object{
Data: string(nodeData), Data: string(nodeData),
Type: nodepb.NODE_TYPE, Type: nodepb.NODE_TYPE,
} }
err = logic.SetNetworkNodesLastModified(node.Network) err = logic.SetNetworkNodesLastModified(node.Network)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -152,7 +152,7 @@ func deleteAllNodes() {
} }
func createTestNode() *models.Node { func createTestNode() *models.Node {
createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"} createnode := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"}
node, _ := logic.CreateNode(createnode, "skynet") logic.CreateNode(&createnode)
return node return &createnode
} }

View file

@ -60,10 +60,7 @@ func securityCheckServer(adminonly bool, next http.Handler) http.HandlerFunc {
//Consider a more secure way of setting master key //Consider a more secure way of setting master key
func authenticateMasterServer(tokenString string) bool { func authenticateMasterServer(tokenString string) bool {
if tokenString == servercfg.GetMasterKey() { return tokenString == servercfg.GetMasterKey()
return true
}
return false
} }
func removeNetwork(w http.ResponseWriter, r *http.Request) { func removeNetwork(w http.ResponseWriter, r *http.Request) {

View file

@ -196,6 +196,7 @@ func IsKeyValid(networkname string, keyvalue string) bool {
return isvalid return isvalid
} }
// RemoveKeySensitiveInfo - remove sensitive key info
func RemoveKeySensitiveInfo(keys []models.AccessKey) []models.AccessKey { func RemoveKeySensitiveInfo(keys []models.AccessKey) []models.AccessKey {
var returnKeys []models.AccessKey var returnKeys []models.AccessKey
for _, key := range keys { for _, key := range keys {

View file

@ -114,7 +114,7 @@ func GetExtClient(clientid string, network string) (models.ExtClient, error) {
} }
// CreateExtClient - creates an extclient // CreateExtClient - creates an extclient
func CreateExtClient(extclient models.ExtClient) error { func CreateExtClient(extclient *models.ExtClient) error {
if extclient.PrivateKey == "" { if extclient.PrivateKey == "" {
privateKey, err := wgtypes.GeneratePrivateKey() privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil { if err != nil {
@ -155,7 +155,7 @@ func CreateExtClient(extclient models.ExtClient) error {
} }
// UpdateExtClient - only supports name changes right now // UpdateExtClient - only supports name changes right now
func UpdateExtClient(newclientid string, network string, client models.ExtClient) (models.ExtClient, error) { func UpdateExtClient(newclientid string, network string, client *models.ExtClient) (*models.ExtClient, error) {
err := DeleteExtClient(network, client.ClientID) err := DeleteExtClient(network, client.ClientID)
if err != nil { if err != nil {

View file

@ -155,15 +155,15 @@ func GetParentNetwork(networkname string) (models.Network, error) {
} }
// GetParentNetwork - get parent network // GetParentNetwork - get parent network
func GetNetworkSettings(networkname string) (*models.Network, error) { func GetNetworkSettings(networkname string) (models.Network, error) {
var network *models.Network var network models.Network
networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname) networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
if err != nil { if err != nil {
return network, err return network, err
} }
if err = json.Unmarshal([]byte(networkData), network); err != nil { if err = json.Unmarshal([]byte(networkData), &network); err != nil {
return &models.Network{}, err return models.Network{}, err
} }
network.AccessKeys = []models.AccessKey{} network.AccessKeys = []models.AccessKey{}
return network, nil return network, nil

View file

@ -79,7 +79,7 @@ func ServerJoin(network string, serverID string, privateKey string) error {
node.Network = network node.Network = network
logger.Log(2, "adding a server instance on network", node.Network) logger.Log(2, "adding a server instance on network", node.Network)
node, err = CreateNode(node, network) err = CreateNode(node)
if err != nil { if err != nil {
return err return err
} }
@ -283,7 +283,7 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri
// handle egress gateway peers // handle egress gateway peers
if node.IsEgressGateway == "yes" { if node.IsEgressGateway == "yes" {
hasGateway = true hasGateway = true
ranges := node.EgressGatewayRanges[:] ranges := node.EgressGatewayRanges
for _, iprange := range ranges { // go through each cidr for egress gateway for _, iprange := range ranges { // go through each cidr for egress gateway
_, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr
if err != nil { if err != nil {

View file

@ -76,18 +76,15 @@ func DeleteNode(node *models.Node, exterminate bool) error {
} }
// CreateNode - creates a node in database // CreateNode - creates a node in database
func CreateNode(node *models.Node, networkName string) (*models.Node, error) { func CreateNode(node *models.Node) error {
//encrypt that password so we never see it //encrypt that password so we never see it
hash, err := bcrypt.GenerateFromPassword([]byte(node.Password), 5) hash, err := bcrypt.GenerateFromPassword([]byte(node.Password), 5)
if err != nil { if err != nil {
return node, err return err
} }
//set password to encrypted password //set password to encrypted password
node.Password = string(hash) node.Password = string(hash)
node.Network = networkName
if node.Name == models.NODE_SERVER_NAME { if node.Name == models.NODE_SERVER_NAME {
node.IsServer = "yes" node.IsServer = "yes"
} }
@ -99,35 +96,35 @@ func CreateNode(node *models.Node, networkName string) (*models.Node, error) {
} }
} }
SetNodeDefaults(node) SetNodeDefaults(node)
node.Address, err = UniqueAddress(networkName) node.Address, err = UniqueAddress(node.Network)
if err != nil { if err != nil {
return node, err return err
} }
node.Address6, err = UniqueAddress6(networkName) node.Address6, err = UniqueAddress6(node.Network)
if err != nil { if err != nil {
return node, err return err
} }
//Create a JWT for the node //Create a JWT for the node
tokenString, _ := CreateJWT(node.MacAddress, networkName) tokenString, _ := CreateJWT(node.MacAddress, node.Network)
if tokenString == "" { if tokenString == "" {
//returnErrorResponse(w, r, errorResponse) //returnErrorResponse(w, r, errorResponse)
return node, err return err
} }
err = ValidateNode(node, false) err = ValidateNode(node, false)
if err != nil { if err != nil {
return node, err return err
} }
key, err := GetRecordKey(node.MacAddress, node.Network) key, err := GetRecordKey(node.MacAddress, node.Network)
if err != nil { if err != nil {
return node, err return err
} }
nodebytes, err := json.Marshal(&node) nodebytes, err := json.Marshal(&node)
if err != nil { if err != nil {
return node, err return err
} }
err = database.Insert(key, string(nodebytes), database.NODES_TABLE_NAME) err = database.Insert(key, string(nodebytes), database.NODES_TABLE_NAME)
if err != nil { if err != nil {
return node, err return err
} }
if node.IsPending != "yes" { if node.IsPending != "yes" {
DecrimentKey(node.Network, node.AccessKey) DecrimentKey(node.Network, node.AccessKey)
@ -136,7 +133,7 @@ func CreateNode(node *models.Node, networkName string) (*models.Node, error) {
if servercfg.IsDNSMode() { if servercfg.IsDNSMode() {
err = SetDNS() err = SetDNS()
} }
return node, err return err
} }
// SetNetworkNodesLastModified - sets the network nodes last modified // SetNetworkNodesLastModified - sets the network nodes last modified

View file

@ -300,6 +300,7 @@ func setWGConfig(node *models.Node, peerupdate bool) error {
err = initWireguard(node, privkey, peers[:], hasGateway, gateways[:]) err = initWireguard(node, privkey, peers[:], hasGateway, gateways[:])
logger.Log(3, "finished setting wg config on server", node.Name) logger.Log(3, "finished setting wg config on server", node.Name)
} }
peers = nil
return err return err
} }

12
main.go
View file

@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"log"
"net" "net"
"os" "os"
"os/signal" "os/signal"
@ -38,8 +37,7 @@ func initialize() { // Client Mode Prereq Check
var err error var err error
if err = database.InitializeDatabase(); err != nil { if err = database.InitializeDatabase(); err != nil {
logger.Log(0, "Error connecting to database") logger.FatalLog("Error connecting to database")
log.Fatal(err)
} }
logger.Log(0, "database successfully connected") logger.Log(0, "database successfully connected")
@ -134,16 +132,12 @@ func runGRPC(wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
// Configure 'log' package to give file name and line number on eg. log.Fatal
// Pipe flags to one another (log.LstdFLags = log.Ldate | log.Ltime)
log.SetFlags(log.LstdFlags | log.Lshortfile)
grpcport := servercfg.GetGRPCPort() grpcport := servercfg.GetGRPCPort()
listener, err := net.Listen("tcp", ":"+grpcport) listener, err := net.Listen("tcp", ":"+grpcport)
// Handle errors if any // Handle errors if any
if err != nil { if err != nil {
log.Fatalf("[netmaker] Unable to listen on port "+grpcport+", error: %v", err) logger.FatalLog("[netmaker] Unable to listen on port", grpcport, ": error:", err.Error())
} }
s := grpc.NewServer( s := grpc.NewServer(
@ -158,7 +152,7 @@ func runGRPC(wg *sync.WaitGroup) {
// Start the server in a child routine // Start the server in a child routine
go func() { go func() {
if err := s.Serve(listener); err != nil { if err := s.Serve(listener); err != nil {
log.Fatalf("Failed to serve: %v", err) logger.FatalLog("Failed to serve:", err.Error())
} }
}() }()
logger.Log(0, "Agent Server successfully started on port ", grpcport, "(gRPC)") logger.Log(0, "Agent Server successfully started on port ", grpcport, "(gRPC)")

View file

@ -31,7 +31,7 @@ type Node struct {
Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"` Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"` LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"` Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"`
NetworkSettings *Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"` NetworkSettings Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"` ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"` PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"` Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
@ -239,7 +239,7 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.PostDown = currentNode.PostDown newNode.PostDown = currentNode.PostDown
} }
if newNode.AllowedIPs == nil { if newNode.AllowedIPs == nil {
newNode.AllowedIPs = currentNode.AllowedIPs[:] newNode.AllowedIPs = currentNode.AllowedIPs
} }
if newNode.PersistentKeepalive == 0 { if newNode.PersistentKeepalive == 0 {
newNode.PersistentKeepalive = currentNode.PersistentKeepalive newNode.PersistentKeepalive = currentNode.PersistentKeepalive
@ -298,10 +298,10 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.IsIngressGateway = currentNode.IsIngressGateway newNode.IsIngressGateway = currentNode.IsIngressGateway
} }
if newNode.EgressGatewayRanges == nil { if newNode.EgressGatewayRanges == nil {
newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges[:] newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
} }
if newNode.IngressGatewayRange == "" { if newNode.IngressGatewayRange == "" {
newNode.IngressGatewayRange = currentNode.IngressGatewayRange[:] newNode.IngressGatewayRange = currentNode.IngressGatewayRange
} }
if newNode.IsStatic == "" { if newNode.IsStatic == "" {
newNode.IsStatic = currentNode.IsStatic newNode.IsStatic = currentNode.IsStatic
@ -343,7 +343,7 @@ func (newNode *Node) Fill(currentNode *Node) {
newNode.OS = currentNode.OS newNode.OS = currentNode.OS
} }
if newNode.RelayAddrs == nil { if newNode.RelayAddrs == nil {
newNode.RelayAddrs = currentNode.RelayAddrs[:] newNode.RelayAddrs = currentNode.RelayAddrs
} }
if newNode.IsRelay == "" { if newNode.IsRelay == "" {
newNode.IsRelay = currentNode.IsRelay newNode.IsRelay = currentNode.IsRelay

View file

@ -85,7 +85,7 @@ type AccessKey struct {
Name string `json:"name" bson:"name" validate:"omitempty,max=20"` Name string `json:"name" bson:"name" validate:"omitempty,max=20"`
Value string `json:"value" bson:"value" validate:"omitempty,alphanum,max=16"` Value string `json:"value" bson:"value" validate:"omitempty,alphanum,max=16"`
AccessString string `json:"accessstring" bson:"accessstring"` AccessString string `json:"accessstring" bson:"accessstring"`
Uses int `json:"uses" bson:"uses"` Uses int `json:"uses" bson:"uses" validate:"numeric,min=0"`
} }
// DisplayKey - what is displayed for key // DisplayKey - what is displayed for key

View file

@ -122,7 +122,7 @@ func ModConfig(node *models.Node) error {
} }
modconfig.Node = (*node) modconfig.Node = (*node)
modconfig.NetworkSettings = (*node.NetworkSettings) modconfig.NetworkSettings = node.NetworkSettings
err = Write(&modconfig, network) err = Write(&modconfig, network)
return err return err
} }