feat(api): allow specifying access_token type (opaque/JWT) for service users (#5150)

Add functionality to configure the access token type on the service accounts to provide the oidc library with the necessary information to create the right type of access token.
This commit is contained in:
Stefan Benz 2023-02-08 09:06:34 +01:00 committed by GitHub
parent da130c2ed9
commit 3616b6b028
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 504 additions and 331 deletions

View File

@ -3586,6 +3586,7 @@ This is an empty request
| user_name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> | | user_name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> | | name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
| description | string | - | string.max_len: 500<br /> | | description | string | - | string.max_len: 500<br /> |
| access_token_type | zitadel.user.v1.AccessTokenType | - | enum.defined_only: true<br /> |
@ -8768,6 +8769,7 @@ This is an empty request
| user_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> | | user_id | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
| description | string | - | string.max_len: 500<br /> | | description | string | - | string.max_len: 500<br /> |
| name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> | | name | string | - | string.min_len: 1<br /> string.max_len: 200<br /> |
| access_token_type | zitadel.user.v1.AccessTokenType | - | enum.defined_only: true<br /> |

View File

@ -134,6 +134,7 @@ title: zitadel/user.proto
| name | string | - | | | name | string | - | |
| description | string | - | | | description | string | - | |
| has_secret | bool | - | | | has_secret | bool | - | |
| access_token_typ | AccessTokenType | - | |
@ -633,6 +634,17 @@ UserTypeQuery is always equals
## Enums ## Enums
### AccessTokenType {#accesstokentype}
| Name | Number | Description |
| ---- | ------ | ----------- |
| ACCESS_TOKEN_TYPE_BEARER | 0 | - |
| ACCESS_TOKEN_TYPE_JWT | 1 | - |
### AuthFactorState {#authfactorstate} ### AuthFactorState {#authfactorstate}

2
go.mod
View File

@ -55,7 +55,7 @@ require (
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
github.com/ttacon/libphonenumber v1.2.1 github.com/ttacon/libphonenumber v1.2.1
github.com/zitadel/logging v0.3.4 github.com/zitadel/logging v0.3.4
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.7 github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.8
github.com/zitadel/saml v0.0.9 github.com/zitadel/saml v0.0.9
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0

2
go.sum
View File

@ -908,6 +908,8 @@ github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM
github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0= github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.7 h1:CGs4gdoSrZZyZM5pGeXCf8FH12r4r8hpJL/wUR3PxRA= github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.7 h1:CGs4gdoSrZZyZM5pGeXCf8FH12r4r8hpJL/wUR3PxRA=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.7/go.mod h1:2jHMP6o/WK0EmcNJkz+FSpjeqcCuQG9YqqqzKZkfgIE= github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.7/go.mod h1:2jHMP6o/WK0EmcNJkz+FSpjeqcCuQG9YqqqzKZkfgIE=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.8 h1:e6sRhY3Lijku8XBzazLoWpJcjO/EniEA7C5UEgiApRY=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.8/go.mod h1:2jHMP6o/WK0EmcNJkz+FSpjeqcCuQG9YqqqzKZkfgIE=
github.com/zitadel/saml v0.0.9 h1:q7FRu52Wm2S5rsSGuzR2nYhEClvexga8bwnGrBL7Bbw= github.com/zitadel/saml v0.0.9 h1:q7FRu52Wm2S5rsSGuzR2nYhEClvexga8bwnGrBL7Bbw=
github.com/zitadel/saml v0.0.9/go.mod h1:DIy/ln32rNYv/bIBA8uOB6Y2JmxjZldDYBeMNn7YyeQ= github.com/zitadel/saml v0.0.9/go.mod h1:DIy/ln32rNYv/bIBA8uOB6Y2JmxjZldDYBeMNn7YyeQ=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=

View File

@ -170,9 +170,10 @@ func AddMachineUserRequestToCommand(req *mgmt_pb.AddMachineUserRequest, resource
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
ResourceOwner: resourceowner, ResourceOwner: resourceowner,
}, },
Username: req.UserName, Username: req.UserName,
Name: req.Name, Name: req.Name,
Description: req.Description, Description: req.Description,
AccessTokenType: user_grpc.AccessTokenTypeToDomain(req.AccessTokenType),
} }
} }
@ -226,8 +227,9 @@ func UpdateMachineRequestToCommand(req *mgmt_pb.UpdateMachineRequest, orgID stri
AggregateID: req.UserId, AggregateID: req.UserId,
ResourceOwner: orgID, ResourceOwner: orgID,
}, },
Name: req.Name, Name: req.Name,
Description: req.Description, Description: req.Description,
AccessTokenType: user_grpc.AccessTokenTypeToDomain(req.AccessTokenType),
} }
} }

View File

