package boards2 import ( "chain/banker" "errors" "gno.land/p/gnoland/boards" "gno.land/p/nt/ufmt/v0" ) // validateOpenBoardRename validates PermissionBoardRename. // // Expected `args` values: // 1. Caller address // 2. Board ID // 3. Current board name // 4. New board name func validateOpenBoardRename(_ boards.Permissions, args boards.Args) error { caller, ok := args[0].(address) if !ok { return errors.New("expected a valid caller address") } newName, ok := args[3].(string) if !ok { return errors.New("expected new board name to be a string") } if err := checkBoardNameIsNotAddress(newName); err != nil { return err } if err := checkBoardNameBelongsToAddress(caller, newName); err != nil { return err } return nil } // validateOpenMemberInvite validates PermissionMemberInvite. // // Expected `args` values: // 1. Caller address // 2. Board ID // 3. Invites func validateOpenMemberInvite(perms boards.Permissions, args boards.Args) error { caller, ok := args[0].(address) if !ok { return errors.New("expected a valid caller address") } invites, ok := args[2].([]Invite) if !ok { return errors.New("expected valid user invites") } // Make sure that only owners invite other owners callerIsOwner := perms.HasRole(caller, RoleOwner) for _, v := range invites { if v.Role == RoleOwner && !callerIsOwner { return errors.New("only owners are allowed to invite other owners") } } return nil } // validateOpenRoleChange validates PermissionRoleChange. // // Expected `args` values: // 1. Caller address // 2. Board ID // 3. Member address // 4. Role func validateOpenRoleChange(perms boards.Permissions, args boards.Args) error { caller, ok := args[0].(address) if !ok { return errors.New("expected a valid caller address") } // Owners and Admins can change roles. // Admins should not be able to assign or remove the Owner role from members. if perms.HasRole(caller, RoleAdmin) { role, ok := args[3].(boards.Role) if !ok { return errors.New("expected a valid member role") } if role == RoleOwner { return errors.New("admins are not allowed to promote members to Owner") } else { member, ok := args[2].(address) if !ok { return errors.New("expected a valid member address") } if perms.HasRole(member, RoleOwner) { return errors.New("admins are not allowed to remove the Owner role") } } } return nil } // validateOpenThreadCreate validates PermissionThreadCreate. // // Expected `args` values: // 1. Caller address // 2. Board ID // 3. Thread ID // 4. Title // 5. Body func validateOpenThreadCreate(perms boards.Permissions, args boards.Args) error { caller, ok := args[0].(address) if !ok { return errors.New("expected a valid caller address") } // Owners and admins can create threads without special requirements if perms.HasRole(caller, RoleOwner) || perms.HasRole(caller, RoleAdmin) { return nil } // Require non members to have some GNOT in their accounts if err := checkAccountHasAmount(caller, gOpenAccountAmount); err != nil { return ufmt.Errorf("caller is not allowed to create threads: %s", err) } return nil } // validateOpenReplyCreate validates PermissionReplyCreate. // // Expected `args` values: // 1. Caller address // 2. Board ID // 3. Thread ID // 4. Parent ID // 5. Reply ID // 6. Body func validateOpenReplyCreate(perms boards.Permissions, args boards.Args) error { caller, ok := args[0].(address) if !ok { return errors.New("expected a valid caller address") } // All board members can reply if perms.HasUser(caller) { return nil } // Require non members to have some GNOT in their accounts if err := checkAccountHasAmount(caller, gOpenAccountAmount); err != nil { return ufmt.Errorf("caller is not allowed to comment: %s", err) } return nil } func checkAccountHasAmount(addr address, amount int64) error { bnk := banker.NewBanker(banker.BankerTypeReadonly) coins := bnk.GetCoins(addr) if coins.AmountOf("ugnot") < gOpenAccountAmount { amount = amount / 1_000_000 // ugnot -> GNOT return ufmt.Errorf("account amount is lower than %d GNOT", amount) } return nil }