networkusers.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "net/http"
  6. "github.com/gorilla/mux"
  7. "github.com/gravitl/netmaker/database"
  8. "github.com/gravitl/netmaker/logger"
  9. "github.com/gravitl/netmaker/logic"
  10. "github.com/gravitl/netmaker/logic/pro"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/models/promodels"
  13. )
  14. func networkUsersHandlers(r *mux.Router) {
  15. r.HandleFunc("/api/networkusers", logic.SecurityCheck(true, http.HandlerFunc(getAllNetworkUsers))).Methods("GET")
  16. r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkUsers))).Methods("GET")
  17. r.HandleFunc("/api/networkusers/{network}/{networkuser}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkUser))).Methods("GET")
  18. r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(createNetworkUser))).Methods("POST")
  19. r.HandleFunc("/api/networkusers/{network}", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkUser))).Methods("PUT")
  20. r.HandleFunc("/api/networkusers/data/{networkuser}/me", logic.NetUserSecurityCheck(false, false, http.HandlerFunc(getNetworkUserData))).Methods("GET")
  21. r.HandleFunc("/api/networkusers/{network}/{networkuser}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetworkUser))).Methods("DELETE")
  22. }
  23. // == RETURN TYPES ==
  24. // NetworkName - represents a network name/ID
  25. type NetworkName string
  26. // NetworkUserDataMap - map of all data per network for a user
  27. type NetworkUserDataMap map[NetworkName]NetworkUserData
  28. // NetworkUserData - data struct for network users
  29. type NetworkUserData struct {
  30. Nodes []models.Node `json:"nodes" bson:"nodes" yaml:"nodes"`
  31. Clients []models.ExtClient `json:"clients" bson:"clients" yaml:"clients"`
  32. Vpn []models.Node `json:"vpns" bson:"vpns" yaml:"vpns"`
  33. Networks []models.Network `json:"networks" bson:"networks" yaml:"networks"`
  34. User promodels.NetworkUser `json:"user" bson:"user" yaml:"user"`
  35. }
  36. // == END RETURN TYPES ==
  37. // returns a map of a network user's data across all networks
  38. func getNetworkUserData(w http.ResponseWriter, r *http.Request) {
  39. w.Header().Set("Content-Type", "application/json")
  40. var params = mux.Vars(r)
  41. networkUserName := params["networkuser"]
  42. logger.Log(1, r.Header.Get("user"), "requested fetching network user data for user", networkUserName)
  43. networks, err := logic.GetNetworks()
  44. if err != nil {
  45. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  46. return
  47. }
  48. if networkUserName == "" {
  49. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("netuserToGet"), "badrequest"))
  50. return
  51. }
  52. u, err := logic.GetUser(networkUserName)
  53. if err != nil {
  54. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("could not find user"), "badrequest"))
  55. return
  56. }
  57. // initialize the return data of network users
  58. returnData := make(NetworkUserDataMap)
  59. // go through each network and get that user's data
  60. // if user has no access, give no data
  61. // if user is a net admin, give all nodes
  62. // if user has node access, give user's nodes if any
  63. // if user has client access, git user's clients if any
  64. for i := range networks {
  65. netID := networks[i].NetID
  66. newData := NetworkUserData{
  67. Nodes: []models.Node{},
  68. Clients: []models.ExtClient{},
  69. Vpn: []models.Node{},
  70. Networks: []models.Network{},
  71. }
  72. netUser, err := pro.GetNetworkUser(netID, promodels.NetworkUserID(networkUserName))
  73. // check if user has access
  74. if err == nil && netUser.AccessLevel != pro.NO_ACCESS {
  75. newData.User = promodels.NetworkUser{
  76. AccessLevel: netUser.AccessLevel,
  77. ClientLimit: netUser.ClientLimit,
  78. NodeLimit: netUser.NodeLimit,
  79. Nodes: netUser.Nodes,
  80. Clients: netUser.Clients,
  81. }
  82. // check network level permissions
  83. if doesNetworkAllow := pro.IsUserAllowed(&networks[i], networkUserName, u.Groups); doesNetworkAllow || netUser.AccessLevel == pro.NET_ADMIN {
  84. netNodes, err := logic.GetNetworkNodes(netID)
  85. if err != nil {
  86. if database.IsEmptyRecord(err) && netUser.AccessLevel == pro.NET_ADMIN {
  87. newData.Networks = append(newData.Networks, networks[i])
  88. } else {
  89. logger.Log(0, "failed to retrieve nodes on network", netID, "for user", string(netUser.ID))
  90. }
  91. } else {
  92. if netUser.AccessLevel <= pro.NODE_ACCESS { // handle nodes
  93. // if access level is NODE_ACCESS, filter nodes
  94. if netUser.AccessLevel == pro.NODE_ACCESS {
  95. for i := range netNodes {
  96. if logic.StringSliceContains(netUser.Nodes, netNodes[i].ID) {
  97. newData.Nodes = append(newData.Nodes, netNodes[i])
  98. }
  99. }
  100. } else { // net admin so, get all nodes and ext clients on network...
  101. newData.Nodes = netNodes
  102. for i := range netNodes {
  103. if netNodes[i].IsIngressGateway == "yes" {
  104. newData.Vpn = append(newData.Vpn, netNodes[i])
  105. if clients, err := logic.GetExtClientsByID(netNodes[i].ID, netID); err == nil {
  106. newData.Clients = append(newData.Clients, clients...)
  107. }
  108. }
  109. }
  110. newData.Networks = append(newData.Networks, networks[i])
  111. }
  112. }
  113. if netUser.AccessLevel <= pro.CLIENT_ACCESS && netUser.AccessLevel != pro.NET_ADMIN {
  114. for _, c := range netUser.Clients {
  115. if client, err := logic.GetExtClient(c, netID); err == nil {
  116. newData.Clients = append(newData.Clients, client)
  117. }
  118. }
  119. for i := range netNodes {
  120. if netNodes[i].IsIngressGateway == "yes" {
  121. newData.Vpn = append(newData.Vpn, netNodes[i])
  122. }
  123. }
  124. }
  125. }
  126. }
  127. returnData[NetworkName(netID)] = newData
  128. }
  129. }
  130. w.WriteHeader(http.StatusOK)
  131. json.NewEncoder(w).Encode(returnData)
  132. }
  133. // returns a map of all network users mapped to each network
  134. func getAllNetworkUsers(w http.ResponseWriter, r *http.Request) {
  135. w.Header().Set("Content-Type", "application/json")
  136. logger.Log(1, r.Header.Get("user"), "requested fetching all network users")
  137. type allNetworkUsers = map[string][]promodels.NetworkUser
  138. networks, err := logic.GetNetworks()
  139. if err != nil {
  140. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  141. return
  142. }
  143. var allNetUsers = make(allNetworkUsers, len(networks))
  144. for i := range networks {
  145. netusers, err := pro.GetNetworkUsers(networks[i].NetID)
  146. if err != nil {
  147. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  148. return
  149. }
  150. for _, v := range netusers {
  151. allNetUsers[networks[i].NetID] = append(allNetUsers[networks[i].NetID], v)
  152. }
  153. }
  154. w.WriteHeader(http.StatusOK)
  155. json.NewEncoder(w).Encode(allNetUsers)
  156. }
  157. func getNetworkUsers(w http.ResponseWriter, r *http.Request) {
  158. w.Header().Set("Content-Type", "application/json")
  159. var params = mux.Vars(r)
  160. netname := params["network"]
  161. logger.Log(1, r.Header.Get("user"), "requested fetching network users for network", netname)
  162. _, err := logic.GetNetwork(netname)
  163. if err != nil {
  164. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  165. return
  166. }
  167. netusers, err := pro.GetNetworkUsers(netname)
  168. if err != nil {
  169. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  170. return
  171. }
  172. w.WriteHeader(http.StatusOK)
  173. json.NewEncoder(w).Encode(netusers)
  174. }
  175. func getNetworkUser(w http.ResponseWriter, r *http.Request) {
  176. w.Header().Set("Content-Type", "application/json")
  177. var params = mux.Vars(r)
  178. netname := params["network"]
  179. logger.Log(1, r.Header.Get("user"), "requested fetching network user", params["networkuser"], "on network", netname)
  180. _, err := logic.GetNetwork(netname)
  181. if err != nil {
  182. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  183. return
  184. }
  185. netuserToGet := params["networkuser"]
  186. if netuserToGet == "" {
  187. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("netuserToGet"), "badrequest"))
  188. return
  189. }
  190. netuser, err := pro.GetNetworkUser(netname, promodels.NetworkUserID(netuserToGet))
  191. if err != nil {
  192. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  193. return
  194. }
  195. w.WriteHeader(http.StatusOK)
  196. json.NewEncoder(w).Encode(netuser)
  197. }
  198. func createNetworkUser(w http.ResponseWriter, r *http.Request) {
  199. w.Header().Set("Content-Type", "application/json")
  200. var params = mux.Vars(r)
  201. netname := params["network"]
  202. logger.Log(1, r.Header.Get("user"), "requested creating a network user on network", netname)
  203. network, err := logic.GetNetwork(netname)
  204. if err != nil {
  205. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  206. return
  207. }
  208. var networkuser promodels.NetworkUser
  209. // we decode our body request params
  210. err = json.NewDecoder(r.Body).Decode(&networkuser)
  211. if err != nil {
  212. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  213. return
  214. }
  215. err = pro.CreateNetworkUser(&network, &networkuser)
  216. if err != nil {
  217. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  218. return
  219. }
  220. w.WriteHeader(http.StatusOK)
  221. }
  222. func updateNetworkUser(w http.ResponseWriter, r *http.Request) {
  223. w.Header().Set("Content-Type", "application/json")
  224. var params = mux.Vars(r)
  225. netname := params["network"]
  226. logger.Log(1, r.Header.Get("user"), "requested updating a network user on network", netname)
  227. network, err := logic.GetNetwork(netname)
  228. if err != nil {
  229. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  230. return
  231. }
  232. var networkuser promodels.NetworkUser
  233. // we decode our body request params
  234. err = json.NewDecoder(r.Body).Decode(&networkuser)
  235. if err != nil {
  236. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  237. return
  238. }
  239. if networkuser.ID == "" || !pro.DoesNetworkUserExist(netname, networkuser.ID) {
  240. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))
  241. return
  242. }
  243. if networkuser.AccessLevel < pro.NET_ADMIN || networkuser.AccessLevel > pro.NO_ACCESS {
  244. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user access level provided"), "badrequest"))
  245. return
  246. }
  247. if networkuser.ClientLimit < 0 || networkuser.NodeLimit < 0 {
  248. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("negative user limit provided"), "badrequest"))
  249. return
  250. }
  251. u, err := logic.GetUser(string(networkuser.ID))
  252. if err != nil {
  253. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))
  254. return
  255. }
  256. if !pro.IsUserAllowed(&network, u.UserName, u.Groups) {
  257. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user must be in allowed groups or users"), "badrequest"))
  258. return
  259. }
  260. if networkuser.AccessLevel == pro.NET_ADMIN {
  261. currentUser, err := logic.GetUser(string(networkuser.ID))
  262. if err != nil {
  263. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model not found for "+string(networkuser.ID)), "badrequest"))
  264. return
  265. }
  266. if !logic.StringSliceContains(currentUser.Networks, netname) {
  267. // append network name to user model to conform to old model
  268. if err = logic.UpdateUserNetworks(
  269. append(currentUser.Networks, netname),
  270. currentUser.Groups,
  271. currentUser.IsAdmin,
  272. &models.ReturnUser{
  273. Groups: currentUser.Groups,
  274. IsAdmin: currentUser.IsAdmin,
  275. Networks: currentUser.Networks,
  276. UserName: currentUser.UserName,
  277. },
  278. ); err != nil {
  279. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model failed net admin update "+string(networkuser.ID)+" (are they an admin?"), "badrequest"))
  280. return
  281. }
  282. }
  283. }
  284. err = pro.UpdateNetworkUser(netname, &networkuser)
  285. if err != nil {
  286. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  287. return
  288. }
  289. w.WriteHeader(http.StatusOK)
  290. }
  291. func deleteNetworkUser(w http.ResponseWriter, r *http.Request) {
  292. var params = mux.Vars(r)
  293. netname := params["network"]
  294. logger.Log(1, r.Header.Get("user"), "requested deleting network user", params["networkuser"], "on network", netname)
  295. _, err := logic.GetNetwork(netname)
  296. if err != nil {
  297. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  298. return
  299. }
  300. netuserToDelete := params["networkuser"]
  301. if netuserToDelete == "" {
  302. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("no group name provided"), "badrequest"))
  303. return
  304. }
  305. if err := pro.DeleteNetworkUser(netname, netuserToDelete); err != nil {
  306. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  307. return
  308. }
  309. w.WriteHeader(http.StatusOK)
  310. }