@ -70,9 +70,10 @@ func HumanToPb(view *query.Human, assetPrefix, owner string) *user_pb.Human {
func MachineToPb(view *query.Machine) *user_pb.Machine { func MachineToPb(view *query.Machine) *user_pb.Machine {
return &user_pb.Machine{ return &user_pb.Machine{
Name: view.Name, Name: view.Name,
Description: view.Description, Description: view.Description,
HasSecret: view.HasSecret, HasSecret: view.HasSecret,
AccessTokenTyp: AccessTokenTypeToPb(view.AccessTokenType),
} }
} }
@ -129,6 +130,17 @@ func GenderToDomain(gender user_pb.Gender) domain.Gender {
} }
} }
func AccessTokenTypeToDomain(accessTokenType user_pb.AccessTokenType) domain.OIDCTokenType {
switch accessTokenType {
case user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_BEARER:
return domain.OIDCTokenTypeBearer
case user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_JWT:
return domain.OIDCTokenTypeJWT
default:
return -1
}
}
func UserStateToPb(state domain.UserState) user_pb.UserState { func UserStateToPb(state domain.UserState) user_pb.UserState {
switch state { switch state {
case domain.UserStateActive: case domain.UserStateActive:
@ -161,6 +173,17 @@ func GenderToPb(gender domain.Gender) user_pb.Gender {
} }
} }
func AccessTokenTypeToPb(accessTokenType domain.OIDCTokenType) user_pb.AccessTokenType {
switch accessTokenType {
case domain.OIDCTokenTypeBearer:
return user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_BEARER
case domain.OIDCTokenTypeJWT:
return user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_JWT
default:
return user_pb.AccessTokenType_ACCESS_TOKEN_TYPE_BEARER
}
}
func AuthMethodsToPb(mfas *query.AuthMethods) []*user_pb.AuthFactor { func AuthMethodsToPb(mfas *query.AuthMethods) []*user_pb.AuthFactor {
factors := make([]*user_pb.AuthFactor, len(mfas.AuthMethods)) factors := make([]*user_pb.AuthFactor, len(mfas.AuthMethods))
for i, mfa := range mfas.AuthMethods { for i, mfa := range mfas.AuthMethods {

View File

@ -200,9 +200,11 @@ func (o *OPStorage) ClientCredentialsTokenRequest(ctx context.Context, clientID
if err != nil { if err != nil {
return nil, err return nil, err
} }
audience := domain.AddAudScopeToAudience(ctx, nil, scope)
return &clientCredentialsRequest{ return &clientCredentialsRequest{
sub: user.ID, sub: user.ID,
scopes: scope, scopes: scope,
audience: audience,
}, nil }, nil
} }
@ -219,7 +221,8 @@ func (o *OPStorage) ClientCredentials(ctx context.Context, clientID, clientSecre
return nil, err return nil, err
} }
return &clientCredentialsClient{ return &clientCredentialsClient{
id: clientID, id: clientID,
tokenType: accessTokenTypeToOIDC(user.Machine.AccessTokenType),
}, nil }, nil
} }

View File

@ -8,18 +8,20 @@ import (
) )
type clientCredentialsRequest struct { type clientCredentialsRequest struct {
sub string sub string
scopes []string audience []string
scopes []string
} }
// GetSubject returns the subject for token to be created because of the client credentials request
// the subject will be the id of the service user
func (c *clientCredentialsRequest) GetSubject() string { func (c *clientCredentialsRequest) GetSubject() string {
return c.sub return c.sub
} }
// GetAudience returns the audience for token to be created because of the client credentials request // GetAudience returns the audience for token to be created because of the client credentials request
// return nil as the audience is set during the token creation in command.addUserToken
func (c *clientCredentialsRequest) GetAudience() []string { func (c *clientCredentialsRequest) GetAudience() []string {
return nil return c.audience
} }
func (c *clientCredentialsRequest) GetScopes() []string { func (c *clientCredentialsRequest) GetScopes() []string {
@ -27,13 +29,14 @@ func (c *clientCredentialsRequest) GetScopes() []string {
} }
type clientCredentialsClient struct { type clientCredentialsClient struct {
id string id string
tokenType op.AccessTokenType
} }
// AccessTokenType returns the AccessTokenType for the token to be created because of the client credentials request // AccessTokenType returns the AccessTokenType for the token to be created because of the client credentials request
// machine users currently only have opaque tokens ([op.AccessTokenTypeBearer]) // machine users currently only have opaque tokens ([op.AccessTokenTypeBearer])
func (c *clientCredentialsClient) AccessTokenType() op.AccessTokenType { func (c *clientCredentialsClient) AccessTokenType() op.AccessTokenType {
return op.AccessTokenTypeBearer return c.tokenType
} }
// GetID returns the client_id (username of the machine user) for the token to be created because of the client credentials request // GetID returns the client_id (username of the machine user) for the token to be created because of the client credentials request

View File

@ -0,0 +1,33 @@
package oidc
import (
"context"
"github.com/zitadel/oidc/v2/pkg/oidc"
"github.com/zitadel/oidc/v2/pkg/op"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/errors"
)
func (o *OPStorage) JWTProfileTokenType(ctx context.Context, request op.TokenRequest) (op.AccessTokenType, error) {
mapJWTProfileScopesToAudience(ctx, request)
user, err := o.query.GetUserByID(ctx, false, request.GetSubject(), false)
if err != nil {
return 0, err
}
// the user should always be a machine, but let's just be sure
if user.Machine == nil {
return 0, errors.ThrowInvalidArgument(nil, "OIDC-jk26S", "invalid client type")
}
return accessTokenTypeToOIDC(user.Machine.AccessTokenType), nil
}
func mapJWTProfileScopesToAudience(ctx context.Context, request op.TokenRequest) {
// the request should always be a JWTTokenRequest, but let's make sure
jwt, ok := request.(*oidc.JWTTokenRequest)
if !ok {
return
}
jwt.Audience = domain.AddAudScopeToAudience(ctx, jwt.Audience, jwt.Scopes)
}

View File

@ -109,6 +109,7 @@ func TestAddMember(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
}, nil }, nil
}). }).
@ -148,6 +149,7 @@ func TestAddMember(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
}, nil }, nil
}). }).

View File

@ -1250,6 +1250,7 @@ func TestCommandSide_RemoveOrg(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),

View File

@ -20,9 +20,10 @@ type AddMachine struct {
type Machine struct { type Machine struct {
models.ObjectRoot models.ObjectRoot
Username string Username string
Name string Name string
Description string Description string
AccessTokenType domain.OIDCTokenType
} }
func (m *Machine) IsZero() bool { func (m *Machine) IsZero() bool {
@ -56,7 +57,7 @@ func AddMachineCommand(a *user.Aggregate, machine *Machine) preparation.Validati
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-3M9fs", "Errors.Org.DomainPolicy.NotFound") return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-3M9fs", "Errors.Org.DomainPolicy.NotFound")
} }
return []eventstore.Command{ return []eventstore.Command{
user.NewMachineAddedEvent(ctx, &a.Aggregate, machine.Username, machine.Name, machine.Description, domainPolicy.UserLoginMustBeDomain), user.NewMachineAddedEvent(ctx, &a.Aggregate, machine.Username, machine.Name, machine.Description, domainPolicy.UserLoginMustBeDomain, machine.AccessTokenType),
}, nil }, nil
}, nil }, nil
} }
@ -124,7 +125,7 @@ func changeMachineCommand(a *user.Aggregate, machine *Machine) preparation.Valid
if !isUserStateExists(writeModel.UserState) { if !isUserStateExists(writeModel.UserState) {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-5M0od", "Errors.User.NotFound") return nil, caos_errs.ThrowNotFound(nil, "COMMAND-5M0od", "Errors.User.NotFound")
} }
changedEvent, hasChanged, err := writeModel.NewChangedEvent(ctx, &a.Aggregate, machine.Name, machine.Description) changedEvent, hasChanged, err := writeModel.NewChangedEvent(ctx, &a.Aggregate, machine.Name, machine.Description, machine.AccessTokenType)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -135,6 +135,7 @@ func TestCommands_AddMachineKey(t *testing.T) {
"Machine", "Machine",
"", "",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -187,6 +188,7 @@ func TestCommands_AddMachineKey(t *testing.T) {
"Machine", "Machine",
"", "",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),

View File

@ -15,9 +15,10 @@ type MachineWriteModel struct {
UserName string UserName string
Name string Name string
Description string Description string
UserState domain.UserState UserState domain.UserState
AccessTokenType domain.OIDCTokenType
ClientSecret *crypto.CryptoValue ClientSecret *crypto.CryptoValue
} }
@ -38,6 +39,7 @@ func (wm *MachineWriteModel) Reduce() error {
wm.UserName = e.UserName wm.UserName = e.UserName
wm.Name = e.Name wm.Name = e.Name
wm.Description = e.Description wm.Description = e.Description
wm.AccessTokenType = e.AccessTokenType
wm.UserState = domain.UserStateActive wm.UserState = domain.UserStateActive
case *user.UsernameChangedEvent: case *user.UsernameChangedEvent:
wm.UserName = e.UserName wm.UserName = e.UserName
@ -48,6 +50,9 @@ func (wm *MachineWriteModel) Reduce() error {
if e.Description != nil { if e.Description != nil {
wm.Description = *e.Description wm.Description = *e.Description
} }
if e.AccessTokenType != nil {
wm.AccessTokenType = *e.AccessTokenType
}
case *user.UserLockedEvent: case *user.UserLockedEvent:
if wm.UserState != domain.UserStateDeleted { if wm.UserState != domain.UserStateDeleted {
wm.UserState = domain.UserStateLocked wm.UserState = domain.UserStateLocked
@ -99,6 +104,7 @@ func (wm *MachineWriteModel) NewChangedEvent(
aggregate *eventstore.Aggregate, aggregate *eventstore.Aggregate,
name, name,
description string, description string,
accessTokenType domain.OIDCTokenType,
) (*user.MachineChangedEvent, bool, error) { ) (*user.MachineChangedEvent, bool, error) {
changes := make([]user.MachineChanges, 0) changes := make([]user.MachineChanges, 0)
var err error var err error
@ -109,6 +115,9 @@ func (wm *MachineWriteModel) NewChangedEvent(
if wm.Description != description { if wm.Description != description {
changes = append(changes, user.ChangeDescription(description)) changes = append(changes, user.ChangeDescription(description))
} }
if wm.AccessTokenType != accessTokenType {
changes = append(changes, user.ChangeAccessTokenType(accessTokenType))
}
if len(changes) == 0 { if len(changes) == 0 {
return nil, false, nil return nil, false, nil
} }

View File

@ -104,6 +104,7 @@ func TestCommandSide_GenerateMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -244,6 +245,7 @@ func TestCommandSide_RemoveMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -271,6 +273,7 @@ func TestCommandSide_RemoveMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
eventFromEventPusher( eventFromEventPusher(
@ -409,6 +412,7 @@ func TestCommandSide_VerifyMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -436,6 +440,7 @@ func TestCommandSide_VerifyMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
eventFromEventPusher( eventFromEventPusher(
@ -486,6 +491,7 @@ func TestCommandSide_VerifyMachineSecret(t *testing.T) {
"username", "username",
"user", "user",
false, false,
domain.OIDCTokenTypeBearer,
), ),
), ),
eventFromEventPusher( eventFromEventPusher(

View File

@ -128,6 +128,7 @@ func TestCommandSide_AddMachine(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
}, },
@ -268,6 +269,7 @@ func TestCommandSide_ChangeMachine(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -302,6 +304,7 @@ func TestCommandSide_ChangeMachine(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),

View File

@ -81,6 +81,7 @@ func TestCommands_AddPersonalAccessToken(t *testing.T) {
"Machine", "Machine",
"", "",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -175,6 +176,7 @@ func TestCommands_AddPersonalAccessToken(t *testing.T) {
"Machine", "Machine",
"", "",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),
@ -226,6 +228,7 @@ func TestCommands_AddPersonalAccessToken(t *testing.T) {
"Machine", "Machine",
"", "",
true, true,
domain.OIDCTokenTypeBearer,
), ),
), ),
), ),

View File

@ -1786,6 +1786,7 @@ func TestExistsUser(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
}, nil }, nil
}, },
@ -1807,6 +1808,7 @@ func TestExistsUser(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
), ),
user.NewUserRemovedEvent( user.NewUserRemovedEvent(
context.Background(), context.Background(),

View File

@ -31,7 +31,16 @@ func AddAudScopeToAudience(ctx context.Context, audience, scopes []string) []str
if projectID == ProjectIDScopeZITADEL { if projectID == ProjectIDScopeZITADEL {
projectID = authz.GetInstance(ctx).ProjectID() projectID = authz.GetInstance(ctx).ProjectID()
} }
audience = append(audience, projectID) audience = addProjectID(audience, projectID)
} }
return audience return audience
} }
func addProjectID(audience []string, projectID string) []string {
for _, a := range audience {
if a == projectID {
return audience
}
}
return append(audience, projectID)
}

