From e622fd4f6e5a3814e04a1e7edcdbc4df949a863e Mon Sep 17 00:00:00 2001 From: MikaelVallenet Date: Mon, 13 Jan 2025 10:23:40 +0100 Subject: [PATCH] feat(gno/dao): adapt role manager to receive the caller --- gno/p/dao_roles_based/dao_roles_based.gno | 11 ++-- gno/p/dao_roles_based/members.gno | 8 ++- gno/p/dao_roles_based/render.gno | 14 ++-- gno/p/dao_roles_group/roles_group.gno | 12 ++-- gno/p/role_manager/role_manager.gno | 18 ++---- gno/p/role_manager/role_manager_test.gno | 78 +++++++++++------------ gno/r/dao_realm/dao_realm.gno | 9 ++- 7 files changed, 77 insertions(+), 73 deletions(-) diff --git a/gno/p/dao_roles_based/dao_roles_based.gno b/gno/p/dao_roles_based/dao_roles_based.gno index 5003557cb4..dff70f6bd1 100644 --- a/gno/p/dao_roles_based/dao_roles_based.gno +++ b/gno/p/dao_roles_based/dao_roles_based.gno @@ -1,6 +1,7 @@ package dao_roles_based import ( + "path" "std" "gno.land/p/demo/avl" @@ -12,7 +13,6 @@ import ( type DaoRolesBased struct { Name string Description string - RealmName string MemberModule *MemberModule ResourcesModule *ResourcesModule @@ -20,9 +20,10 @@ type DaoRolesBased struct { MessagesRegistry *MessagesRegistry renderingRouter *mux.Router + realmName string } -func NewDaoRolesBasedJSON(name, description, realmName, rolesJSON, membersJSON, resourcesJSON string, handlers []MessageHandler) *DaoRolesBased { +func NewDaoRolesBasedJSON(name, description, rolesJSON, membersJSON, resourcesJSON string, handlers []MessageHandler) *DaoRolesBased { if len(name) < 5 { panic("dao name should be at least 5 characters long") } @@ -34,12 +35,12 @@ func NewDaoRolesBasedJSON(name, description, realmName, rolesJSON, membersJSON, dao := &DaoRolesBased{ Name: name, Description: description, - RealmName: realmName, MemberModule: newMemberModule(), ResourcesModule: newResourcesModule(), ProposalModule: newProposalModule(), MessagesRegistry: newMessagesRegistry(), renderingRouter: mux.NewRouter(), + realmName: path.Base(std.CurrentRealm().PkgPath()), } dao.initRenderingRouter() @@ -56,13 +57,10 @@ func NewDaoRolesBasedJSON(name, description, realmName, rolesJSON, membersJSON, dao.MessagesRegistry.register(handler) } - //TODO: Register name & description into the profile realm - return dao } func (d *DaoRolesBased) Vote(proposalID uint64, vote string) { - // 3th caller is the voter, 2nd is the dao realm, 1st is the dao_roles_based module voter := std.PrevRealm().Addr() if !d.MemberModule.IsMember(voter.String()) { panic("voter is not a member") @@ -92,7 +90,6 @@ func (d *DaoRolesBased) Vote(proposalID uint64, vote string) { } func (d *DaoRolesBased) Execute(proposalID uint64) { - // 3th caller is the executor, 2nd is the dao realm, 1st is the dao_roles_based module executor := std.PrevRealm().Addr() if !d.MemberModule.IsMember(executor.String()) { panic("executor is not a member") diff --git a/gno/p/dao_roles_based/members.gno b/gno/p/dao_roles_based/members.gno index a43d68cdbe..3864756155 100644 --- a/gno/p/dao_roles_based/members.gno +++ b/gno/p/dao_roles_based/members.gno @@ -15,7 +15,7 @@ type MemberModule struct { // TODO: FIX the owner of the role_manager is the deployer of the contract not the realm func newMemberModule() *MemberModule { return &MemberModule{ - roleManager: role_manager.NewWithAddress(std.PrevRealm().Addr()), + roleManager: role_manager.NewWithAddress(std.CurrentRealm().Addr()), members: avl.NewTree(), } } @@ -33,8 +33,9 @@ func (m *MemberModule) MembersCount() uint64 { } func (m *MemberModule) setRoles(roles []string) { + caller := std.CurrentRealm().Addr() for _, role := range roles { - m.roleManager.CreateNewRole(role, []string{}) + m.roleManager.CreateNewRole(role, []string{}, caller) } } @@ -47,10 +48,11 @@ func (m *MemberModule) getUserRoles(memberId string) []string { } func (m *MemberModule) setMembers(members [][]string) { + caller := std.CurrentRealm().Addr() for _, member := range members { m.members.Set(member[0], struct{}{}) for _, role := range member[1:] { - m.roleManager.AddRoleToUser(std.Address(member[0]), role) + m.roleManager.AddRoleToUser(std.Address(member[0]), role, caller) } } } diff --git a/gno/p/dao_roles_based/render.gno b/gno/p/dao_roles_based/render.gno index cfce375c96..d1fbf5521e 100644 --- a/gno/p/dao_roles_based/render.gno +++ b/gno/p/dao_roles_based/render.gno @@ -1,6 +1,8 @@ package dao_roles_based import ( + "std" + "gno.land/p/demo/mux" "gno.land/p/demo/seqid" "gno.land/p/demo/ufmt" @@ -28,14 +30,14 @@ func (d *DaoRolesBased) Render(path string) string { } func (d *DaoRolesBased) renderHomePage(res *mux.ResponseWriter, req *mux.Request) { - res.Write(ufmt.Sprintf("# %s\n\n", d.Name)) + res.Write(ufmt.Sprintf("# %s - %s\n\n", d.Name, std.CurrentRealm().Addr().String())) res.Write(ufmt.Sprintf("> Description: %s\n\n", d.Description)) - res.Write(ufmt.Sprintf("Discover more about this DAO on the [configuration page ⚙️](%s:%s)\n\n", d.RealmName, CONFIG_PATH)) + res.Write(ufmt.Sprintf("Discover more about this DAO on the [configuration page ⚙️](%s:%s)\n\n", d.realmName, CONFIG_PATH)) res.Write(ufmt.Sprintf("## Members 👤 \n\n")) i := 1 d.MemberModule.members.Iterate("", "", func(key string, value interface{}) bool { - res.Write(ufmt.Sprintf("- **Member %d: [%s](%s:%s/%s)**\n\n", i, key, d.RealmName, "member", key)) + res.Write(ufmt.Sprintf("- **Member %d: [%s](%s:%s/%s)**\n\n", i, key, d.realmName, "member", key)) i += 1 return false }) @@ -54,7 +56,7 @@ func (d *DaoRolesBased) renderHomePage(res *mux.ResponseWriter, req *mux.Request if err != nil { panic(err) } - res.Write(ufmt.Sprintf("- **Proposal %d: [%s](%s:%s/%s)**\n\n", uint64(id), proposal.title, d.RealmName, "proposal", key)) + res.Write(ufmt.Sprintf("- **Proposal %d: [%s](%s:%s/%s)**\n\n", uint64(id), proposal.title, d.realmName, "proposal", key)) i += 1 return false }) @@ -62,7 +64,7 @@ func (d *DaoRolesBased) renderHomePage(res *mux.ResponseWriter, req *mux.Request res.Write(ufmt.Sprintf("\t⚠️ There are no running proposals at the moment\n\n")) } - res.Write(ufmt.Sprintf("> See the [proposal history 📜](%s:%s) for more information\n\n", d.RealmName, PROPOSAL_HISTORY_PATH)) + res.Write(ufmt.Sprintf("> See the [proposal history 📜](%s:%s) for more information\n\n", d.realmName, PROPOSAL_HISTORY_PATH)) } func (d *DaoRolesBased) renderConfigPage(res *mux.ResponseWriter, req *mux.Request) { @@ -94,7 +96,7 @@ func (d *DaoRolesBased) renderProposalHistoryPage(res *mux.ResponseWriter, req * if err != nil { panic(err) } - res.Write(ufmt.Sprintf("- **Proposal %d: [%s](%s:%s/%s) - %s**\n\n", uint64(id), proposal.title, d.RealmName, "proposal", key, proposal.status)) + res.Write(ufmt.Sprintf("- **Proposal %d: [%s](%s:%s/%s) - %s**\n\n", uint64(id), proposal.title, d.realmName, "proposal", key, proposal.status)) i += 1 return false }) diff --git a/gno/p/dao_roles_group/roles_group.gno b/gno/p/dao_roles_group/roles_group.gno index 688a2ca12e..aec5c82b6c 100644 --- a/gno/p/dao_roles_group/roles_group.gno +++ b/gno/p/dao_roles_group/roles_group.gno @@ -63,22 +63,26 @@ func (r *RolesGroup) NewRoleJSON(roleName, resourcesJSON string) { } func (r *RolesGroup) NewRole(roleName string, resources []ResourceVPower) { - r.rm.CreateNewRole(roleName, []string{}) + caller := std.PrevRealm().Addr() + r.rm.CreateNewRole(roleName, []string{}, caller) if len(resources) > 0 { r.resourcesVPower.Set(roleName, resources) } } func (r *RolesGroup) DeleteRole(roleName string) { - r.rm.DeleteRole(roleName) + caller := std.PrevRealm().Addr() + r.rm.DeleteRole(roleName, caller) } func (r *RolesGroup) GrantRole(address std.Address, role string) { - r.rm.AddRoleToUser(address, role) + caller := std.PrevRealm().Addr() + r.rm.AddRoleToUser(address, role, caller) } func (r *RolesGroup) RevokeRole(address std.Address, role string) { - r.rm.RemoveRoleFromUser(address, role) + caller := std.PrevRealm().Addr() + r.rm.RemoveRoleFromUser(address, role, caller) } func (r *RolesGroup) GetMemberRoles(address std.Address) []string { diff --git a/gno/p/role_manager/role_manager.gno b/gno/p/role_manager/role_manager.gno index fbee3df6ef..02235a3027 100644 --- a/gno/p/role_manager/role_manager.gno +++ b/gno/p/role_manager/role_manager.gno @@ -38,8 +38,7 @@ func (rm *RoleManager) GetOwner() *ownable.Ownable { return rm.owner } -func (rm *RoleManager) CreateNewRole(roleName string, permissions []string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) CreateNewRole(roleName string, permissions []string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } @@ -61,8 +60,7 @@ func (rm *RoleManager) CreateNewRole(roleName string, permissions []string) { rm.roles.Set(roleName, role) } -func (rm *RoleManager) DeleteRole(roleName string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) DeleteRole(roleName string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } @@ -81,8 +79,7 @@ func (rm *RoleManager) DeleteRole(roleName string) { rm.roles.Remove(roleName) } -func (rm *RoleManager) AddPermissionToRole(permission string, roleName string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) AddPermissionToRole(permission string, roleName string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } @@ -91,8 +88,7 @@ func (rm *RoleManager) AddPermissionToRole(permission string, roleName string) { role.permissions.Set(permission, struct{}{}) } -func (rm *RoleManager) RemovePermissionFromRole(permission string, roleName string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) RemovePermissionFromRole(permission string, roleName string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } @@ -101,8 +97,7 @@ func (rm *RoleManager) RemovePermissionFromRole(permission string, roleName stri role.permissions.Remove(permission) } -func (rm *RoleManager) AddRoleToUser(user std.Address, roleName string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) AddRoleToUser(user std.Address, roleName string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } @@ -117,8 +112,7 @@ func (rm *RoleManager) AddRoleToUser(user std.Address, roleName string) { role.users.Set(user.String(), struct{}{}) } -func (rm *RoleManager) RemoveRoleFromUser(user std.Address, roleName string) { - caller := std.PrevRealm().Addr() +func (rm *RoleManager) RemoveRoleFromUser(user std.Address, roleName string, caller std.Address) { if rm.owner.Owner() != caller && !rm.HasPermission(caller, PermissionWriteRole) { panic("caller does not have permission") } diff --git a/gno/p/role_manager/role_manager_test.gno b/gno/p/role_manager/role_manager_test.gno index d7f6fb1222..5e9608de19 100644 --- a/gno/p/role_manager/role_manager_test.gno +++ b/gno/p/role_manager/role_manager_test.gno @@ -32,8 +32,8 @@ func TestDropOwnership(t *testing.T) { func TestCreateNewRole(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) v, ok := rm.roles.Get("role1") if !ok { @@ -70,12 +70,12 @@ func TestCreateNewRole(t *testing.T) { func TestDeleteRole(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) - rm.AddRoleToUser(alice, "role1") + rm.AddRoleToUser(alice, "role1", alice) - rm.DeleteRole("role1") + rm.DeleteRole("role1", alice) if _, ok := rm.roles.Get("role1"); ok { t.Fatalf("expected role1 to be deleted") @@ -94,9 +94,9 @@ func TestDeleteRole(t *testing.T) { func TestAddPermissionToRole(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.AddPermissionToRole("perm3", "role1") - rm.AddRoleToUser(alice, "role1") + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.AddPermissionToRole("perm3", "role1", alice) + rm.AddRoleToUser(alice, "role1", alice) v, ok := rm.roles.Get("role1") if !ok { @@ -121,11 +121,11 @@ func TestAddPermissionToRole(t *testing.T) { func TestRemovePermissionFromRole(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2", "perm3"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2", "perm3"}, alice) - rm.AddRoleToUser(alice, "role1") + rm.AddRoleToUser(alice, "role1", alice) - rm.RemovePermissionFromRole("perm3", "role1") + rm.RemovePermissionFromRole("perm3", "role1", alice) v, ok := rm.roles.Get("role1") if !ok { @@ -150,15 +150,15 @@ func TestRemovePermissionFromRole(t *testing.T) { func TestAddRoleToUser(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) - rm.CreateNewRole("role3", []string{"perm5", "perm6"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) + rm.CreateNewRole("role3", []string{"perm5", "perm6"}, alice) - rm.AddRoleToUser(alice, "role1") - rm.AddRoleToUser(alice, "role2") - rm.AddRoleToUser(alice, "role3") + rm.AddRoleToUser(alice, "role1", alice) + rm.AddRoleToUser(alice, "role2", alice) + rm.AddRoleToUser(alice, "role3", alice) - rm.RemoveRoleFromUser(alice, "role2") + rm.RemoveRoleFromUser(alice, "role2", alice) aliceRoles := rm.getUser(alice) if !aliceRoles.Has("role1") { @@ -175,16 +175,16 @@ func TestAddRoleToUser(t *testing.T) { func TestRemoveRoleFromUser(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) - rm.CreateNewRole("role3", []string{"perm5", "perm6"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) + rm.CreateNewRole("role3", []string{"perm5", "perm6"}, alice) - rm.AddRoleToUser(alice, "role1") - rm.AddRoleToUser(alice, "role2") - rm.AddRoleToUser(alice, "role3") + rm.AddRoleToUser(alice, "role1", alice) + rm.AddRoleToUser(alice, "role2", alice) + rm.AddRoleToUser(alice, "role3", alice) - rm.RemoveRoleFromUser(alice, "role2") - rm.RemoveRoleFromUser(alice, "role1") + rm.RemoveRoleFromUser(alice, "role2", alice) + rm.RemoveRoleFromUser(alice, "role1", alice) aliceRoles := rm.getUser(alice) if aliceRoles.Has("role1") { @@ -201,13 +201,13 @@ func TestRemoveRoleFromUser(t *testing.T) { func TestHasPermission(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) - rm.CreateNewRole("role3", []string{"perm5", "perm6"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) + rm.CreateNewRole("role3", []string{"perm5", "perm6"}, alice) - rm.AddRoleToUser(alice, "role1") - rm.AddRoleToUser(alice, "role2") - rm.AddRoleToUser(alice, "role3") + rm.AddRoleToUser(alice, "role1", alice) + rm.AddRoleToUser(alice, "role2", alice) + rm.AddRoleToUser(alice, "role3", alice) if !rm.HasPermission(alice, "perm1") { t.Fatalf("expected user to have perm1") @@ -226,13 +226,13 @@ func TestHasPermission(t *testing.T) { func TestHasRole(t *testing.T) { std.TestSetOrigCaller(alice) rm := NewWithAddress(alice) - rm.CreateNewRole("role1", []string{"perm1", "perm2"}) - rm.CreateNewRole("role2", []string{"perm3", "perm4"}) - rm.CreateNewRole("role3", []string{"perm5", "perm6"}) + rm.CreateNewRole("role1", []string{"perm1", "perm2"}, alice) + rm.CreateNewRole("role2", []string{"perm3", "perm4"}, alice) + rm.CreateNewRole("role3", []string{"perm5", "perm6"}, alice) - rm.AddRoleToUser(alice, "role1") - rm.AddRoleToUser(alice, "role2") - rm.AddRoleToUser(alice, "role3") + rm.AddRoleToUser(alice, "role1", alice) + rm.AddRoleToUser(alice, "role2", alice) + rm.AddRoleToUser(alice, "role3", alice) if !rm.HasRole(alice, "role1") { t.Fatalf("expected user to have role1") diff --git a/gno/r/dao_realm/dao_realm.gno b/gno/r/dao_realm/dao_realm.gno index a86ae1773b..12bad43761 100644 --- a/gno/r/dao_realm/dao_realm.gno +++ b/gno/r/dao_realm/dao_realm.gno @@ -2,6 +2,7 @@ package dao_realm import ( "gno.land/p/teritori/dao_roles_based" + "gno.land/r/demo/profile" "gno.land/r/teritori/social_feeds" ) @@ -10,7 +11,6 @@ var dao *dao_roles_based.DaoRolesBased func init() { name := "Demo DAO" description := "This is a demo DAO" - realmName := "dao_realm2" var rolesJSON = `["admin","public-relationships","finance-officer"]` var membersJSON = `[{"address":"g126gx6p6d3da4ymef35ury6874j6kys044r7zlg","roles":["admin","public-relationships"]},{"address":"g1ld6uaykyugld4rnm63rcy7vju4zx23lufml3jv","roles":["public-relationships"]},{"address":"g1r69l0vhp7tqle3a0rk8m8fulr8sjvj4h7n0tth","roles":["finance-officer"]},{"address":"g16jv3rpz7mkt0gqulxas56se2js7v5vmc6n6e0r","roles":[]}]` @@ -31,7 +31,12 @@ func init() { } resourcesJSON += `]` - dao = dao_roles_based.NewDaoRolesBasedJSON(name, description, realmName, rolesJSON, membersJSON, resourcesJSON, messagesHandlers) + dao = dao_roles_based.NewDaoRolesBasedJSON(name, description, rolesJSON, membersJSON, resourcesJSON, messagesHandlers) + + // Register the DAO profile + profile.SetStringField(profile.DisplayName, name) + profile.SetStringField(profile.Bio, description) + profile.SetStringField(profile.Avatar, "") } func ProposeJSON(proposalJSON string) {