Skip to content

Commit

Permalink
feat: support for B2B SSO (ory#3489)
Browse files Browse the repository at this point in the history
  • Loading branch information
hperl authored Sep 21, 2023
1 parent 83bfb2d commit 0ec037a
Show file tree
Hide file tree
Showing 160 changed files with 1,003 additions and 186 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cover.out
.idea/
tmp/
ddl/
.DS_Store
/kratos
packrd/
Expand Down
1 change: 1 addition & 0 deletions .grype.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ ignore:
- vulnerability: CVE-2015-5237
- vulnerability: CVE-2022-30065
- vulnerability: CVE-2023-2650
- vulnerability: CVE-2023-4813
2 changes: 2 additions & 0 deletions cmd/identities/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,15 @@ func TestGetCmd(t *testing.T) {
InitialAccessToken: transform(accessToken + "0"),
InitialRefreshToken: transform(refreshToken + "0"),
InitialIDToken: transform(idToken + "0"),
Organization: "foo-org-id",
},
{
Subject: "baz",
Provider: "zab",
InitialAccessToken: transform(accessToken + "1"),
InitialRefreshToken: transform(refreshToken + "1"),
InitialIDToken: transform(idToken + "1"),
Organization: "bar-org-id",
},
}}),
}
Expand Down
29 changes: 24 additions & 5 deletions driver/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,13 @@ func NewRegistryFromDSN(ctx context.Context, c *config.Config, l *logrusx.Logger
}

type options struct {
skipNetworkInit bool
config *config.Config
replaceTracer func(*otelx.Tracer) *otelx.Tracer
inspect func(Registry) error
extraMigrations []fs.FS
skipNetworkInit bool
config *config.Config
replaceTracer func(*otelx.Tracer) *otelx.Tracer
inspect func(Registry) error
extraMigrations []fs.FS
replacementStrategies []NewStrategy
extraHooks map[string]func(config.SelfServiceHook) any
}

type RegistryOption func(*options)
Expand All @@ -205,6 +207,23 @@ func ReplaceTracer(f func(*otelx.Tracer) *otelx.Tracer) RegistryOption {
}
}

type NewStrategy func(deps any) any

// WithReplaceStrategies adds a strategy to the registry. This is useful if you want to
// add a custom strategy to the registry. Default strategies with the same
// name/ID will be overwritten.
func WithReplaceStrategies(s ...NewStrategy) RegistryOption {
return func(o *options) {
o.replacementStrategies = append(o.replacementStrategies, s...)
}
}

func WithExtraHooks(hooks map[string]func(config.SelfServiceHook) any) RegistryOption {
return func(o *options) {
o.extraHooks = hooks
}
}

