chore: move the go code into a subfolder

This commit is contained in:
Florian Forster
2025-08-05 15:20:32 -07:00
parent 4ad22ba456
commit cd2921de26
2978 changed files with 373 additions and 300 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
package eventstore
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
auth_view "github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
"github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
iam_model "github.com/zitadel/zitadel/internal/iam/model"
iam_view_model "github.com/zitadel/zitadel/internal/iam/repository/view/model"
"github.com/zitadel/zitadel/internal/query"
)
type OrgRepository struct {
SearchLimit uint64
Eventstore *eventstore.Eventstore
View *auth_view.View
SystemDefaults systemdefaults.SystemDefaults
Query *query.Queries
}
func (repo *OrgRepository) GetMyPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) {
policy, err := repo.Query.PasswordComplexityPolicyByOrg(ctx, false, authz.GetCtxData(ctx).OrgID, false)
if err != nil {
return nil, err
}
return iam_view_model.PasswordComplexityViewToModel(policy), err
}
func (repo *OrgRepository) GetLoginText(ctx context.Context, orgID string) ([]*domain.CustomText, error) {
loginTexts, err := repo.Query.CustomTextListByTemplate(ctx, authz.GetInstance(ctx).InstanceID(), domain.LoginCustomText, false)
if err != nil {
return nil, err
}
orgLoginTexts, err := repo.Query.CustomTextListByTemplate(ctx, orgID, domain.LoginCustomText, false)
if err != nil {
return nil, err
}
return append(query.CustomTextsToDomain(loginTexts), query.CustomTextsToDomain(orgLoginTexts)...), nil
}

View File

@@ -0,0 +1,117 @@
package eventstore
import (
"context"
"time"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
"github.com/zitadel/zitadel/internal/crypto"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/telemetry/tracing"
usr_model "github.com/zitadel/zitadel/internal/user/model"
usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
"github.com/zitadel/zitadel/internal/user/repository/view/model"
"github.com/zitadel/zitadel/internal/zerrors"
)
type RefreshTokenRepo struct {
Eventstore *eventstore.Eventstore
View *view.View
SearchLimit uint64
KeyAlgorithm crypto.EncryptionAlgorithm
}
func (r *RefreshTokenRepo) RefreshTokenByToken(ctx context.Context, refreshToken string) (*usr_model.RefreshTokenView, error) {
userID, tokenID, token, err := domain.FromRefreshToken(refreshToken, r.KeyAlgorithm)
if err != nil {
return nil, err
}
tokenView, err := r.RefreshTokenByID(ctx, tokenID, userID)
if err != nil {
return nil, err
}
if tokenView.Token != token {
return nil, zerrors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.User.RefreshToken.Invalid")
}
return tokenView, nil
}
func (r *RefreshTokenRepo) RefreshTokenByID(ctx context.Context, tokenID, userID string) (*usr_model.RefreshTokenView, error) {
instanceID := authz.GetInstance(ctx).InstanceID()
// always load the latest sequence first, so in case the token was not found by id,
// the sequence will be equal or lower than the actual projection and no events are lost
sequence, err := r.View.GetLatestRefreshTokenSequence(ctx)
logging.WithFields("instanceID", instanceID, "userID", userID, "tokenID", tokenID).
OnError(err).
Errorf("could not get current sequence for RefreshTokenByID")
tokenView, viewErr := r.View.RefreshTokenByID(tokenID, instanceID)
if viewErr != nil && !zerrors.IsNotFound(viewErr) {
return nil, viewErr
}
if zerrors.IsNotFound(viewErr) {
tokenView = new(model.RefreshTokenView)
tokenView.ID = tokenID
tokenView.UserID = userID
tokenView.InstanceID = instanceID
if sequence != nil {
tokenView.ChangeDate = sequence.EventCreatedAt
}
}
events, esErr := r.getUserEvents(ctx, userID, tokenView.InstanceID, tokenView.ChangeDate, tokenView.GetRelevantEventTypes())
if zerrors.IsNotFound(viewErr) && len(events) == 0 {
return nil, zerrors.ThrowNotFound(nil, "EVENT-BHB52", "Errors.User.RefreshToken.Invalid")
}
if esErr != nil {
logging.Log("EVENT-AE462").WithError(viewErr).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("error retrieving new events")
return model.RefreshTokenViewToModel(tokenView), nil
}
viewToken := *tokenView
for _, event := range events {
err := tokenView.AppendEventIfMyRefreshToken(event)
if err != nil {
return model.RefreshTokenViewToModel(&viewToken), nil
}
}
if !tokenView.Expiration.After(time.Now()) {
return nil, zerrors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.User.RefreshToken.Invalid")
}
return model.RefreshTokenViewToModel(tokenView), nil
}
func (r *RefreshTokenRepo) SearchMyRefreshTokens(ctx context.Context, userID string, request *usr_model.RefreshTokenSearchRequest) (*usr_model.RefreshTokenSearchResponse, error) {
err := request.EnsureLimit(r.SearchLimit)
if err != nil {
return nil, err
}
sequence, err := r.View.GetLatestRefreshTokenSequence(ctx)
logging.Log("EVENT-GBdn4").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest refresh token sequence")
request.Queries = append(request.Queries, &usr_model.RefreshTokenSearchQuery{Key: usr_model.RefreshTokenSearchKeyUserID, Method: domain.SearchMethodEquals, Value: userID})
tokens, count, err := r.View.SearchRefreshTokens(request)
if err != nil {
return nil, err
}
return &usr_model.RefreshTokenSearchResponse{
Offset: request.Offset,
Limit: request.Limit,
TotalResult: count,
Sequence: sequence.Sequence,
Timestamp: sequence.LastRun,
Result: model.RefreshTokenViewsToModel(tokens),
}, nil
}
func (r *RefreshTokenRepo) getUserEvents(ctx context.Context, userID, instanceID string, changeDate time.Time, eventTypes []eventstore.EventType) ([]eventstore.Event, error) {
query, err := usr_view.UserByIDQuery(userID, instanceID, changeDate, eventTypes)
if err != nil {
return nil, err
}
return r.Eventstore.Filter(ctx, query)
}

