mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
etcdhttp: fix access check for multiple roles in auth
Check access for multiple roles should go through all roles.
This commit is contained in:
parent
ff5c3469c1
commit
18169e896c
@ -97,9 +97,12 @@ func hasKeyPrefixAccess(sec auth.Store, r *http.Request, key string, recursive b
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if recursive {
|
if recursive {
|
||||||
return role.HasRecursiveAccess(key, writeAccess)
|
if role.HasRecursiveAccess(key, writeAccess) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if role.HasKeyAccess(key, writeAccess) {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return role.HasKeyAccess(key, writeAccess)
|
|
||||||
}
|
}
|
||||||
plog.Warningf("auth: invalid access for user %s on key %s.", username, key)
|
plog.Warningf("auth: invalid access for user %s on key %s.", username, key)
|
||||||
return false
|
return false
|
||||||
|
@ -38,7 +38,7 @@ func mustJSONRequest(t *testing.T, method string, p string, body string) *http.R
|
|||||||
|
|
||||||
type mockAuthStore struct {
|
type mockAuthStore struct {
|
||||||
user *auth.User
|
user *auth.User
|
||||||
role *auth.Role
|
roles map[string]*auth.Role
|
||||||
err error
|
err error
|
||||||
enabled bool
|
enabled bool
|
||||||
}
|
}
|
||||||
@ -59,13 +59,15 @@ func (s *mockAuthStore) UpdateUser(user auth.User) (auth.User, error) { return *
|
|||||||
func (s *mockAuthStore) AllRoles() ([]string, error) {
|
func (s *mockAuthStore) AllRoles() ([]string, error) {
|
||||||
return []string{"awesome", "guest", "root"}, s.err
|
return []string{"awesome", "guest", "root"}, s.err
|
||||||
}
|
}
|
||||||
func (s *mockAuthStore) GetRole(name string) (auth.Role, error) { return *s.role, s.err }
|
func (s *mockAuthStore) GetRole(name string) (auth.Role, error) { return *s.roles[name], s.err }
|
||||||
func (s *mockAuthStore) CreateRole(role auth.Role) error { return s.err }
|
func (s *mockAuthStore) CreateRole(role auth.Role) error { return s.err }
|
||||||
func (s *mockAuthStore) DeleteRole(name string) error { return s.err }
|
func (s *mockAuthStore) DeleteRole(name string) error { return s.err }
|
||||||
func (s *mockAuthStore) UpdateRole(role auth.Role) (auth.Role, error) { return *s.role, s.err }
|
func (s *mockAuthStore) UpdateRole(role auth.Role) (auth.Role, error) {
|
||||||
func (s *mockAuthStore) AuthEnabled() bool { return s.enabled }
|
return *s.roles[role.Role], s.err
|
||||||
func (s *mockAuthStore) EnableAuth() error { return s.err }
|
}
|
||||||
func (s *mockAuthStore) DisableAuth() error { return s.err }
|
func (s *mockAuthStore) AuthEnabled() bool { return s.enabled }
|
||||||
|
func (s *mockAuthStore) EnableAuth() error { return s.err }
|
||||||
|
func (s *mockAuthStore) DisableAuth() error { return s.err }
|
||||||
|
|
||||||
func TestAuthFlow(t *testing.T) {
|
func TestAuthFlow(t *testing.T) {
|
||||||
enableMapMu.Lock()
|
enableMapMu.Lock()
|
||||||
@ -159,8 +161,10 @@ func TestAuthFlow(t *testing.T) {
|
|||||||
{
|
{
|
||||||
req: mustJSONRequest(t, "GET", "roles/manager", ""),
|
req: mustJSONRequest(t, "GET", "roles/manager", ""),
|
||||||
store: mockAuthStore{
|
store: mockAuthStore{
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "manager",
|
"manager": {
|
||||||
|
Role: "manager",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wcode: http.StatusOK,
|
wcode: http.StatusOK,
|
||||||
@ -181,8 +185,10 @@ func TestAuthFlow(t *testing.T) {
|
|||||||
{
|
{
|
||||||
req: mustJSONRequest(t, "PUT", "roles/manager", `{"role":"manager","revoke":{"kv":{"read":["foo"],"write":[]}}}`),
|
req: mustJSONRequest(t, "PUT", "roles/manager", `{"role":"manager","revoke":{"kv":{"read":["foo"],"write":[]}}}`),
|
||||||
store: mockAuthStore{
|
store: mockAuthStore{
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "manager",
|
"manager": {
|
||||||
|
Role: "manager",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wcode: http.StatusOK,
|
wcode: http.StatusOK,
|
||||||
@ -223,8 +229,10 @@ func TestAuthFlow(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"root"},
|
Roles: []string{"root"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "root",
|
"root": {
|
||||||
|
Role: "root",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wcode: http.StatusOK,
|
wcode: http.StatusOK,
|
||||||
@ -279,8 +287,10 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"root"},
|
Roles: []string{"root"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "root",
|
"root": {
|
||||||
|
Role: "root",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
@ -297,12 +307,14 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"foorole"},
|
Roles: []string{"foorole"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "foorole",
|
"foorole": {
|
||||||
Permissions: auth.Permissions{
|
Role: "foorole",
|
||||||
KV: auth.RWPermission{
|
Permissions: auth.Permissions{
|
||||||
Read: []string{"/foo"},
|
KV: auth.RWPermission{
|
||||||
Write: []string{"/foo"},
|
Read: []string{"/foo"},
|
||||||
|
Write: []string{"/foo"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -321,12 +333,14 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"foorole"},
|
Roles: []string{"foorole"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "foorole",
|
"foorole": {
|
||||||
Permissions: auth.Permissions{
|
Role: "foorole",
|
||||||
KV: auth.RWPermission{
|
Permissions: auth.Permissions{
|
||||||
Read: []string{"/foo*"},
|
KV: auth.RWPermission{
|
||||||
Write: []string{"/foo*"},
|
Read: []string{"/foo*"},
|
||||||
|
Write: []string{"/foo*"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -345,12 +359,14 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"foorole"},
|
Roles: []string{"foorole"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "foorole",
|
"foorole": {
|
||||||
Permissions: auth.Permissions{
|
Role: "foorole",
|
||||||
KV: auth.RWPermission{
|
Permissions: auth.Permissions{
|
||||||
Read: []string{"/foo*"},
|
KV: auth.RWPermission{
|
||||||
Write: []string{"/foo*"},
|
Read: []string{"/foo*"},
|
||||||
|
Write: []string{"/foo*"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -381,12 +397,14 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"foorole"},
|
Roles: []string{"foorole"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "guest",
|
"guest": {
|
||||||
Permissions: auth.Permissions{
|
Role: "guest",
|
||||||
KV: auth.RWPermission{
|
Permissions: auth.Permissions{
|
||||||
Read: []string{"/foo*"},
|
KV: auth.RWPermission{
|
||||||
Write: []string{"/foo*"},
|
Read: []string{"/foo*"},
|
||||||
|
Write: []string{"/foo*"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -405,12 +423,14 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
Password: goodPassword,
|
Password: goodPassword,
|
||||||
Roles: []string{"foorole"},
|
Roles: []string{"foorole"},
|
||||||
},
|
},
|
||||||
role: &auth.Role{
|
roles: map[string]*auth.Role{
|
||||||
Role: "guest",
|
"guest": {
|
||||||
Permissions: auth.Permissions{
|
Role: "guest",
|
||||||
KV: auth.RWPermission{
|
Permissions: auth.Permissions{
|
||||||
Read: []string{"/foo*"},
|
KV: auth.RWPermission{
|
||||||
Write: []string{"/foo*"},
|
Read: []string{"/foo*"},
|
||||||
|
Write: []string{"/foo*"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -420,6 +440,36 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
hasKeyPrefixAccess: false,
|
hasKeyPrefixAccess: false,
|
||||||
hasRecursiveAccess: false,
|
hasRecursiveAccess: false,
|
||||||
},
|
},
|
||||||
|
// check access for multiple roles
|
||||||
|
{
|
||||||
|
key: "/foo",
|
||||||
|
req: mustAuthRequest("GET", "user", "good"),
|
||||||
|
store: &mockAuthStore{
|
||||||
|
user: &auth.User{
|
||||||
|
User: "user",
|
||||||
|
Password: goodPassword,
|
||||||
|
Roles: []string{"role1", "role2"},
|
||||||
|
},
|
||||||
|
roles: map[string]*auth.Role{
|
||||||
|
"role1": {
|
||||||
|
Role: "role1",
|
||||||
|
},
|
||||||
|
"role2": {
|
||||||
|
Role: "role2",
|
||||||
|
Permissions: auth.Permissions{
|
||||||
|
KV: auth.RWPermission{
|
||||||
|
Read: []string{"/foo"},
|
||||||
|
Write: []string{"/foo"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
hasRoot: false,
|
||||||
|
hasKeyPrefixAccess: true,
|
||||||
|
hasRecursiveAccess: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range table {
|
for i, tt := range table {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user