actions.gno
3.92 Kb · 158 lines
1package basedao
2
3import (
4 "errors"
5 "strings"
6
7 "gno.land/p/moul/md"
8 "gno.land/p/nt/ufmt/v0"
9 "gno.land/p/samcrew/daokit"
10)
11
12// ADD MEMBER
13
14const ActionAddMemberKind = "gno.land/p/samcrew/basedao.AddMember"
15
16type ActionAddMember struct {
17 Address address
18 Roles []string
19}
20
21func (a *ActionAddMember) String() string {
22 s := "Add member " + a.Address.String()
23 if len(a.Roles) != 0 {
24 s += " with roles " + strings.Join(a.Roles, ", ")
25 }
26 return s
27}
28
29func NewAddMemberHandler(dao *DAOPrivate) daokit.ActionHandler {
30 return daokit.NewActionHandler(ActionAddMemberKind, func(ipayload interface{}, _ realm) {
31 payload, ok := ipayload.(*ActionAddMember)
32 if !ok {
33 panic(errors.New("invalid payload type"))
34 }
35 dao.Members.AddMember(payload.Address.String(), payload.Roles)
36 })
37}
38
39func NewAddMemberAction(payload *ActionAddMember) daokit.Action {
40 return daokit.NewAction(ActionAddMemberKind, payload)
41}
42
43// REMOVE MEMBER
44
45const ActionRemoveMemberKind = "gno.land/p/samcrew/basedao.RemoveMember"
46
47func NewRemoveMemberHandler(dao *DAOPrivate) daokit.ActionHandler {
48 return daokit.NewActionHandler(ActionRemoveMemberKind, func(ipayload interface{}, _ realm) {
49 addr, ok := ipayload.(address)
50 if !ok {
51 panic(errors.New("invalid payload type"))
52 }
53 dao.Members.RemoveMember(addr.String())
54 })
55}
56
57func NewRemoveMemberAction(addr address) daokit.Action {
58 return daokit.NewAction(ActionRemoveMemberKind, addr)
59}
60
61// ASSIGN ROLE
62
63const ActionAssignRoleKind = "gno.land/p/samcrew/basedao.AssignRole"
64
65type ActionAssignRole struct {
66 Address address
67 Role string
68}
69
70func (a *ActionAssignRole) String() string {
71 return ufmt.Sprintf("Assign role %q to user %s", a.Role, a.Address)
72}
73
74func NewAssignRoleHandler(dao *DAOPrivate) daokit.ActionHandler {
75 return daokit.NewActionHandler(ActionAssignRoleKind, func(i interface{}, _ realm) {
76 payload, ok := i.(*ActionAssignRole)
77 if !ok {
78 panic(errors.New("invalid payload type"))
79 }
80 dao.Members.AddRoleToMember(payload.Address.String(), payload.Role)
81 })
82}
83
84func NewAssignRoleAction(payload *ActionAssignRole) daokit.Action {
85 return daokit.NewAction(ActionAssignRoleKind, payload)
86}
87
88// UNASSIGN ROLE
89
90const ActionUnassignRoleKind = "gno.land/p/samcrew/basedao.UnassignRole"
91
92type ActionUnassignRole struct {
93 Address address
94 Role string
95}
96
97func (a *ActionUnassignRole) String() string {
98 return ufmt.Sprintf("Remove role %q from user %s", a.Role, a.Address)
99}
100
101func NewUnassignRoleHandler(dao *DAOPrivate) daokit.ActionHandler {
102 return daokit.NewActionHandler(ActionUnassignRoleKind, func(i interface{}, _ realm) {
103 payload, ok := i.(*ActionUnassignRole)
104 if !ok {
105 panic(errors.New("invalid payload type"))
106 }
107 dao.Members.RemoveRoleFromMember(payload.Address.String(), payload.Role)
108 })
109}
110
111func NewUnassignRoleAction(payload *ActionUnassignRole) daokit.Action {
112 return daokit.NewAction(ActionUnassignRoleKind, payload)
113}
114
115// EDIT PROFILE
116
117const ActionEditProfileKind = "gno.land/p/samcrew/basedao.EditProfile"
118
119type ActionEditProfile struct {
120 kv [][2]string
121}
122
123func (a *ActionEditProfile) String() string {
124 elems := []string{}
125 for _, v := range a.kv {
126 elems = append(elems, v[0]+": "+v[1])
127 }
128 return md.BulletList(elems)
129}
130
131func NewEditProfileAction(kv ...[2]string) daokit.Action {
132 return daokit.NewAction(ActionEditProfileKind, &ActionEditProfile{kv: kv})
133}
134
135func NewEditProfileHandler(setter ProfileStringSetter, allowedFields []string) daokit.ActionHandler {
136 return daokit.NewActionHandler(ActionEditProfileKind, func(i interface{}, rlm realm) {
137 action, ok := i.(*ActionEditProfile)
138 if !ok {
139 panic(errors.New("invalid action type"))
140 }
141 for _, elem := range action.kv {
142 k, v := elem[0], elem[1]
143 if len(allowedFields) > 0 && !stringSliceContains(allowedFields, k) {
144 panic(ufmt.Errorf("unauthorized field %q", k))
145 }
146 setter(cross(rlm), k, v)
147 }
148 })
149}
150
151func stringSliceContains(s []string, target string) bool {
152 for _, elem := range s {
153 if elem == target {
154 return true
155 }
156 }
157 return false
158}