Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(examples): implement r/events, p/authorizable #2372

Merged
merged 72 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
269ec83
rm
leohhhn Jun 17, 2024
a8f05aa
add authorizable, modify ownable, add initial r/events
leohhhn Jun 17, 2024
2147978
Merge branch 'master' into feat/r/events
leohhhn Jun 18, 2024
aa40767
Merge branch 'master' into feat/r/events
leohhhn Jun 18, 2024
22ba744
save events
leohhhn Jun 18, 2024
de5ec06
save
leohhhn Jun 18, 2024
8c3bbf1
Update examples/gno.land/p/demo/ownable/exts/authorizable/authorizabl…
leohhhn Jun 18, 2024
9a9e215
save
leohhhn Jun 18, 2024
f6b809a
save
leohhhn Jun 18, 2024
e66aea8
save
leohhhn Jun 18, 2024
a5c9191
save
leohhhn Jun 18, 2024
7569d08
Merge branch 'master' into feat/r/events
leohhhn Jun 19, 2024
55e4e90
save
leohhhn Jun 19, 2024
f3409e0
Merge branch 'master' into feat/r/events
leohhhn Jun 25, 2024
a55c2e5
Merge branch 'master' into feat/r/events
leohhhn Jun 26, 2024
8a20f6f
add upcoming & past rendering
leohhhn Jun 26, 2024
c47fc12
del func
leohhhn Jun 26, 2024
26104ec
rm
leohhhn Jun 27, 2024
f7513b3
add
leohhhn Jun 27, 2024
9d9140a
del
leohhhn Jun 27, 2024
dd2f4aa
edit func
leohhhn Jun 27, 2024
fb63100
renderHome edit
leohhhn Jun 27, 2024
4993c62
admin page
leohhhn Jun 30, 2024
aa42d70
past evts
leohhhn Jun 30, 2024
ffd686a
comment
leohhhn Jun 30, 2024
dfcd1a1
Merge branch 'master' into feat/r/events
leohhhn Jul 6, 2024
668ccd2
Merge branch 'refs/heads/master' into feat/r/events
leohhhn Jul 13, 2024
bacab7b
play around with gnoweb links
leohhhn Jul 13, 2024
2490a25
Merge branch 'master' into feat/r/events
leohhhn Jul 18, 2024
edf77e1
add endtime, delete admin button
leohhhn Jul 18, 2024
b9cdfbb
add tests
leohhhn Jul 18, 2024
f3d9d8b
update error
leohhhn Jul 18, 2024
8288c1f
tests
leohhhn Jul 18, 2024
a7b4178
mod tidy
leohhhn Jul 18, 2024
9eeeec1
add tests
leohhhn Jul 19, 2024
f481506
add godoc
leohhhn Jul 19, 2024
3dae9f4
edit tests
leohhhn Jul 19, 2024
ed0ada1
update authorizable test
leohhhn Jul 19, 2024
097dc6a
mod tidy and lint
leohhhn Jul 19, 2024
b84b11d
Merge branch 'master' into feat/r/events
leohhhn Jul 19, 2024
ef89f74
update home test
leohhhn Jul 19, 2024
af4a043
a>auth
leohhhn Aug 6, 2024
79cca29
update event var names
leohhhn Aug 6, 2024
11d500d
trimspace
leohhhn Aug 6, 2024
486d21d
flip if case
leohhhn Aug 6, 2024
d89e797
update widget arg
leohhhn Aug 6, 2024
b96bc60
update naming in widget
leohhhn Aug 6, 2024
acb9b14
fix widget
leohhhn Aug 6, 2024
aad4123
typo
leohhhn Aug 6, 2024
555f123
rename index
leohhhn Aug 6, 2024
3245bd0
update authorizable err
leohhhn Aug 6, 2024
6bfd617
update test names
leohhhn Aug 6, 2024
82ae082
update test names v2
leohhhn Aug 6, 2024
0447cc4
split events.gno
leohhhn Aug 6, 2024
fc99cce
Merge branch 'master' into feat/r/events
leohhhn Aug 7, 2024
0852ad2
update home test
leohhhn Aug 7, 2024
2a24cfe
delevent
leohhhn Aug 7, 2024
ecf3b04
replace panic with errors in rendering
leohhhn Aug 8, 2024
c3bb3e9
wip save
leohhhn Aug 8, 2024
be2a6d1
update home
leohhhn Aug 8, 2024
cb92015
update rendering, update errors, remove panics
leohhhn Aug 9, 2024
91bea8b
update widget, rendering, home
leohhhn Aug 9, 2024
5c33eba
help git diff
leohhhn Aug 9, 2024
c6a81f9
add back events folder
leohhhn Aug 9, 2024
815b482
parseTimes, update home, update rendering
leohhhn Aug 9, 2024
3d643f0
update tests, home
leohhhn Aug 9, 2024
9ba3ea6
update tests
leohhhn Aug 9, 2024
61c1de1
Merge branch 'master' into feat/r/events
leohhhn Aug 9, 2024
731cad1
Merge branch 'master' into feat/r/events
leohhhn Aug 10, 2024
647c9b2
update doc
leohhhn Aug 10, 2024
04b0049
update types, update golden tests
leohhhn Aug 11, 2024
335848b
update tests/rendering
leohhhn Aug 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/gno.land/p/demo/ownable/errors.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package ownable
import "errors"

