Search Apps Documentation Source Content File Folder Download Copy Actions Download

permissions_validators_open.gno

4.04 Kb · 164 lines
  1package boards2
  2
  3import (
  4	"chain/banker"
  5	"errors"
  6
  7	"gno.land/p/gnoland/boards"
  8	"gno.land/p/nt/ufmt/v0"
  9)
 10
 11// validateOpenBoardRename validates PermissionBoardRename.
 12//
 13// Expected `args` values:
 14// 1. Caller address
 15// 2. Board ID
 16// 3. Current board name
 17// 4. New board name
 18func validateOpenBoardRename(_ boards.Permissions, args boards.Args) error {
 19	caller, ok := args[0].(address)
 20	if !ok {
 21		return errors.New("expected a valid caller address")
 22	}
 23
 24	newName, ok := args[3].(string)
 25	if !ok {
 26		return errors.New("expected new board name to be a string")
 27	}
 28
 29	if err := checkBoardNameIsNotAddress(newName); err != nil {
 30		return err
 31	}
 32
 33	if err := checkBoardNameBelongsToAddress(caller, newName); err != nil {
 34		return err
 35	}
 36	return nil
 37}
 38
 39// validateOpenMemberInvite validates PermissionMemberInvite.
 40//
 41// Expected `args` values:
 42// 1. Caller address
 43// 2. Board ID
 44// 3. Invites
 45func validateOpenMemberInvite(perms boards.Permissions, args boards.Args) error {
 46	caller, ok := args[0].(address)
 47	if !ok {
 48		return errors.New("expected a valid caller address")
 49	}
 50
 51	invites, ok := args[2].([]Invite)
 52	if !ok {
 53		return errors.New("expected valid user invites")
 54	}
 55
 56	// Make sure that only owners invite other owners
 57	callerIsOwner := perms.HasRole(caller, RoleOwner)
 58	for _, v := range invites {
 59		if v.Role == RoleOwner && !callerIsOwner {
 60			return errors.New("only owners are allowed to invite other owners")
 61		}
 62	}
 63	return nil
 64}
 65
 66// validateOpenRoleChange validates PermissionRoleChange.
 67//
 68// Expected `args` values:
 69// 1. Caller address
 70// 2. Board ID
 71// 3. Member address
 72// 4. Role
 73func validateOpenRoleChange(perms boards.Permissions, args boards.Args) error {
 74	caller, ok := args[0].(address)
 75	if !ok {
 76		return errors.New("expected a valid caller address")
 77	}
 78
 79	// Owners and Admins can change roles.
 80	// Admins should not be able to assign or remove the Owner role from members.
 81	if perms.HasRole(caller, RoleAdmin) {
 82		role, ok := args[3].(boards.Role)
 83		if !ok {
 84			return errors.New("expected a valid member role")
 85		}
 86
 87		if role == RoleOwner {
 88			return errors.New("admins are not allowed to promote members to Owner")
 89		} else {
 90			member, ok := args[2].(address)
 91			if !ok {
 92				return errors.New("expected a valid member address")
 93			}
 94
 95			if perms.HasRole(member, RoleOwner) {
 96				return errors.New("admins are not allowed to remove the Owner role")
 97			}
 98		}
 99	}
100	return nil
101}
102
103// validateOpenThreadCreate validates PermissionThreadCreate.
104//
105// Expected `args` values:
106// 1. Caller address
107// 2. Board ID
108// 3. Thread ID
109// 4. Title
110// 5. Body
111func validateOpenThreadCreate(perms boards.Permissions, args boards.Args) error {
112	caller, ok := args[0].(address)
113	if !ok {
114		return errors.New("expected a valid caller address")
115	}
116
117	// Owners and admins can create threads without special requirements
118	if perms.HasRole(caller, RoleOwner) || perms.HasRole(caller, RoleAdmin) {
119		return nil
120	}
121
122	// Require non members to have some GNOT in their accounts
123	if err := checkAccountHasAmount(caller, gOpenAccountAmount); err != nil {
124		return ufmt.Errorf("caller is not allowed to create threads: %s", err)
125	}
126	return nil
127}
128
129// validateOpenReplyCreate validates PermissionReplyCreate.
130//
131// Expected `args` values:
132// 1. Caller address
133// 2. Board ID
134// 3. Thread ID
135// 4. Parent ID
136// 5. Reply ID
137// 6. Body
138func validateOpenReplyCreate(perms boards.Permissions, args boards.Args) error {
139	caller, ok := args[0].(address)
140	if !ok {
141		return errors.New("expected a valid caller address")
142	}
143
144	// All board members can reply
145	if perms.HasUser(caller) {
146		return nil
147	}
148
149	// Require non members to have some GNOT in their accounts
150	if err := checkAccountHasAmount(caller, gOpenAccountAmount); err != nil {
151		return ufmt.Errorf("caller is not allowed to comment: %s", err)
152	}
153	return nil
154}
155
156func checkAccountHasAmount(addr address, amount int64) error {
157	bnk := banker.NewBanker(banker.BankerTypeReadonly)
158	coins := bnk.GetCoins(addr)
159	if coins.AmountOf("ugnot") < gOpenAccountAmount {
160		amount = amount / 1_000_000 // ugnot -> GNOT
161		return ufmt.Errorf("account amount is lower than %d GNOT", amount)
162	}
163	return nil
164}