package gnoblog
import (
"chain/runtime"
"errors"
"strings"
"gno.land/p/nt/avl/v0"
"gno.land/p/nt/ufmt/v0"
"gno.land/r/gov/dao"
)
var (
errNotAdmin = errors.New("access restricted: not admin")
errNotModerator = errors.New("access restricted: not moderator")
errNotCommenter = errors.New("access restricted: not commenter")
)
var (
adminAddr = address("g1rp7cmetn27eqlpjpc4vuusf8kaj746tysc0qgh") // govdao t1 multisig
moderatorList = avl.NewTree()
commenterList = avl.NewTree()
inPause bool
)
func AdminSetAdminAddr(_ realm, addr address) {
assertIsAdmin()
adminAddr = addr
}
func AdminSetInPause(_ realm, state bool) {
assertIsAdmin()
inPause = state
}
func AdminAddModerator(_ realm, addr address) {
assertIsAdmin()
moderatorList.Set(addr.String(), true)
}
func AdminRemoveModerator(_ realm, addr address) {
assertIsAdmin()
moderatorList.Set(addr.String(), false) // FIXME: delete instead?
}
func NewPostProposalRequest(_ realm, slug, title, body, publicationDate, authors, tags string) dao.ProposalRequest {
caller := runtime.PreviousRealm().Address()
e := dao.NewSimpleExecutor(
func(realm) error {
addPost(caller, slug, title, body, publicationDate, authors, tags)
return nil
},
ufmt.Sprintf("- Post Title: %v\n- Post Publication Date: %v\n- Authors: %v\n- Tags: %v", title, publicationDate, authors, tags),
)
return dao.NewProposalRequest(
"Add new post to gnoland blog",
"This propoposal is looking to add a new post to gnoland blog",
e,
)
}
func ModAddPost(_ realm, slug, title, body, publicationDate, authors, tags string) {
assertIsModerator()
caller := runtime.OriginCaller()
addPost(caller, slug, title, body, publicationDate, authors, tags)
}
func addPost(caller address, slug, title, body, publicationDate, authors, tags string) {
var tagList []string
if tags != "" {
tagList = strings.Split(tags, ",")
}
var authorList []string
if authors != "" {
authorList = strings.Split(authors, ",")
}
err := b.NewPost(caller, slug, title, body, publicationDate, authorList, tagList)
checkErr(err)
}
func ModEditPost(_ realm, slug, title, body, publicationDate, authors, tags string) {
assertIsModerator()
tagList := strings.Split(tags, ",")
authorList := strings.Split(authors, ",")
err := b.GetPost(slug).Update(title, body, publicationDate, authorList, tagList)
checkErr(err)
}
func ModRemovePost(_ realm, slug string) {
assertIsModerator()
b.RemovePost(slug)
}
func ModAddCommenter(_ realm, addr address) {
assertIsModerator()
commenterList.Set(addr.String(), true)
}
func ModDelCommenter(_ realm, addr address) {
assertIsModerator()
commenterList.Set(addr.String(), false) // FIXME: delete instead?
}
func ModDelComment(_ realm, slug string, index int) {
assertIsModerator()
err := b.GetPost(slug).DeleteComment(index)
checkErr(err)
}
func isAdmin(addr address) bool {
return addr == adminAddr
}
func isModerator(addr address) bool {
_, found := moderatorList.Get(addr.String())
return found
}
func isCommenter(addr address) bool {
_, found := commenterList.Get(addr.String())
return found
}
func assertIsAdmin() {
caller := runtime.OriginCaller()
if !isAdmin(caller) {
panic(errNotAdmin.Error())
}
}
func assertIsModerator() {
caller := runtime.OriginCaller()
if isAdmin(caller) || isModerator(caller) {
return
}
panic(errNotModerator.Error())
}
func assertIsCommenter() {
caller := runtime.OriginCaller()
if isAdmin(caller) || isModerator(caller) || isCommenter(caller) {
return
}
panic(errNotCommenter.Error())
}
func assertNotInPause() {
if inPause {
panic("access restricted (pause)")
}
}