storage

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2017 License: Apache-2.0 Imports: 14 Imported by: 1

README

fosite-storage-mongo

Build Status Coverage Status Go Report Card

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

Lastest Version: v0.2.0

Table of contents

Documentation

We wanted a Fosite/Hydra* storage backend that supported MongoDB. 'Nuf said.

Development

To start hacking:

  • Install glide - A golang package manager
  • Run glide install
  • go build successfully!
Testing

We use go test $(glide novendor) to discover our heinous crimes against coding. For those developing on windows, like ourselves, there is a slight problem with linux based commandline expansion for obvious reasons...

In order to test correctly under windows, neither go test or glide novendor work happily together. For this reason, please run ./test.bat which has been manually created to achieve what glide novendor does.

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/ory/fosite/compose"
	"github.com/ory/fosite/handler/openid"
	"github.com/ory/fosite/token/jwt"
	"github.com/MatthewHartstonge/storage"
	"github.com/pkg/errors"
	"gopkg.in/mgo.v2"
)

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,
)

// 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:  "https://my-client.my-application.com",
			ExpiresAt: time.Now().Add(time.Hour * 6),
			IssuedAt:  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
}

type stackTracer interface {
	StackTrace() errors.StackTrace
}

Disclaimers

  • We haven't tested implementation with Hydra at all, but we implemented on top of fosite which Hydra uses store it's data under the hood.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConnectToMongo

func ConnectToMongo(cfg *Config) (*mgo.Database, error)

ConnectToMongo returns a connection to mongo.

func ConnectionURI

func ConnectionURI(cfg *Config) string

ConnectionURI generates a formatted Mongo Connection URL

Types

type Config

type Config struct {
	// Default connection settings
	Hostname     string
	Hostnames    []string
	Port         uint16 // 0 to 65,535
	DatabaseName string

	// Credential Access
	Username string
	Password string

	// Replica Set
	Replset string

	// Timeout specified in seconds.
	Timeout uint
}

Config provides a way to define the specific pieces that make up a mongo connection

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration for a locally hosted, unauthenticated mongo

type MongoStore

type MongoStore struct {
	// DB is the Mongo connection that holds the base session that can be copied and closed.
	DB       *mgo.Database
	Hasher   fosite.Hasher
	Clients  *client.MongoManager
	Requests *request.MongoManager
	Users    *user.MongoManager
	// Cache Stores
	// - *cache.MemoryManager
	// - *cache.MongoManager
	// - *cache.RedisManager
	Cache *cache.MongoManager
}

MongoStore composes all stores into the one datastore to rule them all

func NewDefaultMongoStore

func NewDefaultMongoStore() (*MongoStore, error)

NewDefaultMongoStore returns a MongoStore configured with the default mongo configuration and default hasher.

func NewExampleMongoStore

func NewExampleMongoStore() *MongoStore

NewExampleMongoStore returns an example mongo store that matches the fosite-example data. If a default unauthenticated mongo database can't be found at localhost:27017, it will panic as you've done it wrong.

func NewMongoStore

func NewMongoStore(cfg *Config, hasher fosite.Hasher) (*MongoStore, error)

NewMongoStore allows for custom mongo configuration and custom hashers.

func (*MongoStore) Authenticate

func (m *MongoStore) Authenticate(ctx context.Context, username string, secret string) error

Authenticate checks if supplied user credentials are valid for User Credentials Grant

func (MongoStore) AuthenticateClient

func (m MongoStore) AuthenticateClient(id string, secret []byte) (*client.Client, error)

AuthenticateClient checks is supplied client credentials are valid

func (*MongoStore) AuthenticateUserByUsername

func (m *MongoStore) AuthenticateUserByUsername(ctx context.Context, username string, secret string) (*user.User, error)

AuthenticateUserByUsername checks if supplied user credentials are valid

func (*MongoStore) Close

func (m *MongoStore) Close()

Close ensures that each endpoint has it's connection closed properly.

func (*MongoStore) CreateAccessTokenSession

func (m *MongoStore) CreateAccessTokenSession(ctx context.Context, signature string, request fosite.Requester) (err error)

CreateAccessTokenSession creates a new session for an Access Token in mongo

func (*MongoStore) CreateAuthorizeCodeSession

func (m *MongoStore) CreateAuthorizeCodeSession(ctx context.Context, code string, request fosite.Requester) (err error)

CreateAuthorizeCodeSession creates a new session for an authorize code grant in mongo

func (*MongoStore) CreateClient

func (m *MongoStore) CreateClient(c *client.Client) error

CreateClient adds a new OAuth2.0 Client to the client store.

func (*MongoStore) CreateImplicitAccessTokenSession

