Skip to content

Commit

Permalink
feat: password migration hook (#3978)
Browse files Browse the repository at this point in the history
This adds a password migration hook to easily migrate passwords for which we do not have the hash.

For each user that needs to be migrated to Ory Network, a new identity is created with a credential of type password with a config of {"use_password_migration_hook": true} .
When a user logs in, the credential identifier and password will be sent to the password_migration web hook if all of these are true:
The user’s identity’s password credential is {"use_password_migration_hook": true}
The password_migration hook is configured
After calling the password_migration hook, the HTTP status code will be inspected:
On 200, we parse the response as JSON and look for {"status": "password_match"}. The password credential config will be replaced with the hash of the actual password.
On any other status code, we assume that the password is not valid.

---------

Co-authored-by: zepatrik <[email protected]>
  • Loading branch information
hperl and zepatrik authored Jul 3, 2024
1 parent 7c5299f commit c9d5573
Show file tree
Hide file tree
Showing 12 changed files with 620 additions and 499 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,12 @@ jobs:
- run: npm install
name: Install node deps
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v4
uses: golangci/golangci-lint-action@v6
env:
GOGC: 100
with:
args: --timeout 10m0s
version: v1.56.2
skip-pkg-cache: true
version: v1.59.1
- name: Build Kratos
run: make install
- name: Run go-acc (tests)
Expand Down
8 changes: 3 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@ linters-settings:
goimports:
local-prefixes: github.com/ory

run:
skip-dirs:
issues:
exclude-dirs:
- sdk/
skip-files:
exclude-files:
- ".+_test.go"
- "corpx/faker.go"

issues:
exclude:
- "Set is deprecated: use context-based WithConfigValue instead"
- "SetDefaultIdentitySchemaFromRaw is deprecated: Use context-based WithDefaultIdentitySchemaFromRaw instead"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ docs/swagger:
npx @redocly/openapi-cli preview-docs spec/swagger.json

.bin/golangci-lint: Makefile
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -d -b .bin v1.56.2
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -d -b .bin v1.59.1

.bin/hydra: Makefile
bash <(curl https://raw.githubusercontent.com/ory/meta/master/install.sh) -d -b .bin hydra v2.2.0-rc.3
Expand Down
19 changes: 16 additions & 3 deletions driver/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ const (
ViperKeyClientHTTPPrivateIPExceptionURLs = "clients.http.private_ip_exception_urls"
ViperKeyPreviewDefaultReadConsistencyLevel = "preview.default_read_consistency_level"
ViperKeyVersion = "version"
ViperKeyPasswordMigrationHook = "selfservice.flows.login.password_migration"
)

const (
Expand Down Expand Up @@ -290,6 +291,10 @@ type (
Headers map[string]string `json:"headers" koanf:"headers"`
LocalName string `json:"local_name" koanf:"local_name"`
}
PasswordMigrationHook struct {
Enabled bool `json:"enabled"`
Config json.RawMessage `json:"config"`
}
Config struct {
l *logrusx.Logger
p *configx.Provider
Expand Down Expand Up @@ -518,13 +523,13 @@ func (p *Config) cors(ctx context.Context, prefix string) (cors.Options, bool) {
})
}

// Deprecatd: use context-based WithConfigValue instead
func (p *Config) Set(ctx context.Context, key string, value interface{}) error {
// Deprecated: use context-based WithConfigValue instead
func (p *Config) Set(_ context.Context, key string, value interface{}) error {
return p.p.Set(key, value)
}

// Deprecated: use context-based WithConfigValue instead
func (p *Config) MustSet(ctx context.Context, key string, value interface{}) {
func (p *Config) MustSet(_ context.Context, key string, value interface{}) {
if err := p.p.Set(key, value); err != nil {
p.l.WithError(err).Fatalf("Unable to set \"%s\" to \"%s\".", key, value)
}
Expand Down Expand Up @@ -1599,3 +1604,11 @@ func (p *Config) TokenizeTemplate(ctx context.Context, key string) (_ *SessionTo
func (p *Config) DefaultConsistencyLevel(ctx context.Context) crdbx.ConsistencyLevel {
return crdbx.ConsistencyLevelFromString(p.GetProvider(ctx).String(ViperKeyPreviewDefaultReadConsistencyLevel))
}

func (p *Config) PasswordMigrationHook(ctx context.Context) (hook *PasswordMigrationHook) {
hook = new(PasswordMigrationHook)
// Error is ignored on purpose, as we then default to a hook with `enabled = false`.
_ = p.GetProvider(ctx).Unmarshal(ViperKeyPasswordMigrationHook, hook)

return hook
}
Loading

0 comments on commit c9d5573

Please sign in to comment.