upd(system): check service grant permissions

This commit is contained in:
Mitja Zivkovic
2019-02-27 09:20:55 +01:00
parent 9bed5005c6
commit ff22af4b33
11 changed files with 87 additions and 39 deletions
-5
View File
@@ -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")
+14
View File
@@ -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)
-4
View File
@@ -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()
-4
View File
@@ -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()
-4
View File
@@ -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()
+15
View File
@@ -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(),
-4
View File
@@ -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()
-4
View File
@@ -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()
+21
View File
@@ -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)
}
+37 -13
View File
@@ -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))
}
-1
View File
@@ -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))