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 2d0f9c6 able to change password (#652)
2d0f9c6 is described below
commit 2d0f9c6dc758af85a5875bb027bd571e686c7325
Author: Shawn <[email protected]>
AuthorDate: Mon Jun 29 08:36:50 2020 +0800
able to change password (#652)
---
docs/user-guides/rbac.md | 37 ++++++--
pkg/model/account.go | 12 ++-
server/handler/auth/auth.go | 20 +++--
server/rest/controller/v4/auth_resource.go | 53 ++++++++++-
server/service/rbac/authr_plugin.go | 8 +-
server/service/rbac/dao/account_dao.go | 28 ++++++
server/service/rbac/dao/secret_dao.go | 53 -----------
server/service/rbac/dao/secret_dao_test.go | 36 --------
server/service/rbac/rbac.go | 137 ++++++++++++++++++-----------
server/service/rbac/rbca_test.go | 28 ++++--
server/service/util/common.go | 4 +
11 files changed, 245 insertions(+), 171 deletions(-)
diff --git a/docs/user-guides/rbac.md b/docs/user-guides/rbac.md
index aee26af..b8ed63a 100644
--- a/docs/user-guides/rbac.md
+++ b/docs/user-guides/rbac.md
@@ -13,23 +13,27 @@ openssl rsa -in private.key -pubout -out public.key
```
2.edit app.conf
+
+can revoke private.key after each cluster restart,
```ini
rbac_enabled = true
-rbac_rsa_pub_key_file = ./public.key
+rbac_rsa_public_key_file = ./public.key
+rbac_rsa_private_key_file = ./private.key
```
+3.root account
+before you start server, you need to set env to set your root account
password.
-before you start server, you need to set env to set your root account.
-can revoke private.key after each cluster restart,can not revoke root name and
password
```sh
-export SC_INIT_ROOT_USERNAME=root
export SC_INIT_ROOT_PASSWORD=rootpwd
-export SC_INIT_PRIVATE_KEY=`cat private.key`
```
-at the first time service center cluster init, it will use this env to setup
rbac module.
+at the first time service center cluster init, it will use this env to setup
rbac module. you can not revoke password after cluster start
+
+the root account name is "root"
To securely distribute your root account and private key,
you can use kubernetes
[secret](https://kubernetes.io/zh/docs/tasks/inject-data-application/distribute-credentials-secure/)
### Generate a token
+token is the only credential to access rest API, before you access any API,
you need to get a token
```shell script
curl -X POST \
http://127.0.0.1:30100/v4/token \
@@ -42,12 +46,27 @@ will return a token, token will expired after 30m
```
### Authentication
-in each request you must add token to http header
+in each request you must add token to http header:
+```
Authorization: Bear {token}
-
+```
for example:
```shell script
curl -X GET \
'http://127.0.0.1:30100/v4/default/registry/microservices/{service-id}/instances'
\
-H 'Authorization: Bear
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTI4OTQ1NTEsInVzZXIiOiJyb290In0.FfLOSvVmHT9qCZSe_6iPf4gNjbXLwCrkXxKHsdJoQ8w'
-```
\ No newline at end of file
+```
+
+### Change password
+You must supply current password and token to update to new password
+curl -X PUT \
+ http://127.0.0.1:30100/v4/account-password \
+ -H 'Authorization: Bear
eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50Ijoicm9vdCIsImV4cCI6MTU5MzMyOTE3OSwicm9sZSI6IiJ9.OR_uruuLds1wz10_J4gDEA-L9Ma_1RrHiKEA6CS-Nilv6hHB5KyhZ9_4qqf_c0iia4uKryAGHKsXUvrjOE51tz4QCXlgCmddrkYuLQsnDezXhV3TIqzdl4R_cy8h2cZo8O_b_q7eU2Iemd6x7BJE49SLgNiP5LTXCVct5Qm_GiXYTaM4dbHIJ01V-EPmNQuBr1vKdfNa8cqWtASSp9IEkFx1YpzhFacQgmfoiSGHvxQYZldQXuAh60ZXLBDexGu6jGnG39MqVNRysvHTpZRqxZWBhmEn5DeXpgKu-zlakJMjeEma4zcN-H0MumE-nMlBT5kjKWVr1DOdtOyJI6i786ZpS0wWHV4VOxpSursoKsW_XuTZ
[...]
+ -d '{
+ "currentPassword":"rootpwd",
+ "password":"123"
+}'
+### Roles TODO
+currently, you can not custom and manage any role and role policy. there is
only 1 build in roles
+- admin: able to do anything, including manage account, even change other
account password
+- service: able to call most of API except account management.
\ No newline at end of file
diff --git a/pkg/model/account.go b/pkg/model/account.go
index 4211772..b1da8dd 100644
--- a/pkg/model/account.go
+++ b/pkg/model/account.go
@@ -17,11 +17,17 @@
package model
+const (
+ RoleAdmin = "admin"
+ RoleAuditor = "auditor"
+)
+
type Account struct {
- Name string `json:"name,omitempty"`
- Password string `json:"password,omitempty"`
+ Name string `json:"name,omitempty"`
+ Password string `json:"password,omitempty"`
+ Role string `json:"role,omitempty"`
+ CurrentPassword string `json:"currentPassword,omitempty"`
}
-
type Token struct {
TokenStr string `json:"token,omitempty"`
}
diff --git a/server/handler/auth/auth.go b/server/handler/auth/auth.go
index 9fbd5b3..7105ca8 100644
--- a/server/handler/auth/auth.go
+++ b/server/handler/auth/auth.go
@@ -17,6 +17,7 @@
package auth
import (
+ "context"
"github.com/apache/servicecomb-service-center/pkg/chain"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rest"
@@ -63,15 +64,20 @@ func (h *Handler) Handle(i *chain.Invocation) {
}
to := s[1]
//TODO rbac
- _, err := authr.Authenticate(i.Context(), to)
- if err == nil {
- log.Info("user access")
- i.Next()
+ claims, err := authr.Authenticate(i.Context(), to)
+ if err != nil {
+ log.Errorf(err, "authenticate request failed, %s %s",
req.Method, req.RequestURI)
+ controller.WriteError(w, scerr.ErrUnauthorized, err.Error())
+ i.Fail(nil)
return
}
- log.Errorf(err, "authenticate request failed, %s %s", req.Method,
req.RequestURI)
- controller.WriteError(w, scerr.ErrUnauthorized, err.Error())
- i.Fail(nil)
+ log.Info("user access")
+ req2 := req.WithContext(context.WithValue(req.Context(), "accountInfo",
claims))
+
+ *req = *req2
+ i.Next()
+ return
+
}
func mustAuth(req *http.Request) bool {
if strings.Contains(req.URL.Path, "/v4/token") {
diff --git a/server/rest/controller/v4/auth_resource.go
b/server/rest/controller/v4/auth_resource.go
index 5839e1f..8232452 100644
--- a/server/rest/controller/v4/auth_resource.go
+++ b/server/rest/controller/v4/auth_resource.go
@@ -19,12 +19,14 @@ package v4
import (
"context"
"encoding/json"
+ "errors"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/model"
"github.com/apache/servicecomb-service-center/pkg/rest"
"github.com/apache/servicecomb-service-center/server/rest/controller"
"github.com/apache/servicecomb-service-center/server/scerror"
"github.com/apache/servicecomb-service-center/server/service/rbac"
+ "github.com/apache/servicecomb-service-center/server/service/util"
"github.com/go-chassis/go-chassis/security/authr"
"io/ioutil"
"net/http"
@@ -37,9 +39,58 @@ type AuthResource struct {
func (r *AuthResource) URLPatterns() []rest.Route {
return []rest.Route{
{http.MethodPost, "/v4/token", r.Login},
+ {http.MethodPut, "/v4/account-password", r.ChangePassword},
+ }
+}
+func (r *AuthResource) ChangePassword(w http.ResponseWriter, req
*http.Request) {
+ body, err := ioutil.ReadAll(req.Body)
+ if err != nil {
+ log.Error("read body err", err)
+ controller.WriteError(w, scerror.ErrInternal, err.Error())
+ return
+ }
+ a := &model.Account{}
+ if err = json.Unmarshal(body, a); err != nil {
+ log.Error("json err", err)
+ controller.WriteError(w, scerror.ErrInvalidParams, err.Error())
+ return
+ }
+ if a.Password == "" {
+ controller.WriteError(w, scerror.ErrInvalidParams, "new
password is empty")
+ return
+ }
+ claims := req.Context().Value("accountInfo")
+ m, ok := claims.(map[string]interface{})
+ if !ok {
+ log.Error("claims convert failed",
errors.New(util.ErrMsgConvert))
+ controller.WriteError(w, scerror.ErrInvalidParams,
util.ErrMsgConvert)
+ return
+ }
+ accountNameI := m[rbac.ClaimsUser]
+ changer, ok := accountNameI.(string)
+ if !ok {
+ log.Error("claims convert failed",
errors.New(util.ErrMsgConvert))
+ controller.WriteError(w, scerror.ErrInternal,
util.ErrMsgConvert)
+ return
+ }
+ roleI := m[rbac.ClaimsRole]
+ role, ok := roleI.(string)
+ if !ok {
+ log.Error("claims convert failed",
errors.New(util.ErrMsgConvert))
+ controller.WriteError(w, scerror.ErrInternal,
util.ErrMsgConvert)
+ return
+ }
+ if role == "" {
+ controller.WriteError(w, scerror.ErrInvalidParams, "role is
empty")
+ return
+ }
+ err = rbac.ChangePassword(context.TODO(), role, changer, a)
+ if err != nil {
+ log.Error("change password failed", err)
+ controller.WriteError(w, scerror.ErrInternal, err.Error())
+ return
}
}
-
func (r *AuthResource) Login(w http.ResponseWriter, req *http.Request) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
diff --git a/server/service/rbac/authr_plugin.go
b/server/service/rbac/authr_plugin.go
index 6bba434..3d2ea24 100644
--- a/server/service/rbac/authr_plugin.go
+++ b/server/service/rbac/authr_plugin.go
@@ -31,7 +31,8 @@ import (
var ErrUnauthorized = errors.New("wrong user name or password")
const (
- ClaimsUser = "user"
+ ClaimsUser = "account"
+ ClaimsRole = "role"
)
//EmbeddedAuthenticator is sc default auth plugin, RBAC data is persisted in
etcd
@@ -57,12 +58,13 @@ func (a *EmbeddedAuthenticator) Login(ctx context.Context,
user string, password
return "", err
}
if user == account.Name && password == account.Password {
- secret, err := GetPrivateKey(ctx)
+ secret, err := GetPrivateKey()
if err != nil {
return "", err
}
tokenStr, err := token.Sign(map[string]interface{}{
- ClaimsUser: user, //TODO more claims for RBAC, for
example role name
+ ClaimsUser: user,
+ ClaimsRole: account.Role, //TODO more claims for RBAC,
for example rule config
},
secret,
token.WithExpTime("30m"),
diff --git a/server/service/rbac/dao/account_dao.go
b/server/service/rbac/dao/account_dao.go
index 07a81f2..0a0d076 100644
--- a/server/service/rbac/dao/account_dao.go
+++ b/server/service/rbac/dao/account_dao.go
@@ -30,6 +30,7 @@ import (
)
var ErrDuplicated = errors.New("account is duplicated")
+var ErrCanNotEdit = errors.New("account can not be edited")
//CreateAccount save 2 kv
//1. account info
@@ -86,3 +87,30 @@ func AccountExist(ctx context.Context, name string) (bool,
error) {
}
return exist, nil
}
+
+//CreateAccount save 2 kv
+//1. account info
+func EditAccount(ctx context.Context, a *model.Account) error {
+ key := core.GenerateAccountKey(a.Name)
+ exist, err := kv.Exist(ctx, key)
+ if err != nil {
+ log.Errorf(err, "can not edit account info")
+ return err
+ }
+ if !exist {
+ return ErrCanNotEdit
+ }
+
+ value, err := json.Marshal(a)
+ if err != nil {
+ log.Errorf(err, "account info is invalid")
+ return err
+ }
+ err = kv.PutBytes(ctx, key, value)
+ if err != nil {
+ log.Errorf(err, "can not edit account info")
+ return err
+ }
+
+ return nil
+}
diff --git a/server/service/rbac/dao/secret_dao.go
b/server/service/rbac/dao/secret_dao.go
deleted file mode 100644
index b2cd837..0000000
--- a/server/service/rbac/dao/secret_dao.go
+++ /dev/null
@@ -1,53 +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
-
-import (
- "context"
- "github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/server/core"
- "github.com/apache/servicecomb-service-center/server/service/kv"
-)
-
-//OverrideSecret write secret to kv store
-func OverrideSecret(ctx context.Context, sk string) error {
- key := core.GenerateRBACSecretKey()
- err := kv.Put(context.Background(), key, sk)
- if err != nil {
- log.Errorf(err, "can not override secret")
- return err
- }
- return nil
-}
-func GetSecret(ctx context.Context) ([]byte, error) {
- key := core.GenerateRBACSecretKey()
- r, err := kv.Get(ctx, key)
- if err != nil {
- log.Errorf(err, "can not get secret")
- return nil, err
- }
- return r.Value, nil
-}
-func SecretExist(ctx context.Context) (bool, error) {
- exist, err := kv.Exist(ctx, core.GenerateRBACSecretKey())
- if err != nil {
- log.Errorf(err, "can not get secret info")
- return false, err
- }
- return exist, nil
-}
diff --git a/server/service/rbac/dao/secret_dao_test.go
b/server/service/rbac/dao/secret_dao_test.go
deleted file mode 100644
index 8012788..0000000
--- a/server/service/rbac/dao/secret_dao_test.go
+++ /dev/null
@@ -1,36 +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
-
-import (
- "context"
- "github.com/apache/servicecomb-service-center/server/service/rbac/dao"
- "github.com/stretchr/testify/assert"
- "testing"
-)
-
-func TestOverrideSecret(t *testing.T) {
- err := dao.OverrideSecret(context.Background(), "sk")
- assert.NoError(t, err)
- s, err := dao.GetSecret(context.Background())
- assert.NoError(t, err)
- assert.Equal(t, "sk", string(s))
- b, err := dao.SecretExist(context.Background())
- assert.NoError(t, err)
- assert.True(t, b)
-}
diff --git a/server/service/rbac/rbac.go b/server/service/rbac/rbac.go
index 4840713..5cef488 100644
--- a/server/service/rbac/rbac.go
+++ b/server/service/rbac/rbac.go
@@ -20,6 +20,7 @@ package rbac
import (
"context"
"crypto/rsa"
+ "errors"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/model"
"github.com/apache/servicecomb-service-center/server/service/cipher"
@@ -28,14 +29,18 @@ import (
"github.com/go-chassis/go-archaius"
"github.com/go-chassis/go-chassis/security/authr"
"github.com/go-chassis/go-chassis/security/secret"
- "io"
- "os"
+ "io/ioutil"
)
const (
- InitRoot = "SC_INIT_ROOT_USERNAME"
+ RootName = "root"
InitPassword = "SC_INIT_ROOT_PASSWORD"
- InitPrivate = "SC_INIT_PRIVATE_KEY"
+ PubFilePath = "rbac_rsa_public_key_file"
+)
+
+var (
+ ErrInputCurrentPassword = errors.New("current password should not be
empty")
+ ErrInputChangeAccount = errors.New("can not change other account
password")
)
//Init decide whether enable rbac function and save root account to db
@@ -49,43 +54,42 @@ func Init() {
if err != nil {
log.Fatal("can not enable auth module", err)
}
- admin := archaius.GetString(InitRoot, "")
- if admin == "" {
- log.Fatal("can not enable rbac, root is empty", nil)
- return
- }
- accountExist, err := dao.AccountExist(context.Background(), admin)
+ accountExist, err := dao.AccountExist(context.Background(), RootName)
if err != nil {
log.Fatal("can not enable auth module", err)
}
if !accountExist {
- initFirstTime(admin)
+ initFirstTime(RootName)
}
- overrideSecretKey()
+ readPrivateKey()
readPublicKey()
log.Info("rbac is enabled")
}
//readPublicKey read key to memory
-func readPublicKey() {
- pf := beego.AppConfig.String("rbac_rsa_pub_key_file")
+func readPrivateKey() {
+ pf := beego.AppConfig.String("rbac_rsa_private_key_file")
// 打开文件
- fp, err := os.Open(pf)
+ data, err := ioutil.ReadFile(pf)
if err != nil {
- log.Fatal("can not find public key", err)
+ log.Fatal("can not read private key", err)
return
}
- defer fp.Close()
- buf := make([]byte, 1024)
- for {
- // 循环读取文件
- _, err := fp.Read(buf)
- if err == io.EOF { // io.EOF表示文件末尾
- break
- }
+ archaius.Set("rbac_private_key", string(data))
+ log.Info("read private key success")
+}
+//readPublicKey read key to memory
+func readPublicKey() {
+ pf := beego.AppConfig.String(PubFilePath)
+ // 打开文件
+ content, err := ioutil.ReadFile(pf)
+ if err != nil {
+ log.Fatal("can not find public key", err)
+ return
}
- archaius.Set("rbac_public_key", string(buf))
+ archaius.Set("rbac_public_key", string(content))
+ log.Info("read public key success")
}
func initFirstTime(admin string) {
//handle root account
@@ -93,13 +97,10 @@ func initFirstTime(admin string) {
if pwd == "" {
log.Fatal("can not enable rbac, password is empty", nil)
}
- pwd, err := cipher.Encrypt(pwd)
- if err != nil {
- log.Fatal("can not enable rbac, encryption failed", err)
- }
if err := dao.CreateAccount(context.Background(), &model.Account{
Name: admin,
Password: pwd,
+ Role: model.RoleAdmin,
}); err != nil {
if err == dao.ErrDuplicated {
log.Info("rbac is enabled")
@@ -110,18 +111,6 @@ func initFirstTime(admin string) {
log.Info("root account init success")
}
-//should override key on each start procedure,
-//so that a system such as kubernetes can use secret to distribute a new
secret to revoke the old one
-func overrideSecretKey() {
- secret := archaius.GetString(InitPrivate, "")
- if secret == "" {
- log.Fatal("can not enable rbac, secret is empty", nil)
- }
- if err := dao.OverrideSecret(context.Background(), secret); err != nil {
- log.Fatal("can not save secret", err)
- }
-
-}
func Enabled() bool {
return beego.AppConfig.DefaultBool("rbac_enabled", false)
}
@@ -131,23 +120,19 @@ func PublicKey() string {
return archaius.GetString("rbac_public_key", "")
}
-//GetSecretStr return decrypted secret
-func GetSecretStr(ctx context.Context) (string, error) {
- sk, err := dao.GetSecret(ctx)
+//privateKey get decrypted private key to verify a token
+func privateKey() (string, error) {
+ ep := archaius.GetString("rbac_private_key", "")
+ p, err := cipher.Decrypt(ep)
if err != nil {
return "", err
}
- skStr, err := cipher.Decrypt(string(sk))
- if err != nil {
- log.Error("can not decrypt:", err)
- return "", err
- }
- return skStr, nil
+ return p, nil
}
//GetPrivateKey return rsa key instance
-func GetPrivateKey(ctx context.Context) (*rsa.PrivateKey, error) {
- sk, err := GetSecretStr(ctx)
+func GetPrivateKey() (*rsa.PrivateKey, error) {
+ sk, err := privateKey()
if err != nil {
return nil, err
}
@@ -158,3 +143,51 @@ func GetPrivateKey(ctx context.Context) (*rsa.PrivateKey,
error) {
}
return p, nil
}
+
+func ChangePassword(ctx context.Context, changerRole, changerName string, a
*model.Account) error {
+ if a.Name != "" {
+ if changerRole != model.RoleAdmin { //need to check password
mismatch. but admin role can change any user password without supply current
password
+ log.Error("can not change other account pwd", nil)
+ return ErrInputChangeAccount
+ }
+ return changePasswordForcibly(ctx, a.Name, a.Password)
+ } else {
+ if a.CurrentPassword == "" {
+ log.Error("current pwd is empty", nil)
+ return ErrInputCurrentPassword
+ }
+ return changePassword(ctx, changerName, a.CurrentPassword,
a.Password)
+ }
+}
+func changePasswordForcibly(ctx context.Context, name, pwd string) error {
+ old, err := dao.GetAccount(ctx, name)
+ if err != nil {
+ log.Error("can not change pwd", err)
+ return err
+ }
+ old.Password = pwd
+ err = dao.EditAccount(ctx, old)
+ if err != nil {
+ log.Error("can not change pwd", err)
+ return err
+ }
+ return nil
+}
+func changePassword(ctx context.Context, name, currentPassword, pwd string)
error {
+ old, err := dao.GetAccount(ctx, name)
+ if err != nil {
+ log.Error("can not change pwd", err)
+ return err
+ }
+ if old.Password != currentPassword {
+ log.Error("current pwd is wrong", nil)
+ return errors.New("can not change pwd")
+ }
+ old.Password = pwd
+ err = dao.EditAccount(ctx, old)
+ if err != nil {
+ log.Error("can not change pwd", err)
+ return err
+ }
+ return nil
+}
diff --git a/server/service/rbac/rbca_test.go b/server/service/rbac/rbca_test.go
index a4db540..b01aa28 100644
--- a/server/service/rbac/rbca_test.go
+++ b/server/service/rbac/rbca_test.go
@@ -19,6 +19,7 @@ package rbac_test
import (
"context"
+ "github.com/apache/servicecomb-service-center/pkg/model"
mgr "github.com/apache/servicecomb-service-center/server/plugin"
"github.com/apache/servicecomb-service-center/server/plugin/pkg/discovery/etcd"
etcd2
"github.com/apache/servicecomb-service-center/server/plugin/pkg/registry/etcd"
@@ -38,7 +39,8 @@ import (
func init() {
beego.AppConfig.Set("registry_plugin", "etcd")
beego.AppConfig.Set("rbac_enabled", "true")
- beego.AppConfig.Set("rbac_rsa_pub_key_file", "./rbac.pub")
+ beego.AppConfig.Set(rbac.PubFilePath, "./rbac.pub")
+ beego.AppConfig.Set("rbac_rsa_private_key_file", "./private.key")
mgr.RegisterPlugin(mgr.Plugin{mgr.REGISTRY, "etcd", etcd2.NewRegistry})
mgr.RegisterPlugin(mgr.Plugin{mgr.DISCOVERY, "buildin",
etcd.NewRepository})
mgr.RegisterPlugin(mgr.Plugin{mgr.DISCOVERY, "etcd",
etcd.NewRepository})
@@ -55,22 +57,17 @@ func TestInitRBAC(t *testing.T) {
b, err := secret.RSAPrivate2Bytes(pri)
assert.NoError(t, err)
- archaius.Set(rbac.InitPrivate, string(b))
-
+ ioutil.WriteFile("./private.key", b, 0600)
b, err = secret.RSAPublicKey2Bytes(pub)
err = ioutil.WriteFile("./rbac.pub", b, 0600)
assert.NoError(t, err)
- archaius.Set(rbac.InitRoot, "root")
archaius.Set(rbac.InitPassword, "root")
rbac.Init()
a, err := dao.GetAccount(context.Background(), "root")
assert.NoError(t, err)
assert.Equal(t, "root", a.Name)
- s, err := dao.GetSecret(context.Background())
- assert.NoError(t, err)
- assert.NotEmpty(t, s)
t.Run("login and authenticate", func(t *testing.T) {
token, err := authr.Login(context.Background(), "root", "root")
@@ -84,4 +81,21 @@ func TestInitRBAC(t *testing.T) {
t.Run("second time init", func(t *testing.T) {
rbac.Init()
})
+
+ t.Run("change pwd,admin can change any one password", func(t
*testing.T) {
+ dao.CreateAccount(context.Background(), &model.Account{Name:
"a", Password: "123"})
+ err := rbac.ChangePassword(context.Background(),
model.RoleAdmin, "admin", &model.Account{Name: "a", Password: "1234"})
+ assert.NoError(t, err)
+ a, err := dao.GetAccount(context.Background(), "a")
+ assert.NoError(t, err)
+ assert.Equal(t, "1234", a.Password)
+ })
+ t.Run("change own password", func(t *testing.T) {
+ dao.CreateAccount(context.Background(), &model.Account{Name:
"b", Password: "123"})
+ err := rbac.ChangePassword(context.Background(), "", "b",
&model.Account{CurrentPassword: "123", Password: "1234"})
+ assert.NoError(t, err)
+ a, err := dao.GetAccount(context.Background(), "b")
+ assert.NoError(t, err)
+ assert.Equal(t, "1234", a.Password)
+ })
}
diff --git a/server/service/util/common.go b/server/service/util/common.go
index 88c5737..b34362d 100644
--- a/server/service/util/common.go
+++ b/server/service/util/common.go
@@ -24,3 +24,7 @@ const (
CTX_REQUEST_REVISION = "requestRev"
CTX_RESPONSE_REVISION = "responseRev"
)
+
+const (
+ ErrMsgConvert = "type convert error"
+)