networkHttpController.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. package controller
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "errors"
  6. "net/http"
  7. "strings"
  8. "time"
  9. "github.com/go-playground/validator/v10"
  10. "github.com/gorilla/mux"
  11. "github.com/gravitl/netmaker/database"
  12. "github.com/gravitl/netmaker/functions"
  13. "github.com/gravitl/netmaker/logic"
  14. "github.com/gravitl/netmaker/models"
  15. "github.com/gravitl/netmaker/servercfg"
  16. "github.com/gravitl/netmaker/serverctl"
  17. )
  18. const ALL_NETWORK_ACCESS = "THIS_USER_HAS_ALL"
  19. const NO_NETWORKS_PRESENT = "THIS_USER_HAS_NONE"
  20. const PLACEHOLDER_KEY_TEXT = "ACCESS_KEY"
  21. const PLACEHOLDER_TOKEN_TEXT = "ACCESS_TOKEN"
  22. func networkHandlers(r *mux.Router) {
  23. r.HandleFunc("/api/networks", securityCheck(false, http.HandlerFunc(getNetworks))).Methods("GET")
  24. r.HandleFunc("/api/networks", securityCheck(true, http.HandlerFunc(createNetwork))).Methods("POST")
  25. r.HandleFunc("/api/networks/{networkname}", securityCheck(false, http.HandlerFunc(getNetwork))).Methods("GET")
  26. r.HandleFunc("/api/networks/{networkname}", securityCheck(false, http.HandlerFunc(updateNetwork))).Methods("PUT")
  27. r.HandleFunc("/api/networks/{networkname}/nodelimit", securityCheck(true, http.HandlerFunc(updateNetworkNodeLimit))).Methods("PUT")
  28. r.HandleFunc("/api/networks/{networkname}", securityCheck(true, http.HandlerFunc(deleteNetwork))).Methods("DELETE")
  29. r.HandleFunc("/api/networks/{networkname}/keyupdate", securityCheck(false, http.HandlerFunc(keyUpdate))).Methods("POST")
  30. r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(createAccessKey))).Methods("POST")
  31. r.HandleFunc("/api/networks/{networkname}/keys", securityCheck(false, http.HandlerFunc(getAccessKeys))).Methods("GET")
  32. r.HandleFunc("/api/networks/{networkname}/signuptoken", securityCheck(false, http.HandlerFunc(getSignupToken))).Methods("GET")
  33. r.HandleFunc("/api/networks/{networkname}/keys/{name}", securityCheck(false, http.HandlerFunc(deleteAccessKey))).Methods("DELETE")
  34. }
  35. //Security check is middleware for every function and just checks to make sure that its the master calling
  36. //Only admin should have access to all these network-level actions
  37. //or maybe some Users once implemented
  38. func securityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
  39. return func(w http.ResponseWriter, r *http.Request) {
  40. var errorResponse = models.ErrorResponse{
  41. Code: http.StatusUnauthorized, Message: "W1R3: It's not you it's me.",
  42. }
  43. var params = mux.Vars(r)
  44. bearerToken := r.Header.Get("Authorization")
  45. err, networks, username := SecurityCheck(reqAdmin, params["networkname"], bearerToken)
  46. if err != nil {
  47. if strings.Contains(err.Error(), "does not exist") {
  48. errorResponse.Code = http.StatusNotFound
  49. }
  50. errorResponse.Message = err.Error()
  51. returnErrorResponse(w, r, errorResponse)
  52. return
  53. }
  54. networksJson, err := json.Marshal(&networks)
  55. if err != nil {
  56. errorResponse.Message = err.Error()
  57. returnErrorResponse(w, r, errorResponse)
  58. return
  59. }
  60. r.Header.Set("user", username)
  61. r.Header.Set("networks", string(networksJson))
  62. next.ServeHTTP(w, r)
  63. }
  64. }
  65. func SecurityCheck(reqAdmin bool, netname string, token string) (error, []string, string) {
  66. var hasBearer = true
  67. var tokenSplit = strings.Split(token, " ")
  68. var authToken = ""
  69. if len(tokenSplit) < 2 {
  70. hasBearer = false
  71. } else {
  72. authToken = tokenSplit[1]
  73. }
  74. userNetworks := []string{}
  75. //all endpoints here require master so not as complicated
  76. isMasterAuthenticated := authenticateMaster(authToken)
  77. username := ""
  78. if !hasBearer || !isMasterAuthenticated {
  79. userName, networks, isadmin, err := logic.VerifyUserToken(authToken)
  80. username = userName
  81. if err != nil {
  82. return errors.New("error verifying user token"), nil, username
  83. }
  84. if !isadmin && reqAdmin {
  85. return errors.New("you are unauthorized to access this endpoint"), nil, username
  86. }
  87. userNetworks = networks
  88. if isadmin {
  89. userNetworks = []string{ALL_NETWORK_ACCESS}
  90. } else {
  91. networkexists, err := functions.NetworkExists(netname)
  92. if err != nil && !database.IsEmptyRecord(err) {
  93. return err, nil, ""
  94. }
  95. if netname != "" && !networkexists {
  96. return errors.New("this network does not exist"), nil, ""
  97. }
  98. }
  99. } else if isMasterAuthenticated {
  100. userNetworks = []string{ALL_NETWORK_ACCESS}
  101. }
  102. if len(userNetworks) == 0 {
  103. userNetworks = append(userNetworks, NO_NETWORKS_PRESENT)
  104. }
  105. return nil, userNetworks, username
  106. }
  107. //Consider a more secure way of setting master key
  108. func authenticateMaster(tokenString string) bool {
  109. return tokenString == servercfg.GetMasterKey()
  110. }
  111. //Consider a more secure way of setting master key
  112. func authenticateDNSToken(tokenString string) bool {
  113. return tokenString == servercfg.GetDNSKey()
  114. }
  115. //simple get all networks function
  116. func getNetworks(w http.ResponseWriter, r *http.Request) {
  117. headerNetworks := r.Header.Get("networks")
  118. networksSlice := []string{}
  119. marshalErr := json.Unmarshal([]byte(headerNetworks), &networksSlice)
  120. if marshalErr != nil {
  121. returnErrorResponse(w, r, formatError(marshalErr, "internal"))
  122. return
  123. }
  124. allnetworks := []models.Network{}
  125. err := errors.New("Networks Error")
  126. if networksSlice[0] == ALL_NETWORK_ACCESS {
  127. allnetworks, err = logic.GetNetworks()
  128. if err != nil && !database.IsEmptyRecord(err) {
  129. returnErrorResponse(w, r, formatError(err, "internal"))
  130. return
  131. }
  132. } else {
  133. for _, network := range networksSlice {
  134. netObject, parentErr := logic.GetParentNetwork(network)
  135. if parentErr == nil {
  136. allnetworks = append(allnetworks, netObject)
  137. }
  138. }
  139. }
  140. functions.PrintUserLog(r.Header.Get("user"), "fetched networks.", 2)
  141. w.WriteHeader(http.StatusOK)
  142. json.NewEncoder(w).Encode(allnetworks)
  143. }
  144. func ValidateNetworkUpdate(network models.Network) error {
  145. v := validator.New()
  146. _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
  147. if fl.Field().String() == "" {
  148. return true
  149. }
  150. inCharSet := functions.NameInNetworkCharSet(fl.Field().String())
  151. return inCharSet
  152. })
  153. err := v.Struct(network)
  154. if err != nil {
  155. for _, e := range err.(validator.ValidationErrors) {
  156. functions.PrintUserLog("validator", e.Error(), 1)
  157. }
  158. }
  159. return err
  160. }
  161. //Simple get network function
  162. func getNetwork(w http.ResponseWriter, r *http.Request) {
  163. // set header.
  164. w.Header().Set("Content-Type", "application/json")
  165. var params = mux.Vars(r)
  166. netname := params["networkname"]
  167. network, err := GetNetwork(netname)
  168. if err != nil {
  169. returnErrorResponse(w, r, formatError(err, "internal"))
  170. return
  171. }
  172. functions.PrintUserLog(r.Header.Get("user"), "fetched network "+netname, 2)
  173. w.WriteHeader(http.StatusOK)
  174. json.NewEncoder(w).Encode(network)
  175. }
  176. func GetNetwork(name string) (models.Network, error) {
  177. var network models.Network
  178. record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, name)
  179. if err != nil {
  180. return network, err
  181. }
  182. if err = json.Unmarshal([]byte(record), &network); err != nil {
  183. return models.Network{}, err
  184. }
  185. return network, nil
  186. }
  187. func keyUpdate(w http.ResponseWriter, r *http.Request) {
  188. w.Header().Set("Content-Type", "application/json")
  189. var params = mux.Vars(r)
  190. netname := params["networkname"]
  191. network, err := KeyUpdate(netname)
  192. if err != nil {
  193. returnErrorResponse(w, r, formatError(err, "internal"))
  194. return
  195. }
  196. functions.PrintUserLog(r.Header.Get("user"), "updated key on network "+netname, 2)
  197. w.WriteHeader(http.StatusOK)
  198. json.NewEncoder(w).Encode(network)
  199. }
  200. func KeyUpdate(netname string) (models.Network, error) {
  201. err := functions.NetworkNodesUpdateAction(netname, models.NODE_UPDATE_KEY)
  202. if err != nil {
  203. return models.Network{}, err
  204. }
  205. return models.Network{}, nil
  206. }
  207. //Update a network
  208. func AlertNetwork(netid string) error {
  209. var network models.Network
  210. network, err := logic.GetParentNetwork(netid)
  211. if err != nil {
  212. return err
  213. }
  214. updatetime := time.Now().Unix()
  215. network.NodesLastModified = updatetime
  216. network.NetworkLastModified = updatetime
  217. data, err := json.Marshal(&network)
  218. if err != nil {
  219. return err
  220. }
  221. database.Insert(netid, string(data), database.NETWORKS_TABLE_NAME)
  222. return nil
  223. }
  224. //Update a network
  225. func updateNetwork(w http.ResponseWriter, r *http.Request) {
  226. w.Header().Set("Content-Type", "application/json")
  227. var params = mux.Vars(r)
  228. var network models.Network
  229. netname := params["networkname"]
  230. network, err := logic.GetParentNetwork(netname)
  231. if err != nil {
  232. returnErrorResponse(w, r, formatError(err, "internal"))
  233. return
  234. }
  235. var newNetwork models.Network
  236. err = json.NewDecoder(r.Body).Decode(&newNetwork)
  237. if err != nil {
  238. returnErrorResponse(w, r, formatError(err, "badrequest"))
  239. return
  240. }
  241. rangeupdate, localrangeupdate, err := logic.UpdateNetwork(&network, &newNetwork)
  242. if err != nil {
  243. returnErrorResponse(w, r, formatError(err, "badrequest"))
  244. return
  245. }
  246. if rangeupdate {
  247. err = logic.UpdateNetworkNodeAddresses(network.NetID)
  248. if err != nil {
  249. returnErrorResponse(w, r, formatError(err, "internal"))
  250. return
  251. }
  252. }
  253. if localrangeupdate {
  254. err = logic.UpdateNetworkLocalAddresses(network.NetID)
  255. if err != nil {
  256. returnErrorResponse(w, r, formatError(err, "internal"))
  257. return
  258. }
  259. }
  260. functions.PrintUserLog(r.Header.Get("user"), "updated network "+netname, 1)
  261. w.WriteHeader(http.StatusOK)
  262. json.NewEncoder(w).Encode(newNetwork)
  263. }
  264. func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) {
  265. w.Header().Set("Content-Type", "application/json")
  266. var params = mux.Vars(r)
  267. var network models.Network
  268. netname := params["networkname"]
  269. network, err := logic.GetParentNetwork(netname)
  270. if err != nil {
  271. returnErrorResponse(w, r, formatError(err, "internal"))
  272. return
  273. }
  274. var networkChange models.Network
  275. _ = json.NewDecoder(r.Body).Decode(&networkChange)
  276. if networkChange.NodeLimit != 0 {
  277. network.NodeLimit = networkChange.NodeLimit
  278. data, err := json.Marshal(&network)
  279. if err != nil {
  280. returnErrorResponse(w, r, formatError(err, "badrequest"))
  281. return
  282. }
  283. database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME)
  284. functions.PrintUserLog(r.Header.Get("user"), "updated network node limit on, "+netname, 1)
  285. }
  286. w.WriteHeader(http.StatusOK)
  287. json.NewEncoder(w).Encode(network)
  288. }
  289. //Delete a network
  290. //Will stop you if there's any nodes associated
  291. func deleteNetwork(w http.ResponseWriter, r *http.Request) {
  292. // Set header
  293. w.Header().Set("Content-Type", "application/json")
  294. var params = mux.Vars(r)
  295. network := params["networkname"]
  296. err := DeleteNetwork(network)
  297. if err != nil {
  298. errtype := "badrequest"
  299. if strings.Contains(err.Error(), "Node check failed") {
  300. errtype = "forbidden"
  301. }
  302. returnErrorResponse(w, r, formatError(err, errtype))
  303. return
  304. }
  305. functions.PrintUserLog(r.Header.Get("user"), "deleted network "+network, 1)
  306. w.WriteHeader(http.StatusOK)
  307. json.NewEncoder(w).Encode("success")
  308. }
  309. func DeleteNetwork(network string) error {
  310. nodeCount, err := functions.GetNetworkNonServerNodeCount(network)
  311. if nodeCount == 0 || database.IsEmptyRecord(err) {
  312. // delete server nodes first then db records
  313. servers, err := logic.GetSortedNetworkServerNodes(network)
  314. if err == nil {
  315. for _, s := range servers {
  316. if err = logic.DeleteNode(&s, true); err != nil {
  317. functions.PrintUserLog("", "could not removed server "+s.Name+" before deleting network "+network, 2)
  318. } else {
  319. functions.PrintUserLog("", "removed server "+s.Name+" before deleting network "+network, 2)
  320. }
  321. }
  322. } else {
  323. functions.PrintUserLog("", "could not remove servers before deleting network "+network, 1)
  324. }
  325. return database.DeleteRecord(database.NETWORKS_TABLE_NAME, network)
  326. }
  327. return errors.New("node check failed. All nodes must be deleted before deleting network")
  328. }
  329. //Create a network
  330. //Pretty simple
  331. func createNetwork(w http.ResponseWriter, r *http.Request) {
  332. w.Header().Set("Content-Type", "application/json")
  333. var network models.Network
  334. // we decode our body request params
  335. err := json.NewDecoder(r.Body).Decode(&network)
  336. if err != nil {
  337. returnErrorResponse(w, r, formatError(err, "internal"))
  338. return
  339. }
  340. err = CreateNetwork(network)
  341. if err != nil {
  342. returnErrorResponse(w, r, formatError(err, "badrequest"))
  343. return
  344. }
  345. functions.PrintUserLog(r.Header.Get("user"), "created network "+network.NetID, 1)
  346. w.WriteHeader(http.StatusOK)
  347. //json.NewEncoder(w).Encode(result)
  348. }
  349. func CreateNetwork(network models.Network) error {
  350. network.SetDefaults()
  351. network.SetNodesLastModified()
  352. network.SetNetworkLastModified()
  353. network.KeyUpdateTimeStamp = time.Now().Unix()
  354. err := logic.ValidateNetwork(&network, false)
  355. if err != nil {
  356. //returnErrorResponse(w, r, formatError(err, "badrequest"))
  357. return err
  358. }
  359. data, err := json.Marshal(&network)
  360. if err != nil {
  361. return err
  362. }
  363. if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
  364. return err
  365. }
  366. if servercfg.IsClientMode() != "off" {
  367. var success bool
  368. success, err = serverctl.AddNetwork(network.NetID)
  369. if err != nil || !success {
  370. DeleteNetwork(network.NetID)
  371. if err == nil {
  372. err = errors.New("Failed to add server to network " + network.DisplayName)
  373. }
  374. }
  375. }
  376. return err
  377. }
  378. // BEGIN KEY MANAGEMENT SECTION
  379. func createAccessKey(w http.ResponseWriter, r *http.Request) {
  380. w.Header().Set("Content-Type", "application/json")
  381. var params = mux.Vars(r)
  382. var accesskey models.AccessKey
  383. //start here
  384. netname := params["networkname"]
  385. network, err := logic.GetParentNetwork(netname)
  386. if err != nil {
  387. returnErrorResponse(w, r, formatError(err, "internal"))
  388. return
  389. }
  390. err = json.NewDecoder(r.Body).Decode(&accesskey)
  391. if err != nil {
  392. returnErrorResponse(w, r, formatError(err, "internal"))
  393. return
  394. }
  395. key, err := CreateAccessKey(accesskey, network)
  396. if err != nil {
  397. returnErrorResponse(w, r, formatError(err, "badrequest"))
  398. return
  399. }
  400. functions.PrintUserLog(r.Header.Get("user"), "created access key "+accesskey.Name+" on "+netname, 1)
  401. w.WriteHeader(http.StatusOK)
  402. json.NewEncoder(w).Encode(key)
  403. //w.Write([]byte(accesskey.AccessString))
  404. }
  405. func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models.AccessKey, error) {
  406. if accesskey.Name == "" {
  407. accesskey.Name = functions.GenKeyName()
  408. }
  409. if accesskey.Value == "" {
  410. accesskey.Value = functions.GenKey()
  411. }
  412. if accesskey.Uses == 0 {
  413. accesskey.Uses = 1
  414. }
  415. checkkeys, err := GetKeys(network.NetID)
  416. if err != nil {
  417. return models.AccessKey{}, errors.New("could not retrieve network keys")
  418. }
  419. for _, key := range checkkeys {
  420. if key.Name == accesskey.Name {
  421. return models.AccessKey{}, errors.New("duplicate AccessKey Name")
  422. }
  423. }
  424. privAddr := ""
  425. if network.IsLocal != "" {
  426. privAddr = network.LocalRange
  427. }
  428. netID := network.NetID
  429. var accessToken models.AccessToken
  430. s := servercfg.GetServerConfig()
  431. servervals := models.ServerConfig{
  432. CoreDNSAddr: s.CoreDNSAddr,
  433. APIConnString: s.APIConnString,
  434. APIHost: s.APIHost,
  435. APIPort: s.APIPort,
  436. GRPCConnString: s.GRPCConnString,
  437. GRPCHost: s.GRPCHost,
  438. GRPCPort: s.GRPCPort,
  439. GRPCSSL: s.GRPCSSL,
  440. CheckinInterval: s.CheckinInterval,
  441. }
  442. accessToken.ServerConfig = servervals
  443. accessToken.ClientConfig.Network = netID
  444. accessToken.ClientConfig.Key = accesskey.Value
  445. accessToken.ClientConfig.LocalRange = privAddr
  446. tokenjson, err := json.Marshal(accessToken)
  447. if err != nil {
  448. return accesskey, err
  449. }
  450. accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(tokenjson))
  451. //validate accesskey
  452. v := validator.New()
  453. err = v.Struct(accesskey)
  454. if err != nil {
  455. for _, e := range err.(validator.ValidationErrors) {
  456. functions.PrintUserLog("validator", e.Error(), 1)
  457. }
  458. return models.AccessKey{}, err
  459. }
  460. network.AccessKeys = append(network.AccessKeys, accesskey)
  461. data, err := json.Marshal(&network)
  462. if err != nil {
  463. return models.AccessKey{}, err
  464. }
  465. if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
  466. return models.AccessKey{}, err
  467. }
  468. return accesskey, nil
  469. }
  470. func GetSignupToken(netID string) (models.AccessKey, error) {
  471. var accesskey models.AccessKey
  472. var accessToken models.AccessToken
  473. s := servercfg.GetServerConfig()
  474. servervals := models.ServerConfig{
  475. APIConnString: s.APIConnString,
  476. APIHost: s.APIHost,
  477. APIPort: s.APIPort,
  478. GRPCConnString: s.GRPCConnString,
  479. GRPCHost: s.GRPCHost,
  480. GRPCPort: s.GRPCPort,
  481. GRPCSSL: s.GRPCSSL,
  482. }
  483. accessToken.ServerConfig = servervals
  484. tokenjson, err := json.Marshal(accessToken)
  485. if err != nil {
  486. return accesskey, err
  487. }
  488. accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(tokenjson))
  489. return accesskey, nil
  490. }
  491. func getSignupToken(w http.ResponseWriter, r *http.Request) {
  492. w.Header().Set("Content-Type", "application/json")
  493. var params = mux.Vars(r)
  494. netID := params["networkname"]
  495. token, err := GetSignupToken(netID)
  496. if err != nil {
  497. returnErrorResponse(w, r, formatError(err, "internal"))
  498. return
  499. }
  500. functions.PrintUserLog(r.Header.Get("user"), "got signup token "+netID, 2)
  501. w.WriteHeader(http.StatusOK)
  502. json.NewEncoder(w).Encode(token)
  503. }
  504. //pretty simple get
  505. func getAccessKeys(w http.ResponseWriter, r *http.Request) {
  506. w.Header().Set("Content-Type", "application/json")
  507. var params = mux.Vars(r)
  508. network := params["networkname"]
  509. keys, err := GetKeys(network)
  510. if err != nil {
  511. returnErrorResponse(w, r, formatError(err, "internal"))
  512. return
  513. }
  514. if !servercfg.IsDisplayKeys() {
  515. keys = RemoveKeySensitiveInfo(keys)
  516. }
  517. functions.PrintUserLog(r.Header.Get("user"), "fetched access keys on network "+network, 2)
  518. w.WriteHeader(http.StatusOK)
  519. json.NewEncoder(w).Encode(keys)
  520. }
  521. func GetKeys(net string) ([]models.AccessKey, error) {
  522. record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, net)
  523. if err != nil {
  524. return []models.AccessKey{}, err
  525. }
  526. network, err := functions.ParseNetwork(record)
  527. if err != nil {
  528. return []models.AccessKey{}, err
  529. }
  530. return network.AccessKeys, nil
  531. }
  532. //delete key. Has to do a little funky logic since it's not a collection item
  533. func deleteAccessKey(w http.ResponseWriter, r *http.Request) {
  534. w.Header().Set("Content-Type", "application/json")
  535. var params = mux.Vars(r)
  536. keyname := params["name"]
  537. netname := params["networkname"]
  538. err := DeleteKey(keyname, netname)
  539. if err != nil {
  540. returnErrorResponse(w, r, formatError(err, "badrequest"))
  541. return
  542. }
  543. functions.PrintUserLog(r.Header.Get("user"), "deleted access key "+keyname+" on network "+netname, 1)
  544. w.WriteHeader(http.StatusOK)
  545. }
  546. func DeleteKey(keyname, netname string) error {
  547. network, err := logic.GetParentNetwork(netname)
  548. if err != nil {
  549. return err
  550. }
  551. //basically, turn the list of access keys into the list of access keys before and after the item
  552. //have not done any error handling for if there's like...1 item. I think it works? need to test.
  553. found := false
  554. var updatedKeys []models.AccessKey
  555. for _, currentkey := range network.AccessKeys {
  556. if currentkey.Name == keyname {
  557. found = true
  558. } else {
  559. updatedKeys = append(updatedKeys, currentkey)
  560. }
  561. }
  562. if !found {
  563. return errors.New("key " + keyname + " does not exist")
  564. }
  565. network.AccessKeys = updatedKeys
  566. data, err := json.Marshal(&network)
  567. if err != nil {
  568. return err
  569. }
  570. if err := database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
  571. return err
  572. }
  573. return nil
  574. }
  575. func RemoveKeySensitiveInfo(keys []models.AccessKey) []models.AccessKey {
  576. var returnKeys []models.AccessKey
  577. for _, key := range keys {
  578. key.Value = PLACEHOLDER_KEY_TEXT
  579. key.AccessString = PLACEHOLDER_TOKEN_TEXT
  580. returnKeys = append(returnKeys, key)
  581. }
  582. return returnKeys
  583. }