admin.gno
3.91 Kb · 160 lines
1package blog
2
3import (
4 "chain/runtime/unsafe"
5 "errors"
6 "strings"
7
8 "gno.land/p/nt/bptree/v0"
9 "gno.land/p/nt/ufmt/v0"
10 "gno.land/r/gov/dao"
11)
12
13var (
14 errNotAdmin = errors.New("access restricted: not admin")
15 errNotModerator = errors.New("access restricted: not moderator")
16 errNotCommenter = errors.New("access restricted: not commenter")
17)
18
19var (
20 adminAddr = address("g1rp7cmetn27eqlpjpc4vuusf8kaj746tysc0qgh") // govdao t1 multisig
21 moderatorList = bptree.NewBPTree32()
22 commenterList = bptree.NewBPTree32()
23 inPause bool
24)
25
26func AdminSetAdminAddr(_ realm, addr address) {
27 assertIsAdmin()
28 adminAddr = addr
29}
30
31func AdminSetInPause(_ realm, state bool) {
32 assertIsAdmin()
33 inPause = state
34}
35
36func AdminAddModerator(_ realm, addr address) {
37 assertIsAdmin()
38 moderatorList.Set(addr.String(), true)
39}
40
41func AdminRemoveModerator(_ realm, addr address) {
42 assertIsAdmin()
43 moderatorList.Set(addr.String(), false) // entry kept as a revocation record; isModerator checks the value
44}
45
46func NewPostProposalRequest(cur realm, slug, title, body, publicationDate, authors, tags string) dao.ProposalRequest {
47 caller := cur.Previous().Address()
48 e := dao.NewSimpleExecutor(0, cur,
49 func(realm) error {
50 addPost(caller, slug, title, body, publicationDate, authors, tags)
51
52 return nil
53 },
54 ufmt.Sprintf("- Post Title: %v\n- Post Publication Date: %v\n- Authors: %v\n- Tags: %v", title, publicationDate, authors, tags),
55 )
56
57 return dao.NewProposalRequest(
58 "Add new post to gnoland blog",
59 "This propoposal is looking to add a new post to gnoland blog",
60 e,
61 )
62}
63
64func ModAddPost(_ realm, slug, title, body, publicationDate, authors, tags string) {
65 assertIsModerator()
66 caller := unsafe.OriginCaller()
67 addPost(caller, slug, title, body, publicationDate, authors, tags)
68}
69
70func addPost(caller address, slug, title, body, publicationDate, authors, tags string) {
71 var tagList []string
72 if tags != "" {
73 tagList = strings.Split(tags, ",")
74 }
75 var authorList []string
76 if authors != "" {
77 authorList = strings.Split(authors, ",")
78 }
79
80 err := b.NewPost(caller, slug, title, body, publicationDate, authorList, tagList)
81
82 checkErr(err)
83}
84
85func ModEditPost(_ realm, slug, title, body, publicationDate, authors, tags string) {
86 assertIsModerator()
87 tagList := strings.Split(tags, ",")
88 authorList := strings.Split(authors, ",")
89
90 err := b.GetPost(slug).Update(title, body, publicationDate, authorList, tagList)
91 checkErr(err)
92}
93
94func ModRemovePost(_ realm, slug string) {
95 assertIsModerator()
96 b.RemovePost(slug)
97}
98
99func ModAddCommenter(_ realm, addr address) {
100 assertIsModerator()
101 commenterList.Set(addr.String(), true)
102}
103
104func ModDelCommenter(_ realm, addr address) {
105 assertIsModerator()
106 commenterList.Set(addr.String(), false) // entry kept as a revocation record; isCommenter checks the value
107}
108
109func ModDelComment(_ realm, slug string, index int) {
110 assertIsModerator()
111 err := b.GetPost(slug).DeleteComment(index)
112 checkErr(err)
113}
114
115func isAdmin(addr address) bool {
116 return addr == adminAddr
117}
118
119func isModerator(addr address) bool {
120 // Removed moderators stay in the list with a false value, so the
121 // stored value must be checked, not just key presence.
122 active, _ := moderatorList.Get(addr.String()).(bool)
123 return active
124}
125
126func isCommenter(addr address) bool {
127 // Removed commenters stay in the list with a false value, so the
128 // stored value must be checked, not just key presence.
129 active, _ := commenterList.Get(addr.String()).(bool)
130 return active
131}
132
133func assertIsAdmin() {
134 caller := unsafe.OriginCaller()
135 if !isAdmin(caller) {
136 panic(errNotAdmin.Error())
137 }
138}
139
140func assertIsModerator() {
141 caller := unsafe.OriginCaller()
142 if isAdmin(caller) || isModerator(caller) {
143 return
144 }
145 panic(errNotModerator.Error())
146}
147
148func assertIsCommenter() {
149 caller := unsafe.OriginCaller()
150 if isAdmin(caller) || isModerator(caller) || isCommenter(caller) {
151 return
152 }
153 panic(errNotCommenter.Error())
154}
155
156func assertNotInPause() {
157 if inPause {
158 panic("access restricted (pause)")
159 }
160}