View File

@ -20,18 +20,18 @@ var (
", members.user_id" + ", members.user_id" +
", members.roles" + ", members.roles" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_machines.name" + ", projections.users8_machines.name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", COUNT(*) OVER () " + ", COUNT(*) OVER () " +
"FROM projections.instance_members3 AS members " + "FROM projections.instance_members3 AS members " +
"LEFT JOIN projections.users7_humans " + "LEFT JOIN projections.users8_humans " +
"ON members.user_id = projections.users7_humans.user_id AND members.instance_id = projections.users7_humans.instance_id " + "ON members.user_id = projections.users8_humans.user_id AND members.instance_id = projections.users8_humans.instance_id " +
"LEFT JOIN projections.users7_machines " + "LEFT JOIN projections.users8_machines " +
"ON members.user_id = projections.users7_machines.user_id AND members.instance_id = projections.users7_machines.instance_id " + "ON members.user_id = projections.users8_machines.user_id AND members.instance_id = projections.users8_machines.instance_id " +
"LEFT JOIN projections.login_names2 " + "LEFT JOIN projections.login_names2 " +
"ON members.user_id = projections.login_names2.user_id AND members.instance_id = projections.login_names2.instance_id " + "ON members.user_id = projections.login_names2.user_id AND members.instance_id = projections.login_names2.instance_id " +
"WHERE projections.login_names2.is_primary = $1") "WHERE projections.login_names2.is_primary = $1")

View File