var (
ErrUnauthorized = errors.New("unauthorized; caller is not owner")
ErrInvalidAddress = errors.New("new owner address is invalid")
ErrUnauthorized = errors.New("ownable: caller is not owner")
ErrInvalidAddress = errors.New("ownable: new owner address is invalid")
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Package authorizable is an extension of p/demo/ownable;
// It allows the user to instantiate an Authorizable struct, which extends
// p/demo/ownable with a list of users that are authorized for something.
// By using authorizable, you have a superuser (ownable), as well as another
// authorization level, which can be used for adding moderators or similar to your realm.
package authorizable

import (
"std"

"gno.land/p/demo/avl"
"gno.land/p/demo/ownable"
"gno.land/p/demo/ufmt"
)

type Authorizable struct {
*ownable.Ownable // owner in ownable is superuser
authorized *avl.Tree // std.Addr > struct{}{}
}

func NewAuthorizable() *Authorizable {
deelawn marked this conversation as resolved.
Show resolved Hide resolved
a := &Authorizable{
ownable.New(),
avl.NewTree(),
}

// Add owner to auth list
a.authorized.Set(a.Owner().String(), struct{}{})
return a
}

func NewAuthorizableWithAddress(addr std.Address) *Authorizable {
a := &Authorizable{
ownable.NewWithAddress(addr),
avl.NewTree(),
}

// Add owner to auth list
a.authorized.Set(a.Owner().String(), struct{}{})
return a
}

func (a *Authorizable) AddToAuthList(addr std.Address) error {
leohhhn marked this conversation as resolved.
Show resolved Hide resolved
if err := a.CallerIsOwner(); err != nil {
return ErrNotSuperuser
}

if _, exists := a.authorized.Get(addr.String()); exists {
return ErrAlreadyInList
}

a.authorized.Set(addr.String(), struct{}{})

return nil
}

func (a *Authorizable) DeleteFromAuthList(addr std.Address) error {
if err := a.CallerIsOwner(); err != nil {
return ErrNotSuperuser
}

if !a.authorized.Has(addr.String()) {
return ErrNotInAuthList
}

if _, removed := a.authorized.Remove(addr.String()); !removed {
str := ufmt.Sprintf("authorizable: could not remove %s from auth list", addr.String())
panic(str)
}

return nil
}

func (a Authorizable) CallerOnAuthList() error {
deelawn marked this conversation as resolved.
Show resolved Hide resolved
caller := std.PrevRealm().Addr()

if !a.authorized.Has(caller.String()) {
return ErrNotInAuthList
}

return nil
}

func (a Authorizable) AssertOnAuthList() {
caller := std.PrevRealm().Addr()

if !a.authorized.Has(caller.String()) {
panic(ErrNotInAuthList)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package authorizable

import (
"std"
"testing"

"gno.land/p/demo/testutils"
"gno.land/p/demo/uassert"
)

var (
alice = testutils.TestAddress("alice")
bob = testutils.TestAddress("bob")
charlie = testutils.TestAddress("charlie")
)

func TestNewAuthorizable(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice) // TODO(bug, issue #2371): should not be needed

a := NewAuthorizable()
got := a.Owner()

if alice != got {
t.Fatalf("Expected %s, got: %s", alice, got)
}
}

func TestNewAuthorizableWithAddress(t *testing.T) {
a := NewAuthorizableWithAddress(alice)

got := a.Owner()

if alice != got {
t.Fatalf("Expected %s, got: %s", alice, got)
}
}

func TestCallerOnAuthList(t *testing.T) {
a := NewAuthorizableWithAddress(alice)
std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice)

if err := a.CallerOnAuthList(); err == ErrNotInAuthList {
t.Fatalf("expected alice to be on the list")
}
}

func TestNotCallerOnAuthList(t *testing.T) {
a := NewAuthorizableWithAddress(alice)
std.TestSetRealm(std.NewUserRealm(bob))
std.TestSetOrigCaller(bob)

if err := a.CallerOnAuthList(); err == nil {
t.Fatalf("expected bob to not be on the list")
}
}

func TestAddToAuthList(t *testing.T) {
a := NewAuthorizableWithAddress(alice)
std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice)

if err := a.AddToAuthList(bob); err != nil {
t.Fatalf("Expected no error, got %v", err)
}

std.TestSetRealm(std.NewUserRealm(bob))
std.TestSetOrigCaller(bob)

if err := a.AddToAuthList(bob); err == nil {
t.Fatalf("Expected AddToAuth to error while bob called it, but it didn't")
}
}

