storage

package module
v0.18.6 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2019 License: Apache-2.0 Imports: 13 Imported by: 1

README

fosite-storage-mongo

Coverage Status Go Report Card Build Status FOSSA Status

fosite-storage-mongo provides a native Go based Mongo backed database storage that conforms to all the interfaces! required by fosite.

Table of contents

Compatibility

The following table lists the compatible versions of fosite-storage-mongo with fosite. If you are currently using this in production, it would be awesome to know what versions you are successfully paired with.

storage version minimum fosite version maximum fosite version
v0.18.X v0.27.X v0.30.X
v0.17.X v0.26.X v0.26.X
v0.16.X v0.25.X v0.25.X
v0.15.X v0.23.X v0.24.X
v0.14.X v0.22.X v0.22.X
v0.13.X v0.20.X v0.21.X
v0.12.X v0.11.0 v0.16.X
v0.11.X v0.11.0 v0.16.X

Development

To start hacking:

  • Install dep - A golang package manager
  • Run dep ensure
  • go build successfully!
Testing

Since Go 1.9, we use go test ./... to discover our heinous crimes against coding.

Example

Following the fosite-example/authorizationserver example, we can extend this to add support for Mongo storage via the compose configuration.

package authorizationserver

import (
	"crypto/rand"
	"crypto/rsa"
	"net/http"
	"time"

	"github.com/matthewhartstonge/storage"
	"github.com/ory/fosite/compose"
	"github.com/ory/fosite/handler/openid"
	"github.com/ory/fosite/token/jwt"
)

func RegisterHandlers() {
	// Set up oauth2 endpoints. 
	// You could also use gorilla/mux or any other router.
	http.HandleFunc("/oauth2/auth", authEndpoint)
	http.HandleFunc("/oauth2/token", tokenEndpoint)

	// revoke tokens
	http.HandleFunc("/oauth2/revoke", revokeEndpoint)
	http.HandleFunc("/oauth2/introspect", introspectionEndpoint)
}

// NewExampleMongoStore allows us to create an example Mongo Datastore and 
// panics if you don't have an unauthenticated mongo database that can be found 
// at `localhost:27017`. NewExampleMongoStore has one Client and one User. 
// Check out storage.NewExampleMongoStore() for the implementation/specific 
// client/user details.
var store = storage.NewExampleMongoStore()
var config = new(compose.Config)

// Because we are using oauth2 and open connect id, we use this little helper 
// to combine the two in one variable.
var strat = compose.CommonStrategy{
	// alternatively you could use:
	//  OAuth2Strategy: compose.NewOAuth2JWTStrategy(mustRSAKey())
	CoreStrategy: compose.NewOAuth2HMACStrategy(config, []byte("some-super-cool-secret-that-nobody-knows")),

	// open id connect strategy
	OpenIDConnectTokenStrategy: compose.NewOpenIDConnectStrategy(mustRSAKey()),
}

var oauth2 = compose.Compose(
	config,
	store,
	strat,

	// enabled handlers
	compose.OAuth2AuthorizeExplicitFactory,
	compose.OAuth2AuthorizeImplicitFactory,
	compose.OAuth2ClientCredentialsGrantFactory,
	compose.OAuth2RefreshTokenGrantFactory,
	compose.OAuth2ResourceOwnerPasswordCredentialsFactory,

	compose.OAuth2TokenRevocationFactory,
	compose.OAuth2TokenIntrospectionFactory,

	// Be aware that open id connect factories need to be added after oauth2 
	// factories to work properly.
	compose.OpenIDConnectExplicitFactory,
	compose.OpenIDConnectImplicitFactory,
	compose.OpenIDConnectHybridFactory,
	compose.OpenIDConnectRefreshFactory,
)

// A session is passed from the `/auth` to the `/token` endpoint. You probably 
// want to store data like: "Who made the request", "What organization does 
// that person belong to" and so on.
// For our use case, the session will meet the requirements imposed by JWT 
// access tokens, HMAC access tokens and OpenID Connect ID Tokens plus a custom 
// field.

// newSession is a helper function for creating a new session. This may look 
// like a lot of code but since we are setting up multiple strategies it is a 
// bit longer.
//
// Usually, you could do:
// session = new(fosite.DefaultSession)
//
func newSession(user string) *openid.DefaultSession {
	return &openid.DefaultSession{
		Claims: &jwt.IDTokenClaims{
			Issuer:      "https://fosite.my-application.com",
			Subject:     user,
			Audience:    []string{"https://my-client.my-application.com"},
			ExpiresAt:   time.Now().Add(time.Hour * 6),
			IssuedAt:    time.Now(),
			RequestedAt: time.Now(),
			AuthTime:    time.Now(),
		},
		Headers: &jwt.Headers{
			Extra: make(map[string]interface{}),
		},
	}
}

