user.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  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/headless", auth.HandleHeadlessSSO)
  32. r.HandleFunc("/api/oauth/register/{regKey}", auth.RegisterHostSSO).Methods(http.MethodGet)
  33. }
  34. // swagger:route POST /api/users/adm/authenticate user authenticateUser
  35. //
  36. // Node authenticates using its password and retrieves a JWT for authorization.
  37. //
  38. // Schemes: https
  39. //
  40. // Security:
  41. // oauth
  42. //
  43. // Responses:
  44. // 200: successResponse
  45. func authenticateUser(response http.ResponseWriter, request *http.Request) {
  46. // Auth request consists of Mac Address and Password (from node that is authorizing
  47. // in case of Master, auth is ignored and mac is set to "mastermac"
  48. var authRequest models.UserAuthParams
  49. var errorResponse = models.ErrorResponse{
  50. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  51. }
  52. if !servercfg.IsBasicAuthEnabled() {
  53. logic.ReturnErrorResponse(response, request, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  54. return
  55. }
  56. decoder := json.NewDecoder(request.Body)
  57. decoderErr := decoder.Decode(&authRequest)
  58. defer request.Body.Close()
  59. if decoderErr != nil {
  60. logger.Log(0, "error decoding request body: ",
  61. decoderErr.Error())
  62. logic.ReturnErrorResponse(response, request, errorResponse)
  63. return
  64. }
  65. username := authRequest.UserName
  66. jwt, err := logic.VerifyAuthRequest(authRequest)
  67. if err != nil {
  68. logger.Log(0, username, "user validation failed: ",
  69. err.Error())
  70. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "badrequest"))
  71. return
  72. }
  73. if jwt == "" {
  74. // very unlikely that err is !nil and no jwt returned, but handle it anyways.
  75. logger.Log(0, username, "jwt token is empty")
  76. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("no token returned"), "internal"))
  77. return
  78. }
  79. var successResponse = models.SuccessResponse{
  80. Code: http.StatusOK,
  81. Message: "W1R3: Device " + username + " Authorized",
  82. Response: models.SuccessfulUserLoginResponse{
  83. AuthToken: jwt,
  84. UserName: username,
  85. },
  86. }
  87. // Send back the JWT
  88. successJSONResponse, jsonError := json.Marshal(successResponse)
  89. if jsonError != nil {
  90. logger.Log(0, username,
  91. "error marshalling resp: ", err.Error())
  92. logic.ReturnErrorResponse(response, request, errorResponse)
  93. return
  94. }
  95. logger.Log(2, username, "was authenticated")
  96. response.Header().Set("Content-Type", "application/json")
  97. response.Write(successJSONResponse)
  98. }
  99. // swagger:route GET /api/users/adm/hasadmin user hasAdmin
  100. //
  101. // Checks whether the server has an admin.
  102. //
  103. // Schemes: https
  104. //
  105. // Security:
  106. // oauth
  107. //
  108. // Responses:
  109. // 200: successResponse
  110. func hasAdmin(w http.ResponseWriter, r *http.Request) {
  111. w.Header().Set("Content-Type", "application/json")
  112. hasadmin, err := logic.HasAdmin()
  113. if err != nil {
  114. logger.Log(0, "failed to check for admin: ", err.Error())
  115. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  116. return
  117. }
  118. json.NewEncoder(w).Encode(hasadmin)
  119. }
  120. // swagger:route GET /api/users/{username} user getUser
  121. //
  122. // Get an individual user.
  123. //
  124. // Schemes: https
  125. //
  126. // Security:
  127. // oauth
  128. //
  129. // Responses:
  130. // 200: userBodyResponse
  131. func getUser(w http.ResponseWriter, r *http.Request) {
  132. // set header.
  133. w.Header().Set("Content-Type", "application/json")
  134. var params = mux.Vars(r)
  135. usernameFetched := params["username"]
  136. user, err := logic.GetUser(usernameFetched)
  137. if err != nil {
  138. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  139. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  140. return
  141. }
  142. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  143. json.NewEncoder(w).Encode(user)
  144. }
  145. // swagger:route GET /api/users user getUsers
  146. //
  147. // Get all users.
  148. //
  149. // Schemes: https
  150. //
  151. // Security:
  152. // oauth
  153. //
  154. // Responses:
  155. // 200: userBodyResponse
  156. func getUsers(w http.ResponseWriter, r *http.Request) {
  157. // set header.
  158. w.Header().Set("Content-Type", "application/json")
  159. users, err := logic.GetUsers()
  160. if err != nil {
  161. logger.Log(0, "failed to fetch users: ", err.Error())
  162. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  163. return
  164. }
  165. logic.SortUsers(users[:])
  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. jwtUser, _, isadmin, err := logic.VerifyJWT(r.Header.Get("Authorization"))
  298. if err != nil {
  299. logger.Log(0, "verifyJWT error", err.Error())
  300. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  301. return
  302. }
  303. username := params["username"]
  304. if username != jwtUser && !isadmin {
  305. logger.Log(0, "non-admin user", jwtUser, "attempted to update user", username)
  306. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("not authorizied"), "unauthorized"))
  307. return
  308. }
  309. user, err := logic.GetUser(username)
  310. if err != nil {
  311. logger.Log(0, username,
  312. "failed to update user info: ", err.Error())
  313. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  314. return
  315. }
  316. if auth.IsOauthUser(user) == nil {
  317. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  318. logger.Log(0, err.Error())
  319. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  320. return
  321. }
  322. var userchange models.User
  323. // we decode our body request params
  324. err = json.NewDecoder(r.Body).Decode(&userchange)
  325. if err != nil {
  326. logger.Log(0, username, "error decoding request body: ",
  327. err.Error())
  328. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  329. return
  330. }
  331. if userchange.IsAdmin && !isadmin {
  332. logger.Log(0, "non-admin user", jwtUser, "attempted get admin privilages")
  333. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("not authorizied"), "unauthorized"))
  334. return
  335. }
  336. userchange.Networks = nil
  337. user, err = logic.UpdateUser(&userchange, user)
  338. if err != nil {
  339. logger.Log(0, username,
  340. "failed to update user info: ", err.Error())
  341. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  342. return
  343. }
  344. logger.Log(1, username, "was updated")
  345. json.NewEncoder(w).Encode(user)
  346. }
  347. // swagger:route PUT /api/users/{username}/adm user updateUserAdm
  348. //
  349. // Updates the given admin user's info (as long as the user is an admin).
  350. //
  351. // Schemes: https
  352. //
  353. // Security:
  354. // oauth
  355. //
  356. // Responses:
  357. // 200: userBodyResponse
  358. func updateUserAdm(w http.ResponseWriter, r *http.Request) {
  359. w.Header().Set("Content-Type", "application/json")
  360. var params = mux.Vars(r)
  361. // start here
  362. username := params["username"]
  363. user, err := logic.GetUser(username)
  364. if err != nil {
  365. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  366. return
  367. }
  368. if auth.IsOauthUser(user) != nil {
  369. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  370. logger.Log(0, err.Error())
  371. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  372. return
  373. }
  374. var userchange models.User
  375. // we decode our body request params
  376. err = json.NewDecoder(r.Body).Decode(&userchange)
  377. if err != nil {
  378. logger.Log(0, username, "error decoding request body: ",
  379. err.Error())
  380. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  381. return
  382. }
  383. if !user.IsAdmin {
  384. logger.Log(0, username, "not an admin user")
  385. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("not a admin user"), "badrequest"))
  386. }
  387. user, err = logic.UpdateUser(&userchange, user)
  388. if err != nil {
  389. logger.Log(0, username,
  390. "failed to update user (admin) info: ", err.Error())
  391. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  392. return
  393. }
  394. logger.Log(1, username, "was updated (admin)")
  395. json.NewEncoder(w).Encode(user)
  396. }
  397. // swagger:route DELETE /api/users/{username} user deleteUser
  398. //
  399. // Delete a user.
  400. //
  401. // Schemes: https
  402. //
  403. // Security:
  404. // oauth
  405. //
  406. // Responses:
  407. // 200: userBodyResponse
  408. func deleteUser(w http.ResponseWriter, r *http.Request) {
  409. // Set header
  410. w.Header().Set("Content-Type", "application/json")
  411. // get params
  412. var params = mux.Vars(r)
  413. username := params["username"]
  414. success, err := logic.DeleteUser(username)
  415. if err != nil {
  416. logger.Log(0, username,
  417. "failed to delete user: ", err.Error())
  418. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  419. return
  420. } else if !success {
  421. err := errors.New("delete unsuccessful")
  422. logger.Log(0, username, err.Error())
  423. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  424. return
  425. }
  426. logger.Log(1, username, "was deleted")
  427. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  428. }
  429. // Called when vpn client dials in to start the auth flow and first stage is to get register URL itself
  430. func socketHandler(w http.ResponseWriter, r *http.Request) {
  431. // Upgrade our raw HTTP connection to a websocket based one
  432. conn, err := upgrader.Upgrade(w, r, nil)
  433. if err != nil {
  434. logger.Log(0, "error during connection upgrade for node sign-in:", err.Error())
  435. return
  436. }
  437. if conn == nil {
  438. logger.Log(0, "failed to establish web-socket connection during node sign-in")
  439. return
  440. }
  441. // Start handling the session
  442. go auth.SessionHandler(conn)
  443. }