security.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package logic
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/gorilla/mux"
  6. "github.com/gravitl/netmaker/models"
  7. "github.com/gravitl/netmaker/servercfg"
  8. )
  9. const (
  10. MasterUser = "masteradministrator"
  11. Forbidden_Msg = "forbidden"
  12. Forbidden_Err = models.Error(Forbidden_Msg)
  13. Unauthorized_Msg = "unauthorized"
  14. Unauthorized_Err = models.Error(Unauthorized_Msg)
  15. )
  16. // SecurityCheck - Check if user has appropriate permissions
  17. func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
  18. return func(w http.ResponseWriter, r *http.Request) {
  19. r.Header.Set("ismaster", "no")
  20. bearerToken := r.Header.Get("Authorization")
  21. username, err := UserPermissions(reqAdmin, bearerToken)
  22. if err != nil {
  23. ReturnErrorResponse(w, r, FormatError(err, err.Error()))
  24. return
  25. }
  26. // detect masteradmin
  27. if username == MasterUser {
  28. r.Header.Set("ismaster", "yes")
  29. }
  30. r.Header.Set("user", username)
  31. next.ServeHTTP(w, r)
  32. }
  33. }
  34. // UserPermissions - checks token stuff
  35. func UserPermissions(reqAdmin bool, token string) (string, error) {
  36. var tokenSplit = strings.Split(token, " ")
  37. var authToken = ""
  38. if len(tokenSplit) < 2 {
  39. return "", Unauthorized_Err
  40. } else {
  41. authToken = tokenSplit[1]
  42. }
  43. //all endpoints here require master so not as complicated
  44. if authenticateMaster(authToken) {
  45. // TODO log in as an actual admin user
  46. return MasterUser, nil
  47. }
  48. username, issuperadmin, isadmin, err := VerifyUserToken(authToken)
  49. if err != nil {
  50. return username, Unauthorized_Err
  51. }
  52. if reqAdmin && !(issuperadmin || isadmin) {
  53. return username, Forbidden_Err
  54. }
  55. return username, nil
  56. }
  57. // Consider a more secure way of setting master key
  58. func authenticateMaster(tokenString string) bool {
  59. return tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != ""
  60. }
  61. func ContinueIfUserMatch(next http.Handler) http.HandlerFunc {
  62. return func(w http.ResponseWriter, r *http.Request) {
  63. var errorResponse = models.ErrorResponse{
  64. Code: http.StatusForbidden, Message: Forbidden_Msg,
  65. }
  66. var params = mux.Vars(r)
  67. var requestedUser = params["username"]
  68. if requestedUser != r.Header.Get("user") {
  69. ReturnErrorResponse(w, r, errorResponse)
  70. return
  71. }
  72. next.ServeHTTP(w, r)
  73. }
  74. }