authtest

package
v0.0.0-...-d3da680 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2024 License: Apache-2.0 Imports: 19 Imported by: 11

Documentation

Overview

Package authtest implements some interfaces used by auth package to simplify unit testing.

Index

Constants

This section is empty.

Variables

View Source
var ErrAuthenticationError = errors.New("authtest: fake Authenticate error")

ErrAuthenticationError is returned by FakeAuth.Authenticate.

Functions

func MockAuthConfig

func MockAuthConfig(ctx context.Context, mocks ...MockedDatum) context.Context

MockAuthConfig configures the auth library for unit tests environment.

You need this *only* if your tests call auth.Authenticate(...) or auth.GetRPCTransport(...). If your tests only check groups or permissions (for example when testing bodies of request handlers), use FakeState instead. See its docs for some examples.

Types

type Condition

type Condition func(realms.Attrs) bool

Condition evaluates attributes passed to HasPermission and decides if the permission should apply.

Used for mocking conditional bindings.

func RestrictAttribute

func RestrictAttribute(attr string, vals ...string) Condition

RestrictAttribute produces a Condition that check the given attribute has any of the given values.

Its logic matches AttributeRestriction condition in the RealmsDB.

type FakeAuth

type FakeAuth struct {
	User    *auth.User   // the user to return in Authenticate or nil for error
	Session auth.Session // the session to return
	Error   error        // an error to return from all methods, if set
}

FakeAuth implements auth.Method's Authenticate by returning predefined user and session.

func (FakeAuth) Authenticate

Authenticate returns predefined User object (if it is not nil) or error.

func (FakeAuth) LoginURL

func (m FakeAuth) LoginURL(ctx context.Context, dest string) (string, error)

LoginURL returns fake login URL.

func (FakeAuth) LogoutURL

func (m FakeAuth) LogoutURL(ctx context.Context, dest string) (string, error)

LogoutURL returns fake logout URL.

type FakeDB

type FakeDB struct {
	// contains filtered or unexported fields
}

FakeDB implements authdb.DB by mocking membership and permission checks.

Initialize it with a bunch of mocks like:

db := authtest.NewFakeDB(

authtest.MockMembership("user:a@example.com", "group"),
authtest.MockPermission("user:a@example.com", "proj:realm", perm),
...

)

The list of mocks can also be extended later via db.AddMocks(...).

func NewFakeDB

func NewFakeDB(mocks ...MockedDatum) *FakeDB

NewFakeDB creates a FakeDB populated with the given mocks.

Construct mocks using MockMembership, MockPermission, MockIPAllowlist and MockError functions.

func (*FakeDB) AddMocks

func (db *FakeDB) AddMocks(mocks ...MockedDatum)

AddMocks applies a bunch of mocks to the state in the db.

func (*FakeDB) AsProvider

func (db *FakeDB) AsProvider() auth.DBProvider

AsProvider returns the current database as an auth.DBProvider.

Here is how you use it:

testServer, err := servertest.RunServer(ctx, &servertest.Settings{
	Options: &server.Options{
		AuthDBProvider: (&authtest.FakeDB{}).AsProvider(),
	},
})

func (*FakeDB) CheckMembership

func (db *FakeDB) CheckMembership(ctx context.Context, id identity.Identity, groups []string) (out []string, err error)

CheckMembership is part of authdb.DB interface.

func (*FakeDB) FilterKnownGroups

func (db *FakeDB) FilterKnownGroups(ctx context.Context, groups []string) ([]string, error)

FilterKnownGroups is part of authdb.DB interface.

func (*FakeDB) GetAllowlistForIdentity

func (db *FakeDB) GetAllowlistForIdentity(ctx context.Context, ident identity.Identity) (string, error)

GetAllowlistForIdentity is part of authdb.DB interface.

func (*FakeDB) GetAuthServiceURL

func (db *FakeDB) GetAuthServiceURL(ctx context.Context) (string, error)

GetAuthServiceURL is part of authdb.DB interface.

func (*FakeDB) GetCertificates

func (db *FakeDB) GetCertificates(ctx context.Context, id identity.Identity) (*signing.PublicCertificates, error)

GetCertificates is part of authdb.DB interface.

func (*FakeDB) GetRealmData