func mustRSAKey() *rsa.PrivateKey {
	key, err := rsa.GenerateKey(rand.Reader, 1024)
	if err != nil {
		panic(err)
	}
	return key
}

Disclaimer

  • Currently, OIDC clients are not supported.
  • We are currently using this project in house with Storage v0.18.5 and Fosite v0.30.x with good success.
  • My aim is to keep storage to date with Fosite releases, as always though, my time is limited due to my human frame.
  • If you are able to provide help in keeping storage up to date, feel free to raise a github issue and discuss where you are able/willing to help. I'm always happy to review PRs and merge code in 👌
  • We haven't tested implementation with Hydra at all but theoretically this should be compatible as Hydra uses Fosite to store it's data under the hood.

Licensing

storage is under the Apache 2.0 License.

FOSSA Status

Documentation

Index

Constants

View Source
const (
	// EntityOpenIDSessions provides the name of the entity to use in order to
	// create, read, update and delete OpenID Sessions.
	EntityOpenIDSessions = "openIDConnectSessions"

	// EntityAccessTokens provides the name of the entity to use in order to
	// create, read, update and delete Access Token sessions.
	EntityAccessTokens = "accessTokens"

	// EntityRefreshTokens provides the name of the entity to use in order to
	// create, read, update and delete Refresh Token sessions.
	EntityRefreshTokens = "refreshTokens"

	// EntityAuthorizationCodes provides the name of the entity to use in order
	// to create, read, update and delete Authorization Code sessions.
	EntityAuthorizationCodes = "authorizationCodes"

	// EntityPKCESessions provides the name of the entity to use in order to
	// create, read, update and delete Proof Key for Code Exchange sessions.
	EntityPKCESessions = "pkceSessions"

	// EntityClients provides the name of the entity to use in order to create,
	// read, update and delete Clients.
	EntityClients = "clients"

	// EntityUsers provides the name of the entity to use in order to create,
	// read, update and delete Users.
	EntityUsers = "users"

	// EntityCacheAccessTokens provides the name of the entity to use in order
	// to create, read, update and delete Cache Access Tokens.
	EntityCacheAccessTokens = "cacheAccessTokens"

	// EntityCacheRefreshTokens provides the name of the entity to use in
	// order to create, read, update and delete Cache Refresh Tokens.
	EntityCacheRefreshTokens = "cacheRefreshTokens"
)

Variables

View Source
var (
	// ErrResourceExists provides an error for when, in most cases, a record's
	// unique identifier already exists in the system.
	ErrResourceExists = errors.New("resource conflict")
)

Functions

This section is empty.

Types

type AuthClientFunc added in v0.14.0

type AuthClientFunc func() (Client, bool)

AuthClientFunc enables developers to supply their own authentication function, to check old hashes that need to be upgraded for clients.

For example, you may have passwords in MD5 and wanting them to be migrated to fosite's default hasher, bcrypt. Therefore, if you do a mass data migration, the function you supply would have to:

  +- Shortcut logic if the hash string prefix matches what you expect from
		the new hash
  - Get the current client record (return nil, false if not found)
  - Authenticate the current DB secret against MD5
  - Return the Client record and if the client authenticated.
  - if true, the AuthenticateMigration function will upgrade the hash.

type AuthClientMigrator added in v0.14.0

type AuthClientMigrator interface {
	// Migrate is provided solely for the case where you want to migrate clients
	// and push in their old hash. This should perform an upsert, either
	// creating or overwriting the record with the newly provided record.
	// If Client.ID is passed in empty, a new ID will be generated for you.
	// Use with caution, be secure, don't be dumb.
	Migrate(ctx context.Context, migratedClient Client) (Client, error)

	// AuthenticateMigration enables developers to supply your own
	// authentication function, which in turn, if true, will migrate the secret
	// to the hasher implemented within fosite.
	AuthenticateMigration(ctx context.Context, currentAuth AuthClientFunc, clientID string, secret string) (Client, error)
}

AuthClientMigrator provides an interface to enable storage backends to implement functionality to upgrade hashes currently stored in the datastore.

type AuthUserFunc added in v0.14.0

type AuthUserFunc func() (User, bool)

AuthUserFunc enables developers to supply their own authentication function, to check old hashes that need to be upgraded for users.

See AuthClientFunc for example usage.

type AuthUserMigrator added in v0.14.0

