security.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. package logic
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strings"
  6. "github.com/gorilla/mux"
  7. "github.com/gravitl/netmaker/database"
  8. "github.com/gravitl/netmaker/logic/pro"
  9. "github.com/gravitl/netmaker/models"
  10. "github.com/gravitl/netmaker/models/promodels"
  11. "github.com/gravitl/netmaker/servercfg"
  12. )
  13. const (
  14. // ALL_NETWORK_ACCESS - represents all networks
  15. ALL_NETWORK_ACCESS = "THIS_USER_HAS_ALL"
  16. master_uname = "masteradministrator"
  17. Unauthorized_Msg = "unauthorized"
  18. Unauthorized_Err = models.Error(Unauthorized_Msg)
  19. )
  20. // SecurityCheck - Check if user has appropriate permissions
  21. func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
  22. return func(w http.ResponseWriter, r *http.Request) {
  23. var errorResponse = models.ErrorResponse{
  24. Code: http.StatusUnauthorized, Message: Unauthorized_Msg,
  25. }
  26. var params = mux.Vars(r)
  27. bearerToken := r.Header.Get("Authorization")
  28. // to have a custom DNS service adding entries
  29. // we should refactor this, but is for the special case of an external service to query the DNS api
  30. if strings.Contains(r.RequestURI, "/dns") && strings.ToUpper(r.Method) == "GET" && authenticateDNSToken(bearerToken) {
  31. // do dns stuff
  32. r.Header.Set("user", "nameserver")
  33. networks, _ := json.Marshal([]string{ALL_NETWORK_ACCESS})
  34. r.Header.Set("networks", string(networks))
  35. next.ServeHTTP(w, r)
  36. return
  37. }
  38. var networkName = params["networkname"]
  39. if len(networkName) == 0 {
  40. networkName = params["network"]
  41. }
  42. networks, username, err := UserPermissions(reqAdmin, networkName, bearerToken)
  43. if err != nil {
  44. ReturnErrorResponse(w, r, errorResponse)
  45. return
  46. }
  47. networksJson, err := json.Marshal(&networks)
  48. if err != nil {
  49. ReturnErrorResponse(w, r, errorResponse)
  50. return
  51. }
  52. r.Header.Set("user", username)
  53. r.Header.Set("networks", string(networksJson))
  54. next.ServeHTTP(w, r)
  55. }
  56. }
  57. // NetUserSecurityCheck - Check if network user has appropriate permissions
  58. func NetUserSecurityCheck(isNodes, isClients bool, next http.Handler) http.HandlerFunc {
  59. return func(w http.ResponseWriter, r *http.Request) {
  60. var errorResponse = models.ErrorResponse{
  61. Code: http.StatusUnauthorized, Message: "unauthorized",
  62. }
  63. r.Header.Set("ismaster", "no")
  64. var params = mux.Vars(r)
  65. var netUserName = params["networkuser"]
  66. var network = params["network"]
  67. bearerToken := r.Header.Get("Authorization")
  68. var tokenSplit = strings.Split(bearerToken, " ")
  69. var authToken = ""
  70. if len(tokenSplit) < 2 {
  71. ReturnErrorResponse(w, r, errorResponse)
  72. return
  73. } else {
  74. authToken = tokenSplit[1]
  75. }
  76. isMasterAuthenticated := authenticateMaster(authToken)
  77. if isMasterAuthenticated {
  78. r.Header.Set("user", "master token user")
  79. r.Header.Set("ismaster", "yes")
  80. next.ServeHTTP(w, r)
  81. return
  82. }
  83. userName, _, isadmin, err := VerifyUserToken(authToken)
  84. if err != nil {
  85. ReturnErrorResponse(w, r, errorResponse)
  86. return
  87. }
  88. r.Header.Set("user", userName)
  89. if isadmin {
  90. next.ServeHTTP(w, r)
  91. return
  92. }
  93. if isNodes || isClients {
  94. necessaryAccess := pro.NET_ADMIN
  95. if isClients {
  96. necessaryAccess = pro.CLIENT_ACCESS
  97. }
  98. if isNodes {
  99. necessaryAccess = pro.NODE_ACCESS
  100. }
  101. u, err := pro.GetNetworkUser(network, promodels.NetworkUserID(userName))
  102. if err != nil {
  103. ReturnErrorResponse(w, r, errorResponse)
  104. return
  105. }
  106. if u.AccessLevel > necessaryAccess {
  107. ReturnErrorResponse(w, r, errorResponse)
  108. return
  109. }
  110. } else if netUserName != userName {
  111. ReturnErrorResponse(w, r, errorResponse)
  112. return
  113. }
  114. next.ServeHTTP(w, r)
  115. }
  116. }
  117. // UserPermissions - checks token stuff
  118. func UserPermissions(reqAdmin bool, netname string, token string) ([]string, string, error) {
  119. var tokenSplit = strings.Split(token, " ")
  120. var authToken = ""
  121. userNetworks := []string{}
  122. if len(tokenSplit) < 2 {
  123. return userNetworks, "", Unauthorized_Err
  124. } else {
  125. authToken = tokenSplit[1]
  126. }
  127. //all endpoints here require master so not as complicated
  128. if authenticateMaster(authToken) {
  129. return []string{ALL_NETWORK_ACCESS}, master_uname, nil
  130. }
  131. username, networks, isadmin, err := VerifyUserToken(authToken)
  132. if err != nil {
  133. return nil, username, Unauthorized_Err
  134. }
  135. if !isadmin && reqAdmin {
  136. return nil, username, Unauthorized_Err
  137. }
  138. userNetworks = networks
  139. if isadmin {
  140. return []string{ALL_NETWORK_ACCESS}, username, nil
  141. }
  142. // check network admin access
  143. if len(netname) > 0 && (!authenticateNetworkUser(netname, userNetworks) || len(userNetworks) == 0) {
  144. return nil, username, Unauthorized_Err
  145. }
  146. if isEE && !pro.IsUserNetAdmin(netname, username) {
  147. return nil, "", Unauthorized_Err
  148. }
  149. return userNetworks, username, nil
  150. }
  151. // Consider a more secure way of setting master key
  152. func authenticateMaster(tokenString string) bool {
  153. return tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != ""
  154. }
  155. func authenticateNetworkUser(network string, userNetworks []string) bool {
  156. networkexists, err := NetworkExists(network)
  157. if (err != nil && !database.IsEmptyRecord(err)) || !networkexists {
  158. return false
  159. }
  160. return StringSliceContains(userNetworks, network)
  161. }
  162. //Consider a more secure way of setting master key
  163. func authenticateDNSToken(tokenString string) bool {
  164. tokens := strings.Split(tokenString, " ")
  165. if len(tokens) < 2 {
  166. return false
  167. }
  168. return tokens[1] == servercfg.GetDNSKey()
  169. }
  170. func ContinueIfUserMatch(next http.Handler) http.HandlerFunc {
  171. return func(w http.ResponseWriter, r *http.Request) {
  172. var errorResponse = models.ErrorResponse{
  173. Code: http.StatusUnauthorized, Message: Unauthorized_Msg,
  174. }
  175. var params = mux.Vars(r)
  176. var requestedUser = params["username"]
  177. if requestedUser != r.Header.Get("user") {
  178. ReturnErrorResponse(w, r, errorResponse)
  179. return
  180. }
  181. next.ServeHTTP(w, r)
  182. }
  183. }