mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-25 16:52:17 +00:00
fix(oidc): use authenticated encryption for opaque tokens (#12017)
# Which Problems Are Solved Opaque tokens now use authenticated encryption. # How the Problems Are Solved - Upgrade zitadel/oidc to v3.47 - Copy crypto implementation for refresh and session tokens (internal to zitadel) - Added config that allows validating old tokens for gradual roll-out # Additional Changes - Set NX cache for `integration-test-build` to `false`, working on a seperate fix. # Additional Context - closes #11315 --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: muhlemmer <[email protected]>
This commit is contained in:
@@ -80,6 +80,7 @@ type Commands struct {
|
||||
webauthnConfig *webauthn_helper.Config
|
||||
keySize int
|
||||
keyAlgorithm crypto.EncryptionAlgorithm
|
||||
authAlgorithm crypto.AuthAlgorithm
|
||||
certificateAlgorithm crypto.EncryptionAlgorithm
|
||||
certKeySize int
|
||||
privateKeyLifetime time.Duration
|
||||
@@ -129,7 +130,8 @@ func StartCommands(
|
||||
externalDomain string,
|
||||
externalSecure bool,
|
||||
externalPort uint16,
|
||||
idpConfigEncryption, otpEncryption, smtpEncryption, smsEncryption, userEncryption, domainVerificationEncryption, oidcEncryption, samlEncryption, targetEncryption crypto.EncryptionAlgorithm,
|
||||
idpConfigEncryption, otpEncryption, smtpEncryption, smsEncryption, userEncryption, domainVerificationEncryption, samlEncryption, targetEncryption crypto.EncryptionAlgorithm,
|
||||
oidcEncryption crypto.AuthEncryptionAlgorithm,
|
||||
httpClient *http.Client,
|
||||
permissionCheck domain.PermissionCheck,
|
||||
sessionTokenVerifier func(ctx context.Context, sessionToken string, sessionID string, tokenID string) (err error),
|
||||
@@ -187,6 +189,7 @@ func StartCommands(
|
||||
domainVerificationGenerator: crypto.NewEncryptionGenerator(defaults.DomainVerification.VerificationGenerator, domainVerificationEncryption),
|
||||
domainVerificationValidator: api_http.ValidateDomain,
|
||||
keyAlgorithm: oidcEncryption,
|
||||
authAlgorithm: oidcEncryption,
|
||||
certificateAlgorithm: samlEncryption,
|
||||
webauthnConfig: webAuthN,
|
||||
httpClient: httpClient,
|
||||
|
||||
@@ -99,6 +99,20 @@ func testSecretGeneratorAddedEvent(typ domain.SecretGeneratorType) *instance.Sec
|
||||
)
|
||||
}
|
||||
|
||||
type mockAuthCrypto struct{}
|
||||
|
||||
func (m *mockAuthCrypto) EncryptToken(data string) (string, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (m *mockAuthCrypto) DecryptToken(token string) (string, error) {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (m *mockAuthCrypto) LegacyTokenEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func Test_newCryptoCode(t *testing.T) {
|
||||
type args struct {
|
||||
typ domain.SecretGeneratorType
|
||||
|
||||
@@ -1490,7 +1490,7 @@ func TestCommands_CreateOIDCSessionFromDeviceAuth(t *testing.T) {
|
||||
Header: http.Header{"foo": []string{"bar"}},
|
||||
},
|
||||
Reason: domain.TokenReasonAuthRequest,
|
||||
RefreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID-rt_refreshTokenID:userID
|
||||
RefreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID",
|
||||
SessionID: "sessionID",
|
||||
},
|
||||
},
|
||||
@@ -1504,6 +1504,7 @@ func TestCommands_CreateOIDCSessionFromDeviceAuth(t *testing.T) {
|
||||
defaultRefreshTokenLifetime: tt.fields.defaultRefreshTokenLifetime,
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
got, err := c.CreateOIDCSessionFromDeviceAuth(tt.args.ctx, tt.args.deviceCode, tt.args.backChannelLogoutURI)
|
||||
c.jobs.Wait()
|
||||
|
||||
@@ -681,7 +681,7 @@ func setupMachineAdmin(commands *Commands, validations *[]preparation.Validation
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
*validations = append(*validations, prepareAddPersonalAccessToken(pat, commands.keyAlgorithm))
|
||||
*validations = append(*validations, prepareAddPersonalAccessToken(pat, commands.authAlgorithm))
|
||||
}
|
||||
if machine.MachineKey != nil {
|
||||
machineKey = NewMachineKey(orgID, userID, machine.MachineKey.ExpirationDate, machine.MachineKey.Type)
|
||||
@@ -705,7 +705,7 @@ func setupLoginClient(commands *Commands, validations *[]preparation.Validation,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*validations = append(*validations, prepareAddPersonalAccessToken(pat, commands.keyAlgorithm))
|
||||
*validations = append(*validations, prepareAddPersonalAccessToken(pat, commands.authAlgorithm))
|
||||
}
|
||||
return pat, nil
|
||||
}
|
||||
|
||||
@@ -1053,6 +1053,7 @@ func TestCommandSide_setupAdmins(t *testing.T) {
|
||||
zitadelRoles: tt.fields.roles,
|
||||
userPasswordHasher: tt.fields.userPasswordHasher,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
validations := make([]preparation.Validation, 0)
|
||||
owner, pat, mk, loginClientPat, err := setupAdmins(r, &validations, tt.args.instanceAgg, tt.args.orgAgg, tt.args.machine, tt.args.human, tt.args.loginClient)
|
||||
@@ -1223,6 +1224,7 @@ func TestCommandSide_setupDefaultOrg(t *testing.T) {
|
||||
zitadelRoles: tt.fields.roles,
|
||||
userPasswordHasher: tt.fields.userPasswordHasher,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
validations := make([]preparation.Validation, 0)
|
||||
pat, mk, loginClientPat, err := setupDefaultOrg(tt.args.ctx, r, &validations, tt.args.instanceAgg, tt.args.orgName, tt.args.machine, tt.args.human, tt.args.loginClient, tt.args.ids)
|
||||
@@ -1395,6 +1397,7 @@ func TestCommandSide_setUpInstance(t *testing.T) {
|
||||
userPasswordHasher: tt.fields.userPasswordHasher,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
GenerateDomain: tt.fields.generateDomain,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
|
||||
validations, pat, mk, loginClientPat, err := setUpInstance(tt.args.ctx, r, tt.args.setup)
|
||||
|
||||
@@ -2,7 +2,6 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -314,7 +313,7 @@ func (c *Commands) newOIDCSessionAddEvents(ctx context.Context, userID, resource
|
||||
return &OIDCSessionEvents{
|
||||
commands: c,
|
||||
idGenerator: c.idGenerator,
|
||||
encryptionAlg: c.keyAlgorithm,
|
||||
authAlg: c.authAlgorithm,
|
||||
events: pending,
|
||||
oidcSessionWriteModel: NewOIDCSessionWriteModel(sessionID, resourceOwner),
|
||||
userStateModel: userStateModel,
|
||||
@@ -325,11 +324,7 @@ func (c *Commands) newOIDCSessionAddEvents(ctx context.Context, userID, resource
|
||||
}
|
||||
|
||||
func (c *Commands) decryptRefreshToken(refreshToken string) (sessionID, refreshTokenID string, err error) {
|
||||
decoded, err := base64.RawURLEncoding.DecodeString(refreshToken)
|
||||
if err != nil {
|
||||
return "", "", zerrors.ThrowInvalidArgument(err, "OIDCS-Cux9a", "Errors.User.RefreshToken.Invalid")
|
||||
}
|
||||
decrypted, err := c.keyAlgorithm.DecryptString(decoded, c.keyAlgorithm.EncryptionKeyID())
|
||||
decrypted, err := c.authAlgorithm.DecryptToken(refreshToken)
|
||||
if err != nil {
|
||||
return "", "", zerrors.ThrowInvalidArgument(err, "OIDCS-Jei0i", "Errors.User.RefreshToken.Invalid")
|
||||
}
|
||||
@@ -372,7 +367,7 @@ func (c *Commands) newOIDCSessionUpdateEvents(ctx context.Context, refreshToken
|
||||
return &OIDCSessionEvents{
|
||||
commands: c,
|
||||
idGenerator: c.idGenerator,
|
||||
encryptionAlg: c.keyAlgorithm,
|
||||
authAlg: c.authAlgorithm,
|
||||
oidcSessionWriteModel: sessionWriteModel,
|
||||
accessTokenLifetime: accessTokenLifetime,
|
||||
refreshTokenLifeTime: refreshTokenLifeTime,
|
||||
@@ -383,7 +378,7 @@ func (c *Commands) newOIDCSessionUpdateEvents(ctx context.Context, refreshToken
|
||||
type OIDCSessionEvents struct {
|
||||
commands *Commands
|
||||
idGenerator id.Generator
|
||||
encryptionAlg crypto.EncryptionAlgorithm
|
||||
authAlg crypto.AuthAlgorithm
|
||||
events []eventstore.Command
|
||||
oidcSessionWriteModel *OIDCSessionWriteModel
|
||||
userStateModel *UserV2WriteModel
|
||||
@@ -502,11 +497,11 @@ func (c *OIDCSessionEvents) generateRefreshToken(userID string) (refreshTokenID,
|
||||
return "", "", err
|
||||
}
|
||||
refreshTokenID = RefreshTokenPrefix + refreshTokenID
|
||||
token, err := c.encryptionAlg.Encrypt([]byte(fmt.Sprintf(oidcTokenFormat, c.oidcSessionWriteModel.OIDCRefreshTokenID(refreshTokenID), userID)))
|
||||
token, err := c.authAlg.EncryptToken(fmt.Sprintf(oidcTokenFormat, c.oidcSessionWriteModel.OIDCRefreshTokenID(refreshTokenID), userID))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return refreshTokenID, base64.RawURLEncoding.EncodeToString(token), nil
|
||||
return refreshTokenID, token, nil
|
||||
}
|
||||
|
||||
func (c *OIDCSessionEvents) PushEvents(ctx context.Context) (*OIDCSession, error) {
|
||||
|
||||
@@ -440,7 +440,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) {
|
||||
Header: http.Header{"foo": []string{"bar"}},
|
||||
},
|
||||
Reason: domain.TokenReasonAuthRequest,
|
||||
RefreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID-rt_refreshTokenID:userID
|
||||
RefreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID",
|
||||
},
|
||||
state: "state",
|
||||
},
|
||||
@@ -584,7 +584,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) {
|
||||
Header: http.Header{"foo": []string{"bar"}},
|
||||
},
|
||||
Reason: domain.TokenReasonAuthRequest,
|
||||
RefreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID-rt_refreshTokenID:userID
|
||||
RefreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID",
|
||||
},
|
||||
state: "state",
|
||||
},
|
||||
@@ -721,6 +721,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) {
|
||||
defaultRefreshTokenLifetime: tt.fields.defaultRefreshTokenLifetime,
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
c.setMilestonesCompletedForTest("instanceID")
|
||||
gotSession, gotState, err := c.CreateOIDCSessionFromAuthRequest(tt.args.ctx, tt.args.authRequestID, tt.args.complianceCheck, tt.args.needRefreshToken, tt.args.backChannelLogoutURI)
|
||||
@@ -1137,7 +1138,7 @@ func TestCommands_CreateOIDCSession(t *testing.T) {
|
||||
UserID: "user2",
|
||||
Issuer: "foo.com",
|
||||
},
|
||||
RefreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID-rt_refreshTokenID:userID
|
||||
RefreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1610,6 +1611,7 @@ func TestCommands_CreateOIDCSession(t *testing.T) {
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
checkPermission: tt.fields.checkPermission,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
c.setMilestonesCompletedForTest("instanceID")
|
||||
got, err := c.CreateOIDCSession(tt.args.ctx,
|
||||
@@ -1703,7 +1705,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
},
|
||||
args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instanceID"),
|
||||
refreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
refreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
complianceCheck: mockRefreshTokenComplianceChecker(nil),
|
||||
},
|
||||
res{
|
||||
@@ -1732,7 +1734,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
},
|
||||
args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instanceID"),
|
||||
refreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
refreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
complianceCheck: mockRefreshTokenComplianceChecker(nil),
|
||||
},
|
||||
res{
|
||||
@@ -1765,7 +1767,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
},
|
||||
args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instanceID"),
|
||||
refreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
refreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
complianceCheck: mockRefreshTokenComplianceChecker(nil),
|
||||
},
|
||||
res{
|
||||
@@ -1821,7 +1823,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
},
|
||||
args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instanceID"),
|
||||
refreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
refreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
scope: []string{"openid", "offline_access"},
|
||||
complianceCheck: mockRefreshTokenComplianceChecker(nil),
|
||||
},
|
||||
@@ -1881,7 +1883,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
},
|
||||
args{
|
||||
ctx: authz.WithInstanceID(context.Background(), "instanceID"),
|
||||
refreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDp1c2VySUQ", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
refreshToken: "V2_oidcSessionID-rt_refreshTokenID:userID", //V2_oidcSessionID:rt_refreshTokenID:userID
|
||||
scope: []string{"openid", "offline_access"},
|
||||
complianceCheck: mockRefreshTokenComplianceChecker(nil),
|
||||
},
|
||||
@@ -1892,7 +1894,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
ClientID: "clientID",
|
||||
UserID: "userID",
|
||||
Audience: []string{"audience"},
|
||||
RefreshToken: "VjJfb2lkY1Nlc3Npb25JRC1ydF9yZWZyZXNoVG9rZW5JRDI6dXNlcklE", // V2_oidcSessionID-rt_refreshTokenID2:userID%
|
||||
RefreshToken: "V2_oidcSessionID-rt_refreshTokenID2:userID", // V2_oidcSessionID-rt_refreshTokenID2:userID%
|
||||
Expiration: time.Time{}.Add(time.Hour),
|
||||
Scope: []string{"openid", "profile", "offline_access"},
|
||||
AuthMethods: []domain.UserAuthMethodType{domain.UserAuthMethodTypePassword},
|
||||
@@ -1914,6 +1916,7 @@ func TestCommands_ExchangeOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
||||
defaultRefreshTokenLifetime: tt.fields.defaultRefreshTokenLifetime,
|
||||
defaultRefreshTokenIdleLifetime: tt.fields.defaultRefreshTokenIdleLifetime,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
got, err := c.ExchangeOIDCSessionRefreshAndAccessToken(tt.args.ctx, tt.args.refreshToken, tt.args.scope, tt.args.complianceCheck)
|
||||
require.ErrorIs(t, err, tt.res.err)
|
||||
|
||||
@@ -164,7 +164,7 @@ func (c *orgSetupCommands) setupOrgAdminMachine(orgAgg *org.Aggregate, machine *
|
||||
}
|
||||
pat.TokenID = tokenID
|
||||
c.pats = append(c.pats, pat)
|
||||
c.validations = append(c.validations, prepareAddPersonalAccessToken(pat, c.commands.keyAlgorithm))
|
||||
c.validations = append(c.validations, prepareAddPersonalAccessToken(pat, c.commands.authAlgorithm))
|
||||
}
|
||||
if machine.MachineKey != nil {
|
||||
machineKey = NewMachineKey(orgAgg.ID, machine.Machine.AggregateID, machine.MachineKey.ExpirationDate, machine.MachineKey.Type)
|
||||
|
||||
@@ -2096,7 +2096,7 @@ func TestCommandSide_SetUpOrg(t *testing.T) {
|
||||
Scopes: []string{openid.ScopeOpenID},
|
||||
AllowedUserType: domain.UserTypeMachine,
|
||||
TokenID: "tokenID",
|
||||
Token: "dG9rZW5JRDp1c2VySUQ", // token
|
||||
Token: "tokenID:userID",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2151,6 +2151,7 @@ func TestCommandSide_SetUpOrg(t *testing.T) {
|
||||
Role: domain.RoleOrgOwner,
|
||||
},
|
||||
},
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
got, err := r.SetUpOrg(tt.args.ctx, tt.args.setupOrg, tt.args.allowInitialMail, tt.args.permissionCheck, tt.args.userIDs...)
|
||||
assert.ErrorIs(t, err, tt.res.err)
|
||||
|
||||
@@ -3,7 +3,6 @@ package command
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -451,17 +450,17 @@ func (c *Commands) sessionUserResourceOwner(ctx context.Context, model *SessionW
|
||||
return r.resourceOwner, nil
|
||||
}
|
||||
|
||||
func sessionTokenCreator(idGenerator id.Generator, sessionAlg crypto.EncryptionAlgorithm) func(sessionID string) (id string, token string, err error) {
|
||||
func sessionTokenCreator(idGenerator id.Generator, sessionAlg crypto.AuthAlgorithm) func(sessionID string) (id string, token string, err error) {
|
||||
return func(sessionID string) (id string, token string, err error) {
|
||||
id, err = idGenerator.Next()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
encrypted, err := sessionAlg.Encrypt([]byte(fmt.Sprintf(authz.SessionTokenFormat, sessionID, id)))
|
||||
token, err = sessionAlg.EncryptToken(fmt.Sprintf(authz.SessionTokenFormat, sessionID, id))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return id, base64.RawURLEncoding.EncodeToString(encrypted), nil
|
||||
return id, token, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||
@@ -85,7 +84,7 @@ func (c *Commands) AddPersonalAccessToken(ctx context.Context, pat *PersonalAcce
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
validation := prepareAddPersonalAccessToken(pat, c.keyAlgorithm)
|
||||
validation := prepareAddPersonalAccessToken(pat, c.authAlgorithm)
|
||||
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -101,7 +100,7 @@ func (c *Commands) AddPersonalAccessToken(ctx context.Context, pat *PersonalAcce
|
||||
}, nil
|
||||
}
|
||||
|
||||
func prepareAddPersonalAccessToken(pat *PersonalAccessToken, algorithm crypto.EncryptionAlgorithm) preparation.Validation {
|
||||
func prepareAddPersonalAccessToken(pat *PersonalAccessToken, algorithm crypto.AuthAlgorithm) preparation.Validation {
|
||||
return func() (_ preparation.CreateCommands, err error) {
|
||||
if err := pat.valid(); err != nil {
|
||||
return nil, err
|
||||
@@ -114,7 +113,7 @@ func prepareAddPersonalAccessToken(pat *PersonalAccessToken, algorithm crypto.En
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pat.Token, err = createToken(algorithm, writeModel.TokenID, writeModel.AggregateID)
|
||||
pat.Token, err = algorithm.EncryptToken(pat.TokenID + ":" + pat.AggregateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -173,14 +172,6 @@ func prepareRemovePersonalAccessToken(pat *PersonalAccessToken) preparation.Vali
|
||||
}
|
||||
}
|
||||
|
||||
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, check PermissionCheck) (_ *PersonalAccessTokenWriteModel, err error) {
|
||||
writeModel := NewPersonalAccessTokenWriteModel(userID, tokenID, resourceOwner)
|
||||
events, err := filter(ctx, writeModel.Query())
|
||||
|
||||
@@ -2,7 +2,6 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -203,7 +202,7 @@ func TestCommands_AddPersonalAccessToken(t *testing.T) {
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
token: base64.RawURLEncoding.EncodeToString([]byte("token1:user1")),
|
||||
token: "token1:user1",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -251,16 +250,17 @@ func TestCommands_AddPersonalAccessToken(t *testing.T) {
|
||||
want: &domain.ObjectDetails{
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
token: base64.RawURLEncoding.EncodeToString([]byte("token1:user1")),
|
||||
token: "token1:user1",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := &Commands{
|
||||
eventstore: tt.fields.eventstore,
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
eventstore: tt.fields.eventstore,
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
keyAlgorithm: tt.fields.keyAlgorithm,
|
||||
authAlgorithm: &mockAuthCrypto{},
|
||||
}
|
||||
got, err := c.AddPersonalAccessToken(tt.args.ctx, tt.args.pat)
|
||||
if tt.res.err == nil {
|
||||
|
||||
Reference in New Issue
Block a user