mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat(api/v2): implement U2F session check (#6339)
This commit is contained in:
@@ -4,22 +4,18 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/repository/session"
|
||||
)
|
||||
|
||||
type PasskeyChallengeModel struct {
|
||||
type WebAuthNChallengeModel struct {
|
||||
Challenge string
|
||||
AllowedCrentialIDs [][]byte
|
||||
UserVerification domain.UserVerificationRequirement
|
||||
RPID string
|
||||
}
|
||||
|
||||
func (p *PasskeyChallengeModel) WebAuthNLogin(human *domain.Human, credentialAssertionData []byte) (*domain.WebAuthNLogin, error) {
|
||||
if p == nil {
|
||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Ioqu5", "Errors.Session.Passkey.NoChallenge")
|
||||
}
|
||||
func (p *WebAuthNChallengeModel) WebAuthNLogin(human *domain.Human, credentialAssertionData []byte) *domain.WebAuthNLogin {
|
||||
return &domain.WebAuthNLogin{
|
||||
ObjectRoot: human.ObjectRoot,
|
||||
CredentialAssertionData: credentialAssertionData,
|
||||
@@ -27,23 +23,23 @@ func (p *PasskeyChallengeModel) WebAuthNLogin(human *domain.Human, credentialAss
|
||||
AllowedCredentialIDs: p.AllowedCrentialIDs,
|
||||
UserVerification: p.UserVerification,
|
||||
RPID: p.RPID,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
type SessionWriteModel struct {
|
||||
eventstore.WriteModel
|
||||
|
||||
TokenID string
|
||||
UserID string
|
||||
UserCheckedAt time.Time
|
||||
PasswordCheckedAt time.Time
|
||||
IntentCheckedAt time.Time
|
||||
PasskeyCheckedAt time.Time
|
||||
Metadata map[string][]byte
|
||||
Domain string
|
||||
State domain.SessionState
|
||||
TokenID string
|
||||
UserID string
|
||||
UserCheckedAt time.Time
|
||||
PasswordCheckedAt time.Time
|
||||
IntentCheckedAt time.Time
|
||||
WebAuthNCheckedAt time.Time
|
||||
WebAuthNUserVerified bool
|
||||
Metadata map[string][]byte
|
||||
State domain.SessionState
|
||||
|
||||
PasskeyChallenge *PasskeyChallengeModel
|
||||
WebAuthNChallenge *WebAuthNChallengeModel
|
||||
|
||||
aggregate *eventstore.Aggregate
|
||||
}
|
||||
@@ -70,10 +66,10 @@ func (wm *SessionWriteModel) Reduce() error {
|
||||
wm.reducePasswordChecked(e)
|
||||
case *session.IntentCheckedEvent:
|
||||
wm.reduceIntentChecked(e)
|
||||
case *session.PasskeyChallengedEvent:
|
||||
wm.reducePasskeyChallenged(e)
|
||||
case *session.PasskeyCheckedEvent:
|
||||
wm.reducePasskeyChecked(e)
|
||||
case *session.WebAuthNChallengedEvent:
|
||||
wm.reduceWebAuthNChallenged(e)
|
||||
case *session.WebAuthNCheckedEvent:
|
||||
wm.reduceWebAuthNChecked(e)
|
||||
case *session.TokenSetEvent:
|
||||
wm.reduceTokenSet(e)
|
||||
case *session.TerminateEvent:
|
||||
@@ -93,8 +89,8 @@ func (wm *SessionWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
session.UserCheckedType,
|
||||
session.PasswordCheckedType,
|
||||
session.IntentCheckedType,
|
||||
session.PasskeyChallengedType,
|
||||
session.PasskeyCheckedType,
|
||||
session.WebAuthNChallengedType,
|
||||
session.WebAuthNCheckedType,
|
||||
session.TokenSetType,
|
||||
session.MetadataSetType,
|
||||
session.TerminateType,
|
||||
@@ -108,7 +104,6 @@ func (wm *SessionWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
}
|
||||
|
||||
func (wm *SessionWriteModel) reduceAdded(e *session.AddedEvent) {
|
||||
wm.Domain = e.Domain
|
||||
wm.State = domain.SessionStateActive
|
||||
}
|
||||
|
||||
@@ -125,18 +120,19 @@ func (wm *SessionWriteModel) reduceIntentChecked(e *session.IntentCheckedEvent)
|
||||
wm.IntentCheckedAt = e.CheckedAt
|
||||
}
|
||||
|
||||
func (wm *SessionWriteModel) reducePasskeyChallenged(e *session.PasskeyChallengedEvent) {
|
||||
wm.PasskeyChallenge = &PasskeyChallengeModel{
|
||||
func (wm *SessionWriteModel) reduceWebAuthNChallenged(e *session.WebAuthNChallengedEvent) {
|
||||
wm.WebAuthNChallenge = &WebAuthNChallengeModel{
|
||||
Challenge: e.Challenge,
|
||||
AllowedCrentialIDs: e.AllowedCrentialIDs,
|
||||
UserVerification: e.UserVerification,
|
||||
RPID: wm.Domain,
|
||||
RPID: e.RPID,
|
||||
}
|
||||
}
|
||||
|
||||
func (wm *SessionWriteModel) reducePasskeyChecked(e *session.PasskeyCheckedEvent) {
|
||||
wm.PasskeyChallenge = nil
|
||||
wm.PasskeyCheckedAt = e.CheckedAt
|
||||
func (wm *SessionWriteModel) reduceWebAuthNChecked(e *session.WebAuthNCheckedEvent) {
|
||||
wm.WebAuthNChallenge = nil
|
||||
wm.WebAuthNCheckedAt = e.CheckedAt
|
||||
wm.WebAuthNUserVerified = e.UserVerified
|
||||
}
|
||||
|
||||
func (wm *SessionWriteModel) reduceTokenSet(e *session.TokenSetEvent) {
|
||||
@@ -152,9 +148,9 @@ func (wm *SessionWriteModel) AuthenticationTime() time.Time {
|
||||
var authTime time.Time
|
||||
for _, check := range []time.Time{
|
||||
wm.PasswordCheckedAt,
|
||||
wm.PasskeyCheckedAt,
|
||||
wm.WebAuthNCheckedAt,
|
||||
wm.IntentCheckedAt,
|
||||
// TODO: add U2F and OTP check https://github.com/zitadel/zitadel/issues/5477
|
||||
// TODO: add OTP check https://github.com/zitadel/zitadel/issues/5477
|
||||
// TODO: add OTP (sms and email) check https://github.com/zitadel/zitadel/issues/6224
|
||||
} {
|
||||
if check.After(authTime) {
|
||||
@@ -170,8 +166,12 @@ func (wm *SessionWriteModel) AuthMethodTypes() []domain.UserAuthMethodType {
|
||||
if !wm.PasswordCheckedAt.IsZero() {
|
||||
types = append(types, domain.UserAuthMethodTypePassword)
|
||||
}
|
||||
if !wm.PasskeyCheckedAt.IsZero() {
|
||||
types = append(types, domain.UserAuthMethodTypePasswordless)
|
||||
if !wm.WebAuthNCheckedAt.IsZero() {
|
||||
if wm.WebAuthNUserVerified {
|
||||
types = append(types, domain.UserAuthMethodTypePasswordless)
|
||||
} else {
|
||||
types = append(types, domain.UserAuthMethodTypeU2F)
|
||||
}
|
||||
}
|
||||
if !wm.IntentCheckedAt.IsZero() {
|
||||
types = append(types, domain.UserAuthMethodTypeIDP)
|
||||
@@ -181,9 +181,6 @@ func (wm *SessionWriteModel) AuthMethodTypes() []domain.UserAuthMethodType {
|
||||
if !wm.TOTPCheckedAt.IsZero() {
|
||||
types = append(types, domain.UserAuthMethodTypeTOTP)
|
||||
}
|
||||
if !wm.U2FCheckedAt.IsZero() {
|
||||
types = append(types, domain.UserAuthMethodTypeU2F)
|
||||
}
|
||||
*/
|
||||
// TODO: add checks with https://github.com/zitadel/zitadel/issues/6224
|
||||
/*
|
||||
|
Reference in New Issue
Block a user