mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
- Transitioned from using `handler.Statements` to a repository pattern for managing organization data in migrations. - Introduced a new method to set the updated timestamp for organizations. - Updated the projection logic to utilize the repository for creating, updating, and deleting organization records.
443 lines
17 KiB
Go
443 lines
17 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/muhlemmer/gu"
|
|
|
|
"github.com/zitadel/zitadel/backend/v3/domain"
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
|
)
|
|
|
|
type idpIntentRepository struct{}
|
|
|
|
func (i idpIntentRepository) qualifiedTableName() string {
|
|
return "zitadel.identity_provider_intents"
|
|
}
|
|
|
|
func (i idpIntentRepository) unqualifiedTableName() string {
|
|
return "identity_provider_intents"
|
|
}
|
|
|
|
func IDPIntentRepository() domain.IDPIntentRepository {
|
|
return new(idpIntentRepository)
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// repository
|
|
// -------------------------------------------------------------
|
|
|
|
const queryIDPIntentStmt = `
|
|
SELECT
|
|
identity_provider_intents.instance_id
|
|
, identity_provider_intents.id
|
|
, identity_provider_intents.state
|
|
, identity_provider_intents.success_url
|
|
, identity_provider_intents.failure_url
|
|
, identity_provider_intents.created_at
|
|
, identity_provider_intents.updated_at
|
|
, identity_provider_intents.idp_id
|
|
, identity_provider_intents.idp_arguments
|
|
, identity_provider_intents.idp_user
|
|
, identity_provider_intents.idp_user_id
|
|
, identity_provider_intents.idp_username
|
|
, identity_provider_intents.user_id
|
|
, identity_provider_intents.idp_access_token
|
|
, identity_provider_intents.idp_id_token
|
|
, identity_provider_intents.idp_entry_attributes
|
|
, identity_provider_intents.request_id
|
|
, identity_provider_intents.assertion
|
|
, identity_provider_intents.succeeded_at
|
|
, identity_provider_intents.failed_at
|
|
, identity_provider_intents.fail_reason
|
|
, identity_provider_intents.expires_at
|
|
FROM
|
|
zitadel.identity_provider_intents
|
|
`
|
|
|
|
// Create implements [domain.IDPIntentRepository].
|
|
func (i idpIntentRepository) Create(ctx context.Context, client database.QueryExecutor, intent *domain.IDPIntent) error {
|
|
var createdAt any = database.DefaultInstruction
|
|
if !intent.CreatedAt.IsZero() {
|
|
createdAt = intent.CreatedAt
|
|
}
|
|
var updatedAt = createdAt
|
|
if !intent.UpdatedAt.IsZero() {
|
|
updatedAt = intent.UpdatedAt
|
|
}
|
|
|
|
builder := new(database.StatementBuilder)
|
|
builder.WriteString(`INSERT INTO `)
|
|
builder.WriteString(i.qualifiedTableName())
|
|
builder.WriteString(` (instance_id, id, success_url, failure_url, idp_id, idp_arguments, created_at, updated_at) VALUES ( `)
|
|
builder.WriteArgs(intent.InstanceID, intent.ID, intent.SuccessURL.String(), intent.FailureURL.String(), intent.IDPID, intent.IDPArguments, createdAt, updatedAt)
|
|
builder.WriteString(` ) RETURNING created_at, updated_at`)
|
|
return client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(&intent.CreatedAt, &intent.UpdatedAt)
|
|
}
|
|
|
|
// Delete implements [domain.IDPIntentRepository].
|
|
func (i idpIntentRepository) Delete(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) {
|
|
return deleteOne(ctx, client, i, condition)
|
|
}
|
|
|
|
// Get implements [domain.IDPIntentRepository].
|
|
func (i idpIntentRepository) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.IDPIntent, error) {
|
|
options := new(database.QueryOpts)
|
|
for _, opt := range opts {
|
|
opt(options)
|
|
}
|
|
|
|
if options.Condition == nil || !options.Condition.IsRestrictingColumn(i.InstanceIDColumn()) {
|
|
return nil, database.NewMissingConditionError(i.InstanceIDColumn())
|
|
}
|
|
|
|
var builder database.StatementBuilder
|
|
builder.WriteString(queryIDPIntentStmt)
|
|
options.Write(&builder)
|
|
|
|
return scanIDPIntent(ctx, client, &builder)
|
|
}
|
|
|
|
type rawIDPIntent struct {
|
|
*domain.IDPIntent
|
|
SuccessURL string `json:"success_url,omitempty" db:"success_url"`
|
|
FailureURL string `json:"failure_url,omitempty" db:"failure_url"`
|
|
IDPUserID *string `json:"idp_user_id,omitempty" db:"idp_user_id"`
|
|
IDPUsername *string `json:"idp_username,omitempty" db:"idp_username"`
|
|
UserID *string `json:"user_id,omitempty" db:"user_id"`
|
|
IDPIDToken *string `json:"idp_id_token,omitempty" db:"idp_id_token"`
|
|
RequestID *string `json:"request_id,omitempty" db:"request_id"`
|
|
FailReason *string `json:"fail_reason,omitempty" db:"fail_reason"`
|
|
}
|
|
|
|
func scanIDPIntent(ctx context.Context, querier database.QueryExecutor, builder *database.StatementBuilder) (*domain.IDPIntent, error) {
|
|
rows, err := querier.Query(ctx, builder.String(), builder.Args()...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
raw := new(rawIDPIntent)
|
|
if err := rows.(database.CollectableRows).CollectExactlyOneRow(raw); err != nil {
|
|
return nil, err
|
|
}
|
|
return rawIDPIntentToDomain(raw)
|
|
}
|
|
|
|
func rawIDPIntentToDomain(raw *rawIDPIntent) (*domain.IDPIntent, error) {
|
|
successURL, _ := url.Parse(raw.SuccessURL)
|
|
failureURL, _ := url.Parse(raw.FailureURL)
|
|
raw.IDPIntent.SuccessURL = successURL
|
|
raw.IDPIntent.FailureURL = failureURL
|
|
raw.IDPIntent.IDPUserID = gu.Value(raw.IDPUserID)
|
|
raw.IDPIntent.IDPUsername = gu.Value(raw.IDPUsername)
|
|
raw.IDPIntent.UserID = gu.Value(raw.UserID)
|
|
raw.IDPIntent.IDPIDToken = gu.Value(raw.IDPIDToken)
|
|
raw.IDPIntent.RequestID = gu.Value(raw.RequestID)
|
|
raw.IDPIntent.FailReason = gu.Value(raw.FailReason)
|
|
|
|
return raw.IDPIntent, nil
|
|
}
|
|
|
|
// Update implements [domain.IDPIntentRepository].
|
|
func (i idpIntentRepository) Update(ctx context.Context, client database.QueryExecutor, condition database.Condition, changes ...database.Change) (int64, error) {
|
|
if changes == nil {
|
|
return 0, database.ErrNoChanges
|
|
}
|
|
if condition == nil || !condition.IsRestrictingColumn(i.InstanceIDColumn()) {
|
|
return 0, database.NewMissingConditionError(i.InstanceIDColumn())
|
|
}
|
|
if !database.Changes(changes).IsOnColumn(i.UpdatedAtColumn()) {
|
|
changes = append(changes, database.NewChange(i.UpdatedAtColumn(), database.DefaultInstruction))
|
|
}
|
|
|
|
builder := database.StatementBuilder{}
|
|
builder.WriteString(`UPDATE zitadel.identity_provider_intents SET `)
|
|
|
|
err := database.Changes(changes).Write(&builder)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
writeCondition(&builder, condition)
|
|
|
|
return client.Exec(ctx, builder.String(), builder.Args()...)
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// changes
|
|
// -------------------------------------------------------------
|
|
|
|
// SetAssertion implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetAssertion(assertion []byte) database.Change {
|
|
return database.NewChange(i.AssertionColumn(), assertion)
|
|
}
|
|
|
|
// SetFailureURL implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetFailureURL(failureURL url.URL) database.Change {
|
|
return database.NewChange(i.FailureURLColumn(), failureURL.String())
|
|
}
|
|
|
|
// SetIDPAccessToken implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPAccessToken(idpAccessToken []byte) database.Change {
|
|
return database.NewChange(i.IDPAccessTokenColumn(), idpAccessToken)
|
|
}
|
|
|
|
// SetIDPIDToken implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) SetIDPIDToken(idpIDToken string) database.Change {
|
|
return database.NewChange(i.IDPIDTokenColumn(), idpIDToken)
|
|
}
|
|
|
|
// SetIDPArguments implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPArguments(idpArguments []byte) database.Change {
|
|
return database.NewChange(i.IDPArgumentsColumn(), idpArguments)
|
|
}
|
|
|
|
// SetIDPEntryAttributes implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPEntryAttributes(idpEntryAttributes []byte) database.Change {
|
|
return database.NewChange(i.IDPEntryAttributesColumn(), idpEntryAttributes)
|
|
}
|
|
|
|
// SetIDPID implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPID(idpID string) database.Change {
|
|
return database.NewChange(i.IDPIDColumn(), idpID)
|
|
}
|
|
|
|
// SetIDPUser implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPUser(idpUser []byte) database.Change {
|
|
return database.NewChange(i.IDPUserColumn(), idpUser)
|
|
}
|
|
|
|
// SetIDPUserID implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPUserID(idpUserID string) database.Change {
|
|
return database.NewChange(i.IDPUserIDColumn(), idpUserID)
|
|
}
|
|
|
|
// SetIDPUsername implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetIDPUsername(idpUsername string) database.Change {
|
|
return database.NewChange(i.IDPUsernameColumn(), idpUsername)
|
|
}
|
|
|
|
// SetRequestID implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetRequestID(requestID string) database.Change {
|
|
return database.NewChange(i.RequestIDColumn(), requestID)
|
|
}
|
|
|
|
// SetState implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetState(state domain.IDPIntentState) database.Change {
|
|
return database.NewChange(i.StateColumn(), state)
|
|
}
|
|
|
|
// SetSuccessURL implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetSuccessURL(successURL url.URL) database.Change {
|
|
return database.NewChange(i.SuccessURLColumn(), successURL.String())
|
|
}
|
|
|
|
// SetUserID implements [domain.idpIntentChanges].
|
|
func (i idpIntentRepository) SetUserID(userID string) database.Change {
|
|
return database.NewChange(i.UserIDColumn(), userID)
|
|
}
|
|
|
|
// SetExpiresAt implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) SetExpiresAt(expiration time.Time) database.Change {
|
|
return database.NewChange(i.ExpiresAtColumn(), expiration)
|
|
}
|
|
|
|
// SetSucceededAt implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) SetSucceededAt(succeededAt time.Time) database.Change {
|
|
return database.NewChange(i.SucceededAtColumn(), succeededAt)
|
|
}
|
|
|
|
// SetFailedAt implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) SetFailedAt(failedAt time.Time) database.Change {
|
|
return database.NewChange(i.FailedAtColumn(), failedAt)
|
|
}
|
|
|
|
// SetFailReason implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) SetFailReason(reason string) database.Change {
|
|
return database.NewChange(i.FailReasonColumn(), reason)
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// conditions
|
|
// -------------------------------------------------------------
|
|
|
|
// CreatedAtCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) CreatedAtCondition(op database.NumberOperation, createdAt time.Time) database.Condition {
|
|
return database.NewNumberCondition(i.CreatedAtColumn(), op, createdAt)
|
|
}
|
|
|
|
// IDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) IDCondition(id string) database.Condition {
|
|
return database.NewTextCondition(i.IDColumn(), database.TextOperationEqual, id)
|
|
}
|
|
|
|
// IDPIDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) IDPIDCondition(idpID string) database.Condition {
|
|
return database.NewTextCondition(i.IDPIDColumn(), database.TextOperationEqual, idpID)
|
|
}
|
|
|
|
// IDPUserIDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) IDPUserIDCondition(idpUserID string) database.Condition {
|
|
return database.NewTextCondition(i.IDPUserIDColumn(), database.TextOperationEqual, idpUserID)
|
|
}
|
|
|
|
// IDPUsernameCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) IDPUsernameCondition(idpUsername string) database.Condition {
|
|
return database.NewTextCondition(i.IDPUsernameColumn(), database.TextOperationEqual, idpUsername)
|
|
}
|
|
|
|
// InstanceIDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) InstanceIDCondition(instanceID string) database.Condition {
|
|
return database.NewTextCondition(i.InstanceIDColumn(), database.TextOperationEqual, instanceID)
|
|
}
|
|
|
|
// PrimaryKeyCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) PrimaryKeyCondition(instanceID, id string) database.Condition {
|
|
return database.And(
|
|
i.InstanceIDCondition(instanceID),
|
|
i.IDCondition(id),
|
|
)
|
|
}
|
|
|
|
// RequestIDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) RequestIDCondition(requestID string) database.Condition {
|
|
return database.NewTextCondition(i.RequestIDColumn(), database.TextOperationEqual, requestID)
|
|
}
|
|
|
|
// StateCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) StateCondition(state domain.IDPIntentState) database.Condition {
|
|
return database.NewTextCondition(i.StateColumn(), database.TextOperationEqual, state.String())
|
|
}
|
|
|
|
// UpdatedAtCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) UpdatedAtCondition(op database.NumberOperation, updatedAt time.Time) database.Condition {
|
|
return database.NewNumberCondition(i.UpdatedAtColumn(), op, updatedAt)
|
|
}
|
|
|
|
// UserIDCondition implements [domain.idpIntentConditions].
|
|
func (i idpIntentRepository) UserIDCondition(userID string) database.Condition {
|
|
return database.NewTextCondition(i.UserIDColumn(), database.TextOperationEqual, userID)
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// columns
|
|
// -------------------------------------------------------------
|
|
|
|
// AssertionColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) AssertionColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "assertion")
|
|
}
|
|
|
|
// CreatedAtColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) CreatedAtColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "created_at")
|
|
}
|
|
|
|
// ExpiresAtColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) ExpiresAtColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "expires_at")
|
|
}
|
|
|
|
// FailureURLColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) FailureURLColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "failure_url")
|
|
}
|
|
|
|
// IDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "id")
|
|
}
|
|
|
|
// IDPAccessTokenColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPAccessTokenColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_access_token")
|
|
}
|
|
|
|
// IDPIDTokenColumn implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) IDPIDTokenColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_id_token")
|
|
}
|
|
|
|
// IDPArgumentsColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPArgumentsColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_arguments")
|
|
}
|
|
|
|
// IDPEntryAttributesColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPEntryAttributesColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_entry_attributes")
|
|
}
|
|
|
|
// IDPIDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPIDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_id")
|
|
}
|
|
|
|
// IDPUserColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPUserColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_user")
|
|
}
|
|
|
|
// IDPUserIDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPUserIDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_user_id")
|
|
}
|
|
|
|
// IDPUsernameColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) IDPUsernameColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "idp_username")
|
|
}
|
|
|
|
// InstanceIDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) InstanceIDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "instance_id")
|
|
}
|
|
|
|
// PrimaryKeyColumns implements [domain.IDPIntentRepository].
|
|
func (i idpIntentRepository) PrimaryKeyColumns() []database.Column {
|
|
return []database.Column{i.IDColumn(), i.InstanceIDColumn()}
|
|
}
|
|
|
|
// RequestIDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) RequestIDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "request_id")
|
|
}
|
|
|
|
// StateColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) StateColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "state")
|
|
}
|
|
|
|
// SucceededAtColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) SucceededAtColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "succeeded_at")
|
|
}
|
|
|
|
// SuccessURLColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) SuccessURLColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "success_url")
|
|
}
|
|
|
|
// FailReasonColumn implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) FailReasonColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "fail_reason")
|
|
}
|
|
|
|
// FailedAtColumn implements [domain.IDPIntentRepository].
|
|
func (i *idpIntentRepository) FailedAtColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "failed_at")
|
|
}
|
|
|
|
// UpdatedAtColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) UpdatedAtColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "updated_at")
|
|
}
|
|
|
|
// UserIDColumn implements [domain.idpIntentColumns].
|
|
func (i idpIntentRepository) UserIDColumn() database.Column {
|
|
return database.NewColumn(i.unqualifiedTableName(), "user_id")
|
|
}
|
|
|
|
var _ domain.IDPIntentRepository = (*idpIntentRepository)(nil)
|