Skip to content

Commit

Permalink
feat(gno/dao): adapt role manager to receive the caller
Browse files Browse the repository at this point in the history
  • Loading branch information
MikaelVallenet committed Jan 13, 2025
1 parent d4613c9 commit e622fd4
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 73 deletions.
11 changes: 4 additions & 7 deletions gno/p/dao_roles_based/dao_roles_based.gno
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dao_roles_based

import (
"path"
"std"

"gno.land/p/demo/avl"
Expand All @@ -12,17 +13,17 @@ import (
type DaoRolesBased struct {
Name string
Description string
RealmName string

MemberModule *MemberModule
ResourcesModule *ResourcesModule
ProposalModule *ProposalModule
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")
}
Expand All @@ -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()

Expand All @@ -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")
Expand Down Expand Up @@ -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")
Expand Down
8 changes: 5 additions & 3 deletions gno/p/dao_roles_based/members.gno
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}
Expand All @@ -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)
}
}

Expand All @@ -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)
}
}
}
14 changes: 8 additions & 6 deletions gno/p/dao_roles_based/render.gno
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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
})
Expand All @@ -54,15 +56,15 @@ 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
})
if i == 0 {
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) {
Expand Down Expand Up @@ -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
})
Expand Down
12 changes: 8 additions & 4 deletions gno/p/dao_roles_group/roles_group.gno
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 6 additions & 12 deletions gno/p/role_manager/role_manager.gno
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -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")
}
Expand All @@ -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")
}
Expand All @@ -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")
}
Expand All @@ -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")
}
Expand All @@ -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")
}
Expand Down
78 changes: 39 additions & 39 deletions gno/p/role_manager/role_manager_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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")
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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") {
Expand All @@ -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") {
Expand All @@ -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")
Expand All @@ -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")
Expand Down
Loading

0 comments on commit e622fd4

Please sign in to comment.