From 6719d2cdf859213caeaeac04aa625cf6768704fc Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Wed, 3 Apr 2019 23:09:34 +0200 Subject: [PATCH] Move role/rule reset code out of repository to CLI command --- internal/rules/interfaces.go | 1 + internal/rules/resources.go | 18 +++++ system/cli/roles.go | 120 +++++++++++++++++++++++++++-- system/internal/repository/role.go | 98 ----------------------- 4 files changed, 133 insertions(+), 104 deletions(-) diff --git a/internal/rules/interfaces.go b/internal/rules/interfaces.go index e52a45b34..3842ede22 100644 --- a/internal/rules/interfaces.go +++ b/internal/rules/interfaces.go @@ -14,4 +14,5 @@ type ResourcesInterface interface { Grant(roleID uint64, rules []Rule) error Read(roleID uint64) ([]Rule, error) Delete(roleID uint64) error + Reset(rules []Rule) error } diff --git a/internal/rules/resources.go b/internal/rules/resources.go index 2fafb0319..a9ba8610d 100644 --- a/internal/rules/resources.go +++ b/internal/rules/resources.go @@ -17,6 +17,9 @@ type ( resources struct { ctx context.Context db *factory.DB + + // sql table reference + dbTable string } // CheckAccessFunc function. @@ -31,6 +34,8 @@ func (rr *resources) With(ctx context.Context, db *factory.DB) ResourcesInterfac return &resources{ ctx: ctx, db: db, + + dbTable: "sys_rules", } } @@ -170,3 +175,16 @@ func (rr *resources) Delete(roleID uint64) error { } return nil } + +// Resets rules on all roles and inserts new +func (rr *resources) Reset(rules []Rule) error { + return rr.db.Transaction(func() error { + for r := range rules { + if err := rr.db.Replace(rr.dbTable, rules[r]); err != nil { + return err + } + } + + return nil + }) +} diff --git a/system/cli/roles.go b/system/cli/roles.go index ad0029b2e..8d28f10ee 100644 --- a/system/cli/roles.go +++ b/system/cli/roles.go @@ -5,22 +5,130 @@ import ( "fmt" "os" "strconv" + "time" + "github.com/crusttech/crust/internal/rules" "github.com/crusttech/crust/system/internal/repository" "github.com/crusttech/crust/system/types" ) func RolesReset() { - ctx := context.Background() - db := repository.DB(ctx) + var ( + err error + ctx = context.Background() + db = repository.DB(ctx) + roleRepo = repository.Role(ctx, db) + ruleRepo = rules.NewResources(ctx, db) + ) + + // Recreates core roles (will not reset memberships!) + err = types.RoleSet{ + &types.Role{ID: 1, Handle: "everyone", Name: "Everyone"}, + &types.Role{ID: 2, Handle: "admins", Name: "Administrators"}, + }.Walk(func(r *types.Role) error { + // Update will exec REPLACE and take care of creation as well + r.CreatedAt = time.Now() + _, err := roleRepo.Update(r) + return err + }) - err := repository.Role(ctx, db).Reset() if err != nil { - fmt.Printf("Error: %v\n", err) - os.Exit(1) + fmt.Printf("could not reset roles: %v", err) + return } - fmt.Println("Everyone and Administrators role were reset.") + rules := []rules.Rule{ + {1, "system", "user.create", 2}, + {1, "compose", "access", 2}, + {1, "messaging", "access", 2}, + {2, "compose", "namespace.create", 2}, + {2, "compose", "access", 2}, + {2, "compose", "grant", 2}, + {2, "compose:namespace:*", "page.create", 2}, + {2, "compose:namespace:*", "read", 2}, + {2, "compose:namespace:*", "update", 2}, + {2, "compose:namespace:*", "delete", 2}, + {2, "compose:namespace:*", "module.create", 2}, + {2, "compose:namespace:*", "chart.create", 2}, + {2, "compose:namespace:*", "trigger.create", 2}, + {2, "compose:chart:*", "read", 2}, + {2, "compose:chart:*", "update", 2}, + {2, "compose:chart:*", "delete", 2}, + {2, "compose:trigger:*", "read", 2}, + {2, "compose:trigger:*", "update", 2}, + {2, "compose:trigger:*", "delete", 2}, + {2, "compose:page:*", "read", 2}, + {2, "compose:page:*", "update", 2}, + {2, "compose:page:*", "delete", 2}, + {2, "system", "access", 2}, + {2, "system", "grant", 2}, + {2, "system", "settings.read", 2}, + {2, "system", "settings.manage", 2}, + {2, "system", "organisation.create", 2}, + {2, "system", "user.create", 2}, + {2, "system", "role.create", 2}, + {2, "system:organisation:*", "access", 2}, + {2, "system:user:*", "read", 2}, + {2, "system:user:*", "update", 2}, + {2, "system:user:*", "suspend", 2}, + {2, "system:user:*", "unsuspend", 2}, + {2, "system:user:*", "delete", 2}, + {2, "system:role:*", "read", 2}, + {2, "system:role:*", "update", 2}, + {2, "system:role:*", "delete", 2}, + {2, "system:role:*", "members.manage", 2}, + {2, "messaging", "access", 2}, + {2, "messaging", "grant", 2}, + {2, "messaging", "channel.public.create", 2}, + {2, "messaging", "channel.private.create", 2}, + {2, "messaging", "channel.group.create", 2}, + {2, "messaging:channel:*", "update", 2}, + {2, "messaging:channel:*", "leave", 2}, + {2, "messaging:channel:*", "read", 2}, + {2, "messaging:channel:*", "join", 2}, + {2, "messaging:channel:*", "delete", 2}, + {2, "messaging:channel:*", "undelete", 2}, + {2, "messaging:channel:*", "archive", 2}, + {2, "messaging:channel:*", "unarchive", 2}, + {2, "messaging:channel:*", "members.manage", 2}, + {2, "messaging:channel:*", "webhooks.manage", 2}, + {2, "messaging:channel:*", "attachments.manage", 2}, + {2, "messaging:channel:*", "message.attach", 2}, + {2, "messaging:channel:*", "message.update.all", 2}, + {2, "messaging:channel:*", "message.update.own", 2}, + {2, "messaging:channel:*", "message.delete.all", 2}, + {2, "messaging:channel:*", "message.delete.own", 2}, + {2, "messaging:channel:*", "message.embed", 2}, + {2, "messaging:channel:*", "message.send", 2}, + {2, "messaging:channel:*", "message.reply", 2}, + {2, "messaging:channel:*", "message.react", 2}, + {2, "compose:module:*", "read", 2}, + {2, "compose:module:*", "update", 2}, + {2, "compose:module:*", "delete", 2}, + {2, "compose:module:*", "record.create", 2}, + {2, "compose:module:*", "record.read", 2}, + {2, "compose:module:*", "record.update", 2}, + {2, "compose:module:*", "record.delete", 2}, + } + + var purgedRoles = map[uint64]bool{} + for _, r := range rules { + if !purgedRoles[r.RoleID] { + if err = ruleRepo.Delete(r.RoleID); err != nil { + fmt.Printf("could not reset rules: %v", err) + return + } + + purgedRoles[r.RoleID] = true + } + } + + // Recreates rules for core roles + err = ruleRepo.Reset(rules) + + if err != nil { + fmt.Printf("could not reset rules: %v", err) + } } func RoleAssignUser(roleStr string, userStr string) { diff --git a/system/internal/repository/role.go b/system/internal/repository/role.go index c035eddf1..d0bffd653 100644 --- a/system/internal/repository/role.go +++ b/system/internal/repository/role.go @@ -30,8 +30,6 @@ type ( MemberFindByRoleID(roleID uint64) ([]*types.RoleMember, error) MemberAddByID(roleID, userID uint64) error MemberRemoveByID(roleID, userID uint64) error - - Reset() error } role struct { @@ -149,99 +147,3 @@ func (r *role) MemberRemoveByID(roleID, userID uint64) error { } return r.db().Delete(r.members, mod, "rel_role", "rel_user") } - -func (r *role) Reset() error { - sql := `REPLACE INTO sys_role (id, name, handle) VALUES - (1, 'Everyone', 'everyone'), - (2, 'Administrators', 'admins') - ` - _, err := r.db().Exec(sql) - if err != nil { - return err - } - - // Remove all rules for both roles - sql = "DELETE FROM sys_rules WHERE rel_role IN (1, 2)" - if _, err = r.db().Exec(sql); err != nil { - return err - } - - // Value: Allow (2), Deny (1), Inherit(0) - sql = `REPLACE INTO sys_rules (rel_role, resource, operation, value) VALUES - -- Everyone - (1, 'system', 'user.create', 2), - (1, 'compose', 'access', 2), - (1, 'messaging', 'access', 2), - -- Admins - (2, 'compose', 'namespace.create', 2), - (2, 'compose', 'access', 2), - (2, 'compose', 'grant', 2), - (2, 'compose:namespace:*', 'page.create', 2), - (2, 'compose:namespace:*', 'read', 2), - (2, 'compose:namespace:*', 'update', 2), - (2, 'compose:namespace:*', 'delete', 2), - (2, 'compose:namespace:*', 'module.create', 2), - (2, 'compose:namespace:*', 'chart.create', 2), - (2, 'compose:namespace:*', 'trigger.create', 2), - (2, 'compose:chart:*', 'read', 2), - (2, 'compose:chart:*', 'update', 2), - (2, 'compose:chart:*', 'delete', 2), - (2, 'compose:trigger:*', 'read', 2), - (2, 'compose:trigger:*', 'update', 2), - (2, 'compose:trigger:*', 'delete', 2), - (2, 'compose:page:*', 'read', 2), - (2, 'compose:page:*', 'update', 2), - (2, 'compose:page:*', 'delete', 2), - (2, 'system', 'access', 2), - (2, 'system', 'grant', 2), - (2, 'system', 'settings.read', 2), - (2, 'system', 'settings.manage', 2), - (2, 'system', 'organisation.create', 2), - (2, 'system', 'user.create', 2), - (2, 'system', 'role.create', 2), - (2, 'system:organisation:*', 'access', 2), - (2, 'system:user:*', 'read', 2), - (2, 'system:user:*', 'update', 2), - (2, 'system:user:*', 'suspend', 2), - (2, 'system:user:*', 'unsuspend', 2), - (2, 'system:user:*', 'delete', 2), - (2, 'system:role:*', 'read', 2), - (2, 'system:role:*', 'update', 2), - (2, 'system:role:*', 'delete', 2), - (2, 'system:role:*', 'members.manage', 2), - (2, 'messaging', 'access', 2), - (2, 'messaging', 'grant', 2), - (2, 'messaging', 'channel.public.create', 2), - (2, 'messaging', 'channel.private.create', 2), - (2, 'messaging', 'channel.group.create', 2), - (2, 'messaging:channel:*', 'update', 2), - (2, 'messaging:channel:*', 'leave', 2), - (2, 'messaging:channel:*', 'read', 2), - (2, 'messaging:channel:*', 'join', 2), - (2, 'messaging:channel:*', 'delete', 2), - (2, 'messaging:channel:*', 'undelete', 2), - (2, 'messaging:channel:*', 'archive', 2), - (2, 'messaging:channel:*', 'unarchive', 2), - (2, 'messaging:channel:*', 'members.manage', 2), - (2, 'messaging:channel:*', 'webhooks.manage', 2), - (2, 'messaging:channel:*', 'attachments.manage', 2), - (2, 'messaging:channel:*', 'message.attach', 2), - (2, 'messaging:channel:*', 'message.update.all', 2), - (2, 'messaging:channel:*', 'message.update.own', 2), - (2, 'messaging:channel:*', 'message.delete.all', 2), - (2, 'messaging:channel:*', 'message.delete.own', 2), - (2, 'messaging:channel:*', 'message.embed', 2), - (2, 'messaging:channel:*', 'message.send', 2), - (2, 'messaging:channel:*', 'message.reply', 2), - (2, 'messaging:channel:*', 'message.react', 2), - (2, 'compose:module:*', 'read', 2), - (2, 'compose:module:*', 'update', 2), - (2, 'compose:module:*', 'delete', 2), - (2, 'compose:module:*', 'record.create', 2), - (2, 'compose:module:*', 'record.read', 2), - (2, 'compose:module:*', 'record.update', 2), - (2, 'compose:module:*', 'record.delete', 2) - ` - _, err = r.db().Exec(sql) - return err -}