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}