View File

@@ -0,0 +1,83 @@
package eventstore
import (
"context"
"time"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/telemetry/tracing"
usr_model "github.com/zitadel/zitadel/internal/user/model"
usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
"github.com/zitadel/zitadel/internal/user/repository/view/model"
"github.com/zitadel/zitadel/internal/zerrors"
)
type TokenRepo struct {
Eventstore *eventstore.Eventstore
View *view.View
}
func (repo *TokenRepo) TokenByIDs(ctx context.Context, userID, tokenID string) (_ *usr_model.TokenView, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
instanceID := authz.GetInstance(ctx).InstanceID()
// always load the latest sequence first, so in case the token was not found by id,
// the sequence will be equal or lower than the actual projection and no events are lost
sequence, err := repo.View.GetLatestTokenSequence(ctx, instanceID)
logging.WithFields("instanceID", instanceID, "userID", userID, "tokenID", tokenID).
OnError(err).
Errorf("could not get current sequence for TokenByIDs")
token, viewErr := repo.View.TokenByIDs(tokenID, userID, instanceID)
if viewErr != nil && !zerrors.IsNotFound(viewErr) {
return nil, viewErr
}
if zerrors.IsNotFound(viewErr) {
token = new(model.TokenView)
token.ID = tokenID
token.UserID = userID
token.InstanceID = instanceID
if sequence != nil {
token.ChangeDate = sequence.EventCreatedAt
}
}
events, esErr := repo.getUserEvents(ctx, userID, token.InstanceID, token.ChangeDate, token.GetRelevantEventTypes())
if zerrors.IsNotFound(viewErr) && len(events) == 0 {
return nil, zerrors.ThrowNotFound(nil, "EVENT-4T90g", "Errors.Token.NotFound")
}
if esErr != nil {
logging.Log("EVENT-5Nm9s").WithError(viewErr).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("error retrieving new events")
return model.TokenViewToModel(token), nil
}
viewToken := *token
for _, event := range events {
err := token.AppendEventIfMyToken(event)
if err != nil {
return model.TokenViewToModel(&viewToken), nil
}
}
if !token.Expiration.After(time.Now().UTC()) || token.Deactivated {
return nil, zerrors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.Token.NotFound")
}
return model.TokenViewToModel(token), nil
}
func (r *TokenRepo) getUserEvents(ctx context.Context, userID, instanceID string, changeDate time.Time, eventTypes []eventstore.EventType) (_ []eventstore.Event, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
query, err := usr_view.UserByIDQuery(userID, instanceID, changeDate, eventTypes)
if err != nil {
return nil, err
}
return r.Eventstore.Filter(ctx, query)
}

View File