type AuthUserMigrator interface {
	// Migrate is provided solely for the case where you want to migrate users
	// and push in their old hash. This should perform an upsert, either
	// creating or overwriting the current record with the newly provided
	// record.
	// If User.ID is passed in empty, a new ID will be generated for you.
	// Use with caution, be secure, don't be dumb.
	Migrate(ctx context.Context, migratedUser User) (User, error)

	// AuthenticateMigration enables developers to supply your own
	// authentication function, which in turn, if true, will migrate the secret
	// to the hasher implemented within fosite.
	AuthenticateMigration(ctx context.Context, currentAuth AuthUserFunc, userID string, password string) (User, error)
}

AuthUserMigrator provides an interface to enable storage backends to implement functionality to upgrade hashes currently stored in the datastore.

type CacheManager added in v0.14.0

type CacheManager interface {
	Configurer
	CacheStorer
}

CacheManager provides a generic interface to key value cache objects in order to build a cache datastore.

type CacheStorer added in v0.14.0

type CacheStorer interface {
	Create(ctx context.Context, entityName string, cacheObject SessionCache) (SessionCache, error)
	Get(ctx context.Context, entityName string, key string) (SessionCache, error)
	Update(ctx context.Context, entityName string, cacheObject SessionCache) (SessionCache, error)
	Delete(ctx context.Context, entityName string, key string) error
	DeleteByValue(ctx context.Context, entityName string, value string) error
}

CacheStorer provides a way to create cache based objects in mongo

type Cacher added in v0.14.0

type Cacher interface {
	Key() string
	Value() string
}

Cacher provides a generic interface for storing data in a cache

type Client added in v0.14.0

type Client struct {
	//// Client Meta
	// ID is the id for this client.
	ID string `bson:"id" json:"id" xml:"id"`

	// createTime is when the resource was created in seconds from the epoch.
	CreateTime int64 `bson:"createTime" json:"createTime" xml:"createTime"`

	// updateTime is the last time the resource was modified in seconds from
	// the epoch.
	UpdateTime int64 `bson:"updateTime" json:"updateTime" xml:"updateTime"`

	// AllowedAudiences contains a list of Audiences that the client has been
	// given rights to access.
	AllowedAudiences []string `bson:"allowedAudiences" json:"allowedAudiences,omitempty" xml:"allowedAudiences,omitempty"`

	// AllowedRegions contains a list of regions that the client has been
	// given permission to access. This enables filtering for clients based on
	// geographic region.
	AllowedRegions []string `bson:"allowedRegions" json:"allowedRegions,omitempty" xml:"allowedRegions,omitempty"`

	// AllowedTenantAccess contains a list of Tenants that the client has been
	// given rights to access.
	AllowedTenantAccess []string `bson:"allowedTenantAccess" json:"allowedTenantAccess,omitempty" xml:"allowedTenantAccess,omitempty"`

	// GrantTypes contains a list of grant types the client is allowed to use.
	//
	// Pattern: client_credentials|authorize_code|implicit|refresh_token
	GrantTypes []string `bson:"grantTypes" json:"grantTypes" xml:"grantTypes"`

	// ResponseTypes contains a list of the OAuth 2.0 response type strings
	// that the client can use at the authorization endpoint.
	//
	// Pattern: id_token|code|token
	ResponseTypes []string `bson:"responseTypes" json:"responseTypes" xml:"responseTypes"`

	// Scopes contains a list of values the client is entitled to use when
	// requesting an access token (as described in Section 3.3 of OAuth 2.0
	// [RFC6749]).
	//
	// Pattern: ([a-zA-Z0-9\.]+\s)+
	Scopes []string `bson:"scopes" json:"scopes" xml:"scopes"`

	// Public is a boolean that identifies this client as public, meaning that
	// it does not have a secret. It will disable the client_credentials grant
	// type for this client if set.
	Public bool `bson:"public" json:"public" xml:"public"`

	// Disabled stops the client from being able to authenticate to the system.
	Disabled bool `bson:"disabled" json:"disabled" xml:"disabled"`

	//// Client Content
	// Name contains a human-readable string name of the client to be presented
	// to the end-user during authorization.
	Name string `bson:"name" json:"name" xml:"name"`

	// Secret is the client's secret. The secret will be included in the create
	// request as cleartext, and then never again. The secret is stored using
	// BCrypt so it is impossible to recover it.
	// Tell your users that they need to remember the client secret as it will
	// not be made available again.
	Secret string `bson:"secret,omitempty" json:"secret,omitempty" xml:"secret,omitempty"`

	// RedirectURIs contains a list of allowed redirect urls for the client, for
	// example: http://mydomain/oauth/callback.
	RedirectURIs []string `bson:"redirectUris" json:"redirectUris" xml:"redirectUris"`

	// Owner identifies the owner of the OAuth 2.0 Client.
	Owner string `bson:"owner" json:"owner" xml:"owner"`

	// PolicyURI allows the application developer to provide a URI string that
	// points to a human-readable privacy policy document that describes how the
	// deployment organization collects, uses, retains, and discloses personal
	// data.
	PolicyURI string `bson:"policyUri" json:"policyUri" xml:"policyUri"`

	// TermsOfServiceURI allows the application developer to provide a URI
	// string that points to a human-readable terms of service document that
	// describes and outlines the contractual relationship between the end-user
	// and the client application that the end-user accepts when authorizing
	// their use of the client.
	TermsOfServiceURI string `bson:"termsOfServiceUri" json:"termsOfServiceUri" xml:"termsOfServiceUri"`

	// ClientURI allows the application developer to provide a URI string that
	// points to a human-readable web page that provides information about the
	// client application.
	// If present, the server SHOULD display this URL to the end-user in a
	// click-able fashion.
	ClientURI string `bson:"clientUri" json:"clientUri" xml:"clientUri"`

	// LogoURI is an URL string that references a logo for the client.
	LogoURI string `bson:"logoUri" json:"logoUri" xml:"logoUri"`

	// Contacts contains a list ways to contact the developers responsible for
	// this OAuth 2.0 client, typically email addresses.
	Contacts []string `bson:"contacts" json:"contacts" xml:"contacts"`

	// Published provides a switch to hide specific clients if not quite ready
	// for the prime time, or if wanting to keep them hidden.
	Published bool `bson:"published" json:"published" xml:"published"`
}

