Browse Source

allow user to use master key to update any user

Abhishek Kondur 2 years ago
parent
commit
64370f2696
5 changed files with 27 additions and 13 deletions
  1. 1 1
      controllers/ext_client.go
  2. 21 7
      controllers/user.go
  3. 1 1
      logic/gateway.go
  4. 1 1
      logic/jwts.go
  5. 3 3
      logic/security.go

+ 1 - 1
controllers/ext_client.go

@@ -346,7 +346,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 	var userName string
 	var userName string
 	if r.Header.Get("ismaster") == "yes" {
 	if r.Header.Get("ismaster") == "yes" {
-		userName = logic.Master_uname
+		userName = logic.MasterUser
 	} else {
 	} else {
 		caller, err := logic.GetUser(r.Header.Get("user"))
 		caller, err := logic.GetUser(r.Header.Get("user"))
 		if err != nil {
 		if err != nil {

+ 21 - 7
controllers/user.go

@@ -353,11 +353,18 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
 	var params = mux.Vars(r)
 	var params = mux.Vars(r)
 	// start here
 	// start here
-
-	caller, err := logic.GetUser(r.Header.Get("user"))
-	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+	var caller *models.User
+	var err error
+	var ismaster bool
+	if r.Header.Get("user") == logic.MasterUser {
+		ismaster = true
+	} else {
+		caller, err = logic.GetUser(r.Header.Get("user"))
+		if err != nil {
+			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		}
 	}
 	}
+
 	username := params["username"]
 	username := params["username"]
 	user, err := logic.GetUser(username)
 	user, err := logic.GetUser(username)
 	if err != nil {
 	if err != nil {
@@ -379,11 +386,11 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 	selfUpdate := false
 	selfUpdate := false
-	if caller.UserName == user.UserName {
+	if !ismaster && caller.UserName == user.UserName {
 		selfUpdate = true
 		selfUpdate = true
 	}
 	}
 
 
-	if !selfUpdate {
+	if !ismaster && !selfUpdate {
 		if caller.IsAdmin && user.IsSuperAdmin {
 		if caller.IsAdmin && user.IsSuperAdmin {
 			slog.Error("non-superadmin user", "caller", caller.UserName, "attempted to update superadmin user", username)
 			slog.Error("non-superadmin user", "caller", caller.UserName, "attempted to update superadmin user", username)
 			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"))
 			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"))
@@ -407,7 +414,7 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
 		}
 		}
 
 
 	}
 	}
-	if selfUpdate {
+	if !ismaster && selfUpdate {
 		if user.IsAdmin != userchange.IsAdmin || user.IsSuperAdmin != userchange.IsSuperAdmin {
 		if user.IsAdmin != userchange.IsAdmin || user.IsSuperAdmin != userchange.IsSuperAdmin {
 			slog.Error("user cannot change his own role", "caller", caller.UserName, "attempted to update user role", username)
 			slog.Error("user cannot change his own role", "caller", caller.UserName, "attempted to update user role", username)
 			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"))
 			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"))
@@ -415,6 +422,13 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
 
 
 		}
 		}
 	}
 	}
+	if ismaster {
+		if !user.IsSuperAdmin && userchange.IsSuperAdmin {
+			slog.Error("operation not allowed", "caller", logic.MasterUser, "attempted to update user role to superadmin", username)
+			logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("attempted to update user role to superadmin"), "forbidden"))
+			return
+		}
+	}
 
 
 	if auth.IsOauthUser(user) == nil {
 	if auth.IsOauthUser(user) == nil {
 		err := fmt.Errorf("cannot update user info for oauth user %s", username)
 		err := fmt.Errorf("cannot update user info for oauth user %s", username)

+ 1 - 1
logic/gateway.go

@@ -232,7 +232,7 @@ func DeleteGatewayExtClients(gatewayID string, networkName string) error {
 
 
 // IsUserAllowedAccessToExtClient - checks if user has permission to access extclient
 // IsUserAllowedAccessToExtClient - checks if user has permission to access extclient
 func IsUserAllowedAccessToExtClient(username string, client models.ExtClient) bool {
 func IsUserAllowedAccessToExtClient(username string, client models.ExtClient) bool {
-	if username == Master_uname {
+	if username == MasterUser {
 		return true
 		return true
 	}
 	}
 	user, err := GetUser(username)
 	user, err := GetUser(username)

+ 1 - 1
logic/jwts.go

@@ -92,7 +92,7 @@ func VerifyUserToken(tokenString string) (username string, issuperadmin, isadmin
 	claims := &models.UserClaims{}
 	claims := &models.UserClaims{}
 
 
 	if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
 	if tokenString == servercfg.GetMasterKey() && servercfg.GetMasterKey() != "" {
-		return Master_uname, true, true, nil
+		return MasterUser, true, true, nil
 	}
 	}
 
 
 	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
 	token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {

+ 3 - 3
logic/security.go

@@ -10,7 +10,7 @@ import (
 )
 )
 
 
 const (
 const (
-	Master_uname     = "masteradministrator"
+	MasterUser       = "masteradministrator"
 	Forbidden_Msg    = "forbidden"
 	Forbidden_Msg    = "forbidden"
 	Forbidden_Err    = models.Error(Forbidden_Msg)
 	Forbidden_Err    = models.Error(Forbidden_Msg)
 	Unauthorized_Msg = "unauthorized"
 	Unauthorized_Msg = "unauthorized"
@@ -29,7 +29,7 @@ func SecurityCheck(reqAdmin bool, next http.Handler) http.HandlerFunc {
 			return
 			return
 		}
 		}
 		// detect masteradmin
 		// detect masteradmin
-		if username == Master_uname {
+		if username == MasterUser {
 			r.Header.Set("ismaster", "yes")
 			r.Header.Set("ismaster", "yes")
 		}
 		}
 		r.Header.Set("user", username)
 		r.Header.Set("user", username)
@@ -50,7 +50,7 @@ func UserPermissions(reqAdmin bool, token string) (string, error) {
 	//all endpoints here require master so not as complicated
 	//all endpoints here require master so not as complicated
 	if authenticateMaster(authToken) {
 	if authenticateMaster(authToken) {
 		// TODO log in as an actual admin user
 		// TODO log in as an actual admin user
-		return Master_uname, nil
+		return MasterUser, nil
 	}
 	}
 	username, issuperadmin, isadmin, err := VerifyUserToken(authToken)
 	username, issuperadmin, isadmin, err := VerifyUserToken(authToken)
 	if err != nil {
 	if err != nil {