Skip to content

Commit

Permalink
all: Introduce database backend interface and update plugin system an…
Browse files Browse the repository at this point in the history
…d boostrap accordingly

Signed-off-by: Prateek Malhotra <someone1@gmail.com>
  • Loading branch information
someone1 committed Aug 2, 2018
1 parent c2a9ca4 commit 6dfc8f7
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 224 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
- run: go test -race -short $(go list ./... | grep -v cmd)
- run: ./scripts/test-e2e-jwt.sh
- run: ./scripts/test-e2e-opaque.sh
- run: ./scripts/test-plugin.sh
- run: test -z "$CIRCLE_PR_NUMBER" && goveralls -service=circle-ci -coverprofile=coverage.txt -repotoken=$COVERALLS_REPO_TOKEN || echo "forks are not allowed to push to coveralls"

swagger:
Expand Down
2 changes: 0 additions & 2 deletions cmd/server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ import (

var _ = &consent.Handler{}

var errNilDependency = errors.New("A dependency was expected to be defined but is nil. Please open an issue with the stack trace.")

func RunHost(c *config.Config) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
fmt.Println(banner)
Expand Down
24 changes: 1 addition & 23 deletions cmd/server/handler_client_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,11 @@ import (
"github.com/ory/herodot"
"github.com/ory/hydra/client"
"github.com/ory/hydra/config"
"github.com/ory/sqlcon"
)

func newClientManager(c *config.Config) client.Manager {
ctx := c.Context()

switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
expectDependency(c.GetLogger(), ctx.Hasher)
return client.NewMemoryManager(ctx.Hasher)
case *sqlcon.SQLConnection:
expectDependency(c.GetLogger(), ctx.Hasher, con.GetDatabase())
return &client.SQLManager{
DB: con.GetDatabase(),
Hasher: ctx.Hasher,
}
case *config.PluginConnection:
if m, err := con.NewClientManager(); err != nil {
c.GetLogger().Fatalf("Could not load client manager plugin %s", err)
} else {
return m
}
break
default:
panic("Unknown connection type.")
}
return nil
return ctx.Connection.NewClientManager(ctx.Hasher)
}

func newClientHandler(c *config.Config, router *httprouter.Router, manager client.Manager) *client.Handler {
Expand Down
28 changes: 1 addition & 27 deletions cmd/server/handler_consent_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,11 @@ import (
"github.com/ory/hydra/client"
"github.com/ory/hydra/config"
"github.com/ory/hydra/consent"
"github.com/ory/sqlcon"
)

func injectConsentManager(c *config.Config, cm client.Manager) {
var ctx = c.Context()
var manager consent.Manager

switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
expectDependency(c.GetLogger(), ctx.FositeStore)
manager = consent.NewMemoryManager(ctx.FositeStore)
break
case *sqlcon.SQLConnection:
expectDependency(c.GetLogger(), ctx.FositeStore, con.GetDatabase())
manager = consent.NewSQLManager(
con.GetDatabase(),
cm,
ctx.FositeStore,
)
break
case *config.PluginConnection:
var err error
if manager, err = con.NewConsentManager(); err != nil {
c.GetLogger().Fatalf("Could not load client manager plugin %s", err)
}
break
default:
panic("Unknown connection type.")
}

ctx.ConsentManager = manager
ctx.ConsentManager = ctx.Connection.NewConsentManager(cm, ctx.FositeStore)
}

func newConsentHandler(c *config.Config, router *httprouter.Router) *consent.Handler {
Expand Down
24 changes: 1 addition & 23 deletions cmd/server/handler_health_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,11 @@ import (
"github.com/ory/herodot"
"github.com/ory/hydra/config"
"github.com/ory/hydra/health"
"github.com/ory/sqlcon"
)

func newHealthHandler(c *config.Config, router *httprouter.Router) *health.Handler {
ctx := c.Context()
var rc health.ReadyChecker

switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
rc = func() error {
return nil
}
break
case *sqlcon.SQLConnection:
expectDependency(c.GetLogger(), con.GetDatabase())
rc = func() error {
return con.GetDatabase().Ping()
}
break
case *config.PluginConnection:
rc = func() error {
return con.Ping()
}
break
default:
panic("Unknown connection type.")
}
var rc health.ReadyChecker = ctx.Connection.Ping

w := herodot.NewJSONWriter(c.GetLogger())
w.ErrorEnhancer = writerErrorEnhancer
Expand Down
27 changes: 3 additions & 24 deletions cmd/server/handler_jwk_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,14 @@ import (
"github.com/ory/hydra/config"
"github.com/ory/hydra/jwk"
"github.com/ory/hydra/oauth2"
"github.com/ory/sqlcon"
)

func injectJWKManager(c *config.Config) {
ctx := c.Context()

switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
ctx.KeyManager = &jwk.MemoryManager{}
break
case *sqlcon.SQLConnection:
expectDependency(c.GetLogger(), con.GetDatabase())
ctx.KeyManager = &jwk.SQLManager{
DB: con.GetDatabase(),
Cipher: &jwk.AEAD{
Key: c.GetSystemSecret(),
},
}
break
case *config.PluginConnection:
var err error
ctx.KeyManager, err = con.NewJWKManager()
if err != nil {
c.GetLogger().Fatalf("Could not load client manager plugin %s", err)
}
break
default:
c.GetLogger().Fatalf("Unknown connection type.")
}
ctx.KeyManager = ctx.Connection.NewJWKManager(&jwk.AEAD{
Key: c.GetSystemSecret(),
})
}