Client provides the structure of an OAuth2.0 Client.

func (*Client) DisableScopeAccess added in v0.14.0

func (c *Client) DisableScopeAccess(scopes ...string)

DisableScopeAccess disables client scope access.

func (*Client) DisableTenantAccess added in v0.14.0

func (c *Client) DisableTenantAccess(tenantIDs ...string)

DisableTenantAccess removes a single or multiple tenantIDs from the given client.

func (*Client) EnableScopeAccess added in v0.14.0

func (c *Client) EnableScopeAccess(scopes ...string)

EnableScopeAccess enables client scope access

func (*Client) EnableTenantAccess added in v0.14.0

func (c *Client) EnableTenantAccess(tenantIDs ...string)

EnableTenantAccess adds a single or multiple tenantIDs to the given client.

func (Client) Equal added in v0.14.0

func (c Client) Equal(x Client) bool

Equal enables checking for client equality.

func (*Client) GetAudience added in v0.18.0

func (c *Client) GetAudience() fosite.Arguments

GetAudience returns the allowed audience(s) for this client.

func (*Client) GetGrantTypes added in v0.14.0

func (c *Client) GetGrantTypes() fosite.Arguments

GetGrantTypes returns an array of strings, wrapped as `fosite.Arguments` to provide functions that allow verifying the Client's Grant Types against incoming requests.

func (*Client) GetHashedSecret added in v0.14.0

func (c *Client) GetHashedSecret() []byte

GetHashedSecret returns the Client's Hashed Secret for authenticating with the Identity Provider.

func (*Client) GetID added in v0.14.0

func (c *Client) GetID() string

GetID returns the client's Client ID.

func (*Client) GetOwner added in v0.14.0

func (c *Client) GetOwner() string

GetOwner returns a string which contains the OAuth Client owner's name. Generally speaking, this will be a developer or an organisation.

func (*Client) GetRedirectURIs added in v0.14.0

func (c *Client) GetRedirectURIs() []string

GetRedirectURIs returns the OAuth2.0 authorized Client redirect URIs.

func (*Client) GetResponseTypes added in v0.14.0

func (c *Client) GetResponseTypes() fosite.Arguments

GetResponseTypes returns an array of strings, wrapped as `fosite.Arguments` to provide functions that allow verifying the Client's Response Types against incoming requests.

func (*Client) GetScopes added in v0.14.0

func (c *Client) GetScopes() fosite.Arguments

GetScopes returns an array of strings, wrapped as `fosite.Arguments` to provide functions that allow verifying the Client's scopes against incoming requests.

func (*Client) IsDisabled added in v0.14.0

func (c *Client) IsDisabled() bool

IsDisabled returns a boolean as to whether the Client itself has had it's access disabled.

func (Client) IsEmpty added in v0.14.0

func (c Client) IsEmpty() bool

IsEmpty returns whether or not the client resource is an empty record.

func (*Client) IsPublic added in v0.14.0

func (c *Client) IsPublic() bool

IsPublic returns a boolean as to whether the Client itself is either private or public. If public, only trusted OAuth grant types should be used as client secrets shouldn't be exposed to a public client.

type ClientManager added in v0.14.0

type ClientManager interface {
	Configurer
	ClientStorer
	AuthClientMigrator
}

ClientManager provides a generic interface to clients in order to build a Datastore backend.

type ClientStorer added in v0.14.0

