Skip to content

Identity

Overview

The Identity domain is a default domain in comby. Identities can be linked to accounts, associated with groups, and assigned tokens for secure interactions. The Identity aggregate is at the core of this domain, handling events and maintaining consistency across identity-related operations.

An Identity can only be associated with a single Tenant. However, an account can have multiple identities, each linked to a different Tenant. This design allows a user to log in to multiple Tenants using a single account.

Structure

The Identity aggregate extends the BaseAggregate, inheriting core event-sourcing capabilities like event tracking and versioning. It includes fields to represent the identity’s relationships, attributes, and associated entities:

The Identity is an aggregate that represents a user within a system holding entities Profile and Token. Profile contains information about the user, such as their name, email address, title, and avatar. Token represents API tokens associated with the identity, each containing a unique UUID, name, description, token value, and expiration. An identity can act as an Service Account - without an associated account.

References:

  • AccountUuid: Link the identity to an existing account in the Account domain (optional).
  • GroupUuids: Tracks the groups to which the identity belongs.

Entities:

  • Profile: Captures personal information about the identity, such as name, email, title, and avatar.
  • Tokens: Represents authentication or API tokens associated with the identity, each containing a unique UUID, name, description, token value, and expiration.

Commands

IdentityCommandAddGroup

Domain Command Struct:

