mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-05 10:02:12 +00:00
296 lines
8.6 KiB
Go
296 lines
8.6 KiB
Go
|
|
package query
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"database/sql"
|
||
|
|
errs "errors"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
sq "github.com/Masterminds/squirrel"
|
||
|
|
"github.com/caos/zitadel/internal/domain"
|
||
|
|
"github.com/caos/zitadel/internal/errors"
|
||
|
|
"github.com/caos/zitadel/internal/query/projection"
|
||
|
|
"github.com/lib/pq"
|
||
|
|
)
|
||
|
|
|
||
|
|
type LoginPolicy struct {
|
||
|
|
OrgID string
|
||
|
|
CreationDate time.Time
|
||
|
|
ChangeDate time.Time
|
||
|
|
Sequence uint64
|
||
|
|
AllowRegister bool
|
||
|
|
AllowUsernamePassword bool
|
||
|
|
AllowExternalIDPs bool
|
||
|
|
ForceMFA bool
|
||
|
|
SecondFactors []domain.SecondFactorType
|
||
|
|
MultiFactors []domain.MultiFactorType
|
||
|
|
PasswordlessType domain.PasswordlessType
|
||
|
|
IsDefault bool
|
||
|
|
HidePasswordReset bool
|
||
|
|
}
|
||
|
|
|
||
|
|
type SecondFactors struct {
|
||
|
|
SearchResponse
|
||
|
|
Factors []domain.SecondFactorType
|
||
|
|
}
|
||
|
|
|
||
|
|
type MultiFactors struct {
|
||
|
|
SearchResponse
|
||
|
|
Factors []domain.MultiFactorType
|
||
|
|
}
|
||
|
|
|
||
|
|
var (
|
||
|
|
loginPolicyTable = table{
|
||
|
|
name: projection.LoginPolicyTable,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnOrgID = Column{
|
||
|
|
name: projection.LoginPolicyIDCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnCreationDate = Column{
|
||
|
|
name: projection.LoginPolicyCreationDateCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnChangeDate = Column{
|
||
|
|
name: projection.LoginPolicyChangeDateCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnSequence = Column{
|
||
|
|
name: projection.LoginPolicySequenceCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnAllowRegister = Column{
|
||
|
|
name: projection.LoginPolicyAllowRegisterCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnAllowUsernamePassword = Column{
|
||
|
|
name: projection.LoginPolicyAllowUsernamePasswordCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnAllowExternalIDPs = Column{
|
||
|
|
name: projection.LoginPolicyAllowExternalIDPsCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnForceMFA = Column{
|
||
|
|
name: projection.LoginPolicyForceMFACol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnSecondFactors = Column{
|
||
|
|
name: projection.LoginPolicy2FAsCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnMultiFactors = Column{
|
||
|
|
name: projection.LoginPolicyMFAsCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnPasswordlessType = Column{
|
||
|
|
name: projection.LoginPolicyPasswordlessTypeCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnIsDefault = Column{
|
||
|
|
name: projection.LoginPolicyIsDefaultCol,
|
||
|
|
}
|
||
|
|
LoginPolicyColumnHidePasswordReset = Column{
|
||
|
|
name: projection.LoginPolicyHidePWResetCol,
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
func (q *Queries) LoginPolicyByID(ctx context.Context, orgID string) (*LoginPolicy, error) {
|
||
|
|
query, scan := prepareLoginPolicyQuery()
|
||
|
|
stmt, args, err := query.Where(
|
||
|
|
sq.Or{
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): orgID,
|
||
|
|
},
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
},
|
||
|
|
}).
|
||
|
|
OrderBy(LoginPolicyColumnIsDefault.identifier()).
|
||
|
|
Limit(1).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-scVHo", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (q *Queries) DefaultLoginPolicy(ctx context.Context) (*LoginPolicy, error) {
|
||
|
|
query, scan := prepareLoginPolicyQuery()
|
||
|
|
stmt, args, err := query.Where(sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-t4TBK", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (q *Queries) SecondFactorsByID(ctx context.Context, orgID string) (*SecondFactors, error) {
|
||
|
|
query, scan := prepareLoginPolicy2FAsQuery()
|
||
|
|
stmt, args, err := query.Where(
|
||
|
|
sq.Or{
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): orgID,
|
||
|
|
},
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
},
|
||
|
|
}).
|
||
|
|
OrderBy(LoginPolicyColumnIsDefault.identifier()).
|
||
|
|
Limit(1).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-scVHo", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (q *Queries) DefaultSecondFactors(ctx context.Context) (*SecondFactors, error) {
|
||
|
|
query, scan := prepareLoginPolicy2FAsQuery()
|
||
|
|
stmt, args, err := query.Where(sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-CZ2Nv", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (q *Queries) MultiFactorsByID(ctx context.Context, orgID string) (*MultiFactors, error) {
|
||
|
|
query, scan := prepareLoginPolicyMFAsQuery()
|
||
|
|
stmt, args, err := query.Where(
|
||
|
|
sq.Or{
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): orgID,
|
||
|
|
},
|
||
|
|
sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
},
|
||
|
|
}).
|
||
|
|
OrderBy(LoginPolicyColumnIsDefault.identifier()).
|
||
|
|
Limit(1).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-B4o7h", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (q *Queries) DefaultMultiFactors(ctx context.Context) (*MultiFactors, error) {
|
||
|
|
query, scan := prepareLoginPolicyMFAsQuery()
|
||
|
|
stmt, args, err := query.Where(sq.Eq{
|
||
|
|
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
|
||
|
|
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
|
||
|
|
if err != nil {
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-WxYjr", "Errors.Query.SQLStatement")
|
||
|
|
}
|
||
|
|
|
||
|
|
row := q.client.QueryRowContext(ctx, stmt, args...)
|
||
|
|
return scan(row)
|
||
|
|
}
|
||
|
|
|
||
|
|
func prepareLoginPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*LoginPolicy, error)) {
|
||
|
|
return sq.Select(
|
||
|
|
LoginPolicyColumnOrgID.identifier(),
|
||
|
|
LoginPolicyColumnCreationDate.identifier(),
|
||
|
|
LoginPolicyColumnChangeDate.identifier(),
|
||
|
|
LoginPolicyColumnSequence.identifier(),
|
||
|
|
LoginPolicyColumnAllowRegister.identifier(),
|
||
|
|
LoginPolicyColumnAllowUsernamePassword.identifier(),
|
||
|
|
LoginPolicyColumnAllowExternalIDPs.identifier(),
|
||
|
|
LoginPolicyColumnForceMFA.identifier(),
|
||
|
|
LoginPolicyColumnSecondFactors.identifier(),
|
||
|
|
LoginPolicyColumnMultiFactors.identifier(),
|
||
|
|
LoginPolicyColumnPasswordlessType.identifier(),
|
||
|
|
LoginPolicyColumnIsDefault.identifier(),
|
||
|
|
LoginPolicyColumnHidePasswordReset.identifier(),
|
||
|
|
).From(loginPolicyTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||
|
|
func(row *sql.Row) (*LoginPolicy, error) {
|
||
|
|
p := new(LoginPolicy)
|
||
|
|
secondFactors := pq.Int32Array{}
|
||
|
|
multiFactors := pq.Int32Array{}
|
||
|
|
err := row.Scan(
|
||
|
|
&p.OrgID,
|
||
|
|
&p.CreationDate,
|
||
|
|
&p.ChangeDate,
|
||
|
|
&p.Sequence,
|
||
|
|
&p.AllowRegister,
|
||
|
|
&p.AllowUsernamePassword,
|
||
|
|
&p.AllowExternalIDPs,
|
||
|
|
&p.ForceMFA,
|
||
|
|
&secondFactors,
|
||
|
|
&multiFactors,
|
||
|
|
&p.PasswordlessType,
|
||
|
|
&p.IsDefault,
|
||
|
|
&p.HidePasswordReset,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
if errs.Is(err, sql.ErrNoRows) {
|
||
|
|
return nil, errors.ThrowNotFound(err, "QUERY-QsUBJ", "Errors.LoginPolicy.NotFound")
|
||
|
|
}
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-YcC53", "Errors.Internal")
|
||
|
|
}
|
||
|
|
|
||
|
|
p.MultiFactors = make([]domain.MultiFactorType, len(multiFactors))
|
||
|
|
for i, mfa := range multiFactors {
|
||
|
|
p.MultiFactors[i] = domain.MultiFactorType(mfa)
|
||
|
|
}
|
||
|
|
p.SecondFactors = make([]domain.SecondFactorType, len(secondFactors))
|
||
|
|
for i, mfa := range secondFactors {
|
||
|
|
p.SecondFactors[i] = domain.SecondFactorType(mfa)
|
||
|
|
}
|
||
|
|
return p, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func prepareLoginPolicy2FAsQuery() (sq.SelectBuilder, func(*sql.Row) (*SecondFactors, error)) {
|
||
|
|
return sq.Select(
|
||
|
|
LoginPolicyColumnSequence.identifier(),
|
||
|
|
LoginPolicyColumnSecondFactors.identifier(),
|
||
|
|
).From(loginPolicyTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||
|
|
func(row *sql.Row) (*SecondFactors, error) {
|
||
|
|
p := new(SecondFactors)
|
||
|
|
secondFactors := pq.Int32Array{}
|
||
|
|
err := row.Scan(
|
||
|
|
&p.Sequence,
|
||
|
|
&secondFactors,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
if errs.Is(err, sql.ErrNoRows) {
|
||
|
|
return nil, errors.ThrowNotFound(err, "QUERY-yPqIZ", "Errors.LoginPolicy.NotFound")
|
||
|
|
}
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-Mr6H3", "Errors.Internal")
|
||
|
|
}
|
||
|
|
|
||
|
|
p.Factors = make([]domain.SecondFactorType, len(secondFactors))
|
||
|
|
for i, mfa := range secondFactors {
|
||
|
|
p.Factors[i] = domain.SecondFactorType(mfa)
|
||
|
|
}
|
||
|
|
return p, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func prepareLoginPolicyMFAsQuery() (sq.SelectBuilder, func(*sql.Row) (*MultiFactors, error)) {
|
||
|
|
return sq.Select(
|
||
|
|
LoginPolicyColumnSequence.identifier(),
|
||
|
|
LoginPolicyColumnMultiFactors.identifier(),
|
||
|
|
).From(loginPolicyTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||
|
|
func(row *sql.Row) (*MultiFactors, error) {
|
||
|
|
p := new(MultiFactors)
|
||
|
|
multiFactors := pq.Int32Array{}
|
||
|
|
err := row.Scan(
|
||
|
|
&p.Sequence,
|
||
|
|
&multiFactors,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
if errs.Is(err, sql.ErrNoRows) {
|
||
|
|
return nil, errors.ThrowNotFound(err, "QUERY-yPqIZ", "Errors.LoginPolicy.NotFound")
|
||
|
|
}
|
||
|
|
return nil, errors.ThrowInternal(err, "QUERY-Mr6H3", "Errors.Internal")
|
||
|
|
}
|
||
|
|
|
||
|
|
p.Factors = make([]domain.MultiFactorType, len(multiFactors))
|
||
|
|
for i, mfa := range multiFactors {
|
||
|
|
p.Factors[i] = domain.MultiFactorType(mfa)
|
||
|
|
}
|
||
|
|
return p, nil
|
||
|
|
}
|
||
|
|
}
|