func newJWKHandler(c *config.Config, router *httprouter.Router) *jwk.Handler {
Expand Down
23 changes: 1 addition & 22 deletions cmd/server/handler_oauth2_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,12 @@ import (
"github.com/ory/hydra/jwk"
"github.com/ory/hydra/oauth2"
"github.com/ory/hydra/pkg"
"github.com/ory/sqlcon"
"github.com/pborman/uuid"
)

func injectFositeStore(c *config.Config, clients client.Manager) {
var ctx = c.Context()
var store pkg.FositeStorer

switch con := ctx.Connection.(type) {
case *config.MemoryConnection:
store = oauth2.NewFositeMemoryStore(clients, c.GetAccessTokenLifespan())
break
case *sqlcon.SQLConnection:
expectDependency(c.GetLogger(), con.GetDatabase())
store = oauth2.NewFositeSQLStore(clients, con.GetDatabase(), c.GetLogger(), c.GetAccessTokenLifespan(), c.OAuth2AccessTokenStrategy == "jwt")
break
case *config.PluginConnection:
var err error
if store, err = con.NewOAuth2Manager(clients); err != nil {
c.GetLogger().Fatalf("Could not load client manager plugin %s", err)
}
break
default:
panic("Unknown connection type.")
}

ctx.FositeStore = store
ctx.FositeStore = ctx.Connection.NewOAuth2Manager(clients, c.GetAccessTokenLifespan(), c.OAuth2AccessTokenStrategy)
}

func newOAuth2Provider(c *config.Config) fosite.OAuth2Provider {
Expand Down
2 changes: 2 additions & 0 deletions cmd/server/helper_deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"github.com/sirupsen/logrus"
)

var errNilDependency = errors.New("A dependency was expected to be defined but is nil. Please open an issue with the stack trace.")

func expectDependency(logger logrus.FieldLogger, dependencies ...interface{}) {
for _, d := range dependencies {
if d == nil {
Expand Down
80 changes: 80 additions & 0 deletions config/backend_connector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright © 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author Aeneas Rekkas <aeneas+oss@aeneas.io>
* @copyright 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
* @license Apache-2.0
*/

package config

import (
"sync"
"time"

"github.com/pkg/errors"
"github.com/sirupsen/logrus"

"github.com/ory/fosite"
"github.com/ory/hydra/client"
"github.com/ory/hydra/consent"
"github.com/ory/hydra/jwk"
"github.com/ory/hydra/pkg"
)

var (
backends = make(map[string]BackendConnector)
bmutex sync.Mutex
errNilDependency = errors.New("A dependency was expected to be defined but is nil. Please open an issue with the stack trace.")
)

type BackendConnector interface {
Init(url string, l logrus.FieldLogger) error
NewConsentManager(clientManager client.Manager, fs pkg.FositeStorer) consent.Manager
NewOAuth2Manager(clientManager client.Manager, accessTokenLifespan time.Duration, tokenStrategy string) pkg.FositeStorer
NewClientManager(hasher fosite.Hasher) client.Manager
NewJWKManager(cipher *jwk.AEAD) jwk.Manager
Ping() error
Prefixes() []string
}

func RegisterBackend(b BackendConnector) {
bmutex.Lock()
for _, prefix := range b.Prefixes() {
backends[prefix] = b
}
bmutex.Unlock()
}

func supportedSchemes() []string {
keys := make([]string, len(backends))
i := 0
for k := range backends {
keys[i] = k
i++
}
return keys
}

func expectDependency(logger logrus.FieldLogger, dependencies ...interface{}) {
if logger == nil {
panic("missing logger for dependency check")
}
for _, d := range dependencies {
if d == nil {
logger.WithError(errors.WithStack(errNilDependency)).Fatalf("A fatal issue occurred.")
}
}
}
53 changes: 52 additions & 1 deletion config/backend_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,55 @@

package config

type MemoryConnection struct{}
import (
"time"

"github.com/sirupsen/logrus"

"github.com/ory/fosite"
"github.com/ory/hydra/client"
"github.com/ory/hydra/consent"
"github.com/ory/hydra/jwk"
"github.com/ory/hydra/oauth2"
"github.com/ory/hydra/pkg"
)

type MemoryBackend struct {
l logrus.FieldLogger
}

func init() {
RegisterBackend(&MemoryBackend{})
}

func (m *MemoryBackend) Init(url string, l logrus.FieldLogger) error {
m.l = l
return nil
}

func (m *MemoryBackend) NewConsentManager(_ client.Manager, fs pkg.FositeStorer) consent.Manager {
expectDependency(m.l, fs)
return consent.NewMemoryManager(fs)
}

func (m *MemoryBackend) NewOAuth2Manager(clientManager client.Manager, accessTokenLifespan time.Duration, _ string) pkg.FositeStorer {
expectDependency(m.l, clientManager)
return oauth2.NewFositeMemoryStore(clientManager, accessTokenLifespan)
}

func (m *MemoryBackend) NewClientManager(hasher fosite.Hasher) client.Manager {
expectDependency(m.l, hasher)
return client.NewMemoryManager(hasher)
}

func (m *MemoryBackend) NewJWKManager(_ *jwk.AEAD) jwk.Manager {
return &jwk.MemoryManager{}
}

func (m *MemoryBackend) Prefixes() []string {
return []string{"memory"}
}

func (m *MemoryBackend) Ping() error {
return nil
}
Loading

0 comments on commit 6dfc8f7

Please sign in to comment.