@@ -0,0 +1,153 @@
package eventstore
import (
"context"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/repository/user"
usr_view "github.com/zitadel/zitadel/internal/user/repository/view"
"github.com/zitadel/zitadel/internal/user/repository/view/model"
"github.com/zitadel/zitadel/internal/zerrors"
)
type UserRepo struct {
SearchLimit uint64
Eventstore *eventstore.Eventstore
View *view.View
Query *query.Queries
SystemDefaults systemdefaults.SystemDefaults
}
func (repo *UserRepo) Health(ctx context.Context) error {
return repo.Eventstore.Health(ctx)
}
func (repo *UserRepo) UserSessionsByAgentID(ctx context.Context, agentID string) ([]command.HumanSignOutSession, error) {
sessions, err := repo.View.UserSessionsByAgentID(ctx, agentID, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
signoutSessions := make([]command.HumanSignOutSession, 0, len(sessions))
for _, session := range sessions {
if session.State.V == domain.UserSessionStateActive && session.ID.Valid {
signoutSessions = append(signoutSessions, command.HumanSignOutSession{
ID: session.ID.String,
UserID: session.UserID,
})
}
}
return signoutSessions, nil
}
func (repo *UserRepo) UserAgentIDBySessionID(ctx context.Context, sessionID string) (string, error) {
return repo.View.UserAgentIDBySessionID(ctx, sessionID, authz.GetInstance(ctx).InstanceID())
}
func (repo *UserRepo) UserSessionByID(ctx context.Context, sessionID string) (*model.UserSessionView, error) {
return repo.View.UserSessionByID(ctx, sessionID, authz.GetInstance(ctx).InstanceID())
}
func (repo *UserRepo) ActiveUserSessionsBySessionID(ctx context.Context, sessionID string) (userAgentID string, signoutSessions []command.HumanSignOutSession, err error) {
userAgentID, sessions, err := repo.View.ActiveUserSessionsBySessionID(ctx, sessionID, authz.GetInstance(ctx).InstanceID())
if err != nil {
return "", nil, err
}
signoutSessions = make([]command.HumanSignOutSession, 0, len(sessions))
for sessionID, userID := range sessions {
signoutSessions = append(signoutSessions, command.HumanSignOutSession{
ID: sessionID,
UserID: userID,
})
}
return userAgentID, signoutSessions, nil
}
func (repo *UserRepo) UserEventsByID(ctx context.Context, id string, changeDate time.Time, eventTypes []eventstore.EventType) ([]eventstore.Event, error) {
query, err := usr_view.UserByIDQuery(id, authz.GetInstance(ctx).InstanceID(), changeDate, eventTypes)
if err != nil {
return nil, err
}
return repo.Eventstore.Filter(ctx, query) //nolint:staticcheck
}
type passwordCodeCheck struct {
userID string
exists bool
events int
}
func (p *passwordCodeCheck) Reduce() error {
p.exists = p.events > 0
return nil
}
func (p *passwordCodeCheck) AppendEvents(events ...eventstore.Event) {
p.events += len(events)
}
func (p *passwordCodeCheck) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
AddQuery().
AggregateTypes(user.AggregateType).
AggregateIDs(p.userID).
EventTypes(user.UserV1PasswordCodeAddedType, user.UserV1PasswordCodeSentType,
user.HumanPasswordCodeAddedType, user.HumanPasswordCodeSentType).
Builder()
}
func (repo *UserRepo) PasswordCodeExists(ctx context.Context, userID string) (exists bool, err error) {
model := &passwordCodeCheck{
userID: userID,
}
err = repo.Eventstore.FilterToQueryReducer(ctx, model)
if err != nil {
return false, zerrors.ThrowPermissionDenied(err, "EVENT-SJ642", "Errors.Internal")
}
return model.exists, nil
}
type inviteCodeCheck struct {
userID string
exists bool
events int
}
func (p *inviteCodeCheck) Reduce() error {
p.exists = p.events > 0
return nil
}
func (p *inviteCodeCheck) AppendEvents(events ...eventstore.Event) {
p.events += len(events)
}
func (p *inviteCodeCheck) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
AddQuery().
AggregateTypes(user.AggregateType).
AggregateIDs(p.userID).
EventTypes(
user.HumanInviteCodeAddedType,
user.HumanInviteCodeSentType).
Builder()
}
func (repo *UserRepo) InviteCodeExists(ctx context.Context, userID string) (exists bool, err error) {
model := &inviteCodeCheck{
userID: userID,
}
err = repo.Eventstore.FilterToQueryReducer(ctx, model)
if err != nil {
return false, zerrors.ThrowPermissionDenied(err, "EVENT-GJ2os", "Errors.Internal")
}
return model.exists, nil
}

View File

@@ -0,0 +1,22 @@
package eventstore
import (
"context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/auth/repository/eventsourcing/view"
usr_model "github.com/zitadel/zitadel/internal/user/model"
"github.com/zitadel/zitadel/internal/user/repository/view/model"
)
type UserSessionRepo struct {
View *view.View
}
func (repo *UserSessionRepo) GetMyUserSessions(ctx context.Context) ([]*usr_model.UserSessionView, error) {
userSessions, err := repo.View.UserSessionsByAgentID(ctx, authz.GetCtxData(ctx).AgentID, authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
return model.UserSessionsToModel(userSessions), nil
}