fix: user session with external login (#797)

* fix: user session with external login

* fix: tests

* fix: tests

* fix: change idp config name
This commit is contained in:
Fabi
2020-10-02 08:02:09 +02:00
committed by GitHub
parent 124988e2d2
commit 198370325d
24 changed files with 267 additions and 101 deletions

View File

@@ -17,7 +17,9 @@ type UserSessionView struct {
UserName string
LoginName string
DisplayName string
SelectedIDPConfigID string
PasswordVerification time.Time
ExternalLoginVerification time.Time
MfaSoftwareVerification time.Time
MfaSoftwareVerificationType req_model.MfaType
MfaHardwareVerification time.Time

View File

@@ -592,6 +592,25 @@ func (es *UserEventstore) SetPassword(ctx context.Context, policy *policy_model.
return err
}
func (es *UserEventstore) ExternalLoginChecked(ctx context.Context, userID string, authRequest *req_model.AuthRequest) error {
user, err := es.UserByID(ctx, userID)
if err != nil {
return err
}
if user.Human == nil {
return errors.ThrowPreconditionFailed(nil, "EVENT-Gns8i", "Errors.User.NotHuman")
}
repoUser := model.UserFromModel(user)
repoAuthRequest := model.AuthRequestFromModel(authRequest)
agg := ExternalLoginCheckSucceededAggregate(es.AggregateCreator(), repoUser, repoAuthRequest)
err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg)
if err != nil {
return err
}
es.userCache.cacheUser(repoUser)
return nil
}
func (es *UserEventstore) ChangeMachine(ctx context.Context, machine *usr_model.Machine) (*usr_model.Machine, error) {
user, err := es.UserByID(ctx, machine.AggregateID)
if err != nil {

View File

@@ -1,22 +1,28 @@
package model
import (
"encoding/json"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"net"
"github.com/caos/zitadel/internal/auth_request/model"
)
type AuthRequest struct {
ID string `json:"id,omitempty"`
UserAgentID string `json:"userAgentID,omitempty"`
ID string `json:"id,omitempty"`
UserAgentID string `json:"userAgentID,omitempty"`
SelectedIDPConfigID string `json:"selectedIDPConfigID,omitempty"`
*BrowserInfo
}
func AuthRequestFromModel(request *model.AuthRequest) *AuthRequest {
return &AuthRequest{
ID: request.ID,
UserAgentID: request.AgentID,
BrowserInfo: BrowserInfoFromModel(request.BrowserInfo),
ID: request.ID,
UserAgentID: request.AgentID,
BrowserInfo: BrowserInfoFromModel(request.BrowserInfo),
SelectedIDPConfigID: request.SelectedIDPConfigID,
}
}
@@ -33,3 +39,11 @@ func BrowserInfoFromModel(info *model.BrowserInfo) *BrowserInfo {
RemoteIP: info.RemoteIP,
}
}
func (a *AuthRequest) SetData(event *es_models.Event) error {
if err := json.Unmarshal(event.Data, a); err != nil {
logging.Log("EVEN-T5df6").WithError(err).Error("could not unmarshal event data")
return caos_errs.ThrowInternal(err, "MODEL-yGmhh", "could not unmarshal event")
}
return nil
}

View File

@@ -84,6 +84,8 @@ const (
HumanPasswordCheckSucceeded models.EventType = "user.human.password.check.succeeded"
HumanPasswordCheckFailed models.EventType = "user.human.password.check.failed"
HumanExternalLoginCheckSucceeded models.EventType = "user.human.externallogin.check.succeeded"
HumanExternalIDPReserved models.EventType = "user.human.externalidp.reserved"
HumanExternalIDPReleased models.EventType = "user.human.externalidp.released"

View File

@@ -445,6 +445,16 @@ func PasswordCodeSentAggregate(aggCreator *es_models.AggregateCreator, user *mod
}
}
func ExternalLoginCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, user *model.User, check *model.AuthRequest) es_sdk.AggregateFunc {
return func(ctx context.Context) (*es_models.Aggregate, error) {
agg, err := UserAggregate(ctx, aggCreator, user)
if err != nil {
return nil, err
}
return agg.AppendEvent(model.HumanExternalLoginCheckSucceeded, check)
}
}
func MachineChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, machine *model.Machine) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if machine == nil {

View File

@@ -30,7 +30,9 @@ type UserSessionView struct {
UserName string `json:"-" gorm:"column:user_name"`
LoginName string `json:"-" gorm:"column:login_name"`
DisplayName string `json:"-" gorm:"column:user_display_name"`
SelectedIDPConfigID string `json:"selectedIDPConfigID" gorm:"column:selected_idp_config_id"`
PasswordVerification time.Time `json:"-" gorm:"column:password_verification"`
ExternalLoginVerification time.Time `json:"-" gorm:"column:external_login_verification"`
MfaSoftwareVerification time.Time `json:"-" gorm:"column:mfa_software_verification"`
MfaSoftwareVerificationType int32 `json:"-" gorm:"column:mfa_software_verification_type"`
MfaHardwareVerification time.Time `json:"-" gorm:"column:mfa_hardware_verification"`
@@ -58,7 +60,9 @@ func UserSessionToModel(userSession *UserSessionView) *model.UserSessionView {
UserName: userSession.UserName,
LoginName: userSession.LoginName,
DisplayName: userSession.DisplayName,
SelectedIDPConfigID: userSession.SelectedIDPConfigID,
PasswordVerification: userSession.PasswordVerification,
ExternalLoginVerification: userSession.ExternalLoginVerification,
MfaSoftwareVerification: userSession.MfaSoftwareVerification,
MfaSoftwareVerificationType: req_model.MfaType(userSession.MfaSoftwareVerificationType),
MfaHardwareVerification: userSession.MfaHardwareVerification,
@@ -83,6 +87,12 @@ func (v *UserSessionView) AppendEvent(event *models.Event) {
es_model.HumanPasswordCheckSucceeded:
v.PasswordVerification = event.CreationDate
v.State = int32(req_model.UserSessionStateActive)
case es_model.HumanExternalLoginCheckSucceeded:
data := new(es_model.AuthRequest)
data.SetData(event)
v.ExternalLoginVerification = event.CreationDate
v.SelectedIDPConfigID = data.SelectedIDPConfigID
v.State = int32(req_model.UserSessionStateActive)
case es_model.UserPasswordCheckFailed,
es_model.UserPasswordChanged,
es_model.HumanPasswordCheckFailed,

View File

@@ -20,7 +20,7 @@ func UserMembershipByIDs(db *gorm.DB, table, userID, aggregateID, objectID strin
query := repository.PrepareGetByQuery(table, userIDQuery, aggregateIDQuery, objectIDQuery, memberTypeQuery)
err := query(db, memberships)
if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-sj8Sw", "Errors.UserMembership.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "VIEW-5Tsji", "Errors.UserMembership.NotFound")
}
return memberships, err
}