You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2020/07/16 06:47:38 UTC
[servicecomb-service-center] branch master updated: delete account,
list account (#668)
This is an automated email from the ASF dual-hosted git repository.
tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new a3a5ebd delete account,list account (#668)
a3a5ebd is described below
commit a3a5ebdff1d2b1b0eb3d9c3af0e72b0d363b8815
Author: Shawn <xi...@gmail.com>
AuthorDate: Thu Jul 16 14:47:23 2020 +0800
delete account,list account (#668)
---
pkg/errors/text.go | 9 ++-
pkg/rbacframe/account.go | 7 ++
.../rbac/dao => pkg/rbacframe}/resource_dao.go | 25 ++++---
server/plugin/auth/buildin/buidlin_test.go | 21 +++++-
server/plugin/auth/buildin/buildin.go | 37 +++++++---
server/rest/controller/v4/auth_resource.go | 55 +++++++++++++-
server/rest/controller/v4/auth_resource_test.go | 86 ++++++++++++++++++++++
server/service/kv/store.go | 10 +++
server/service/kv/store_test.go | 11 +++
server/service/rbac/dao/account_dao.go | 29 +++++++-
server/service/rbac/rbac.go | 11 +++
server/service/rbac/rbca_test.go | 5 ++
12 files changed, 272 insertions(+), 34 deletions(-)
diff --git a/pkg/errors/text.go b/pkg/errors/text.go
index a9c3e7b..998e17e 100644
--- a/pkg/errors/text.go
+++ b/pkg/errors/text.go
@@ -18,9 +18,10 @@
package errors
const (
- ErrMsgJSON = "json is invalid"
+ MsgJSON = "json is invalid"
- ErrMsgCreateAccount = "create account failed"
- ErrMsgRolePerm = "check role permissions failed"
- ErrMsgNoPerm = "no permission to operate"
+ MsgOperateAccountFailed = "operate account failed"
+ MsgGetAccountFailed = "get account failed"
+ MsgRolePerm = "check role permissions failed"
+ MsgNoPerm = "no permission to operate"
)
diff --git a/pkg/rbacframe/account.go b/pkg/rbacframe/account.go
index 4b32c4f..00cd133 100644
--- a/pkg/rbacframe/account.go
+++ b/pkg/rbacframe/account.go
@@ -21,12 +21,19 @@ const (
RoleAdmin = "admin"
)
+type AccountResponse struct {
+ Total int64 `json:"total"`
+ Accounts []*Account `json:"data,omitempty"`
+}
+
type Account struct {
+ ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Password string `json:"password,omitempty"`
Role string `json:"role,omitempty"`
TokenExpiryTime string `json:"tokenExpiryTime,omitempty"`
CurrentPassword string `json:"currentPassword,omitempty"`
+ Status string `json:"status,omitempty"`
}
type Token struct {
diff --git a/server/service/rbac/dao/resource_dao.go b/pkg/rbacframe/resource_dao.go
similarity index 63%
rename from server/service/rbac/dao/resource_dao.go
rename to pkg/rbacframe/resource_dao.go
index f0b01da..1e39350 100644
--- a/server/service/rbac/dao/resource_dao.go
+++ b/pkg/rbacframe/resource_dao.go
@@ -15,22 +15,23 @@
* limitations under the License.
*/
-package dao
+package rbacframe
-import "context"
+//as a user, he only understand resource of this system,
+//but to decouple authorization code from business code,
+//a middleware should handle all the authorization logic, and this middleware only understand rest API,
+//a resource mapping helps to do it.
+var resourceMap = map[string]string{}
-//TODO save to etcd
-//TODO now simply write dead code "*" to map all other API except account and role to service, should define resource for every API in future
-var resourceMap = map[string]string{
- "/v4/account": "account",
- "/v4/role": "account",
- "*": "service",
-}
-
-func GetResource(ctx context.Context, API string) string {
- r, ok := resourceMap[API]
+func GetResource(api string) string {
+ r, ok := resourceMap[api]
if !ok {
return resourceMap["*"]
}
return r
}
+
+//MapResource save the mapping from api to resource
+func MapResource(api, resource string) {
+ resourceMap[api] = resource
+}
diff --git a/server/plugin/auth/buildin/buidlin_test.go b/server/plugin/auth/buildin/buidlin_test.go
index f6953da..39f09a3 100644
--- a/server/plugin/auth/buildin/buidlin_test.go
+++ b/server/plugin/auth/buildin/buidlin_test.go
@@ -98,7 +98,7 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
t.Log(err)
assert.Error(t, err)
})
- t.Run("valid admin token, should be able to operate account", func(t *testing.T) {
+ t.Run("valid admin token, should be able to get account", func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/v4/account", nil)
to, err := authr.Login(context.TODO(), "root", "Complicated_password1")
assert.NoError(t, err)
@@ -106,7 +106,7 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
err = ta.Identify(r)
assert.NoError(t, err)
})
- t.Run("valid normal token, should no be able to operate account", func(t *testing.T) {
+ t.Run("valid normal token, should no be able to get account", func(t *testing.T) {
err := dao.CreateAccount(context.TODO(), &rbacframe.Account{Name: "non-admin", Password: "Complicated_password1", Role: "developer"})
assert.NoError(t, err)
r := httptest.NewRequest(http.MethodGet, "/v4/account", nil)
@@ -117,4 +117,21 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
t.Log(err)
assert.Error(t, err)
})
+ t.Run("valid normal token, should no be able to delete account", func(t *testing.T) {
+ r := httptest.NewRequest(http.MethodDelete, "/v4/account", nil)
+ to, err := authr.Login(context.TODO(), "non-admin", "Complicated_password1")
+ assert.NoError(t, err)
+ r.Header.Set(restful.HeaderAuth, "Bear "+to)
+ err = ta.Identify(r)
+ t.Log(err)
+ assert.Error(t, err)
+ })
+ t.Run("valid admin token, should be able to delete account", func(t *testing.T) {
+ r := httptest.NewRequest(http.MethodDelete, "/v4/account", nil)
+ to, err := authr.Login(context.TODO(), "root", "Complicated_password1")
+ assert.NoError(t, err)
+ r.Header.Set(restful.HeaderAuth, "Bear "+to)
+ err = ta.Identify(r)
+ assert.NoError(t, err)
+ })
}
diff --git a/server/plugin/auth/buildin/buildin.go b/server/plugin/auth/buildin/buildin.go
index 9003c4e..a6640ee 100644
--- a/server/plugin/auth/buildin/buildin.go
+++ b/server/plugin/auth/buildin/buildin.go
@@ -26,7 +26,6 @@ import (
"github.com/apache/servicecomb-service-center/pkg/rest"
mgr "github.com/apache/servicecomb-service-center/server/plugin"
"github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
"github.com/go-chassis/go-chassis/security/authr"
"github.com/go-chassis/go-chassis/server/restful"
"net/http"
@@ -67,7 +66,6 @@ func (ba *TokenAuthenticator) Identify(req *http.Request) error {
log.Errorf(err, "authenticate request failed, %s %s", req.Method, req.RequestURI)
return err
}
- //TODO rbac
m, ok := claims.(map[string]interface{})
if !ok {
log.Error("claims convert failed", rbacframe.ErrConvertErr)
@@ -79,17 +77,38 @@ func (ba *TokenAuthenticator) Identify(req *http.Request) error {
log.Error("role convert failed", rbacframe.ErrConvertErr)
return rbacframe.ErrConvertErr
}
- r := dao.GetResource(context.TODO(), req.URL.Path)
- //TODO add verbs
- allow, err := rbac.Allow(context.TODO(), roleName, req.URL.Query().Get(":project"), r, "")
+ var apiPattern string
+ a := req.Context().Value(rest.CtxMatchPattern)
+ if a == nil { //handle exception
+ apiPattern = req.URL.Path
+ log.Warn("can not find api pattern")
+ } else {
+ apiPattern = a.(string)
+ }
+ err = checkPerm(roleName, apiPattern)
+ if err != nil {
+ return err
+ }
+ req2 := req.WithContext(rbacframe.NewContext(req.Context(), claims))
+ *req = *req2
+ return nil
+}
+
+//this method decouple business code and perm checks
+func checkPerm(roleName, apiPattern string) error {
+ resource := rbacframe.GetResource(apiPattern)
+ if resource == "" {
+ //fast fail, no need to access role storage
+ return errors.New(errorsEx.MsgNoPerm)
+ }
+ //TODO add verbs,project
+ allow, err := rbac.Allow(context.TODO(), roleName, "", resource, "")
if err != nil {
log.Error("", err)
- return errors.New(errorsEx.ErrMsgRolePerm)
+ return errors.New(errorsEx.MsgRolePerm)
}
if !allow {
- return errors.New(errorsEx.ErrMsgNoPerm)
+ return errors.New(errorsEx.MsgNoPerm)
}
- req2 := req.WithContext(rbacframe.NewContext(req.Context(), claims))
- *req = *req2
return nil
}
diff --git a/server/rest/controller/v4/auth_resource.go b/server/rest/controller/v4/auth_resource.go
index 70ab5b4..bbfa154 100644
--- a/server/rest/controller/v4/auth_resource.go
+++ b/server/rest/controller/v4/auth_resource.go
@@ -43,6 +43,9 @@ func (r *AuthResource) URLPatterns() []rest.Route {
return []rest.Route{
{Method: http.MethodPost, Path: "/v4/token", Func: r.Login},
{Method: http.MethodPost, Path: "/v4/account", Func: r.CreateAccount},
+ {Method: http.MethodGet, Path: "/v4/account", Func: r.ListAccount},
+ {Method: http.MethodGet, Path: "/v4/account/:name", Func: r.GetAccount},
+ {Method: http.MethodDelete, Path: "/v4/account/:name", Func: r.DeleteAccount},
{Method: http.MethodPost, Path: "/v4/account/:name/password", Func: r.ChangePassword},
}
}
@@ -56,7 +59,7 @@ func (r *AuthResource) CreateAccount(w http.ResponseWriter, req *http.Request) {
a := &rbacframe.Account{}
if err = json.Unmarshal(body, a); err != nil {
log.Error("json err", err)
- controller.WriteError(w, scerror.ErrInvalidParams, errorsEx.ErrMsgJSON)
+ controller.WriteError(w, scerror.ErrInvalidParams, errorsEx.MsgJSON)
return
}
err = service.ValidateCreateAccount(a)
@@ -70,11 +73,55 @@ func (r *AuthResource) CreateAccount(w http.ResponseWriter, req *http.Request) {
controller.WriteError(w, scerror.ErrConflictAccount, "")
return
}
- log.Error(errorsEx.ErrMsgCreateAccount, err)
- controller.WriteError(w, scerror.ErrInternal, errorsEx.ErrMsgCreateAccount)
+ log.Error(errorsEx.MsgOperateAccountFailed, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgOperateAccountFailed)
return
}
}
+func (r *AuthResource) DeleteAccount(w http.ResponseWriter, req *http.Request) {
+ _, err := dao.DeleteAccount(context.TODO(), req.URL.Query().Get(":name"))
+ if err != nil {
+ log.Error(errorsEx.MsgOperateAccountFailed, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgOperateAccountFailed)
+ return
+ }
+ w.WriteHeader(http.StatusNoContent)
+}
+func (r *AuthResource) ListAccount(w http.ResponseWriter, req *http.Request) {
+ as, n, err := dao.ListAccount(context.TODO())
+ if err != nil {
+ log.Error(errorsEx.MsgGetAccountFailed, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgGetAccountFailed)
+ return
+ }
+ resp := &rbacframe.AccountResponse{
+ Total: n,
+ Accounts: as,
+ }
+ b, err := json.Marshal(resp)
+ if err != nil {
+ log.Error(errorsEx.MsgJSON, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgJSON)
+ return
+ }
+ controller.WriteJSON(w, b)
+}
+func (r *AuthResource) GetAccount(w http.ResponseWriter, req *http.Request) {
+ a, err := dao.GetAccount(context.TODO(), req.URL.Query().Get(":name"))
+ if err != nil {
+ log.Error(errorsEx.MsgGetAccountFailed, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgGetAccountFailed)
+ return
+ }
+ a.Password = ""
+ b, err := json.Marshal(a)
+ if err != nil {
+ log.Error(errorsEx.MsgJSON, err)
+ controller.WriteError(w, scerror.ErrInternal, errorsEx.MsgJSON)
+ return
+ }
+ controller.WriteJSON(w, b)
+}
func (r *AuthResource) ChangePassword(w http.ResponseWriter, req *http.Request) {
ip := util.GetRealIP(req)
if rbac.IsBanned(ip) {
@@ -91,7 +138,7 @@ func (r *AuthResource) ChangePassword(w http.ResponseWriter, req *http.Request)
a := &rbacframe.Account{}
if err = json.Unmarshal(body, a); err != nil {
log.Error("json err", err)
- controller.WriteError(w, scerror.ErrInvalidParams, errorsEx.ErrMsgJSON)
+ controller.WriteError(w, scerror.ErrInvalidParams, errorsEx.MsgJSON)
return
}
a.Name = req.URL.Query().Get(":name")
diff --git a/server/rest/controller/v4/auth_resource_test.go b/server/rest/controller/v4/auth_resource_test.go
index 273ad35..a84b67f 100644
--- a/server/rest/controller/v4/auth_resource_test.go
+++ b/server/rest/controller/v4/auth_resource_test.go
@@ -105,6 +105,92 @@ func TestAuthResource_Login(t *testing.T) {
rest.GetRouter().ServeHTTP(w, r)
assert.Equal(t, http.StatusOK, w.Code)
})
+
+}
+func TestAuthResource_DeleteAccount(t *testing.T) {
+ t.Run("dev_account can not even delete him self", func(t *testing.T) {
+ b, _ := json.Marshal(&rbacframe.Account{Name: "dev_account", Password: "Complicated_password2"})
+
+ r, _ := http.NewRequest(http.MethodPost, "/v4/token", bytes.NewBuffer(b))
+ w := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w, r)
+ assert.Equal(t, http.StatusOK, w.Code)
+ to := &rbacframe.Token{}
+ json.Unmarshal(w.Body.Bytes(), to)
+
+ r2, _ := http.NewRequest(http.MethodDelete, "/v4/account/dev_account", nil)
+ r2.Header.Set(restful.HeaderAuth, "Bearer "+to.TokenStr)
+ w2 := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w2, r2)
+ assert.Equal(t, http.StatusUnauthorized, w2.Code)
+ })
+ t.Run("root can delete account", func(t *testing.T) {
+ b, _ := json.Marshal(&rbacframe.Account{Name: "root", Password: "Complicated_password1"})
+ r, _ := http.NewRequest(http.MethodPost, "/v4/token", bytes.NewBuffer(b))
+ w := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w, r)
+ assert.Equal(t, http.StatusOK, w.Code)
+ to := &rbacframe.Token{}
+ json.Unmarshal(w.Body.Bytes(), to)
+
+ b, _ = json.Marshal(&rbacframe.Account{Name: "delete_account", Password: "Complicated_password1"})
+ r2, _ := http.NewRequest(http.MethodPost, "/v4/account", bytes.NewBuffer(b))
+ r2.Header.Set(restful.HeaderAuth, "Bearer "+to.TokenStr)
+ w2 := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w2, r2)
+ assert.Equal(t, http.StatusOK, w2.Code)
+
+ r3, _ := http.NewRequest(http.MethodDelete, "/v4/account/delete_account", nil)
+ r3.Header.Set(restful.HeaderAuth, "Bearer "+to.TokenStr)
+ w3 := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w3, r3)
+ assert.Equal(t, http.StatusNoContent, w3.Code)
+ })
+}
+func TestAuthResource_GetAccount(t *testing.T) {
+ t.Run("get account", func(t *testing.T) {
+ b, _ := json.Marshal(&rbacframe.Account{Name: "root", Password: "Complicated_password1"})
+ r, _ := http.NewRequest(http.MethodPost, "/v4/token", bytes.NewBuffer(b))
+ w := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w, r)
+ assert.Equal(t, http.StatusOK, w.Code)
+ to := &rbacframe.Token{}
+ json.Unmarshal(w.Body.Bytes(), to)
+
+ r3, _ := http.NewRequest(http.MethodGet, "/v4/account/dev_account", nil)
+ r3.Header.Set(restful.HeaderAuth, "Bearer "+to.TokenStr)
+ w3 := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w3, r3)
+ assert.Equal(t, http.StatusOK, w3.Code)
+
+ a := &rbacframe.Account{}
+ json.Unmarshal(w3.Body.Bytes(), a)
+ assert.Equal(t, "dev_account", a.Name)
+ assert.Equal(t, "developer", a.Role)
+ assert.Empty(t, a.Password)
+ })
+ t.Run("list account", func(t *testing.T) {
+ b, _ := json.Marshal(&rbacframe.Account{Name: "root", Password: "Complicated_password1"})
+ r, _ := http.NewRequest(http.MethodPost, "/v4/token", bytes.NewBuffer(b))
+ w := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w, r)
+ assert.Equal(t, http.StatusOK, w.Code)
+ to := &rbacframe.Token{}
+ json.Unmarshal(w.Body.Bytes(), to)
+
+ r3, _ := http.NewRequest(http.MethodGet, "/v4/account", nil)
+ r3.Header.Set(restful.HeaderAuth, "Bearer "+to.TokenStr)
+ w3 := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w3, r3)
+ assert.Equal(t, http.StatusOK, w3.Code)
+
+ a := &rbacframe.AccountResponse{}
+ json.Unmarshal(w3.Body.Bytes(), a)
+ assert.Greater(t, a.Total, int64(2))
+ assert.Empty(t, a.Accounts[0].Password)
+ })
+}
+func TestAuthResource_Login2(t *testing.T) {
t.Run("bock user dev_account", func(t *testing.T) {
b, _ := json.Marshal(&rbacframe.Account{Name: "dev_account", Password: "Complicated_password1"})
diff --git a/server/service/kv/store.go b/server/service/kv/store.go
index b9418bb..f47a42c 100644
--- a/server/service/kv/store.go
+++ b/server/service/kv/store.go
@@ -58,6 +58,16 @@ func Get(ctx context.Context, key string) (*mvccpb.KeyValue, error) {
return resp.Kvs[0], err
}
+//Get get kv list
+func List(ctx context.Context, key string) ([]*mvccpb.KeyValue, int64, error) {
+ resp, err := backend.Registry().Do(ctx, registry.GET,
+ registry.WithStrKey(key), registry.WithPrefix())
+ if err != nil {
+ return nil, 0, err
+ }
+ return resp.Kvs, resp.Count, nil
+}
+
//Exist get one kv, if can not get return false
func Exist(ctx context.Context, key string) (bool, error) {
resp, err := backend.Registry().Do(ctx, registry.GET,
diff --git a/server/service/kv/store_test.go b/server/service/kv/store_test.go
index 2692460..3b27937 100644
--- a/server/service/kv/store_test.go
+++ b/server/service/kv/store_test.go
@@ -59,4 +59,15 @@ func TestStoreData(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "value", string(r.Value))
})
+
+ t.Run("put many and list", func(t *testing.T) {
+ err := kv.Put(context.Background(), "/test/1", "value1")
+ assert.NoError(t, err)
+ err = kv.Put(context.Background(), "/test/2", "value2")
+ assert.NoError(t, err)
+ kvs, n, err := kv.List(context.Background(), "/test")
+ assert.NoError(t, err)
+ assert.Equal(t, int64(2), n)
+ t.Log(kvs)
+ })
}
diff --git a/server/service/rbac/dao/account_dao.go b/server/service/rbac/dao/account_dao.go
index cf47b76..94500f8 100644
--- a/server/service/rbac/dao/account_dao.go
+++ b/server/service/rbac/dao/account_dao.go
@@ -26,6 +26,7 @@ import (
"github.com/apache/servicecomb-service-center/pkg/etcdsync"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rbacframe"
+ "github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/core"
"github.com/apache/servicecomb-service-center/server/service/kv"
stringutil "github.com/go-chassis/foundation/string"
@@ -63,6 +64,7 @@ func CreateAccount(ctx context.Context, a *rbacframe.Account) error {
return err
}
a.Password = stringutil.Bytes2str(hash)
+ a.ID = util.GenerateUUID()
value, err := json.Marshal(a)
if err != nil {
log.Errorf(err, "account info is invalid")
@@ -73,7 +75,7 @@ func CreateAccount(ctx context.Context, a *rbacframe.Account) error {
log.Errorf(err, "can not save account info")
return err
}
-
+ log.Info("create new account: " + a.ID)
return nil
}
@@ -87,11 +89,31 @@ func GetAccount(ctx context.Context, name string) (*rbacframe.Account, error) {
a := &rbacframe.Account{}
err = json.Unmarshal(r.Value, a)
if err != nil {
- log.Errorf(err, "account info is invalid format")
+ log.Errorf(err, "account info format invalid")
return nil, err
}
return a, nil
}
+func ListAccount(ctx context.Context) ([]*rbacframe.Account, int64, error) {
+ key := core.GenerateAccountKey("")
+ r, n, err := kv.List(ctx, key)
+ if err != nil {
+ log.Errorf(err, "can not get account info")
+ return nil, 0, err
+ }
+ as := make([]*rbacframe.Account, 0, n)
+ for _, v := range r {
+ a := &rbacframe.Account{}
+ err = json.Unmarshal(v.Value, a)
+ if err != nil {
+ log.Error("account info format invalid:", err)
+ continue //do not fail if some account is invalid
+ }
+ a.Password = ""
+ as = append(as, a)
+ }
+ return as, n, nil
+}
func AccountExist(ctx context.Context, name string) (bool, error) {
exist, err := kv.Exist(ctx, core.GenerateAccountKey(name))
if err != nil {
@@ -106,6 +128,7 @@ func DeleteAccount(ctx context.Context, name string) (bool, error) {
log.Errorf(err, "can not get account info")
return false, err
}
+ log.Info("account is deleted")
return exist, nil
}
@@ -132,6 +155,6 @@ func EditAccount(ctx context.Context, a *rbacframe.Account) error {
log.Errorf(err, "can not edit account info")
return err
}
-
+ log.Info("account is edit")
return nil
}
diff --git a/server/service/rbac/rbac.go b/server/service/rbac/rbac.go
index 54c0c70..e741b7c 100644
--- a/server/service/rbac/rbac.go
+++ b/server/service/rbac/rbac.go
@@ -38,6 +38,9 @@ const (
InitPassword = "SC_INIT_ROOT_PASSWORD"
PubFilePath = "rbac_rsa_public_key_file"
)
+const (
+ ResourceAccount = "account"
+)
var (
ErrEmptyCurrentPassword = errors.New("current password should not be empty")
@@ -53,6 +56,7 @@ func Init() {
log.Info("rbac is disabled")
return
}
+ initResourceMap()
err := authr.Init()
if err != nil {
log.Fatal("can not enable auth module", err)
@@ -69,6 +73,13 @@ func Init() {
rbacframe.Add2WhiteAPIList("/v4/token")
log.Info("rbac is enabled")
}
+func initResourceMap() {
+ rbacframe.MapResource("/v4/account", ResourceAccount)
+ rbacframe.MapResource("/v4/account/:name", ResourceAccount)
+ rbacframe.MapResource("/v4/role", "role")
+ //TODO now simply write dead code "*" to map all other API except account and role to service, should define resource for every API in future
+ rbacframe.MapResource("*", "service")
+}
//readPublicKey read key to memory
func readPrivateKey() {
diff --git a/server/service/rbac/rbca_test.go b/server/service/rbac/rbca_test.go
index c72b884..b2a819f 100644
--- a/server/service/rbac/rbca_test.go
+++ b/server/service/rbac/rbca_test.go
@@ -98,5 +98,10 @@ func TestInitRBAC(t *testing.T) {
assert.True(t, rbac.SamePassword(a.Password, "Complicated_password2"))
})
+ t.Run("list kv", func(t *testing.T) {
+ _, n, err := dao.ListAccount(context.TODO())
+ assert.NoError(t, err)
+ assert.Greater(t, n, int64(2))
+ })
}