func (m *MongoStore) CreateImplicitAccessTokenSession(ctx context.Context, token string, request fosite.Requester) (err error)

CreateImplicitAccessTokenSession stores an implicit access token based session in mongo

func (*MongoStore) CreateOpenIDConnectSession

func (m *MongoStore) CreateOpenIDConnectSession(ctx context.Context, authorizeCode string, requester fosite.Requester) (err error)

CreateOpenIDConnectSession creates an open id connect session for a given authorize code in mongo. This is relevant for explicit open id connect flow.

func (*MongoStore) CreateRefreshTokenSession

func (m *MongoStore) CreateRefreshTokenSession(ctx context.Context, signature string, request fosite.Requester) (err error)

CreateRefreshTokenSession stores a new Refresh Token Session in mongo

func (*MongoStore) DeleteAccessTokenSession

func (m *MongoStore) DeleteAccessTokenSession(ctx context.Context, signature string) (err error)

DeleteAccessTokenSession removes an Access Tokens current session from mongo

func (*MongoStore) DeleteAuthorizeCodeSession

func (m *MongoStore) DeleteAuthorizeCodeSession(ctx context.Context, code string) (err error)

DeleteAuthorizeCodeSession removes an authorize code session from mongo

func (*MongoStore) DeleteClient

func (m *MongoStore) DeleteClient(id string) error

DeleteClient removes an OAuth 2.0 Client from the client store

func (*MongoStore) DeleteOpenIDConnectSession

func (m *MongoStore) DeleteOpenIDConnectSession(ctx context.Context, authorizeCode string) (err error)

DeleteOpenIDConnectSession removes an open id connect session from mongo.

func (*MongoStore) DeleteRefreshTokenSession

func (m *MongoStore) DeleteRefreshTokenSession(ctx context.Context, signature string) (err error)

DeleteRefreshTokenSession removes a Refresh Token that has been previously stored in mongo

func (MongoStore) GetAccessTokenSession

func (m MongoStore) GetAccessTokenSession(ctx context.Context, signature string, session fosite.Session) (request fosite.Requester, err error)

GetAccessTokenSession returns a session if it can be found by signature in mongo

func (MongoStore) GetAuthorizeCodeSession

func (m MongoStore) GetAuthorizeCodeSession(ctx context.Context, code string, session fosite.Session) (request fosite.Requester, err error)

GetAuthorizeCodeSession finds an authorize code grant session in mongo

func (MongoStore) GetClient

func (m MongoStore) GetClient(ctx context.Context, id string) (fosite.Client, error)

GetClient returns a Client if found by an ID lookup.

func (MongoStore) GetClients

func (m MongoStore) GetClients() (clients map[string]client.Client, err error)

GetClients returns a map of clients mapped by client ID

func (*MongoStore) GetOpenIDConnectSession

func (m *MongoStore) GetOpenIDConnectSession(ctx context.Context, authorizeCode string, requester fosite.Requester) (req fosite.Requester, err error)

GetOpenIDConnectSession gets a session based off the Authorize Code and returns a fosite.Requester which contains a session or an error.

func (*MongoStore) GetRefreshTokenSession

func (m *MongoStore) GetRefreshTokenSession(ctx context.Context, signature string, session fosite.Session) (request fosite.Requester, err error)

GetRefreshTokenSession returns a Refresh Token Session that's been previously stored in mongo

func (*MongoStore) PersistAuthorizeCodeGrantSession

func (m *MongoStore) PersistAuthorizeCodeGrantSession(ctx context.Context, authorizeCode, accessSignature, refreshSignature string, request fosite.Requester) error

PersistAuthorizeCodeGrantSession creates an Authorise Code Grant session in mongo

func (*MongoStore) PersistRefreshTokenGrantSession

func (m *MongoStore) PersistRefreshTokenGrantSession(ctx context.Context, requestRefreshSignature, accessSignature, refreshSignature string, request fosite.Requester) (err error)

PersistRefreshTokenGrantSession stores a refresh token grant session in mongo

func (*MongoStore) RevokeAccessToken

func (m *MongoStore) RevokeAccessToken(ctx context.Context, requestID string) error

RevokeAccessToken finds a token stored in cache based on request ID and deletes the session by signature.

func (*MongoStore) RevokeRefreshToken

func (m *MongoStore) RevokeRefreshToken(ctx context.Context, requestID string) error

RevokeRefreshToken finds a token stored in cache based on request ID and deletes the session by signature.

func (*MongoStore) UpdateClient

func (m *MongoStore) UpdateClient(c *client.Client) error

UpdateClient updates an OAuth 2.0 Client record. This is done using the equivalent of an object replace.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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