@ -20,20 +20,20 @@ var (
", members.user_id" + ", members.user_id" +
", members.roles" + ", members.roles" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_machines.name" + ", projections.users8_machines.name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", COUNT(*) OVER () " + ", COUNT(*) OVER () " +
"FROM projections.org_members3 AS members " + "FROM projections.org_members3 AS members " +
"LEFT JOIN projections.users7_humans " + "LEFT JOIN projections.users8_humans " +
"ON members.user_id = projections.users7_humans.user_id " + "ON members.user_id = projections.users8_humans.user_id " +
"AND members.instance_id = projections.users7_humans.instance_id " + "AND members.instance_id = projections.users8_humans.instance_id " +
"LEFT JOIN projections.users7_machines " + "LEFT JOIN projections.users8_machines " +
"ON members.user_id = projections.users7_machines.user_id " + "ON members.user_id = projections.users8_machines.user_id " +
"AND members.instance_id = projections.users7_machines.instance_id " + "AND members.instance_id = projections.users8_machines.instance_id " +
"LEFT JOIN projections.login_names2 " + "LEFT JOIN projections.login_names2 " +
"ON members.user_id = projections.login_names2.user_id " + "ON members.user_id = projections.login_names2.user_id " +
"AND members.instance_id = projections.login_names2.instance_id " + "AND members.instance_id = projections.login_names2.instance_id " +

View File

@ -20,20 +20,20 @@ var (
", members.user_id" + ", members.user_id" +
", members.roles" + ", members.roles" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_machines.name" + ", projections.users8_machines.name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", COUNT(*) OVER () " + ", COUNT(*) OVER () " +
"FROM projections.project_grant_members3 AS members " + "FROM projections.project_grant_members3 AS members " +
"LEFT JOIN projections.users7_humans " + "LEFT JOIN projections.users8_humans " +
"ON members.user_id = projections.users7_humans.user_id " + "ON members.user_id = projections.users8_humans.user_id " +
"AND members.instance_id = projections.users7_humans.instance_id " + "AND members.instance_id = projections.users8_humans.instance_id " +
"LEFT JOIN projections.users7_machines " + "LEFT JOIN projections.users8_machines " +
"ON members.user_id = projections.users7_machines.user_id " + "ON members.user_id = projections.users8_machines.user_id " +
"AND members.instance_id = projections.users7_machines.instance_id " + "AND members.instance_id = projections.users8_machines.instance_id " +
"LEFT JOIN projections.login_names2 " + "LEFT JOIN projections.login_names2 " +
"ON members.user_id = projections.login_names2.user_id " + "ON members.user_id = projections.login_names2.user_id " +
"AND members.instance_id = projections.login_names2.instance_id " + "AND members.instance_id = projections.login_names2.instance_id " +

View File

@ -20,20 +20,20 @@ var (
", members.user_id" + ", members.user_id" +
", members.roles" + ", members.roles" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_machines.name" + ", projections.users8_machines.name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", COUNT(*) OVER () " + ", COUNT(*) OVER () " +
"FROM projections.project_members3 AS members " + "FROM projections.project_members3 AS members " +
"LEFT JOIN projections.users7_humans " + "LEFT JOIN projections.users8_humans " +
"ON members.user_id = projections.users7_humans.user_id " + "ON members.user_id = projections.users8_humans.user_id " +
"AND members.instance_id = projections.users7_humans.instance_id " + "AND members.instance_id = projections.users8_humans.instance_id " +
"LEFT JOIN projections.users7_machines " + "LEFT JOIN projections.users8_machines " +
"ON members.user_id = projections.users7_machines.user_id " + "ON members.user_id = projections.users8_machines.user_id " +
"AND members.instance_id = projections.users7_machines.instance_id " + "AND members.instance_id = projections.users8_machines.instance_id " +
"LEFT JOIN projections.login_names2 " + "LEFT JOIN projections.login_names2 " +
"ON members.user_id = projections.login_names2.user_id " + "ON members.user_id = projections.login_names2.user_id " +
"AND members.instance_id = projections.login_names2.instance_id " + "AND members.instance_id = projections.login_names2.instance_id " +

View File

@ -19,7 +19,7 @@ type userProjection struct {
} }
const ( const (
UserTable = "projections.users7" UserTable = "projections.users8"
UserHumanTable = UserTable + "_" + UserHumanSuffix UserHumanTable = UserTable + "_" + UserHumanSuffix
UserMachineTable = UserTable + "_" + UserMachineSuffix UserMachineTable = UserTable + "_" + UserMachineSuffix
UserNotifyTable = UserTable + "_" + UserNotifySuffix UserNotifyTable = UserTable + "_" + UserNotifySuffix
@ -57,12 +57,13 @@ const (
HumanIsPhoneVerifiedCol = "is_phone_verified" HumanIsPhoneVerifiedCol = "is_phone_verified"
// machine // machine
UserMachineSuffix = "machines" UserMachineSuffix = "machines"
MachineUserIDCol = "user_id" MachineUserIDCol = "user_id"
MachineUserInstanceIDCol = "instance_id" MachineUserInstanceIDCol = "instance_id"
MachineNameCol = "name" MachineNameCol = "name"
MachineDescriptionCol = "description" MachineDescriptionCol = "description"
MachineHasSecretCol = "has_secret" MachineHasSecretCol = "has_secret"
MachineAccessTokenTypeCol = "access_token_type"
// notify // notify
UserNotifySuffix = "notifications" UserNotifySuffix = "notifications"
@ -122,6 +123,7 @@ func newUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(MachineNameCol, crdb.ColumnTypeText), crdb.NewColumn(MachineNameCol, crdb.ColumnTypeText),
crdb.NewColumn(MachineDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()), crdb.NewColumn(MachineDescriptionCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MachineHasSecretCol, crdb.ColumnTypeBool, crdb.Default(false)), crdb.NewColumn(MachineHasSecretCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(MachineAccessTokenTypeCol, crdb.ColumnTypeEnum, crdb.Default(0)),
}, },
crdb.NewPrimaryKey(MachineUserInstanceIDCol, MachineUserIDCol), crdb.NewPrimaryKey(MachineUserInstanceIDCol, MachineUserIDCol),
UserMachineSuffix, UserMachineSuffix,
@ -1005,6 +1007,7 @@ func (p *userProjection) reduceMachineAdded(event eventstore.Event) (*handler.St
handler.NewCol(MachineUserInstanceIDCol, e.Aggregate().InstanceID), handler.NewCol(MachineUserInstanceIDCol, e.Aggregate().InstanceID),
handler.NewCol(MachineNameCol, e.Name), handler.NewCol(MachineNameCol, e.Name),
handler.NewCol(MachineDescriptionCol, &sql.NullString{String: e.Description, Valid: e.Description != ""}), handler.NewCol(MachineDescriptionCol, &sql.NullString{String: e.Description, Valid: e.Description != ""}),
handler.NewCol(MachineAccessTokenTypeCol, e.AccessTokenType),
}, },
crdb.WithTableSuffix(UserMachineSuffix), crdb.WithTableSuffix(UserMachineSuffix),
), ),
@ -1024,6 +1027,9 @@ func (p *userProjection) reduceMachineChanged(event eventstore.Event) (*handler.
if e.Description != nil { if e.Description != nil {
cols = append(cols, handler.NewCol(MachineDescriptionCol, *e.Description)) cols = append(cols, handler.NewCol(MachineDescriptionCol, *e.Description))
} }
if e.AccessTokenType != nil {
cols = append(cols, handler.NewCol(MachineAccessTokenTypeCol, e.AccessTokenType))
}
if len(cols) == 0 { if len(cols) == 0 {
return crdb.NewNoOpStatement(e), nil return crdb.NewNoOpStatement(e), nil
} }

View File

@ -51,7 +51,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -65,7 +65,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -80,7 +80,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -120,7 +120,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -134,7 +134,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -149,7 +149,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -184,7 +184,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -198,7 +198,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -213,7 +213,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -253,7 +253,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -267,7 +267,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -282,7 +282,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -322,7 +322,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -336,7 +336,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -351,7 +351,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -386,7 +386,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -400,7 +400,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)", expectedStmt: "INSERT INTO projections.users8_humans (user_id, instance_id, first_name, last_name, nick_name, display_name, preferred_language, gender, email, phone) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -415,7 +415,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)", expectedStmt: "INSERT INTO projections.users8_notifications (user_id, instance_id, last_email, last_phone, password_set) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -445,7 +445,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
domain.UserStateInitial, domain.UserStateInitial,
"agg-id", "agg-id",
@ -473,7 +473,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
domain.UserStateInitial, domain.UserStateInitial,
"agg-id", "agg-id",
@ -501,7 +501,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
domain.UserStateActive, domain.UserStateActive,
"agg-id", "agg-id",
@ -529,7 +529,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8 SET state = $1 WHERE (id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
domain.UserStateActive, domain.UserStateActive,
"agg-id", "agg-id",
@ -557,7 +557,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
domain.UserStateLocked, domain.UserStateLocked,
@ -587,7 +587,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
domain.UserStateActive, domain.UserStateActive,
@ -617,7 +617,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
domain.UserStateInactive, domain.UserStateInactive,
@ -647,7 +647,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, state, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
domain.UserStateActive, domain.UserStateActive,
@ -677,7 +677,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "DELETE FROM projections.users7 WHERE (id = $1) AND (instance_id = $2)", expectedStmt: "DELETE FROM projections.users8 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -706,7 +706,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
"username", "username",
@ -738,7 +738,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, username, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
"id@temporary.domain", "id@temporary.domain",
@ -775,7 +775,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -784,7 +784,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)", expectedStmt: "UPDATE projections.users8_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"first-name", "first-name",
"last-name", "last-name",
@ -824,7 +824,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -833,7 +833,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)", expectedStmt: "UPDATE projections.users8_humans SET (first_name, last_name, nick_name, display_name, preferred_language, gender) = ($1, $2, $3, $4, $5, $6) WHERE (user_id = $7) AND (instance_id = $8)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"first-name", "first-name",
"last-name", "last-name",
@ -868,7 +868,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -877,7 +877,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"+41 00 000 00 00", "+41 00 000 00 00",
false, false,
@ -886,7 +886,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
&sql.NullString{String: "+41 00 000 00 00", Valid: true}, &sql.NullString{String: "+41 00 000 00 00", Valid: true},
"agg-id", "agg-id",
@ -916,7 +916,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -925,7 +925,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"+41 00 000 00 00", "+41 00 000 00 00",
false, false,
@ -934,7 +934,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
&sql.NullString{String: "+41 00 000 00 00", Valid: true}, &sql.NullString{String: "+41 00 000 00 00", Valid: true},
"agg-id", "agg-id",
@ -962,7 +962,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -971,7 +971,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
nil, nil,
nil, nil,
@ -980,7 +980,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
nil, nil,
nil, nil,
@ -1009,7 +1009,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1018,7 +1018,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (phone, is_phone_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
nil, nil,
nil, nil,
@ -1027,7 +1027,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_notifications SET (last_phone, verified_phone) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
nil, nil,
nil, nil,
@ -1056,7 +1056,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1065,7 +1065,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
true, true,
"agg-id", "agg-id",
@ -1073,7 +1073,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)", expectedStmt: "UPDATE projections.users8_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -1100,7 +1100,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1109,7 +1109,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
true, true,
"agg-id", "agg-id",
@ -1117,7 +1117,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)", expectedStmt: "UPDATE projections.users8_notifications SET verified_phone = last_phone WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -1146,7 +1146,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1155,7 +1155,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"email@zitadel.com", "email@zitadel.com",
false, false,
@ -1164,7 +1164,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
&sql.NullString{String: "email@zitadel.com", Valid: true}, &sql.NullString{String: "email@zitadel.com", Valid: true},
"agg-id", "agg-id",
@ -1194,7 +1194,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1203,7 +1203,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_humans SET (email, is_email_verified) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"email@zitadel.com", "email@zitadel.com",
false, false,
@ -1212,7 +1212,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
&sql.NullString{String: "email@zitadel.com", Valid: true}, &sql.NullString{String: "email@zitadel.com", Valid: true},
"agg-id", "agg-id",
@ -1240,7 +1240,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1249,7 +1249,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
true, true,
"agg-id", "agg-id",
@ -1257,7 +1257,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)", expectedStmt: "UPDATE projections.users8_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -1284,7 +1284,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1293,7 +1293,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
true, true,
"agg-id", "agg-id",
@ -1301,7 +1301,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)", expectedStmt: "UPDATE projections.users8_notifications SET verified_email = last_email WHERE (user_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
@ -1330,7 +1330,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1339,7 +1339,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"users/agg-id/avatar", "users/agg-id/avatar",
"agg-id", "agg-id",
@ -1367,7 +1367,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1376,7 +1376,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
nil, nil,
"agg-id", "agg-id",
@ -1407,7 +1407,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -1421,12 +1421,13 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)", expectedStmt: "INSERT INTO projections.users8_machines (user_id, instance_id, name, description, access_token_type) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
"machine-name", "machine-name",
&sql.NullString{}, &sql.NullString{},
domain.OIDCTokenTypeBearer,
}, },
}, },
}, },
@ -1454,7 +1455,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "INSERT INTO projections.users7 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", expectedStmt: "INSERT INTO projections.users8 (id, creation_date, change_date, resource_owner, instance_id, state, sequence, username, type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
anyArg{}, anyArg{},
@ -1468,12 +1469,13 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "INSERT INTO projections.users7_machines (user_id, instance_id, name, description) VALUES ($1, $2, $3, $4)", expectedStmt: "INSERT INTO projections.users8_machines (user_id, instance_id, name, description, access_token_type) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
"instance-id", "instance-id",
"machine-name", "machine-name",
&sql.NullString{String: "description", Valid: true}, &sql.NullString{String: "description", Valid: true},
domain.OIDCTokenTypeBearer,
}, },
}, },
}, },
@ -1500,7 +1502,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1509,7 +1511,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8_machines SET (name, description) = ($1, $2) WHERE (user_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"machine-name", "machine-name",
"description", "description",
@ -1540,7 +1542,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1549,7 +1551,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_machines SET name = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_machines SET name = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"machine-name", "machine-name",
"agg-id", "agg-id",
@ -1579,7 +1581,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1588,7 +1590,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_machines SET description = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_machines SET description = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"description", "description",
"agg-id", "agg-id",
@ -1637,7 +1639,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1646,7 +1648,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_machines SET has_secret = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_machines SET has_secret = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
true, true,
"agg-id", "agg-id",
@ -1674,7 +1676,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1683,7 +1685,7 @@ func TestUserProjection_reduces(t *testing.T) {
}, },
}, },
{ {
expectedStmt: "UPDATE projections.users7_machines SET has_secret = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedStmt: "UPDATE projections.users8_machines SET has_secret = $1 WHERE (user_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
false, false,
"agg-id", "agg-id",
@ -1711,7 +1713,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "UPDATE projections.users7 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)", expectedStmt: "UPDATE projections.users8 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
anyArg{}, anyArg{},
uint64(15), uint64(15),
@ -1741,7 +1743,7 @@ func TestUserProjection_reduces(t *testing.T) {
executer: &testExecuter{ executer: &testExecuter{
executions: []execution{ executions: []execution{
{ {
expectedStmt: "DELETE FROM projections.users7 WHERE (instance_id = $1)", expectedStmt: "DELETE FROM projections.users8 WHERE (instance_id = $1)",
expectedArgs: []interface{}{ expectedArgs: []interface{}{
"agg-id", "agg-id",
}, },

View File

@ -88,9 +88,10 @@ type Phone struct {
} }
type Machine struct { type Machine struct {
Name string Name string
Description string Description string
HasSecret bool HasSecret bool
AccessTokenType domain.OIDCTokenType
} }
type NotifyUser struct { type NotifyUser struct {
@ -282,6 +283,10 @@ var (
name: projection.MachineHasSecretCol, name: projection.MachineHasSecretCol,
table: machineTable, table: machineTable,
} }
MachineAccessTokenTypeCol = Column{
name: projection.MachineAccessTokenTypeCol,
table: machineTable,
}
) )
var ( var (
@ -753,6 +758,7 @@ func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) {
MachineNameCol.identifier(), MachineNameCol.identifier(),
MachineDescriptionCol.identifier(), MachineDescriptionCol.identifier(),
MachineHasSecretCol.identifier(), MachineHasSecretCol.identifier(),
MachineAccessTokenTypeCol.identifier(),
countColumn.identifier(), countColumn.identifier(),
). ).
From(userTable.identifier()). From(userTable.identifier()).
@ -789,6 +795,7 @@ func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) {
name := sql.NullString{} name := sql.NullString{}
description := sql.NullString{} description := sql.NullString{}
hasSecret := sql.NullBool{} hasSecret := sql.NullBool{}
accessTokenType := sql.NullInt32{}
err := row.Scan( err := row.Scan(
&u.ID, &u.ID,
@ -817,6 +824,7 @@ func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) {
&name, &name,
&description, &description,
&hasSecret, &hasSecret,
&accessTokenType,
&count, &count,
) )
@ -845,9 +853,10 @@ func prepareUserQuery() (sq.SelectBuilder, func(*sql.Row) (*User, error)) {
} }
} else if machineID.Valid { } else if machineID.Valid {
u.Machine = &Machine{ u.Machine = &Machine{
Name: name.String, Name: name.String,
Description: description.String, Description: description.String,
HasSecret: hasSecret.Bool, HasSecret: hasSecret.Bool,
AccessTokenType: domain.OIDCTokenType(accessTokenType.Int32),
} }
} }
return u, nil return u, nil
@ -1219,6 +1228,7 @@ func prepareUsersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Users, error)) {
MachineNameCol.identifier(), MachineNameCol.identifier(),
MachineDescriptionCol.identifier(), MachineDescriptionCol.identifier(),
MachineHasSecretCol.identifier(), MachineHasSecretCol.identifier(),
MachineAccessTokenTypeCol.identifier(),
countColumn.identifier()). countColumn.identifier()).
From(userTable.identifier()). From(userTable.identifier()).
LeftJoin(join(HumanUserIDCol, UserIDCol)). LeftJoin(join(HumanUserIDCol, UserIDCol)).
@ -1257,6 +1267,7 @@ func prepareUsersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Users, error)) {
name := sql.NullString{} name := sql.NullString{}
description := sql.NullString{} description := sql.NullString{}
hasSecret := sql.NullBool{} hasSecret := sql.NullBool{}
accessTokenType := sql.NullInt32{}
err := rows.Scan( err := rows.Scan(
&u.ID, &u.ID,
@ -1285,6 +1296,7 @@ func prepareUsersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Users, error)) {
&name, &name,
&description, &description,
&hasSecret, &hasSecret,
&accessTokenType,
&count, &count,
) )
if err != nil { if err != nil {
@ -1312,9 +1324,10 @@ func prepareUsersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Users, error)) {
} }
} else if machineID.Valid { } else if machineID.Valid {
u.Machine = &Machine{ u.Machine = &Machine{
Name: name.String, Name: name.String,
Description: description.String, Description: description.String,
HasSecret: hasSecret.Bool, HasSecret: hasSecret.Bool,
AccessTokenType: domain.OIDCTokenType(accessTokenType.Int32),
} }
} }

