mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-10 14:23:40 +00:00
fix(instance): update logic for pats and machinekeys
This commit is contained in:
parent
d92caaf07d
commit
bff0db4be4
@ -2,7 +2,6 @@ package management
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||||
@ -725,27 +724,24 @@ func (s *Server) ListMachineKeys(ctx context.Context, req *mgmt_pb.ListMachineKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) AddMachineKey(ctx context.Context, req *mgmt_pb.AddMachineKeyRequest) (*mgmt_pb.AddMachineKeyResponse, error) {
|
func (s *Server) AddMachineKey(ctx context.Context, req *mgmt_pb.AddMachineKeyRequest) (*mgmt_pb.AddMachineKeyResponse, error) {
|
||||||
key, err := s.command.AddUserMachineKey(ctx, AddMachineKeyRequestToDomain(req), authz.GetCtxData(ctx).OrgID)
|
machineKey := AddMachineKeyRequestToCommand(req, authz.GetCtxData(ctx).OrgID)
|
||||||
|
details, err := s.command.AddUserMachineKey(ctx, machineKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
keyDetails, err := key.Detail()
|
keyDetails, err := machineKey.Detail()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.AddMachineKeyResponse{
|
return &mgmt_pb.AddMachineKeyResponse{
|
||||||
KeyId: key.KeyID,
|
KeyId: machineKey.KeyID,
|
||||||
KeyDetails: keyDetails,
|
KeyDetails: keyDetails,
|
||||||
Details: obj_grpc.AddToDetailsPb(
|
Details: obj_grpc.DomainToChangeDetailsPb(details),
|
||||||
key.Sequence,
|
|
||||||
key.ChangeDate,
|
|
||||||
key.ResourceOwner,
|
|
||||||
),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RemoveMachineKey(ctx context.Context, req *mgmt_pb.RemoveMachineKeyRequest) (*mgmt_pb.RemoveMachineKeyResponse, error) {
|
func (s *Server) RemoveMachineKey(ctx context.Context, req *mgmt_pb.RemoveMachineKeyRequest) (*mgmt_pb.RemoveMachineKeyResponse, error) {
|
||||||
objectDetails, err := s.command.RemoveUserMachineKey(ctx, req.UserId, req.KeyId, authz.GetCtxData(ctx).OrgID)
|
objectDetails, err := s.command.RemoveUserMachineKey(ctx, RemoveMachineKeyRequestToCommand(req, authz.GetCtxData(ctx).OrgID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -788,28 +784,21 @@ func (s *Server) ListPersonalAccessTokens(ctx context.Context, req *mgmt_pb.List
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) AddPersonalAccessToken(ctx context.Context, req *mgmt_pb.AddPersonalAccessTokenRequest) (*mgmt_pb.AddPersonalAccessTokenResponse, error) {
|
func (s *Server) AddPersonalAccessToken(ctx context.Context, req *mgmt_pb.AddPersonalAccessTokenRequest) (*mgmt_pb.AddPersonalAccessTokenResponse, error) {
|
||||||
expDate := time.Time{}
|
|
||||||
if req.ExpirationDate != nil {
|
|
||||||
expDate = req.ExpirationDate.AsTime()
|
|
||||||
}
|
|
||||||
scopes := []string{oidc.ScopeOpenID, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner}
|
scopes := []string{oidc.ScopeOpenID, z_oidc.ScopeUserMetaData, z_oidc.ScopeResourceOwner}
|
||||||
pat, token, err := s.command.AddPersonalAccessToken(ctx, req.UserId, authz.GetCtxData(ctx).OrgID, expDate, scopes, domain.UserTypeMachine)
|
pat := AddPersonalAccessTokenRequestToCommand(req, authz.GetCtxData(ctx).OrgID, scopes, domain.UserTypeMachine)
|
||||||
|
details, err := s.command.AddPersonalAccessToken(ctx, pat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &mgmt_pb.AddPersonalAccessTokenResponse{
|
return &mgmt_pb.AddPersonalAccessTokenResponse{
|
||||||
TokenId: pat.TokenID,
|
TokenId: pat.TokenID,
|
||||||
Token: token,
|
Token: pat.Token,
|
||||||
Details: obj_grpc.AddToDetailsPb(
|
Details: obj_grpc.DomainToChangeDetailsPb(details),
|
||||||
pat.Sequence,
|
|
||||||
pat.ChangeDate,
|
|
||||||
pat.ResourceOwner,
|
|
||||||
),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RemovePersonalAccessToken(ctx context.Context, req *mgmt_pb.RemovePersonalAccessTokenRequest) (*mgmt_pb.RemovePersonalAccessTokenResponse, error) {
|
func (s *Server) RemovePersonalAccessToken(ctx context.Context, req *mgmt_pb.RemovePersonalAccessTokenRequest) (*mgmt_pb.RemovePersonalAccessTokenResponse, error) {
|
||||||
objectDetails, err := s.command.RemovePersonalAccessToken(ctx, req.UserId, req.TokenId, authz.GetCtxData(ctx).OrgID)
|
objectDetails, err := s.command.RemovePersonalAccessToken(ctx, RemovePersonalAccessTokenRequestToCommand(req, authz.GetCtxData(ctx).OrgID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
"github.com/zitadel/zitadel/pkg/grpc/user"
|
"github.com/zitadel/zitadel/pkg/grpc/user"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
@ -243,21 +244,59 @@ func ListMachineKeysRequestToQuery(ctx context.Context, req *mgmt_pb.ListMachine
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddMachineKeyRequestToDomain(req *mgmt_pb.AddMachineKeyRequest) *domain.MachineKey {
|
func AddMachineKeyRequestToCommand(req *mgmt_pb.AddMachineKeyRequest, resourceOwner string) *command.MachineKey {
|
||||||
expDate := time.Time{}
|
expDate := time.Time{}
|
||||||
if req.ExpirationDate != nil {
|
if req.ExpirationDate != nil {
|
||||||
expDate = req.ExpirationDate.AsTime()
|
expDate = req.ExpirationDate.AsTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &domain.MachineKey{
|
return &command.MachineKey{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
AggregateID: req.UserId,
|
AggregateID: req.UserId,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
},
|
},
|
||||||
ExpirationDate: expDate,
|
ExpirationDate: expDate,
|
||||||
Type: authn.KeyTypeToDomain(req.Type),
|
Type: authn.KeyTypeToDomain(req.Type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RemoveMachineKeyRequestToCommand(req *mgmt_pb.RemoveMachineKeyRequest, resourceOwner string) *command.MachineKey {
|
||||||
|
return &command.MachineKey{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: req.UserId,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
|
},
|
||||||
|
KeyID: req.KeyId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddPersonalAccessTokenRequestToCommand(req *mgmt_pb.AddPersonalAccessTokenRequest, resourceOwner string, scopes []string, allowedUserType domain.UserType) *command.PersonalAccessToken {
|
||||||
|
expDate := time.Time{}
|
||||||
|
if req.ExpirationDate != nil {
|
||||||
|
expDate = req.ExpirationDate.AsTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
return &command.PersonalAccessToken{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: req.UserId,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
|
},
|
||||||
|
ExpirationDate: expDate,
|
||||||
|
Scopes: scopes,
|
||||||
|
AllowedUserType: allowedUserType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemovePersonalAccessTokenRequestToCommand(req *mgmt_pb.RemovePersonalAccessTokenRequest, resourceOwner string) *command.PersonalAccessToken {
|
||||||
|
return &command.PersonalAccessToken{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: req.UserId,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
|
},
|
||||||
|
TokenID: req.TokenId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ListPersonalAccessTokensRequestToQuery(ctx context.Context, req *mgmt_pb.ListPersonalAccessTokensRequest) (*query.PersonalAccessTokenSearchQueries, error) {
|
func ListPersonalAccessTokensRequestToQuery(ctx context.Context, req *mgmt_pb.ListPersonalAccessTokensRequest) (*query.PersonalAccessTokenSearchQueries, error) {
|
||||||
resourceOwner, err := query.NewPersonalAccessTokenResourceOwnerSearchQuery(authz.GetCtxData(ctx).OrgID)
|
resourceOwner, err := query.NewPersonalAccessTokenResourceOwnerSearchQuery(authz.GetCtxData(ctx).OrgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/zitadel/zitadel/internal/id"
|
"github.com/zitadel/zitadel/internal/id"
|
||||||
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
"github.com/zitadel/zitadel/internal/notification/channels/smtp"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
@ -376,6 +375,27 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pat *PersonalAccessToken
|
||||||
|
var machineKey *MachineKey
|
||||||
|
if setup.Org.Machine != nil {
|
||||||
|
if setup.Org.Machine.Pat {
|
||||||
|
pat = NewPersonalAccessToken(orgID, userID, setup.Org.Machine.PatExpirationDate, setup.Org.Machine.PatScopes, domain.UserTypeMachine)
|
||||||
|
pat.TokenID, err = c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", nil, nil, err
|
||||||
|
}
|
||||||
|
validations = append(validations, prepareAddPersonalAccessToken(pat, c.keyAlgorithm))
|
||||||
|
}
|
||||||
|
if setup.Org.Machine.MachineKey {
|
||||||
|
machineKey = NewMachineKey(orgID, userID, setup.Org.Machine.MachineKeyExpirationDate, setup.Org.Machine.MachineKeyType)
|
||||||
|
machineKey.KeyID, err = c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", nil, nil, err
|
||||||
|
}
|
||||||
|
validations = append(validations, prepareAddUserMachineKey(machineKey, c.machineKeySize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validations...)
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validations...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, nil, err
|
return "", "", nil, nil, err
|
||||||
@ -386,32 +406,18 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
|||||||
return "", "", nil, nil, err
|
return "", "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var pat string
|
var token string
|
||||||
var machineKey []byte
|
var key []byte
|
||||||
if setup.Org.Machine != nil {
|
if setup.Org.Machine != nil {
|
||||||
if setup.Org.Machine.Pat {
|
if setup.Org.Machine.Pat {
|
||||||
_, token, err := c.AddPersonalAccessToken(ctx, userID, orgID, setup.Org.Machine.PatExpirationDate, setup.Org.Machine.PatScopes, domain.UserTypeMachine)
|
token = pat.Token
|
||||||
if err != nil {
|
|
||||||
return "", "", nil, nil, err
|
|
||||||
}
|
|
||||||
pat = token
|
|
||||||
}
|
}
|
||||||
if setup.Org.Machine.MachineKey {
|
if setup.Org.Machine.MachineKey {
|
||||||
key, err := c.AddUserMachineKey(ctx, &domain.MachineKey{
|
key = machineKey.PrivateKey
|
||||||
ObjectRoot: models.ObjectRoot{
|
|
||||||
AggregateID: userID,
|
|
||||||
},
|
|
||||||
ExpirationDate: setup.Org.Machine.MachineKeyExpirationDate,
|
|
||||||
Type: setup.Org.Machine.MachineKeyType,
|
|
||||||
}, orgID)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", nil, nil, err
|
|
||||||
}
|
|
||||||
machineKey = key.PrivateKey
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return instanceID, pat, machineKey, &domain.ObjectDetails{
|
return instanceID, token, key, &domain.ObjectDetails{
|
||||||
Sequence: events[len(events)-1].Sequence(),
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
EventDate: events[len(events)-1].CreationDate(),
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
ResourceOwner: orgID,
|
ResourceOwner: orgID,
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
|
||||||
"github.com/zitadel/zitadel/internal/repository/org"
|
"github.com/zitadel/zitadel/internal/repository/org"
|
||||||
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
user_repo "github.com/zitadel/zitadel/internal/repository/user"
|
||||||
)
|
)
|
||||||
@ -49,10 +48,30 @@ func (c *Commands) setUpOrgWithIDs(ctx context.Context, o *OrgSetup, orgID, user
|
|||||||
AddOrgCommand(ctx, orgAgg, o.Name, userIDs...),
|
AddOrgCommand(ctx, orgAgg, o.Name, userIDs...),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pat *PersonalAccessToken
|
||||||
|
var machineKey *MachineKey
|
||||||
if o.Human != nil {
|
if o.Human != nil {
|
||||||
validations = append(validations, AddHumanCommand(userAgg, o.Human, c.userPasswordAlg, c.userEncryption))
|
validations = append(validations, AddHumanCommand(userAgg, o.Human, c.userPasswordAlg, c.userEncryption))
|
||||||
} else if o.Machine != nil {
|
} else if o.Machine != nil {
|
||||||
validations = append(validations, AddMachineCommand(userAgg, o.Machine.Machine))
|
validations = append(validations, AddMachineCommand(userAgg, o.Machine.Machine))
|
||||||
|
if o.Machine.Pat {
|
||||||
|
pat = NewPersonalAccessToken(orgID, userID, o.Machine.PatExpirationDate, o.Machine.PatScopes, domain.UserTypeMachine)
|
||||||
|
tokenID, err := c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", nil, nil, err
|
||||||
|
}
|
||||||
|
pat.TokenID = tokenID
|
||||||
|
validations = append(validations, prepareAddPersonalAccessToken(pat, c.keyAlgorithm))
|
||||||
|
}
|
||||||
|
if o.Machine.MachineKey {
|
||||||
|
machineKey = NewMachineKey(orgID, userID, o.Machine.MachineKeyExpirationDate, o.Machine.MachineKeyType)
|
||||||
|
keyID, err := c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", nil, nil, err
|
||||||
|
}
|
||||||
|
machineKey.KeyID = keyID
|
||||||
|
validations = append(validations, prepareAddUserMachineKey(machineKey, c.keySize))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
validations = append(validations, c.AddOrgMemberCommand(orgAgg, userID, roles...))
|
validations = append(validations, c.AddOrgMemberCommand(orgAgg, userID, roles...))
|
||||||
|
|
||||||
@ -70,32 +89,18 @@ func (c *Commands) setUpOrgWithIDs(ctx context.Context, o *OrgSetup, orgID, user
|
|||||||
return "", "", nil, nil, err
|
return "", "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var pat string
|
var token string
|
||||||
var machineKey []byte
|
var key []byte
|
||||||
if o.Machine != nil {
|
if o.Machine != nil {
|
||||||
if o.Machine.Pat {
|
if o.Machine.Pat {
|
||||||
_, token, err := c.AddPersonalAccessToken(ctx, userID, orgID, o.Machine.PatExpirationDate, o.Machine.PatScopes, domain.UserTypeMachine)
|
token = pat.Token
|
||||||
if err != nil {
|
|
||||||
return "", "", nil, nil, err
|
|
||||||
}
|
|
||||||
pat = token
|
|
||||||
}
|
}
|
||||||
if o.Machine.MachineKey {
|
if o.Machine.MachineKey {
|
||||||
key, err := c.AddUserMachineKey(ctx, &domain.MachineKey{
|
key = machineKey.PrivateKey
|
||||||
ObjectRoot: models.ObjectRoot{
|
|
||||||
AggregateID: userID,
|
|
||||||
},
|
|
||||||
ExpirationDate: o.Machine.MachineKeyExpirationDate,
|
|
||||||
Type: o.Machine.MachineKeyType,
|
|
||||||
}, orgID)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", nil, nil, err
|
|
||||||
}
|
|
||||||
machineKey = key.PrivateKey
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return userID, pat, machineKey, &domain.ObjectDetails{
|
return userID, token, key, &domain.ObjectDetails{
|
||||||
Sequence: events[len(events)-1].Sequence(),
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
EventDate: events[len(events)-1].CreationDate(),
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
ResourceOwner: orgID,
|
ResourceOwner: orgID,
|
||||||
|
@ -396,6 +396,17 @@ func (c *Commands) checkUserExists(ctx context.Context, userID, resourceOwner st
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkUserExists(ctx context.Context, filter preparation.FilterToQueryReducer, userID, resourceOwner string) error {
|
||||||
|
existingUser, err := userWriteModelByID(ctx, filter, userID, resourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !isUserStateExists(existingUser.UserState) {
|
||||||
|
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.User.NotFound")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Commands) userWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) {
|
func (c *Commands) userWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
@ -2,89 +2,195 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user"
|
"github.com/zitadel/zitadel/internal/repository/user"
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddUserMachineKey(ctx context.Context, machineKey *domain.MachineKey, resourceOwner string) (*domain.MachineKey, error) {
|
type MachineKey struct {
|
||||||
err := c.checkUserExists(ctx, machineKey.AggregateID, resourceOwner)
|
models.ObjectRoot
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keyID, err := c.idGenerator.Next()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keyWriteModel := NewMachineKeyWriteModel(machineKey.AggregateID, keyID, resourceOwner)
|
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, keyWriteModel)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = domain.EnsureValidExpirationDate(machineKey); err != nil {
|
KeyID string
|
||||||
return nil, err
|
Type domain.AuthNKeyType
|
||||||
}
|
ExpirationDate time.Time
|
||||||
|
PrivateKey []byte
|
||||||
if err = domain.SetNewAuthNKeyPair(machineKey, c.machineKeySize); err != nil {
|
PublicKey []byte
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
|
||||||
user.NewMachineKeyAddedEvent(
|
|
||||||
ctx,
|
|
||||||
UserAggregateFromWriteModel(&keyWriteModel.WriteModel),
|
|
||||||
keyID,
|
|
||||||
machineKey.Type,
|
|
||||||
machineKey.ExpirationDate,
|
|
||||||
machineKey.PublicKey))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = AppendAndReduce(keyWriteModel, events...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := keyWriteModelToMachineKey(keyWriteModel)
|
|
||||||
key.PrivateKey = machineKey.PrivateKey
|
|
||||||
return key, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RemoveUserMachineKey(ctx context.Context, userID, keyID, resourceOwner string) (*domain.ObjectDetails, error) {
|
func NewMachineKey(resourceOwner string, userID string, expirationDate time.Time, keyType domain.AuthNKeyType) *MachineKey {
|
||||||
keyWriteModel, err := c.machineKeyWriteModelByID(ctx, userID, keyID, resourceOwner)
|
return &MachineKey{
|
||||||
if err != nil {
|
ObjectRoot: models.ObjectRoot{
|
||||||
return nil, err
|
AggregateID: userID,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
|
},
|
||||||
|
ExpirationDate: expirationDate,
|
||||||
|
Type: keyType,
|
||||||
}
|
}
|
||||||
if !keyWriteModel.Exists() {
|
|
||||||
return nil, errors.ThrowNotFound(nil, "COMMAND-4m77G", "Errors.User.Machine.Key.NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
pushedEvents, err := c.eventstore.Push(ctx,
|
|
||||||
user.NewMachineKeyRemovedEvent(ctx, UserAggregateFromWriteModel(&keyWriteModel.WriteModel), keyID))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = AppendAndReduce(keyWriteModel, pushedEvents...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return writeModelToObjectDetails(&keyWriteModel.WriteModel), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) machineKeyWriteModelByID(ctx context.Context, userID, keyID, resourceOwner string) (writeModel *MachineKeyWriteModel, err error) {
|
func (key *MachineKey) SetPublicKey(publicKey []byte) {
|
||||||
if userID == "" {
|
key.PublicKey = publicKey
|
||||||
return nil, errors.ThrowInvalidArgument(nil, "COMMAND-4n8vs", "Errors.User.UserIDMissing")
|
}
|
||||||
}
|
func (key *MachineKey) SetPrivateKey(privateKey []byte) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
key.PrivateKey = privateKey
|
||||||
defer func() { span.EndWithError(err) }()
|
}
|
||||||
|
func (key *MachineKey) GetExpirationDate() time.Time {
|
||||||
|
return key.ExpirationDate
|
||||||
|
}
|
||||||
|
func (key *MachineKey) SetExpirationDate(t time.Time) {
|
||||||
|
key.ExpirationDate = t
|
||||||
|
}
|
||||||
|
|
||||||
writeModel = NewMachineKeyWriteModel(userID, keyID, resourceOwner)
|
func (key *MachineKey) Detail() ([]byte, error) {
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
if len(key.PrivateKey) == 0 {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "KEY-sp2l2m", "Errors.Internal")
|
||||||
|
}
|
||||||
|
if key.Type == domain.AuthNKeyTypeJSON {
|
||||||
|
return domain.MachineKeyMarshalJSON(key.KeyID, key.PrivateKey, key.AggregateID)
|
||||||
|
}
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "KEY-dsg52", "Errors.Internal")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (key *MachineKey) content() error {
|
||||||
|
if key.ResourceOwner == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-kqpoix", "Errors.ResourceOwnerMissing")
|
||||||
|
}
|
||||||
|
if key.AggregateID == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-xuiwk2", "Errors.User.UserIDMissing")
|
||||||
|
}
|
||||||
|
if key.KeyID == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-0p2m1h", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (key *MachineKey) valid() (err error) {
|
||||||
|
if err := key.content(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
key.ExpirationDate, err = domain.ValidateExpirationDate(key.ExpirationDate)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (key *MachineKey) checkAggregate(ctx context.Context, filter preparation.FilterToQueryReducer) error {
|
||||||
|
return checkUserExists(ctx, filter, key.AggregateID, key.ResourceOwner)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) AddUserMachineKey(ctx context.Context, machineKey *MachineKey) (*domain.ObjectDetails, error) {
|
||||||
|
if machineKey.KeyID == "" {
|
||||||
|
keyID, err := c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
machineKey.KeyID = keyID
|
||||||
|
}
|
||||||
|
|
||||||
|
validation := prepareAddUserMachineKey(machineKey, c.machineKeySize)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModel, nil
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().ResourceOwner,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareAddUserMachineKey(machineKey *MachineKey, keySize int) preparation.Validation {
|
||||||
|
return func() (_ preparation.CreateCommands, err error) {
|
||||||
|
if err := machineKey.valid(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
if err := machineKey.checkAggregate(ctx, filter); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(machineKey.PublicKey) == 0 {
|
||||||
|
if err = domain.SetNewAuthNKeyPair(machineKey, keySize); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeModel, err := getMachineKeyWriteModelByID(ctx, filter, machineKey.AggregateID, machineKey.KeyID, machineKey.ResourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if writeModel.Exists() {
|
||||||
|
return nil, errors.ThrowAlreadyExists(nil, "COMMAND-091mops", "Errors.User.Machine.Key.AlreadyExists")
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
user.NewMachineKeyAddedEvent(
|
||||||
|
ctx,
|
||||||
|
UserAggregateFromWriteModel(&writeModel.WriteModel),
|
||||||
|
writeModel.KeyID,
|
||||||
|
writeModel.KeyType,
|
||||||
|
writeModel.ExpirationDate,
|
||||||
|
machineKey.PublicKey,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) RemoveUserMachineKey(ctx context.Context, machineKey *MachineKey) (*domain.ObjectDetails, error) {
|
||||||
|
validation := prepareRemoveUserMachineKey(machineKey)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().ResourceOwner,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareRemoveUserMachineKey(machineKey *MachineKey) preparation.Validation {
|
||||||
|
return func() (_ preparation.CreateCommands, err error) {
|
||||||
|
if err := machineKey.content(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||||
|
writeModel, err := getMachineKeyWriteModelByID(ctx, filter, machineKey.AggregateID, machineKey.KeyID, machineKey.ResourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !writeModel.Exists() {
|
||||||
|
return nil, errors.ThrowNotFound(nil, "COMMAND-4m77G", "Errors.User.Machine.Key.NotFound")
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
user.NewMachineKeyRemovedEvent(
|
||||||
|
ctx,
|
||||||
|
UserAggregateFromWriteModel(&writeModel.WriteModel),
|
||||||
|
writeModel.KeyID,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMachineKeyWriteModelByID(ctx context.Context, filter preparation.FilterToQueryReducer, userID, keyID, resourceOwner string) (_ *MachineKeyWriteModel, err error) {
|
||||||
|
writeModel := NewMachineKeyWriteModel(userID, keyID, resourceOwner)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(events) == 0 {
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
err = writeModel.Reduce()
|
||||||
|
return writeModel, err
|
||||||
}
|
}
|
||||||
|
@ -2,91 +2,187 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
|
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
||||||
"github.com/zitadel/zitadel/internal/repository/user"
|
"github.com/zitadel/zitadel/internal/repository/user"
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) AddPersonalAccessToken(ctx context.Context, userID, resourceOwner string, expirationDate time.Time, scopes []string, allowedUserType domain.UserType) (*domain.Token, string, error) {
|
type PersonalAccessToken struct {
|
||||||
userWriteModel, err := c.userWriteModelByID(ctx, userID, resourceOwner)
|
models.ObjectRoot
|
||||||
|
|
||||||
|
ExpirationDate time.Time
|
||||||
|
Scopes []string
|
||||||
|
AllowedUserType domain.UserType
|
||||||
|
|
||||||
|
TokenID string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPersonalAccessToken(resourceOwner string, userID string, expirationDate time.Time, scopes []string, allowedUserType domain.UserType) *PersonalAccessToken {
|
||||||
|
return &PersonalAccessToken{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: userID,
|
||||||
|
ResourceOwner: resourceOwner,
|
||||||
|
},
|
||||||
|
ExpirationDate: expirationDate,
|
||||||
|
Scopes: scopes,
|
||||||
|
AllowedUserType: allowedUserType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pat *PersonalAccessToken) content() error {
|
||||||
|
if pat.ResourceOwner == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-xs0k2n", "Errors.ResourceOwnerMissing")
|
||||||
|
}
|
||||||
|
if pat.AggregateID == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-0pzb1", "Errors.User.UserIDMissing")
|
||||||
|
}
|
||||||
|
if pat.TokenID == "" {
|
||||||
|
return errors.ThrowInvalidArgument(nil, "COMMAND-68xm2o", "Errors.IDMissing")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pat *PersonalAccessToken) valid() (err error) {
|
||||||
|
if err := pat.content(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pat.ExpirationDate, err = domain.ValidateExpirationDate(pat.ExpirationDate)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pat *PersonalAccessToken) checkAggregate(ctx context.Context, filter preparation.FilterToQueryReducer) error {
|
||||||
|
userWriteModel, err := userWriteModelByID(ctx, filter, pat.AggregateID, pat.ResourceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return err
|
||||||
}
|
}
|
||||||
if !isUserStateExists(userWriteModel.UserState) {
|
if !isUserStateExists(userWriteModel.UserState) {
|
||||||
return nil, "", errors.ThrowPreconditionFailed(nil, "COMMAND-Dggw2", "Errors.User.NotFound")
|
return errors.ThrowPreconditionFailed(nil, "COMMAND-Dggw2", "Errors.User.NotFound")
|
||||||
}
|
}
|
||||||
if allowedUserType != domain.UserTypeUnspecified && userWriteModel.UserType != allowedUserType {
|
if pat.AllowedUserType != domain.UserTypeUnspecified && userWriteModel.UserType != pat.AllowedUserType {
|
||||||
return nil, "", errors.ThrowPreconditionFailed(nil, "COMMAND-Df2f1", "Errors.User.WrongType")
|
return errors.ThrowPreconditionFailed(nil, "COMMAND-Df2f1", "Errors.User.WrongType")
|
||||||
}
|
}
|
||||||
tokenID, err := c.idGenerator.Next()
|
return nil
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
tokenWriteModel := NewPersonalAccessTokenWriteModel(userID, tokenID, resourceOwner)
|
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, tokenWriteModel)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
expirationDate, err = domain.ValidateExpirationDate(expirationDate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
events, err := c.eventstore.Push(ctx,
|
|
||||||
user.NewPersonalAccessTokenAddedEvent(
|
|
||||||
ctx,
|
|
||||||
UserAggregateFromWriteModel(&tokenWriteModel.WriteModel),
|
|
||||||
tokenID,
|
|
||||||
expirationDate,
|
|
||||||
scopes,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
err = AppendAndReduce(tokenWriteModel, events...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
return personalTokenWriteModelToToken(tokenWriteModel, c.keyAlgorithm)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) RemovePersonalAccessToken(ctx context.Context, userID, tokenID, resourceOwner string) (*domain.ObjectDetails, error) {
|
func (c *Commands) AddPersonalAccessToken(ctx context.Context, pat *PersonalAccessToken) (_ *domain.ObjectDetails, err error) {
|
||||||
tokenWriteModel, err := c.personalAccessTokenWriteModelByID(ctx, userID, tokenID, resourceOwner)
|
if pat.TokenID == "" {
|
||||||
|
pat.TokenID, err = c.idGenerator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
validation := prepareAddPersonalAccessToken(pat, c.keyAlgorithm)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !tokenWriteModel.Exists() {
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
return nil, errors.ThrowNotFound(nil, "COMMAND-4m77G", "Errors.User.PAT.NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
pushedEvents, err := c.eventstore.Push(ctx,
|
|
||||||
user.NewPersonalAccessTokenRemovedEvent(ctx, UserAggregateFromWriteModel(&tokenWriteModel.WriteModel), tokenID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = AppendAndReduce(tokenWriteModel, pushedEvents...)
|
return &domain.ObjectDetails{
|
||||||
if err != nil {
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
return nil, err
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
}
|
ResourceOwner: events[len(events)-1].Aggregate().ResourceOwner,
|
||||||
return writeModelToObjectDetails(&tokenWriteModel.WriteModel), nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) personalAccessTokenWriteModelByID(ctx context.Context, userID, tokenID, resourceOwner string) (writeModel *PersonalAccessTokenWriteModel, err error) {
|
func prepareAddPersonalAccessToken(pat *PersonalAccessToken, algorithm crypto.EncryptionAlgorithm) preparation.Validation {
|
||||||
if userID == "" {
|
return func() (_ preparation.CreateCommands, err error) {
|
||||||
return nil, errors.ThrowInvalidArgument(nil, "COMMAND-4n8vs", "Errors.User.UserIDMissing")
|
if err := pat.valid(); err != nil {
|
||||||
}
|
return nil, err
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
}
|
||||||
defer func() { span.EndWithError(err) }()
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) (_ []eventstore.Command, err error) {
|
||||||
|
writeModel, err := getPersonalAccessTokenWriteModelByID(ctx, filter, pat.AggregateID, pat.TokenID, pat.ResourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
writeModel = NewPersonalAccessTokenWriteModel(userID, tokenID, resourceOwner)
|
pat.Token, err = createToken(algorithm, writeModel.TokenID, writeModel.AggregateID)
|
||||||
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []eventstore.Command{
|
||||||
|
user.NewPersonalAccessTokenAddedEvent(
|
||||||
|
ctx,
|
||||||
|
UserAggregateFromWriteModel(&writeModel.WriteModel),
|
||||||
|
pat.TokenID,
|
||||||
|
pat.ExpirationDate,
|
||||||
|
pat.Scopes,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) RemovePersonalAccessToken(ctx context.Context, pat *PersonalAccessToken) (*domain.ObjectDetails, error) {
|
||||||
|
validation := prepareRemovePersonalAccessToken(pat)
|
||||||
|
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return writeModel, nil
|
events, err := c.eventstore.Push(ctx, cmds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &domain.ObjectDetails{
|
||||||
|
Sequence: events[len(events)-1].Sequence(),
|
||||||
|
EventDate: events[len(events)-1].CreationDate(),
|
||||||
|
ResourceOwner: events[len(events)-1].Aggregate().ResourceOwner,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareRemovePersonalAccessToken(pat *PersonalAccessToken) preparation.Validation {
|
||||||
|
return func() (_ preparation.CreateCommands, err error) {
|
||||||
|
if err := pat.content(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return func(ctx context.Context, filter preparation.FilterToQueryReducer) (_ []eventstore.Command, err error) {
|
||||||
|
writeModel, err := getPersonalAccessTokenWriteModelByID(ctx, filter, pat.AggregateID, pat.TokenID, pat.ResourceOwner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !writeModel.Exists() {
|
||||||
|
return nil, errors.ThrowNotFound(nil, "COMMAND-4m77G", "Errors.User.PAT.NotFound")
|
||||||
|
}
|
||||||
|
return []eventstore.Command{
|
||||||
|
user.NewPersonalAccessTokenRemovedEvent(
|
||||||
|
ctx,
|
||||||
|
UserAggregateFromWriteModel(&writeModel.WriteModel),
|
||||||
|
pat.TokenID,
|
||||||
|
),
|
||||||
|
}, nil
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createToken(algorithm crypto.EncryptionAlgorithm, tokenID, userID string) (string, error) {
|
||||||
|
encrypted, err := algorithm.Encrypt([]byte(tokenID + ":" + userID))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return base64.RawURLEncoding.EncodeToString(encrypted), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPersonalAccessTokenWriteModelByID(ctx context.Context, filter preparation.FilterToQueryReducer, userID, tokenID, resourceOwner string) (_ *PersonalAccessTokenWriteModel, err error) {
|
||||||
|
writeModel := NewPersonalAccessTokenWriteModel(userID, tokenID, resourceOwner)
|
||||||
|
events, err := filter(ctx, writeModel.Query())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(events) == 0 {
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
||||||
|
writeModel.AppendEvents(events...)
|
||||||
|
err = writeModel.Reduce()
|
||||||
|
return writeModel, err
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,19 @@ type ApplicationKey struct {
|
|||||||
PublicKey []byte
|
PublicKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *ApplicationKey) setPublicKey(publicKey []byte) {
|
func (k *ApplicationKey) SetPublicKey(publicKey []byte) {
|
||||||
k.PublicKey = publicKey
|
k.PublicKey = publicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *ApplicationKey) setPrivateKey(privateKey []byte) {
|
func (k *ApplicationKey) SetPrivateKey(privateKey []byte) {
|
||||||
k.PrivateKey = privateKey
|
k.PrivateKey = privateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *ApplicationKey) expirationDate() time.Time {
|
func (k *ApplicationKey) GetExpirationDate() time.Time {
|
||||||
return k.ExpirationDate
|
return k.ExpirationDate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *ApplicationKey) setExpirationDate(expiration time.Time) {
|
func (k *ApplicationKey) SetExpirationDate(expiration time.Time) {
|
||||||
k.ExpirationDate = expiration
|
k.ExpirationDate = expiration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type authNKey interface {
|
type authNKey interface {
|
||||||
setPublicKey([]byte)
|
SetPublicKey([]byte)
|
||||||
setPrivateKey([]byte)
|
SetPrivateKey([]byte)
|
||||||
expiration
|
expiration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ func SetNewAuthNKeyPair(key authNKey, keySize int) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
key.setPrivateKey(privateKey)
|
key.SetPrivateKey(privateKey)
|
||||||
key.setPublicKey(publicKey)
|
key.SetPublicKey(publicKey)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,16 +12,16 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type expiration interface {
|
type expiration interface {
|
||||||
expirationDate() time.Time
|
GetExpirationDate() time.Time
|
||||||
setExpirationDate(time.Time)
|
SetExpirationDate(time.Time)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnsureValidExpirationDate(key expiration) error {
|
func EnsureValidExpirationDate(key expiration) error {
|
||||||
date, err := ValidateExpirationDate(key.expirationDate())
|
date, err := ValidateExpirationDate(key.GetExpirationDate())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
key.setExpirationDate(date)
|
key.SetExpirationDate(date)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,17 +42,7 @@ func (key *MachineKey) Detail() ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (key *MachineKey) MarshalJSON() ([]byte, error) {
|
func (key *MachineKey) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(struct {
|
return MachineKeyMarshalJSON(key.KeyID, key.PrivateKey, key.AggregateID)
|
||||||
Type string `json:"type"`
|
|
||||||
KeyID string `json:"keyId"`
|
|
||||||
Key string `json:"key"`
|
|
||||||
UserID string `json:"userId"`
|
|
||||||
}{
|
|
||||||
Type: "serviceaccount",
|
|
||||||
KeyID: key.KeyID,
|
|
||||||
Key: string(key.PrivateKey),
|
|
||||||
UserID: key.AggregateID,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MachineKeyState int32
|
type MachineKeyState int32
|
||||||
@ -68,3 +58,17 @@ const (
|
|||||||
func (f MachineKeyState) Valid() bool {
|
func (f MachineKeyState) Valid() bool {
|
||||||
return f >= 0 && f < machineKeyStateCount
|
return f >= 0 && f < machineKeyStateCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MachineKeyMarshalJSON(keyID string, privateKey []byte, userID string) ([]byte, error) {
|
||||||
|
return json.Marshal(struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
KeyID string `json:"keyId"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
}{
|
||||||
|
Type: "serviceaccount",
|
||||||
|
KeyID: keyID,
|
||||||
|
Key: string(privateKey),
|
||||||
|
UserID: userID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user