user.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "github.com/gorilla/mux"
  8. "github.com/gorilla/websocket"
  9. "github.com/gravitl/netmaker/auth"
  10. "github.com/gravitl/netmaker/logger"
  11. "github.com/gravitl/netmaker/logic"
  12. "github.com/gravitl/netmaker/models"
  13. "github.com/gravitl/netmaker/servercfg"
  14. )
  15. var (
  16. upgrader = websocket.Upgrader{}
  17. )
  18. func userHandlers(r *mux.Router) {
  19. r.HandleFunc("/api/users/adm/hasadmin", hasAdmin).Methods(http.MethodGet)
  20. r.HandleFunc("/api/users/adm/createadmin", createAdmin).Methods(http.MethodPost)
  21. r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods(http.MethodPost)
  22. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(updateUser)))).Methods(http.MethodPut)
  23. r.HandleFunc("/api/users/networks/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods(http.MethodPut)
  24. r.HandleFunc("/api/users/{username}/adm", logic.SecurityCheck(true, http.HandlerFunc(updateUserAdm))).Methods(http.MethodPut)
  25. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(users_l, http.HandlerFunc(createUser)))).Methods(http.MethodPost)
  26. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods(http.MethodDelete)
  27. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods(http.MethodGet)
  28. r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods(http.MethodGet)
  29. r.HandleFunc("/api/oauth/login", auth.HandleAuthLogin).Methods(http.MethodGet)
  30. r.HandleFunc("/api/oauth/callback", auth.HandleAuthCallback).Methods(http.MethodGet)
  31. r.HandleFunc("/api/oauth/node-handler", socketHandler)
  32. r.HandleFunc("/api/oauth/headless", auth.HandleHeadlessSSO)
  33. r.HandleFunc("/api/oauth/register/{regKey}", auth.RegisterNodeSSO).Methods(http.MethodGet)
  34. }
  35. // swagger:route POST /api/users/adm/authenticate user authenticateUser
  36. //
  37. // Node authenticates using its password and retrieves a JWT for authorization.
  38. //
  39. // Schemes: https
  40. //
  41. // Security:
  42. // oauth
  43. //
  44. // Responses:
  45. // 200: successResponse
  46. func authenticateUser(response http.ResponseWriter, request *http.Request) {
  47. // Auth request consists of Mac Address and Password (from node that is authorizing
  48. // in case of Master, auth is ignored and mac is set to "mastermac"
  49. var authRequest models.UserAuthParams
  50. var errorResponse = models.ErrorResponse{
  51. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  52. }
  53. if !servercfg.IsBasicAuthEnabled() {
  54. logic.ReturnErrorResponse(response, request, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  55. return
  56. }
  57. decoder := json.NewDecoder(request.Body)
  58. decoderErr := decoder.Decode(&authRequest)
  59. defer request.Body.Close()
  60. if decoderErr != nil {
  61. logger.Log(0, "error decoding request body: ",
  62. decoderErr.Error())
  63. logic.ReturnErrorResponse(response, request, errorResponse)
  64. return
  65. }
  66. username := authRequest.UserName
  67. jwt, err := logic.VerifyAuthRequest(authRequest)
  68. if err != nil {
  69. logger.Log(0, username, "user validation failed: ",
  70. err.Error())
  71. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "badrequest"))
  72. return
  73. }
  74. if jwt == "" {
  75. // very unlikely that err is !nil and no jwt returned, but handle it anyways.
  76. logger.Log(0, username, "jwt token is empty")
  77. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("no token returned"), "internal"))
  78. return
  79. }
  80. var successResponse = models.SuccessResponse{
  81. Code: http.StatusOK,
  82. Message: "W1R3: Device " + username + " Authorized",
  83. Response: models.SuccessfulUserLoginResponse{
  84. AuthToken: jwt,
  85. UserName: username,
  86. },
  87. }
  88. // Send back the JWT
  89. successJSONResponse, jsonError := json.Marshal(successResponse)
  90. if jsonError != nil {
  91. logger.Log(0, username,
  92. "error marshalling resp: ", err.Error())
  93. logic.ReturnErrorResponse(response, request, errorResponse)
  94. return
  95. }
  96. logger.Log(2, username, "was authenticated")
  97. response.Header().Set("Content-Type", "application/json")
  98. response.Write(successJSONResponse)
  99. }
  100. // swagger:route GET /api/users/adm/hasadmin user hasAdmin
  101. //
  102. // Checks whether the server has an admin.
  103. //
  104. // Schemes: https
  105. //
  106. // Security:
  107. // oauth
  108. //
  109. // Responses:
  110. // 200: successResponse
  111. func hasAdmin(w http.ResponseWriter, r *http.Request) {
  112. w.Header().Set("Content-Type", "application/json")
  113. hasadmin, err := logic.HasAdmin()
  114. if err != nil {
  115. logger.Log(0, "failed to check for admin: ", err.Error())
  116. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  117. return
  118. }
  119. json.NewEncoder(w).Encode(hasadmin)
  120. }
  121. // swagger:route GET /api/users/{username} user getUser
  122. //
  123. // Get an individual user.
  124. //
  125. // Schemes: https
  126. //
  127. // Security:
  128. // oauth
  129. //
  130. // Responses:
  131. // 200: userBodyResponse
  132. func getUser(w http.ResponseWriter, r *http.Request) {
  133. // set header.
  134. w.Header().Set("Content-Type", "application/json")
  135. var params = mux.Vars(r)
  136. usernameFetched := params["username"]
  137. user, err := logic.GetUser(usernameFetched)
  138. if err != nil {
  139. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  140. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  141. return
  142. }
  143. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  144. json.NewEncoder(w).Encode(user)
  145. }
  146. // swagger:route GET /api/users user getUsers
  147. //
  148. // Get all users.
  149. //
  150. // Schemes: https
  151. //
  152. // Security:
  153. // oauth
  154. //
  155. // Responses:
  156. // 200: userBodyResponse
  157. func getUsers(w http.ResponseWriter, r *http.Request) {
  158. // set header.
  159. w.Header().Set("Content-Type", "application/json")
  160. users, err := logic.GetUsers()
  161. if err != nil {
  162. logger.Log(0, "failed to fetch users: ", err.Error())
  163. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  164. return
  165. }
  166. logger.Log(2, r.Header.Get("user"), "fetched users")
  167. json.NewEncoder(w).Encode(users)
  168. }
  169. // swagger:route POST /api/users/adm/createadmin user createAdmin
  170. //
  171. // Make a user an admin.
  172. //
  173. // Schemes: https
  174. //
  175. // Security:
  176. // oauth
  177. //
  178. // Responses:
  179. // 200: userBodyResponse
  180. func createAdmin(w http.ResponseWriter, r *http.Request) {
  181. w.Header().Set("Content-Type", "application/json")
  182. var admin models.User
  183. err := json.NewDecoder(r.Body).Decode(&admin)
  184. if err != nil {
  185. logger.Log(0, admin.UserName, "error decoding request body: ",
  186. err.Error())
  187. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  188. return
  189. }
  190. if !servercfg.IsBasicAuthEnabled() {
  191. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  192. return
  193. }
  194. err = logic.CreateAdmin(&admin)
  195. if err != nil {
  196. logger.Log(0, admin.UserName, "failed to create admin: ",
  197. err.Error())
  198. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  199. return
  200. }
  201. logger.Log(1, admin.UserName, "was made a new admin")
  202. json.NewEncoder(w).Encode(admin)
  203. }
  204. // swagger:route POST /api/users/{username} user createUser
  205. //
  206. // Create a user.
  207. //
  208. // Schemes: https
  209. //
  210. // Security:
  211. // oauth
  212. //
  213. // Responses:
  214. // 200: userBodyResponse
  215. func createUser(w http.ResponseWriter, r *http.Request) {
  216. w.Header().Set("Content-Type", "application/json")
  217. var user models.User
  218. err := json.NewDecoder(r.Body).Decode(&user)
  219. if err != nil {
  220. logger.Log(0, user.UserName, "error decoding request body: ",
  221. err.Error())
  222. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  223. return
  224. }
  225. err = logic.CreateUser(&user)
  226. if err != nil {
  227. logger.Log(0, user.UserName, "error creating new user: ",
  228. err.Error())
  229. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  230. return
  231. }
  232. logger.Log(1, user.UserName, "was created")
  233. json.NewEncoder(w).Encode(user)
  234. }
  235. // swagger:route PUT /api/users/networks/{username} user updateUserNetworks
  236. //
  237. // Updates the networks of the given user.
  238. //
  239. // Schemes: https
  240. //
  241. // Security:
  242. // oauth
  243. //
  244. // Responses:
  245. // 200: userBodyResponse
  246. func updateUserNetworks(w http.ResponseWriter, r *http.Request) {
  247. w.Header().Set("Content-Type", "application/json")
  248. var params = mux.Vars(r)
  249. // start here
  250. username := params["username"]
  251. user, err := logic.GetUser(username)
  252. if err != nil {
  253. logger.Log(0, username,
  254. "failed to update user networks: ", err.Error())
  255. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  256. return
  257. }
  258. var userchange models.User
  259. // we decode our body request params
  260. err = json.NewDecoder(r.Body).Decode(&userchange)
  261. if err != nil {
  262. logger.Log(0, username, "error decoding request body: ",
  263. err.Error())
  264. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  265. return
  266. }
  267. err = logic.UpdateUserNetworks(userchange.Networks, userchange.Groups, userchange.IsAdmin, &models.ReturnUser{
  268. Groups: user.Groups,
  269. IsAdmin: user.IsAdmin,
  270. Networks: user.Networks,
  271. UserName: user.UserName,
  272. })
  273. if err != nil {
  274. logger.Log(0, username,
  275. "failed to update user networks: ", err.Error())
  276. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  277. return
  278. }
  279. logger.Log(1, username, "status was updated")
  280. json.NewEncoder(w).Encode(user)
  281. }
  282. // swagger:route PUT /api/users/{username} user updateUser
  283. //
  284. // Update a user.
  285. //
  286. // Schemes: https
  287. //
  288. // Security:
  289. // oauth
  290. //
  291. // Responses:
  292. // 200: userBodyResponse
  293. func updateUser(w http.ResponseWriter, r *http.Request) {
  294. w.Header().Set("Content-Type", "application/json")
  295. var params = mux.Vars(r)
  296. // start here
  297. username := params["username"]
  298. user, err := logic.GetUser(username)
  299. if err != nil {
  300. logger.Log(0, username,
  301. "failed to update user info: ", err.Error())
  302. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  303. return
  304. }
  305. if auth.IsOauthUser(user) == nil {
  306. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  307. logger.Log(0, err.Error())
  308. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  309. return
  310. }
  311. var userchange models.User
  312. // we decode our body request params
  313. err = json.NewDecoder(r.Body).Decode(&userchange)
  314. if err != nil {
  315. logger.Log(0, username, "error decoding request body: ",
  316. err.Error())
  317. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  318. return
  319. }
  320. userchange.Networks = nil
  321. user, err = logic.UpdateUser(&userchange, user)
  322. if err != nil {
  323. logger.Log(0, username,
  324. "failed to update user info: ", err.Error())
  325. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  326. return
  327. }
  328. logger.Log(1, username, "was updated")
  329. json.NewEncoder(w).Encode(user)
  330. }
  331. // swagger:route PUT /api/users/{username}/adm user updateUserAdm
  332. //
  333. // Updates the given admin user's info (as long as the user is an admin).
  334. //
  335. // Schemes: https
  336. //
  337. // Security:
  338. // oauth
  339. //
  340. // Responses:
  341. // 200: userBodyResponse
  342. func updateUserAdm(w http.ResponseWriter, r *http.Request) {
  343. w.Header().Set("Content-Type", "application/json")
  344. var params = mux.Vars(r)
  345. // start here
  346. username := params["username"]
  347. user, err := logic.GetUser(username)
  348. if err != nil {
  349. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  350. return
  351. }
  352. if auth.IsOauthUser(user) != nil {
  353. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  354. logger.Log(0, err.Error())
  355. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  356. return
  357. }
  358. var userchange models.User
  359. // we decode our body request params
  360. err = json.NewDecoder(r.Body).Decode(&userchange)
  361. if err != nil {
  362. logger.Log(0, username, "error decoding request body: ",
  363. err.Error())
  364. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  365. return
  366. }
  367. if !user.IsAdmin {
  368. logger.Log(0, username, "not an admin user")
  369. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("not a admin user"), "badrequest"))
  370. }
  371. user, err = logic.UpdateUser(&userchange, user)
  372. if err != nil {
  373. logger.Log(0, username,
  374. "failed to update user (admin) info: ", err.Error())
  375. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  376. return
  377. }
  378. logger.Log(1, username, "was updated (admin)")
  379. json.NewEncoder(w).Encode(user)
  380. }
  381. // swagger:route DELETE /api/users/{username} user deleteUser
  382. //
  383. // Delete a user.
  384. //
  385. // Schemes: https
  386. //
  387. // Security:
  388. // oauth
  389. //
  390. // Responses:
  391. // 200: userBodyResponse
  392. func deleteUser(w http.ResponseWriter, r *http.Request) {
  393. // Set header
  394. w.Header().Set("Content-Type", "application/json")
  395. // get params
  396. var params = mux.Vars(r)
  397. username := params["username"]
  398. success, err := logic.DeleteUser(username)
  399. if err != nil {
  400. logger.Log(0, username,
  401. "failed to delete user: ", err.Error())
  402. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  403. return
  404. } else if !success {
  405. err := errors.New("delete unsuccessful")
  406. logger.Log(0, username, err.Error())
  407. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  408. return
  409. }
  410. logger.Log(1, username, "was deleted")
  411. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  412. }
  413. // Called when vpn client dials in to start the auth flow and first stage is to get register URL itself
  414. func socketHandler(w http.ResponseWriter, r *http.Request) {
  415. // Upgrade our raw HTTP connection to a websocket based one
  416. conn, err := upgrader.Upgrade(w, r, nil)
  417. if err != nil {
  418. logger.Log(0, "error during connection upgrade for node sign-in:", err.Error())
  419. return
  420. }
  421. if conn == nil {
  422. logger.Log(0, "failed to establish web-socket connection during node sign-in")
  423. return
  424. }
  425. // Start handling the session
  426. go auth.SessionHandler(conn)
  427. }