func TestDeleteFromList(t *testing.T) {
a := NewAuthorizableWithAddress(alice)
std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice)

if err := a.AddToAuthList(bob); err != nil {
t.Fatalf("Expected no error, got %v", err)
}

if err := a.AddToAuthList(charlie); err != nil {
t.Fatalf("Expected no error, got %v", err)
}

std.TestSetRealm(std.NewUserRealm(bob))
std.TestSetOrigCaller(bob)

// Try an unauthorized deletion
if err := a.DeleteFromAuthList(alice); err == nil {
t.Fatalf("Expected DelFromAuth to error with %v", err)
}

std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice)

if err := a.DeleteFromAuthList(charlie); err != nil {
t.Fatalf("Expected no error, got %v", err)
}
}

func TestAssertOnList(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(alice))
std.TestSetOrigCaller(alice)
a := NewAuthorizableWithAddress(alice)

std.TestSetRealm(std.NewUserRealm(bob))
std.TestSetOrigCaller(bob)

uassert.PanicsWithMessage(t, ErrNotInAuthList.Error(), func() {
a.AssertOnAuthList()
})
}
9 changes: 9 additions & 0 deletions examples/gno.land/p/demo/ownable/exts/authorizable/errors.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package authorizable

import "errors"

var (
ErrNotInAuthList = errors.New("authorizable: caller is not in authorized list")
ErrNotSuperuser = errors.New("authorizable: caller is not superuser")
ErrAlreadyInList = errors.New("authorizable: address is already in authorized list")
)
9 changes: 9 additions & 0 deletions examples/gno.land/p/demo/ownable/exts/authorizable/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module gno.land/p/demo/ownable/exts/authorizable

require (
gno.land/p/demo/avl v0.0.0-latest
gno.land/p/demo/ownable v0.0.0-latest
gno.land/p/demo/testutils v0.0.0-latest
gno.land/p/demo/uassert v0.0.0-latest
gno.land/p/demo/ufmt v0.0.0-latest
)
12 changes: 8 additions & 4 deletions examples/gno.land/p/demo/ownable/ownable.gno
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package ownable

import (
"std"
)
import "std"

const OwnershipTransferEvent = "OwnershipTransfer"

Expand All @@ -19,7 +17,9 @@ func New() *Ownable {
}

func NewWithAddress(addr std.Address) *Ownable {
return &Ownable{owner: addr}
return &Ownable{
owner: addr,
}
}

// TransferOwnership transfers ownership of the Ownable struct to a new address
Expand All @@ -40,6 +40,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error {
"from", string(prevOwner),
"to", string(newOwner),
)

return nil
}

Expand All @@ -64,6 +65,7 @@ func (o *Ownable) DropOwnership() error {
return nil
}

// Owner returns the owner address from Ownable
func (o Ownable) Owner() std.Address {
return o.owner
}
Expand All @@ -73,9 +75,11 @@ func (o Ownable) CallerIsOwner() error {
if std.PrevRealm().Addr() == o.owner {
return nil
}

deelawn marked this conversation as resolved.
Show resolved Hide resolved
return ErrUnauthorized
}

// AssertCallerIsOwner panics if the caller is not the owner
func (o Ownable) AssertCallerIsOwner() {
if std.PrevRealm().Addr() != o.owner {
panic(ErrUnauthorized)
Expand Down
Loading
Loading