mirror of
https://github.com/zitadel/zitadel.git
synced 2025-06-20 11:08:35 +00:00
chore: merge rc into next (#6037)
### Definition of Ready - [ ] I am happy with the code - [ ] Short description of the feature/issue is added in the pr description - [ ] PR is linked to the corresponding user story - [ ] Acceptance criteria are met - [ ] All open todos and follow ups are defined in a new ticket and justified - [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented. - [ ] No debug or dead code - [ ] My code has no repetitions - [ ] Critical parts are tested automatically - [ ] Where possible E2E tests are implemented - [ ] Documentation/examples are up-to-date - [ ] All non-functional requirements are met - [ ] Functionality of the acceptance criteria is checked manually on the dev system.
This commit is contained in:
commit
55d589cd44
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,10 +1,7 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 🚀 Feature Request
|
|
||||||
url: https://github.com/zitadel/zitadel/discussions/categories/ideas
|
|
||||||
about: Tell us about your idea in the discussions
|
|
||||||
- name: ❓ Questions
|
- name: ❓ Questions
|
||||||
url: https://github.com/zitadel/zitadel/discussions/categories/q-a
|
url: https://github.com/zitadel/zitadel/discussions/categories/q-a
|
||||||
about: Ask for help in our Q&A discussions
|
about: Ask for help in our Q&A discussions
|
||||||
- name: 💬 ZITADEL Chat
|
- name: 💬 ZITADEL Community Chat
|
||||||
url: https://zitadel.com/chat
|
url: https://zitadel.com/chat
|
||||||
|
1
.github/ISSUE_TEMPLATE/docs.yaml
vendored
1
.github/ISSUE_TEMPLATE/docs.yaml
vendored
@ -1,6 +1,5 @@
|
|||||||
name: 📄 Documentation
|
name: 📄 Documentation
|
||||||
description: Create an issue for missing or wrong documentation.
|
description: Create an issue for missing or wrong documentation.
|
||||||
title:
|
|
||||||
labels: ["docs"]
|
labels: ["docs"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
3
.github/ISSUE_TEMPLATE/improvement.yaml
vendored
3
.github/ISSUE_TEMPLATE/improvement.yaml
vendored
@ -1,6 +1,5 @@
|
|||||||
name: 🛠️ Improvement
|
name: 🛠️ Improvement
|
||||||
description:
|
description: "Create an new issue for an improvment in ZITADEL"
|
||||||
title:
|
|
||||||
labels: ["improvement"]
|
labels: ["improvement"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
3
.github/ISSUE_TEMPLATE/proposal.yaml
vendored
3
.github/ISSUE_TEMPLATE/proposal.yaml
vendored
@ -1,6 +1,5 @@
|
|||||||
name: 💡 Proposal / Feature request
|
name: 💡 Proposal / Feature request
|
||||||
description:
|
description: "Create an issue for a feature request/proposal."
|
||||||
title:
|
|
||||||
labels: ["enhancement"]
|
labels: ["enhancement"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
|
@ -23,10 +23,12 @@ type FirstInstance struct {
|
|||||||
DefaultLanguage language.Tag
|
DefaultLanguage language.Tag
|
||||||
Org command.OrgSetup
|
Org command.OrgSetup
|
||||||
MachineKeyPath string
|
MachineKeyPath string
|
||||||
|
PatPath string
|
||||||
|
|
||||||
instanceSetup command.InstanceSetup
|
instanceSetup command.InstanceSetup
|
||||||
userEncryptionKey *crypto.KeyConfig
|
userEncryptionKey *crypto.KeyConfig
|
||||||
smtpEncryptionKey *crypto.KeyConfig
|
smtpEncryptionKey *crypto.KeyConfig
|
||||||
|
oidcEncryptionKey *crypto.KeyConfig
|
||||||
masterKey string
|
masterKey string
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
es *eventstore.Eventstore
|
es *eventstore.Eventstore
|
||||||
@ -59,6 +61,14 @@ func (mig *FirstInstance) Execute(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = verifyKey(mig.oidcEncryptionKey, keyStorage); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oidcEncryption, err := crypto.NewAESCrypto(mig.oidcEncryptionKey, keyStorage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
cmd, err := command.StartCommands(mig.es,
|
cmd, err := command.StartCommands(mig.es,
|
||||||
mig.defaults,
|
mig.defaults,
|
||||||
mig.zitadelRoles,
|
mig.zitadelRoles,
|
||||||
@ -73,13 +83,12 @@ func (mig *FirstInstance) Execute(ctx context.Context) error {
|
|||||||
nil,
|
nil,
|
||||||
userAlg,
|
userAlg,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
oidcEncryption,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -101,25 +110,43 @@ func (mig *FirstInstance) Execute(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, key, _, err := cmd.SetUpInstance(ctx, &mig.instanceSetup)
|
_, token, key, _, err := cmd.SetUpInstance(ctx, &mig.instanceSetup)
|
||||||
if key == nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if mig.instanceSetup.Org.Machine != nil &&
|
||||||
|
((mig.instanceSetup.Org.Machine.Pat != nil && token == "") ||
|
||||||
|
(mig.instanceSetup.Org.Machine.MachineKey != nil && key == nil)) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if key != nil {
|
||||||
|
keyDetails, err := key.Detail()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := outputStdoutOrPath(mig.MachineKeyPath, string(keyDetails)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if token != "" {
|
||||||
|
if err := outputStdoutOrPath(mig.PatPath, token); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func outputStdoutOrPath(path string, content string) (err error) {
|
||||||
f := os.Stdout
|
f := os.Stdout
|
||||||
if mig.MachineKeyPath != "" {
|
if path != "" {
|
||||||
f, err = os.OpenFile(mig.MachineKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
f, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
}
|
}
|
||||||
|
_, err = fmt.Fprintln(f, content)
|
||||||
keyDetails, err := key.Detail()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintln(f, string(keyDetails))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ type Steps struct {
|
|||||||
type encryptionKeyConfig struct {
|
type encryptionKeyConfig struct {
|
||||||
User *crypto.KeyConfig
|
User *crypto.KeyConfig
|
||||||
SMTP *crypto.KeyConfig
|
SMTP *crypto.KeyConfig
|
||||||
|
OIDC *crypto.KeyConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustNewSteps(v *viper.Viper) *Steps {
|
func MustNewSteps(v *viper.Viper) *Steps {
|
||||||
|
@ -75,6 +75,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
|
|||||||
steps.FirstInstance.instanceSetup = config.DefaultInstance
|
steps.FirstInstance.instanceSetup = config.DefaultInstance
|
||||||
steps.FirstInstance.userEncryptionKey = config.EncryptionKeys.User
|
steps.FirstInstance.userEncryptionKey = config.EncryptionKeys.User
|
||||||
steps.FirstInstance.smtpEncryptionKey = config.EncryptionKeys.SMTP
|
steps.FirstInstance.smtpEncryptionKey = config.EncryptionKeys.SMTP
|
||||||
|
steps.FirstInstance.oidcEncryptionKey = config.EncryptionKeys.OIDC
|
||||||
steps.FirstInstance.masterKey = masterKey
|
steps.FirstInstance.masterKey = masterKey
|
||||||
steps.FirstInstance.db = dbClient.DB
|
steps.FirstInstance.db = dbClient.DB
|
||||||
steps.FirstInstance.es = eventstoreClient
|
steps.FirstInstance.es = eventstoreClient
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
FirstInstance:
|
FirstInstance:
|
||||||
MachineKeyPath:
|
MachineKeyPath:
|
||||||
|
PatPath:
|
||||||
InstanceName: ZITADEL
|
InstanceName: ZITADEL
|
||||||
DefaultLanguage: en
|
DefaultLanguage: en
|
||||||
Org:
|
Org:
|
||||||
@ -30,6 +31,8 @@ FirstInstance:
|
|||||||
MachineKey:
|
MachineKey:
|
||||||
ExpirationDate:
|
ExpirationDate:
|
||||||
Type:
|
Type:
|
||||||
|
Pat:
|
||||||
|
ExpirationDate:
|
||||||
|
|
||||||
CorrectCreationDate:
|
CorrectCreationDate:
|
||||||
FailAfter: 5m
|
FailAfter: 5m
|
||||||
|
@ -113,13 +113,11 @@ func createInstancePbToAddMachine(req *system_pb.CreateInstanceRequest_Machine,
|
|||||||
// Scopes are currently static and can not be overwritten
|
// Scopes are currently static and can not be overwritten
|
||||||
Scopes: []string{oidc.ScopeOpenID, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner},
|
Scopes: []string{oidc.ScopeOpenID, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner},
|
||||||
}
|
}
|
||||||
|
if req.GetPersonalAccessToken().GetExpirationDate().IsValid() {
|
||||||
if !defaultMachine.Pat.ExpirationDate.IsZero() {
|
|
||||||
pat.ExpirationDate = defaultMachine.Pat.ExpirationDate
|
|
||||||
} else if req.PersonalAccessToken.ExpirationDate.IsValid() {
|
|
||||||
pat.ExpirationDate = req.PersonalAccessToken.ExpirationDate.AsTime()
|
pat.ExpirationDate = req.PersonalAccessToken.ExpirationDate.AsTime()
|
||||||
|
} else if defaultMachine.Pat != nil && !defaultMachine.Pat.ExpirationDate.IsZero() {
|
||||||
|
pat.ExpirationDate = defaultMachine.Pat.ExpirationDate
|
||||||
}
|
}
|
||||||
|
|
||||||
machine.Pat = &pat
|
machine.Pat = &pat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,14 +292,14 @@ func (l *Login) handleExternalUserAuthenticated(
|
|||||||
l.renderError(w, r, authReq, externalErr)
|
l.renderError(w, r, authReq, externalErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
externalUser, externalUserChange, err := l.runPostExternalAuthenticationActions(externalUser, tokens(session), authReq, r, user, externalErr)
|
externalUser, externalUserChange, err := l.runPostExternalAuthenticationActions(externalUser, tokens(session), authReq, r, user, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.renderError(w, r, authReq, err)
|
l.renderError(w, r, authReq, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// if action is done and no user linked then link or register
|
// if action is done and no user linked then link or register
|
||||||
if errors.IsNotFound(externalErr) {
|
if errors.IsNotFound(externalErr) {
|
||||||
l.externalUserNotExisting(w, r, authReq, provider, externalUser)
|
l.externalUserNotExisting(w, r, authReq, provider, externalUser, externalUserChange)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if provider.IsAutoUpdate || len(externalUser.Metadatas) > 0 || externalUserChange {
|
if provider.IsAutoUpdate || len(externalUser.Metadatas) > 0 || externalUserChange {
|
||||||
@ -334,7 +334,7 @@ func (l *Login) handleExternalUserAuthenticated(
|
|||||||
// * external not found overview:
|
// * external not found overview:
|
||||||
// - creation by user
|
// - creation by user
|
||||||
// - linking to existing user
|
// - linking to existing user
|
||||||
func (l *Login) externalUserNotExisting(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, provider *query.IDPTemplate, externalUser *domain.ExternalUser) {
|
func (l *Login) externalUserNotExisting(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, provider *query.IDPTemplate, externalUser *domain.ExternalUser, changed bool) {
|
||||||
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
resourceOwner := authz.GetInstance(r.Context()).DefaultOrganisationID()
|
||||||
|
|
||||||
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
if authReq.RequestedOrgID != "" && authReq.RequestedOrgID != resourceOwner {
|
||||||
@ -360,6 +360,12 @@ func (l *Login) externalUserNotExisting(w http.ResponseWriter, r *http.Request,
|
|||||||
l.renderExternalNotFoundOption(w, r, authReq, orgIAMPolicy, human, idpLink, err)
|
l.renderExternalNotFoundOption(w, r, authReq, orgIAMPolicy, human, idpLink, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if changed {
|
||||||
|
if err := l.authRepo.SetLinkingUser(r.Context(), authReq, externalUser); err != nil {
|
||||||
|
l.renderError(w, r, authReq, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
l.autoCreateExternalUser(w, r, authReq)
|
l.autoCreateExternalUser(w, r, authReq)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ type AuthRequestRepository interface {
|
|||||||
CheckLoginName(ctx context.Context, id, loginName, userAgentID string) error
|
CheckLoginName(ctx context.Context, id, loginName, userAgentID string) error
|
||||||
CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser, info *domain.BrowserInfo) error
|
CheckExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser, info *domain.BrowserInfo) error
|
||||||
SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser) error
|
SetExternalUserLogin(ctx context.Context, authReqID, userAgentID string, user *domain.ExternalUser) error
|
||||||
|
SetLinkingUser(ctx context.Context, request *domain.AuthRequest, externalUser *domain.ExternalUser) error
|
||||||
SelectUser(ctx context.Context, id, userID, userAgentID string) error
|
SelectUser(ctx context.Context, id, userID, userAgentID string) error
|
||||||
SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID string) error
|
SelectExternalIDP(ctx context.Context, authReqID, idpConfigID, userAgentID string) error
|
||||||
VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID string, info *domain.BrowserInfo) error
|
VerifyPassword(ctx context.Context, id, userID, resourceOwner, password, userAgentID string, info *domain.BrowserInfo) error
|
||||||
|
@ -278,6 +278,16 @@ func (repo *AuthRequestRepo) SetExternalUserLogin(ctx context.Context, authReqID
|
|||||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *AuthRequestRepo) SetLinkingUser(ctx context.Context, request *domain.AuthRequest, externalUser *domain.ExternalUser) error {
|
||||||
|
for i, user := range request.LinkingUsers {
|
||||||
|
if user.ExternalUserID == externalUser.ExternalUserID {
|
||||||
|
request.LinkingUsers[i] = externalUser
|
||||||
|
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (repo *AuthRequestRepo) setLinkingUser(ctx context.Context, request *domain.AuthRequest, externalUser *domain.ExternalUser) error {
|
func (repo *AuthRequestRepo) setLinkingUser(ctx context.Context, request *domain.AuthRequest, externalUser *domain.ExternalUser) error {
|
||||||
request.LinkingUsers = append(request.LinkingUsers, externalUser)
|
request.LinkingUsers = append(request.LinkingUsers, externalUser)
|
||||||
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
return repo.AuthRequests.UpdateAuthRequest(ctx, request)
|
||||||
|
@ -351,6 +351,10 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
Event: instance.OIDCIDPMigratedAzureADEventType,
|
Event: instance.OIDCIDPMigratedAzureADEventType,
|
||||||
Reduce: p.reduceOIDCIDPMigratedAzureAD,
|
Reduce: p.reduceOIDCIDPMigratedAzureAD,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Event: instance.OIDCIDPMigratedGoogleEventType,
|
||||||
|
Reduce: p.reduceOIDCIDPMigratedGoogle,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Event: instance.JWTIDPAddedEventType,
|
Event: instance.JWTIDPAddedEventType,
|
||||||
Reduce: p.reduceJWTIDPAdded,
|
Reduce: p.reduceJWTIDPAdded,
|
||||||
@ -472,6 +476,14 @@ func (p *idpTemplateProjection) reducers() []handler.AggregateReducer {
|
|||||||
Event: org.OIDCIDPChangedEventType,
|
Event: org.OIDCIDPChangedEventType,
|
||||||
Reduce: p.reduceOIDCIDPChanged,
|
Reduce: p.reduceOIDCIDPChanged,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Event: org.OIDCIDPMigratedAzureADEventType,
|
||||||
|
Reduce: p.reduceOIDCIDPMigratedAzureAD,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: org.OIDCIDPMigratedGoogleEventType,
|
||||||
|
Reduce: p.reduceOIDCIDPMigratedGoogle,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Event: org.JWTIDPAddedEventType,
|
Event: org.JWTIDPAddedEventType,
|
||||||
Reduce: p.reduceJWTIDPAdded,
|
Reduce: p.reduceJWTIDPAdded,
|
||||||
|
@ -263,7 +263,7 @@ func NewOIDCIDPMigratedGoogleEvent(
|
|||||||
eventstore.NewBaseEventForPush(
|
eventstore.NewBaseEventForPush(
|
||||||
ctx,
|
ctx,
|
||||||
aggregate,
|
aggregate,
|
||||||
OIDCIDPMigratedAzureADEventType,
|
OIDCIDPMigratedGoogleEventType,
|
||||||
),
|
),
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user