PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/sys/users

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
users
Namespace
sys
Files
12 (README)(gnomod.toml)
Exported functions
21
Module
gno.land/r/sys/users
gno
0.9

Files (12)

  • README.mdmarkdown
  • gnomod.tomltoml
  • admin.gnogno
  • api.gnogno
  • canonical.gnogno
  • errors.gnogno
  • render.gnogno
  • store.gnogno
  • users.gnogno
  • crossrealm_test.gnogno
  • store_test.gnogno
  • users_test.gnogno
  • crossrealm_test.gnogno
    1package users23import (4	"testing"56	"gno.land/p/nt/testutils/v0"7	"gno.land/p/nt/uassert/v0"8

    Functions

    • AddControllerAtGenesis(interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string)

    • Canonicalize(name string) string

    • Controllers() [].uverse.address

    • GetReadonlyAddrStore() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

    • GetReadOnlyNameStore() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree

    • IsCanonicalTaken(name string) (existing string, taken bool)

    • IsController(addr string) bool

    • IsNameTaken(name string) bool

    • NewErrNotWhitelisted(int, caller interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) struct{Caller string}

    • ProposeControllerAdditionAndRemoval(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, toAdd string, toRemove string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • ProposeControllerRemoval(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • ProposeDeleteUser(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • ProposeNewController(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • ProposeRegisterUser(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, addr string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • ProposeUpdateName(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, addr string, newName string) struct{title string; description string; executor gno.land/r/gov/dao.Executor; filter gno.land/r/gov/dao.Filter}

    • RegisterUser(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, address_XXX string) interface {Error func() string}

    • RegisterUserIgnoreCanonical(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, address_XXX string) interface {Error func() string}

    • Render(string) string

    • ResolveAddress(addr string) *gno.land/r/sys/users.UserData

    • ResolveAny(input string) (*gno.land/r/sys/users.UserData, bool)

    • ResolveName(name string) (data *gno.land/r/sys/users.UserData, isCurrent bool)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    Rendered

    RenderedRawgnoweb ↗

    vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.

    "gno.land/p/nt/urequire/v0"
    9)
    10
    11// TestUpdateNameCallerIdentity verifies that the CurrentRealm() check in
    12// UpdateName correctly identifies the calling controller.
    13//
    14// Background: RegisterUser uses PreviousRealm() because it is a crossing
    15// function (cur realm). UpdateName uses CurrentRealm() because it is a
    16// non-crossing method on *UserData. Per the interrealm spec:
    17//
    18// - Crossing function: CurrentRealm = this realm, PreviousRealm = caller
    19// - Non-crossing method on external object, called from crossing context:
    20// CurrentRealm = caller (unchanged from crossing context)
    21//
    22// This test verifies that a whitelisted controller can call UpdateName,
    23// and a non-whitelisted realm cannot.
    24func TestUpdateNameCallerIdentity(cur realm, t *testing.T) {
    25 controllerPath := initControllerPath
    26 nonControllerPath := "gno.land/r/evil/attacker"
    27
    28 t.Run("whitelisted_controller_can_update", func(cur realm, t *testing.T) {
    29 cleanStore(t)
    30
    31 // Register as whitelisted controller
    32 testing.SetRealm(testing.NewCodeRealm(controllerPath))
    33 urequire.NoError(t, RegisterUser(cross(cur), "testuser1", testutils.TestAddress("testuser1")))
    34
    35 // Resolve and update name — should succeed because controller is whitelisted
    36 data := ResolveAddress(testutils.TestAddress("testuser1"))
    37 urequire.NotEqual(t, nil, data)
    38 uassert.NoError(t, data.UpdateName(0, cur, "newname1"))
    39 uassert.Equal(t, "newname1", data.Name())
    40 })
    41
    42 t.Run("non_whitelisted_realm_cannot_update", func(cur realm, t *testing.T) {
    43 cleanStore(t)
    44
    45 // Register as whitelisted controller
    46 testing.SetRealm(testing.NewCodeRealm(controllerPath))
    47 urequire.NoError(t, RegisterUser(cross(cur), "testuser2", testutils.TestAddress("testuser2")))
    48
    49 data := ResolveAddress(testutils.TestAddress("testuser2"))
    50 urequire.NotEqual(t, nil, data)
    51
    52 // Switch to non-whitelisted realm — UpdateName should fail
    53 testing.SetRealm(testing.NewCodeRealm(nonControllerPath))
    54 err := data.UpdateName(0, cur, "hacked")
    55 uassert.ErrorContains(t, err, "does not exist in whitelist")
    56 uassert.Equal(t, "testuser2", data.Name()) // name unchanged
    57 })
    58}
    59
    60// TestDeleteCallerIdentity verifies the same CurrentRealm() behavior for Delete.
    61func TestDeleteCallerIdentity(cur realm, t *testing.T) {
    62 controllerPath := initControllerPath
    63 nonControllerPath := "gno.land/r/evil/attacker"
    64
    65 t.Run("whitelisted_controller_can_delete", func(cur realm, t *testing.T) {
    66 cleanStore(t)
    67
    68 testing.SetRealm(testing.NewCodeRealm(controllerPath))
    69 urequire.NoError(t, RegisterUser(cross(cur), "deluser1", testutils.TestAddress("deluser1")))
    70
    71 data := ResolveAddress(testutils.TestAddress("deluser1"))
    72 urequire.NotEqual(t, nil, data)
    73 uassert.NoError(t, data.Delete(0, cur))
    74 uassert.True(t, data.IsDeleted())
    75 })
    76
    77 t.Run("non_whitelisted_realm_cannot_delete", func(cur realm, t *testing.T) {
    78 cleanStore(t)
    79
    80 testing.SetRealm(testing.NewCodeRealm(controllerPath))
    81 urequire.NoError(t, RegisterUser(cross(cur), "deluser2", testutils.TestAddress("deluser2")))
    82
    83 data := ResolveAddress(testutils.TestAddress("deluser2"))
    84 urequire.NotEqual(t, nil, data)
    85
    86 // Switch to non-whitelisted realm — Delete should fail
    87 testing.SetRealm(testing.NewCodeRealm(nonControllerPath))
    88 err := data.Delete(0, cur)
    89 uassert.ErrorContains(t, err, "does not exist in whitelist")
    90 uassert.False(t, data.IsDeleted()) // not deleted
    91 })
    92}
    93