type ClientStorer interface {
	// fosite.Storage provides get client.
	fosite.Storage

	List(ctx context.Context, filter ListClientsRequest) ([]Client, error)
	Create(ctx context.Context, client Client) (Client, error)
	Get(ctx context.Context, clientID string) (Client, error)
	Update(ctx context.Context, clientID string, client Client) (Client, error)
	Delete(ctx context.Context, clientID string) error

	// Utility Functions
	Authenticate(ctx context.Context, clientID string, secret string) (Client, error)
	GrantScopes(ctx context.Context, clientID string, scopes []string) (Client, error)
	RemoveScopes(ctx context.Context, clientID string, scopes []string) (Client, error)
}

ClientStorer conforms to fosite.Storage and provides methods

type Configurer added in v0.14.0

type Configurer interface {
	// Configure configures the underlying database engine to match
	// requirements.
	// Configure will be called each time a service is started, so ensure this
	// function maintains idempotency.
	// The main use here is to apply creation of tables, collections, schemas
	// any needed migrations and configuration of indexes as required.
	Configure(ctx context.Context) error
}

Configurer enables an implementer to configure required migrations, indexing and is called when the datastore connects.

type ListClientsRequest added in v0.14.0

type ListClientsRequest struct {
	// AllowedTenantAccess filters clients based on an Allowed Tenant Access.
	AllowedTenantAccess string `json:"allowedTenantAccess" xml:"allowedTenantAccess"`
	// AllowedRegion filters clients based on an Allowed Region.
	AllowedRegion string `json:"allowedRegion" xml:"allowedRegion"`
	// RedirectURI filters clients based on redirectURI.
	RedirectURI string `json:"redirectURI" xml:"redirectURI"`
	// GrantType filters clients based on GrantType.
	GrantType string `json:"grantType" xml:"grantType"`
	// ResponseType filters clients based on ResponseType.
	ResponseType string `json:"responseType" xml:"responseType"`
	// ScopesIntersection filters clients that have at least the listed scopes.
	// ScopesIntersection performs an AND operation.
	// For example:
	// - given ["cats"] the client must have "cats" in their scopes.
	// - given ["cats, dogs"] the client must have "cats" AND "dogs in their
	//   scopes.
	//
	// If ScopesUnion is provided, a union operation will be performed as it
	// returns the wider selection.
	ScopesIntersection []string `json:"scopesIntersection" xml:"scopesIntersection"`
	// ScopesUnion filters users that have at least one of the listed scopes.
	// ScopesUnion performs an OR operation.
	// For example:
	// - given ["cats"] the client must have "cats" in their scopes.
	// - given ["cats, dogs"] the client must have "cats" OR "dogs in their
	//   scopes.
	ScopesUnion []string `json:"scopesUnion" xml:"scopesUnion"`
	// Contact filters clients based on Contact.
	Contact string `json:"contact" xml:"contact"`
	// Public filters clients based on Public status.
	Public bool `json:"public" xml:"public"`
	// Disabled filters clients based on denied access.
	Disabled bool `json:"disabled" xml:"disabled"`
	// Published filters clients based on published status.
	Published bool `json:"published" xml:"published"`
}

ListClientsRequest enables listing and filtering client records.

type ListRequestsRequest added in v0.14.0

type ListRequestsRequest struct {
	// ClientID enables filtering requests based on Client ID
	ClientID string `json:"clientId" xml:"clientId"`
	// UserID enables filtering requests based on User ID
	UserID string `json:"userId" xml:"userId"`
	// ScopesIntersection filters clients that have all of the listed scopes.
	// ScopesIntersection performs an AND operation.
	// If ScopesUnion is provided, a union operation will be performed as it
	// returns the wider selection.
	ScopesIntersection []string `json:"scopesIntersection" xml:"scopesIntersection"`
	// ScopesUnion filters users that have at least one of of the listed scopes.
	// ScopesUnion performs an OR operation.
	ScopesUnion []string `json:"scopesUnion" xml:"scopesUnion"`
	// GrantedScopesIntersection enables filtering requests based on GrantedScopes
	// GrantedScopesIntersection performs an AND operation.
	// If GrantedScopesIntersection is provided, a union operation will be
	// performed as it returns the wider selection.
	GrantedScopesIntersection []string `json:"grantedScopesIntersection" xml:"grantedScopesIntersection"`
	// GrantedScopesUnion enables filtering requests based on GrantedScopes
	// GrantedScopesUnion performs an OR operation.
	GrantedScopesUnion []string `json:"grantedScopesUnion" xml:"grantedScopesUnion"`
}

ListRequestsRequest enables filtering stored Request entities.

type ListUsersRequest added in v0.14.0