View File

@ -23,14 +23,14 @@ var (
", projections.user_grants3.roles" + ", projections.user_grants3.roles" +
", projections.user_grants3.state" + ", projections.user_grants3.state" +
", projections.user_grants3.user_id" + ", projections.user_grants3.user_id" +
", projections.users7.username" + ", projections.users8.username" +
", projections.users7.type" + ", projections.users8.type" +
", projections.users7.resource_owner" + ", projections.users8.resource_owner" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.user_grants3.resource_owner" + ", projections.user_grants3.resource_owner" +
", projections.orgs.name" + ", projections.orgs.name" +
@ -38,8 +38,8 @@ var (
", projections.user_grants3.project_id" + ", projections.user_grants3.project_id" +
", projections.projects3.name" + ", projections.projects3.name" +
" FROM projections.user_grants3" + " FROM projections.user_grants3" +
" LEFT JOIN projections.users7 ON projections.user_grants3.user_id = projections.users7.id AND projections.user_grants3.instance_id = projections.users7.instance_id" + " LEFT JOIN projections.users8 ON projections.user_grants3.user_id = projections.users8.id AND projections.user_grants3.instance_id = projections.users8.instance_id" +
" LEFT JOIN projections.users7_humans ON projections.user_grants3.user_id = projections.users7_humans.user_id AND projections.user_grants3.instance_id = projections.users7_humans.instance_id" + " LEFT JOIN projections.users8_humans ON projections.user_grants3.user_id = projections.users8_humans.user_id AND projections.user_grants3.instance_id = projections.users8_humans.instance_id" +
" LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" + " LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" +
" LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" + " LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" +
" LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" + " LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" +
@ -77,14 +77,14 @@ var (
", projections.user_grants3.roles" + ", projections.user_grants3.roles" +
", projections.user_grants3.state" + ", projections.user_grants3.state" +
", projections.user_grants3.user_id" + ", projections.user_grants3.user_id" +
", projections.users7.username" + ", projections.users8.username" +
", projections.users7.type" + ", projections.users8.type" +
", projections.users7.resource_owner" + ", projections.users8.resource_owner" +
", projections.users7_humans.first_name" + ", projections.users8_humans.first_name" +
", projections.users7_humans.last_name" + ", projections.users8_humans.last_name" +
", projections.users7_humans.email" + ", projections.users8_humans.email" +
", projections.users7_humans.display_name" + ", projections.users8_humans.display_name" +
", projections.users7_humans.avatar_key" + ", projections.users8_humans.avatar_key" +
", projections.login_names2.login_name" + ", projections.login_names2.login_name" +
", projections.user_grants3.resource_owner" + ", projections.user_grants3.resource_owner" +
", projections.orgs.name" + ", projections.orgs.name" +
@ -93,8 +93,8 @@ var (
", projections.projects3.name" + ", projections.projects3.name" +
", COUNT(*) OVER ()" + ", COUNT(*) OVER ()" +
" FROM projections.user_grants3" + " FROM projections.user_grants3" +
" LEFT JOIN projections.users7 ON projections.user_grants3.user_id = projections.users7.id AND projections.user_grants3.instance_id = projections.users7.instance_id" + " LEFT JOIN projections.users8 ON projections.user_grants3.user_id = projections.users8.id AND projections.user_grants3.instance_id = projections.users8.instance_id" +
" LEFT JOIN projections.users7_humans ON projections.user_grants3.user_id = projections.users7_humans.user_id AND projections.user_grants3.instance_id = projections.users7_humans.instance_id" + " LEFT JOIN projections.users8_humans ON projections.user_grants3.user_id = projections.users8_humans.user_id AND projections.user_grants3.instance_id = projections.users8_humans.instance_id" +
" LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" + " LEFT JOIN projections.orgs ON projections.user_grants3.resource_owner = projections.orgs.id AND projections.user_grants3.instance_id = projections.orgs.instance_id" +
" LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" + " LEFT JOIN projections.projects3 ON projections.user_grants3.project_id = projections.projects3.id AND projections.user_grants3.instance_id = projections.projects3.instance_id" +
" LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" + " LEFT JOIN projections.login_names2 ON projections.user_grants3.user_id = projections.login_names2.user_id AND projections.user_grants3.instance_id = projections.login_names2.instance_id" +

View File

@ -23,42 +23,43 @@ var (
preferredLoginNameQuery = `SELECT preferred_login_name.user_id, preferred_login_name.login_name, preferred_login_name.instance_id, preferred_login_name.user_owner_removed, preferred_login_name.policy_owner_removed, preferred_login_name.domain_owner_removed` + preferredLoginNameQuery = `SELECT preferred_login_name.user_id, preferred_login_name.login_name, preferred_login_name.instance_id, preferred_login_name.user_owner_removed, preferred_login_name.policy_owner_removed, preferred_login_name.domain_owner_removed` +
` FROM projections.login_names2 AS preferred_login_name` + ` FROM projections.login_names2 AS preferred_login_name` +
` WHERE preferred_login_name.is_primary = $1` ` WHERE preferred_login_name.is_primary = $1`
userQuery = `SELECT projections.users7.id,` + userQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7.state,` + ` projections.users8.state,` +
` projections.users7.type,` + ` projections.users8.type,` +
` projections.users7.username,` + ` projections.users8.username,` +
` login_names.loginnames,` + ` login_names.loginnames,` +
` preferred_login_name.login_name,` + ` preferred_login_name.login_name,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.first_name,` + ` projections.users8_humans.first_name,` +
` projections.users7_humans.last_name,` + ` projections.users8_humans.last_name,` +
` projections.users7_humans.nick_name,` + ` projections.users8_humans.nick_name,` +
` projections.users7_humans.display_name,` + ` projections.users8_humans.display_name,` +
` projections.users7_humans.preferred_language,` + ` projections.users8_humans.preferred_language,` +
` projections.users7_humans.gender,` + ` projections.users8_humans.gender,` +
` projections.users7_humans.avatar_key,` + ` projections.users8_humans.avatar_key,` +
` projections.users7_humans.email,` + ` projections.users8_humans.email,` +
` projections.users7_humans.is_email_verified,` + ` projections.users8_humans.is_email_verified,` +
` projections.users7_humans.phone,` + ` projections.users8_humans.phone,` +
` projections.users7_humans.is_phone_verified,` + ` projections.users8_humans.is_phone_verified,` +
` projections.users7_machines.user_id,` + ` projections.users8_machines.user_id,` +
` projections.users7_machines.name,` + ` projections.users8_machines.name,` +
` projections.users7_machines.description,` + ` projections.users8_machines.description,` +
` projections.users7_machines.has_secret,` + ` projections.users8_machines.has_secret,` +
` projections.users8_machines.access_token_type,` +
` COUNT(*) OVER ()` + ` COUNT(*) OVER ()` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` + ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id` +
` LEFT JOIN projections.users7_machines ON projections.users7.id = projections.users7_machines.user_id AND projections.users7.instance_id = projections.users7_machines.instance_id` + ` LEFT JOIN projections.users8_machines ON projections.users8.id = projections.users8_machines.user_id AND projections.users8.instance_id = projections.users8_machines.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + loginNamesQuery + `) AS login_names` + ` (` + loginNamesQuery + `) AS login_names` +
` ON login_names.user_id = projections.users7.id AND login_names.instance_id = projections.users7.instance_id` + ` ON login_names.user_id = projections.users8.id AND login_names.instance_id = projections.users8.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + preferredLoginNameQuery + `) AS preferred_login_name` + ` (` + preferredLoginNameQuery + `) AS preferred_login_name` +
` ON preferred_login_name.user_id = projections.users7.id AND preferred_login_name.instance_id = projections.users7.instance_id` ` ON preferred_login_name.user_id = projections.users8.id AND preferred_login_name.instance_id = projections.users8.instance_id`
userCols = []string{ userCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -88,23 +89,24 @@ var (
"name", "name",
"description", "description",
"has_secret", "has_secret",
"access_token_type",
"count", "count",
} }
profileQuery = `SELECT projections.users7.id,` + profileQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.first_name,` + ` projections.users8_humans.first_name,` +
` projections.users7_humans.last_name,` + ` projections.users8_humans.last_name,` +
` projections.users7_humans.nick_name,` + ` projections.users8_humans.nick_name,` +
` projections.users7_humans.display_name,` + ` projections.users8_humans.display_name,` +
` projections.users7_humans.preferred_language,` + ` projections.users8_humans.preferred_language,` +
` projections.users7_humans.gender,` + ` projections.users8_humans.gender,` +
` projections.users7_humans.avatar_key` + ` projections.users8_humans.avatar_key` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id`
profileCols = []string{ profileCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -120,16 +122,16 @@ var (
"gender", "gender",
"avatar_key", "avatar_key",
} }
emailQuery = `SELECT projections.users7.id,` + emailQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.email,` + ` projections.users8_humans.email,` +
` projections.users7_humans.is_email_verified` + ` projections.users8_humans.is_email_verified` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id`
emailCols = []string{ emailCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -140,16 +142,16 @@ var (
"email", "email",
"is_email_verified", "is_email_verified",
} }
phoneQuery = `SELECT projections.users7.id,` + phoneQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.phone,` + ` projections.users8_humans.phone,` +
` projections.users7_humans.is_phone_verified` + ` projections.users8_humans.is_phone_verified` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id`
phoneCols = []string{ phoneCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -160,14 +162,14 @@ var (
"phone", "phone",
"is_phone_verified", "is_phone_verified",
} }
userUniqueQuery = `SELECT projections.users7.id,` + userUniqueQuery = `SELECT projections.users8.id,` +
` projections.users7.state,` + ` projections.users8.state,` +
` projections.users7.username,` + ` projections.users8.username,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.email,` + ` projections.users8_humans.email,` +
` projections.users7_humans.is_email_verified` + ` projections.users8_humans.is_email_verified` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id`
userUniqueCols = []string{ userUniqueCols = []string{
"id", "id",
"state", "state",
@ -176,40 +178,40 @@ var (
"email", "email",
"is_email_verified", "is_email_verified",
} }
notifyUserQuery = `SELECT projections.users7.id,` + notifyUserQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7.state,` + ` projections.users8.state,` +
` projections.users7.type,` + ` projections.users8.type,` +
` projections.users7.username,` + ` projections.users8.username,` +
` login_names.loginnames,` + ` login_names.loginnames,` +
` preferred_login_name.login_name,` + ` preferred_login_name.login_name,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.first_name,` + ` projections.users8_humans.first_name,` +
` projections.users7_humans.last_name,` + ` projections.users8_humans.last_name,` +
` projections.users7_humans.nick_name,` + ` projections.users8_humans.nick_name,` +
` projections.users7_humans.display_name,` + ` projections.users8_humans.display_name,` +
` projections.users7_humans.preferred_language,` + ` projections.users8_humans.preferred_language,` +
` projections.users7_humans.gender,` + ` projections.users8_humans.gender,` +
` projections.users7_humans.avatar_key,` + ` projections.users8_humans.avatar_key,` +
` projections.users7_notifications.user_id,` + ` projections.users8_notifications.user_id,` +
` projections.users7_notifications.last_email,` + ` projections.users8_notifications.last_email,` +
` projections.users7_notifications.verified_email,` + ` projections.users8_notifications.verified_email,` +
` projections.users7_notifications.last_phone,` + ` projections.users8_notifications.last_phone,` +
` projections.users7_notifications.verified_phone,` + ` projections.users8_notifications.verified_phone,` +
` projections.users7_notifications.password_set,` + ` projections.users8_notifications.password_set,` +
` COUNT(*) OVER ()` + ` COUNT(*) OVER ()` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` + ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id` +
` LEFT JOIN projections.users7_notifications ON projections.users7.id = projections.users7_notifications.user_id AND projections.users7.instance_id = projections.users7_notifications.instance_id` + ` LEFT JOIN projections.users8_notifications ON projections.users8.id = projections.users8_notifications.user_id AND projections.users8.instance_id = projections.users8_notifications.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + loginNamesQuery + `) AS login_names` + ` (` + loginNamesQuery + `) AS login_names` +
` ON login_names.user_id = projections.users7.id AND login_names.instance_id = projections.users7.instance_id` + ` ON login_names.user_id = projections.users8.id AND login_names.instance_id = projections.users8.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + preferredLoginNameQuery + `) AS preferred_login_name` + ` (` + preferredLoginNameQuery + `) AS preferred_login_name` +
` ON preferred_login_name.user_id = projections.users7.id AND preferred_login_name.instance_id = projections.users7.instance_id` ` ON preferred_login_name.user_id = projections.users8.id AND preferred_login_name.instance_id = projections.users8.instance_id`
notifyUserCols = []string{ notifyUserCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -239,42 +241,43 @@ var (
"password_set", "password_set",
"count", "count",
} }
usersQuery = `SELECT projections.users7.id,` + usersQuery = `SELECT projections.users8.id,` +
` projections.users7.creation_date,` + ` projections.users8.creation_date,` +
` projections.users7.change_date,` + ` projections.users8.change_date,` +
` projections.users7.resource_owner,` + ` projections.users8.resource_owner,` +
` projections.users7.sequence,` + ` projections.users8.sequence,` +
` projections.users7.state,` + ` projections.users8.state,` +
` projections.users7.type,` + ` projections.users8.type,` +
` projections.users7.username,` + ` projections.users8.username,` +
` login_names.loginnames,` + ` login_names.loginnames,` +
` preferred_login_name.login_name,` + ` preferred_login_name.login_name,` +
` projections.users7_humans.user_id,` + ` projections.users8_humans.user_id,` +
` projections.users7_humans.first_name,` + ` projections.users8_humans.first_name,` +
` projections.users7_humans.last_name,` + ` projections.users8_humans.last_name,` +
` projections.users7_humans.nick_name,` + ` projections.users8_humans.nick_name,` +
` projections.users7_humans.display_name,` + ` projections.users8_humans.display_name,` +
` projections.users7_humans.preferred_language,` + ` projections.users8_humans.preferred_language,` +
` projections.users7_humans.gender,` + ` projections.users8_humans.gender,` +
` projections.users7_humans.avatar_key,` + ` projections.users8_humans.avatar_key,` +
` projections.users7_humans.email,` + ` projections.users8_humans.email,` +
` projections.users7_humans.is_email_verified,` + ` projections.users8_humans.is_email_verified,` +
` projections.users7_humans.phone,` + ` projections.users8_humans.phone,` +
` projections.users7_humans.is_phone_verified,` + ` projections.users8_humans.is_phone_verified,` +
` projections.users7_machines.user_id,` + ` projections.users8_machines.user_id,` +
` projections.users7_machines.name,` + ` projections.users8_machines.name,` +
` projections.users7_machines.description,` + ` projections.users8_machines.description,` +
` projections.users7_machines.has_secret,` + ` projections.users8_machines.has_secret,` +
` projections.users8_machines.access_token_type,` +
` COUNT(*) OVER ()` + ` COUNT(*) OVER ()` +
` FROM projections.users7` + ` FROM projections.users8` +
` LEFT JOIN projections.users7_humans ON projections.users7.id = projections.users7_humans.user_id AND projections.users7.instance_id = projections.users7_humans.instance_id` + ` LEFT JOIN projections.users8_humans ON projections.users8.id = projections.users8_humans.user_id AND projections.users8.instance_id = projections.users8_humans.instance_id` +
` LEFT JOIN projections.users7_machines ON projections.users7.id = projections.users7_machines.user_id AND projections.users7.instance_id = projections.users7_machines.instance_id` + ` LEFT JOIN projections.users8_machines ON projections.users8.id = projections.users8_machines.user_id AND projections.users8.instance_id = projections.users8_machines.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + loginNamesQuery + `) AS login_names` + ` (` + loginNamesQuery + `) AS login_names` +
` ON login_names.user_id = projections.users7.id AND login_names.instance_id = projections.users7.instance_id` + ` ON login_names.user_id = projections.users8.id AND login_names.instance_id = projections.users8.instance_id` +
` LEFT JOIN` + ` LEFT JOIN` +
` (` + preferredLoginNameQuery + `) AS preferred_login_name` + ` (` + preferredLoginNameQuery + `) AS preferred_login_name` +
` ON preferred_login_name.user_id = projections.users7.id AND preferred_login_name.instance_id = projections.users7.instance_id` ` ON preferred_login_name.user_id = projections.users8.id AND preferred_login_name.instance_id = projections.users8.instance_id`
usersCols = []string{ usersCols = []string{
"id", "id",
"creation_date", "creation_date",
@ -304,6 +307,7 @@ var (
"name", "name",
"description", "description",
"has_secret", "has_secret",
"access_token_type",
"count", "count",
} }
) )
@ -377,6 +381,7 @@ func Test_UserPrepares(t *testing.T) {
nil, nil,
nil, nil,
nil, nil,
nil,
1, 1,
}, },
), ),
@ -445,6 +450,7 @@ func Test_UserPrepares(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
1, 1,
}, },
), ),
@ -461,9 +467,10 @@ func Test_UserPrepares(t *testing.T) {
LoginNames: database.StringArray{"login_name1", "login_name2"}, LoginNames: database.StringArray{"login_name1", "login_name2"},
PreferredLoginName: "login_name1", PreferredLoginName: "login_name1",
Machine: &Machine{ Machine: &Machine{
Name: "name", Name: "name",
Description: "description", Description: "description",
HasSecret: true, HasSecret: true,
AccessTokenType: domain.OIDCTokenTypeBearer,
}, },
}, },
}, },
@ -1044,6 +1051,7 @@ func Test_UserPrepares(t *testing.T) {
nil, nil,
nil, nil,
nil, nil,
nil,
}, },
}, },
), ),
@ -1120,6 +1128,7 @@ func Test_UserPrepares(t *testing.T) {
nil, nil,
nil, nil,
nil, nil,
nil,
}, },
{ {
"id", "id",
@ -1150,6 +1159,7 @@ func Test_UserPrepares(t *testing.T) {
"name", "name",
"description", "description",
true, true,
domain.OIDCTokenTypeBearer,
}, },
}, },
), ),
@ -1196,9 +1206,10 @@ func Test_UserPrepares(t *testing.T) {
LoginNames: database.StringArray{"login_name1", "login_name2"}, LoginNames: database.StringArray{"login_name1", "login_name2"},
PreferredLoginName: "login_name1", PreferredLoginName: "login_name1",
Machine: &Machine{ Machine: &Machine{
Name: "name", Name: "name",
Description: "description", Description: "description",
HasSecret: true, HasSecret: true,
AccessTokenType: domain.OIDCTokenTypeBearer,
}, },
}, },
}, },

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/errors" "github.com/zitadel/zitadel/internal/errors"
@ -20,10 +21,11 @@ type MachineAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
UserName string `json:"userName"` UserName string `json:"userName"`
userLoginMustBeDomain bool `json:"-"` userLoginMustBeDomain bool
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
AccessTokenType domain.OIDCTokenType `json:"accessTokenType,omitempty"`
} }
func (e *MachineAddedEvent) Data() interface{} { func (e *MachineAddedEvent) Data() interface{} {
@ -41,6 +43,7 @@ func NewMachineAddedEvent(
name, name,
description string, description string,
userLoginMustBeDomain bool, userLoginMustBeDomain bool,
accessTokenType domain.OIDCTokenType,
) *MachineAddedEvent { ) *MachineAddedEvent {
return &MachineAddedEvent{ return &MachineAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
@ -52,6 +55,7 @@ func NewMachineAddedEvent(
Name: name, Name: name,
Description: description, Description: description,
userLoginMustBeDomain: userLoginMustBeDomain, userLoginMustBeDomain: userLoginMustBeDomain,
AccessTokenType: accessTokenType,
} }
} }
@ -70,8 +74,9 @@ func MachineAddedEventMapper(event *repository.Event) (eventstore.Event, error)
type MachineChangedEvent struct { type MachineChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
Name *string `json:"name,omitempty"` Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
AccessTokenType *domain.OIDCTokenType `json:"accessTokenType,omitempty"`
} }
func (e *MachineChangedEvent) Data() interface{} { func (e *MachineChangedEvent) Data() interface{} {
@ -117,6 +122,12 @@ func ChangeDescription(description string) func(event *MachineChangedEvent) {
} }
} }
func ChangeAccessTokenType(accessTokenType domain.OIDCTokenType) func(event *MachineChangedEvent) {
return func(e *MachineChangedEvent) {
e.AccessTokenType = &accessTokenType
}
}
func MachineChangedEventMapper(event *repository.Event) (eventstore.Event, error) { func MachineChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
machineChanged := &MachineChangedEvent{ machineChanged := &MachineChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),

View File

@ -3313,6 +3313,7 @@ message AddMachineUserRequest {
string name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}]; string name = 2 [(validate.rules).string = {min_len: 1, max_len: 200}];
string description = 3 [(validate.rules).string = {max_len: 500}]; string description = 3 [(validate.rules).string = {max_len: 500}];
zitadel.user.v1.AccessTokenType access_token_type = 4 [(validate.rules).enum = {defined_only: true}];
} }
message AddMachineUserResponse { message AddMachineUserResponse {
@ -3633,6 +3634,7 @@ message UpdateMachineRequest {
string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; string user_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
string description = 2 [(validate.rules).string.max_len = 500]; string description = 2 [(validate.rules).string.max_len = 500];
string name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}]; string name = 3 [(validate.rules).string = {min_len: 1, max_len: 200}];
zitadel.user.v1.AccessTokenType access_token_type = 4 [(validate.rules).enum = {defined_only: true}];
} }
message UpdateMachineResponse { message UpdateMachineResponse {

View File

@ -83,6 +83,11 @@ message Machine {
example: "\"true\""; example: "\"true\"";
} }
]; ];
AccessTokenType access_token_typ = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "Type of access token to receive";
}
];
} }
message Profile { message Profile {
@ -161,6 +166,11 @@ enum Gender {
GENDER_DIVERSE = 3; GENDER_DIVERSE = 3;
} }
enum AccessTokenType {
ACCESS_TOKEN_TYPE_BEARER = 0;
ACCESS_TOKEN_TYPE_JWT = 1;
}
message SearchQuery { message SearchQuery {
oneof query { oneof query {
option (validate.required) = true; option (validate.required) = true;