feat: integrate passwap for human user password hashing (#6196)

* feat: use passwap for human user passwords

* fix tests

* passwap config

* add the event mapper

* cleanup query side and api

* solve linting errors

* regression test

* try to fix linter errors again

* pass systemdefaults into externalConfigChange migration

* fix: user password set in auth view

* pin passwap v0.2.0

* v2: validate hashed password hash based on prefix

* resolve remaining comments

* add error tag and translation for unsupported hash encoding

* fix unit test

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Tim Möhlmann
2023-07-14 09:49:57 +03:00
committed by GitHub
parent 6fcfa63f54
commit 4589ddad4a
56 changed files with 1853 additions and 775 deletions

View File

@@ -140,7 +140,6 @@ func TestSessionCommands_getHumanWriteModel(t *testing.T) {
func TestCommands_CreateSession(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
idGenerator id.Generator
tokenCreator func(sessionID string) (string, string, error)
}
@@ -158,6 +157,7 @@ func TestCommands_CreateSession(t *testing.T) {
name string
fields fields
args args
expect []expect
res res
}{
{
@@ -168,6 +168,7 @@ func TestCommands_CreateSession(t *testing.T) {
args{
ctx: context.Background(),
},
[]expect{},
res{
err: caos_errs.ThrowInternal(nil, "id", "generator failed"),
},
@@ -176,13 +177,13 @@ func TestCommands_CreateSession(t *testing.T) {
"eventstore failed",
fields{
idGenerator: mock.NewIDGeneratorExpectIDs(t, "sessionID"),
eventstore: eventstoreExpect(t,
expectFilterError(caos_errs.ThrowInternal(nil, "id", "filter failed")),
),
},
args{
ctx: context.Background(),
},
[]expect{
expectFilterError(caos_errs.ThrowInternal(nil, "id", "filter failed")),
},
res{
err: caos_errs.ThrowInternal(nil, "id", "filter failed"),
},
@@ -191,17 +192,6 @@ func TestCommands_CreateSession(t *testing.T) {
"empty session",
fields{
idGenerator: mock.NewIDGeneratorExpectIDs(t, "sessionID"),
eventstore: eventstoreExpect(t,
expectFilter(),
expectPush(
eventPusherToEvents(
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, ""),
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
"tokenID",
),
),
),
),
tokenCreator: func(sessionID string) (string, string, error) {
return "tokenID",
"token",
@@ -211,6 +201,17 @@ func TestCommands_CreateSession(t *testing.T) {
args{
ctx: authz.NewMockContext("", "org1", ""),
},
[]expect{
expectFilter(),
expectPush(
eventPusherToEvents(
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, ""),
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
"tokenID",
),
),
),
},
res{
want: &SessionChanged{
ObjectDetails: &domain.ObjectDetails{ResourceOwner: "org1"},
@@ -223,17 +224,6 @@ func TestCommands_CreateSession(t *testing.T) {
"empty session with domain",
fields{
idGenerator: mock.NewIDGeneratorExpectIDs(t, "sessionID"),
eventstore: eventstoreExpect(t,
expectFilter(),
expectPush(
eventPusherToEvents(
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld"),
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
"tokenID",
),
),
),
),
tokenCreator: func(sessionID string) (string, string, error) {
return "tokenID",
"token",
@@ -244,6 +234,17 @@ func TestCommands_CreateSession(t *testing.T) {
ctx: authz.NewMockContext("", "org1", ""),
domain: "domain.tld",
},
[]expect{
expectFilter(),
expectPush(
eventPusherToEvents(
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate, "domain.tld"),
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
"tokenID",
),
),
),
},
res{
want: &SessionChanged{
ObjectDetails: &domain.ObjectDetails{ResourceOwner: "org1"},
@@ -257,7 +258,7 @@ func TestCommands_CreateSession(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Commands{
eventstore: tt.fields.eventstore,
eventstore: eventstoreExpect(t, tt.expect...),
idGenerator: tt.fields.idGenerator,
sessionTokenCreator: tt.fields.tokenCreator,
}
@@ -432,7 +433,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
func(ctx context.Context, cmd *SessionCommands) error {
return caos_errs.ThrowInternal(nil, "id", "check failed")
},
@@ -452,7 +453,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{},
sessionCommands: []SessionCommand{},
},
},
res{
@@ -487,7 +488,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
CheckUser("userID"),
CheckPassword("password"),
},
@@ -499,12 +500,7 @@ func TestCommands_updateSession(t *testing.T) {
),
eventFromEventPusher(
user.NewHumanPasswordChangedEvent(context.Background(), &user.NewAggregate("userID", "org1").Aggregate,
&crypto.CryptoValue{
CryptoType: crypto.TypeHash,
Algorithm: "hash",
KeyID: "",
Crypted: []byte("password"),
}, false, ""),
"$plain$x$password", false, ""),
),
),
),
@@ -513,7 +509,7 @@ func TestCommands_updateSession(t *testing.T) {
"token",
nil
},
userPasswordAlg: crypto.CreateMockHashAlg(gomock.NewController(t)),
hasher: mockPasswordHasher("x"),
now: func() time.Time {
return testNow
},
@@ -541,7 +537,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
CheckUser("userID"),
CheckIntent("intent", "aW50ZW50"),
},
@@ -580,7 +576,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
CheckUser("userID"),
CheckIntent("intent", "aW50ZW50"),
},
@@ -629,7 +625,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
CheckUser("userID"),
CheckIntent("intent2", "aW50ZW50"),
},
@@ -674,7 +670,7 @@ func TestCommands_updateSession(t *testing.T) {
ctx: context.Background(),
checks: &SessionCommands{
sessionWriteModel: NewSessionWriteModel("sessionID", "org1"),
cmds: []SessionCommand{
sessionCommands: []SessionCommand{
CheckUser("userID"),
CheckIntent("intent", "aW50ZW50"),
},