From 29891ce45da7d63afde50ca5d65c7e85d7438f15 Mon Sep 17 00:00:00 2001 From: caffeinated92 Date: Fri, 25 Oct 2024 19:10:41 +0700 Subject: [PATCH] fix react UI and set user when creating cluster --- cluster/cluster_acl.go | 8 +-- server/api.go | 51 +++++++++++++++++++ .../src/components/Modals/AddUserModal.jsx | 7 ++- .../dashboard_react/src/redux/clusterSlice.js | 4 +- .../src/services/clusterService.js | 4 +- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/cluster/cluster_acl.go b/cluster/cluster_acl.go index 4988c5e3f..6fc5cf9fb 100644 --- a/cluster/cluster_acl.go +++ b/cluster/cluster_acl.go @@ -26,7 +26,7 @@ type APIUser struct { Grants map[string]bool `json:"grants"` } -func (cluster *Cluster) SetUserGrants(u *APIUser, grant string) { +func (cluster *Cluster) SetNewUserGrants(u *APIUser, grant string) { acls := strings.Split(grant, " ") for key, value := range cluster.Grants { found := false @@ -40,7 +40,7 @@ func (cluster *Cluster) SetUserGrants(u *APIUser, grant string) { } } -func (cluster *Cluster) SetUserRoles(u *APIUser, roles string) { +func (cluster *Cluster) SetNewUserRoles(u *APIUser, roles string) { list := strings.Split(roles, " ") if u.Grants[config.GrantGlobalGrant] && roles == "" { @@ -156,8 +156,8 @@ func (cluster *Cluster) LoadAPIUsers() error { // For compatibility allow empty cluster list ACL if useracl == newapiuser.User && (listcluster == "" || slices.Contains(cluster_acls, cluster.Name)) { - cluster.SetUserGrants(&newapiuser, listacls) - cluster.SetUserRoles(&newapiuser, listroles) + cluster.SetNewUserGrants(&newapiuser, listacls) + cluster.SetNewUserRoles(&newapiuser, listroles) } } diff --git a/server/api.go b/server/api.go index 1bf5d83f4..78293c2b1 100644 --- a/server/api.go +++ b/server/api.go @@ -39,6 +39,7 @@ import ( "github.com/gorilla/mux" "github.com/signal18/replication-manager/cert" "github.com/signal18/replication-manager/cluster" + "github.com/signal18/replication-manager/config" "github.com/signal18/replication-manager/regtest" "github.com/signal18/replication-manager/share" "github.com/signal18/replication-manager/utils/githelper" @@ -360,6 +361,31 @@ func (repman *ReplicationManager) IsValidClusterACL(r *http.Request, cluster *cl return false, "" } +func (repman *ReplicationManager) GetUserFromRequest(r *http.Request) string { + + token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor, func(token *jwt.Token) (interface{}, error) { + vk, _ := jwt.ParseRSAPublicKeyFromPEM(verificationKey) + return vk, nil + }) + + if err == nil { + claims := token.Claims.(jwt.MapClaims) + userinfo := claims["CustomUserInfo"] + mycutinfo := userinfo.(map[string]interface{}) + meuser := mycutinfo["Name"].(string) + _, ok := mycutinfo["profile"] + + if ok { + if strings.Contains(mycutinfo["profile"].(string), repman.Conf.OAuthProvider) /*&& strings.Contains(mycutinfo["email_verified"]*/ { + return mycutinfo["email"].(string) + } + } + return meuser + } + + return "" +} + func (repman *ReplicationManager) loginHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") var user userCredentials @@ -753,8 +779,33 @@ func (repman *ReplicationManager) jsonResponse(apiresponse interface{}, w http.R func (repman *ReplicationManager) handlerMuxClusterAdd(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") vars := mux.Vars(r) + + username := repman.GetUserFromRequest(r) + if username == "" { + http.Error(w, "User is not valid", http.StatusInternalServerError) + return + } + repman.AddCluster(vars["clusterName"], "") + // Create user and grant for new cluster + cl := repman.getClusterByName(vars["clusterName"]) + if cl != nil { + if u, ok := cl.APIUsers[username]; !ok { + // Create user and grant for new cluster + userform := cluster.UserForm{ + Username: username, + Roles: strings.Join(([]string{config.RoleSponsor, config.RoleDBOps, config.RoleSysOps}), " "), + Grants: "cluster db proxy prov", + } + cl.AddUser(userform) + } else { + // Update grant for new cluster + cl.SetNewUserGrants(&u, "cluster db proxy prov") + cl.SetNewUserRoles(&u, strings.Join(([]string{config.RoleSponsor, config.RoleDBOps, config.RoleSysOps}), " ")) + cl.APIUsers[u.User] = u + } + } } func (repman *ReplicationManager) handlerMuxClusterDelete(w http.ResponseWriter, r *http.Request) { diff --git a/share/dashboard_react/src/components/Modals/AddUserModal.jsx b/share/dashboard_react/src/components/Modals/AddUserModal.jsx index 5d8447b2f..7fc0acc49 100644 --- a/share/dashboard_react/src/components/Modals/AddUserModal.jsx +++ b/share/dashboard_react/src/components/Modals/AddUserModal.jsx @@ -142,7 +142,6 @@ function AddUserModal({ clusterName, isOpen, closeModal }) { return } - const selectedRoles = roles.filter((x) => x.selected).map((x) => x.role) if (selectedRoles.length === 0) { setRolesError('Please select atleast one role') @@ -155,7 +154,7 @@ function AddUserModal({ clusterName, isOpen, closeModal }) { return } - dispatch(addUser({ clusterName, username: userName, password, grants: selectedGrants.join(' '), roles: selectedRoles.join(' ') })) + dispatch(addUser({ clusterName, username: userName, grants: selectedGrants.join(' '), roles: selectedRoles.join(' ') })) closeModal() } return ( @@ -184,7 +183,7 @@ function AddUserModal({ clusterName, isOpen, closeModal }) { */} - + {roles.length > 0 && roles.map((role) => ( @@ -201,7 +200,7 @@ function AddUserModal({ clusterName, isOpen, closeModal }) { - + {acls.length > 0 && acls.map((acl) => ( diff --git a/share/dashboard_react/src/redux/clusterSlice.js b/share/dashboard_react/src/redux/clusterSlice.js index e9778a1d9..c2fb1aa61 100644 --- a/share/dashboard_react/src/redux/clusterSlice.js +++ b/share/dashboard_react/src/redux/clusterSlice.js @@ -895,9 +895,9 @@ export const toggleDatabaseActions = createAsyncThunk( export const addUser = createAsyncThunk( 'cluster/addUser', - async ({ clusterName, username, password, grants }, thunkAPI) => { + async ({ clusterName, username, grants, roles }, thunkAPI) => { try { - const { data, status } = await clusterService.addUser(clusterName, username, password, grants) + const { data, status } = await clusterService.addUser(clusterName, username, grants, roles) showSuccessBanner(`User is added successful!`, status, thunkAPI) return { data, status } } catch (error) { diff --git a/share/dashboard_react/src/services/clusterService.js b/share/dashboard_react/src/services/clusterService.js index 74d509c2e..109cb025a 100644 --- a/share/dashboard_react/src/services/clusterService.js +++ b/share/dashboard_react/src/services/clusterService.js @@ -383,8 +383,8 @@ function runRegressionTests(clusterName, testName) { //#endregion cluster>run tests //#region cluster> add user -function addUser(clusterName, username, password, grants, roles) { - return postRequest(`clusters/${clusterName}/users/add`, { username, password, grants, roles }) +function addUser(clusterName, username, grants, roles) { + return postRequest(`clusters/${clusterName}/users/add`, { username, grants, roles }) } //#endregion cluster>add user