Skip to content

Commit

Permalink
feat(app-reg-v2): show auth strategy info in spec view (TDX-3718) (#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidma415 authored Feb 5, 2024
1 parent 8341d0b commit 72159dc
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 4 deletions.
27 changes: 26 additions & 1 deletion cypress/e2e/fixtures/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@ const versions: ProductVersion[] = [
}
]

const versionWithOidcAuthStrategy: ProductVersion = {
...versions[0],
registration_configs: [
{
auth_methods: ['bearer', 'client_credentials'],
name: 'oidc auth strategy',
credential_type: 'client_credentials'
}
]
}

const versionWithKeyAuthAuthStrategy: ProductVersion = {
created_at: '2022-03-26T14:52:46.323Z',
updated_at: '2022-03-26T14:52:46.323Z',
id: '1afac832-5b2a-474c-a56d-c241364f41cf',
name: 'v1-beta',
deprecated: false,
registration_configs: [
{
name: 'key auth auth strategy',
credential_type: 'key_auth'
}
]
}

const product: Product = {
created_at: '2022-03-23T14:52:41.893Z',
updated_at: '2022-03-23T14:52:41.893Z',
Expand Down Expand Up @@ -94,4 +119,4 @@ const productRegistrations: GetRegistrationResponse[] = [
productRegistration
]

export { versions, product, productVersion, productRegistration, productRegistrations, apps, defaultContext }
export { versions, product, productVersion, productRegistration, versionWithOidcAuthStrategy, versionWithKeyAuthAuthStrategy, productRegistrations, apps, defaultContext }
79 changes: 78 additions & 1 deletion cypress/e2e/specs/application_registration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CredentialCreationResponse, GetApplicationResponse, ListCredentialsResponse, ListCredentialsResponseDataInner, ListRegistrationsResponse } from '@kong/sdk-portal-js'
import { product, versions, productRegistration, apps } from '../fixtures/consts'
import { product, versions, productRegistration, apps, versionWithKeyAuthAuthStrategy, versionWithOidcAuthStrategy } from '../fixtures/consts'

const mockApplicationWithCredAndReg = (
data: GetApplicationResponse,
Expand Down Expand Up @@ -673,6 +673,83 @@ describe('Application Registration', () => {
'You will be notified upon approval'
)
})
it('appreg-v2 - feature flag off - does not show auth strategy card', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: false
}
])
cy.mockProductDocument()
cy.mockProduct(product.id, product, [versionWithKeyAuthAuthStrategy])
cy.mockProductVersionApplicationRegistration(versions[0])
cy.mockGetProductDocuments(product.id)
cy.mockProductOperations(product.id, versions[0].id)
cy.mockProductVersionSpec(product.id, versions[0].id)
cy.mockRegistrations('*', []) // mock with empty so that we add one.

cy.viewport(1440, 900)
cy.visit(`/spec/${product.id}`)
cy.get('.swagger-ui', { timeout: 12000 }).should('exist')

cy.get('[data-testid="auth-strategy-card"]').should('not.exist')
cy.get('[data-testid="app-reg-v2-register-btn"]').should('not.exist')
cy.get('[data-testid="register-button"]', { timeout: 12000 }).should('exist')
})
it('appreg-v2 - feature flag on - shows information about application auth strategy (key-auth)', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: true
}
])
cy.mockProductDocument()
cy.mockProduct(product.id, product, [versionWithKeyAuthAuthStrategy])
cy.mockProductVersionApplicationRegistration(versions[0])
cy.mockGetProductDocuments(product.id)
cy.mockProductOperations(product.id, versions[0].id)
cy.mockProductVersionSpec(product.id, versions[0].id)
cy.mockRegistrations('*', []) // mock with empty so that we add one.

cy.viewport(1440, 900)
cy.visit(`/spec/${product.id}`)
cy.get('.swagger-ui', { timeout: 12000 }).should('exist')

cy.get('[data-testid="auth-strategy-card"]').should('exist')
cy.get('[data-testid="auth-strategy-title"]').should('exist').should('contain.text', versionWithKeyAuthAuthStrategy.registration_configs[0].name)
cy.get('[data-testid="auth-method-key-auth"]').should('exist')
cy.get('[data-testid="app-reg-v2-bearer"]').should('not.exist')
cy.get('[data-testid="app-reg-v2-register-btn"]').should('exist')
cy.get('[data-testid="register-button"]', { timeout: 12000 }).should('not.exist')
})
it('appreg-v2 - feature flag on - shows information about application auth strategy (oidc auth)', () => {
cy.mockLaunchDarklyFlags([
{
name: 'tdx-3531-app-reg-v2',
value: true
}
])
cy.mockProductDocument()
cy.mockProduct(product.id, product, [versionWithOidcAuthStrategy])
cy.mockProductVersionApplicationRegistration(versions[0])
cy.mockGetProductDocuments(product.id)
cy.mockProductOperations(product.id, versions[0].id)
cy.mockProductVersionSpec(product.id, versions[0].id)
cy.mockRegistrations('*', []) // mock with empty so that we add one.

cy.viewport(1440, 900)
cy.visit(`/spec/${product.id}`)
cy.get('.swagger-ui', { timeout: 12000 }).should('exist')

cy.get('[data-testid="auth-strategy-card"]').should('exist')
cy.get('[data-testid="auth-strategy-title"]').should('exist').should('contain.text', versionWithOidcAuthStrategy.registration_configs[0].name)
cy.get('[data-testid="auth-method-key-auth"]').should('not.exist')
versionWithOidcAuthStrategy.registration_configs[0].auth_methods.forEach((method) => {
cy.get(`[data-testid="auth-method-${method}"]`).should('exist')
})
cy.get('[data-testid="app-reg-v2-register-btn"]').should('exist')
cy.get('[data-testid="register-button"]', { timeout: 12000 }).should('not.exist')
})

it('does not show select available scopes if no scopes are available - feature flag on', () => {
cy.mockProductDocument()
Expand Down
2 changes: 1 addition & 1 deletion src/components/ActionsDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
>
<slot>
<KButton
apperance="btn-link"
appearance="btn-link"
class="action-dropdown-button"
>
<KBadge
Expand Down
9 changes: 9 additions & 0 deletions src/locales/ca_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const ca_ES: I18nType = {
noProductVersionsTitle: translationNeeded(en.productVersion.noProductVersionsTitle),
registerProductVersion: translationNeeded(en.productVersion.registerProductVersion)
},
authStrategyInfo: {
title: (authStrategyName: string) => translationNeeded(en.authStrategyInfo.title(authStrategyName)),
registerBtnText: (productVersionName: string) => translationNeeded(en.authStrategyInfo.registerBtnText(productVersionName)),
authMethods: translationNeeded(en.authStrategyInfo.authMethods),
bearer: translationNeeded(en.authStrategyInfo.bearer),
keyAuth: translationNeeded(en.authStrategyInfo.keyAuth),
clientCredentials: translationNeeded(en.authStrategyInfo.clientCredentials),
session: translationNeeded(en.authStrategyInfo.session)
},
userDropdown: {
myApps: 'Les meves aplicacions',
logout: 'Tancar sessió'
Expand Down
9 changes: 9 additions & 0 deletions src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const de: I18nType = {
noProductVersionsTitle: translationNeeded(en.productVersion.noProductVersionsTitle),
registerProductVersion: translationNeeded(en.productVersion.registerProductVersion)
},
authStrategyInfo: {
title: (authStrategyName: string) => translationNeeded(en.authStrategyInfo.title(authStrategyName)),
registerBtnText: (productVersionName: string) => translationNeeded(en.authStrategyInfo.registerBtnText(productVersionName)),
authMethods: translationNeeded(en.authStrategyInfo.authMethods),
bearer: translationNeeded(en.authStrategyInfo.bearer),
keyAuth: translationNeeded(en.authStrategyInfo.keyAuth),
clientCredentials: translationNeeded(en.authStrategyInfo.clientCredentials),
session: translationNeeded(en.authStrategyInfo.session)
},
userDropdown: {
myApps: 'Meine Applikationen',
logout: 'Abmelden'
Expand Down
9 changes: 9 additions & 0 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ export const en = {
noProductVersionsTitle: 'No Product Versions',
registerProductVersion: 'Register Product version'
},
authStrategyInfo: {
title: (authStrategyName: string) => `Supported Application Auth Strategy: ${authStrategyName}`,
registerBtnText: (productVersionName: string) => `Register for ${productVersionName}`,
authMethods: 'Auth Methods:',
bearer: 'Bearer',
keyAuth: 'Key Auth',
clientCredentials: 'Client Credentials',
session: 'Session'
},
userDropdown: {
myApps: 'My Apps',
logout: 'Logout'
Expand Down
9 changes: 9 additions & 0 deletions src/locales/es_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const es_ES: I18nType = {
noProductVersionsTitle: translationNeeded(en.productVersion.noProductVersionsTitle),
registerProductVersion: translationNeeded(en.productVersion.registerProductVersion)
},
authStrategyInfo: {
title: (authStrategyName: string) => translationNeeded(en.authStrategyInfo.title(authStrategyName)),
registerBtnText: (productVersionName: string) => translationNeeded(en.authStrategyInfo.registerBtnText(productVersionName)),
authMethods: translationNeeded(en.authStrategyInfo.authMethods),
bearer: translationNeeded(en.authStrategyInfo.bearer),
keyAuth: translationNeeded(en.authStrategyInfo.keyAuth),
clientCredentials: translationNeeded(en.authStrategyInfo.clientCredentials),
session: translationNeeded(en.authStrategyInfo.session)
},
userDropdown: {
myApps: 'Mis aplicaciones',
logout: 'Cerrar sesión'
Expand Down
9 changes: 9 additions & 0 deletions src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export const fr: I18nType = {
noProductVersionsTitle: 'Aucune version de produit',
registerProductVersion: 'Enregistrer une version de produit'
},
authStrategyInfo: {
title: (authStrategyName: string) => translationNeeded(en.authStrategyInfo.title(authStrategyName)),
registerBtnText: (productVersionName: string) => translationNeeded(en.authStrategyInfo.registerBtnText(productVersionName)),
authMethods: translationNeeded(en.authStrategyInfo.authMethods),
bearer: translationNeeded(en.authStrategyInfo.bearer),
keyAuth: translationNeeded(en.authStrategyInfo.keyAuth),
clientCredentials: translationNeeded(en.authStrategyInfo.clientCredentials),
session: translationNeeded(en.authStrategyInfo.session)
},
userDropdown: {
myApps: 'Mes Applications',
logout: 'Déconnexion'
Expand Down
9 changes: 9 additions & 0 deletions src/locales/i18n-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ export interface I18nType {
noProductVersionsTitle: string;
registerProductVersion: string;
};
authStrategyInfo: {
title: (authStrategyName: string) => string;
registerBtnText: (productVersionName: string) => string;
authMethods: string;
bearer: string;
keyAuth: string;
clientCredentials: string;
session: string;
};
userDropdown: {
myApps: string;
logout: string;
Expand Down
93 changes: 92 additions & 1 deletion src/views/Spec.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,53 @@
>
<div class="container max-w-screen-2xl px-5 md:px-0">
<div class="swagger-ui has-sidebar breadcrumbs">
<KCard
v-if="appRegV2Enabled && applicationRegistrationEnabled && currentVersion?.registration_configs?.length"
class="auth-strategy-card"
data-testid="auth-strategy-card"
>
<template #body>
<p
class="title"
data-testid="auth-strategy-title"
>
{{ helpText.authStrategyInfo.title(currentVersion?.registration_configs?.[0].name) }}
</p>
<p class="auth-methods-label">
{{ helpText.authStrategyInfo.authMethods }}
</p>
<div class="info-container">
<KCard class="badge-container">
<template #body>
<KBadge
v-if="currentVersion?.registration_configs?.[0].credential_type === 'key_auth'"
shape="rectangular"
data-testid="auth-method-key-auth"
>
{{ helpText.authStrategyInfo.keyAuth }}
</KBadge>
<KBadge
v-for="(authMethod, index) in currentVersion?.registration_configs?.[0].auth_methods"
v-else
:key="authMethod + index"
:data-testid="`auth-method-${authMethod}`"
shape="rectangular"
>
{{ authMethodLabelObj[authMethod] }}
</KBadge>
</template>
</KCard>
<KButton
appearance="primary"
class="register-btn"
data-testid="app-reg-v2-register-btn"
@click="triggerViewSpecRegistrationModal"
>
{{ helpText.authStrategyInfo.registerBtnText(currentVersion?.name) }}
</KButton>
</div>
</template>
</KCard>
<KBreadcrumbs :items="breadcrumbs" />
</div>
</div>
Expand Down Expand Up @@ -40,7 +87,7 @@
class="w-100"
:document="spec"
:has-sidebar="false"
:application-registration-enabled="applicationRegistrationEnabled"
:application-registration-enabled="appRegV2Enabled ? false : applicationRegistrationEnabled"
:active-operation="sidebarActiveOperationListItem"
:current-version="currentVersion?.name"
@clicked-view-spec="triggerViewSpecModal"
Expand Down Expand Up @@ -79,6 +126,8 @@ import { OperationListItem, SpecDetails } from '@kong-ui-public/spec-renderer'
import { idFromPathMethod } from '@/helpers/generatedOperationId'
import '@kong-ui-public/spec-renderer/dist/style.css'
import { ProductVersionSpecDocument } from '@kong/sdk-portal-js'
import { FeatureFlags } from '@/constants/feature-flags'
import useLDFeatureFlag from '@/hooks/useLDFeatureFlag'
export default defineComponent({
name: 'Spec',
Expand All @@ -101,6 +150,7 @@ export default defineComponent({
const viewSpecModalIsVisible = ref(false)
const viewSpecRegistrationModalIsVisible = ref(false)
const isAllowedToRegister = ref(false)
const appRegV2Enabled = useLDFeatureFlag(FeatureFlags.AppRegV2, false)
const specContents = ref('')
const specName = ref('')
const specDetails = ref(null)
Expand All @@ -120,6 +170,12 @@ export default defineComponent({
const helpText = useI18nStore().state.helpText
const authMethodLabelObj = {
bearer: helpText.authStrategyInfo.bearer,
session: helpText.authStrategyInfo.session,
client_credentials: helpText.authStrategyInfo.clientCredentials
}
const productStore = useProductStore()
const { sidebarActiveOperation, sidebarOperations } = storeToRefs(productStore)
Expand Down Expand Up @@ -455,6 +511,8 @@ export default defineComponent({
}
return {
appRegV2Enabled,
authMethodLabelObj,
helpText,
viewSpecModalIsVisible,
viewSpecRegistrationModalIsVisible,
Expand Down Expand Up @@ -527,3 +585,36 @@ export default defineComponent({
margin-left: 0;
}
</style>
<style lang="scss" scoped>
.auth-strategy-card {
--KCardBorder: 1px solid var(--section_colors-stroke);
--KCardBorderRadius: 4px;
--KCardPaddingX: 12px;
--KCardPaddingY: 12px;
margin-bottom: 4px;
.title, .auth-methods-label {
margin-bottom: 4px;
}
.info-container {
align-items: center;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
row-gap: 8px;
}
.badge-container {
:deep(.k-badge) {
&:not(:last-child) {
margin-right: 4px;
}
background: var(--button_colors-primary-fill, var(--blue-500, #1155cb));
border: 1px solid transparent;
color: var(--button_colors-primary-text, #fff);
}
}
}
</style>

0 comments on commit 72159dc

Please sign in to comment.