public_freeze.gno
3.92 Kb ยท 155 lines
1package boards2
2
3import (
4 "chain"
5 "chain/runtime"
6 "strconv"
7)
8
9// FreezeBoard freezes a board so no more threads and comments can be created or modified.
10func FreezeBoard(_ realm, boardID BoardID) {
11 setBoardReadonly(boardID, true)
12}
13
14// UnfreezeBoard removes frozen status from a board.
15func UnfreezeBoard(_ realm, boardID BoardID) {
16 setBoardReadonly(boardID, false)
17}
18
19// IsBoardFrozen checks if a board has been frozen.
20func IsBoardFrozen(boardID BoardID) bool {
21 board := mustGetBoard(boardID)
22 return board.Readonly
23}
24
25// FreezeThread freezes a thread so thread cannot be replied, modified or deleted.
26//
27// Fails if board is frozen.
28func FreezeThread(_ realm, boardID BoardID, threadID PostID) {
29 setThreadReadonly(boardID, threadID, true)
30}
31
32// UnfreezeThread removes frozen status from a thread.
33//
34// Fails if board is frozen.
35func UnfreezeThread(_ realm, boardID BoardID, threadID PostID) {
36 setThreadReadonly(boardID, threadID, false)
37}
38
39// IsThreadFrozen checks if a thread has been frozen.
40//
41// Returns true if board is frozen.
42func IsThreadFrozen(boardID BoardID, threadID PostID) bool {
43 board := mustGetBoard(boardID)
44 thread := mustGetThread(board, threadID)
45 assertThreadIsVisible(thread)
46
47 return board.Readonly || thread.Readonly
48}
49
50// UnfreezeReply removes frozen status from a reply.
51//
52// Fails when parent thread or board are frozen.
53func UnfreezeReply(_ realm, boardID BoardID, threadID, replyID PostID) {
54 // XXX: Is there a use case for also freezing replies?
55 setReplyReadonly(boardID, threadID, replyID, false)
56}
57
58// FreezeReply freezes a thread reply so it cannot be modified or deleted.
59//
60// Fails when parent thread or board are frozen.
61func FreezeReply(_ realm, boardID BoardID, threadID, replyID PostID) {
62 setReplyReadonly(boardID, threadID, replyID, true)
63}
64
65// IsReplyFrozen checks if a thread reply has been frozen.
66//
67// Returns true when board or a parent thread is frozen.
68func IsReplyFrozen(boardID BoardID, threadID, replyID PostID) bool {
69 board := mustGetBoard(boardID)
70 thread := mustGetThread(board, threadID)
71 assertThreadIsVisible(thread)
72
73 reply := mustGetReply(thread, replyID)
74 assertReplyIsVisible(reply)
75
76 return board.Readonly || thread.Readonly || reply.Readonly
77}
78
79func setReplyReadonly(boardID BoardID, threadID, replyID PostID, isReadonly bool) {
80 assertRealmIsNotLocked()
81
82 board := mustGetBoard(boardID)
83 assertBoardIsNotFrozen(board)
84
85 caller := runtime.PreviousRealm().Address()
86 assertHasPermission(board.perms, caller, PermissionReplyFreeze)
87
88 thread := mustGetThread(board, threadID)
89 assertThreadIsVisible(thread)
90 assertThreadIsNotFrozen(thread)
91
92 reply := mustGetReply(thread, replyID)
93 assertReplyIsVisible(reply)
94
95 if isReadonly {
96 assertReplyIsNotFrozen(reply)
97 }
98
99 reply.Readonly = isReadonly
100
101 chain.Emit(
102 "ReplyFreeze",
103 "caller", caller.String(),
104 "boardID", boardID.String(),
105 "threadID", threadID.String(),
106 "replyID", replyID.String(),
107 "frozen", strconv.FormatBool(isReadonly),
108 )
109}
110
111func setThreadReadonly(boardID BoardID, threadID PostID, isReadonly bool) {
112 assertRealmIsNotLocked()
113
114 board := mustGetBoard(boardID)
115 assertBoardIsNotFrozen(board)
116
117 caller := runtime.PreviousRealm().Address()
118 assertHasPermission(board.perms, caller, PermissionThreadFreeze)
119
120 thread := mustGetThread(board, threadID)
121 if isReadonly {
122 assertThreadIsNotFrozen(thread)
123 }
124
125 thread.Readonly = isReadonly
126
127 chain.Emit(
128 "ThreadFreeze",
129 "caller", caller.String(),
130 "boardID", boardID.String(),
131 "threadID", threadID.String(),
132 "frozen", strconv.FormatBool(isReadonly),
133 )
134}
135
136func setBoardReadonly(boardID BoardID, isReadonly bool) {
137 assertRealmIsNotLocked()
138
139 board := mustGetBoard(boardID)
140 if isReadonly {
141 assertBoardIsNotFrozen(board)
142 }
143
144 caller := runtime.PreviousRealm().Address()
145 assertHasPermission(board.perms, caller, PermissionBoardFreeze)
146
147 board.Readonly = isReadonly
148
149 chain.Emit(
150 "BoardFreeze",
151 "caller", caller.String(),
152 "boardID", boardID.String(),
153 "frozen", strconv.FormatBool(isReadonly),
154 )
155}