type ListUsersRequest struct {
	// AllowedTenantAccess filters users based on an Allowed Tenant Access.
	AllowedTenantAccess string `json:"allowedTenantAccess" xml:"allowedTenantAccess"`
	// AllowedPersonAccess filters users based on Allowed Person Access.
	AllowedPersonAccess string `json:"allowedPersonAccess" xml:"allowedPersonAccess"`
	// AllowedPersonAccess filters users based on Person Access.
	PersonID string `json:"personId" xml:"personId"`
	// Username filters users based on username.
	Username string `json:"username" xml:"username"`
	// ScopesUnion filters users that have at least one of of the listed scopes.
	// ScopesUnion performs an OR operation.
	// If ScopesUnion is provided, a union operation will be performed as it
	// returns the wider selection.
	ScopesUnion []string `json:"scopesUnion" xml:"scopesUnion"`
	// ScopesIntersection filters users that have all of the listed scopes.
	// ScopesIntersection performs an AND operation.
	ScopesIntersection []string `json:"scopesIntersection" xml:"scopesIntersection"`
	// FirstName filters users based on their First Name.
	FirstName string `json:"firstName" xml:"firstName"`
	// LastName filters users based on their Last Name.
	LastName string `json:"lastName" xml:"lastName"`
	// Disabled filters users to those with disabled accounts.
	Disabled bool `json:"disabled" xml:"disabled"`
}

ListUsersRequest enables filtering stored User entities.

type Request added in v0.14.0

type Request struct {
	// ID contains the unique request identifier.
	ID string `bson:"id" json:"id" xml:"id"`
	// CreateTime is when the resource was created in seconds from the epoch.
	CreateTime int64 `bson:"createTime" json:"createTime" xml:"createTime"`
	// UpdateTime is the last time the resource was modified in seconds from
	// the epoch.
	UpdateTime int64 `bson:"updateTime" json:"updateTime" xml:"updateTime"`
	// RequestedAt is the time the request was made.
	RequestedAt time.Time `bson:"requestedAt" json:"requestedAt" xml:"requestedAt"`
	// Signature contains a unique session signature.
	Signature string `bson:"signature" json:"signature" xml:"signature"`
	// ClientID contains a link to the Client that was used to authenticate
	// this session.
	ClientID string `bson:"clientId" json:"clientId" xml:"clientId"`
	// UserID contains the subject's unique ID which links back to a stored
	// user account.
	UserID string `bson:"userId" json:"userId" xml:"userId"`
	// Scopes contains the scopes that the user requested.
	RequestedScope fosite.Arguments `bson:"scopes" json:"scopes" xml:"scopes"`
	// GrantedScope contains the list of scopes that the user was actually
	// granted.
	GrantedScope fosite.Arguments `bson:"grantedScopes" json:"grantedScopes" xml:"grantedScopes"`
	// RequestedAudience contains the audience the user requested.
	RequestedAudience fosite.Arguments `bson:"requestedAudience" json:"requestedAudience" xml:"requestedAudience"`
	// GrantedAudience contains the list of audiences the user was actually
	// granted.
	GrantedAudience fosite.Arguments `bson:"grantedAudience" json:"grantedAudience" xml:"grantedAudience"`
	// Form contains the url values that were passed in to authenticate the
	// user's client session.
	Form url.Values `bson:"formData" json:"formData" xml:"formData"`
	// Active is specifically used for Authorize Code flow revocation.
	Active bool `bson:"active" json:"active" xml:"active"`
	// Session contains the session data. The underlying structure differs
	// based on OAuth strategy, so we need to store it as binary-encoded JSON.
	// Otherwise, it can be stored but not unmarshalled back into a
	// fosite.Session.
	Session []byte `bson:"sessionData" json:"sessionData" xml:"sessionData"`
}

Request is a concrete implementation of a fosite.Requester, extended to support the required data for OAuth2 and OpenID.

func NewRequest added in v0.14.0

func NewRequest() Request

NewRequest returns a new Mongo Store request object.

func (*Request) ToRequest added in v0.14.0

func (r *Request) ToRequest(ctx context.Context, session fosite.Session, cm ClientStorer) (*fosite.Request, error)

ToRequest transforms a mongo request to a fosite.Request

type RequestManager added in v0.14.0

type RequestManager interface {
	Configurer
	RequestStorer
}

RequestManager provides an interface in order to build a compliant Fosite storage backend.

type RequestStorer added in v0.14.0

