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

Remove mssql dependency, use tediousjs/connection-string for parsing #224

Merged
merged 8 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion __tests__/AzureSqlAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('AzureSqlAction tests', () => {
expect(execSpy).toHaveBeenCalledWith(`"${sqlcmdExe}" ${expectedSqlCmdCall}`);

// Except for AAD default, password/client secret should be set as SqlCmdPassword environment variable
if (inputs.connectionConfig.Config['authentication']?.type !== 'azure-active-directory-default') {
if (inputs.connectionConfig.ParsedConnectionString.authentication !== 'activedirectorydefault') {
expect(exportVariableSpy).toHaveBeenCalledTimes(1);
expect(exportVariableSpy).toHaveBeenCalledWith(Constants.sqlcmdPasswordEnvVarName, "placeholder");
}
Expand Down
69 changes: 30 additions & 39 deletions __tests__/SqlConnectionConfig.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as core from '@actions/core';
import { ConnectionPool } from 'mssql';
import SqlConnectionConfig from '../src/SqlConnectionConfig';

jest.mock('@actions/core');
Expand All @@ -25,10 +24,10 @@ describe('SqlConnectionConfig tests', () => {
const connectionString = new SqlConnectionConfig(connectionStringInput);

expect(connectionString.ConnectionString).toMatch(connectionStringInput);
expect(connectionString.Config.password).toMatch(passwordOutput);
expect(connectionString.Config.user).toMatch(`user`);
expect(connectionString.Config.database).toMatch('testdb');
if(!!connectionString.Config.server) expect(connectionString.Config.server).toMatch('test1.database.windows.net');
expect(connectionString.ParsedConnectionString.password).toMatch(passwordOutput);
expect(connectionString.ParsedConnectionString.userId).toMatch(`user`);
expect(connectionString.ParsedConnectionString.database).toMatch('testdb');
if(!!connectionString.ParsedConnectionString.server) expect(connectionString.ParsedConnectionString.server).toMatch('test1.database.windows.net');
});
})

Expand All @@ -42,7 +41,6 @@ describe('SqlConnectionConfig tests', () => {
[`Server=test1.database.windows.net;Password=placeholder;Initial catalog=testdb`, `Invalid connection string. Please ensure 'User' or 'User ID' is provided in the connection string.`, 'missing user id'],
[`Server=test1.database.windows.net;User Id=user;Initial catalog=testdb`, `Invalid connection string. Please ensure 'Password' is provided in the connection string.`, 'missing password'],
[`Server=test1.database.windows.net;User Id=user;Password=password;`, `Invalid connection string. Please ensure 'Database' or 'Initial Catalog' is provided in the connection string.`, 'missing initial catalog'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Fake Auth Type;Password=password;`, `Authentication type 'Fake Auth Type' is not supported.`, 'Unsupported authentication type'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='Active Directory Password';Password=password;`, `Invalid connection string. Please ensure 'User' or 'User ID' is provided in the connection string.`, 'AAD password auth missing user'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='Active Directory Password';User Id=user;`, `Invalid connection string. Please ensure 'Password' is provided in the connection string.`, 'AAD password auth missing password'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='SQL Password';Password=password;`, `Invalid connection string. Please ensure 'User' or 'User ID' is provided in the connection string.`, 'SQL password auth missing user'],
Expand All @@ -56,12 +54,6 @@ describe('SqlConnectionConfig tests', () => {
})
})

it('should call into mssql module to parse connection string', () => {
const parseConnectionStringSpy = jest.spyOn(ConnectionPool, 'parseConnectionString');
new SqlConnectionConfig('User Id=user;Password=placeholder;Server=test1.database.windows.net;Initial Catalog=testDB');
expect(parseConnectionStringSpy).toHaveBeenCalled();
});

it('should mask connection string password', () => {
const setSecretSpy = jest.spyOn(core, 'setSecret');
new SqlConnectionConfig('User Id=user;Password=placeholder;Server=test1.database.windows.net;Initial Catalog=testDB');
Expand All @@ -71,39 +63,38 @@ describe('SqlConnectionConfig tests', () => {
describe('parse authentication in connection strings', () => {
// For ease of testing, all user/client IDs will be 'user' and password/secrets will be 'placeholder'
const connectionStrings = [
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Password";User Id=user;Password="placeholder";`, 'azure-active-directory-password', 'Validates AAD password with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Password;User Id=user;Password="placeholder";`, 'azure-active-directory-password', 'Validates AAD password with no quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryPassword';User Id=user;Password="placeholder";`, 'azure-active-directory-password', 'Validates AAD password with one word'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Service Principal";User Id=user;Password="placeholder";`, 'azure-active-directory-service-principal-secret', 'Validates AAD service principal with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Service Principal;User Id=user;Password="placeholder";`, 'azure-active-directory-service-principal-secret', 'Validates AAD service principal with single quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryServicePrincipal';User Id=user;Password="placeholder";`, 'azure-active-directory-service-principal-secret', 'Validates AAD service principal with one word'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Default"`, 'azure-active-directory-default', 'Validates default AAD with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Default`, 'azure-active-directory-default', 'Validates default AAD with single quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryDefault'`, 'azure-active-directory-default', 'Validates default AAD with one word'],
[`Server=test1.database.windows.net;Database=testdb;User Id=user;Password="placeholder";`, '', 'Validates no authentication set'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Sql Password";User Id=user;Password="placeholder";`, 'sqlpassword', 'Validates SQL password with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Sql Password;User Id=user;Password="placeholder";`, 'sqlpassword', 'Validates SQL password with no quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='SqlPassword';User Id=user;Password="placeholder";`, 'sqlpassword', 'Validates SQL password with one word'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Password";User Id=user;Password="placeholder";`, 'activedirectorypassword', 'Validates AAD password with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Password;User Id=user;Password="placeholder";`, 'activedirectorypassword', 'Validates AAD password with no quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryPassword';User Id=user;Password="placeholder";`, 'activedirectorypassword', 'Validates AAD password with one word'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Service Principal";User Id=user;Password="placeholder";`, 'activedirectoryserviceprincipal', 'Validates AAD service principal with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Service Principal;User Id=user;Password="placeholder";`, 'activedirectoryserviceprincipal', 'Validates AAD service principal with single quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryServicePrincipal';User Id=user;Password="placeholder";`, 'activedirectoryserviceprincipal', 'Validates AAD service principal with one word'],
[`Server=test1.database.windows.net;Database=testdb;Authentication="Active Directory Default"`, 'activedirectorydefault', 'Validates default AAD with double quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication=Active Directory Default`, 'activedirectorydefault', 'Validates default AAD with single quotes'],
[`Server=test1.database.windows.net;Database=testdb;Authentication='ActiveDirectoryDefault'`, 'activedirectorydefault', 'Validates default AAD with one word'],
];

it.each(connectionStrings)('should parse different authentication types successfully', (connectionStringInput, expectedAuthType) => {
const config = new SqlConnectionConfig(connectionStringInput);

expect(config.Config.server).toMatch('test1.database.windows.net');
expect(config.Config.database).toMatch('testdb');
expect(config.ParsedConnectionString.server).toMatch('test1.database.windows.net');
expect(config.ParsedConnectionString.database).toMatch('testdb');
expect(config.ConnectionString).toMatch(connectionStringInput);
expect(config.Config['authentication']).toBeDefined();
expect(config.Config['authentication']!.type).toMatch(expectedAuthType);
expect(config.ParsedConnectionString.authentication ?? '').toMatch(expectedAuthType);
switch (expectedAuthType) {
case 'azure-active-directory-password': {
expect(config.Config['authentication']!.options).toBeDefined();
expect(config.Config['authentication']!.options!.userName).toMatch('user');
expect(config.Config['authentication']!.options!.password).toMatch('placeholder');
break;
}
case 'azure-active-directory-service-principal-secret': {
expect(config.Config['authentication']!.options).toBeDefined();
expect(config.Config['authentication']!.options!.clientId).toMatch('user');
expect(config.Config['authentication']!.options!.clientSecret).toMatch('placeholder');
case '':
case 'sqlpassword':
case 'activedirectorypassword':
case 'activedirectoryserviceprincipal': {
expect(config.ParsedConnectionString.userId).toMatch('user');
expect(config.ParsedConnectionString.password).toMatch('placeholder');
break;
}
case 'azure-active-directory-default': {
case 'activedirectorydefault': {
// AAD default uses environment variables, nothing needs to be passed in
break;
}
Expand All @@ -124,9 +115,9 @@ describe('SqlConnectionConfig tests', () => {
it.each(connectionStrings)('should parse server name successfully', (connectionStringInput, expectedServerName, expectedPortNumber) => {
const config = new SqlConnectionConfig(connectionStringInput);

expect(config.Config.server).toMatch(expectedServerName);
expect(config.Config.port?.toString()).toMatch(expectedPortNumber);
expect(config.Config.database).toMatch('testdb');
expect(config.ParsedConnectionString.server).toMatch(expectedServerName);
expect(config.ParsedConnectionString.port?.toString() || '').toMatch(expectedPortNumber);
expect(config.ParsedConnectionString.database).toMatch('testdb');
expect(config.ConnectionString).toMatch(connectionStringInput);
});
});
Expand Down
3 changes: 1 addition & 2 deletions lib/main.js

Large diffs are not rendered by default.

52 changes: 0 additions & 52 deletions lib/main.js.LICENSE.txt

This file was deleted.

Loading
Loading