func (db *FakeDB) GetRealmData(ctx context.Context, realm string) (*protocol.RealmData, error)

GetRealmData is part of authdb.DB interface.

func (*FakeDB) GetTokenServiceURL

func (db *FakeDB) GetTokenServiceURL(ctx context.Context) (string, error)

GetTokenServiceURL is part of authdb.DB interface.

func (*FakeDB) HasPermission

func (db *FakeDB) HasPermission(ctx context.Context, id identity.Identity, perm realms.Permission, realm string, attrs realms.Attrs) (bool, error)

HasPermission is part of authdb.DB interface.

func (*FakeDB) IsAllowedIP

func (db *FakeDB) IsAllowedIP(ctx context.Context, ip net.IP, allowlist string) (bool, error)

IsAllowedIP is part of authdb.DB interface.

func (*FakeDB) IsAllowedOAuthClientID

func (db *FakeDB) IsAllowedOAuthClientID(ctx context.Context, email, clientID string) (bool, error)

IsAllowedOAuthClientID is part of authdb.DB interface.

func (*FakeDB) IsInternalService

func (db *FakeDB) IsInternalService(ctx context.Context, hostname string) (bool, error)

IsInternalService is part of authdb.DB interface.

func (*FakeDB) IsMember

func (db *FakeDB) IsMember(ctx context.Context, id identity.Identity, groups []string) (bool, error)

IsMember is part of authdb.DB interface.

func (*FakeDB) QueryRealms

func (db *FakeDB) QueryRealms(ctx context.Context, id identity.Identity, perm realms.Permission, project string, attrs realms.Attrs) ([]string, error)

QueryRealms is part of authdb.DB interface.

func (*FakeDB) Use

func (db *FakeDB) Use(ctx context.Context) context.Context

Use installs the fake db into the context.

Note that if you use auth.WithState(ctx, &authtest.FakeState{...}), you don't need this method. Modify FakeDB in the FakeState instead. See its doc for some examples.

type FakeRequestMetadata

type FakeRequestMetadata struct {
	FakeHeader     http.Header
	FakeCookies    map[string]*http.Cookie
	FakeRemoteAddr string
	FakeHost       string
}

FakeRequestMetadata implements RequestMetadata using fake values.

func NewFakeRequestMetadata

func NewFakeRequestMetadata() *FakeRequestMetadata

NewFakeRequestMetadata constructs an empty FakeRequestMetadata.

func (*FakeRequestMetadata) Cookie

func (r *FakeRequestMetadata) Cookie(key string) (*http.Cookie, error)

Cookie is part of RequestMetadata interface.

func (*FakeRequestMetadata) Header

func (r *FakeRequestMetadata) Header(key string) string

Header is part of RequestMetadata interface.

func (*FakeRequestMetadata) Host

func (r *FakeRequestMetadata) Host() string

Host is part of RequestMetadata interface.

func (*FakeRequestMetadata) RemoteAddr

func (r *FakeRequestMetadata) RemoteAddr() string

RemoteAddr is part of RequestMetadata interface.

type FakeState

type FakeState struct {
	// Identity is main identity associated with the request.
	//
	// identity.AnonymousIdentity if not set.
	Identity identity.Identity

	// IdentityGroups is list of groups the calling identity belongs to.
	IdentityGroups []string

	// IdentityPermissions is a list of (realm, permission) tuples that define
	// caller's permissions.
	IdentityPermissions []RealmPermission

	// PeerIPAllowlist is a list of IP allowlists the caller IP belongs to.
	PeerIPAllowlist []string

	// Error, if not nil, is returned by auth DB checks.
	Error error

	// FakeDB is an authdb.DB implementation to use.
	//
	// If not nil, takes precedence over IdentityGroups, IdentityPermissions,
	// PeerIPAllowlist and Error.
	FakeDB authdb.DB

	// SessionOverride may be set for Session() to return custom value.
	//
	// By default Session() returns nil.
	SessionOverride auth.Session

	// PeerIdentityOverride may be set for PeerIdentity() to return custom value.
	//
	// By default PeerIdentity() returns Identity (i.e. no delegation is
	// happening).
	PeerIdentityOverride identity.Identity

	// PeerIPOverride may be set for PeerIP() to return custom value.
	//
	// By default PeerIP() returns "127.0.0.1".
	PeerIPOverride net.IP

	// UserCredentialsOverride may be set to override UserCredentials().
	//
	// By default UserCredentials() returns ErrNoForwardableCreds error.
	UserCredentialsOverride *oauth2.Token

	// UserExtra is returned as Extra field of User() return value.
	UserExtra any
}

