2022-02-08 08:37:28 +00:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
2022-04-26 23:01:45 +00:00
|
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
|
|
"github.com/zitadel/zitadel/internal/errors"
|
|
|
|
"github.com/zitadel/zitadel/internal/repository/user"
|
|
|
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
2022-02-08 08:37:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (c *Commands) AddPersonalAccessToken(ctx context.Context, userID, resourceOwner string, expirationDate time.Time, scopes []string, allowedUserType domain.UserType) (*domain.Token, string, error) {
|
|
|
|
userWriteModel, err := c.userWriteModelByID(ctx, userID, resourceOwner)
|
|
|
|
if err != nil {
|
|
|
|
return nil, "", err
|
|
|
|
}
|
|
|
|
if !isUserStateExists(userWriteModel.UserState) {
|
|
|
|
return nil, "", errors.ThrowPreconditionFailed(nil, "COMMAND-Dggw2", "Errors.User.NotFound")
|
|
|
|
}
|
|
|
|
if allowedUserType != domain.UserTypeUnspecified && userWriteModel.UserType != allowedUserType {
|
|
|
|
return nil, "", errors.ThrowPreconditionFailed(nil, "COMMAND-Df2f1", "Errors.User.WrongType")
|
|
|
|
}
|
|
|
|
tokenID, err := c.idGenerator.Next()
|
|
|
|
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) {
|
|
|
|
tokenWriteModel, err := c.personalAccessTokenWriteModelByID(ctx, userID, tokenID, resourceOwner)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if !tokenWriteModel.Exists() {
|
|
|
|
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 {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = AppendAndReduce(tokenWriteModel, pushedEvents...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return writeModelToObjectDetails(&tokenWriteModel.WriteModel), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Commands) personalAccessTokenWriteModelByID(ctx context.Context, userID, tokenID, resourceOwner string) (writeModel *PersonalAccessTokenWriteModel, err error) {
|
|
|
|
if userID == "" {
|
|
|
|
return nil, errors.ThrowInvalidArgument(nil, "COMMAND-4n8vs", "Errors.User.UserIDMissing")
|
|
|
|
}
|
|
|
|
ctx, span := tracing.NewSpan(ctx)
|
|
|
|
defer func() { span.EndWithError(err) }()
|
|
|
|
|
|
|
|
writeModel = NewPersonalAccessTokenWriteModel(userID, tokenID, resourceOwner)
|
|
|
|
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return writeModel, nil
|
|
|
|
}
|