type RequestStorer interface {
	// OAuth2 storage interfaces.
	oauth2.CoreStorage

	// OpenID storage interfaces.
	openid.OpenIDConnectRequestStorage

	// Proof Key for Code Exchange storage interfaces.
	pkce.PKCERequestStorage

	// Implements the rest of oauth2.TokenRevocationStorage
	RevokeRefreshToken(ctx context.Context, requestID string) error
	RevokeAccessToken(ctx context.Context, requestID string) error

	// Implements the rest of oauth2.ResourceOwnerPasswordCredentialsGrantStorage
	Authenticate(ctx context.Context, username string, secret string) error

	// Standard CRUD Storage API
	List(ctx context.Context, entityName string, filter ListRequestsRequest) ([]Request, error)
	Create(ctx context.Context, entityName string, request Request) (Request, error)
	Get(ctx context.Context, entityName string, requestID string) (Request, error)
	Update(ctx context.Context, entityName string, requestID string, request Request) (Request, error)
	Delete(ctx context.Context, entityName string, requestID string) error
	DeleteBySignature(ctx context.Context, entityName string, signature string) error
}

RequestStorer implements all fosite interfaces required to be a storage driver.

type SessionCache added in v0.14.0

type SessionCache struct {
	// ID contains the unique identifier of the request.
	ID string `bson:"id" json:"id" xml:"id"`

	// createTime is when the resource was created in seconds from the epoch.
	CreateTime int64 `bson:"createTime" json:"createTime" xml:"createTime"`

	// updateTime is the last time the resource was modified in seconds from
	// the epoch.
	UpdateTime int64 `bson:"updateTime" json:"updateTime" xml:"updateTime"`

	// Signature contains the unique token signature.
	Signature string `bson:"signature" json:"signature" xml:"signature"`
}

SessionCache allows storing a map between a session ID and a session signature

func (SessionCache) Key added in v0.14.0

func (s SessionCache) Key() string

Key returns the key of the cached session map

func (SessionCache) Value added in v0.14.0

func (s SessionCache) Value() string

Value returns session data as a string

type Store added in v0.14.0

Store brings all the interfaces together as a way to be composable into storage backend implementations

func (*Store) Authenticate added in v0.14.0

func (s *Store) Authenticate(ctx context.Context, username string, secret string) error

Authenticate provides a top level pointer to UserManager to implement fosite.ResourceOwnerPasswordCredentialsGrantStorage at the top level.

You can still access either the RequestManager API, or UserManager API by calling the methods on store direct depending on if you want the User resource returned as well via: - `store.RequestManager.Authenticate(ctx, username, secret) error` - `store.UserManager.Authenticate(ctx, username, secret) (User, error)`

type User added in v0.14.0

type User struct {
	//// User Meta
	// ID is the uniquely assigned uuid that references the user
	ID string `bson:"id" json:"id" xml:"id"`

	// createTime is when the resource was created in seconds from the epoch.
	CreateTime int64 `bson:"createTime" json:"createTime" xml:"createTime"`

	// updateTime is the last time the resource was modified in seconds from
	// the epoch.
	UpdateTime int64 `bson:"updateTime" json:"updateTime" xml:"updateTime"`

	// AllowedTenantAccess contains the Tenant IDs that the user has been given
	// rights to access.
	// This helps in multi-tenanted situations where a user can be given
	// explicit cross-tenant access.
	AllowedTenantAccess []string `bson:"allowedTenantAccess" json:"allowedTenantAccess,omitempty" xml:"allowedTenantAccess,omitempty"`

	// AllowedPersonAccess contains a list of Person IDs that the user is
	// allowed access to.
	// This helps in multi-tenanted situations where a user can be given
	// explicit access to other people accounts, for example, parents to
	// children records.
	AllowedPersonAccess []string `bson:"allowedPersonAccess" json:"allowedPersonAccess,omitempty" xml:"allowedPersonAccess,omitempty"`

	// Scopes contains the permissions that the user is entitled to request.
	Scopes []string `bson:"scopes" json:"scopes" xml:"scopes"`

	// PersonID is a uniquely assigned id that references a person within the
	// system.
	// This enables applications where an external person data store is present.
	// This helps in multi-tenanted situations where the person is unique, but
	// the underlying user accounts can exist per tenant.
	PersonID string `bson:"personId" json:"personId" xml:"personId"`

	// Disabled specifies whether the user has been disallowed from signing in
	Disabled bool `bson:"disabled" json:"disabled" xml:"disabled"`

	//// User Content
	// Username is used to authenticate a user
	Username string `bson:"username" json:"username" xml:"username"`

	// Password of the user - will be a hash based on your fosite selected
	// hasher.
	// If using this model directly in an API, be sure to clear the password
	// out when marshaling to json/xml.
	Password string `bson:"password,omitempty" json:"password,omitempty" xml:"password,omitempty"`

	// FirstName stores the user's Last Name
	FirstName string `bson:"firstName" json:"firstName" xml:"firstName"`

	// LastName stores the user's Last Name
	LastName string `bson:"lastName" json:"lastName" xml:"lastName"`

	// ProfileURI is a pointer to where their profile picture lives
	ProfileURI string `bson:"profileUri" json:"profileUri,omitempty" xml:"profileUri,omitempty"`
}

