users.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package controllers
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "github.com/gorilla/mux"
  8. "github.com/gravitl/netmaker/logger"
  9. "github.com/gravitl/netmaker/logic"
  10. "github.com/gravitl/netmaker/models"
  11. "golang.org/x/exp/slog"
  12. )
  13. func UserHandlers(r *mux.Router) {
  14. r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(attachUserToRemoteAccessGw))).Methods(http.MethodPost)
  15. r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(removeUserFromRemoteAccessGW))).Methods(http.MethodDelete)
  16. r.HandleFunc("/api/users/{username}/remote_access_gw", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUserRemoteAccessGws)))).Methods(http.MethodGet)
  17. r.HandleFunc("/api/users/ingress/{ingress_id}", logic.SecurityCheck(true, http.HandlerFunc(ingressGatewayUsers))).Methods(http.MethodGet)
  18. }
  19. // swagger:route POST /api/users/{username}/remote_access_gw user attachUserToRemoteAccessGateway
  20. //
  21. // Attach User to a remote access gateway.
  22. //
  23. // Schemes: https
  24. //
  25. // Security:
  26. // oauth
  27. //
  28. // Responses:
  29. // 200: userBodyResponse
  30. func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) {
  31. // set header.
  32. w.Header().Set("Content-Type", "application/json")
  33. var params = mux.Vars(r)
  34. username := params["username"]
  35. remoteGwID := params["remote_access_gateway_id"]
  36. if username == "" || remoteGwID == "" {
  37. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params `username` and `remote_access_gateway_id`"), "badrequest"))
  38. return
  39. }
  40. user, err := logic.GetUser(username)
  41. if err != nil {
  42. slog.Error("failed to fetch user: ", "username", username, "error", err.Error())
  43. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  44. return
  45. }
  46. if user.IsAdmin || user.IsSuperAdmin {
  47. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("superadmins/admins have access to all gateways"), "badrequest"))
  48. return
  49. }
  50. node, err := logic.GetNodeByID(remoteGwID)
  51. if err != nil {
  52. slog.Error("failed to fetch gateway node", "nodeID", remoteGwID, "error", err)
  53. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch remote access gateway node, error: %v", err), "badrequest"))
  54. return
  55. }
  56. if !node.IsIngressGateway {
  57. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("node is not a remote access gateway"), "badrequest"))
  58. return
  59. }
  60. if user.RemoteGwIDs == nil {
  61. user.RemoteGwIDs = make(map[string]struct{})
  62. }
  63. user.RemoteGwIDs[node.ID.String()] = struct{}{}
  64. err = logic.UpsertUser(*user)
  65. if err != nil {
  66. slog.Error("failed to update user's gateways", "user", username, "error", err)
  67. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch remote access gateway node,error: %v", err), "badrequest"))
  68. return
  69. }
  70. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  71. }
  72. // swagger:route DELETE /api/users/{username}/remote_access_gw user removeUserFromRemoteAccessGW
  73. //
  74. // Delete User from a remote access gateway.
  75. //
  76. // Schemes: https
  77. //
  78. // Security:
  79. // oauth
  80. //
  81. // Responses:
  82. // 200: userBodyResponse
  83. func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) {
  84. // set header.
  85. w.Header().Set("Content-Type", "application/json")
  86. var params = mux.Vars(r)
  87. username := params["username"]
  88. remoteGwID := params["remote_access_gateway_id"]
  89. if username == "" || remoteGwID == "" {
  90. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params `username` and `remote_access_gateway_id`"), "badrequest"))
  91. return
  92. }
  93. user, err := logic.GetUser(username)
  94. if err != nil {
  95. logger.Log(0, username, "failed to fetch user: ", err.Error())
  96. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  97. return
  98. }
  99. delete(user.RemoteGwIDs, remoteGwID)
  100. go func(user models.User, remoteGwID string) {
  101. extclients, err := logic.GetAllExtClients()
  102. if err != nil {
  103. slog.Error("failed to fetch extclients", "error", err)
  104. return
  105. }
  106. for _, extclient := range extclients {
  107. if extclient.OwnerID == user.UserName && remoteGwID == extclient.IngressGatewayID {
  108. logic.DeleteExtClient(extclient.Network, extclient.ClientID)
  109. }
  110. }
  111. }(*user, remoteGwID)
  112. err = logic.UpsertUser(*user)
  113. if err != nil {
  114. slog.Error("failed to update user gateways", "user", username, "error", err)
  115. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to fetch remote access gaetway node "+err.Error()), "badrequest"))
  116. return
  117. }
  118. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  119. }
  120. // swagger:route GET "/api/users/{username}/remote_access_gw" nodes getUserRemoteAccessGws
  121. //
  122. // Get an individual node.
  123. //
  124. // Schemes: https
  125. //
  126. // Security:
  127. // oauth
  128. //
  129. // Responses:
  130. // 200: nodeResponse
  131. func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
  132. // set header.
  133. w.Header().Set("Content-Type", "application/json")
  134. var params = mux.Vars(r)
  135. username := params["username"]
  136. if username == "" {
  137. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params username"), "badrequest"))
  138. return
  139. }
  140. var req models.UserRemoteGwsReq
  141. err := json.NewDecoder(r.Body).Decode(&req)
  142. if err != nil {
  143. slog.Error("error decoding request body: ", "error", err)
  144. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  145. return
  146. }
  147. if req.RemoteAccessClientID == "" {
  148. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest"))
  149. return
  150. }
  151. userGws := make(map[string][]models.UserRemoteGws)
  152. user, err := logic.GetUser(username)
  153. if err != nil {
  154. logger.Log(0, username, "failed to fetch user: ", err.Error())
  155. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  156. return
  157. }
  158. if user.IsAdmin || user.IsSuperAdmin {
  159. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("admins can visit dashboard to create remote clients"), "badrequest"))
  160. return
  161. }
  162. allextClients, err := logic.GetAllExtClients()
  163. if err != nil {
  164. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  165. return
  166. }
  167. for _, extClient := range allextClients {
  168. if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username {
  169. node, err := logic.GetNodeByID(extClient.IngressGatewayID)
  170. if err != nil {
  171. continue
  172. }
  173. if node.PendingDelete {
  174. continue
  175. }
  176. if !node.IsIngressGateway {
  177. continue
  178. }
  179. host, err := logic.GetHost(node.HostID.String())
  180. if err != nil {
  181. continue
  182. }
  183. if _, ok := user.RemoteGwIDs[node.ID.String()]; ok {
  184. gws := userGws[node.Network]
  185. gws = append(gws, models.UserRemoteGws{
  186. GwID: node.ID.String(),
  187. GWName: host.Name,
  188. Network: node.Network,
  189. GwClient: extClient,
  190. Connected: true,
  191. IsInternetGateway: node.IsInternetGateway,
  192. })
  193. userGws[node.Network] = gws
  194. delete(user.RemoteGwIDs, node.ID.String())
  195. }
  196. }
  197. }
  198. // add remaining gw nodes to resp
  199. for gwID := range user.RemoteGwIDs {
  200. node, err := logic.GetNodeByID(gwID)
  201. if err != nil {
  202. continue
  203. }
  204. if !node.IsIngressGateway {
  205. continue
  206. }
  207. if node.PendingDelete {
  208. continue
  209. }
  210. host, err := logic.GetHost(node.HostID.String())
  211. if err != nil {
  212. continue
  213. }
  214. gws := userGws[node.Network]
  215. gws = append(gws, models.UserRemoteGws{
  216. GwID: node.ID.String(),
  217. GWName: host.Name,
  218. Network: node.Network,
  219. IsInternetGateway: node.IsInternetGateway,
  220. })
  221. userGws[node.Network] = gws
  222. }
  223. w.WriteHeader(http.StatusOK)
  224. json.NewEncoder(w).Encode(userGws)
  225. }
  226. // swagger:route GET /api/nodes/{network}/{nodeid}/ingress/users users ingressGatewayUsers
  227. //
  228. // Lists all the users attached to an ingress gateway.
  229. //
  230. // Schemes: https
  231. //
  232. // Security:
  233. // oauth
  234. //
  235. // Responses:
  236. // 200: nodeResponse
  237. func ingressGatewayUsers(w http.ResponseWriter, r *http.Request) {
  238. w.Header().Set("Content-Type", "application/json")
  239. var params = mux.Vars(r)
  240. ingressID := params["ingress_id"]
  241. node, err := logic.GetNodeByID(ingressID)
  242. if err != nil {
  243. slog.Error("failed to get ingress node", "error", err)
  244. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  245. return
  246. }
  247. gwUsers, err := logic.GetIngressGwUsers(node)
  248. if err != nil {
  249. slog.Error("failed to get users on ingress gateway", "nodeid", ingressID, "network", node.Network, "user", r.Header.Get("user"),
  250. "error", err)
  251. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  252. return
  253. }
  254. w.WriteHeader(http.StatusOK)
  255. json.NewEncoder(w).Encode(gwUsers)
  256. }