zitadel/internal/query/features.go
Livio Amstutz 958362e6c9
feat: handle instance from context (#3382)
* commander

* commander

* selber!

* move to packages

* fix(errors): implement Is interface

* test: command

* test: commands

* add init steps

* setup tenant

* add default step yaml

* possibility to set password

* merge v2 into v2-commander

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: search query builder can filter events in memory

* fix: filters for add member

* fix(setup): add `ExternalSecure` to config

* chore: name iam to instance

* fix: matching

* remove unsued func

* base url

* base url

* test(command): filter funcs

* test: commands

* fix: rename orgiampolicy to domain policy

* start from init

* commands

* config

* fix indexes and add constraints

* fixes

* fix: merge conflicts

* fix: protos

* fix: md files

* setup

* add deprecated org iam policy again

* typo

* fix search query

* fix filter

* Apply suggestions from code review

* remove custom org from org setup

* add todos for verification

* change apps creation

* simplify package structure

* fix error

* move preparation helper for tests

* fix unique constraints

* fix config mapping in setup

* fix error handling in encryption_keys.go

* fix projection config

* fix query from old views to projection

* fix setup of mgmt api

* set iam project and fix instance projection

* fix tokens view

* fix steps.yaml and defaults.yaml

* fix projections

* change instance context to interface

* instance interceptors and additional events in setup

* cleanup

* tests for interceptors

* fix label policy

* add todo

* single api endpoint in environment.json

Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
2022-03-29 11:53:19 +02:00

328 lines
9.1 KiB
Go

package query
import (
"context"
"database/sql"
errs "errors"
"time"
sq "github.com/Masterminds/squirrel"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/query/projection"
)
type Features struct {
AggregateID string
ChangeDate time.Time
Sequence uint64
IsDefault bool
TierName string
TierDescription string
State domain.FeaturesState
StateDescription string
AuditLogRetention time.Duration
LoginPolicyFactors bool
LoginPolicyIDP bool
LoginPolicyPasswordless bool
LoginPolicyRegistration bool
LoginPolicyUsernameLogin bool
LoginPolicyPasswordReset bool
PasswordComplexityPolicy bool
LabelPolicyPrivateLabel bool
LabelPolicyWatermark bool
CustomDomain bool
PrivacyPolicy bool
MetadataUser bool
CustomTextMessage bool
CustomTextLogin bool
LockoutPolicy bool
ActionsAllowed domain.ActionsAllowed
MaxActions int32
}
var (
featureTable = table{
name: projection.FeatureTable,
}
FeatureColumnAggregateID = Column{
name: projection.FeatureAggregateIDCol,
table: featureTable,
}
FeatureColumnInstanceID = Column{
name: projection.FeatureInstanceIDCol,
table: featureTable,
}
FeatureColumnChangeDate = Column{
name: projection.FeatureChangeDateCol,
table: featureTable,
}
FeatureColumnSequence = Column{
name: projection.FeatureSequenceCol,
table: featureTable,
}
FeatureColumnIsDefault = Column{
name: projection.FeatureIsDefaultCol,
table: featureTable,
}
FeatureTierName = Column{
name: projection.FeatureTierNameCol,
table: featureTable,
}
FeatureTierDescription = Column{
name: projection.FeatureTierDescriptionCol,
table: featureTable,
}
FeatureState = Column{
name: projection.FeatureStateCol,
table: featureTable,
}
FeatureStateDescription = Column{
name: projection.FeatureStateDescriptionCol,
table: featureTable,
}
FeatureAuditLogRetention = Column{
name: projection.FeatureAuditLogRetentionCol,
table: featureTable,
}
FeatureLoginPolicyFactors = Column{
name: projection.FeatureLoginPolicyFactorsCol,
table: featureTable,
}
FeatureLoginPolicyIDP = Column{
name: projection.FeatureLoginPolicyIDPCol,
table: featureTable,
}
FeatureLoginPolicyPasswordless = Column{
name: projection.FeatureLoginPolicyPasswordlessCol,
table: featureTable,
}
FeatureLoginPolicyRegistration = Column{
name: projection.FeatureLoginPolicyRegistrationCol,
table: featureTable,
}
FeatureLoginPolicyUsernameLogin = Column{
name: projection.FeatureLoginPolicyUsernameLoginCol,
table: featureTable,
}
FeatureLoginPolicyPasswordReset = Column{
name: projection.FeatureLoginPolicyPasswordResetCol,
table: featureTable,
}
FeaturePasswordComplexityPolicy = Column{
name: projection.FeaturePasswordComplexityPolicyCol,
table: featureTable,
}
FeatureLabelPolicyPrivateLabel = Column{
name: projection.FeatureLabelPolicyPrivateLabelCol,
table: featureTable,
}
FeatureLabelPolicyWatermark = Column{
name: projection.FeatureLabelPolicyWatermarkCol,
table: featureTable,
}
FeatureCustomDomain = Column{
name: projection.FeatureCustomDomainCol,
table: featureTable,
}
FeaturePrivacyPolicy = Column{
name: projection.FeaturePrivacyPolicyCol,
table: featureTable,
}
FeatureMetadataUser = Column{
name: projection.FeatureMetadataUserCol,
table: featureTable,
}
FeatureCustomTextMessage = Column{
name: projection.FeatureCustomTextMessageCol,
table: featureTable,
}
FeatureCustomTextLogin = Column{
name: projection.FeatureCustomTextLoginCol,
table: featureTable,
}
FeatureLockoutPolicy = Column{
name: projection.FeatureLockoutPolicyCol,
table: featureTable,
}
FeatureActionsAllowed = Column{
name: projection.FeatureActionsAllowedCol,
table: featureTable,
}
FeatureMaxActions = Column{
name: projection.FeatureMaxActionsCol,
table: featureTable,
}
)
func (q *Queries) FeaturesByOrgID(ctx context.Context, orgID string) (*Features, error) {
query, scan := prepareFeaturesQuery()
stmt, args, err := query.Where(
sq.And{
sq.Eq{
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
FeatureColumnAggregateID.identifier(): orgID,
},
sq.Eq{
FeatureColumnAggregateID.identifier(): domain.IAMID,
},
},
}).
OrderBy(FeatureColumnIsDefault.identifier()).
Limit(1).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-P9gwg", "Errors.Query.SQLStatement")
}
row := q.client.QueryRowContext(ctx, stmt, args...)
return scan(row)
}
func (q *Queries) DefaultFeatures(ctx context.Context) (*Features, error) {
query, scan := prepareFeaturesQuery()
stmt, args, err := query.Where(sq.Eq{
FeatureColumnAggregateID.identifier(): domain.IAMID,
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-1Ndlg", "Errors.Query.SQLStatement")
}
row := q.client.QueryRowContext(ctx, stmt, args...)
return scan(row)
}
func prepareFeaturesQuery() (sq.SelectBuilder, func(*sql.Row) (*Features, error)) {
return sq.Select(
FeatureColumnAggregateID.identifier(),
FeatureColumnChangeDate.identifier(),
FeatureColumnSequence.identifier(),
FeatureColumnIsDefault.identifier(),
FeatureTierName.identifier(),
FeatureTierDescription.identifier(),
FeatureState.identifier(),
FeatureStateDescription.identifier(),
FeatureAuditLogRetention.identifier(),
FeatureLoginPolicyFactors.identifier(),
FeatureLoginPolicyIDP.identifier(),
FeatureLoginPolicyPasswordless.identifier(),
FeatureLoginPolicyRegistration.identifier(),
FeatureLoginPolicyUsernameLogin.identifier(),
FeatureLoginPolicyPasswordReset.identifier(),
FeaturePasswordComplexityPolicy.identifier(),
FeatureLabelPolicyPrivateLabel.identifier(),
FeatureLabelPolicyWatermark.identifier(),
FeatureCustomDomain.identifier(),
FeaturePrivacyPolicy.identifier(),
FeatureMetadataUser.identifier(),
FeatureCustomTextMessage.identifier(),
FeatureCustomTextLogin.identifier(),
FeatureLockoutPolicy.identifier(),
FeatureActionsAllowed.identifier(),
FeatureMaxActions.identifier(),
).From(featureTable.identifier()).PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*Features, error) {
p := new(Features)
tierName := sql.NullString{}
tierDescription := sql.NullString{}
stateDescription := sql.NullString{}
err := row.Scan(
&p.AggregateID,
&p.ChangeDate,
&p.Sequence,
&p.IsDefault,
&tierName,
&tierDescription,
&p.State,
&stateDescription,
&p.AuditLogRetention,
&p.LoginPolicyFactors,
&p.LoginPolicyIDP,
&p.LoginPolicyPasswordless,
&p.LoginPolicyRegistration,
&p.LoginPolicyUsernameLogin,
&p.LoginPolicyPasswordReset,
&p.PasswordComplexityPolicy,
&p.LabelPolicyPrivateLabel,
&p.LabelPolicyWatermark,
&p.CustomDomain,
&p.PrivacyPolicy,
&p.MetadataUser,
&p.CustomTextMessage,
&p.CustomTextLogin,
&p.LockoutPolicy,
&p.ActionsAllowed,
&p.MaxActions,
)
if err != nil {
if errs.Is(err, sql.ErrNoRows) {
return nil, errors.ThrowNotFound(err, "QUERY-M9fse", "Errors.Features.NotFound")
}
return nil, errors.ThrowInternal(err, "QUERY-3o9gd", "Errors.Internal")
}
p.TierName = tierName.String
p.TierDescription = tierDescription.String
p.StateDescription = stateDescription.String
return p, nil
}
}
func (f *Features) EnabledFeatureTypes() []string {
list := make([]string, 0)
if f.LoginPolicyFactors {
list = append(list, domain.FeatureLoginPolicyFactors)
}
if f.LoginPolicyIDP {
list = append(list, domain.FeatureLoginPolicyIDP)
}
if f.LoginPolicyPasswordless {
list = append(list, domain.FeatureLoginPolicyPasswordless)
}
if f.LoginPolicyRegistration {
list = append(list, domain.FeatureLoginPolicyRegistration)
}
if f.LoginPolicyUsernameLogin {
list = append(list, domain.FeatureLoginPolicyUsernameLogin)
}
if f.LoginPolicyPasswordReset {
list = append(list, domain.FeatureLoginPolicyPasswordReset)
}
if f.PasswordComplexityPolicy {
list = append(list, domain.FeaturePasswordComplexityPolicy)
}
if f.LabelPolicyPrivateLabel {
list = append(list, domain.FeatureLabelPolicyPrivateLabel)
}
if f.LabelPolicyWatermark {
list = append(list, domain.FeatureLabelPolicyWatermark)
}
if f.CustomDomain {
list = append(list, domain.FeatureCustomDomain)
}
if f.PrivacyPolicy {
list = append(list, domain.FeaturePrivacyPolicy)
}
if f.MetadataUser {
list = append(list, domain.FeatureMetadataUser)
}
if f.CustomTextMessage {
list = append(list, domain.FeatureCustomTextMessage)
}
if f.CustomTextLogin {
list = append(list, domain.FeatureCustomTextLogin)
}
if f.LockoutPolicy {
list = append(list, domain.FeatureLockoutPolicy)
}
if f.ActionsAllowed != domain.ActionsNotAllowed {
list = append(list, domain.FeatureActions)
}
return list
}