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

feat: add authentication setting #487

Merged
merged 3 commits into from
Jul 9, 2024
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
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Snyk Security Changelog

### [2.13.1]
## [2.13.2]
- allow to select oauth2 authentication

## [2.13.1]
- Refactor the Suggestion Panel for OSS so it's more secure and will be supported in other IDEs
- allow to select OAuth2 as authentication

## [2.13.0]
- Fix `.suggestion` class to ensure it is scrollable and not overlapped by the `.suggestion-actions` fixed element. This change prevents the suggestion content from being hidden.
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@
"scope": "window",
"pattern": "^(|(https?://)api.*.(snyk|snykgov).io)$"
},
"snyk.advanced.useTokenAuthentication": {
"type": "boolean",
"markdownDescription": "Use token authentication. It is recommended to keep this turned off, as the default OAuth2 authentication is more secure.",
"scope": "window",
"default": true
},
"snyk.advanced.organization": {
"type": "string",
"markdownDescription": "Specifies an organization slug name to run tests for that organization. \n\nNote: The slug name can be extracted from the URL of your organization in the Snyk UI: `https://app.snyk.io/org/[orgslugname]`. If not specified, preferred organization as defined in your [web account settings](https://app.snyk.io/account) is used to run tests.",
Expand Down
23 changes: 22 additions & 1 deletion src/snyk/common/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
YES_BACKGROUND_OSS_NOTIFICATION_SETTING,
YES_CRASH_REPORT_SETTING,
YES_WELCOME_NOTIFICATION_SETTING,
ADVANCED_USE_TOKEN_AUTHENTICATION,
DELTA_FINDINGS,
} from '../constants/settings';
import SecretStorageAdapter from '../vscode/secretStorage';
Expand Down Expand Up @@ -62,6 +63,10 @@ export interface IConfiguration {

authHost: string;

useTokenAuthentication(): boolean;

setUseTokenAuthentication(useTokenAuth: boolean): void;

getFeatureFlag(flagName: string): boolean;

setFeatureFlag(flagName: string, value: boolean): void;
Expand Down Expand Up @@ -125,7 +130,6 @@ export interface IConfiguration {

export class Configuration implements IConfiguration {
// These attributes are used in tests
private readonly defaultSnykCodeBaseURL = 'https://deeproxy.snyk.io';
private readonly defaultAuthHost = 'https://app.snyk.io';
private readonly defaultApiEndpoint = 'https://api.snyk.io';

Expand All @@ -138,6 +142,23 @@ export class Configuration implements IConfiguration {
return !strictSSL;
}

useTokenAuthentication(): boolean {
const useTokenAuth = this.workspace.getConfiguration<boolean>(
CONFIGURATION_IDENTIFIER,
this.getConfigName(ADVANCED_USE_TOKEN_AUTHENTICATION),
);
return useTokenAuth ?? false;
}

async setUseTokenAuthentication(useTokenAuth: boolean): Promise<void> {
await this.workspace.updateConfiguration(
CONFIGURATION_IDENTIFIER,
this.getConfigName(ADVANCED_USE_TOKEN_AUTHENTICATION),
useTokenAuth,
true,
);
}

static async getVersion(): Promise<string> {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { version } = await this.getPackageJsonConfig();
Expand Down
1 change: 1 addition & 0 deletions src/snyk/common/constants/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const ADVANCED_ORGANIZATION = `${CONFIGURATION_IDENTIFIER}.advanced.organ
export const ADVANCED_AUTOMATIC_DEPENDENCY_MANAGEMENT = `${CONFIGURATION_IDENTIFIER}.advanced.automaticDependencyManagement`;
export const ADVANCED_CLI_PATH = `${CONFIGURATION_IDENTIFIER}.advanced.cliPath`;
export const ADVANCED_CUSTOM_LS_PATH = `${CONFIGURATION_IDENTIFIER}.advanced.languageServerPath`;
export const ADVANCED_USE_TOKEN_AUTHENTICATION = `${CONFIGURATION_IDENTIFIER}.advanced.useTokenAuthentication`;

export const ISSUE_VIEW_OPTIONS_SETTING = `${CONFIGURATION_IDENTIFIER}.issueViewOptions`;
export const SEVERITY_FILTER_SETTING = `${CONFIGURATION_IDENTIFIER}.severity`;
Expand Down
7 changes: 7 additions & 0 deletions src/snyk/common/languageServer/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type ServerSettings = {
// Authentication and parameters
token?: string;
automaticAuthentication?: string;
authenticationMethod?: string;
additionalParams?: string;
manageBinariesAutomatically?: string;

Expand Down Expand Up @@ -57,6 +58,11 @@ export class LanguageServerSettings {
? true
: featuresConfiguration.codeQualityEnabled;

let authenticationMethod = 'oauth';
if (configuration.useTokenAuthentication()) {
authenticationMethod = 'token';
}

return {
activateSnykCodeSecurity: `${codeSecurityEnabled}`,
activateSnykCodeQuality: `${codeQualityEnabled}`,
Expand All @@ -80,6 +86,7 @@ export class LanguageServerSettings {
integrationVersion: await Configuration.getVersion(),
deviceId: user.anonymousId,
requiredProtocolVersion: `${PROTOCOL_VERSION}`,
authenticationMethod: authenticationMethod,
};
}
}
5 changes: 5 additions & 0 deletions src/test/unit/common/languageServer/languageServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ suite('Language Server', () => {

setup(() => {
configurationMock = {
useTokenAuthentication(): boolean {
return false;
},

getInsecure(): boolean {
return true;
},
Expand Down Expand Up @@ -223,6 +227,7 @@ suite('Language Server', () => {
insecure: 'true',
requiredProtocolVersion: '12',
scanningMode: 'auto',
authenticationMethod: 'oauth',
};

deepStrictEqual(await languageServer.getInitializationOptions(), expectedInitializationOptions);
Expand Down
3 changes: 3 additions & 0 deletions src/test/unit/common/languageServer/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ suite('Language Server: Middleware', () => {
setup(() => {
user = { anonymousId: 'anonymous-id' } as User;
configuration = {
useTokenAuthentication(): boolean {
return false;
},
shouldReportErrors: false,
snykApiEndpoint: 'https://dev.snyk.io/api',
getAdditionalCliParameters: () => '',
Expand Down
3 changes: 3 additions & 0 deletions src/test/unit/common/languageServer/settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ suite('LanguageServerSettings', () => {
organization: 'my-org',
// eslint-disable-next-line @typescript-eslint/require-await
getToken: async () => 'snyk-token',
useTokenAuthentication(): boolean {
return false;
},
getFeaturesConfiguration: () => ({}), // iacEnabled, codeSecurityEnabled, codeQualityEnabled are undefined
getCliPath: () => '/path/to/cli',
getAdditionalCliParameters: () => '--all-projects -d',
Expand Down
Loading