FakeState implements auth.State by returning predefined values.

Inject it into the context when testing handlers that expect an auth state:

ctx = auth.WithState(ctx, &authtest.FakeState{
  Identity: "user:user@example.com",
  IdentityGroups: []string{"admins"},
  IdentityPermissions: []authtest.RealmPermission{
    {"proj:realm1", perm1},
    {"proj:realm1", perm2},
  }
})
auth.IsMember(ctx, "admins") -> returns true.
auth.HasPermission(ctx, perm1, "proj:realm1", nil) -> returns true.

Note that IdentityGroups, IdentityPermissions, PeerIPAllowlist and Error are effective only when FakeDB is nil. They are used as a shortcut to construct the corresponding FakeDB on the fly. If you need to prepare a more complex fake state, pass NewFakeDB(...) as FakeDB instead:

ctx = auth.WithState(ctx, &authtest.FakeState{
  Identity: "user:user@example.com",
  FakeDB: NewFakeDB(
    authtest.MockMembership("user:user@example.com", "group"),
    authtest.MockMembership("user:another@example.com", "group"),
    authtest.MockPermission("user:user@example.com", "proj:realm1", perm1),
    ...
  ),
})

func (*FakeState) Authenticator

func (s *FakeState) Authenticator() *auth.Authenticator

Authenticator is part of State interface.

func (*FakeState) DB

func (s *FakeState) DB() authdb.DB

DB is part of State interface.

func (*FakeState) Method

func (s *FakeState) Method() auth.Method

Method is part of State interface.

func (*FakeState) PeerIP

func (s *FakeState) PeerIP() net.IP

PeerIP is part of State interface.

func (*FakeState) PeerIdentity

func (s *FakeState) PeerIdentity() identity.Identity

PeerIdentity is part of State interface.

func (*FakeState) Session

func (s *FakeState) Session() auth.Session

Session is part of State interface.

func (*FakeState) User

func (s *FakeState) User() *auth.User

User is part of State interface.

func (*FakeState) UserCredentials

func (s *FakeState) UserCredentials() (*oauth2.Token, map[string]string, error)

UserCredentials is part of State interface.

type MockedDatum

type MockedDatum struct {
	// contains filtered or unexported fields
}

MockedDatum is a return value of various Mock* constructors.

func MockError

func MockError(err error) MockedDatum

MockError modifies db to make its methods return this error.

`err` may be nil, in which case the previously mocked error is removed.

func MockGroup

func MockGroup(group string, ids []identity.Identity) MockedDatum

MockGroup adds a group (potentially empty) to the fake DB.

func MockIPAllowlist

func MockIPAllowlist(ip, allowlist string) MockedDatum

MockIPAllowlist modifies db to make IsAllowedIP(ip, allowlist) == true.

Panics if `ip` is not a valid IP address.

func MockMembership

func MockMembership(id identity.Identity, group string) MockedDatum

MockMembership modifies db to make IsMember(id, group) == true.

func MockPermission

func MockPermission(id identity.Identity, realm string, perm realms.Permission, conds ...Condition) MockedDatum

MockPermission modifies db to make HasPermission(id, realm, perm, …) == true.

Panics if `realm` is not a valid globally scoped realm, i.e. it doesn't look like "<project>:<realm>".

Optional `conds` allow mocking conditional bindings by defining a condition on realms.Attrs that must evaluate to true to allow this permission. Multiple `conds` callbacks are AND'ed together to get the final verdict.

func MockRealmData

func MockRealmData(realm string, data *protocol.RealmData) MockedDatum

MockRealmData modifies what db's GetRealmData returns.

Panics if `realm` is not a valid globally scoped realm, i.e. it doesn't look like "<project>:<realm>".

type RealmPermission

type RealmPermission struct {
	Realm      string
	Permission realms.Permission
}

RealmPermission is used to populate IdentityPermissions in FakeState.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL