Skip to content

Commit

Permalink
feat(app-reg-v2): display proper tables depending on auth strategy fo…
Browse files Browse the repository at this point in the history
…r app (#403)
  • Loading branch information
davidma415 authored Feb 16, 2024
1 parent dc2330a commit a166e0d
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 22 deletions.
8 changes: 6 additions & 2 deletions cypress/e2e/fixtures/consts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GetApplicationResponse, GetRegistrationResponse, PortalContext, Product, ProductVersion, RegistrationConfiguration } from '@kong/sdk-portal-js'
import { AuthStrategyKeyAuthCredentialTypeEnum, GetApplicationResponse, GetRegistrationResponse, PortalContext, Product, ProductVersion, RegistrationConfiguration } from '@kong/sdk-portal-js'

const versions: ProductVersion[] = [
{
Expand Down Expand Up @@ -133,7 +133,11 @@ export const appWithAuthStrategy: GetApplicationResponse = {
id: crypto.randomUUID(),
created_at: '2022-03-25T13:15:02.104Z',
updated_at: '2022-03-25T13:15:02.104Z',
auth_strategy_id: '452664ba-7d37-4e12-875c-3ca8044446fd'
auth_strategy: {
id: crypto.randomUUID(),
name: 'keyauthstrat',
credential_type: AuthStrategyKeyAuthCredentialTypeEnum.KeyAuth
}
}

const productRegistration: GetRegistrationResponse = {
Expand Down
119 changes: 118 additions & 1 deletion cypress/e2e/specs/application_registration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CredentialCreationResponse, GetApplicationResponse, ListAuthStrategiesItem, ListCredentialsResponse, ListCredentialsResponseDataInner, ListRegistrationsResponse } from '@kong/sdk-portal-js'
import { AuthStrategyClientCredentialsCredentialTypeEnum, AuthStrategyKeyAuthCredentialTypeEnum, CredentialCreationResponse, GetApplicationResponse, ListAuthStrategiesItem, ListCredentialsResponse, ListCredentialsResponseDataInner, ListRegistrationsResponse } from '@kong/sdk-portal-js'
import { product, versions, productRegistration, apps, productWithKeyAuthAppAuthStrategy, appWithAuthStrategy, versionWithKeyAuthAuthStrategy, versionWithOidcAuthStrategy } from '../fixtures/consts'

const mockApplicationWithCredAndReg = (
Expand Down Expand Up @@ -1223,6 +1223,123 @@ describe('Application Registration', () => {
cy.get('.credentials-list').should('exist')
})

it('app-reg-v2 - show credentials table if app is keyauth ', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: true
}
])
const keyAuthApp = {
...apps[0],
auth_strategy: {
id: 'key-auth-strat-id',
name: 'keyauthstrat',
credential_type: AuthStrategyKeyAuthCredentialTypeEnum.KeyAuth
}
}

cy.mockApplications([{ ...keyAuthApp }], 1)
mockApplicationWithCredAndReg({ ...keyAuthApp })

cy.visit('/my-apps')

cy.get('[data-testid="applications-table"] tbody tr').click()

cy.get('[data-testid="client-secret-table"]').should('not.exist')
cy.get('[data-testid="client-secret-table"] [data-testid="refresh-secret-button"]').should('not.exist')
cy.get('.credentials-list').should('exist')
})
it('app-reg-v2 - does not show any tables if app is oidc ', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: true
}
])
const oidcApp = {
...apps[0],
auth_strategy: {
id: 'oidc-strat-id',
name: 'oidc-strat',
auth_methods: [
'client_credentials',
'session',
'bearer'
],
credential_type: AuthStrategyClientCredentialsCredentialTypeEnum.SelfManagedClientCredentials
}
}

cy.mockApplications([{ ...oidcApp }], 1)
mockApplicationWithCredAndReg({ ...oidcApp })

cy.visit('/my-apps')

cy.get('[data-testid="applications-table"] tbody tr').click()

cy.get('[data-testid="client-secret-table"]').should('not.exist')
cy.get('[data-testid="client-secret-table"] [data-testid="refresh-secret-button"]').should('not.exist')
cy.get('.credentials-list').should('not.exist')
})

it('app-reg-v2 - show dcr token table if app is DCR ', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: true
}
])
cy.intercept('POST', `api/v2/applications/${apps[0].id}/refresh-token`, {
statusCode: 200,
body: { client_secret: 'SECRET_TOKEN' }
}).as('refreshToken')

const dcrApp = {
...apps[0],
auth_strategy: {
id: 'okta-strat-id',
name: 'dcr-strat',
auth_methods: [
'bearer',
'client_credentials',
'session'
],
credential_type: AuthStrategyClientCredentialsCredentialTypeEnum.ClientCredentials
}
}