func Inspect(f func(reg Registry) error) RegistryOption {
return func(o *options) {
o.inspect = f
Expand Down
63 changes: 46 additions & 17 deletions driver/registry_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import (
"github.com/ory/kratos/driver/config"
"github.com/ory/kratos/identity"
"github.com/ory/kratos/selfservice/errorx"
password2 "github.com/ory/kratos/selfservice/strategy/password"
"github.com/ory/kratos/selfservice/strategy/password"
"github.com/ory/kratos/session"
)

Expand Down Expand Up @@ -123,7 +123,7 @@ type RegistryDefault struct {
sessionTokenizer *session.Tokenizer

passwordHasher hash.Hasher
passwordValidator password2.Validator
passwordValidator password.Validator

crypter cipher.Cipher

Expand Down Expand Up @@ -157,7 +157,8 @@ type RegistryDefault struct {

selfserviceLogoutHandler *logout.Handler

selfserviceStrategies []interface{}
selfserviceStrategies []any
replacementSelfserviceStrategies []NewStrategy

hydra hydra.Hydra

Expand Down Expand Up @@ -317,17 +318,25 @@ func (m *RegistryDefault) CourierConfig() config.CourierConfigs {
return m.Config()
}

func (m *RegistryDefault) selfServiceStrategies() []interface{} {
func (m *RegistryDefault) selfServiceStrategies() []any {
if len(m.selfserviceStrategies) == 0 {
m.selfserviceStrategies = []interface{}{
password2.NewStrategy(m),
oidc.NewStrategy(m),
profile.NewStrategy(m),
code.NewStrategy(m),
link.NewStrategy(m),
totp.NewStrategy(m),
webauthn.NewStrategy(m),
lookup.NewStrategy(m),
if m.replacementSelfserviceStrategies != nil {
// Construct self-service strategies from the replacements
for _, newStrategy := range m.replacementSelfserviceStrategies {
m.selfserviceStrategies = append(m.selfserviceStrategies, newStrategy(m))
}
} else {
// Construct the default list of strategies
m.selfserviceStrategies = []any{
password.NewStrategy(m),
oidc.NewStrategy(m),
profile.NewStrategy(m),
code.NewStrategy(m),
link.NewStrategy(m),
totp.NewStrategy(m),
webauthn.NewStrategy(m),
lookup.NewStrategy(m),
}
}
}

Expand All @@ -352,9 +361,15 @@ func (m *RegistryDefault) strategyLoginEnabled(ctx context.Context, id string) b
}
}

func (m *RegistryDefault) RegistrationStrategies(ctx context.Context) (registrationStrategies registration.Strategies) {
func (m *RegistryDefault) RegistrationStrategies(ctx context.Context, filters ...registration.StrategyFilter) (registrationStrategies registration.Strategies) {
nextStrategy:
for _, strategy := range m.selfServiceStrategies() {
if s, ok := strategy.(registration.Strategy); ok {
for _, filter := range filters {
if !filter(s) {
continue nextStrategy
}
}
if m.strategyRegistrationEnabled(ctx, s.ID().String()) {
registrationStrategies = append(registrationStrategies, s)
}
Expand All @@ -374,9 +389,15 @@ func (m *RegistryDefault) AllRegistrationStrategies() registration.Strategies {
return registrationStrategies
}

func (m *RegistryDefault) LoginStrategies(ctx context.Context) (loginStrategies login.Strategies) {
func (m *RegistryDefault) LoginStrategies(ctx context.Context, filters ...login.StrategyFilter) (loginStrategies login.Strategies) {
nextStrategy:
for _, strategy := range m.selfServiceStrategies() {
if s, ok := strategy.(login.Strategy); ok {
for _, filter := range filters {
if !filter(s) {
continue nextStrategy
}
}
if m.strategyLoginEnabled(ctx, s.ID().String()) {
loginStrategies = append(loginStrategies, s)
}
Expand Down Expand Up @@ -495,10 +516,10 @@ func (m *RegistryDefault) Hasher(ctx context.Context) hash.Hasher {
return m.passwordHasher
}

func (m *RegistryDefault) PasswordValidator() password2.Validator {
func (m *RegistryDefault) PasswordValidator() password.Validator {
if m.passwordValidator == nil {
var err error
m.passwordValidator, err = password2.NewDefaultPasswordValidatorStrategy(m)
m.passwordValidator, err = password.NewDefaultPasswordValidatorStrategy(m)
if err != nil {
m.Logger().WithError(err).Fatal("could not initialize DefaultPasswordValidator")
}
Expand Down Expand Up @@ -622,6 +643,14 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize
m.trc = o.replaceTracer(m.trc)
}

if o.replacementStrategies != nil {
m.replacementSelfserviceStrategies = o.replacementStrategies
}

if o.extraHooks != nil {
m.WithHooks(o.extraHooks)
}

bc := backoff.NewExponentialBackOff()
bc.MaxElapsedTime = time.Minute * 5
bc.Reset()
Expand Down
43 changes: 43 additions & 0 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,23 @@
"hook"
]
},
"b2bSSOHook": {
"type": "object",
"properties": {
"hook": {
"const": "b2b_sso"
},
"config": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false,
"required": [
"hook",
"config"
]
},
"webHookAuthBasicAuthProperties": {
"properties": {
"type": {
Expand Down Expand Up @@ -578,6 +595,14 @@
},
"requested_claims": {
"$ref": "#/definitions/OIDCClaims"
},
"organization_id": {
"title": "Organization ID",
"description": "The ID of the organization that this provider belongs to. Only effective in the Ory Network.",
"type": "string",
"examples": [
"12345678-1234-1234-1234-123456789012"
]
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -699,6 +724,9 @@
"anyOf": [
{
"$ref": "#/definitions/selfServiceWebHook"
},
{
"$ref": "#/definitions/b2bSSOHook"
}
]
},
Expand Down Expand Up @@ -811,6 +839,9 @@
},
{
"$ref": "#/definitions/selfServiceRequireVerifiedAddressHook"
},
{
"$ref": "#/definitions/b2bSSOHook"
}
]
},
Expand Down Expand Up @@ -838,6 +869,9 @@
},
{
"$ref": "#/definitions/selfServiceShowVerificationUIHook"
},
{
"$ref": "#/definitions/b2bSSOHook"
}
]
},
Expand Down Expand Up @@ -932,6 +966,9 @@
},
{
"$ref": "#/definitions/selfServiceRequireVerifiedAddressHook"
},
{
"$ref": "#/definitions/b2bSSOHook"
}
]
},
Expand Down Expand Up @@ -2828,6 +2865,12 @@
}
},
"additionalProperties": false
},
"organizations": {
"title": "Organizations",
"description": "Secifies which organizations are available. Only effective in the Ory Network.",
"type": "array",
"default": []
}
},
"allOf": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
"email": "[email protected]"
},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"state": "active",
"traits": {},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"state": "active",
"traits": {},
"metadata_public": null,
"metadata_admin": null
"metadata_admin": null,
"organization_id": null
}
Loading

0 comments on commit 0ec037a

Please sign in to comment.