boards.gno
3.77 Kb ยท 131 lines
1package boards2
2
3import (
4 "chain/runtime"
5 "strings"
6
7 "gno.land/p/gnoland/boards"
8 "gno.land/p/moul/realmpath"
9 "gno.land/p/moul/txlink"
10 "gno.land/p/nt/avl"
11
12 "gno.land/r/gnoland/boards2/v1/permissions"
13)
14
15// TODO: Refactor globals in favor of a cleaner pattern
16var (
17 gRealmLink txlink.Realm
18 gNotice string
19 gHelp string
20 gListedBoardsByID avl.Tree // string(id) -> *boards.Board
21 gInviteRequests avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
22 gBannedUsers avl.Tree // string(board id) -> *avl.Tree(address -> time.Time)
23 gLocked struct {
24 realm bool
25 realmMembers bool
26 }
27)
28
29var (
30 gBoards = boards.NewStorage()
31 gBoardsSequence = boards.NewIdentifierGenerator()
32 gRealmPath = strings.TrimPrefix(runtime.CurrentRealm().PkgPath(), "gno.land")
33 gPerms = initRealmPermissions(
34 "g16jpf0puufcpcjkph5nxueec8etpcldz7zwgydq", // @devx
35 "g1manfred47kzduec920z88wfr64ylksmdcedlf5", // @moul
36 )
37
38 // TODO: Allow updating open account amount though a proposal (GovDAO, CommonDAO?)
39 gOpenAccountAmount = int64(3_000_000_000) // ugnot required for open board actions
40)
41
42func init() {
43 // Save current realm path so it's available during render calls
44 gRealmLink = txlink.Realm(runtime.CurrentRealm().PkgPath())
45}
46
47// initRealmPermissions returns the default realm permissions.
48func initRealmPermissions(owners ...address) boards.Permissions {
49 perms := permissions.New(
50 permissions.UseSingleUserRole(),
51 permissions.WithSuperRole(permissions.RoleOwner),
52 )
53 perms.AddRole(permissions.RoleAdmin, permissions.PermissionBoardCreate)
54 for _, owner := range owners {
55 perms.SetUserRoles(cross, owner, permissions.RoleOwner)
56 }
57
58 perms.ValidateFunc(permissions.PermissionBoardCreate, validateBasicBoardCreate)
59 perms.ValidateFunc(permissions.PermissionMemberInvite, validateBasicMemberInvite)
60 perms.ValidateFunc(permissions.PermissionRoleChange, validateBasicRoleChange)
61 return perms
62}
63
64// getInvitesRequests returns invite requests for a board.
65func getInviteRequests(boardID boards.ID) (_ *avl.Tree, found bool) {
66 v, exists := gInviteRequests.Get(boardID.Key())
67 if !exists {
68 return nil, false
69 }
70 return v.(*avl.Tree), true
71}
72
73// getBannedUsers returns banned users within a board.
74func getBannedUsers(boardID boards.ID) (_ *avl.Tree, found bool) {
75 v, exists := gBannedUsers.Get(boardID.Key())
76 if !exists {
77 return nil, false
78 }
79 return v.(*avl.Tree), true
80}
81
82// mustGetBoardByName returns a board or panics when it's not found.
83func mustGetBoardByName(name string) *boards.Board {
84 board, found := gBoards.GetByName(name)
85 if !found {
86 panic("board does not exist with name: " + name)
87 }
88 return board
89}
90
91// mustGetBoard returns a board or panics when it's not found.
92func mustGetBoard(id boards.ID) *boards.Board {
93 board, found := gBoards.Get(id)
94 if !found {
95 panic("board does not exist with ID: " + id.String())
96 }
97 return board
98}
99
100// mustGetThread returns a thread or panics when it's not found.
101func mustGetThread(board *boards.Board, threadID boards.ID) *boards.Post {
102 thread, found := board.Threads.Get(threadID)
103 if !found {
104 panic("thread does not exist with ID: " + threadID.String())
105 }
106 return thread
107}
108
109// mustGetReply returns a reply or panics when it's not found.
110func mustGetReply(thread *boards.Post, replyID boards.ID) *boards.Post {
111 reply, found := thread.Replies.Get(replyID)
112 if !found {
113 panic("reply does not exist with ID: " + replyID.String())
114 }
115 return reply
116}
117
118func mustGetPermissions(bid boards.ID) boards.Permissions {
119 if bid != 0 {
120 board := mustGetBoard(bid)
121 return board.Permissions
122 }
123 return gPerms
124}
125
126func parseRealmPath(path string) *realmpath.Request {
127 // Make sure request is using current realm path so paths can be parsed during Render
128 r := realmpath.Parse(path)
129 r.Realm = string(gRealmLink)
130 return r
131}