fix(internal): rbac uses user.ID for actions

This commit is contained in:
Mitja Zivkovic
2019-02-12 18:10:38 +01:00
parent 8015539aaa
commit a0e41d1b92
8 changed files with 73 additions and 61 deletions
+7 -2
View File
@@ -1,15 +1,20 @@
package rbac_test
import (
"github.com/crusttech/crust/internal/rbac"
"github.com/namsral/flag"
"testing"
"github.com/joho/godotenv"
"github.com/namsral/flag"
"github.com/crusttech/crust/internal/rbac"
)
var loaded bool
func getClient() (*rbac.Client, error) {
if !loaded {
godotenv.Load("../../.env")
rbac.Flags()
flag.Parse()
loaded = true
+3 -1
View File
@@ -3,8 +3,10 @@ package rbac
import (
"encoding/json"
"fmt"
"github.com/crusttech/crust/internal/rbac/types"
"github.com/pkg/errors"
"github.com/crusttech/crust/internal/rbac/types"
)
type (
+4 -2
View File
@@ -3,9 +3,11 @@ package rbac
import (
"encoding/json"
"fmt"
"github.com/crusttech/crust/internal/rbac/types"
"github.com/pkg/errors"
"strings"
"github.com/pkg/errors"
"github.com/crusttech/crust/internal/rbac/types"
)
type (
+6 -5
View File
@@ -3,6 +3,7 @@ package rbac
import (
"encoding/json"
"fmt"
"github.com/crusttech/crust/internal/rbac/types"
"github.com/pkg/errors"
)
@@ -13,7 +14,7 @@ type (
}
SessionsInterface interface {
Create(sessionID, username string, roles ...string) error
Create(sessionID, userID string, roles ...string) error
Get(sessionID string) (*types.Session, error)
Delete(sessionID string) error
@@ -30,11 +31,11 @@ const (
sessionsDeactivateRole = "/sessions/%s/deactivateRole"
)
func (u *Sessions) Create(sessionID, username string, roles ...string) error {
func (u *Sessions) Create(sessionID, userID string, roles ...string) error {
body := struct {
Username string `json:"username"`
Roles []string `json:"roles,omitempty"`
}{username, roles}
UserID string `json:"userid"`
Roles []string `json:"roles,omitempty"`
}{userID, roles}
resp, err := u.Client.Post(fmt.Sprintf(sessionsCreate, sessionID), body)
if err != nil {
+16 -12
View File
@@ -16,8 +16,7 @@ func TestSessions(t *testing.T) {
roles := rbac.Roles()
resources := rbac.Resources()
// clean up data
users.Delete("test-user")
// @todo until users.Get implements getting user by email, we need to delete users at end of the test successful and unsuccessful.
sessions.Delete("test-session")
roles.Delete("test-role")
resources.Delete("test-resource")
@@ -25,15 +24,14 @@ func TestSessions(t *testing.T) {
must(t, roles.Create("test-role"), "Error when creating test-role")
{
user, err := users.Create("test-user", "test-password")
must(t, err, "Error when creating test-user")
assert(t, user != nil, "%+v", errors.New("Expected non-nil user"))
assert(t, user.UserID != "", "%+v", errors.New("Expected non-empty user.UserID"))
assert(t, user.Username == "test-user", "%+v", errors.Errorf("Expected test-user == %s", user.Username))
}
must(t, users.AddRole("test-user", "test-role"), "Error when assigning test-role to test-user")
must(t, sessions.Create("test-session", "test-user", "test-role"), "Error when creating test-session")
user, err := users.Create("test-user@crust.tech", "test-password")
must(t, err, "Error when creating test-user@crust.tech")
assert(t, user != nil, "%+v", errors.New("Expected non-nil user"))
assert(t, user.ID != "", "%+v", errors.New("Expected non-empty user.ID"))
assert(t, user.Username == "test-user@crust.tech", "%+v", errors.Errorf("Expected test-user@crust.tech == %s", user.Username))
must(t, users.AddRole(user.ID, "test-role"), "Error when assigning test-role to test-user@crust.tech")
must(t, sessions.Create("test-session", user.ID, "test-role"), "Error when creating test-session")
must(t, resources.Create("test-resource", []string{"view", "edit", "delete"}), "Error when creating test-resource")
must(t, resources.Grant("test-resource", "test-role", []string{"view", "edit"}), "Error when granting permissions to role on resource")
@@ -42,7 +40,6 @@ func TestSessions(t *testing.T) {
session, err := sessions.Get("test-session")
must(t, err, "Error when getting test-session")
assert(t, session.ID == "test-session", "Unexpected Session ID, test-session != '%s'", session.ID)
// assert(t, session.Username == "test-user", "Unexpected user, test-user != '%s'", session.Username)
assert(t, len(session.Roles) == 1, "Expected one session role, got %+v", session.Roles)
assert(t, session.Roles[0] == "test-role", "Unexpected session role, test-role != '%s'", session.Roles[0])
}
@@ -94,4 +91,11 @@ func TestSessions(t *testing.T) {
return err
}())
mustFail(t, sessions.Delete("test-session"))
must(t, users.Delete(user.ID), "Error when deleting test-user")
mustFail(t, func() error {
_, err := users.Get(user.ID)
return err
}())
mustFail(t, users.Delete(user.ID))
}
+4 -4
View File
@@ -2,16 +2,16 @@ package types
type (
User struct {
UserID string `json:"userid"`
ID string `json:"userid"`
Username string `json:"username"`
AssignedRoles []string `json:"assignedRoles"`
AuthorizedRoles []string `json:"authorizedRoles"`
}
Session struct {
ID string `json:"session"`
Username string `json:"username"`
Roles []string `json:"roles"`
ID string `json:"session"`
UserID string `json:"userid"`
Roles []string `json:"roles"`
}
// @todo: need to list nested roles,
+15 -13
View File
@@ -3,8 +3,10 @@ package rbac
import (
"encoding/json"
"fmt"
"github.com/crusttech/crust/internal/rbac/types"
"github.com/pkg/errors"
"github.com/crusttech/crust/internal/rbac/types"
)
type (
@@ -14,11 +16,11 @@ type (
UsersInterface interface {
Create(username, password string) (*types.User, error)
Get(username string) (*types.User, error)
Delete(username string) error
Get(userID string) (*types.User, error)
Delete(userID string) error
AddRole(username string, roles ...string) error
RemoveRole(username string, roles ...string) error
AddRole(userID string, roles ...string) error
RemoveRole(userID string, roles ...string) error
}
)
@@ -51,12 +53,12 @@ func (u *Users) Create(username, password string) (*types.User, error) {
}
}
func (u *Users) AddRole(username string, roles ...string) error {
func (u *Users) AddRole(userID string, roles ...string) error {
body := struct {
Roles []string `json:"roles"`
}{roles}
resp, err := u.Client.Patch(fmt.Sprintf(usersAddRole, username), body)
resp, err := u.Client.Patch(fmt.Sprintf(usersAddRole, userID), body)
if err != nil {
return errors.Wrap(err, "request failed")
}
@@ -69,12 +71,12 @@ func (u *Users) AddRole(username string, roles ...string) error {
}
}
func (u *Users) RemoveRole(username string, roles ...string) error {
func (u *Users) RemoveRole(userID string, roles ...string) error {
body := struct {
Roles []string `json:"roles"`
}{roles}
resp, err := u.Client.Patch(fmt.Sprintf(usersRemoveRole, username), body)
resp, err := u.Client.Patch(fmt.Sprintf(usersRemoveRole, userID), body)
if err != nil {
return errors.Wrap(err, "request failed")
}
@@ -87,8 +89,8 @@ func (u *Users) RemoveRole(username string, roles ...string) error {
}
}
func (u *Users) Get(username string) (*types.User, error) {
resp, err := u.Client.Get(fmt.Sprintf(usersGet, username))
func (u *Users) Get(userID string) (*types.User, error) {
resp, err := u.Client.Get(fmt.Sprintf(usersGet, userID))
if err != nil {
return nil, errors.Wrap(err, "request failed")
}
@@ -102,8 +104,8 @@ func (u *Users) Get(username string) (*types.User, error) {
}
}
func (u *Users) Delete(username string) error {
resp, err := u.Client.Delete(fmt.Sprintf(usersDelete, username))
func (u *Users) Delete(userID string) error {
resp, err := u.Client.Delete(fmt.Sprintf(usersDelete, userID))
if err != nil {
return errors.Wrap(err, "request failed")
}
+18 -22
View File
@@ -11,49 +11,45 @@ func TestUsers(t *testing.T) {
users := rbac.Users()
roles := rbac.Roles()
users.Delete("test-user")
// Cleanup data
roles.Delete("test-role")
// @todo until users.Get implements getting user by email, we need to delete users at end of the test successful and unsuccessful.
must(t, roles.Create("test-role"), "Error when creating test-role")
{
_, err := users.Create("test-user", "test-password")
must(t, err, "Error when creating test-user")
}
user, err := users.Create("test-user@crust.tech", "test-password")
must(t, err, "Error when creating test-user")
// check if we inherited some roles (should be empty)
{
user, err := users.Get("test-user")
u1, err := users.Get(user.ID)
must(t, err, "Error when retrieving test-user 1")
// assert(t, user.Username == "test-user", "Unexpected username, test-user != '%s'", user.Username)
assert(t, len(user.AssignedRoles) == 0, "Unexpected number of roles, expected empty, got %+v", user.AssignedRoles)
assert(t, len(u1.AssignedRoles) == 0, "Unexpected number of roles, expected empty, got %+v", u1.AssignedRoles)
}
must(t, users.AddRole("test-user", "test-role"), "Error when assigning test-role to test-user")
must(t, users.AddRole(user.ID, "test-role"), "Error when assigning test-role to test-user")
// check if we inherited some roles (should be empty)
{
user, err := users.Get("test-user")
must(t, err, "Error when retrieving test-user 3")
// assert(t, user.Username == "test-user", "Unexpected username, test-user != '%s'", user.Username)
assert(t, len(user.AssignedRoles) == 1, "Unexpected number of roles, expected 1, got %+v", user.AssignedRoles)
assert(t, user.AssignedRoles[0] == "test-role", "Unexpected role name, test-role != '%s'", user.AssignedRoles[0])
u2, err := users.Get(user.ID)
must(t, err, "Error when retrieving test-user 2")
assert(t, len(u2.AssignedRoles) == 1, "Unexpected number of roles, expected 1, got %+v", u2.AssignedRoles)
assert(t, u2.AssignedRoles[0] == "test-role", "Unexpected role name, test-role != '%s'", u2.AssignedRoles[0])
}
must(t, users.RemoveRole("test-user", "test-role"), "Error when deassigning test-role to test-user")
must(t, users.RemoveRole(user.ID, "test-role"), "Error when de-assigning test-role to test-user")
// check roles are empty after de-assign
{
user, err := users.Get("test-user")
must(t, err, "Error when retrieving test-user 4")
// assert(t, user.Username == "test-user", "Unexpected username, test-user != '%s'", user.Username)
assert(t, len(user.AssignedRoles) == 0, "Unexpected number of roles, expected empty, got %+v", user.AssignedRoles)
u3, err := users.Get(user.ID)
must(t, err, "Error when retrieving test-user 3")
assert(t, len(u3.AssignedRoles) == 0, "Unexpected number of roles, expected empty, got %+v", u3.AssignedRoles)
}
must(t, users.Delete("test-user"), "Error when deleting test-user")
must(t, users.Delete(user.ID), "Error when deleting test-user")
mustFail(t, func() error {
_, err := users.Get("test-user")
_, err := users.Get(user.ID)
return err
}())
mustFail(t, users.Delete("test-user"))
mustFail(t, users.Delete(user.ID))
}