From 3c41887bafafe5c763d474abe96adddfb64f2f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jer=C3=B3nimo=20Albi?= Date: Tue, 7 Jan 2025 15:52:06 +0100 Subject: [PATCH] chore(boards2): remove permission handlers (#3449) This approach doesn't make a lot of sense for the current implementation, we can use default permissions methods instead. --- examples/gno.land/r/demo/boards2/board.gno | 4 +- .../r/demo/boards2/permission_default.gno | 84 +++++++++++-------- .../r/demo/boards2/permission_handlers.gno | 38 --------- 3 files changed, 51 insertions(+), 75 deletions(-) delete mode 100644 examples/gno.land/r/demo/boards2/permission_handlers.gno diff --git a/examples/gno.land/r/demo/boards2/board.gno b/examples/gno.land/r/demo/boards2/board.gno index 8b667cb291e..bae551e784e 100644 --- a/examples/gno.land/r/demo/boards2/board.gno +++ b/examples/gno.land/r/demo/boards2/board.gno @@ -132,7 +132,7 @@ func (board *Board) GetPostFormURL() string { // TODO: This is a temporary implementation until the permissions and DAO mecahnics are defined func createDefaultBoardPermissions(owner std.Address) *DefaultPermissions { - perms := NewDefaultPermissions( + return NewDefaultPermissions( admindao.New(admindao.WithMember(owner)), WithSuperRole(RoleOwner), WithRole(RoleAdmin, PermissionMemberInvite), @@ -140,6 +140,4 @@ func createDefaultBoardPermissions(owner std.Address) *DefaultPermissions { // WithRole(RoleModerator, permissions...), WithUser(owner, RoleOwner), ) - perms.HandleFunc(PermissionMemberInvite, handleMemberInvite) - return perms } diff --git a/examples/gno.land/r/demo/boards2/permission_default.gno b/examples/gno.land/r/demo/boards2/permission_default.gno index b4558f82bcc..53c924669ca 100644 --- a/examples/gno.land/r/demo/boards2/permission_default.gno +++ b/examples/gno.land/r/demo/boards2/permission_default.gno @@ -6,32 +6,25 @@ import ( "gno.land/p/demo/avl" "gno.land/p/demo/boards2/admindao" -) -type ( - // PermissionsHandlerFunc defines a function to handle permission callbacks. - // Handlers are called by the `WithPermission()` method to execute callbacks - // when users have the permission assigned. - PermissionsHandlerFunc func(Permissions, Args, func(Args)) - - // DefaultPermissions manages users, roles and permissions. - DefaultPermissions struct { - superRole Role - dao *admindao.AdminDAO - handlers *avl.Tree // string(permission) -> PermissionsHandlerFunc - users *avl.Tree // string(std.Address) -> []Role - roles *avl.Tree // string(role) -> []Permission - } + "gno.land/r/demo/users" ) +// DefaultPermissions manages users, roles and permissions. +type DefaultPermissions struct { + superRole Role + dao *admindao.AdminDAO + users *avl.Tree // string(std.Address) -> []Role + roles *avl.Tree // string(role) -> []Permission +} + // NewDefaultPermissions creates a new permissions type. // This type is a default implementation to handle users, roles and permissions. func NewDefaultPermissions(dao *admindao.AdminDAO, options ...DefaultPermissionsOption) *DefaultPermissions { dp := &DefaultPermissions{ - dao: dao, - handlers: avl.NewTree(), - roles: avl.NewTree(), - users: avl.NewTree(), + dao: dao, + roles: avl.NewTree(), + users: avl.NewTree(), } for _, apply := range options { apply(dp) @@ -124,11 +117,6 @@ func (dp *DefaultPermissions) RemoveUser(user std.Address) bool { return removed } -// HandleFunc registers a handler function for a permission. -func (dp *DefaultPermissions) HandleFunc(p Permission, fn PermissionsHandlerFunc) { - dp.handlers.Set(string(p), fn) -} - // WithPermission calls a callback when a user has a specific permission. // It panics on error or when a handler panics. // Callbacks are by default called when there is no handle registered for the permission. @@ -137,20 +125,51 @@ func (dp *DefaultPermissions) WithPermission(user std.Address, perm Permission, panic("unauthorized") } - h, found := dp.handlers.Get(string(perm)) - if !found { - cb(args) // TODO: Should we fail instead? - return + switch perm { + case PermissionBoardCreate: + dp.handleBoardCreate(args, cb) + case PermissionMemberInvite: + dp.handleMemberInvite(args, cb) + default: + cb(args) + } +} + +func (DefaultPermissions) handleBoardCreate(args Args, cb func(Args)) { + // TODO: This way of dealing with arguments is delicate, ideally types should be used + name := args[0].(string) + if std.Address(name).IsValid() { + panic("addresses are not allowed as board name") + } + + // When the board name is the name of a registered user + // check that caller is the owner of the name. + caller := std.GetOrigCaller() + user := users.GetUserByName(name) + if user != nil && user.Address != caller { + panic("board name is a user name registered to a different user") + } + + cb(args) +} + +func (dp DefaultPermissions) handleMemberInvite(args Args, cb func(Args)) { + // Make sure that only owners invite other owners + role := args[1].(Role) + if role == RoleOwner { + caller := std.GetOrigCaller() + if !dp.HasRole(caller, RoleOwner) { + panic("only owners are allowed to invite other owners") + } } - fn := h.(PermissionsHandlerFunc) - fn(dp, args, cb) + cb(args) } func createDefaultPermissions(owner std.Address) *DefaultPermissions { // TODO: DAO should be a different realm or proposal and voting functions should be part of boards realm? // Permissions and DAO mechanics should be discussed and improved. Add `GetDAO()` to `Permissions`?? - perms := NewDefaultPermissions( + return NewDefaultPermissions( admindao.New(admindao.WithMember(owner)), WithSuperRole(RoleOwner), WithRole(RoleAdmin, PermissionBoardCreate, PermissionMemberInvite), @@ -158,7 +177,4 @@ func createDefaultPermissions(owner std.Address) *DefaultPermissions { // WithRole(RoleModerator, permissions...), WithUser(owner, RoleOwner), ) - perms.HandleFunc(PermissionBoardCreate, handleBoardCreate) - perms.HandleFunc(PermissionMemberInvite, handleMemberInvite) - return perms } diff --git a/examples/gno.land/r/demo/boards2/permission_handlers.gno b/examples/gno.land/r/demo/boards2/permission_handlers.gno deleted file mode 100644 index 63b351f1d53..00000000000 --- a/examples/gno.land/r/demo/boards2/permission_handlers.gno +++ /dev/null @@ -1,38 +0,0 @@ -package boards2 - -import ( - "std" - - "gno.land/r/demo/users" -) - -func handleBoardCreate(_ Permissions, args Args, cb func(Args)) { - // TODO: This way of dealing with arguments is delicate, ideally types should be used - name := args[0].(string) - if std.Address(name).IsValid() { - panic("addresses are not allowed as board name") - } - - // When the board name is the name of a registered user - // check that caller is the owner of the name. - caller := std.GetOrigCaller() - user := users.GetUserByName(name) - if user != nil && user.Address != caller { - panic("board name is a user name registered to a different user") - } - - cb(args) -} - -func handleMemberInvite(p Permissions, args Args, cb func(Args)) { - // Make sure that only owners invite other owners - role := args[1].(Role) - if role == RoleOwner { - caller := std.GetOrigCaller() - if !p.HasRole(caller, RoleOwner) { - panic("only owners are allowed to invite other owners") - } - } - - cb(args) -}