From ddf4449d9dfea0de140aa8bedf734274ba8e391b Mon Sep 17 00:00:00 2001 From: wenjia322 Date: Tue, 17 Mar 2020 18:12:47 +0800 Subject: [PATCH] refactor: functions 'addPolicy' and 'removePolicy'; change param 'ak' to 'userID' Signed-off-by: wenjia322 --- master/api_service.go | 5 +- master/api_service_user.go | 75 ++++++------ master/const.go | 18 +-- master/http_server.go | 8 +- master/master_manager.go | 4 +- master/metadata_fsm.go | 2 +- master/metadata_fsm_op.go | 4 +- master/user.go | 227 +++++++++++++++++-------------------- master/userdata_fsm_op.go | 34 +++--- proto/admin_proto.go | 4 +- proto/user_proto.go | 43 +++++-- sdk/master/api_user.go | 4 +- 12 files changed, 216 insertions(+), 212 deletions(-) diff --git a/master/api_service.go b/master/api_service.go index 67b463740c..3d58c6e931 100644 --- a/master/api_service.go +++ b/master/api_service.go @@ -1825,10 +1825,7 @@ func (m *Server) associateVolWithUser(userID, volName string) error { return err } } - policy := &proto.UserPolicy{ - OwnVols: []string{volName}, - } - if _, err = m.user.addPolicy(akPolicy.AccessKey, policy); err != nil { + if _, err = m.user.addOwnVol(akPolicy.UserID, volName); err != nil { return err } return nil diff --git a/master/api_service_user.go b/master/api_service_user.go index a639f30e7d..659db39a40 100644 --- a/master/api_service_user.go +++ b/master/api_service_user.go @@ -90,56 +90,52 @@ func (m *Server) getUserInfo(w http.ResponseWriter, r *http.Request) { sendOkReply(w, r, newSuccessHTTPReply(akPolicy)) } -func (m *Server) addUserPolicy(w http.ResponseWriter, r *http.Request) { +func (m *Server) updateUserPolicy(w http.ResponseWriter, r *http.Request) { var ( - ak string - akPolicy *proto.AKPolicy - userPolicy *proto.UserPolicy - body []byte - err error + akPolicy *proto.AKPolicy + bytes []byte + err error ) - if body, err = ioutil.ReadAll(r.Body); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeReadBodyError, Msg: err.Error()}) + if bytes, err = ioutil.ReadAll(r.Body); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) return } - userPolicy = proto.NewUserPolicy() - if err = json.Unmarshal(body, userPolicy); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeUnmarshalData, Msg: err.Error()}) + var param = proto.UserPermUpdateParam{} + if err = json.Unmarshal(bytes, ¶m); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) return } - if ak, err = parseAccessKey(r); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) + if _, err = m.cluster.getVol(param.Volume); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeVolNotExists, Msg: err.Error()}) return } - if akPolicy, err = m.user.addPolicy(ak, userPolicy); err != nil { + if akPolicy, err = m.user.updatePolicy(¶m); err != nil { sendErrReply(w, r, newErrHTTPReply(err)) return } sendOkReply(w, r, newSuccessHTTPReply(akPolicy)) } -func (m *Server) deleteUserPolicy(w http.ResponseWriter, r *http.Request) { +func (m *Server) removeUserPolicy(w http.ResponseWriter, r *http.Request) { var ( - ak string - akPolicy *proto.AKPolicy - userPolicy *proto.UserPolicy - body []byte - err error + akPolicy *proto.AKPolicy + bytes []byte + err error ) - if body, err = ioutil.ReadAll(r.Body); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeReadBodyError, Msg: err.Error()}) + if bytes, err = ioutil.ReadAll(r.Body); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) return } - userPolicy = proto.NewUserPolicy() - if err = json.Unmarshal(body, userPolicy); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeUnmarshalData, Msg: err.Error()}) + var param = proto.UserPermRemoveParam{} + if err = json.Unmarshal(bytes, ¶m); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) return } - if ak, err = parseAccessKey(r); err != nil { - sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) + if _, err = m.cluster.getVol(param.Volume); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeVolNotExists, Msg: err.Error()}) return } - if akPolicy, err = m.user.deletePolicy(ak, userPolicy); err != nil { + if akPolicy, err = m.user.removePolicy(¶m); err != nil { sendErrReply(w, r, newErrHTTPReply(err)) return } @@ -166,22 +162,25 @@ func (m *Server) deleteUserVolPolicy(w http.ResponseWriter, r *http.Request) { func (m *Server) transferUserVol(w http.ResponseWriter, r *http.Request) { var ( - volName string - ak string - targetKey string - akPolicy *proto.AKPolicy - vol *Vol - err error + bytes []byte + vol *Vol + akPolicy *proto.AKPolicy + err error ) - if volName, ak, targetKey, err = parseVolAndKey(r); err != nil { + if bytes, err = ioutil.ReadAll(r.Body); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) + return + } + var param = proto.UserTransferVolParam{} + if err = json.Unmarshal(bytes, ¶m); err != nil { sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeParamError, Msg: err.Error()}) return } - if vol, err = m.cluster.getVol(volName); err != nil { - sendErrReply(w, r, newErrHTTPReply(proto.ErrVolNotExists)) + if vol, err = m.cluster.getVol(param.Volume); err != nil { + sendErrReply(w, r, &proto.HTTPReply{Code: proto.ErrCodeVolNotExists, Msg: err.Error()}) return } - if akPolicy, err = m.user.transferVol(volName, ak, targetKey); err != nil { + if akPolicy, err = m.user.transferVol(¶m); err != nil { sendErrReply(w, r, newErrHTTPReply(err)) return } diff --git a/master/const.go b/master/const.go index 78fb323b7e..9d73557676 100644 --- a/master/const.go +++ b/master/const.go @@ -123,9 +123,9 @@ const ( opSyncUpdateAKPolicy uint32 = 0x19 opSyncAddUserAK uint32 = 0x1A opSyncDeleteUserAK uint32 = 0x1B - opSyncAddVolAK uint32 = 0x1C - opSyncDeleteVolAK uint32 = 0x1D - opSyncUpdateVolAK uint32 = 0x1E + opSyncAddVolUser uint32 = 0x1C + opSyncDeleteVolUser uint32 = 0x1D + opSyncUpdateVolUser uint32 = 0x1E ) const ( @@ -149,10 +149,10 @@ const ( clusterPrefix = keySeparator + clusterAcronym + keySeparator nodeSetPrefix = keySeparator + nodeSetAcronym + keySeparator - akAcronym = "ak" - userAcronym = "user" - volAKAcronym = "volak" - akPrefix = keySeparator + akAcronym + keySeparator - userPrefix = keySeparator + userAcronym + keySeparator - volAKPrefix = keySeparator + volAKAcronym + keySeparator + akAcronym = "ak" + userAcronym = "user" + volUserAcronym = "voluser" + akPrefix = keySeparator + akAcronym + keySeparator + userPrefix = keySeparator + userAcronym + keySeparator + volUserPrefix = keySeparator + volUserAcronym + keySeparator ) diff --git a/master/http_server.go b/master/http_server.go index 0a8a7cd14b..5bbee92fef 100644 --- a/master/http_server.go +++ b/master/http_server.go @@ -208,11 +208,11 @@ func (m *Server) registerAPIRoutes(router *mux.Router) { Path(proto.UserDelete). HandlerFunc(m.deleteUser) router.NewRoute().Methods(http.MethodGet, http.MethodPost). - Path(proto.UserAddPolicy). - HandlerFunc(m.addUserPolicy) + Path(proto.UserUpdatePolicy). + HandlerFunc(m.updateUserPolicy) router.NewRoute().Methods(http.MethodGet, http.MethodPost). - Path(proto.UserDeletePolicy). - HandlerFunc(m.deleteUserPolicy) + Path(proto.UserRemovePolicy). + HandlerFunc(m.removeUserPolicy) router.NewRoute().Methods(http.MethodGet, http.MethodPost). Path(proto.UserDeleteVolPolicy). HandlerFunc(m.deleteUserVolPolicy) diff --git a/master/master_manager.go b/master/master_manager.go index 1825938b72..a8f90315b2 100644 --- a/master/master_manager.go +++ b/master/master_manager.go @@ -127,7 +127,7 @@ func (m *Server) loadMetadata() { if err = m.user.loadUserAK(); err != nil { panic(err) } - if err = m.user.loadVolAKs(); err != nil { + if err = m.user.loadVolUsers(); err != nil { panic(err) } log.LogInfo("action[loadUserInfo] end") @@ -147,7 +147,7 @@ func (m *Server) clearMetadata() { m.cluster.clearVols() m.user.clearAKStore() m.user.clearUserAK() - m.user.clearVolAKs() + m.user.clearVolUsers() m.cluster.t = newTopology() } diff --git a/master/metadata_fsm.go b/master/metadata_fsm.go index 12273e7550..2483134b36 100644 --- a/master/metadata_fsm.go +++ b/master/metadata_fsm.go @@ -120,7 +120,7 @@ func (mf *MetadataFsm) Apply(command []byte, index uint64) (resp interface{}, er } switch cmd.Op { case opSyncDeleteDataNode, opSyncDeleteMetaNode, opSyncDeleteVol, opSyncDeleteDataPartition, opSyncDeleteMetaPartition, - opSyncDeleteAKPolicy, opSyncDeleteUserAK, opSyncDeleteVolAK: + opSyncDeleteAKPolicy, opSyncDeleteUserAK, opSyncDeleteVolUser: if err = mf.delKeyAndPutIndex(cmd.K, cmdMap); err != nil { panic(err) } diff --git a/master/metadata_fsm_op.go b/master/metadata_fsm_op.go index bd5b84743f..c091f05a5c 100644 --- a/master/metadata_fsm_op.go +++ b/master/metadata_fsm_op.go @@ -253,8 +253,8 @@ func (m *RaftCmd) setOpType() { m.Op = opSyncAddAKPolicy case userAcronym: m.Op = opSyncAddUserAK - case volAKAcronym: - m.Op = opSyncAddVolAK + case volUserAcronym: + m.Op = opSyncAddVolUser default: log.LogWarnf("action[setOpType] unknown opCode[%v]", keyArr[1]) } diff --git a/master/user.go b/master/user.go index 391a10eef7..9d79ccd3ac 100644 --- a/master/user.go +++ b/master/user.go @@ -27,10 +27,10 @@ type User struct { partition raftstore.Partition akStore sync.Map //K: ak, V: AKPolicy userAk sync.Map //K: user, V: ak - volAKs sync.Map //K: vol, V: aks + volUser sync.Map //K: vol, V: userIDs akStoreMutex sync.RWMutex userAKMutex sync.RWMutex - volAKsMutex sync.RWMutex + volUserMutex sync.RWMutex rootExist bool } @@ -130,8 +130,8 @@ func (u *User) deleteKey(userID string) (err error) { } u.akStore.Delete(userAK.AccessKey) u.userAk.Delete(userID) - // delete ak from related policy in volAKStore - u.deleteSingleAKFromVolAKs(userAK.AccessKey) + // delete userID from related policy in volUserStore + u.removeUserFromAllVol(userID) log.LogInfof("action[deleteUser], userID: %v, accesskey[%v]", userID, userAK.AccessKey) return } @@ -161,95 +161,118 @@ func (u *User) getUserInfo(userID string) (akPolicy *proto.AKPolicy, err error) return } -func (u *User) addPolicy(ak string, userPolicy *proto.UserPolicy) (akPolicy *proto.AKPolicy, err error) { - if akPolicy, err = u.loadAKInfo(ak); err != nil { +func (u *User) updatePolicy(params *proto.UserPermUpdateParam) (akPolicy *proto.AKPolicy, err error) { + if akPolicy, err = u.getUserInfo(params.UserID); err != nil { return } - akPolicy.Policy.Add(userPolicy) - akPolicy.Policy = proto.CleanPolicy(akPolicy.Policy) + akPolicy.Policy.AddAuthorizedVol(params.Volume, params.Policy) if err = u.syncUpdateAKPolicy(akPolicy); err != nil { err = proto.ErrPersistenceByRaft return } - if err = u.addVolAKs(ak, userPolicy); err != nil { + if err = u.addUserToVol(params.UserID, params.Volume); err != nil { return } - log.LogInfof("action[addPolicy], accessKey: %v", ak) + log.LogInfof("action[updatePolicy], userID: %v, volume: %v", params.UserID, params.Volume) return } -func (u *User) deletePolicy(ak string, userPolicy *proto.UserPolicy) (akPolicy *proto.AKPolicy, err error) { - if akPolicy, err = u.loadAKInfo(ak); err != nil { +func (u *User) removePolicy(params *proto.UserPermRemoveParam) (akPolicy *proto.AKPolicy, err error) { + if akPolicy, err = u.getUserInfo(params.UserID); err != nil { + return + } + akPolicy.Policy.RemoveAuthorizedVol(params.Volume) + if err = u.syncUpdateAKPolicy(akPolicy); err != nil { + err = proto.ErrPersistenceByRaft + return + } + if err = u.removeUserFromVol(params.UserID, params.Volume); err != nil { + return + } + log.LogInfof("action[removePolicy], userID: %v, volume: %v", params.UserID, params.Volume) + return +} + +func (u *User) addOwnVol(userID, volName string) (akPolicy *proto.AKPolicy, err error) { + if akPolicy, err = u.getUserInfo(userID); err != nil { + return + } + akPolicy.Policy.AddOwnVol(volName) + if err = u.syncUpdateAKPolicy(akPolicy); err != nil { + err = proto.ErrPersistenceByRaft + return + } + if err = u.addUserToVol(userID, volName); err != nil { + return + } + log.LogInfof("action[addOwnVol], userID: %v, volume: %v", userID, volName) + return +} + +func (u *User) removeOwnVol(userID, volName string) (akPolicy *proto.AKPolicy, err error) { + if akPolicy, err = u.getUserInfo(userID); err != nil { return } - akPolicy.Policy.Delete(userPolicy) + akPolicy.Policy.RemoveOwnVol(volName) if err = u.syncUpdateAKPolicy(akPolicy); err != nil { err = proto.ErrPersistenceByRaft return } - if err = u.deleteVolAKs(ak, userPolicy); err != nil { + if err = u.removeUserFromVol(userID, volName); err != nil { return } - log.LogInfof("action[deletePolicy], accessKey: %v", ak) + log.LogInfof("action[removeOwnVol], userID: %v, volume: %v", userID, volName) return } func (u *User) deleteVolPolicy(volName string) (err error) { var ( - volAK *proto.VolAK + volUser *proto.VolUser akPolicy *proto.AKPolicy ) - //get related ak - if value, exist := u.volAKs.Load(volName); exist { - volAK = value.(*proto.VolAK) + //get related userIDs + if value, exist := u.volUser.Load(volName); exist { + volUser = value.(*proto.VolUser) } else { return nil } //delete policy - for ak, akAndActions := range volAK.AKAndActions { - for _, action := range akAndActions { - if akPolicy, err = u.loadAKInfo(ak); err != nil { - return - } - var userPolicy *proto.UserPolicy - if action == ALL { - userPolicy = &proto.UserPolicy{OwnVols: []string{volName}} - } else { - userPolicy = &proto.UserPolicy{AuthorizedVols: map[string][]string{volName: {action}}} - } - akPolicy.Policy.Delete(userPolicy) - if err = u.syncUpdateAKPolicy(akPolicy); err != nil { - err = proto.ErrPersistenceByRaft - return - } + for _, userID := range volUser.UserIDs { + if akPolicy, err = u.getUserInfo(userID); err != nil { + return + } + akPolicy.Policy.RemoveOwnVol(volName) + akPolicy.Policy.RemoveAuthorizedVol(volName) + if err = u.syncUpdateAKPolicy(akPolicy); err != nil { + err = proto.ErrPersistenceByRaft + return } } //delete volName index - if err = u.syncDeleteVolAK(volAK); err != nil { + if err = u.syncDeleteVolUser(volUser); err != nil { return } - u.volAKs.Delete(volAK.Vol) + u.volUser.Delete(volUser.Vol) log.LogInfof("action[deleteVolPolicy], volName: %v", volName) return } -func (u *User) transferVol(volName, ak, targetKey string) (targetAKPolicy *proto.AKPolicy, err error) { +func (u *User) transferVol(params *proto.UserTransferVolParam) (targetAKPolicy *proto.AKPolicy, err error) { var akPolicy *proto.AKPolicy - userPolicy := &proto.UserPolicy{OwnVols: []string{volName}} - if akPolicy, err = u.loadAKInfo(ak); err != nil { + if akPolicy, err = u.getUserInfo(params.UserSrc); err != nil { return } - if !contains(akPolicy.Policy.OwnVols, volName) { + if !contains(akPolicy.Policy.OwnVols, params.Volume) { err = proto.ErrHaveNoPolicy return } - if _, err = u.deletePolicy(ak, userPolicy); err != nil { + if _, err = u.removeOwnVol(params.UserSrc, params.Volume); err != nil { return } - if targetAKPolicy, err = u.addPolicy(targetKey, userPolicy); err != nil { + if targetAKPolicy, err = u.addOwnVol(params.UserDst, params.Volume); err != nil { return } - log.LogInfof("action[transferVol], volName: %v, ak: %v, targetKey: %v", volName, ak, targetKey) + log.LogInfof("action[transferVol], volName: %v, userSrc: %v, userDst: %v", params.Volume, params.UserSrc, params.UserDst) return } @@ -275,108 +298,66 @@ func (u *User) loadAKInfo(ak string) (akPolicy *proto.AKPolicy, err error) { return } -func (u *User) addVolAKs(ak string, policy *proto.UserPolicy) (err error) { - u.volAKsMutex.Lock() - defer u.volAKsMutex.Unlock() - for _, vol := range policy.OwnVols { - if err = u.addAKToVol(ak, ALL, vol); err != nil { - return - } - } - for vol, actions := range policy.AuthorizedVols { - for _, action := range actions { - if err = u.addAKToVol(ak, action, vol); err != nil { - return - } - } - } - return -} - -func (u *User) addAKToVol(ak, action string, volName string) (err error) { +func (u *User) addUserToVol(userID, volName string) (err error) { + u.volUserMutex.Lock() + defer u.volUserMutex.Unlock() var ( - volAK *proto.VolAK - actions []string - exist bool + volUser *proto.VolUser ) - if value, ok := u.volAKs.Load(volName); ok { - volAK = value.(*proto.VolAK) - volAK.Lock() - defer volAK.Unlock() - if actions, exist = volAK.AKAndActions[ak]; !exist { - actions = make([]string, 0) - } - actions = append(actions, action) - volAK.AKAndActions[ak] = actions + if value, ok := u.volUser.Load(volName); ok { + volUser = value.(*proto.VolUser) + volUser.Lock() + defer volUser.Unlock() + volUser.UserIDs = append(volUser.UserIDs, userID) } else { - akAndActions := make(map[string][]string) - actions = []string{action} - akAndActions[ak] = actions - volAK = &proto.VolAK{Vol: volName, AKAndActions: akAndActions} - u.volAKs.Store(volName, volAK) + volUser = &proto.VolUser{Vol: volName, UserIDs: []string{userID}} + u.volUser.Store(volName, volUser) } - if err = u.syncAddVolAK(volAK); err != nil { + if err = u.syncAddVolUser(volUser); err != nil { err = proto.ErrPersistenceByRaft return } return } - -func (u *User) deleteVolAKs(ak string, policy *proto.UserPolicy) (err error) { - for _, vol := range policy.OwnVols { - if err = u.deleteAKFromVol(ak, ALL, vol); err != nil { - return - } - } - for vol, actions := range policy.AuthorizedVols { - for _, action := range actions { - if err = u.deleteAKFromVol(ak, action, vol); err != nil { - return - } - } - } - return -} - -func (u *User) deleteAKFromVol(ak, action string, volName string) (err error) { - var volAK *proto.VolAK - if value, ok := u.volAKs.Load(volName); ok { - volAK = value.(*proto.VolAK) - volAK.Lock() - defer volAK.Unlock() - volAK.AKAndActions[ak] = removeAK(volAK.AKAndActions[ak], action) +func (u *User) removeUserFromVol(userID, volName string) (err error) { + var ( + volUser *proto.VolUser + ) + if value, ok := u.volUser.Load(volName); ok { + volUser = value.(*proto.VolUser) + volUser.Lock() + defer volUser.Unlock() + volUser.UserIDs = removeString(volUser.UserIDs, userID) } else { err = proto.ErrHaveNoPolicy } - if err = u.syncUpdateVolAK(volAK); err != nil { + if err = u.syncUpdateVolUser(volUser); err != nil { err = proto.ErrPersistenceByRaft return } return } -func removeAK(array []string, element string) []string { +func (u *User) removeUserFromAllVol(userID string) { + u.volUser.Range(func(key, value interface{}) bool { + volUser := value.(*proto.VolUser) + volUser.Lock() + volUser.UserIDs = removeString(volUser.UserIDs, userID) + volUser.Unlock() + return true + }) +} + +func removeString(array []string, element string) []string { for k, v := range array { if v == element { return append(array[:k], array[k+1:]...) } } - log.LogErrorf("Delete user policy failed: remove accesskey [%v] form vol", element) + log.LogErrorf("Delete user policy failed: remove userID[%v] form vol", element) return array } -func (u *User) deleteSingleAKFromVolAKs(ak string) { - var akAndActions map[string][]string - u.volAKs.Range(func(key, value interface{}) bool { - volAK := value.(*proto.VolAK) - volAK.Lock() - akAndActions = volAK.AKAndActions - delete(akAndActions, ak) - volAK.Unlock() - return true - }) -} - func sha1String(s string) string { t := sha1.New() io.WriteString(t, s) @@ -397,9 +378,9 @@ func (u *User) clearUserAK() { }) } -func (u *User) clearVolAKs() { - u.volAKs.Range(func(key, value interface{}) bool { - u.volAKs.Delete(key) +func (u *User) clearVolUsers() { + u.volUser.Range(func(key, value interface{}) bool { + u.volUser.Delete(key) return true }) } diff --git a/master/userdata_fsm_op.go b/master/userdata_fsm_op.go index 9b35d1eca9..d8cbbef244 100644 --- a/master/userdata_fsm_op.go +++ b/master/userdata_fsm_op.go @@ -79,23 +79,23 @@ func (u *User) syncPutUserAK(opType uint32, userAK *proto.UserAK) (err error) { return u.submit(userInfo) } -func (u *User) syncAddVolAK(volAK *proto.VolAK) (err error) { - return u.syncPutVolAK(opSyncAddVolAK, volAK) +func (u *User) syncAddVolUser(volUser *proto.VolUser) (err error) { + return u.syncPutVolUser(opSyncAddVolUser, volUser) } -func (u *User) syncDeleteVolAK(volAK *proto.VolAK) (err error) { - return u.syncPutVolAK(opSyncDeleteVolAK, volAK) +func (u *User) syncDeleteVolUser(volUser *proto.VolUser) (err error) { + return u.syncPutVolUser(opSyncDeleteVolUser, volUser) } -func (u *User) syncUpdateVolAK(volAK *proto.VolAK) (err error) { - return u.syncPutVolAK(opSyncUpdateVolAK, volAK) +func (u *User) syncUpdateVolUser(volUser *proto.VolUser) (err error) { + return u.syncPutVolUser(opSyncUpdateVolUser, volUser) } -func (u *User) syncPutVolAK(opType uint32, volAK *proto.VolAK) (err error) { +func (u *User) syncPutVolUser(opType uint32, volUser *proto.VolUser) (err error) { userInfo := new(RaftCmd) userInfo.Op = opType - userInfo.K = volAKPrefix + volAK.Vol - userInfo.V, err = json.Marshal(volAK) + userInfo.K = volUserPrefix + volUser.Vol + userInfo.V, err = json.Marshal(volUser) if err != nil { return errors.New(err.Error()) } @@ -138,20 +138,20 @@ func (u *User) loadUserAK() (err error) { return } -func (u *User) loadVolAKs() (err error) { - result, err := u.fsm.store.SeekForPrefix([]byte(volAKPrefix)) +func (u *User) loadVolUsers() (err error) { + result, err := u.fsm.store.SeekForPrefix([]byte(volUserPrefix)) if err != nil { - err = fmt.Errorf("action[loadVolAKs], err: %v", err.Error()) + err = fmt.Errorf("action[loadVolUsers], err: %v", err.Error()) return err } for _, value := range result { - volAK := &proto.VolAK{} - if err = json.Unmarshal(value, volAK); err != nil { - err = fmt.Errorf("action[loadVolAKs], unmarshal err: %v", err.Error()) + volUser := &proto.VolUser{} + if err = json.Unmarshal(value, volUser); err != nil { + err = fmt.Errorf("action[loadVolUsers], unmarshal err: %v", err.Error()) return err } - u.volAKs.Store(volAK.Vol, volAK) - log.LogInfof("action[loadVolAKs], vol[%v]", volAK.Vol) + u.volUser.Store(volUser.Vol, volUser) + log.LogInfof("action[loadVolUsers], vol[%v]", volUser.Vol) } return } diff --git a/proto/admin_proto.go b/proto/admin_proto.go index dd3a064f00..78d1beba60 100644 --- a/proto/admin_proto.go +++ b/proto/admin_proto.go @@ -72,8 +72,8 @@ const ( // APIs for user management UserCreate = "/user/create" UserDelete = "/user/delete" - UserAddPolicy = "/user/addPolicy" - UserDeletePolicy = "/user/deletePolicy" + UserUpdatePolicy = "/user/updatePolicy" + UserRemovePolicy = "/user/removePolicy" UserDeleteVolPolicy = "/user/deleteVolPolicy" UserGetInfo = "/user/info" UserGetAKInfo = "/user/akInfo" diff --git a/proto/user_proto.go b/proto/user_proto.go index 965573606e..285d08d983 100644 --- a/proto/user_proto.go +++ b/proto/user_proto.go @@ -77,13 +77,13 @@ type AKPolicy struct { CreateTime string `json:"create_time"` } -func NewAkPolicy() *AKPolicy { +func NewAKPolicy() *AKPolicy { return &AKPolicy{Policy: NewUserPolicy()} } -type VolAK struct { - Vol string `json:"vol"` - AKAndActions map[string][]string // k: ak, v: actions or permissions +type VolUser struct { + Vol string `json:"vol"` + UserIDs []string `json:"user_id"` sync.RWMutex } @@ -155,6 +155,27 @@ func (policy *UserPolicy) RemoveOwnVol(volume string) { } } +func (policy *UserPolicy) AddAuthorizedVol(volume string, policies []string) { //todo check duplicate + policy.mu.Lock() + defer policy.mu.Unlock() + newPolicies := make([]string, 0) + for _, policy := range policies { + if perm := ParsePermission(policy); !perm.IsNone() { + newPolicies = append(newPolicies, perm.String()) + } + if act := ParseAction(policy); !act.IsNone() { + newPolicies = append(newPolicies, act.String()) + } + } + policy.AuthorizedVols[volume] = newPolicies +} + +func (policy *UserPolicy) RemoveAuthorizedVol(volume string) { + policy.mu.Lock() + defer policy.mu.Unlock() + delete(policy.AuthorizedVols, volume) +} + func (policy *UserPolicy) SetPerm(volume string, perm Permission) { policy.mu.Lock() defer policy.mu.Unlock() @@ -243,13 +264,19 @@ type UserCreateParam struct { Type UserType } -type UserPermUpdateParam struct { - UserID string `json:"user_id"` - Volume string `json:"volume"` - Perm Permission `json:"perm"` +type UserPermUpdateParam struct { //todo + UserID string `json:"user_id"` + Volume string `json:"volume"` + Policy []string `json:"policy"` } type UserPermRemoveParam struct { UserID string `json:"user_id"` Volume string `json:"volume"` } + +type UserTransferVolParam struct { + Volume string `json:"volume"` + UserSrc string `json:"user_src"` + UserDst string `json:"user_dst"` +} diff --git a/sdk/master/api_user.go b/sdk/master/api_user.go index 98499a2263..aa1f72d4dc 100644 --- a/sdk/master/api_user.go +++ b/sdk/master/api_user.go @@ -71,7 +71,7 @@ func (api *UserAPI) AddPolicy(accesskey string, policy *proto.UserPolicy) (akPol if body, err = json.Marshal(policy); err != nil { return } - var request = newAPIRequest(http.MethodPost, proto.UserAddPolicy) + var request = newAPIRequest(http.MethodPost, proto.UserUpdatePolicy) request.addParam("ak", accesskey) request.addBody(body) var data []byte @@ -90,7 +90,7 @@ func (api *UserAPI) DeletePolicy(accesskey string, policy *proto.UserPolicy) (ak if body, err = json.Marshal(policy); err != nil { return } - var request = newAPIRequest(http.MethodPost, proto.UserDeletePolicy) + var request = newAPIRequest(http.MethodPost, proto.UserRemovePolicy) request.addParam("ak", accesskey) request.addBody(body) var data []byte