Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: [M3-6777] - Rename Cypress functions and variables related to secrets #9350

Merged
merged 4 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions packages/manager/cypress/e2e/core/account/add-oauth-app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
mockGetOAuthApps,
} from 'support/intercepts/profile';
import { ui } from 'support/ui';
import { randomLabel, randomSecret } from 'support/util/random';
import { randomLabel, randomHex } from 'support/util/random';
import { OAuthClient } from '@linode/api-v4/types';

/**
Expand Down Expand Up @@ -128,14 +128,20 @@ describe('Add OAuth Apps', () => {
* - Confirms that the oauth app is listed correctly on OAuth Apps landing page.
*/
it('Adds an OAuth App', () => {
const oauthApps = oauthClientFactory.buildList(2);
const oauthApps = [
oauthClientFactory.build({
label: randomLabel(),
secret: randomHex(64),
Copy link
Contributor

@abailly-akamai abailly-akamai Jun 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also rename instances of the "secret" key? Pretty sure the scanning picks that up even more than the value considering what it actually complains the most about is insecure randomness for a key?
https://github.com/linode/manager/security/code-scanning

Either that or providing a custom yaml to provide an advanced setup in which you could whitelist some terms (I think): https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning-for-a-repository#creating-an-advanced-setup

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and I tried to change what I could, but in that case (and others like it) I'm constrained since I'm using types from the API JS client.

I think the advanced config may be the best solution if these alerts are a big concern (assuming whitelisting terms is one of the capabilities that grants us), but I might be a little hesitant to do that if it means that similar keywords are ignored in the src directory where the alerts might actually be legitimate and useful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Let's merge this as a first step and see if things improve. And if not we can maybe go with an advanced config.

if these alerts are a big concern

They're not for us (we know they're unwarranted), but as we're open source and a security company I am sure they're will be audits and we'll need to justify them at some point, so trying to be proactive 👍

}),
oauthClientFactory.build({
label: randomLabel(),
secret: randomHex(64),
public: true,
}),
];

const privateOauthApp = oauthApps[0];
privateOauthApp.label = randomLabel(5);
privateOauthApp.secret = randomSecret(64);
const publicOauthApp = oauthApps[1];
publicOauthApp.label = randomLabel(5);
publicOauthApp.public = true;
publicOauthApp.secret = randomSecret(64);

interceptGetProfile().as('getProfile');
cy.visitWithLogin('/profile/clients');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ describe('Personal access tokens', () => {
* - Confirms that user can open and close "View Scopes" drawer
*/
it('can create personal access tokens', () => {
const tokenLabel = randomLabel();
const tokenSecret = randomString(64);
const token = appTokenFactory.build({
label: tokenLabel,
token: tokenSecret,
label: randomLabel(),
token: randomString(64),
});

mockGetPersonalAccessTokens([]).as('getTokens');
Expand Down Expand Up @@ -80,7 +78,7 @@ describe('Personal access tokens', () => {
.should('be.visible')
.should('be.enabled')
.click()
.type(tokenLabel);
.type(token.label);

ui.buttonGroup
.findButtonByTitle('Create Token')
Expand Down Expand Up @@ -108,7 +106,7 @@ describe('Personal access tokens', () => {
// Confirm that PAT is shown.
cy.get('[data-testid="textfield-input"]')
.should('be.visible')
.should('have.attr', 'value', tokenSecret);
.should('have.attr', 'value', token.token);

ui.button
.findByTitle('I Have Saved My Personal Access Token')
Expand All @@ -119,7 +117,7 @@ describe('Personal access tokens', () => {

// Confirm that new PAT is shown in list and "View Scopes" drawer works.
cy.wait('@getTokens');
cy.findByText(tokenLabel)
cy.findByText(token.label)
.should('be.visible')
.closest('tr')
.within(() => {
Expand All @@ -131,7 +129,7 @@ describe('Personal access tokens', () => {
});

ui.drawer
.findByTitle(tokenLabel)
.findByTitle(token.label)
.should('be.visible')
.within(() => {
ui.drawerCloseButton.find().click();
Expand All @@ -144,17 +142,14 @@ describe('Personal access tokens', () => {
* - Confirms that token is removed from list after revoking it
*/
it('can rename and revoke personal access tokens', () => {
const tokenOldLabel = randomLabel();
const tokenNewLabel = randomLabel();

const oldToken: Token = appTokenFactory.build({
label: tokenOldLabel,
label: randomLabel(),
token: randomString(64),
});

const newToken: Token = {
...oldToken,
label: tokenNewLabel,
label: randomLabel(),
};

mockGetPersonalAccessTokens([oldToken]).as('getTokens');
Expand All @@ -166,7 +161,7 @@ describe('Personal access tokens', () => {
cy.wait(['@getTokens', '@getAppTokens']);

// Find token in list, click "Rename", and fill out and submit form.
cy.findByText(tokenOldLabel)
cy.findByText(oldToken.label)
.should('be.visible')
.closest('tr')
.within(() => {
Expand All @@ -185,7 +180,7 @@ describe('Personal access tokens', () => {
.should('be.visible')
.click()
.clear()
.type(tokenNewLabel);
.type(newToken.label);

ui.buttonGroup
.findButtonByTitle('Save')
Expand All @@ -196,7 +191,7 @@ describe('Personal access tokens', () => {

// Confirm that token has been renamed, initiate revocation.
cy.wait('@updateToken');
cy.findByText(tokenNewLabel)
cy.findByText(newToken.label)
.should('be.visible')
.closest('tr')
.within(() => {
Expand All @@ -209,7 +204,7 @@ describe('Personal access tokens', () => {

mockGetPersonalAccessTokens([]).as('getTokens');
ui.dialog
.findByTitle(`Revoke ${tokenNewLabel}?`)
.findByTitle(`Revoke ${newToken.label}?`)
.should('be.visible')
.within(() => {
ui.buttonGroup
Expand All @@ -221,11 +216,11 @@ describe('Personal access tokens', () => {

// Confirm that token is removed from list after revoking.
cy.wait(['@revokeToken', '@getTokens']);
ui.toast.assertMessage(`Successfully revoked ${tokenNewLabel}`);
ui.toast.assertMessage(`Successfully revoked ${newToken.label}`);
cy.findByLabelText('List of Personal Access Tokens')
.should('be.visible')
.within(() => {
cy.findByText(tokenNewLabel).should('not.exist');
cy.findByText(newToken.label).should('not.exist');
cy.findByText('No items to display.').should('be.visible');
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fbtVisible, fbtClick, fbltClick } from 'support/helpers';
import { fbtVisible, fbtClick } from 'support/helpers';
import { oauthClientFactory } from '@src/factories';
import 'cypress-file-upload';
import {
Expand All @@ -7,7 +7,7 @@ import {
mockResetOAuthApps,
} from 'support/intercepts/profile';
import { ui } from 'support/ui';
import { randomLabel, randomSecret } from 'support/util/random';
import { randomLabel, randomHex } from 'support/util/random';

describe('Reset OAuth Apps', () => {
/*
Expand All @@ -16,15 +16,13 @@ describe('Reset OAuth Apps', () => {
* - Confirms that the oauth app is reset correctly on OAuth Apps landing page.
*/
it('Resets an OAuth App', () => {
const oauthApps = oauthClientFactory.buildList(2);
const privateOauthApp = oauthApps[0];
privateOauthApp.label = randomLabel(5);
const publicOauApp = oauthApps[1];
publicOauApp.label = randomLabel(5);
publicOauApp.public = true;
const privateOauthApp = oauthClientFactory.build({
label: randomLabel(5),
secret: randomHex(64),
});

interceptGetProfile().as('getProfile');
mockGetOAuthApps(oauthApps).as('getOAuthApps');
mockGetOAuthApps([privateOauthApp]).as('getOAuthApps');
cy.visitWithLogin('/profile/clients');
cy.wait('@getProfile');
cy.wait('@getOAuthApps');
Expand Down Expand Up @@ -57,7 +55,7 @@ describe('Reset OAuth Apps', () => {
fbtVisible('Reset');
fbtClick('Reset');
});
privateOauthApp['secret'] = randomSecret(64);

mockResetOAuthApps(privateOauthApp.id, privateOauthApp).as('resetOAuthApp');
ui.dialog
.findByTitle(`Reset secret for ${privateOauthApp.label}?`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,12 @@ import { authenticate } from 'support/api/authentication';

authenticate();
describe('Third party access tokens', () => {
let tokenLabel: string;
let tokenSecret: string;
let token: Token;

beforeEach(() => {
tokenLabel = randomLabel();
tokenSecret = randomString(64);
token = appTokenFactory.build({
label: tokenLabel,
token: tokenSecret,
label: randomLabel(),
token: randomString(64),
});

mockGetPersonalAccessTokens([]).as('getTokens');
Expand All @@ -38,10 +34,10 @@ describe('Third party access tokens', () => {
* - Confirms that third party apps are listed with expected information.
*/
it('Third party access tokens are listed with expected information', () => {
cy.findByText(tokenLabel)
cy.findByText(token.label)
.closest('tr')
.within(() => {
cy.findByText(tokenLabel).should('be.visible');
cy.findByText(token.label).should('be.visible');
cy.defer(getProfile()).then((profile: Profile) => {
const dateFormatOptions = { timezone: profile.timezone };
cy.findByText(formatDate(token.created, dateFormatOptions)).should(
Expand All @@ -61,13 +57,13 @@ describe('Third party access tokens', () => {
Linodes: 2,
});

cy.findByText(tokenLabel)
cy.findByText(token.label)
.closest('tr')
.within(() => {
ui.button.findByTitle('View Scopes').should('be.visible').click();
});
ui.drawer
.findByTitle(tokenLabel)
.findByTitle(token.label)
.should('be.visible')
.within(() => {
Object.keys(access).forEach((key) => {
Expand All @@ -88,13 +84,13 @@ describe('Third party access tokens', () => {
*/
it('Revokes a third party access token', () => {
// Cancelling will keep the list unchanged.
cy.findByText(tokenLabel)
cy.findByText(token.label)
.closest('tr')
.within(() => {
ui.button.findByTitle('Revoke').should('be.visible').click();
});
ui.dialog
.findByTitle(`Revoke ${tokenLabel}?`)
.findByTitle(`Revoke ${token.label}?`)
.should('be.visible')
.within(() => {
ui.buttonGroup
Expand All @@ -106,13 +102,13 @@ describe('Third party access tokens', () => {

// Confirms revoke will remove the third party app.
mockRevokeAppToken(token.id).as('deleteAppToken');
cy.findByText(tokenLabel)
cy.findByText(token.label)
.closest('tr')
.within(() => {
ui.button.findByTitle('Revoke').should('be.visible').click();
});
ui.dialog
.findByTitle(`Revoke ${tokenLabel}?`)
.findByTitle(`Revoke ${token.label}?`)
.should('be.visible')
.within(() => {
ui.buttonGroup
Expand All @@ -127,6 +123,6 @@ describe('Third party access tokens', () => {
mockGetAppTokens([]).as('getAppTokens');
cy.visitWithLogin('/profile/tokens');
cy.wait(['@getTokens', '@getAppTokens']);
cy.findByText(tokenLabel).should('not.exist');
cy.findByText(token.label).should('not.exist');
});
});
32 changes: 10 additions & 22 deletions packages/manager/cypress/e2e/core/account/two-factor-auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import {
mockGetSecurityQuestions,
} from 'support/intercepts/profile';
import { ui } from 'support/ui';
import { randomNumber, randomLabel, randomString } from 'support/util/random';
import {
randomNumber,
randomLabel,
randomString,
randomHex,
} from 'support/util/random';

/**
* Returns a Cypress chainable for the "Two-Factor Authentication".
Expand All @@ -26,23 +31,6 @@ const getTwoFactorSection = (): Cypress.Chainable => {
return cy.contains('h3', 'Two-Factor Authentication (2FA)').parent();
};

/**
* Generates a random 2FA secret key for mocking.
*
* @returns 2FA secret key.
*/
const randomSecret = (): string => {
const randomSecretOptions = {
lowercase: false,
uppercase: true,
numbers: true,
symbols: false,
spaces: false,
};

return randomString(16, randomSecretOptions);
};

/**
* Generates a random 2FA scratch code for mocking.
*
Expand Down Expand Up @@ -155,7 +143,7 @@ describe('Two-factor authentication', () => {
it('can enable two factor auth', () => {
const invalidToken = randomToken();
const validToken = randomToken();
const mockedSecret = randomSecret();
const mockedKey = randomHex(16);
const mockedScratchCode = randomScratchCode();

// Mock profile data to ensure that 2FA is disabled.
Expand All @@ -168,7 +156,7 @@ describe('Two-factor authentication', () => {
cy.wait('@getSecurityQuestions');

getTwoFactorSection().within(() => {
mockEnableTwoFactorAuth(mockedSecret).as('enableTwoFactorAuth');
mockEnableTwoFactorAuth(mockedKey).as('enableTwoFactorAuth');

ui.toggle
.find()
Expand All @@ -181,7 +169,7 @@ describe('Two-factor authentication', () => {

cy.findByLabelText('Secret Key')
.should('be.visible')
.should('have.value', mockedSecret);
.should('have.value', mockedKey);

// Type an invalid token first, confirm that error message appears as expected.
cy.findByLabelText('Token').should('be.visible').type(invalidToken);
Expand Down Expand Up @@ -312,7 +300,7 @@ describe('Two-factor authentication', () => {
cy.wait('@getSecurityQuestions');

getTwoFactorSection().within(() => {
mockEnableTwoFactorAuth(randomSecret()).as('resetTwoFactorAuth');
mockEnableTwoFactorAuth(randomHex(16)).as('resetTwoFactorAuth');

// Confirm that reset link is present, click on it.
cy.findByText('Reset two-factor authentication')
Expand Down
Loading