user.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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/database"
  11. "github.com/gravitl/netmaker/logger"
  12. "github.com/gravitl/netmaker/logic"
  13. "github.com/gravitl/netmaker/models"
  14. "github.com/gravitl/netmaker/servercfg"
  15. )
  16. var (
  17. upgrader = websocket.Upgrader{}
  18. )
  19. func userHandlers(r *mux.Router) {
  20. r.HandleFunc("/api/users/adm/hasadmin", hasAdmin).Methods("GET")
  21. r.HandleFunc("/api/users/adm/createadmin", createAdmin).Methods("POST")
  22. r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods("POST")
  23. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(updateUser)))).Methods("PUT")
  24. r.HandleFunc("/api/users/networks/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods("PUT")
  25. r.HandleFunc("/api/users/{username}/adm", logic.SecurityCheck(true, http.HandlerFunc(updateUserAdm))).Methods("PUT")
  26. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(users_l, http.HandlerFunc(createUser)))).Methods("POST")
  27. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods("DELETE")
  28. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods("GET")
  29. r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods("GET")
  30. r.HandleFunc("/api/oauth/login", auth.HandleAuthLogin).Methods("GET")
  31. r.HandleFunc("/api/oauth/callback", auth.HandleAuthCallback).Methods("GET")
  32. r.HandleFunc("/api/oauth/node-handler", socketHandler)
  33. r.HandleFunc("/api/oauth/register/{regKey}", auth.RegisterNodeSSO).Methods("GET")
  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. // GetUserInternal - gets an internal user
  122. func GetUserInternal(username string) (models.User, error) {
  123. var user models.User
  124. record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
  125. if err != nil {
  126. return user, err
  127. }
  128. if err = json.Unmarshal([]byte(record), &user); err != nil {
  129. return models.User{}, err
  130. }
  131. return user, err
  132. }
  133. // swagger:route GET /api/users/{username} user getUser
  134. //
  135. // Get an individual user.
  136. //
  137. // Schemes: https
  138. //
  139. // Security:
  140. // oauth
  141. //
  142. // Responses:
  143. // 200: userBodyResponse
  144. func getUser(w http.ResponseWriter, r *http.Request) {
  145. // set header.
  146. w.Header().Set("Content-Type", "application/json")
  147. var params = mux.Vars(r)
  148. usernameFetched := params["username"]
  149. user, err := logic.GetUser(usernameFetched)
  150. if err != nil {
  151. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  152. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  153. return
  154. }
  155. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  156. json.NewEncoder(w).Encode(user)
  157. }
  158. // swagger:route GET /api/users user getUsers
  159. //
  160. // Get all users.
  161. //
  162. // Schemes: https
  163. //
  164. // Security:
  165. // oauth
  166. //
  167. // Responses:
  168. // 200: userBodyResponse
  169. func getUsers(w http.ResponseWriter, r *http.Request) {
  170. // set header.
  171. w.Header().Set("Content-Type", "application/json")
  172. users, err := logic.GetUsers()
  173. if err != nil {
  174. logger.Log(0, "failed to fetch users: ", err.Error())
  175. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  176. return
  177. }
  178. logger.Log(2, r.Header.Get("user"), "fetched users")
  179. json.NewEncoder(w).Encode(users)
  180. }
  181. // swagger:route POST /api/users/adm/createadmin user createAdmin
  182. //
  183. // Make a user an admin.
  184. //
  185. // Schemes: https
  186. //
  187. // Security:
  188. // oauth
  189. //
  190. // Responses:
  191. // 200: userBodyResponse
  192. func createAdmin(w http.ResponseWriter, r *http.Request) {
  193. w.Header().Set("Content-Type", "application/json")
  194. var admin models.User
  195. err := json.NewDecoder(r.Body).Decode(&admin)
  196. if err != nil {
  197. logger.Log(0, admin.UserName, "error decoding request body: ",
  198. err.Error())
  199. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  200. return
  201. }
  202. if !servercfg.IsBasicAuthEnabled() {
  203. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  204. return
  205. }
  206. admin, err = logic.CreateAdmin(admin)
  207. if err != nil {
  208. logger.Log(0, admin.UserName, "failed to create admin: ",
  209. err.Error())
  210. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  211. return
  212. }
  213. logger.Log(1, admin.UserName, "was made a new admin")
  214. json.NewEncoder(w).Encode(admin)
  215. }
  216. // swagger:route POST /api/users/{username} user createUser
  217. //
  218. // Create a user.
  219. //
  220. // Schemes: https
  221. //
  222. // Security:
  223. // oauth
  224. //
  225. // Responses:
  226. // 200: userBodyResponse
  227. func createUser(w http.ResponseWriter, r *http.Request) {
  228. w.Header().Set("Content-Type", "application/json")
  229. var user models.User
  230. err := json.NewDecoder(r.Body).Decode(&user)
  231. if err != nil {
  232. logger.Log(0, user.UserName, "error decoding request body: ",
  233. err.Error())
  234. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  235. return
  236. }
  237. user, err = logic.CreateUser(user)
  238. if err != nil {
  239. logger.Log(0, user.UserName, "error creating new user: ",
  240. err.Error())
  241. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  242. return
  243. }
  244. logger.Log(1, user.UserName, "was created")
  245. json.NewEncoder(w).Encode(user)
  246. }
  247. // swagger:route PUT /api/users/networks/{username} user updateUserNetworks
  248. //
  249. // Updates the networks of the given user.
  250. //
  251. // Schemes: https
  252. //
  253. // Security:
  254. // oauth
  255. //
  256. // Responses:
  257. // 200: userBodyResponse
  258. func updateUserNetworks(w http.ResponseWriter, r *http.Request) {
  259. w.Header().Set("Content-Type", "application/json")
  260. var params = mux.Vars(r)
  261. var user models.User
  262. // start here
  263. username := params["username"]
  264. user, err := GetUserInternal(username)
  265. if err != nil {
  266. logger.Log(0, username,
  267. "failed to update user networks: ", err.Error())
  268. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  269. return
  270. }
  271. var userchange models.User
  272. // we decode our body request params
  273. err = json.NewDecoder(r.Body).Decode(&userchange)
  274. if err != nil {
  275. logger.Log(0, username, "error decoding request body: ",
  276. err.Error())
  277. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  278. return
  279. }
  280. err = logic.UpdateUserNetworks(userchange.Networks, userchange.Groups, userchange.IsAdmin, &models.ReturnUser{
  281. Groups: user.Groups,
  282. IsAdmin: user.IsAdmin,
  283. Networks: user.Networks,
  284. UserName: user.UserName,
  285. })
  286. if err != nil {
  287. logger.Log(0, username,
  288. "failed to update user networks: ", err.Error())
  289. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  290. return
  291. }
  292. logger.Log(1, username, "status was updated")
  293. json.NewEncoder(w).Encode(user)
  294. }
  295. // swagger:route PUT /api/users/{username} user updateUser
  296. //
  297. // Update a user.
  298. //
  299. // Schemes: https
  300. //
  301. // Security:
  302. // oauth
  303. //
  304. // Responses:
  305. // 200: userBodyResponse
  306. func updateUser(w http.ResponseWriter, r *http.Request) {
  307. w.Header().Set("Content-Type", "application/json")
  308. var params = mux.Vars(r)
  309. var user models.User
  310. // start here
  311. username := params["username"]
  312. user, err := GetUserInternal(username)
  313. if err != nil {
  314. logger.Log(0, username,
  315. "failed to update user info: ", err.Error())
  316. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  317. return
  318. }
  319. if auth.IsOauthUser(&user) == nil {
  320. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  321. logger.Log(0, err.Error())
  322. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  323. return
  324. }
  325. var userchange models.User
  326. // we decode our body request params
  327. err = json.NewDecoder(r.Body).Decode(&userchange)
  328. if err != nil {
  329. logger.Log(0, username, "error decoding request body: ",
  330. err.Error())
  331. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  332. return
  333. }
  334. userchange.Networks = nil
  335. user, err = logic.UpdateUser(userchange, user)
  336. if err != nil {
  337. logger.Log(0, username,
  338. "failed to update user info: ", err.Error())
  339. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  340. return
  341. }
  342. logger.Log(1, username, "was updated")
  343. json.NewEncoder(w).Encode(user)
  344. }
  345. // swagger:route PUT /api/users/{username}/adm user updateUserAdm
  346. //
  347. // Updates the given admin user's info (as long as the user is an admin).
  348. //
  349. // Schemes: https
  350. //
  351. // Security:
  352. // oauth
  353. //
  354. // Responses:
  355. // 200: userBodyResponse
  356. func updateUserAdm(w http.ResponseWriter, r *http.Request) {
  357. w.Header().Set("Content-Type", "application/json")
  358. var params = mux.Vars(r)
  359. var user models.User
  360. // start here
  361. username := params["username"]
  362. user, err := GetUserInternal(username)
  363. if err != nil {
  364. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  365. return
  366. }
  367. if auth.IsOauthUser(&user) != nil {
  368. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  369. logger.Log(0, err.Error())
  370. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  371. return
  372. }
  373. var userchange models.User
  374. // we decode our body request params
  375. err = json.NewDecoder(r.Body).Decode(&userchange)
  376. if err != nil {
  377. logger.Log(0, username, "error decoding request body: ",
  378. err.Error())
  379. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  380. return
  381. }
  382. if !user.IsAdmin {
  383. logger.Log(0, username, "not an admin user")
  384. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("not a admin user"), "badrequest"))
  385. }
  386. user, err = logic.UpdateUser(userchange, user)
  387. if err != nil {
  388. logger.Log(0, username,
  389. "failed to update user (admin) info: ", err.Error())
  390. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  391. return
  392. }
  393. logger.Log(1, username, "was updated (admin)")
  394. json.NewEncoder(w).Encode(user)
  395. }
  396. // swagger:route DELETE /api/users/{username} user deleteUser
  397. //
  398. // Delete a user.
  399. //
  400. // Schemes: https
  401. //
  402. // Security:
  403. // oauth
  404. //
  405. // Responses:
  406. // 200: userBodyResponse
  407. func deleteUser(w http.ResponseWriter, r *http.Request) {
  408. // Set header
  409. w.Header().Set("Content-Type", "application/json")
  410. // get params
  411. var params = mux.Vars(r)
  412. username := params["username"]
  413. success, err := logic.DeleteUser(username)
  414. if err != nil {
  415. logger.Log(0, username,
  416. "failed to delete user: ", err.Error())
  417. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  418. return
  419. } else if !success {
  420. err := errors.New("delete unsuccessful")
  421. logger.Log(0, username, err.Error())
  422. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  423. return
  424. }
  425. logger.Log(1, username, "was deleted")
  426. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  427. }
  428. // Called when vpn client dials in to start the auth flow and first stage is to get register URL itself
  429. func socketHandler(w http.ResponseWriter, r *http.Request) {
  430. // Upgrade our raw HTTP connection to a websocket based one
  431. conn, err := upgrader.Upgrade(w, r, nil)
  432. if err != nil {
  433. logger.Log(0, "error during connection upgrade for node sign-in:", err.Error())
  434. return
  435. }
  436. if conn == nil {
  437. logger.Log(0, "failed to establish web-socket connection during node sign-in")
  438. return
  439. }
  440. // Start handling the session
  441. go auth.SessionHandler(conn)
  442. }