mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-21 06:39:02 +00:00
fix(api): fix for ListAppKeys() not returning app keys (#10465)
# Which Problems Are Solved `ListAppKeys()` does not work properly, in that it does not return any app keys. # How the Problems Are Solved The issue stems from a mistake SQL query not joining the `projections.authn_keys2` table to `projections.projects4` instead of joining to `projections.apps7` # Additional Changes `ListAppKeys()` returns the app key IDs in order of their creation - Closes https://github.com/zitadel/zitadel/issues/10420 - backport to v4.x --------- Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
109
internal/api/grpc/management/integration_test/app_key_test.go
Normal file
109
internal/api/grpc/management/integration_test/app_key_test.go
Normal file
@@ -0,0 +1,109 @@
|
||||
//go:build integration
|
||||
|
||||
package management_test
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
app "github.com/zitadel/zitadel/pkg/grpc/app/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/management"
|
||||
project "github.com/zitadel/zitadel/pkg/grpc/project/v2beta"
|
||||
)
|
||||
|
||||
func TestServer_ListAppKeys(t *testing.T) {
|
||||
// create project
|
||||
prjName := gofakeit.Name()
|
||||
createPrjRes, err := Instance.Client.Projectv2Beta.CreateProject(IAMOwnerCTX, &project.CreateProjectRequest{
|
||||
Name: prjName,
|
||||
OrganizationId: Instance.DefaultOrg.Id,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
prjId := createPrjRes.Id
|
||||
|
||||
// add app to project
|
||||
createAppjRes, err := Instance.Client.AppV2Beta.CreateApplication(IAMOwnerCTX, &app.CreateApplicationRequest{
|
||||
ProjectId: prjId,
|
||||
Name: gofakeit.Name(),
|
||||
CreationRequestType: &app.CreateApplicationRequest_ApiRequest{
|
||||
ApiRequest: &app.CreateAPIApplicationRequest{
|
||||
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
appId := createAppjRes.AppId
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
expectedKeyIdsFunc func() []string
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "happy path",
|
||||
expectedKeyIdsFunc: func() []string {
|
||||
// add other app to project
|
||||
createOtherAppjRes, err := Instance.Client.AppV2Beta.CreateApplication(IAMOwnerCTX, &app.CreateApplicationRequest{
|
||||
ProjectId: prjId,
|
||||
Name: gofakeit.Name(),
|
||||
CreationRequestType: &app.CreateApplicationRequest_ApiRequest{
|
||||
ApiRequest: &app.CreateAPIApplicationRequest{
|
||||
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
otherAppId := createOtherAppjRes.AppId
|
||||
// add other project key ids - These SHOULD NOT be returned when calling ListAppKeys()
|
||||
for range 5 {
|
||||
_, err := Instance.Client.AppV2Beta.CreateApplicationKey(IAMOwnerCTX, &app.CreateApplicationKeyRequest{
|
||||
AppId: otherAppId,
|
||||
ProjectId: prjId,
|
||||
ExpirationDate: timestamppb.New(time.Now().AddDate(0, 0, 1).UTC()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// create app keys we expect to be rturned form ListAppKeys()
|
||||
keyIDs := make([]string, 5)
|
||||
for i := range len(keyIDs) {
|
||||
res, err := Instance.Client.AppV2Beta.CreateApplicationKey(IAMOwnerCTX, &app.CreateApplicationKeyRequest{
|
||||
AppId: appId,
|
||||
ProjectId: prjId,
|
||||
ExpirationDate: timestamppb.New(time.Now().AddDate(0, 0, 1).UTC()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
keyIDs[i] = res.Id
|
||||
}
|
||||
return keyIDs
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ct *assert.CollectT) {
|
||||
expectedKeyIds := tt.expectedKeyIdsFunc()
|
||||
|
||||
res, err := Client.ListAppKeys(IAMOwnerCTX, &management.ListAppKeysRequest{
|
||||
AppId: appId,
|
||||
ProjectId: prjId,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, len(expectedKeyIds), len(res.GetResult()))
|
||||
|
||||
for _, key := range res.GetResult() {
|
||||
assert.True(t, slices.Contains(expectedKeyIds, key.Id))
|
||||
}
|
||||
}, retryDuration, tick)
|
||||
})
|
||||
}
|
||||
}
|
@@ -13,9 +13,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
CTX, OrgCTX context.Context
|
||||
Instance *integration.Instance
|
||||
Client mgmt_pb.ManagementServiceClient
|
||||
CTX, IAMOwnerCTX, OrgCTX context.Context
|
||||
Instance *integration.Instance
|
||||
Client mgmt_pb.ManagementServiceClient
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -25,6 +25,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
Instance = integration.NewInstance(ctx)
|
||||
CTX = ctx
|
||||
IAMOwnerCTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
|
||||
OrgCTX = Instance.WithAuthorization(ctx, integration.UserTypeOrgOwner)
|
||||
Client = Instance.Client.Mgmt
|
||||
return m.Run()
|
||||
|
@@ -169,17 +169,16 @@ func (q *Queries) searchAuthNKeys(ctx context.Context, queries *AuthNKeySearchQu
|
||||
case JoinFilterUnspecified:
|
||||
// Select all authN keys
|
||||
case JoinFilterApp:
|
||||
joinCol := ProjectColumnID
|
||||
query = query.Join(joinCol.table.identifier() + " ON " + AuthNKeyColumnIdentifier.identifier() + " = " + joinCol.identifier())
|
||||
query = query.Join(join(AppColumnID, AuthNKeyColumnObjectID))
|
||||
case JoinFilterUserMachine:
|
||||
joinCol := MachineUserIDCol
|
||||
query = query.Join(joinCol.table.identifier() + " ON " + AuthNKeyColumnIdentifier.identifier() + " = " + joinCol.identifier())
|
||||
query = query.Join(join(MachineUserIDCol, AuthNKeyColumnIdentifier))
|
||||
query = userPermissionCheckV2WithCustomColumns(ctx, query, permissionCheckV2, queries.Queries, AuthNKeyColumnResourceOwner, AuthNKeyColumnIdentifier)
|
||||
}
|
||||
eq := sq.Eq{
|
||||
AuthNKeyColumnEnabled.identifier(): true,
|
||||
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
}
|
||||
|
||||
stmt, args, err := query.Where(eq).ToSql()
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInvalidArgument(err, "QUERY-SAf3f", "Errors.Query.InvalidRequest")
|
||||
|
Reference in New Issue
Block a user