cy.mockApplications([{ ...dcrApp }], 1)
mockApplicationWithCredAndReg({ ...dcrApp })

cy.visit('/my-apps')

cy.get('[data-testid="applications-table"] tbody tr').click()
cy.get('.credentials-list').should('not.exist')

cy.get('[data-testid="client-secret-table"]').should('exist')
cy.get('[data-testid="client-secret-table"] [data-testid="refresh-secret-button"]').should('exist').click()

cy.wait('@refreshToken')

cy.get('.toaster-container-outer .message').should(
'contain',
'Successfully refreshed secret'
)

cy.get('[data-testid="application-secret-token-modal"]').should('exist')
cy.get('[data-testid="copy-button"]').should('contain', 'SECRET_TOKEN').click()

cy.get('.toaster-container-outer .message').should(
'contain',
'"SECRET_TOKEN" copied to clipboard'
)

cy.get('[data-testid="close-btn"]').click()

cy.get('[data-testid="application-secret-token-modal"]').should('not.exist')
})

describe('Credential management with DCR', () => {
it('can refresh token of existing application with dcr', () => {
cy.mockDcrPortal()
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/specs/contextual-analytics.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { apps, productRegistrations, versions } from '../fixtures/consts'
import { apps, productRegistrations } from '../fixtures/consts'

describe('Contextual Developer Analytics', () => {
beforeEach(() => {
Expand Down
10 changes: 5 additions & 5 deletions cypress/e2e/support/utils/generateDocuments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,38 @@ export function generateDocuments (docId: any): DocumentTree[] {
parent_document_id: null,
slug: 'mock-document-1',
title: 'Mock Document #1',
meta: {},
metadata: {},
children: []
},
{
id: crypto.randomUUID(),
parent_document_id: null,
slug: 'mock-document-2',
title: 'Mock Document #3',
meta: {},
metadata: {},
children: []
},
{
id: docId,
parent_document_id: null,
slug: 'mock-document-3',
title: 'Mock Document #3',
meta: {},
metadata: {},
children: [
{
id: crypto.randomUUID(),
parent_document_id: docId,
slug: 'child-document-1',
title: 'Child Document #1',
meta: {},
metadata: {},
children: []
},
{
id: crypto.randomUUID(),
parent_document_id: docId,
slug: 'child-document-2',
title: 'Child Document #2',
meta: {},
metadata: {},
children: []
}
]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@kong-ui-public/spec-renderer": "0.13.5",
"@kong/kong-auth-elements": "2.11.1",
"@kong/kongponents": "8.127.0",
"@kong/sdk-portal-js": "2.7.0",
"@kong/sdk-portal-js": "2.8.0",
"@xstate/vue": "2.0.0",
"axios": "1.6.0",
"date-fns": "3.3.0",
Expand Down
30 changes: 26 additions & 4 deletions src/views/Applications/ApplicationDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@
<hr class="my-6">
</div>
<DcrAuthenticationTable
v-if="isDcr"
v-if="isApplicationDcr"
:application="application"
class="mb-6"
/>
<CredentialsList
v-if="!isDcr"
v-if="!isApplicationDcr && !isApplicationOIDC"
:id="id"
class="mb-6"
/>
Expand Down Expand Up @@ -122,6 +122,9 @@ import {
TimeframeKeys,
TimePeriods
} from '@kong-ui-public/analytics-utilities'
import { FeatureFlags } from '@/constants/feature-flags'
import useLDFeatureFlag from '@/hooks/useLDFeatureFlag'
import { AuthStrategyCredentialType } from '@kong/sdk-portal-js'
export default defineComponent({
name: 'ApplicationDetail',
Expand All @@ -130,6 +133,7 @@ export default defineComponent({
setup () {
const errorMessage = ref('')
const application = ref(null)
const appRegV2Enabled = useLDFeatureFlag(FeatureFlags.AppRegV2, false)
const helpText = useI18nStore().state.helpText
const $route = useRoute()
Expand All @@ -142,7 +146,7 @@ export default defineComponent({
const { portalApiV2 } = usePortalApi()
const appStore = useAppStore()
const { isDcr, allowedTimePeriod } = storeToRefs(appStore)
const { isDcr: isPortalDcr, allowedTimePeriod } = storeToRefs(appStore)
const vitalsLoading = ref(false)
const fixedTimeframe = allowedTimePeriod.value === PortalTimeframeKeys.NINETY_DAYS
? ref(TimePeriods.get(TimeframeKeys.THIRTY_DAY) as Timeframe)
Expand All @@ -160,6 +164,23 @@ export default defineComponent({
}
}))
const isApplicationOIDC = computed(() => {
return application.value.auth_strategy?.credential_type === AuthStrategyCredentialType.SelfManagedClientCredentials
})
const isApplicationDcr = computed(() => {
if (appRegV2Enabled && application.value) {
// check the application type
if (application.value.auth_strategy?.credential_type === AuthStrategyCredentialType.ClientCredentials) {
return true
} else {
return false
}
}
return isPortalDcr.value
})
const analyticsCardTitle = allowedTimePeriod.value === PortalTimeframeKeys.NINETY_DAYS
? `${helpText.analytics.summary30Days} ${helpText.analytics.summary}`
: `${helpText.analytics.summary24Hours} ${helpText.analytics.summary}`
Expand Down Expand Up @@ -190,7 +211,8 @@ export default defineComponent({
helpText,
id,
breadcrumbs,
isDcr,
isApplicationDcr,
isApplicationOIDC,
fixedTimeframe,
vitalsLoading
}
Expand Down
2 changes: 1 addition & 1 deletion src/views/Applications/ApplicationForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ export default defineComponent({
description: res.data.description || '',
redirect_uri: res.data.redirect_uri,
reference_id: res.data.reference_id,
auth_strategy_id: res.data.auth_strategy_id
auth_strategy_id: res.data.auth_strategy?.id
}
if (isDcr.value) {
delete newFormData.reference_id
Expand Down
15 changes: 12 additions & 3 deletions src/views/MyApps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
{{ helpTextVitals.viewAnalytics }}
</div>
<div
v-if="isDcr"
v-if="isApplicationDcr(row)"
data-testid="dropdown-refresh-application-dcr-token"
class="py-2 px-3 type-md cursor-pointer"
@click="handleRefreshSecret(row.id)"
Expand Down Expand Up @@ -215,6 +215,7 @@ import { EXPLORE_V2_DIMENSIONS, EXPLORE_V2_FILTER_TYPES, MetricsConsumer } from
import { storeToRefs } from 'pinia'
import { FeatureFlags } from '@/constants/feature-flags'
import useLDFeatureFlag from '@/hooks/useLDFeatureFlag'
import { GetApplicationResponse, AuthStrategyCredentialType } from '@kong/sdk-portal-js'
export default defineComponent({
name: 'MyApps',
Expand All @@ -236,7 +237,7 @@ export default defineComponent({
const fetchingAuthStrategies = ref(true)
const appStore = useAppStore()
const { isDcr } = storeToRefs(appStore)
const { isDcr: isPortalDcr } = storeToRefs(appStore)
const helpText = useI18nStore().state.helpText.myApp
const helpTextVitals = useI18nStore().state.helpText.analytics
const vitalsLoading = ref(true)
Expand All @@ -246,6 +247,14 @@ export default defineComponent({
initialPageSize: 25
})
const isApplicationDcr = (application: GetApplicationResponse) => {
if (appRegV2Enabled) {
return application.auth_strategy?.credential_type === AuthStrategyCredentialType.ClientCredentials
}
return isPortalDcr.value
}
const modalTitle = computed(() => `Delete ${deleteItem.value?.name}`)
const appIds = ref([])
Expand Down Expand Up @@ -395,7 +404,7 @@ export default defineComponent({
tableHeaders,
handleDelete,
fetchingAuthStrategies,
isDcr,
isApplicationDcr,
deleteItem,
showSecretModal,
appRegV2Enabled,
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1119,10 +1119,10 @@
v-calendar "3.0.0-alpha.8"
vue-draggable-next "^2.2.1"

"@kong/sdk-portal-js@2.7.0":
version "2.7.0"
resolved "https://registry.yarnpkg.com/@kong/sdk-portal-js/-/sdk-portal-js-2.7.0.tgz#8bacc5d27ff4c6ad656c48c809598b1f8d976cce"
integrity sha512-KrbIqStnE/43eGmfZpwhrnZ5f1P0oAxw0Ot4YmcyH9J0J+icyIoZBfBMZLexkeUUkWzE3Hjd0UsNlJ/0sf1yhg==
"@kong/sdk-portal-js@2.8.0":
version "2.8.0"
resolved "https://registry.yarnpkg.com/@kong/sdk-portal-js/-/sdk-portal-js-2.8.0.tgz#38046c8fa3fd48defa2c3d516ae2deebe925a5dd"
integrity sha512-inSNL+aCA8GHJUPyztjxX5a3WweAdjEH2+4f9okM6qhxvs1J0+eKJV+PDpttpb8FX47BZNqmq2W096KgJYqMAQ==
dependencies:
axios "1.6.0"

Expand Down

0 comments on commit a166e0d

Please sign in to comment.