networkusers.go 12 KB

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