upd(system): check service grant permissions
This commit is contained in:
@@ -15,11 +15,6 @@ import (
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
if testing.Short() {
|
||||
log.Println("skipping test in short mode.")
|
||||
return
|
||||
}
|
||||
|
||||
// @todo this is a very optimistic initialization, make it more robust
|
||||
godotenv.Load("../../.env")
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/crusttech/crust/internal/rules"
|
||||
. "github.com/crusttech/crust/internal/test"
|
||||
|
||||
"github.com/crusttech/crust/crm/repository"
|
||||
systemService "github.com/crusttech/crust/system/service"
|
||||
systemTypes "github.com/crusttech/crust/system/types"
|
||||
)
|
||||
@@ -41,6 +42,19 @@ func TestPermissions(t *testing.T) {
|
||||
// Set Identity.
|
||||
ctx = auth.SetIdentityToContext(ctx, user)
|
||||
|
||||
// Insert `grant` permission for `compose`.
|
||||
{
|
||||
db := repository.DB(ctx)
|
||||
resources := rules.NewResources(ctx, db)
|
||||
|
||||
list := []rules.Rule{
|
||||
rules.Rule{Resource: "compose", Operation: "grant", Value: rules.Allow},
|
||||
}
|
||||
|
||||
err := resources.Grant(role.ID, list)
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Generate services.
|
||||
permissionsSvc := Permissions().With(ctx)
|
||||
systemPermissionSvc := systemService.Permissions().With(ctx)
|
||||
|
||||
@@ -26,10 +26,6 @@ func TestMain(m *testing.M) {
|
||||
flag.StringVar(&dsn, p("db-dsn"), "crust:crust@tcp(db1:3306)/crust?collation=utf8mb4_general_ci", "DSN for database connection")
|
||||
flag.Parse()
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
factory.Database.Add("default", dsn)
|
||||
|
||||
db := factory.Database.MustGet()
|
||||
|
||||
@@ -29,10 +29,6 @@ func TestMain(m *testing.M) {
|
||||
flag.StringVar(&dsn, p("db-dsn"), "crust:crust@tcp(db1:3306)/crust?collation=utf8mb4_general_ci", "DSN for database connection")
|
||||
flag.Parse()
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
factory.Database.Add("default", dsn)
|
||||
|
||||
db := factory.Database.MustGet()
|
||||
|
||||
@@ -32,10 +32,6 @@ func TestMain(m *testing.M) {
|
||||
flag.StringVar(&dsn, p("db-dsn"), "crust:crust@tcp(db1:3306)/crust?collation=utf8mb4_general_ci", "DSN for database connection")
|
||||
flag.Parse()
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
factory.Database.Add("default", dsn)
|
||||
|
||||
db := factory.Database.MustGet()
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"github.com/crusttech/crust/internal/auth"
|
||||
"github.com/crusttech/crust/internal/rules"
|
||||
. "github.com/crusttech/crust/internal/test"
|
||||
|
||||
"github.com/crusttech/crust/messaging/repository"
|
||||
"github.com/crusttech/crust/messaging/types"
|
||||
systemService "github.com/crusttech/crust/system/service"
|
||||
systemTypes "github.com/crusttech/crust/system/types"
|
||||
@@ -41,6 +43,19 @@ func TestPermissions(t *testing.T) {
|
||||
// Set Identity.
|
||||
ctx = auth.SetIdentityToContext(ctx, user)
|
||||
|
||||
// Insert `grant` permission for `messaging`.
|
||||
{
|
||||
db := repository.DB(ctx)
|
||||
resources := rules.NewResources(ctx, db)
|
||||
|
||||
list := []rules.Rule{
|
||||
rules.Rule{Resource: "messaging", Operation: "grant", Value: rules.Allow},
|
||||
}
|
||||
|
||||
err := resources.Grant(role.ID, list)
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Generate services.
|
||||
channelSvc := (&channel{
|
||||
usr: systemService.User(),
|
||||
|
||||
@@ -28,10 +28,6 @@ func TestMain(m *testing.M) {
|
||||
flag.StringVar(&dsn, p("db-dsn"), "crust:crust@tcp(db1:3306)/crust?collation=utf8mb4_general_ci", "DSN for database connection")
|
||||
flag.Parse()
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
factory.Database.Add("default", dsn)
|
||||
|
||||
db := factory.Database.MustGet()
|
||||
|
||||
@@ -32,10 +32,6 @@ func TestMain(m *testing.M) {
|
||||
flag.StringVar(&dsn, p("db-dsn"), "crust:crust@tcp(db1:3306)/crust?collation=utf8mb4_general_ci", "DSN for database connection")
|
||||
flag.Parse()
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
factory.Database.Add("default", dsn)
|
||||
|
||||
db := factory.Database.MustGet()
|
||||
|
||||
@@ -2,12 +2,19 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/crusttech/crust/internal/rules"
|
||||
"github.com/crusttech/crust/system/repository"
|
||||
"github.com/crusttech/crust/system/types"
|
||||
)
|
||||
|
||||
const (
|
||||
delimiter = ":"
|
||||
)
|
||||
|
||||
type (
|
||||
permissions struct {
|
||||
db db
|
||||
@@ -67,6 +74,10 @@ func (p *permissions) Update(roleID uint64, rules []rules.Rule) (interface{}, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = p.checkServiceAccess(rule.Resource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
err := p.resources.Grant(roleID, rules)
|
||||
if err != nil {
|
||||
@@ -78,3 +89,13 @@ func (p *permissions) Update(roleID uint64, rules []rules.Rule) (interface{}, er
|
||||
func (p *permissions) Delete(roleID uint64) (interface{}, error) {
|
||||
return nil, p.resources.Delete(roleID)
|
||||
}
|
||||
|
||||
func (p *permissions) checkServiceAccess(resource string) error {
|
||||
service := strings.Split(resource, delimiter)[0]
|
||||
|
||||
grant := p.resources.Check(service, "grant")
|
||||
if grant == rules.Allow {
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("No grant permissions for: %v", service)
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ import (
|
||||
internalAuth "github.com/crusttech/crust/internal/auth"
|
||||
"github.com/crusttech/crust/internal/rules"
|
||||
. "github.com/crusttech/crust/internal/test"
|
||||
systemRepos "github.com/crusttech/crust/system/repository"
|
||||
systemTypes "github.com/crusttech/crust/system/types"
|
||||
|
||||
"github.com/crusttech/crust/system/repository"
|
||||
"github.com/crusttech/crust/system/types"
|
||||
)
|
||||
|
||||
func TestPermission(t *testing.T) {
|
||||
@@ -21,8 +22,8 @@ func TestPermission(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
|
||||
// Create user for test.
|
||||
userRepo := systemRepos.User(ctx, factory.Database.MustGet())
|
||||
user := &systemTypes.User{
|
||||
userRepo := repository.User(ctx, factory.Database.MustGet())
|
||||
user := &types.User{
|
||||
Name: "John Doe",
|
||||
Username: "johndoe",
|
||||
SatosaID: "1234",
|
||||
@@ -34,8 +35,8 @@ func TestPermission(t *testing.T) {
|
||||
NoError(t, err, "expected no error creating user, got %v", err)
|
||||
|
||||
// Create role for test and add user
|
||||
roleRepo := systemRepos.Role(ctx, factory.Database.MustGet())
|
||||
role := &systemTypes.Role{
|
||||
roleRepo := repository.Role(ctx, factory.Database.MustGet())
|
||||
role := &types.Role{
|
||||
Name: "Test role v1",
|
||||
}
|
||||
_, err = roleRepo.Create(role)
|
||||
@@ -50,6 +51,29 @@ func TestPermission(t *testing.T) {
|
||||
// Create permission service.
|
||||
permissionSvc := Permissions().With(ctx)
|
||||
|
||||
// Update rules for test role, with error.
|
||||
{
|
||||
list := []rules.Rule{
|
||||
rules.Rule{Resource: "messaging:channel:1", Operation: "message.update.all", Value: rules.Allow},
|
||||
}
|
||||
_, err := permissionSvc.Update(role.ID, list)
|
||||
Error(t, err, "expected error == No Allow permissions for: messaging")
|
||||
}
|
||||
|
||||
// Insert `grant` permission for `messaging` and `system`.
|
||||
{
|
||||
db := repository.DB(ctx)
|
||||
resources := rules.NewResources(ctx, db)
|
||||
|
||||
list := []rules.Rule{
|
||||
rules.Rule{Resource: "system", Operation: "grant", Value: rules.Allow},
|
||||
rules.Rule{Resource: "messaging", Operation: "grant", Value: rules.Allow},
|
||||
}
|
||||
|
||||
err := resources.Grant(role.ID, list)
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Update rules for test role.
|
||||
{
|
||||
list := []rules.Rule{
|
||||
@@ -61,7 +85,7 @@ func TestPermission(t *testing.T) {
|
||||
rules.Rule{Resource: "messaging:channel", Operation: "message.update.all", Value: rules.Allow},
|
||||
}
|
||||
_, err := permissionSvc.Update(role.ID, list)
|
||||
NoError(t, err, "expected no error, setting rules")
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Update with invalid roles
|
||||
@@ -94,23 +118,23 @@ func TestPermission(t *testing.T) {
|
||||
// Read rules for test role.
|
||||
{
|
||||
ret, err := permissionSvc.Read(role.ID)
|
||||
NoError(t, err, "expected no error, setting rules")
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
|
||||
rules := ret.([]rules.Rule)
|
||||
|
||||
Assert(t, len(rules) == 5, "expected len(rules) == 5, got %v", len(rules))
|
||||
Assert(t, len(rules) == 7, "expected len(rules) == 7, got %v", len(rules))
|
||||
}
|
||||
|
||||
// Delete rules for test role.
|
||||
{
|
||||
_, err := permissionSvc.Delete(role.ID)
|
||||
NoError(t, err, "expected no error, setting rules")
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
}
|
||||
|
||||
// Read rules for test role.
|
||||
{
|
||||
ret, err := permissionSvc.Read(role.ID)
|
||||
NoError(t, err, "expected no error, setting rules")
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
|
||||
rules := ret.([]rules.Rule)
|
||||
|
||||
@@ -120,9 +144,9 @@ func TestPermission(t *testing.T) {
|
||||
// List defined permissions.
|
||||
{
|
||||
ret, err := permissionSvc.List()
|
||||
NoError(t, err, "expected no error, setting rules")
|
||||
NoError(t, err, "expected no error, got %v", err)
|
||||
|
||||
perms := ret.([]systemTypes.Permission)
|
||||
perms := ret.([]types.Permission)
|
||||
|
||||
Assert(t, len(perms) > 0, "expected len(rules) > 0, got %v", len(perms))
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ var (
|
||||
)
|
||||
|
||||
func validatePermission(resource string, operation string) error {
|
||||
delimiter := ":"
|
||||
resourceParts := strings.Split(resource, delimiter)
|
||||
if len(resourceParts) < 1 {
|
||||
return errors.Errorf("Invalid resource format, expected >= 1, got %d", len(resourceParts))
|
||||
|
||||
Reference in New Issue
Block a user