networkusers.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. newData.User.SetDefaults()
  83. // check network level permissions
  84. if doesNetworkAllow := pro.IsUserAllowed(&networks[i], networkUserName, u.Groups); doesNetworkAllow || netUser.AccessLevel == pro.NET_ADMIN {
  85. netNodes, err := logic.GetNetworkNodes(netID)
  86. if err != nil {
  87. if database.IsEmptyRecord(err) && netUser.AccessLevel == pro.NET_ADMIN {
  88. newData.Networks = append(newData.Networks, networks[i])
  89. } else {
  90. logger.Log(0, "failed to retrieve nodes on network", netID, "for user", string(netUser.ID))
  91. }
  92. } else {
  93. if netUser.AccessLevel <= pro.NODE_ACCESS { // handle nodes
  94. // if access level is NODE_ACCESS, filter nodes
  95. if netUser.AccessLevel == pro.NODE_ACCESS {
  96. for i := range netNodes {
  97. if logic.StringSliceContains(netUser.Nodes, netNodes[i].ID) {
  98. newData.Nodes = append(newData.Nodes, netNodes[i])
  99. }
  100. }
  101. } else { // net admin so, get all nodes and ext clients on network...
  102. newData.Nodes = netNodes
  103. for i := range netNodes {
  104. if netNodes[i].IsIngressGateway == "yes" {
  105. newData.Vpn = append(newData.Vpn, netNodes[i])
  106. if clients, err := logic.GetExtClientsByID(netNodes[i].ID, netID); err == nil {
  107. newData.Clients = append(newData.Clients, clients...)
  108. }
  109. }
  110. }
  111. newData.Networks = append(newData.Networks, networks[i])
  112. }
  113. }
  114. if netUser.AccessLevel <= pro.CLIENT_ACCESS && netUser.AccessLevel != pro.NET_ADMIN {
  115. for _, c := range netUser.Clients {
  116. if client, err := logic.GetExtClient(c, netID); err == nil {
  117. newData.Clients = append(newData.Clients, client)
  118. }
  119. }
  120. for i := range netNodes {
  121. if netNodes[i].IsIngressGateway == "yes" {
  122. newData.Vpn = append(newData.Vpn, netNodes[i])
  123. }
  124. }
  125. }
  126. }
  127. }
  128. returnData[NetworkName(netID)] = newData
  129. }
  130. }
  131. w.WriteHeader(http.StatusOK)
  132. json.NewEncoder(w).Encode(returnData)
  133. }
  134. // returns a map of all network users mapped to each network
  135. func getAllNetworkUsers(w http.ResponseWriter, r *http.Request) {
  136. w.Header().Set("Content-Type", "application/json")
  137. logger.Log(1, r.Header.Get("user"), "requested fetching all network users")
  138. type allNetworkUsers = map[string][]promodels.NetworkUser
  139. networks, err := logic.GetNetworks()
  140. if err != nil {
  141. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  142. return
  143. }
  144. var allNetUsers = make(allNetworkUsers, len(networks))
  145. for i := range networks {
  146. netusers, err := pro.GetNetworkUsers(networks[i].NetID)
  147. if err != nil {
  148. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  149. return
  150. }
  151. for _, v := range netusers {
  152. allNetUsers[networks[i].NetID] = append(allNetUsers[networks[i].NetID], v)
  153. }
  154. }
  155. w.WriteHeader(http.StatusOK)
  156. json.NewEncoder(w).Encode(allNetUsers)
  157. }
  158. func getNetworkUsers(w http.ResponseWriter, r *http.Request) {
  159. w.Header().Set("Content-Type", "application/json")
  160. var params = mux.Vars(r)
  161. netname := params["network"]
  162. logger.Log(1, r.Header.Get("user"), "requested fetching network users for network", netname)
  163. _, err := logic.GetNetwork(netname)
  164. if err != nil {
  165. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  166. return
  167. }
  168. netusers, err := pro.GetNetworkUsers(netname)
  169. if err != nil {
  170. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  171. return
  172. }
  173. w.WriteHeader(http.StatusOK)
  174. json.NewEncoder(w).Encode(netusers)
  175. }
  176. func getNetworkUser(w http.ResponseWriter, r *http.Request) {
  177. w.Header().Set("Content-Type", "application/json")
  178. var params = mux.Vars(r)
  179. netname := params["network"]
  180. logger.Log(1, r.Header.Get("user"), "requested fetching network user", params["networkuser"], "on network", netname)
  181. _, err := logic.GetNetwork(netname)
  182. if err != nil {
  183. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  184. return
  185. }
  186. netuserToGet := params["networkuser"]
  187. if netuserToGet == "" {
  188. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("netuserToGet"), "badrequest"))
  189. return
  190. }
  191. netuser, err := pro.GetNetworkUser(netname, promodels.NetworkUserID(netuserToGet))
  192. if err != nil {
  193. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  194. return
  195. }
  196. w.WriteHeader(http.StatusOK)
  197. json.NewEncoder(w).Encode(netuser)
  198. }
  199. func createNetworkUser(w http.ResponseWriter, r *http.Request) {
  200. w.Header().Set("Content-Type", "application/json")
  201. var params = mux.Vars(r)
  202. netname := params["network"]
  203. logger.Log(1, r.Header.Get("user"), "requested creating a network user on network", netname)
  204. network, err := logic.GetNetwork(netname)
  205. if err != nil {
  206. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  207. return
  208. }
  209. var networkuser promodels.NetworkUser
  210. // we decode our body request params
  211. err = json.NewDecoder(r.Body).Decode(&networkuser)
  212. if err != nil {
  213. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  214. return
  215. }
  216. err = pro.CreateNetworkUser(&network, &networkuser)
  217. if err != nil {
  218. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  219. return
  220. }
  221. w.WriteHeader(http.StatusOK)
  222. }
  223. func updateNetworkUser(w http.ResponseWriter, r *http.Request) {
  224. w.Header().Set("Content-Type", "application/json")
  225. var params = mux.Vars(r)
  226. netname := params["network"]
  227. logger.Log(1, r.Header.Get("user"), "requested updating a network user on network", netname)
  228. network, err := logic.GetNetwork(netname)
  229. if err != nil {
  230. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  231. return
  232. }
  233. var networkuser promodels.NetworkUser
  234. // we decode our body request params
  235. err = json.NewDecoder(r.Body).Decode(&networkuser)
  236. if err != nil {
  237. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  238. return
  239. }
  240. if networkuser.ID == "" || !pro.DoesNetworkUserExist(netname, networkuser.ID) {
  241. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))
  242. return
  243. }
  244. if networkuser.AccessLevel < pro.NET_ADMIN || networkuser.AccessLevel > pro.NO_ACCESS {
  245. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user access level provided"), "badrequest"))
  246. return
  247. }
  248. if networkuser.ClientLimit < 0 || networkuser.NodeLimit < 0 {
  249. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("negative user limit provided"), "badrequest"))
  250. return
  251. }
  252. u, err := logic.GetUser(string(networkuser.ID))
  253. if err != nil {
  254. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid user "+string(networkuser.ID)), "badrequest"))
  255. return
  256. }
  257. if !pro.IsUserAllowed(&network, u.UserName, u.Groups) {
  258. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user must be in allowed groups or users"), "badrequest"))
  259. return
  260. }
  261. if networkuser.AccessLevel == pro.NET_ADMIN {
  262. currentUser, err := logic.GetUser(string(networkuser.ID))
  263. if err != nil {
  264. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model not found for "+string(networkuser.ID)), "badrequest"))
  265. return
  266. }
  267. if !logic.StringSliceContains(currentUser.Networks, netname) {
  268. // append network name to user model to conform to old model
  269. if err = logic.UpdateUserNetworks(
  270. append(currentUser.Networks, netname),
  271. currentUser.Groups,
  272. currentUser.IsAdmin,
  273. &models.ReturnUser{
  274. Groups: currentUser.Groups,
  275. IsAdmin: currentUser.IsAdmin,
  276. Networks: currentUser.Networks,
  277. UserName: currentUser.UserName,
  278. },
  279. ); err != nil {
  280. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user model failed net admin update "+string(networkuser.ID)+" (are they an admin?"), "badrequest"))
  281. return
  282. }
  283. }
  284. }
  285. err = pro.UpdateNetworkUser(netname, &networkuser)
  286. if err != nil {
  287. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  288. return
  289. }
  290. w.WriteHeader(http.StatusOK)
  291. }
  292. func deleteNetworkUser(w http.ResponseWriter, r *http.Request) {
  293. var params = mux.Vars(r)
  294. netname := params["network"]
  295. logger.Log(1, r.Header.Get("user"), "requested deleting network user", params["networkuser"], "on network", netname)
  296. _, err := logic.GetNetwork(netname)
  297. if err != nil {
  298. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  299. return
  300. }
  301. netuserToDelete := params["networkuser"]
  302. if netuserToDelete == "" {
  303. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("no group name provided"), "badrequest"))
  304. return
  305. }
  306. if err := pro.DeleteNetworkUser(netname, netuserToDelete); err != nil {
  307. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  308. return
  309. }
  310. w.WriteHeader(http.StatusOK)
  311. }