You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2021/05/31 11:12:13 UTC
[servicecomb-service-center] branch master updated: Add
account/auth error code (#1029)
This is an automated email from the ASF dual-hosted git repository.
littlecui 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 2f66380 Add account/auth error code (#1029)
2f66380 is described below
commit 2f66380422260d980f563a8fb1f39befb862b532
Author: humingcheng <hu...@163.com>
AuthorDate: Mon May 31 19:12:03 2021 +0800
Add account/auth error code (#1029)
* Add account/auth error code
* Add account/auth error code
---
datasource/etcd/account.go | 3 +
datasource/mongo/account.go | 6 +-
pkg/rest/util.go | 5 +
server/handler/auth/auth.go | 5 +
server/plugin/auth/buildin/buidlin_test.go | 25 ++-
server/plugin/auth/buildin/buildin.go | 9 +-
server/resource/v4/auth_resource.go | 65 +++----
server/resource/v4/auth_resource_test.go | 15 +-
server/resource/v4/role_resource.go | 12 +-
server/resource/v4/role_resource_test.go | 98 +++++++----
server/service/rbac/account_dao.go | 179 +++++++++++++++++++
server/service/rbac/account_dao_test.go | 228 +++++++++++++++++++++++++
server/service/rbac/authr_plugin.go | 25 ++-
server/service/rbac/dao/account_dao.go | 109 ------------
server/service/rbac/dao/account_dao_test.go | 82 ---------
server/service/rbac/password.go | 7 +-
server/service/rbac/rbac.go | 27 ++-
server/service/rbac/rbac_test.go | 32 +---
server/service/rbac/role.go | 3 +-
server/service/rbac/{dao => }/role_dao.go | 2 +-
server/service/rbac/{dao => }/role_dao_test.go | 53 +++---
21 files changed, 614 insertions(+), 376 deletions(-)
diff --git a/datasource/etcd/account.go b/datasource/etcd/account.go
index bcf37e4..487adea 100644
--- a/datasource/etcd/account.go
+++ b/datasource/etcd/account.go
@@ -115,6 +115,9 @@ func (ds *DataSource) GetAccount(ctx context.Context, name string) (*rbac.Accoun
if err != nil {
return nil, err
}
+ if resp.Count == 0 {
+ return nil, datasource.ErrAccountNotExist
+ }
if resp.Count != 1 {
return nil, client.ErrNotUnique
}
diff --git a/datasource/mongo/account.go b/datasource/mongo/account.go
index effd9e6..0d297cc 100644
--- a/datasource/mongo/account.go
+++ b/datasource/mongo/account.go
@@ -20,6 +20,7 @@ package mongo
import (
"context"
"fmt"
+ "go.mongodb.org/mongo-driver/mongo"
"github.com/go-chassis/cari/rbac"
@@ -80,7 +81,10 @@ func (ds *DataSource) GetAccount(ctx context.Context, name string) (*rbac.Accoun
log.Error(msg, err)
return nil, err
}
- if result.Err() != nil {
+ if err = result.Err(); err != nil {
+ if err == mongo.ErrNoDocuments {
+ return nil, datasource.ErrAccountNotExist
+ }
msg := fmt.Sprintf("failed to query account, account name %s", name)
log.Error(msg, result.Err())
return nil, datasource.ErrQueryAccountFailed
diff --git a/pkg/rest/util.go b/pkg/rest/util.go
index d707b55..142ef12 100644
--- a/pkg/rest/util.go
+++ b/pkg/rest/util.go
@@ -22,6 +22,7 @@ import (
"encoding/json"
"errors"
"io/ioutil"
+ "github.com/go-chassis/cari/pkg/errsvc"
"net/http"
"github.com/apache/servicecomb-service-center/pkg/log"
@@ -33,6 +34,10 @@ var errNilRequestBody = errors.New("request body is nil")
func WriteError(w http.ResponseWriter, code int32, detail string) {
err := discovery.NewError(code, detail)
+ WriteErrsvcError(w, err)
+}
+
+func WriteErrsvcError(w http.ResponseWriter, err *errsvc.Error) {
w.Header().Set(HeaderContentType, ContentTypeJSON)
w.WriteHeader(err.StatusCode())
b, _ := json.Marshal(err)
diff --git a/server/handler/auth/auth.go b/server/handler/auth/auth.go
index 641124b..9e693e4 100644
--- a/server/handler/auth/auth.go
+++ b/server/handler/auth/auth.go
@@ -18,6 +18,7 @@
package auth
import (
+ "github.com/go-chassis/cari/pkg/errsvc"
"net/http"
"github.com/apache/servicecomb-service-center/pkg/chain"
@@ -45,6 +46,10 @@ func (h *Handler) Handle(i *chain.Invocation) {
if err := auth.Identify(r); err != nil {
log.Errorf(err, "authenticate request failed, %s %s", r.Method, r.RequestURI)
+ if e, ok := err.(*errsvc.Error); ok {
+ i.Fail(e)
+ return
+ }
i.Fail(discovery.NewError(rbac.ErrUnauthorized, err.Error()))
return
}
diff --git a/server/plugin/auth/buildin/buidlin_test.go b/server/plugin/auth/buildin/buidlin_test.go
index f337682..17b7354 100644
--- a/server/plugin/auth/buildin/buidlin_test.go
+++ b/server/plugin/auth/buildin/buidlin_test.go
@@ -22,7 +22,8 @@ import (
"context"
"github.com/apache/servicecomb-service-center/pkg/rest"
"github.com/apache/servicecomb-service-center/pkg/util"
- rbacmodel "github.com/go-chassis/cari/rbac"
+ "github.com/go-chassis/cari/pkg/errsvc"
+ "github.com/go-chassis/cari/rbac"
"io/ioutil"
"net/http"
"net/http/httptest"
@@ -30,8 +31,7 @@ import (
"github.com/apache/servicecomb-service-center/server/config"
"github.com/apache/servicecomb-service-center/server/plugin/auth/buildin"
- "github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
+ rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
_ "github.com/apache/servicecomb-service-center/test"
"github.com/astaxie/beego"
carirbac "github.com/go-chassis/cari/rbac"
@@ -51,8 +51,8 @@ func init() {
}
func TestTokenAuthenticator_Identify(t *testing.T) {
- dao.DeleteAccount(context.TODO(), "root")
- dao.DeleteAccount(context.TODO(), "non-admin")
+ rbacsvc.DeleteAccount(context.TODO(), "root")
+ rbacsvc.DeleteAccount(context.TODO(), "non-admin")
t.Run("init rbac", func(t *testing.T) {
err := archaius.Init(archaius.WithMemorySource(), archaius.WithENVSource())
assert.NoError(t, err)
@@ -67,9 +67,9 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
err = ioutil.WriteFile("./rbac.pub", b, 0600)
assert.NoError(t, err)
- archaius.Set(rbac.InitPassword, "Complicated_password1")
+ archaius.Set(rbacsvc.InitPassword, "Complicated_password1")
- rbac.Init()
+ rbacsvc.Init()
})
a := buildin.New()
ta := a.(*buildin.TokenAuthenticator)
@@ -77,8 +77,10 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
t.Run("without auth header should failed", func(t *testing.T) {
r := httptest.NewRequest(http.MethodGet, "/any", nil)
err := ta.Identify(r)
+ assert.NotNil(t, err)
t.Log(err)
- assert.Equal(t, carirbac.ErrNoHeader, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, carirbac.ErrNoAuthHeader, svcErr.Code)
})
t.Run("with wrong auth header should failed", func(t *testing.T) {
@@ -105,7 +107,12 @@ func TestTokenAuthenticator_Identify(t *testing.T) {
assert.NoError(t, err)
})
t.Run("valid normal token, should no be able to get account", func(t *testing.T) {
- err := dao.CreateAccount(context.TODO(), &rbacmodel.Account{Name: "non-admin", Password: "Complicated_password1"})
+ a := &rbac.Account{
+ Name: "non-admin",
+ Password: "Complicated_password1",
+ Roles: []string{rbac.RoleDeveloper},
+ }
+ err := rbacsvc.CreateAccount(context.TODO(), a)
assert.NoError(t, err)
r := httptest.NewRequest(http.MethodGet, "/v4/accounts", nil)
to, err := authr.Login(context.TODO(), "non-admin", "Complicated_password1")
diff --git a/server/plugin/auth/buildin/buildin.go b/server/plugin/auth/buildin/buildin.go
index 1b19d33..ff00102 100644
--- a/server/plugin/auth/buildin/buildin.go
+++ b/server/plugin/auth/buildin/buildin.go
@@ -22,7 +22,6 @@ import (
"net/http"
"strings"
- errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/plugin"
"github.com/apache/servicecomb-service-center/pkg/rest"
@@ -73,7 +72,7 @@ func (ba *TokenAuthenticator) Identify(req *http.Request) error {
}
account, err := rbac.GetAccount(m)
if err != nil {
- log.Error("get account failed", err)
+ log.Error("get account from token failed", err)
return err
}
util.SetRequestContext(req, rbacsvc.CtxRequestClaims, m)
@@ -84,7 +83,7 @@ func (ba *TokenAuthenticator) Identify(req *http.Request) error {
if len(account.Roles) == 0 {
log.Error("no role found in token", nil)
- return errors.New(errorsEx.MsgNoPerm)
+ return errors.New("no role found in token")
}
project := req.URL.Query().Get(":project")
@@ -93,7 +92,7 @@ func (ba *TokenAuthenticator) Identify(req *http.Request) error {
return err
}
if !allow {
- return errors.New(errorsEx.MsgNoPerm)
+ return rbac.NewError(rbac.ErrNoPermission, "")
}
util.SetRequestContext(req, authHandler.CtxResourceLabels, matchedLabels)
@@ -123,7 +122,7 @@ func filterRoles(roleList []string) (hasAdmin bool, normalRoles []string) {
func (ba *TokenAuthenticator) VerifyToken(req *http.Request) (interface{}, error) {
v := req.Header.Get(restful.HeaderAuth)
if v == "" {
- return nil, rbac.ErrNoHeader
+ return nil, rbac.NewError(rbac.ErrNoAuthHeader, "")
}
s := strings.Split(v, " ")
if len(s) != 2 {
diff --git a/server/resource/v4/auth_resource.go b/server/resource/v4/auth_resource.go
index 26c4372..1c92440 100644
--- a/server/resource/v4/auth_resource.go
+++ b/server/resource/v4/auth_resource.go
@@ -20,16 +20,15 @@ package v4
import (
"encoding/json"
"fmt"
+ "github.com/go-chassis/cari/pkg/errsvc"
"io/ioutil"
"net/http"
- "github.com/apache/servicecomb-service-center/datasource"
errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rest"
"github.com/apache/servicecomb-service-center/pkg/util"
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
"github.com/apache/servicecomb-service-center/server/service/validator"
"github.com/go-chassis/cari/discovery"
@@ -63,27 +62,13 @@ func (ar *AuthResource) CreateAccount(w http.ResponseWriter, req *http.Request)
a := &rbac.Account{}
if err = json.Unmarshal(body, a); err != nil {
log.Error("json err", err)
- rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgJSON)
- return
- }
- err = validator.ValidateCreateAccount(a)
- if err != nil {
- rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
- return
- }
- err = a.Check()
- if err != nil {
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
- err = dao.CreateAccount(req.Context(), a)
+ err = rbacsvc.CreateAccount(req.Context(), a)
if err != nil {
- if err == datasource.ErrAccountDuplicated {
- rest.WriteError(w, rbac.ErrAccountConflict, "")
- return
- }
log.Error(errorsEx.MsgOperateAccountFailed, err)
- rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgOperateAccountFailed)
+ writeErrsvcOrInternalErr(w, err)
return
}
rest.WriteSuccess(w, req)
@@ -91,13 +76,10 @@ func (ar *AuthResource) CreateAccount(w http.ResponseWriter, req *http.Request)
func (ar *AuthResource) DeleteAccount(w http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get(":name")
- if ar.illegalCheck(w, req, name) {
- return
- }
- _, err := dao.DeleteAccount(req.Context(), name)
+ err := rbacsvc.DeleteAccount(req.Context(), name)
if err != nil {
log.Error(errorsEx.MsgOperateAccountFailed, err)
- rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgOperateAccountFailed)
+ writeErrsvcOrInternalErr(w, err)
return
}
rest.WriteSuccess(w, req)
@@ -105,9 +87,6 @@ func (ar *AuthResource) DeleteAccount(w http.ResponseWriter, req *http.Request)
func (ar *AuthResource) UpdateAccount(w http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get(":name")
- if ar.illegalCheck(w, req, name) {
- return
- }
body, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Error("read body err", err)
@@ -121,17 +100,17 @@ func (ar *AuthResource) UpdateAccount(w http.ResponseWriter, req *http.Request)
return
}
- err = dao.UpdateAccount(req.Context(), name, a)
+ err = rbacsvc.UpdateAccount(req.Context(), name, a)
if err != nil {
log.Error(errorsEx.MsgOperateAccountFailed, err)
- rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgOperateAccountFailed)
+ writeErrsvcOrInternalErr(w, err)
return
}
rest.WriteSuccess(w, req)
}
func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
- as, n, err := dao.ListAccount(r.Context())
+ as, n, err := rbacsvc.ListAccount(r.Context())
if err != nil {
log.Error(errorsEx.MsgGetAccountFailed, err)
rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
@@ -145,29 +124,16 @@ func (ar *AuthResource) ListAccount(w http.ResponseWriter, r *http.Request) {
}
func (ar *AuthResource) GetAccount(w http.ResponseWriter, r *http.Request) {
- a, err := dao.GetAccount(r.Context(), r.URL.Query().Get(":name"))
+ a, err := rbacsvc.GetAccount(r.Context(), r.URL.Query().Get(":name"))
if err != nil {
log.Error(errorsEx.MsgGetAccountFailed, err)
- rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetAccountFailed)
+ writeErrsvcOrInternalErr(w, err)
return
}
a.Password = ""
rest.WriteResponse(w, r, nil, a)
}
-func (ar *AuthResource) illegalCheck(w http.ResponseWriter, req *http.Request, name string) bool {
- if name == rbacsvc.RootName {
- rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateRoot)
- return true
- }
- user := rbacsvc.UserFromContext(req.Context())
- if name == user {
- rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgCantOperateYour)
- return true
- }
- return false
-}
-
func (ar *AuthResource) ChangePassword(w http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get(":name")
ip := util.GetRealIP(req)
@@ -253,7 +219,7 @@ func (ar *AuthResource) Login(w http.ResponseWriter, r *http.Request) {
if err == rbacsvc.ErrUnauthorized {
log.Error("not authorized", err)
rbacsvc.CountFailure(MakeBanKey(a.Name, ip))
- rest.WriteError(w, rbac.ErrUnauthorized, err.Error())
+ rest.WriteError(w, rbac.ErrUserOrPwdWrong, err.Error())
return
}
log.Error("can not sign token", err)
@@ -266,3 +232,12 @@ func (ar *AuthResource) Login(w http.ResponseWriter, r *http.Request) {
func MakeBanKey(name, ip string) string {
return name + "::" + ip
}
+
+func writeErrsvcOrInternalErr(w http.ResponseWriter, err error) {
+ e, ok := err.(*errsvc.Error)
+ if ok {
+ rest.WriteErrsvcError(w, e)
+ return
+ }
+ rest.WriteError(w, discovery.ErrInternal, err.Error())
+}
diff --git a/server/resource/v4/auth_resource_test.go b/server/resource/v4/auth_resource_test.go
index 6e0e233..38c1d7f 100644
--- a/server/resource/v4/auth_resource_test.go
+++ b/server/resource/v4/auth_resource_test.go
@@ -32,8 +32,7 @@ import (
"github.com/apache/servicecomb-service-center/pkg/rest"
"github.com/apache/servicecomb-service-center/server/config"
v4 "github.com/apache/servicecomb-service-center/server/resource/v4"
- "github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
+ rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
_ "github.com/apache/servicecomb-service-center/test"
"github.com/astaxie/beego"
"github.com/go-chassis/go-archaius"
@@ -71,18 +70,18 @@ func init() {
panic(err)
}
- archaius.Set(rbac.InitPassword, pwd)
+ archaius.Set(rbacsvc.InitPassword, pwd)
ctx := context.TODO()
- dao.DeleteAccount(ctx, "root")
+ rbacsvc.DeleteAccount(ctx, "root")
- rbac.Init()
+ rbacsvc.Init()
rest.RegisterServant(&v4.AuthResource{})
rest.RegisterServant(&v4.RoleResource{})
}
func TestAuthResource_Login(t *testing.T) {
ctx := context.TODO()
- dao.DeleteAccount(ctx, "dev_account")
+ rbacsvc.DeleteAccount(ctx, "dev_account")
t.Run("invalid user login", func(t *testing.T) {
b, _ := json.Marshal(&rbacmodel.Account{Name: "dev_account", Password: pwd})
@@ -190,7 +189,7 @@ func TestAuthResource_DeleteAccount(t *testing.T) {
r2.Header.Set(restful.HeaderAuth, "Bearer "+rootToken.TokenStr)
w2 := httptest.NewRecorder()
rest.GetRouter().ServeHTTP(w2, r2)
- assert.Equal(t, http.StatusBadRequest, w2.Code)
+ assert.Equal(t, http.StatusForbidden, w2.Code)
})
t.Run("dev_account can not even delete him self", func(t *testing.T) {
b, _ := json.Marshal(&rbacmodel.Account{Name: "dev_account", Password: "Complicated_password2", Roles: []string{"developer"}})
@@ -232,7 +231,7 @@ func TestAuthResource_DeleteAccount(t *testing.T) {
r2.Header.Set(restful.HeaderAuth, "Bearer "+yourToken.TokenStr)
w2 := httptest.NewRecorder()
rest.GetRouter().ServeHTTP(w2, r2)
- assert.Equal(t, http.StatusBadRequest, w2.Code)
+ assert.Equal(t, http.StatusForbidden, w2.Code)
r3, _ := http.NewRequest(http.MethodDelete, "/v4/accounts/your_account", nil)
r3.Header.Set(restful.HeaderAuth, "Bearer "+rootToken.TokenStr)
diff --git a/server/resource/v4/role_resource.go b/server/resource/v4/role_resource.go
index 17e363b..a2debe8 100644
--- a/server/resource/v4/role_resource.go
+++ b/server/resource/v4/role_resource.go
@@ -21,13 +21,13 @@ import (
"encoding/json"
"errors"
"github.com/apache/servicecomb-service-center/datasource"
+ rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
"io/ioutil"
"net/http"
errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rest"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
"github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/rbac"
@@ -51,7 +51,7 @@ func (rr *RoleResource) URLPatterns() []rest.Route {
//ListRoles list all roles and there's permissions
func (rr *RoleResource) ListRoles(w http.ResponseWriter, req *http.Request) {
- rs, num, err := dao.ListRole(req.Context())
+ rs, num, err := rbacsvc.ListRole(req.Context())
if err != nil {
log.Error(errorsEx.MsgGetRoleFailed, err)
rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetRoleFailed)
@@ -90,7 +90,7 @@ func (rr *RoleResource) CreateRole(w http.ResponseWriter, req *http.Request) {
return
}
- status, err := dao.CreateRole(req.Context(), role)
+ status, err := rbacsvc.CreateRole(req.Context(), role)
if err != nil {
log.Error(errorsEx.MsgOperateRoleFailed, err)
rest.WriteError(w, discovery.ErrInternal, err.Error())
@@ -113,7 +113,7 @@ func (rr *RoleResource) UpdateRole(w http.ResponseWriter, req *http.Request) {
rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgJSON)
return
}
- status, err := dao.EditRole(req.Context(), name, role)
+ status, err := rbacsvc.EditRole(req.Context(), name, role)
if err != nil {
log.Error(errorsEx.MsgOperateRoleFailed, err)
rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgOperateRoleFailed)
@@ -125,7 +125,7 @@ func (rr *RoleResource) UpdateRole(w http.ResponseWriter, req *http.Request) {
//GetRole get the role info according to role name
func (rr *RoleResource) GetRole(w http.ResponseWriter, r *http.Request) {
- resp, status, err := dao.GetRole(r.Context(), r.URL.Query().Get(":roleName"))
+ resp, status, err := rbacsvc.GetRole(r.Context(), r.URL.Query().Get(":roleName"))
if err != nil {
log.Error(errorsEx.MsgGetRoleFailed, err)
rest.WriteError(w, discovery.ErrInternal, errorsEx.MsgGetRoleFailed)
@@ -139,7 +139,7 @@ func (rr *RoleResource) GetRole(w http.ResponseWriter, r *http.Request) {
func (rr *RoleResource) DeleteRole(w http.ResponseWriter, req *http.Request) {
n := req.URL.Query().Get(":roleName")
- status, err := dao.DeleteRole(req.Context(), n)
+ status, err := rbacsvc.DeleteRole(req.Context(), n)
if errors.Is(err, datasource.ErrRoleBindingExist) {
rest.WriteError(w, discovery.ErrInvalidParams, errorsEx.MsgJSON)
return
diff --git a/server/resource/v4/role_resource_test.go b/server/resource/v4/role_resource_test.go
index 4598496..6ac0e36 100644
--- a/server/resource/v4/role_resource_test.go
+++ b/server/resource/v4/role_resource_test.go
@@ -1,14 +1,15 @@
package v4_test
import (
+ rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
_ "github.com/apache/servicecomb-service-center/test"
+ "github.com/go-chassis/cari/rbac"
"strings"
"bytes"
"context"
"encoding/json"
"github.com/apache/servicecomb-service-center/pkg/rest"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
rbacmodel "github.com/go-chassis/cari/rbac"
"github.com/go-chassis/go-chassis/v2/server/restful"
"github.com/stretchr/testify/assert"
@@ -17,12 +18,46 @@ import (
"testing"
)
+func newRole(name string) *rbac.Role {
+ return &rbac.Role{
+ Name: name,
+ Perms: []*rbac.Permission{
+ {
+ Resources: []*rbac.Resource{
+ {
+ Type: rbacsvc.ResourceService,
+ },
+ },
+ Verbs: []string{"*"},
+ },
+ },
+ }
+}
+
+const (
+ testPwd0 = "Ab@00000"
+ testPwd1 = "Ab@11111"
+)
+
+func newAccount(name string) *rbac.Account {
+ return &rbac.Account{
+ Name: name,
+ Password: testPwd0,
+ Roles: []string{rbac.RoleAdmin},
+ Status: "active",
+ }
+}
+
func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
var superToken = &rbacmodel.Token{}
ctx := context.TODO()
- dao.DeleteAccount(ctx, "dev_test")
- dao.DeleteAccount(ctx, "dev_test2")
- dao.DeleteRole(ctx, "tester")
+ rbacsvc.DeleteAccount(ctx, "dev_test")
+ rbacsvc.DeleteAccount(ctx, "dev_test2")
+ rbacsvc.DeleteRole(ctx, "tester")
+ devAccount := newAccount("dev_test")
+ testRole := newRole("tester")
+ rbacsvc.DeleteAccount(ctx, devAccount.Name)
+ rbacsvc.DeleteRole(ctx, testRole.Name)
t.Run("root login,to get super token", func(t *testing.T) {
b, _ := json.Marshal(&rbacmodel.Account{Name: "root", Password: "Complicated_password1"})
@@ -34,18 +69,8 @@ func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
json.Unmarshal(w.Body.Bytes(), superToken)
})
- t.Run("create account dev_test and add a role", func(t *testing.T) {
- b, _ := json.Marshal(&rbacmodel.Account{Name: "dev_test", Password: "Complicated_password3", Roles: []string{"tester"}})
-
- r, _ := http.NewRequest(http.MethodPost, "/v4/accounts", bytes.NewBuffer(b))
- r.Header.Set(restful.HeaderAuth, "Bearer "+superToken.TokenStr)
- w := httptest.NewRecorder()
- rest.GetRouter().ServeHTTP(w, r)
- assert.Equal(t, http.StatusOK, w.Code)
- })
-
t.Run("create a role name tester ", func(t *testing.T) {
- b, _ := json.Marshal(&rbacmodel.Account{Name: "dev_test", Password: "Complicated_password3", Roles: []string{"tester"}})
+ b, _ := json.Marshal(&rbacmodel.Account{Name: rbacsvc.RootName, Password: "Complicated_password1"})
r, _ := http.NewRequest(http.MethodPost, "/v4/token", bytes.NewBuffer(b))
w := httptest.NewRecorder()
@@ -54,15 +79,7 @@ func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
devToken := &rbacmodel.Token{}
json.Unmarshal(w.Body.Bytes(), devToken)
- b2, _ := json.Marshal(&rbacmodel.Role{
- Name: "tester",
- Perms: []*rbacmodel.Permission{
- {
- Resources: []*rbacmodel.Resource{{Type: "service"}, {Type: "instance"}},
- Verbs: []string{"get", "create", "update"},
- },
- },
- })
+ b2, _ := json.Marshal(testRole)
r2, _ := http.NewRequest(http.MethodPost, "/v4/roles", bytes.NewReader(b2))
r2.Header.Set(restful.HeaderAuth, "Bearer "+superToken.TokenStr)
@@ -76,21 +93,30 @@ func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
rest.GetRouter().ServeHTTP(w3, r3)
assert.Equal(t, http.StatusOK, w3.Code)
- b4, _ := json.Marshal(&rbacmodel.Role{
- Name: "tester",
- Perms: []*rbacmodel.Permission{
- {
- Resources: []*rbacmodel.Resource{{Type: "service"}},
- Verbs: []string{"get", "create", "update"},
- },
+ newTestRole := newRole(testRole.Name)
+ newTestRole.Perms = []*rbac.Permission{
+ {
+ Resources: []*rbacmodel.Resource{{Type: rbacsvc.ResourceAccount}},
+ Verbs: []string{"*"},
},
- })
+ }
+ b4, _ := json.Marshal(newTestRole)
r4, _ := http.NewRequest(http.MethodPut, "/v4/roles/tester", bytes.NewReader(b4))
r4.Header.Set(restful.HeaderAuth, "Bearer "+superToken.TokenStr)
w4 := httptest.NewRecorder()
rest.GetRouter().ServeHTTP(w4, r4)
assert.Equal(t, http.StatusOK, w4.Code)
})
+ t.Run("create account dev_test and add a role", func(t *testing.T) {
+ devAccount.Roles = []string{testRole.Name}
+ b, _ := json.Marshal(devAccount)
+
+ r, _ := http.NewRequest(http.MethodPost, "/v4/accounts", bytes.NewBuffer(b))
+ r.Header.Set(restful.HeaderAuth, "Bearer "+superToken.TokenStr)
+ w := httptest.NewRecorder()
+ rest.GetRouter().ServeHTTP(w, r)
+ assert.Equal(t, http.StatusOK, w.Code)
+ })
t.Run("get role", func(t *testing.T) {
b, _ := json.Marshal(&rbacmodel.Account{Name: "root", Password: "Complicated_password1"})
@@ -150,10 +176,10 @@ func TestRoleResource_CreateOrUpdateRole(t *testing.T) {
func TestRoleResource_MoreRoles(t *testing.T) {
var to = &rbacmodel.Token{}
ctx := context.TODO()
- dao.DeleteAccount(ctx, "dev_test")
- dao.DeleteAccount(ctx, "dev_test2")
- dao.DeleteRole(ctx, "tester")
- dao.DeleteRole(ctx, "tester2")
+ rbacsvc.DeleteAccount(ctx, "dev_test")
+ rbacsvc.DeleteAccount(ctx, "dev_test2")
+ rbacsvc.DeleteRole(ctx, "tester")
+ rbacsvc.DeleteRole(ctx, "tester2")
t.Run("root login", func(t *testing.T) {
b, _ := json.Marshal(&rbacmodel.Account{Name: "root", Password: "Complicated_password1"})
diff --git a/server/service/rbac/account_dao.go b/server/service/rbac/account_dao.go
new file mode 100644
index 0000000..73ae9d1
--- /dev/null
+++ b/server/service/rbac/account_dao.go
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//Package rbac is dao layer API to help service center manage account, policy and role info
+package rbac
+
+import (
+ "context"
+ "fmt"
+ "github.com/apache/servicecomb-service-center/datasource"
+ errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+ "github.com/apache/servicecomb-service-center/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ "github.com/apache/servicecomb-service-center/server/service/validator"
+ "github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/rbac"
+)
+
+//CreateAccount save 2 kv
+//1. account info
+func CreateAccount(ctx context.Context, a *rbac.Account) error {
+ quotaCheckErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
+ util.ParseDomainProject(ctx), "", 1))
+ if quotaCheckErr != nil {
+ return quotaCheckErr
+ }
+ err := validator.ValidateCreateAccount(a)
+ if err != nil {
+ log.Errorf(err, "create account [%s] failed", a.Name)
+ return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+ }
+ err = a.Check()
+ if err != nil {
+ log.Errorf(err, "create account [%s] failed", a.Name)
+ return rbac.NewError(discovery.ErrInvalidParams, err.Error())
+ }
+ if err = checkRoleNames(ctx, a.Roles); err != nil {
+ return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+ }
+
+ err = datasource.Instance().CreateAccount(ctx, a)
+ if err == nil {
+ log.Infof("create account [%s] success", a.Name)
+ return nil
+ }
+ log.Errorf(err, "create account [%s] failed", a.Name)
+ if err == datasource.ErrAccountDuplicated {
+ return rbac.NewError(rbac.ErrAccountConflict, err.Error())
+ }
+ return err
+}
+
+// UpdateAccount updates an account's info, except the password
+func UpdateAccount(ctx context.Context, name string, a *rbac.Account) error {
+ // todo params validation
+ if err := illegalCheck(ctx, name); err != nil {
+ return err
+ }
+ if len(a.Status) == 0 && len(a.Roles) == 0 {
+ return rbac.NewError(discovery.ErrInvalidParams, "status and roles cannot be empty both")
+ }
+
+ oldAccount, err := GetAccount(ctx, name)
+ if err != nil {
+ log.Errorf(err, "get account [%s] failed", name)
+ return err
+ }
+ if len(a.Status) != 0 {
+ oldAccount.Status = a.Status
+ }
+ if len(a.Roles) != 0 {
+ oldAccount.Roles = a.Roles
+ }
+ if err = checkRoleNames(ctx, oldAccount.Roles); err != nil {
+ return rbac.NewError(rbac.ErrAccountHasInvalidRole, err.Error())
+ }
+ err = datasource.Instance().UpdateAccount(ctx, name, oldAccount)
+ if err != nil {
+ log.Errorf(err, "can not edit account info")
+ return err
+ }
+ log.Infof("account [%s] is edit", oldAccount.ID)
+ return nil
+}
+
+func GetAccount(ctx context.Context, name string) (*rbac.Account, error) {
+ r, err := datasource.Instance().GetAccount(ctx, name)
+ if err != nil {
+ if err == datasource.ErrAccountNotExist {
+ msg := fmt.Sprintf("account [%s] not exist", name)
+ return nil, rbac.NewError(rbac.ErrAccountNotExist, msg)
+ }
+ return nil, err
+ }
+ return r, nil
+}
+func ListAccount(ctx context.Context) ([]*rbac.Account, int64, error) {
+ return datasource.Instance().ListAccount(ctx)
+}
+func AccountExist(ctx context.Context, name string) (bool, error) {
+ return datasource.Instance().AccountExist(ctx, name)
+}
+func DeleteAccount(ctx context.Context, name string) error {
+ if err := illegalCheck(ctx, name); err != nil {
+ return err
+ }
+ exist, err := datasource.Instance().AccountExist(ctx, name)
+ if err != nil {
+ log.Errorf(err, "check account [%s] exit failed", name)
+ return err
+ }
+ if !exist {
+ msg := fmt.Sprintf("account [%s] not exist", name)
+ return rbac.NewError(rbac.ErrAccountNotExist, msg)
+ }
+ _, err = datasource.Instance().DeleteAccount(ctx, []string{name})
+ return err
+}
+
+//CreateAccount save 2 kv
+//1. account info
+func EditAccount(ctx context.Context, a *rbac.Account) error {
+ exist, err := datasource.Instance().AccountExist(ctx, a.Name)
+ if err != nil {
+ log.Errorf(err, "can not edit account info")
+ return err
+ }
+ if !exist {
+ return rbac.NewError(rbac.ErrAccountNotExist, "")
+ }
+
+ err = datasource.Instance().UpdateAccount(ctx, a.Name, a)
+ if err != nil {
+ log.Errorf(err, "can not edit account info")
+ return err
+ }
+ log.Infof("account [%s] is edit", a.ID)
+ return nil
+}
+
+func checkRoleNames(ctx context.Context, roles []string) error {
+ for _, name := range roles {
+ exist, err := RoleExist(ctx, name)
+ if err != nil {
+ log.Errorf(err, "check role [%s] exist failed", name)
+ return err
+ }
+ if !exist {
+ return datasource.ErrRoleNotExist
+ }
+ }
+ return nil
+}
+
+func illegalCheck(ctx context.Context, target string) error {
+ if target == RootName {
+ return discovery.NewError(discovery.ErrForbidden, errorsEx.MsgCantOperateRoot)
+ }
+ changer := UserFromContext(ctx)
+ if target == changer {
+ return discovery.NewError(discovery.ErrForbidden, errorsEx.MsgCantOperateYour)
+ }
+ return nil
+}
diff --git a/server/service/rbac/account_dao_test.go b/server/service/rbac/account_dao_test.go
new file mode 100644
index 0000000..546c307
--- /dev/null
+++ b/server/service/rbac/account_dao_test.go
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package rbac_test
+
+// initialize
+import (
+ "context"
+ rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
+ "github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/pkg/errsvc"
+ "testing"
+
+ _ "github.com/apache/servicecomb-service-center/test"
+
+ "github.com/astaxie/beego"
+ "github.com/go-chassis/cari/rbac"
+ "github.com/stretchr/testify/assert"
+)
+
+func init() {
+ beego.AppConfig.Set("registry_plugin", "etcd")
+}
+
+const (
+ testPwd0 = "Ab@00000"
+ testPwd1 = "Ab@11111"
+)
+
+func newAccount(name string) *rbac.Account {
+ return &rbac.Account{
+ Name: name,
+ Password: testPwd0,
+ Roles: []string{rbac.RoleAdmin},
+ Status: "active",
+ }
+}
+
+func TestCreateAccount(t *testing.T) {
+ t.Run("create account, should succeed", func(t *testing.T) {
+ a := newAccount("TestCreateAccount_create_account")
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+ })
+ t.Run("create account twice, should return: "+rbac.NewError(rbac.ErrAccountConflict, "").Error(), func(t *testing.T) {
+ name := "TestCreateAccount_create_account_twice"
+ a := newAccount(name)
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ a = newAccount(name)
+ err = rbacsvc.CreateAccount(context.TODO(), a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountConflict, svcErr.Code)
+ })
+ t.Run("account has invalid role, should return: "+rbac.NewError(rbac.ErrAccountHasInvalidRole, "").Error(), func(t *testing.T) {
+ a := newAccount("TestCreateAccount_account_has_invalid_role")
+ a.Roles = append(a.Roles, "invalid_role")
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountHasInvalidRole, svcErr.Code)
+ })
+}
+
+func TestDeleteAccount(t *testing.T) {
+ t.Run("delete account, should succeed", func(t *testing.T) {
+ a := newAccount("TestDeleteAccount_delete_account")
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ exist, err := rbacsvc.AccountExist(context.TODO(), a.Name)
+ assert.Nil(t, err)
+ assert.True(t, exist)
+ err = rbacsvc.DeleteAccount(context.TODO(), a.Name)
+ assert.Nil(t, err)
+ exist, err = rbacsvc.AccountExist(context.TODO(), a.Name)
+ assert.Nil(t, err)
+ assert.False(t, exist)
+ })
+ t.Run("delete no exist account, should return: "+rbac.NewError(rbac.ErrAccountNotExist, "").Error(), func(t *testing.T) {
+ err := rbacsvc.DeleteAccount(context.TODO(), "TestDeleteAccount_delete_no_exist_account")
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountNotExist, svcErr.Code)
+ })
+ t.Run("delete root, should return: "+rbac.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
+ err := rbacsvc.DeleteAccount(context.TODO(), "root")
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, discovery.ErrForbidden, svcErr.Code)
+ })
+ t.Run("delete self, should return: "+rbac.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
+ a := newAccount("TestDeleteAccount_delete_self")
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+ claims := map[string]interface{}{
+ rbac.ClaimsUser: a.Name,
+ }
+ ctx := context.WithValue(context.TODO(), rbacsvc.CtxRequestClaims, claims)
+ err = rbacsvc.DeleteAccount(ctx, a.Name)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, discovery.ErrForbidden, svcErr.Code)
+ })
+}
+
+func TestUpdateAccount(t *testing.T) {
+ t.Run("update account, should succeed", func(t *testing.T) {
+ name := "TestUpdateAccount_update_account"
+ a := newAccount(name)
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ a = newAccount(name)
+ a.Roles = []string{rbac.RoleAdmin, rbac.RoleDeveloper}
+ err = rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.Nil(t, err)
+ resp, err := rbacsvc.GetAccount(context.TODO(), a.Name)
+ assert.Nil(t, err)
+ assert.Equal(t, 2, len(resp.Roles))
+ })
+ t.Run("update no exist account, should return: "+rbac.NewError(rbac.ErrAccountNotExist, "").Error(), func(t *testing.T) {
+ name := "TestUpdateAccount_update_no_exist_account"
+ a := newAccount(name)
+ err := rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountNotExist, svcErr.Code)
+ })
+ t.Run("update root, should return: "+discovery.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
+ a := newAccount("root")
+ err := rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, discovery.ErrForbidden, svcErr.Code)
+ })
+ t.Run("account has invalid role, should return: "+rbac.NewError(rbac.ErrAccountHasInvalidRole, "").Error(), func(t *testing.T) {
+ name := "TestUpdateAccount_account_has_invalid_role"
+ a := newAccount(name)
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ a.Roles = append(a.Roles, "invalid_role")
+ err = rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountHasInvalidRole, svcErr.Code)
+ })
+ t.Run("roles status empty both, should return: "+discovery.NewError(discovery.ErrInvalidParams, "").Error(), func(t *testing.T) {
+ name := "TestUpdateAccount_roles_status_empty_both"
+ a := newAccount(name)
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ a = newAccount(name)
+ a.Roles = nil
+ a.Status = ""
+ err = rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, discovery.ErrInvalidParams, svcErr.Code)
+ })
+ t.Run("update self, should return: "+rbac.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
+ name := "TestDeleteAccount_update_self"
+ a := newAccount(name)
+ err := rbacsvc.CreateAccount(context.TODO(), a)
+ assert.Nil(t, err)
+
+ a = newAccount(name)
+ claims := map[string]interface{}{
+ rbac.ClaimsUser: a.Name,
+ }
+ ctx := context.WithValue(context.TODO(), rbacsvc.CtxRequestClaims, claims)
+ err = rbacsvc.UpdateAccount(ctx, a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, discovery.ErrForbidden, svcErr.Code)
+ })
+}
+
+func TestEditAccount(t *testing.T) {
+ t.Run("edit no exist account, should return: "+rbac.NewError(rbac.ErrAccountNotExist, "").Error(), func(t *testing.T) {
+ a := newAccount("TestEditAccount_edit_no_exist_account")
+ err := rbacsvc.UpdateAccount(context.TODO(), a.Name, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountNotExist, svcErr.Code)
+ })
+}
+
+func TestGetAccount(t *testing.T) {
+ t.Run("get account, should succeed", func(t *testing.T) {
+ a, err := rbacsvc.GetAccount(context.TODO(), "root")
+ assert.Nil(t, err)
+ assert.Equal(t, "root", a.Name)
+ })
+ t.Run("get no exist account, should return: "+rbac.NewError(rbac.ErrAccountNotExist, "").Error(), func(t *testing.T) {
+ a, err := rbacsvc.GetAccount(context.TODO(), "TestGetAccount_no_exist_account")
+ assert.Nil(t, a)
+ assert.NotNil(t, err)
+ svcErr := err.(*errsvc.Error)
+ assert.Equal(t, rbac.ErrAccountNotExist, svcErr.Code)
+ })
+}
+func TestListAccount(t *testing.T) {
+ t.Run("list account, should succeed", func(t *testing.T) {
+ accounts, n, err := rbacsvc.ListAccount(context.TODO())
+ assert.Nil(t, err)
+ assert.True(t, n > 0)
+ assert.Equal(t, n, int64(len(accounts)))
+ })
+}
diff --git a/server/service/rbac/authr_plugin.go b/server/service/rbac/authr_plugin.go
index 00008bc..b6a4615 100644
--- a/server/service/rbac/authr_plugin.go
+++ b/server/service/rbac/authr_plugin.go
@@ -21,6 +21,7 @@ import (
"context"
"crypto/rsa"
"errors"
+ "fmt"
"github.com/apache/servicecomb-service-center/datasource"
"github.com/go-chassis/cari/rbac"
@@ -30,7 +31,6 @@ import (
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/privacy"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
)
var ErrUnauthorized = errors.New("wrong user name or password")
@@ -49,11 +49,12 @@ func (a *EmbeddedAuthenticator) Login(ctx context.Context, user string, password
for _, o := range opts {
o(opt)
}
- account, err := dao.GetAccount(ctx, user)
+ account, err := GetAccount(ctx, user)
if err != nil {
log.Error("get account err", err)
return "", err
}
+
same := privacy.SamePassword(account.Password, password)
if user == account.Name && same {
secret, err := GetPrivateKey()
@@ -85,6 +86,9 @@ func (a *EmbeddedAuthenticator) Authenticate(ctx context.Context, tokenStr strin
}
claims, err := a.authToken(tokenStr, p)
if err != nil {
+ if a.isTokenExpiredError(err) {
+ return nil, rbac.NewError(rbac.ErrTokenExpired, "")
+ }
return nil, err
}
accountNameI := claims[rbac.ClaimsUser]
@@ -97,11 +101,26 @@ func (a *EmbeddedAuthenticator) Authenticate(ctx context.Context, tokenStr strin
return nil, err
}
if !exist {
- return nil, datasource.ErrAccountNotExist
+ msg := fmt.Sprintf("account [%s] is deleted", n)
+ return nil, rbac.NewError(rbac.ErrTokenOwnedAccountDeleted, msg)
}
return claims, nil
}
+func (a *EmbeddedAuthenticator) isTokenExpiredError(err error) bool {
+ if err == nil {
+ return false
+ }
+ vErr, ok := err.(*jwt.ValidationError)
+ if !ok {
+ return false
+ }
+ if vErr.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
+ return true
+ }
+ return false
+}
+
func (a *EmbeddedAuthenticator) authToken(tokenStr string, pub *rsa.PublicKey) (map[string]interface{}, error) {
return token.Verify(tokenStr, func(claims interface{}, method token.SigningMethod) (interface{}, error) {
return pub, nil
diff --git a/server/service/rbac/dao/account_dao.go b/server/service/rbac/dao/account_dao.go
deleted file mode 100644
index fe7279b..0000000
--- a/server/service/rbac/dao/account_dao.go
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//Package rbac is dao layer API to help service center manage account, policy and role info
-package dao
-
-import (
- "context"
- "errors"
- "github.com/apache/servicecomb-service-center/datasource"
- "github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
-
- rbacmodel "github.com/go-chassis/cari/rbac"
-)
-
-//CreateAccount save 2 kv
-//1. account info
-func CreateAccount(ctx context.Context, a *rbacmodel.Account) error {
- err := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
- util.ParseDomainProject(ctx), "", 1))
- if err != nil {
- return err
- }
- return datasource.Instance().CreateAccount(ctx, a)
-}
-
-// UpdateAccount updates an account's info, except the password
-func UpdateAccount(ctx context.Context, name string, a *rbacmodel.Account) error {
- // todo params validation
- if len(a.Status) == 0 && len(a.Roles) == 0 {
- return errors.New("status and roles cannot be empty both")
- }
- exist, err := datasource.Instance().AccountExist(ctx, name)
- if err != nil {
- log.Errorf(err, "check account [%s] exit failed", name)
- return err
- }
- if !exist {
- return datasource.ErrAccountNotExist
- }
- oldAccount, err := GetAccount(ctx, name)
- if err != nil {
- log.Errorf(err, "get account [%s] failed", name)
- return err
- }
- if len(a.Status) != 0 {
- oldAccount.Status = a.Status
- }
- if len(a.Roles) != 0 {
- oldAccount.Roles = a.Roles
- }
- err = datasource.Instance().UpdateAccount(ctx, name, oldAccount)
- if err != nil {
- log.Errorf(err, "can not edit account info")
- return err
- }
- log.Infof("account [%s] is edit", oldAccount.ID)
- return nil
-}
-
-func GetAccount(ctx context.Context, name string) (*rbacmodel.Account, error) {
- return datasource.Instance().GetAccount(ctx, name)
-}
-func ListAccount(ctx context.Context) ([]*rbacmodel.Account, int64, error) {
- return datasource.Instance().ListAccount(ctx)
-}
-func AccountExist(ctx context.Context, name string) (bool, error) {
- return datasource.Instance().AccountExist(ctx, name)
-}
-func DeleteAccount(ctx context.Context, name string) (bool, error) {
- return datasource.Instance().DeleteAccount(ctx, []string{name})
-}
-
-//CreateAccount save 2 kv
-//1. account info
-func EditAccount(ctx context.Context, a *rbacmodel.Account) error {
- exist, err := datasource.Instance().AccountExist(ctx, a.Name)
- if err != nil {
- log.Errorf(err, "can not edit account info")
- return err
- }
- if !exist {
- return datasource.ErrAccountCanNotEdit
- }
-
- err = datasource.Instance().UpdateAccount(ctx, a.Name, a)
- if err != nil {
- log.Errorf(err, "can not edit account info")
- return err
- }
- log.Infof("account [%s] is edit", a.ID)
- return nil
-}
diff --git a/server/service/rbac/dao/account_dao_test.go b/server/service/rbac/dao/account_dao_test.go
deleted file mode 100644
index 79a48a3..0000000
--- a/server/service/rbac/dao/account_dao_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package dao_test
-
-// initialize
-import (
- "context"
- "testing"
-
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
- _ "github.com/apache/servicecomb-service-center/test"
-
- "github.com/astaxie/beego"
- "github.com/go-chassis/cari/rbac"
- "github.com/stretchr/testify/assert"
- "golang.org/x/crypto/bcrypt"
-)
-
-func init() {
- beego.AppConfig.Set("registry_plugin", "etcd")
-}
-
-func newAccount(name string) *rbac.Account {
- return &rbac.Account{
- Name: name,
- Password: "Ab@11111",
- Roles: []string{rbac.RoleAdmin},
- }
-}
-
-func TestAccountDao_CreateAccount(t *testing.T) {
- account := newAccount("createAccountTest")
- dao.DeleteAccount(context.TODO(), account.Name)
- _ = dao.CreateAccount(context.Background(), account)
- t.Run("get account", func(t *testing.T) {
- r, err := dao.GetAccount(context.Background(), account.Name)
- assert.NoError(t, err)
- assert.Equal(t, account.Name, r.Name)
- hash, err := bcrypt.GenerateFromPassword([]byte(account.Password), 14)
- err = bcrypt.CompareHashAndPassword(hash, []byte(account.Password))
- assert.NoError(t, err)
- })
-}
-func TestAccountDao_UpdateAccount(t *testing.T) {
- account := newAccount("updateAccountTest")
- t.Run("update an none exist account", func(t *testing.T) {
- newAccount := &rbac.Account{Roles: []string{"admin"}}
- err := dao.UpdateAccount(context.Background(), "noExist", newAccount)
- assert.Error(t, err)
- })
-
- dao.DeleteAccount(context.TODO(), account.Name)
- err := dao.CreateAccount(context.Background(), account)
- assert.NoError(t, err)
-
- t.Run("update account", func(t *testing.T) {
- newAccount := &rbac.Account{
- Roles: []string{rbac.RoleDeveloper},
- }
- err = dao.UpdateAccount(context.Background(), account.Name, newAccount)
- assert.NoError(t, err)
- a, err := dao.GetAccount(context.Background(), account.Name)
- assert.NoError(t, err)
- assert.Equal(t, 1, len(a.Roles))
- assert.Equal(t, rbac.RoleDeveloper, a.Roles[0])
- })
-}
diff --git a/server/service/rbac/password.go b/server/service/rbac/password.go
index a8d5dd3..aaf4e21 100644
--- a/server/service/rbac/password.go
+++ b/server/service/rbac/password.go
@@ -27,7 +27,6 @@ import (
"golang.org/x/crypto/bcrypt"
"github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
)
func ChangePassword(ctx context.Context, changerRole []string, changerName string, a *rbacmodel.Account) error {
@@ -49,7 +48,7 @@ func ChangePassword(ctx context.Context, changerRole []string, changerName strin
return ErrNoPermChangeAccount
}
func changePasswordForcibly(ctx context.Context, name, pwd string) error {
- old, err := dao.GetAccount(ctx, name)
+ old, err := GetAccount(ctx, name)
if err != nil {
log.Error("can not change pwd", err)
return err
@@ -64,7 +63,7 @@ func changePassword(ctx context.Context, name, currentPassword, pwd string) erro
if currentPassword == pwd {
return ErrSamePassword
}
- old, err := dao.GetAccount(ctx, name)
+ old, err := GetAccount(ctx, name)
if err != nil {
log.Error("can not change pwd", err)
return err
@@ -88,7 +87,7 @@ func doChangePassword(ctx context.Context, old *rbacmodel.Account, pwd string) e
return err
}
old.Password = stringutil.Bytes2str(hash)
- err = dao.EditAccount(ctx, old)
+ err = EditAccount(ctx, old)
if err != nil {
log.Error("can not change pwd", err)
return err
diff --git a/server/service/rbac/rbac.go b/server/service/rbac/rbac.go
index 4807a34..d72597c 100644
--- a/server/service/rbac/rbac.go
+++ b/server/service/rbac/rbac.go
@@ -21,8 +21,7 @@ import (
"context"
"crypto/rsa"
"errors"
- "github.com/apache/servicecomb-service-center/datasource"
- "github.com/apache/servicecomb-service-center/server/service/validator"
+ "github.com/go-chassis/cari/pkg/errsvc"
"io/ioutil"
"github.com/go-chassis/cari/rbac"
@@ -30,7 +29,6 @@ import (
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/server/config"
"github.com/apache/servicecomb-service-center/server/plugin/security/cipher"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
"github.com/go-chassis/go-archaius"
"github.com/go-chassis/go-chassis/v2/security/authr"
"github.com/go-chassis/go-chassis/v2/security/secret"
@@ -61,7 +59,9 @@ func Init() {
if err != nil {
log.Fatal("can not enable auth module", err)
}
- accountExist, err := dao.AccountExist(context.Background(), RootName)
+ // role init before account
+ initBuildInRole()
+ accountExist, err := AccountExist(context.Background(), RootName)
if err != nil {
log.Fatal("can not enable auth module", err)
}
@@ -70,7 +70,6 @@ func Init() {
}
readPrivateKey()
readPublicKey()
- initBuildInRole()
rbac.Add2WhiteAPIList(APITokenGranter)
log.Info("rbac is enabled")
}
@@ -118,19 +117,17 @@ func initFirstTime(admin string) {
Password: pwd,
Roles: []string{rbac.RoleAdmin},
}
- err = validator.ValidateCreateAccount(a)
- if err != nil {
- log.Fatal("invalid pwd", err)
+ err = CreateAccount(context.Background(), a)
+ if err == nil {
+ log.Info("root account init success")
return
}
- if err := dao.CreateAccount(context.Background(), a); err != nil {
- if err == datasource.ErrAccountDuplicated {
- log.Info("root account already exists")
- return
- }
- log.Fatal("can not enable rbac, init root account failed", err)
+ svcErr, ok := err.(*errsvc.Error)
+ if ok && svcErr.Code == rbac.ErrAccountConflict {
+ log.Info("root account already exist")
+ return
}
- log.Info("root account init success")
+ log.Fatal("can not enable rbac, init root account failed", err)
}
func getPassword() (string, error) {
diff --git a/server/service/rbac/rbac_test.go b/server/service/rbac/rbac_test.go
index 65ae32f..fd55df6 100644
--- a/server/service/rbac/rbac_test.go
+++ b/server/service/rbac/rbac_test.go
@@ -22,7 +22,6 @@ import (
"github.com/apache/servicecomb-service-center/pkg/privacy"
"github.com/apache/servicecomb-service-center/server/config"
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
_ "github.com/apache/servicecomb-service-center/test"
"github.com/astaxie/beego"
"github.com/go-chassis/cari/rbac"
@@ -62,18 +61,10 @@ func init() {
}
archaius.Set(rbacsvc.InitPassword, "Complicated_password1")
- dao.DeleteAccount(context.Background(), "root")
- dao.DeleteAccount(context.Background(), "a")
- dao.DeleteAccount(context.Background(), "b")
-
rbacsvc.Init()
}
func TestInitRBAC(t *testing.T) {
- a, err := dao.GetAccount(context.Background(), "root")
- assert.NoError(t, err)
- assert.Equal(t, "root", a.Name)
-
t.Run("login and authenticate", func(t *testing.T) {
token, err := authr.Login(context.Background(), "root", "Complicated_password1")
assert.NoError(t, err)
@@ -87,29 +78,24 @@ func TestInitRBAC(t *testing.T) {
})
t.Run("change pwd,admin can change any one password", func(t *testing.T) {
- persisted := &rbac.Account{Name: "a", Password: "Complicated_password1"}
- err := dao.CreateAccount(context.Background(), persisted)
+ persisted := newAccount("admin_change_other_pwd")
+ err := rbacsvc.CreateAccount(context.Background(), persisted)
assert.NoError(t, err)
- err = rbacsvc.ChangePassword(context.Background(), []string{rbac.RoleAdmin}, "admin", &rbac.Account{Name: "a", Password: "Complicated_password2"})
+ err = rbacsvc.ChangePassword(context.Background(), []string{rbac.RoleAdmin}, rbac.RoleAdmin, &rbac.Account{Name: persisted.Name, Password: "Complicated_password2"})
assert.NoError(t, err)
- a, err := dao.GetAccount(context.Background(), "a")
+ a, err := rbacsvc.GetAccount(context.Background(), persisted.Name)
assert.NoError(t, err)
assert.True(t, privacy.SamePassword(a.Password, "Complicated_password2"))
})
t.Run("change self password", func(t *testing.T) {
- err := dao.CreateAccount(context.Background(), &rbac.Account{Name: "b", Password: "Complicated_password1"})
- assert.NoError(t, err)
- err = rbacsvc.ChangePassword(context.Background(), nil, "b", &rbac.Account{Name: "b", CurrentPassword: "Complicated_password1", Password: "Complicated_password2"})
+ a := newAccount("change_self_pwd")
+ err := rbacsvc.CreateAccount(context.Background(), a)
assert.NoError(t, err)
- a, err := dao.GetAccount(context.Background(), "b")
+ err = rbacsvc.ChangePassword(context.Background(), nil, a.Name, &rbac.Account{Name: a.Name, CurrentPassword: testPwd0, Password: testPwd1})
assert.NoError(t, err)
- assert.True(t, privacy.SamePassword(a.Password, "Complicated_password2"))
-
- })
- t.Run("list kv", func(t *testing.T) {
- _, n, err := dao.ListAccount(context.TODO())
+ resp, err := rbacsvc.GetAccount(context.Background(), a.Name)
assert.NoError(t, err)
- assert.Greater(t, n, int64(2))
+ assert.True(t, privacy.SamePassword(resp.Password, testPwd1))
})
}
func BenchmarkAuthResource_Login(b *testing.B) {
diff --git a/server/service/rbac/role.go b/server/service/rbac/role.go
index 1523579..8753706 100644
--- a/server/service/rbac/role.go
+++ b/server/service/rbac/role.go
@@ -22,7 +22,6 @@ import (
"github.com/go-chassis/cari/rbac"
"github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
)
var roleMap = map[string]*rbac.Role{}
@@ -46,7 +45,7 @@ func initBuildInRole() {
}
func createBuildInRole(r *rbac.Role) {
- status, err := dao.CreateRole(context.Background(), r)
+ status, err := CreateRole(context.Background(), r)
if err != nil {
log.Fatalf(err, "create role [%s] failed", r.Name)
return
diff --git a/server/service/rbac/dao/role_dao.go b/server/service/rbac/role_dao.go
similarity index 99%
rename from server/service/rbac/dao/role_dao.go
rename to server/service/rbac/role_dao.go
index df8feef..b9f4e3d 100644
--- a/server/service/rbac/dao/role_dao.go
+++ b/server/service/rbac/role_dao.go
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package dao
+package rbac
import (
"context"
diff --git a/server/service/rbac/dao/role_dao_test.go b/server/service/rbac/role_dao_test.go
similarity index 70%
rename from server/service/rbac/dao/role_dao_test.go
rename to server/service/rbac/role_dao_test.go
index 443332f..995a576 100644
--- a/server/service/rbac/dao/role_dao_test.go
+++ b/server/service/rbac/role_dao_test.go
@@ -1,16 +1,15 @@
-package dao_test
+package rbac_test
import (
"context"
rbacsvc "github.com/apache/servicecomb-service-center/server/service/rbac"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
"github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/rbac"
"github.com/stretchr/testify/assert"
"testing"
)
-func exampleRole(name string) *rbac.Role {
+func newRole(name string) *rbac.Role {
return &rbac.Role{
Name: name,
Perms: []*rbac.Permission{
@@ -28,18 +27,18 @@ func exampleRole(name string) *rbac.Role {
func TestCreateRole(t *testing.T) {
t.Run("create new role, should succeed", func(t *testing.T) {
- r := exampleRole("TestCreateRole_createNewRole")
- status, err := dao.CreateRole(context.TODO(), r)
+ r := newRole("TestCreateRole_createNewRole")
+ status, err := rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
})
t.Run("create role twice, should return: "+rbac.NewError(rbac.ErrRoleConflict, "").Error(), func(t *testing.T) {
- r := exampleRole("TestCreateRole_createRoleTwice")
- status, err := dao.CreateRole(context.TODO(), r)
+ r := newRole("TestCreateRole_createRoleTwice")
+ status, err := rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
// twice
- status, err = dao.CreateRole(context.TODO(), r)
+ status, err = rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.Equal(t, rbac.ErrRoleConflict, status.GetCode())
})
@@ -47,17 +46,17 @@ func TestCreateRole(t *testing.T) {
func TestGetRole(t *testing.T) {
t.Run("get no exist role, should return: "+rbac.NewError(rbac.ErrRoleNotExist, "").Error(), func(t *testing.T) {
- r, status, err := dao.GetRole(context.TODO(), "TestGetRole_getNoExistRole")
+ r, status, err := rbacsvc.GetRole(context.TODO(), "TestGetRole_getNoExistRole")
assert.Nil(t, err)
assert.Equal(t, rbac.ErrRoleNotExist, status.GetCode())
assert.Nil(t, r)
})
t.Run("get exist role, should success", func(t *testing.T) {
- r := exampleRole("TestGetRole_getExistRole")
- status, err := dao.CreateRole(context.TODO(), r)
+ r := newRole("TestGetRole_getExistRole")
+ status, err := rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
- resp, status, err := dao.GetRole(context.TODO(), r.Name)
+ resp, status, err := rbacsvc.GetRole(context.TODO(), r.Name)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
assert.Equal(t, r.Name, resp.Name)
@@ -66,14 +65,14 @@ func TestGetRole(t *testing.T) {
func TestEditRole(t *testing.T) {
t.Run("edit no exist role, should return: "+rbac.NewError(rbac.ErrRoleNotExist, "").Error(), func(t *testing.T) {
- r := exampleRole("TestEditRole_editNoExistRole")
- status, err := dao.EditRole(context.TODO(), r.Name, r)
+ r := newRole("TestEditRole_editNoExistRole")
+ status, err := rbacsvc.EditRole(context.TODO(), r.Name, r)
assert.Nil(t, err)
assert.Equal(t, rbac.ErrRoleNotExist, status.GetCode())
})
t.Run("edit role, should success", func(t *testing.T) {
- r := exampleRole("TestGetRole_editRole")
- status, err := dao.CreateRole(context.TODO(), r)
+ r := newRole("TestGetRole_editRole")
+ status, err := rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
@@ -97,18 +96,18 @@ func TestEditRole(t *testing.T) {
Verbs: []string{"*"},
},
}
- status, err = dao.EditRole(context.TODO(), r.Name, r)
+ status, err = rbacsvc.EditRole(context.TODO(), r.Name, r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
- resp, status, err := dao.GetRole(context.TODO(), r.Name)
+ resp, status, err := rbacsvc.GetRole(context.TODO(), r.Name)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
assert.Equal(t, 2, len(resp.Perms))
})
t.Run("edit build in role, should return: "+discovery.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
for _, name := range []string{rbac.RoleDeveloper, rbac.RoleDeveloper} {
- status, err := dao.EditRole(context.TODO(), name, exampleRole(""))
+ status, err := rbacsvc.EditRole(context.TODO(), name, newRole(""))
assert.Nil(t, err)
assert.Equal(t, discovery.ErrForbidden, status.GetCode())
}
@@ -117,27 +116,27 @@ func TestEditRole(t *testing.T) {
func TestDeleteRole(t *testing.T) {
t.Run("delete no exist role, should return: "+rbac.NewError(rbac.ErrRoleNotExist, "").Error(), func(t *testing.T) {
- status, err := dao.DeleteRole(context.TODO(), "TestDeleteRole_deleteNoExistRole")
+ status, err := rbacsvc.DeleteRole(context.TODO(), "TestDeleteRole_deleteNoExistRole")
assert.Nil(t, err)
assert.Equal(t, rbac.ErrRoleNotExist, status.GetCode())
})
t.Run("delete role, should success", func(t *testing.T) {
- r := exampleRole("TestDeleteRole_deleteRole")
- status, err := dao.CreateRole(context.TODO(), r)
+ r := newRole("TestDeleteRole_deleteRole")
+ status, err := rbacsvc.CreateRole(context.TODO(), r)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
- status, err = dao.DeleteRole(context.TODO(), r.Name)
+ status, err = rbacsvc.DeleteRole(context.TODO(), r.Name)
assert.Nil(t, err)
assert.True(t, status.IsSucceed())
- exist, err := dao.RoleExist(context.TODO(), r.Name)
+ exist, err := rbacsvc.RoleExist(context.TODO(), r.Name)
assert.Nil(t, err)
assert.False(t, exist)
})
t.Run("delete build in role, should return: "+discovery.NewError(discovery.ErrForbidden, "").Error(), func(t *testing.T) {
for _, name := range []string{rbac.RoleDeveloper, rbac.RoleDeveloper} {
- status, err := dao.DeleteRole(context.TODO(), name)
+ status, err := rbacsvc.DeleteRole(context.TODO(), name)
assert.Nil(t, err)
assert.Equal(t, discovery.ErrForbidden, status.GetCode())
}
@@ -146,7 +145,7 @@ func TestDeleteRole(t *testing.T) {
func TestListRole(t *testing.T) {
t.Run("list role, should success", func(t *testing.T) {
- roles, total, err := dao.ListRole(context.TODO())
+ roles, total, err := rbacsvc.ListRole(context.TODO())
assert.Nil(t, err)
assert.True(t, total > 0)
assert.Equal(t, int64(len(roles)), total)
@@ -155,7 +154,7 @@ func TestListRole(t *testing.T) {
func TestRoleExistt(t *testing.T) {
t.Run("check no exist role, should success and not exist", func(t *testing.T) {
- exist, err := dao.RoleExist(context.TODO(), "TestRoleExist_checkNoExistRole")
+ exist, err := rbacsvc.RoleExist(context.TODO(), "TestRoleExist_checkNoExistRole")
assert.Nil(t, err)
assert.False(t, exist)
})