go
type IdentityCommandAddGroup struct {
	IdentityUuid string `json:"identityUuid"`
	GroupUuid    string `json:"groupUuid"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandAddGroup(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandAddGroup) ([]comby.Event, error)

IdentityCommandAddToken

Domain Command Struct:

go
type IdentityCommandAddToken struct {
	IdentityUuid string `json:"identityUuid"`
	TokenUuid    string `json:"tokenUuid"`
	TokenValue   string `json:"tokenValue"`
	Name         string `json:"name,omitempty"`
	Description  string `json:"description,omitempty"`
	ExpiredAt    int64  `json:"expiredAt,omitempty"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandAddToken(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandAddToken) ([]comby.Event, error)

IdentityCommandCreate

Domain Command Struct:

go
type IdentityCommandCreate struct {
	IdentityUuid string   `json:"identityUuid"`
	AccountUuid  string   `json:"accountUuid,omitempty"`
	GroupUuids   []string `json:"groupUuids"`
	Attributes   string   `json:"attributes,omitempty"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandCreate(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandCreate) ([]comby.Event, error)

IdentityCommandRemove

Domain Command Struct:

go
type IdentityCommandRemove struct {
	IdentityUuid string `json:"identityUuid"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandRemove(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandRemove) ([]comby.Event, error)

IdentityCommandRemoveAttribute

Domain Command Struct:

go
type IdentityCommandRemoveAttribute struct {
	IdentityUuid string `json:"identityUuid"`
	Key          string `json:"key"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandRemoveAttribute(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandRemoveAttribute) ([]comby.Event, error)

IdentityCommandRemoveGroup

Domain Command Struct:

go
type IdentityCommandRemoveGroup struct {
	IdentityUuid string `json:"identityUuid"`
	GroupUuid    string `json:"groupUuid"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandRemoveGroup(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandRemoveGroup) ([]comby.Event, error)

IdentityCommandRemoveToken

Domain Command Struct:

go
type IdentityCommandRemoveToken struct {
	IdentityUuid string `json:"identityUuid"`
	TokenUuid    string `json:"tokenUuid"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandRemoveToken(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandRemoveToken) ([]comby.Event, error)

IdentityCommandSetAttribute

Domain Command Struct:

go
type IdentityCommandSetAttribute struct {
	IdentityUuid string `json:"identityUuid"`
	Key          string `json:"key"`
	Value        any    `json:"value"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandSetAttribute(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandSetAttribute) ([]comby.Event, error)

IdentityCommandUpdate

Domain Command Struct:

go
type IdentityCommandUpdate struct {
	IdentityUuid  string   `json:"identityUuid"`
	Attributes    string   `json:"attributes,omitempty"`
	PatchedFields []string `json:"patchedFields"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandUpdate(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandUpdate) ([]comby.Event, error)

IdentityCommandUpdateProfile

Domain Command Struct:

go
type IdentityCommandUpdateProfile struct {
	IdentityUuid  string   `json:"identityUuid"`
	Name          string   `json:"name,omitempty"`
	Email         string   `json:"email,omitempty"`
	Title         string   `json:"title,omitempty"`
	Avatar        string   `json:"avatar,omitempty"`
	PatchedFields []string `json:"patchedFields" doc:"list of fields that should be patched - comma separated" example:"field1,field2"`
}

Domain Command Handling Method:

go
func (cs *commandHandler) IdentityCommandUpdateProfile(ctx context.Context, cmd comby.Command, domainCmd *IdentityCommandUpdateProfile) ([]comby.Event, error)

Queries

Domain Query Structs:

Domain Query Responses:

IdentityQueryListByAccountUuid

Domain Query Struct:

go
type IdentityQueryListByAccountUuid struct {
	AccountUuid string `json:"accountUuid"`
	Page        int64  `json:"page,omitempty"`
	PageSize    int64  `json:"pageSize,omitempty"`
	OrderBy     string `json:"orderBy,omitempty"`
}

Domain Query Handling Method:

go
func (qs *queryHandler) IdentityQueryListByAccountUuid(ctx context.Context, qry comby.Query, domainQry *IdentityQueryListByAccountUuid) (*IdentityQueryListResponse, error)

IdentityQueryListByAccountTenantUuid

Domain Query Struct:

go
type IdentityQueryListByAccountTenantUuid struct {
	TenantUuid  string `json:"tenantUuid"`
	AccountUuid string `json:"accountUuid"`
	Page        int64  `json:"page,omitempty"`
	PageSize    int64  `json:"pageSize,omitempty"`
	OrderBy     string `json:"orderBy,omitempty"`
}

Domain Query Handling Method:

go
func (qs *queryHandler) IdentityQueryListByAccountTenantUuid(ctx context.Context, qry comby.Query, domainQry *IdentityQueryListByAccountTenantUuid) (*IdentityQueryListResponse, error)

IdentityQueryList

Domain Query Struct:

go
type IdentityQueryList struct {
	TenantUuid string `json:"tenantUuid"`
	Page       int64  `json:"page,omitempty"`
	PageSize   int64  `json:"pageSize,omitempty"`
	OrderBy    string `json:"orderBy,omitempty"`
	Attributes string `json:"attributes,omitempty"`
}

Domain Query Handling Method:

go
func (qs *queryHandler) IdentityQueryList(ctx context.Context, qry comby.Query, domainQry *IdentityQueryList) (*IdentityQueryListResponse, error)

IdentityQueryModel

Domain Query Struct:

go
type IdentityQueryModel struct {
	IdentityUuid string `json:"identityUuid"`
}

Domain Query Handling Method:

go
func (qs *queryHandler) IdentityQueryModel(ctx context.Context, qry comby.Query, domainQry *IdentityQueryModel) (*IdentityQueryItemResponse, error)

IdentityQueryModelIndependentOfOrganization

Domain Query Struct:

go
type IdentityQueryModelIndependentOfOrganization struct {
	SessionUuid  string `json:"sessionUuid"`
	IdentityUuid string `json:"identityUuid,omitempty"`
}

Domain Query Handling Method:

go
func (qs *queryHandler) IdentityQueryModelIndependentOfOrganization(ctx context.Context, qry comby.Query, domainQry *IdentityQueryModelIndependentOfOrganization) (*IdentityQueryItemResponse, error)

IdentityQueryListResponse

go
type IdentityQueryListResponse struct {
	Items    []*readmodel.IdentityModel `json:"items,omitempty"`
	Total    int64                      `json:"total,omitempty"`
	Page     int64                      `json:"page,omitempty"`
	PageSize int64                      `json:"pageSize,omitempty"`
}

IdentityQueryItemResponse

go
type IdentityQueryItemResponse struct {
	Item *readmodel.IdentityModel `json:"item,omitempty"`
}

Events

IdentityAddedGroupEvent

Domain Event Struct:

go
type IdentityAddedGroupEvent struct {
	GroupUuid string `json:"groupUuid"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityAddedGroupEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityAddedGroupEvent) (error)

IdentityAddedTokenEvent

Domain Event Struct:

go
type IdentityAddedTokenEvent struct {
	TokenUuid   string `json:"tokenUuid"`
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
	TokenValue  string `json:"tokenValue"`
	ExpiredAt   int64  `json:"expiredAt,omitempty"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityAddedTokenEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityAddedTokenEvent) (error)

IdentityCreatedEvent

Domain Event Struct:

go
type IdentityCreatedEvent struct {
	AccountUuid string `json:"accountUuid,omitempty"`
	Attributes  string `json:"attributes,omitempty"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityCreatedEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityCreatedEvent) (error)

IdentityRemovedEvent

Domain Event Struct:

go
type IdentityRemovedEvent struct {
	Reason string `json:"reason,omitempty"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityRemovedEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityRemovedEvent) (error)

IdentityAttributeRemovedEvent

Domain Event Struct:

go
type IdentityAttributeRemovedEvent struct {
	Key string `json:"key"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityAttributeRemovedEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityAttributeRemovedEvent) (error)

IdentityRemovedGroupEvent

Domain Event Struct:

go
type IdentityRemovedGroupEvent struct {
	GroupUuid string `json:"groupUuid"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityRemovedGroupEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityRemovedGroupEvent) (error)

IdentityRemovedTokenEvent

Domain Event Struct:

go
type IdentityRemovedTokenEvent struct {
	TokenUuid string `json:"tokenUuid"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityRemovedTokenEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityRemovedTokenEvent) (error)

IdentityAttributeSetEvent

Domain Event Struct:

go
type IdentityAttributeSetEvent struct {
	Key   string `json:"key"`
	Value any    `json:"value"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityAttributesSetEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityAttributeSetEvent) (error)

IdentityUpdatedEvent

Domain Event Struct:

go
type IdentityUpdatedEvent struct {
	Attributes string `json:"attributes,omitempty"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityUpdatedEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityUpdatedEvent) (error)

IdentityProfileUpdatedEvent

Domain Event Struct:

go
type IdentityProfileUpdatedEvent struct {
	Name   string `json:"name,omitempty"`
	Email  string `json:"email,omitempty"`
	Title  string `json:"title,omitempty"`
	Avatar string `json:"avatar,omitempty"`
}

Domain Event Handling Method:

go
func (agg *Identity) IdentityProfileUpdatedEvent(ctx context.Context, evt comby.Event, domainEvt *IdentityProfileUpdatedEvent) (error)

Aggregate

Aggregate Struct:

go
type Identity struct {
	*comby.BaseAggregate
	// References
	AccountUuid string
	GroupUuids  []string
	// Entities
	Profile *Profile
	Tokens  []*Token
}

Methods

AddGroup

go
func (agg *Identity) AddGroup(groupUuid string) (error)

AddToken

go
func (agg *Identity) AddToken(tokenUuid, tokenValue, name, description string, expiredAt int64) (error)

Add

go
func (agg *Identity) Add(accountUuid, attributes string) (error)

Remove

go
func (agg *Identity) Remove() (error)

RemoveAttribute

go
func (agg *Identity) RemoveAttribute(key string) (error)

RemoveGroup

go
func (agg *Identity) RemoveGroup(groupUuid string) (error)

RemoveToken

go
func (agg *Identity) RemoveToken(tokenUuid string) (error)

SetAttribute

go
func (agg *Identity) SetAttribute(key string, value any) (error)

Update

go
func (agg *Identity) Update(attributes string) (error)

UpdateProfile

go
func (agg *Identity) UpdateProfile(name, email, title, avatar string) (error)

Event Handlers

IdentityReadmodel

Domain EventMethod
tenantAggregate.TenantCreatedEventTenantCreatedEvent
tenantAggregate.TenantAttributeRemovedEventTenantAttributeRemovedEvent
tenantAggregate.TenantAttributeSetEventTenantAttributeSetEvent
tenantAggregate.TenantUpdatedEventTenantUpdatedEvent
tenantAggregate.TenantRemovedEventTenantRemovedEvent
identityAggregate.IdentityAttributeRemovedEventIdentityAttributeRemovedEvent
identityAggregate.IdentityRemovedTokenEventIdentityRemovedTokenEvent
identityAggregate.IdentityUpdatedEventIdentityUpdatedEvent
identityAggregate.IdentityRemovedEventIdentityRemovedEvent
identityAggregate.IdentityAddedGroupEventIdentityAddedGroupEvent
identityAggregate.IdentityRemovedGroupEventIdentityRemovedGroupEvent
identityAggregate.IdentityAddedTokenEventIdentityAddedTokenEvent
identityAggregate.IdentityCreatedEventIdentityCreatedEvent
identityAggregate.IdentityProfileUpdatedEventIdentityProfileUpdatedEvent
identityAggregate.IdentityAttributeSetEventIdentityAttributeSetEvent
groupAggregate.GroupUpdatedEventGroupUpdatedEvent
groupAggregate.GroupRemovedEventGroupRemovedEvent
groupAggregate.GroupAddedEventGroupAddedEvent
assetAggregate.AssetAddedEventAssetAddedEvent
assetAggregate.AssetRemovedEventAssetRemovedEvent
assetAggregate.AssetUpdatedEventAssetUpdatedEvent

Custom Permissions

NameTypeComment
IdentityCommandAddTokenCommandAdd token for any other identity
IdentityCommandRemoveTokenCommandRemove token of any other identity
IdentityCommandUpdateProfileCommandUpdate profile of any other identity
IdentityCommandSetAttributeCommandSet attributes of any other identity