User provides the specific types for storing, editing, deleting and retrieving a User record in mongo.

func (User) Authenticate added in v0.14.0

func (u User) Authenticate(cleartext string, hasher fosite.Hasher) error

Authenticate compares a cleartext string against the user's

func (*User) DisablePeopleAccess added in v0.14.0

func (u *User) DisablePeopleAccess(personIDs ...string)

DisablePeopleAccess disables user access to the provided people.

func (*User) DisableScopeAccess added in v0.14.0

func (u *User) DisableScopeAccess(scopes ...string)

DisableScopeAccess disables user access to one or many scopes.

func (*User) DisableTenantAccess added in v0.14.0

func (u *User) DisableTenantAccess(tenantIDs ...string)

DisableTenantAccess disables user access to one or many tenants.

func (*User) EnablePeopleAccess added in v0.14.0

func (u *User) EnablePeopleAccess(personIDs ...string)

EnablePeopleAccess enables user access to the provided people

func (*User) EnableScopeAccess added in v0.14.0

func (u *User) EnableScopeAccess(scopes ...string)

EnableScopeAccess enables user access to one or many scopes.

func (*User) EnableTenantAccess added in v0.14.0

func (u *User) EnableTenantAccess(tenantIDs ...string)

EnableTenantAccess enables user access to one or many tenants.

func (User) Equal added in v0.14.0

func (u User) Equal(x User) bool

Equal enables checking equality as having a byte array in a struct stops allowing direct equality checks.

func (User) FullName added in v0.14.0

func (u User) FullName() (fn string)

FullName concatenates the User's First Name and Last Name for templating purposes

func (*User) GetHashedSecret added in v0.14.0

func (u *User) GetHashedSecret() []byte

GetHashedSecret returns the Users's Hashed Secret as a byte array

func (User) IsEmpty added in v0.14.0

func (u User) IsEmpty() bool

IsEmpty returns true if the current user holds no data.

func (*User) SetPassword added in v0.14.0

func (u *User) SetPassword(cleartext string, hasher fosite.Hasher) (err error)

SetPassword takes a cleartext secret, hashes it with a hasher and sets it as the user's password

type UserManager added in v0.14.0

type UserManager interface {
	Configurer
	UserStorer
	AuthUserMigrator
}

UserManager provides a generic interface to users in order to build a DataStore

type UserStorer added in v0.14.0

type UserStorer interface {
	List(ctx context.Context, filter ListUsersRequest) ([]User, error)
	Create(ctx context.Context, user User) (User, error)
	Get(ctx context.Context, userID string) (User, error)
	GetByUsername(ctx context.Context, username string) (User, error)
	Update(ctx context.Context, userID string, user User) (User, error)
	Delete(ctx context.Context, userID string) error

	// Utility Functions
	Authenticate(ctx context.Context, username string, password string) (User, error)
	AuthenticateByID(ctx context.Context, userID string, password string) (User, error)
	AuthenticateByUsername(ctx context.Context, username string, password string) (User, error)
	GrantScopes(ctx context.Context, userID string, scopes []string) (User, error)
	RemoveScopes(ctx context.Context, userID string, scopes []string) (User, error)
}

UserStorer provides a definition of specific methods that are required to store a User in a data store.

type UsersByFirstName added in v0.14.0

type UsersByFirstName []User

UsersByFirstName enables sorting user accounts by First Name A-Z

func (UsersByFirstName) Len added in v0.14.0

func (u UsersByFirstName) Len() int

func (UsersByFirstName) Less added in v0.14.0

func (u UsersByFirstName) Less(i, j int) bool

func (UsersByFirstName) Swap added in v0.14.0

func (u UsersByFirstName) Swap(i, j int)

type UsersByLastName added in v0.14.0

type UsersByLastName []User

UsersByLastName enables sorting user accounts by Last Name A-Z

func (UsersByLastName) Len added in v0.14.0

func (u UsersByLastName) Len() int

func (UsersByLastName) Less added in v0.14.0

func (u UsersByLastName) Less(i, j int) bool

func (UsersByLastName) Swap added in v0.14.0

func (u UsersByLastName) Swap(i, j int)

type UsersByUsername added in v0.14.0

type UsersByUsername []User

UsersByUsername enables sorting user accounts by Username A-Z

func (UsersByUsername) Len added in v0.14.0

func (u UsersByUsername) Len() int

func (UsersByUsername) Less added in v0.14.0

func (u UsersByUsername) Less(i, j int) bool

func (UsersByUsername) Swap added in v0.14.0

func (u UsersByUsername) Swap(i, j int)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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