node.go 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. package controller
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "strings"
  7. "github.com/gorilla/mux"
  8. "github.com/gravitl/netmaker/database"
  9. "github.com/gravitl/netmaker/logger"
  10. "github.com/gravitl/netmaker/logic"
  11. "github.com/gravitl/netmaker/logic/pro"
  12. "github.com/gravitl/netmaker/models"
  13. "github.com/gravitl/netmaker/models/promodels"
  14. "github.com/gravitl/netmaker/mq"
  15. "github.com/gravitl/netmaker/servercfg"
  16. "golang.org/x/crypto/bcrypt"
  17. )
  18. func nodeHandlers(r *mux.Router) {
  19. r.HandleFunc("/api/nodes", authorize(false, false, "user", http.HandlerFunc(getAllNodes))).Methods("GET")
  20. r.HandleFunc("/api/nodes/{network}", authorize(false, true, "network", http.HandlerFunc(getNetworkNodes))).Methods("GET")
  21. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, true, "node", http.HandlerFunc(getNode))).Methods("GET")
  22. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(false, true, "node", http.HandlerFunc(updateNode))).Methods("PUT")
  23. r.HandleFunc("/api/nodes/{network}/{nodeid}", authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods("DELETE")
  24. r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", authorize(false, true, "user", http.HandlerFunc(createRelay))).Methods("POST")
  25. r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", authorize(false, true, "user", http.HandlerFunc(deleteRelay))).Methods("DELETE")
  26. r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", authorize(false, true, "user", http.HandlerFunc(createEgressGateway))).Methods("POST")
  27. r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", authorize(false, true, "user", http.HandlerFunc(deleteEgressGateway))).Methods("DELETE")
  28. r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(false, http.HandlerFunc(createIngressGateway))).Methods("POST")
  29. r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(false, http.HandlerFunc(deleteIngressGateway))).Methods("DELETE")
  30. r.HandleFunc("/api/nodes/{network}/{nodeid}/approve", authorize(false, true, "user", http.HandlerFunc(uncordonNode))).Methods("POST")
  31. r.HandleFunc("/api/nodes/{network}", nodeauth(checkFreeTierLimits(node_l, http.HandlerFunc(createNode)))).Methods("POST")
  32. r.HandleFunc("/api/nodes/adm/{network}/lastmodified", authorize(false, true, "network", http.HandlerFunc(getLastModified))).Methods("GET")
  33. r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods("POST")
  34. }
  35. // swagger:route POST /api/nodes/adm/{network}/authenticate nodes authenticate
  36. //
  37. // Authenticate to make further API calls related to a network.
  38. //
  39. // Schemes: https
  40. //
  41. // Security:
  42. // oauth
  43. //
  44. // Responses:
  45. // 200: successResponse
  46. func authenticate(response http.ResponseWriter, request *http.Request) {
  47. var authRequest models.AuthParams
  48. var result models.Node
  49. var errorResponse = models.ErrorResponse{
  50. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  51. }
  52. decoder := json.NewDecoder(request.Body)
  53. decoderErr := decoder.Decode(&authRequest)
  54. defer request.Body.Close()
  55. if decoderErr != nil {
  56. errorResponse.Code = http.StatusBadRequest
  57. errorResponse.Message = decoderErr.Error()
  58. logger.Log(0, request.Header.Get("user"), "error decoding request body: ",
  59. decoderErr.Error())
  60. logic.ReturnErrorResponse(response, request, errorResponse)
  61. return
  62. }
  63. errorResponse.Code = http.StatusBadRequest
  64. if authRequest.ID == "" {
  65. errorResponse.Message = "W1R3: ID can't be empty"
  66. logger.Log(0, request.Header.Get("user"), errorResponse.Message)
  67. logic.ReturnErrorResponse(response, request, errorResponse)
  68. return
  69. } else if authRequest.Password == "" {
  70. errorResponse.Message = "W1R3: Password can't be empty"
  71. logger.Log(0, request.Header.Get("user"), errorResponse.Message)
  72. logic.ReturnErrorResponse(response, request, errorResponse)
  73. return
  74. }
  75. var err error
  76. result, err = logic.GetNodeByID(authRequest.ID)
  77. if err != nil {
  78. errorResponse.Code = http.StatusBadRequest
  79. errorResponse.Message = err.Error()
  80. logger.Log(0, request.Header.Get("user"),
  81. fmt.Sprintf("failed to get node info [%s]: %v", authRequest.ID, err))
  82. logic.ReturnErrorResponse(response, request, errorResponse)
  83. return
  84. }
  85. err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
  86. if err != nil {
  87. errorResponse.Code = http.StatusBadRequest
  88. errorResponse.Message = err.Error()
  89. logger.Log(0, request.Header.Get("user"),
  90. "error validating user password: ", err.Error())
  91. logic.ReturnErrorResponse(response, request, errorResponse)
  92. return
  93. }
  94. // creates network role, node role,node client (added here to resolve any missing configuration in MQ)
  95. event := mq.MqDynsecPayload{
  96. Commands: []mq.MqDynSecCmd{
  97. {
  98. Command: mq.CreateRoleCmd,
  99. RoleName: result.Network,
  100. Textname: "Network wide role with Acls for nodes",
  101. Acls: mq.FetchNetworkAcls(result.Network),
  102. },
  103. {
  104. Command: mq.CreateRoleCmd,
  105. RoleName: fmt.Sprintf("%s-%s", "Node", result.ID),
  106. Acls: mq.FetchNodeAcls(result.ID),
  107. Textname: "Role for node " + result.Name,
  108. },
  109. {
  110. Command: mq.CreateClientCmd,
  111. Username: result.ID,
  112. Password: authRequest.Password,
  113. Textname: result.Name,
  114. Roles: []mq.MqDynSecRole{
  115. {
  116. Rolename: fmt.Sprintf("%s-%s", "Node", result.ID),
  117. Priority: -1,
  118. },
  119. {
  120. Rolename: result.Network,
  121. Priority: -1,
  122. },
  123. },
  124. Groups: make([]mq.MqDynSecGroup, 0),
  125. },
  126. },
  127. }
  128. if err := mq.PublishEventToDynSecTopic(event); err != nil {
  129. logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
  130. event.Commands, err.Error()))
  131. errorResponse.Code = http.StatusInternalServerError
  132. errorResponse.Message = fmt.Sprintf("could not create mq client for node [%s]: %v", result.ID, err)
  133. return
  134. }
  135. tokenString, err := logic.CreateJWT(authRequest.ID, authRequest.MacAddress, result.Network)
  136. if tokenString == "" {
  137. errorResponse.Code = http.StatusBadRequest
  138. errorResponse.Message = "Could not create Token"
  139. logger.Log(0, request.Header.Get("user"),
  140. fmt.Sprintf("%s: %v", errorResponse.Message, err))
  141. logic.ReturnErrorResponse(response, request, errorResponse)
  142. return
  143. }
  144. var successResponse = models.SuccessResponse{
  145. Code: http.StatusOK,
  146. Message: "W1R3: Device " + authRequest.ID + " Authorized",
  147. Response: models.SuccessfulLoginResponse{
  148. AuthToken: tokenString,
  149. ID: authRequest.ID,
  150. },
  151. }
  152. successJSONResponse, jsonError := json.Marshal(successResponse)
  153. if jsonError != nil {
  154. errorResponse.Code = http.StatusBadRequest
  155. errorResponse.Message = err.Error()
  156. logger.Log(0, request.Header.Get("user"),
  157. "error marshalling resp: ", err.Error())
  158. logic.ReturnErrorResponse(response, request, errorResponse)
  159. return
  160. }
  161. response.WriteHeader(http.StatusOK)
  162. response.Header().Set("Content-Type", "application/json")
  163. response.Write(successJSONResponse)
  164. }
  165. // auth middleware for api calls from nodes where node is has not yet joined the server (register, join)
  166. func nodeauth(next http.Handler) http.HandlerFunc {
  167. return func(w http.ResponseWriter, r *http.Request) {
  168. bearerToken := r.Header.Get("Authorization")
  169. var tokenSplit = strings.Split(bearerToken, " ")
  170. var token = ""
  171. if len(tokenSplit) < 2 {
  172. errorResponse := models.ErrorResponse{
  173. Code: http.StatusUnauthorized, Message: "W1R3: You are unauthorized to access this endpoint.",
  174. }
  175. logic.ReturnErrorResponse(w, r, errorResponse)
  176. return
  177. } else {
  178. token = tokenSplit[1]
  179. }
  180. found := false
  181. networks, err := logic.GetNetworks()
  182. if err != nil {
  183. logger.Log(0, "no networks", err.Error())
  184. errorResponse := models.ErrorResponse{
  185. Code: http.StatusNotFound, Message: "no networks",
  186. }
  187. logic.ReturnErrorResponse(w, r, errorResponse)
  188. return
  189. }
  190. for _, network := range networks {
  191. for _, key := range network.AccessKeys {
  192. if key.Value == token {
  193. found = true
  194. break
  195. }
  196. }
  197. }
  198. if !found {
  199. logger.Log(0, "valid access key not found")
  200. errorResponse := models.ErrorResponse{
  201. Code: http.StatusUnauthorized, Message: "You are unauthorized to access this endpoint.",
  202. }
  203. logic.ReturnErrorResponse(w, r, errorResponse)
  204. return
  205. }
  206. next.ServeHTTP(w, r)
  207. }
  208. }
  209. // The middleware for most requests to the API
  210. // They all pass through here first
  211. // This will validate the JWT (or check for master token)
  212. // This will also check against the authNetwork and make sure the node should be accessing that endpoint,
  213. // even if it's technically ok
  214. // This is kind of a poor man's RBAC. There's probably a better/smarter way.
  215. // TODO: Consider better RBAC implementations
  216. func authorize(nodesAllowed, networkCheck bool, authNetwork string, next http.Handler) http.HandlerFunc {
  217. return func(w http.ResponseWriter, r *http.Request) {
  218. var errorResponse = models.ErrorResponse{
  219. Code: http.StatusUnauthorized, Message: logic.Unauthorized_Msg,
  220. }
  221. var params = mux.Vars(r)
  222. networkexists, _ := logic.NetworkExists(params["network"])
  223. //check that the request is for a valid network
  224. //if (networkCheck && !networkexists) || err != nil {
  225. if networkCheck && !networkexists {
  226. logic.ReturnErrorResponse(w, r, errorResponse)
  227. return
  228. } else {
  229. w.Header().Set("Content-Type", "application/json")
  230. //get the auth token
  231. bearerToken := r.Header.Get("Authorization")
  232. var tokenSplit = strings.Split(bearerToken, " ")
  233. //I put this in in case the user doesn't put in a token at all (in which case it's empty)
  234. //There's probably a smarter way of handling this.
  235. var authToken = "928rt238tghgwe@TY@$Y@#WQAEGB2FC#@HG#@$Hddd"
  236. if len(tokenSplit) > 1 {
  237. authToken = tokenSplit[1]
  238. } else {
  239. logic.ReturnErrorResponse(w, r, errorResponse)
  240. return
  241. }
  242. //check if node instead of user
  243. if nodesAllowed {
  244. // TODO --- should ensure that node is only operating on itself
  245. if _, _, _, err := logic.VerifyToken(authToken); err == nil {
  246. // this indicates request is from a node
  247. // used for failover - if a getNode comes from node, this will trigger a metrics wipe
  248. r.Header.Set("requestfrom", "node")
  249. next.ServeHTTP(w, r)
  250. return
  251. }
  252. }
  253. var isAuthorized = false
  254. var nodeID = ""
  255. username, networks, isadmin, errN := logic.VerifyUserToken(authToken)
  256. if errN != nil {
  257. logic.ReturnErrorResponse(w, r, errorResponse)
  258. return
  259. }
  260. isnetadmin := isadmin
  261. if errN == nil && isadmin {
  262. nodeID = "mastermac"
  263. isAuthorized = true
  264. r.Header.Set("ismasterkey", "yes")
  265. }
  266. if !isadmin && params["network"] != "" {
  267. if logic.StringSliceContains(networks, params["network"]) && pro.IsUserNetAdmin(params["network"], username) {
  268. isnetadmin = true
  269. }
  270. }
  271. //The mastermac (login with masterkey from config) can do everything!! May be dangerous.
  272. if nodeID == "mastermac" {
  273. isAuthorized = true
  274. r.Header.Set("ismasterkey", "yes")
  275. //for everyone else, there's poor man's RBAC. The "cases" are defined in the routes in the handlers
  276. //So each route defines which access network should be allowed to access it
  277. } else {
  278. switch authNetwork {
  279. case "all":
  280. isAuthorized = true
  281. case "nodes":
  282. isAuthorized = (nodeID != "") || isnetadmin
  283. case "network":
  284. if isnetadmin {
  285. isAuthorized = true
  286. } else {
  287. node, err := logic.GetNodeByID(nodeID)
  288. if err != nil {
  289. logic.ReturnErrorResponse(w, r, errorResponse)
  290. return
  291. }
  292. isAuthorized = (node.Network == params["network"])
  293. }
  294. case "node":
  295. if isnetadmin {
  296. isAuthorized = true
  297. } else {
  298. isAuthorized = (nodeID == params["netid"])
  299. }
  300. case "user":
  301. isAuthorized = true
  302. default:
  303. isAuthorized = false
  304. }
  305. }
  306. if !isAuthorized {
  307. logic.ReturnErrorResponse(w, r, errorResponse)
  308. return
  309. } else {
  310. //If authorized, this function passes along it's request and output to the appropriate route function.
  311. if username == "" {
  312. username = "(user not found)"
  313. }
  314. r.Header.Set("user", username)
  315. next.ServeHTTP(w, r)
  316. }
  317. }
  318. }
  319. }
  320. // swagger:route GET /api/nodes/{network} nodes getNetworkNodes
  321. //
  322. // Gets all nodes associated with network including pending nodes.
  323. //
  324. // Schemes: https
  325. //
  326. // Security:
  327. // oauth
  328. //
  329. // Responses:
  330. // 200: nodeSliceResponse
  331. func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
  332. w.Header().Set("Content-Type", "application/json")
  333. var nodes []models.Node
  334. var params = mux.Vars(r)
  335. networkName := params["network"]
  336. nodes, err := logic.GetNetworkNodes(networkName)
  337. if err != nil {
  338. logger.Log(0, r.Header.Get("user"),
  339. fmt.Sprintf("error fetching nodes on network %s: %v", networkName, err))
  340. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  341. return
  342. }
  343. for _, node := range nodes {
  344. if len(node.NetworkSettings.AccessKeys) > 0 {
  345. node.NetworkSettings.AccessKeys = []models.AccessKey{} // not to be sent back to client; client already knows how to join the network
  346. }
  347. }
  348. //Returns all the nodes in JSON format
  349. logger.Log(2, r.Header.Get("user"), "fetched nodes on network", networkName)
  350. w.WriteHeader(http.StatusOK)
  351. json.NewEncoder(w).Encode(nodes)
  352. }
  353. // swagger:route GET /api/nodes nodes getAllNodes
  354. //
  355. // Get all nodes across all networks.
  356. //
  357. // Schemes: https
  358. //
  359. // Security:
  360. // oauth
  361. //
  362. // Responses:
  363. // 200: nodeSliceResponse
  364. // 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
  365. func getAllNodes(w http.ResponseWriter, r *http.Request) {
  366. w.Header().Set("Content-Type", "application/json")
  367. user, err := logic.GetUser(r.Header.Get("user"))
  368. if err != nil && r.Header.Get("ismasterkey") != "yes" {
  369. logger.Log(0, r.Header.Get("user"),
  370. "error fetching user info: ", err.Error())
  371. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  372. return
  373. }
  374. var nodes []models.Node
  375. if user.IsAdmin || r.Header.Get("ismasterkey") == "yes" {
  376. nodes, err = logic.GetAllNodes()
  377. if err != nil {
  378. logger.Log(0, "error fetching all nodes info: ", err.Error())
  379. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  380. return
  381. }
  382. } else {
  383. nodes, err = getUsersNodes(user)
  384. if err != nil {
  385. logger.Log(0, r.Header.Get("user"),
  386. "error fetching nodes: ", err.Error())
  387. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  388. return
  389. }
  390. }
  391. //Return all the nodes in JSON format
  392. logger.Log(3, r.Header.Get("user"), "fetched all nodes they have access to")
  393. w.WriteHeader(http.StatusOK)
  394. json.NewEncoder(w).Encode(nodes)
  395. }
  396. func getUsersNodes(user models.User) ([]models.Node, error) {
  397. var nodes []models.Node
  398. var err error
  399. for _, networkName := range user.Networks {
  400. tmpNodes, err := logic.GetNetworkNodes(networkName)
  401. if err != nil {
  402. continue
  403. }
  404. nodes = append(nodes, tmpNodes...)
  405. }
  406. return nodes, err
  407. }
  408. // swagger:route GET /api/nodes/{network}/{nodeid} nodes getNode
  409. //
  410. // Get an individual node.
  411. //
  412. // Schemes: https
  413. //
  414. // Security:
  415. // oauth
  416. //
  417. // Responses:
  418. // 200: nodeResponse
  419. func getNode(w http.ResponseWriter, r *http.Request) {
  420. // set header.
  421. w.Header().Set("Content-Type", "application/json")
  422. nodeRequest := r.Header.Get("requestfrom") == "node"
  423. var params = mux.Vars(r)
  424. nodeid := params["nodeid"]
  425. node, err := logic.GetNodeByID(nodeid)
  426. if err != nil {
  427. logger.Log(0, r.Header.Get("user"),
  428. fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
  429. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  430. return
  431. }
  432. peerUpdate, err := logic.GetPeerUpdate(&node)
  433. if err != nil && !database.IsEmptyRecord(err) {
  434. logger.Log(0, r.Header.Get("user"),
  435. fmt.Sprintf("error fetching wg peers config for node [ %s ]: %v", nodeid, err))
  436. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  437. return
  438. }
  439. if len(node.NetworkSettings.AccessKeys) > 0 {
  440. node.NetworkSettings.AccessKeys = []models.AccessKey{} // not to be sent back to client; client already knows how to join the network
  441. }
  442. response := models.NodeGet{
  443. Node: node,
  444. Peers: peerUpdate.Peers,
  445. ServerConfig: servercfg.GetServerInfo(),
  446. PeerIDs: peerUpdate.PeerIDs,
  447. }
  448. if servercfg.Is_EE && nodeRequest {
  449. if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
  450. logger.Log(1, "failed to reset failover list during node config pull", node.Name, node.Network)
  451. }
  452. }
  453. logger.Log(2, r.Header.Get("user"), "fetched node", params["nodeid"])
  454. w.WriteHeader(http.StatusOK)
  455. json.NewEncoder(w).Encode(response)
  456. }
  457. // swagger:route GET /api/nodes/adm/{network}/lastmodified nodes getLastModified
  458. //
  459. // Get the time that a network of nodes was last modified.
  460. //
  461. // Schemes: https
  462. //
  463. // Security:
  464. // oauth
  465. //
  466. // Responses:
  467. // 200: nodeLastModifiedResponse
  468. // TODO: This needs to be refactored
  469. // Potential way to do this: On UpdateNode, set a new field for "LastModified"
  470. // If we go with the existing way, we need to at least set network.NodesLastModified on UpdateNode
  471. func getLastModified(w http.ResponseWriter, r *http.Request) {
  472. // set header.
  473. w.Header().Set("Content-Type", "application/json")
  474. var params = mux.Vars(r)
  475. networkName := params["network"]
  476. network, err := logic.GetNetwork(networkName)
  477. if err != nil {
  478. logger.Log(0, r.Header.Get("user"),
  479. fmt.Sprintf("error fetching network [%s] info: %v", networkName, err))
  480. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  481. return
  482. }
  483. logger.Log(2, r.Header.Get("user"), "called last modified")
  484. w.WriteHeader(http.StatusOK)
  485. json.NewEncoder(w).Encode(network.NodesLastModified)
  486. }
  487. // swagger:route POST /api/nodes/{network} nodes createNode
  488. //
  489. // Create a node on a network.
  490. //
  491. // Schemes: https
  492. //
  493. // Security:
  494. // oauth
  495. //
  496. // Responses:
  497. // 200: nodeGetResponse
  498. func createNode(w http.ResponseWriter, r *http.Request) {
  499. w.Header().Set("Content-Type", "application/json")
  500. var params = mux.Vars(r)
  501. var errorResponse = models.ErrorResponse{
  502. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  503. }
  504. networkName := params["network"]
  505. networkexists, err := logic.NetworkExists(networkName)
  506. if err != nil {
  507. logger.Log(0, r.Header.Get("user"),
  508. fmt.Sprintf("failed to fetch network [%s] info: %v", networkName, err))
  509. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  510. return
  511. } else if !networkexists {
  512. errorResponse = models.ErrorResponse{
  513. Code: http.StatusNotFound, Message: "W1R3: Network does not exist! ",
  514. }
  515. logger.Log(0, r.Header.Get("user"),
  516. fmt.Sprintf("network [%s] does not exist", networkName))
  517. logic.ReturnErrorResponse(w, r, errorResponse)
  518. return
  519. }
  520. var node = models.Node{}
  521. //get node from body of request
  522. err = json.NewDecoder(r.Body).Decode(&node)
  523. if err != nil {
  524. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  525. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  526. return
  527. }
  528. node.Network = networkName
  529. network, err := logic.GetNetworkByNode(&node)
  530. if err != nil {
  531. logger.Log(0, r.Header.Get("user"),
  532. fmt.Sprintf("failed to get network [%s] info: %v", node.Network, err))
  533. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  534. return
  535. }
  536. node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
  537. if err != nil {
  538. logger.Log(0, r.Header.Get("user"),
  539. fmt.Sprintf("failed to get network [%s] settings: %v", node.Network, err))
  540. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  541. return
  542. }
  543. keyName, validKey := logic.IsKeyValid(networkName, node.AccessKey)
  544. if !validKey {
  545. // Check to see if network will allow manual sign up
  546. // may want to switch this up with the valid key check and avoid a DB call that way.
  547. if network.AllowManualSignUp == "yes" {
  548. node.IsPending = "yes"
  549. } else {
  550. errorResponse = models.ErrorResponse{
  551. Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
  552. }
  553. logger.Log(0, r.Header.Get("user"),
  554. fmt.Sprintf("failed to create node on network [%s]: %s",
  555. node.Network, errorResponse.Message))
  556. logic.ReturnErrorResponse(w, r, errorResponse)
  557. return
  558. }
  559. }
  560. user, err := pro.GetNetworkUser(networkName, promodels.NetworkUserID(keyName))
  561. if err == nil {
  562. if user.ID != "" {
  563. logger.Log(1, "associating new node with user", keyName)
  564. node.OwnerID = string(user.ID)
  565. }
  566. }
  567. key, keyErr := logic.RetrievePublicTrafficKey()
  568. if keyErr != nil {
  569. logger.Log(0, "error retrieving key: ", keyErr.Error())
  570. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  571. return
  572. }
  573. if key == nil {
  574. logger.Log(0, "error: server traffic key is nil")
  575. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  576. return
  577. }
  578. if node.TrafficKeys.Mine == nil {
  579. logger.Log(0, "error: node traffic key is nil")
  580. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  581. return
  582. }
  583. node.TrafficKeys = models.TrafficKeys{
  584. Mine: node.TrafficKeys.Mine,
  585. Server: key,
  586. }
  587. nodePassword := node.Password
  588. err = logic.CreateNode(&node)
  589. if err != nil {
  590. logger.Log(0, r.Header.Get("user"),
  591. fmt.Sprintf("failed to create node on network [%s]: %s",
  592. node.Network, err))
  593. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  594. return
  595. }
  596. // check if key belongs to a user
  597. // if so add to their netuser data
  598. // if it fails remove the node and fail request
  599. if user != nil {
  600. var updatedUserNode bool
  601. user.Nodes = append(user.Nodes, node.ID) // add new node to user
  602. if err = pro.UpdateNetworkUser(networkName, user); err == nil {
  603. logger.Log(1, "added node", node.ID, node.Name, "to user", string(user.ID))
  604. updatedUserNode = true
  605. }
  606. if !updatedUserNode { // user was found but not updated, so delete node
  607. logger.Log(0, "failed to add node to user", keyName)
  608. logic.DeleteNodeByID(&node, true)
  609. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  610. return
  611. }
  612. }
  613. peerUpdate, err := logic.GetPeerUpdate(&node)
  614. if err != nil && !database.IsEmptyRecord(err) {
  615. logger.Log(0, r.Header.Get("user"),
  616. fmt.Sprintf("error fetching wg peers config for node [ %s ]: %v", node.ID, err))
  617. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  618. return
  619. }
  620. // Create client for this node in Mq
  621. event := mq.MqDynsecPayload{
  622. Commands: []mq.MqDynSecCmd{
  623. {
  624. Command: mq.DeleteClientCmd,
  625. Username: node.ID,
  626. },
  627. {
  628. Command: mq.CreateRoleCmd,
  629. RoleName: node.Network,
  630. Textname: "Network wide role with Acls for nodes",
  631. Acls: mq.FetchNetworkAcls(node.Network),
  632. },
  633. {
  634. Command: mq.CreateRoleCmd,
  635. RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),
  636. Acls: mq.FetchNodeAcls(node.ID),
  637. Textname: "Role for node " + node.Name,
  638. },
  639. {
  640. Command: mq.CreateClientCmd,
  641. Username: node.ID,
  642. Password: nodePassword,
  643. Textname: node.Name,
  644. Roles: []mq.MqDynSecRole{
  645. {
  646. Rolename: fmt.Sprintf("%s-%s", "Node", node.ID),
  647. Priority: -1,
  648. },
  649. {
  650. Rolename: node.Network,
  651. Priority: -1,
  652. },
  653. },
  654. Groups: make([]mq.MqDynSecGroup, 0),
  655. },
  656. },
  657. }
  658. if err := mq.PublishEventToDynSecTopic(event); err != nil {
  659. logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
  660. event.Commands, err.Error()))
  661. }
  662. response := models.NodeGet{
  663. Node: node,
  664. Peers: peerUpdate.Peers,
  665. ServerConfig: servercfg.GetServerInfo(),
  666. PeerIDs: peerUpdate.PeerIDs,
  667. }
  668. logger.Log(1, r.Header.Get("user"), "created new node", node.Name, "on network", node.Network)
  669. w.WriteHeader(http.StatusOK)
  670. json.NewEncoder(w).Encode(response)
  671. runForceServerUpdate(&node, true)
  672. }
  673. // swagger:route POST /api/nodes/{network}/{nodeid}/approve nodes uncordonNode
  674. //
  675. // Takes a node out of pending state.
  676. //
  677. // Schemes: https
  678. //
  679. // Security:
  680. // oauth
  681. //
  682. // Responses:
  683. // 200: nodeResponse
  684. // Takes node out of pending state
  685. // TODO: May want to use cordon/uncordon terminology instead of "ispending".
  686. func uncordonNode(w http.ResponseWriter, r *http.Request) {
  687. var params = mux.Vars(r)
  688. w.Header().Set("Content-Type", "application/json")
  689. var nodeid = params["nodeid"]
  690. node, err := logic.UncordonNode(nodeid)
  691. if err != nil {
  692. logger.Log(0, r.Header.Get("user"),
  693. fmt.Sprintf("failed to uncordon node [%s]: %v", node.Name, err))
  694. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  695. return
  696. }
  697. logger.Log(1, r.Header.Get("user"), "uncordoned node", node.Name)
  698. w.WriteHeader(http.StatusOK)
  699. json.NewEncoder(w).Encode("SUCCESS")
  700. runUpdates(&node, false)
  701. }
  702. // == EGRESS ==
  703. // swagger:route POST /api/nodes/{network}/{nodeid}/creategateway nodes createEgressGateway
  704. //
  705. // Create an egress gateway.
  706. //
  707. // Schemes: https
  708. //
  709. // Security:
  710. // oauth
  711. //
  712. // Responses:
  713. // 200: nodeResponse
  714. func createEgressGateway(w http.ResponseWriter, r *http.Request) {
  715. var gateway models.EgressGatewayRequest
  716. var params = mux.Vars(r)
  717. w.Header().Set("Content-Type", "application/json")
  718. err := json.NewDecoder(r.Body).Decode(&gateway)
  719. if err != nil {
  720. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  721. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  722. return
  723. }
  724. gateway.NetID = params["network"]
  725. gateway.NodeID = params["nodeid"]
  726. node, err := logic.CreateEgressGateway(gateway)
  727. if err != nil {
  728. logger.Log(0, r.Header.Get("user"),
  729. fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
  730. gateway.NodeID, gateway.NetID, err))
  731. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  732. return
  733. }
  734. logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
  735. w.WriteHeader(http.StatusOK)
  736. json.NewEncoder(w).Encode(node)
  737. runUpdates(&node, true)
  738. }
  739. // swagger:route DELETE /api/nodes/{network}/{nodeid}/deletegateway nodes deleteEgressGateway
  740. //
  741. // Delete an egress gateway.
  742. //
  743. // Schemes: https
  744. //
  745. // Security:
  746. // oauth
  747. //
  748. // Responses:
  749. // 200: nodeResponse
  750. func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
  751. w.Header().Set("Content-Type", "application/json")
  752. var params = mux.Vars(r)
  753. nodeid := params["nodeid"]
  754. netid := params["network"]
  755. node, err := logic.DeleteEgressGateway(netid, nodeid)
  756. if err != nil {
  757. logger.Log(0, r.Header.Get("user"),
  758. fmt.Sprintf("failed to delete egress gateway on node [%s] on network [%s]: %v",
  759. nodeid, netid, err))
  760. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  761. return
  762. }
  763. logger.Log(1, r.Header.Get("user"), "deleted egress gateway on node", nodeid, "on network", netid)
  764. w.WriteHeader(http.StatusOK)
  765. json.NewEncoder(w).Encode(node)
  766. runUpdates(&node, true)
  767. }
  768. // == INGRESS ==
  769. // swagger:route POST /api/nodes/{network}/{nodeid}/createingress nodes createIngressGateway
  770. //
  771. // Create an ingress gateway.
  772. //
  773. // Schemes: https
  774. //
  775. // Security:
  776. // oauth
  777. //
  778. // Responses:
  779. // 200: nodeResponse
  780. func createIngressGateway(w http.ResponseWriter, r *http.Request) {
  781. var params = mux.Vars(r)
  782. w.Header().Set("Content-Type", "application/json")
  783. nodeid := params["nodeid"]
  784. netid := params["network"]
  785. type failoverData struct {
  786. Failover bool `json:"failover"`
  787. }
  788. var failoverReqBody failoverData
  789. json.NewDecoder(r.Body).Decode(&failoverReqBody)
  790. node, err := logic.CreateIngressGateway(netid, nodeid, failoverReqBody.Failover)
  791. if err != nil {
  792. logger.Log(0, r.Header.Get("user"),
  793. fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
  794. nodeid, netid, err))
  795. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  796. return
  797. }
  798. if servercfg.Is_EE && failoverReqBody.Failover {
  799. if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil {
  800. logger.Log(1, "failed to reset failover list during failover create", node.Name, node.Network)
  801. }
  802. }
  803. logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
  804. w.WriteHeader(http.StatusOK)
  805. json.NewEncoder(w).Encode(node)
  806. runUpdates(&node, true)
  807. }
  808. // swagger:route DELETE /api/nodes/{network}/{nodeid}/deleteingress nodes deleteIngressGateway
  809. //
  810. // Delete an ingress gateway.
  811. //
  812. // Schemes: https
  813. //
  814. // Security:
  815. // oauth
  816. //
  817. // Responses:
  818. // 200: nodeResponse
  819. func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
  820. w.Header().Set("Content-Type", "application/json")
  821. var params = mux.Vars(r)
  822. nodeid := params["nodeid"]
  823. netid := params["network"]
  824. node, wasFailover, err := logic.DeleteIngressGateway(netid, nodeid)
  825. if err != nil {
  826. logger.Log(0, r.Header.Get("user"),
  827. fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",
  828. nodeid, netid, err))
  829. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  830. return
  831. }
  832. if servercfg.Is_EE && wasFailover {
  833. if err = logic.EnterpriseResetFailoverFunc(node.Network); err != nil {
  834. logger.Log(1, "failed to reset failover list during failover create", node.Name, node.Network)
  835. }
  836. }
  837. logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
  838. w.WriteHeader(http.StatusOK)
  839. json.NewEncoder(w).Encode(node)
  840. runUpdates(&node, true)
  841. }
  842. // swagger:route PUT /api/nodes/{network}/{nodeid} nodes updateNode
  843. //
  844. // Update an individual node.
  845. //
  846. // Schemes: https
  847. //
  848. // Security:
  849. // oauth
  850. //
  851. // Responses:
  852. // 200: nodeResponse
  853. func updateNode(w http.ResponseWriter, r *http.Request) {
  854. w.Header().Set("Content-Type", "application/json")
  855. var params = mux.Vars(r)
  856. var node models.Node
  857. //start here
  858. nodeid := params["nodeid"]
  859. node, err := logic.GetNodeByID(nodeid)
  860. if err != nil {
  861. logger.Log(0, r.Header.Get("user"),
  862. fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
  863. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  864. return
  865. }
  866. var newNode models.Node
  867. // we decode our body request params
  868. err = json.NewDecoder(r.Body).Decode(&newNode)
  869. if err != nil {
  870. logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
  871. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  872. return
  873. }
  874. relayupdate := false
  875. if node.IsRelay == "yes" && len(newNode.RelayAddrs) > 0 {
  876. if len(newNode.RelayAddrs) != len(node.RelayAddrs) {
  877. relayupdate = true
  878. } else {
  879. for i, addr := range newNode.RelayAddrs {
  880. if addr != node.RelayAddrs[i] {
  881. relayupdate = true
  882. }
  883. }
  884. }
  885. }
  886. relayedUpdate := false
  887. if node.IsRelayed == "yes" && (node.Address != newNode.Address || node.Address6 != newNode.Address6) {
  888. relayedUpdate = true
  889. }
  890. if !servercfg.GetRce() {
  891. newNode.PostDown = node.PostDown
  892. newNode.PostUp = node.PostUp
  893. }
  894. ifaceDelta := logic.IfaceDelta(&node, &newNode)
  895. // for a hub change also need to update the existing hub
  896. if newNode.IsHub == "yes" && node.IsHub != "yes" {
  897. nodeToUpdate, err := logic.UnsetHub(newNode.Network)
  898. if err != nil {
  899. logger.Log(2, "failed to unset hubs", err.Error())
  900. }
  901. if err := mq.NodeUpdate(nodeToUpdate); err != nil {
  902. logger.Log(2, "failed to update hub node", nodeToUpdate.Name, err.Error())
  903. }
  904. if nodeToUpdate.IsServer == "yes" {
  905. // set ifacdelta true to force server to update peeers
  906. if err := logic.ServerUpdate(nodeToUpdate, true); err != nil {
  907. logger.Log(2, "failed to update server node on hub change", err.Error())
  908. }
  909. }
  910. }
  911. if ifaceDelta && servercfg.Is_EE {
  912. if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
  913. logger.Log(0, "failed to reset failover lists during node update for node", node.Name, node.Network)
  914. }
  915. }
  916. err = logic.UpdateNode(&node, &newNode)
  917. if err != nil {
  918. logger.Log(0, r.Header.Get("user"),
  919. fmt.Sprintf("failed to update node info [ %s ] info: %v", nodeid, err))
  920. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  921. return
  922. }
  923. if relayupdate {
  924. updatenodes := logic.UpdateRelay(node.Network, node.RelayAddrs, newNode.RelayAddrs)
  925. if len(updatenodes) > 0 {
  926. for _, relayedNode := range updatenodes {
  927. runUpdates(&relayedNode, false)
  928. }
  929. }
  930. }
  931. if relayedUpdate {
  932. updateRelay(&node, &newNode)
  933. }
  934. if servercfg.IsDNSMode() {
  935. logic.SetDNS()
  936. }
  937. logger.Log(1, r.Header.Get("user"), "updated node", node.ID, "on network", node.Network)
  938. w.WriteHeader(http.StatusOK)
  939. json.NewEncoder(w).Encode(newNode)
  940. runUpdates(&newNode, ifaceDelta)
  941. }
  942. // swagger:route DELETE /api/nodes/{network}/{nodeid} nodes deleteNode
  943. //
  944. // Delete an individual node.
  945. //
  946. // Schemes: https
  947. //
  948. // Security:
  949. // oauth
  950. //
  951. // Responses:
  952. // 200: nodeResponse
  953. func deleteNode(w http.ResponseWriter, r *http.Request) {
  954. // Set header
  955. w.Header().Set("Content-Type", "application/json")
  956. // get params
  957. var params = mux.Vars(r)
  958. var nodeid = params["nodeid"]
  959. var node, err = logic.GetNodeByID(nodeid)
  960. if err != nil {
  961. logger.Log(0, r.Header.Get("user"),
  962. fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
  963. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  964. return
  965. }
  966. if isServer(&node) {
  967. err := fmt.Errorf("cannot delete server node")
  968. logger.Log(0, r.Header.Get("user"),
  969. fmt.Sprintf("failed to delete node [ %s ]: %v", nodeid, err))
  970. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  971. return
  972. }
  973. if r.Header.Get("ismaster") != "yes" {
  974. username := r.Header.Get("user")
  975. if username != "" && !doesUserOwnNode(username, params["network"], nodeid) {
  976. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("user not permitted"), "badrequest"))
  977. return
  978. }
  979. }
  980. //send update to node to be deleted before deleting on server otherwise message cannot be sent
  981. node.Action = models.NODE_DELETE
  982. err = logic.DeleteNodeByID(&node, false)
  983. if err != nil {
  984. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  985. return
  986. }
  987. // deletes node related role and client
  988. event := mq.MqDynsecPayload{
  989. Commands: []mq.MqDynSecCmd{
  990. {
  991. Command: mq.DeleteRoleCmd,
  992. RoleName: fmt.Sprintf("%s-%s", "Node", nodeid),
  993. },
  994. {
  995. Command: mq.DeleteClientCmd,
  996. Username: nodeid,
  997. },
  998. },
  999. }
  1000. if err := mq.PublishEventToDynSecTopic(event); err != nil {
  1001. logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
  1002. event.Commands, err.Error()))
  1003. }
  1004. if servercfg.Is_EE {
  1005. if err = logic.EnterpriseResetAllPeersFailovers(node.ID, node.Network); err != nil {
  1006. logger.Log(0, "failed to reset failover lists during node delete for node", node.Name, node.Network)
  1007. }
  1008. }
  1009. logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
  1010. logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
  1011. runUpdates(&node, false)
  1012. runForceServerUpdate(&node, false)
  1013. }
  1014. func runUpdates(node *models.Node, ifaceDelta bool) {
  1015. go func() { // don't block http response
  1016. // publish node update if not server
  1017. if err := mq.NodeUpdate(node); err != nil {
  1018. logger.Log(1, "error publishing node update to node", node.Name, node.ID, err.Error())
  1019. }
  1020. if err := runServerUpdate(node, ifaceDelta); err != nil {
  1021. logger.Log(1, "error running server update", err.Error())
  1022. }
  1023. }()
  1024. }
  1025. // updates local peers for a server on a given node's network
  1026. func runServerUpdate(node *models.Node, ifaceDelta bool) error {
  1027. if servercfg.IsClientMode() != "on" || !isServer(node) {
  1028. return nil
  1029. }
  1030. currentServerNode, err := logic.GetNetworkServerLocal(node.Network)
  1031. if err != nil {
  1032. return err
  1033. }
  1034. if ifaceDelta && logic.IsLeader(&currentServerNode) {
  1035. if err := mq.PublishPeerUpdate(&currentServerNode, false); err != nil {
  1036. logger.Log(1, "failed to publish peer update "+err.Error())
  1037. }
  1038. }
  1039. if err := logic.ServerUpdate(&currentServerNode, ifaceDelta); err != nil {
  1040. logger.Log(1, "server node:", currentServerNode.ID, "failed update")
  1041. return err
  1042. }
  1043. return nil
  1044. }
  1045. func runForceServerUpdate(node *models.Node, publishPeerUpdateToNode bool) {
  1046. go func() {
  1047. if err := mq.PublishPeerUpdate(node, publishPeerUpdateToNode); err != nil {
  1048. logger.Log(1, "failed a peer update after creation of node", node.Name)
  1049. }
  1050. var currentServerNode, getErr = logic.GetNetworkServerLeader(node.Network)
  1051. if getErr == nil {
  1052. if err := logic.ServerUpdate(&currentServerNode, false); err != nil {
  1053. logger.Log(1, "server node:", currentServerNode.ID, "failed update")
  1054. }
  1055. }
  1056. }()
  1057. }
  1058. func isServer(node *models.Node) bool {
  1059. return node.IsServer == "yes"
  1060. }
  1061. func updateRelay(oldnode, newnode *models.Node) {
  1062. relay := logic.FindRelay(oldnode)
  1063. newrelay := relay
  1064. //check if node's address has been updated and if so, update the relayAddrs of the relay node with the updated address of the relayed node
  1065. if oldnode.Address != newnode.Address {
  1066. for i, ip := range newrelay.RelayAddrs {
  1067. if ip == oldnode.Address {
  1068. newrelay.RelayAddrs = append(newrelay.RelayAddrs[:i], relay.RelayAddrs[i+1:]...)
  1069. newrelay.RelayAddrs = append(newrelay.RelayAddrs, newnode.Address)
  1070. }
  1071. }
  1072. }
  1073. //check if node's address(v6) has been updated and if so, update the relayAddrs of the relay node with the updated address(v6) of the relayed node
  1074. if oldnode.Address6 != newnode.Address6 {
  1075. for i, ip := range newrelay.RelayAddrs {
  1076. if ip == oldnode.Address {
  1077. newrelay.RelayAddrs = append(newrelay.RelayAddrs[:i], newrelay.RelayAddrs[i+1:]...)
  1078. newrelay.RelayAddrs = append(newrelay.RelayAddrs, newnode.Address6)
  1079. }
  1080. }
  1081. }
  1082. logic.UpdateNode(relay, newrelay)
  1083. }
  1084. func doesUserOwnNode(username, network, nodeID string) bool {
  1085. u, err := logic.GetUser(username)
  1086. if err != nil {
  1087. return false
  1088. }
  1089. if u.IsAdmin {
  1090. return true
  1091. }
  1092. netUser, err := pro.GetNetworkUser(network, promodels.NetworkUserID(u.UserName))
  1093. if err != nil {
  1094. return false
  1095. }
  1096. if netUser.AccessLevel == pro.NET_ADMIN {
  1097. return true
  1098. }
  1099. return logic.StringSliceContains(netUser.Nodes, nodeID)
  1100. }