azure-pipelines-tasks-webdeployment-common 4.257.0 → 4.260.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Tests/L0MSDeployUtility.js +40 -0
- package/Tests/L0MSDeployUtility.ts +41 -0
- package/msdeployutility.js +4 -1
- package/package.json +3 -1
|
@@ -2,8 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runGetWebDeployErrorCodeTests = exports.runGetMSDeployCmdArgsTests = void 0;
|
|
4
4
|
const assert = require("assert");
|
|
5
|
+
const sinon = require("sinon");
|
|
6
|
+
const tl = require("azure-pipelines-task-lib/task"); // Adjust the import path as needed
|
|
5
7
|
const msdeployutility_1 = require("../msdeployutility");
|
|
6
8
|
function runGetMSDeployCmdArgsTests() {
|
|
9
|
+
let getPipelineFeatureStub;
|
|
10
|
+
before(() => {
|
|
11
|
+
getPipelineFeatureStub = sinon.stub(tl, "getPipelineFeature");
|
|
12
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true); // or whatever value you want to mock
|
|
13
|
+
});
|
|
14
|
+
after(() => {
|
|
15
|
+
getPipelineFeatureStub.restore();
|
|
16
|
+
});
|
|
7
17
|
it('Should produce default valid args', () => {
|
|
8
18
|
const profile = createDefaultPublishProfile();
|
|
9
19
|
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, true, false, true, null, null, null, true, false, false);
|
|
@@ -55,6 +65,36 @@ function runGetMSDeployCmdArgsTests() {
|
|
|
55
65
|
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '-retryAttempts:11 -retryInterval:5000', false, false, true);
|
|
56
66
|
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000']);
|
|
57
67
|
});
|
|
68
|
+
it('Should CSstring encode correctly', () => {
|
|
69
|
+
const profile = createDefaultPublishProfile();
|
|
70
|
+
tl.getPipelineFeature("CommaSeperatedConnectionString");
|
|
71
|
+
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\'', false, false, true);
|
|
72
|
+
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000', '-setParam:name="\"ConnectionString\"",value="\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\""']);
|
|
73
|
+
const CSstring = '-setParam:name="\\"ConnectionString\\"",value="\\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\\""';
|
|
74
|
+
assert.ok(args.includes(CSstring));
|
|
75
|
+
});
|
|
76
|
+
it('Should CSstring encode in-correctly', () => {
|
|
77
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(false);
|
|
78
|
+
const profile = createDefaultPublishProfile();
|
|
79
|
+
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\'', false, false, true);
|
|
80
|
+
const CSstring = '-setParam:name="ConnectionString",value="Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;"';
|
|
81
|
+
assert.ok(!args.includes(CSstring));
|
|
82
|
+
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000', '-setParam:name="\"ConnectionString\"",value="\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\""']);
|
|
83
|
+
});
|
|
84
|
+
it('Should encrypt skip directives correctly', () => {
|
|
85
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true);
|
|
86
|
+
const profile = createDefaultPublishProfile();
|
|
87
|
+
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '-skip:objectName=filePath,absolutePath="\\web\.config"', false, false, true);
|
|
88
|
+
const skipsubstring = '-skip:objectName=filePath,absolutePath="\\"\\web.config\\""';
|
|
89
|
+
checkParametersIfPresent(args, ['-skip:objectName=filePath,absolutePath="\\"\\web.config\\""']);
|
|
90
|
+
assert.ok(args.includes(skipsubstring));
|
|
91
|
+
});
|
|
92
|
+
it('Should encrypt skip directives in-correctly', () => {
|
|
93
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true);
|
|
94
|
+
const profile = createDefaultPublishProfile();
|
|
95
|
+
const args = msdeployutility_1.getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\' -skip:objectName=filePath data source,absolutePath="\\web\.config"', false, false, true);
|
|
96
|
+
assert.ok(!args.includes('-skip:objectName=filePath data source,absolutePath="\\web.config"'));
|
|
97
|
+
});
|
|
58
98
|
function checkParametersIfPresent(argumentString, argumentCheckArray) {
|
|
59
99
|
for (const argument of argumentCheckArray) {
|
|
60
100
|
if (argumentString.indexOf(argument) === -1) {
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import assert = require("assert");
|
|
2
|
+
import sinon = require("sinon");
|
|
3
|
+
import * as tl from "azure-pipelines-task-lib/task"; // Adjust the import path as needed
|
|
2
4
|
import { getMSDeployCmdArgs, getWebDeployErrorCode } from "../msdeployutility";
|
|
3
5
|
|
|
4
6
|
export function runGetMSDeployCmdArgsTests() {
|
|
7
|
+
let getPipelineFeatureStub: sinon.SinonStub;
|
|
5
8
|
|
|
9
|
+
before(() => {
|
|
10
|
+
getPipelineFeatureStub = sinon.stub(tl, "getPipelineFeature");
|
|
11
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true); // or whatever value you want to mock
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
after(() => {
|
|
15
|
+
getPipelineFeatureStub.restore();
|
|
16
|
+
});
|
|
6
17
|
it('Should produce default valid args', () => {
|
|
7
18
|
const profile = createDefaultPublishProfile();
|
|
8
19
|
const args = getMSDeployCmdArgs('package.zip', 'webapp_name', profile, true, false, true, null, null, null, true, false, false);
|
|
@@ -73,6 +84,36 @@ export function runGetMSDeployCmdArgsTests() {
|
|
|
73
84
|
|
|
74
85
|
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000']);
|
|
75
86
|
});
|
|
87
|
+
it('Should CSstring encode correctly', () => {
|
|
88
|
+
const profile = createDefaultPublishProfile();
|
|
89
|
+
tl.getPipelineFeature("CommaSeperatedConnectionString");
|
|
90
|
+
const args = getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\'', false, false, true);
|
|
91
|
+
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000', '-setParam:name="\"ConnectionString\"",value="\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\""']);
|
|
92
|
+
const CSstring = '-setParam:name="\\"ConnectionString\\"",value="\\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\\""';
|
|
93
|
+
assert.ok(args.includes(CSstring));
|
|
94
|
+
});
|
|
95
|
+
it('Should CSstring encode in-correctly', () => {
|
|
96
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(false);
|
|
97
|
+
const profile = createDefaultPublishProfile();
|
|
98
|
+
const args = getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\'', false, false, true);
|
|
99
|
+
const CSstring = '-setParam:name="ConnectionString",value="Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;"';
|
|
100
|
+
assert.ok(!args.includes(CSstring));
|
|
101
|
+
checkParametersIfPresent(args, ['-retryAttempts:11', '-retryInterval:5000', '-setParam:name="\"ConnectionString\"",value="\"Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\""']);
|
|
102
|
+
});
|
|
103
|
+
it('Should encrypt skip directives correctly', () => {
|
|
104
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true);
|
|
105
|
+
const profile = createDefaultPublishProfile();
|
|
106
|
+
const args = getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '-skip:objectName=filePath,absolutePath="\\web\.config"', false, false, true);
|
|
107
|
+
const skipsubstring = '-skip:objectName=filePath,absolutePath="\\"\\web.config\\""';
|
|
108
|
+
checkParametersIfPresent(args, ['-skip:objectName=filePath,absolutePath="\\"\\web.config\\""']);
|
|
109
|
+
assert.ok(args.includes(skipsubstring));
|
|
110
|
+
});
|
|
111
|
+
it('Should encrypt skip directives in-correctly', () => {
|
|
112
|
+
getPipelineFeatureStub.withArgs("CommaSeperatedConnectionString").returns(true);
|
|
113
|
+
const profile = createDefaultPublishProfile();
|
|
114
|
+
const args = getMSDeployCmdArgs('package.zip', 'webapp_name', profile, false, true, true, null, null, '"-retryAttempts:11 -retryInterval:5000 -setParam:name=\'ConnectionString\',value=\'Encrypt=True;TrustServerCertificate=False;Data Source=some-sql-server.database.windows.net,1433;Initial Catalog=some-database;User Id=someuser;Password=somepassword;\' -skip:objectName=filePath data source,absolutePath="\\web\.config"', false, false, true);
|
|
115
|
+
assert.ok(!args.includes('-skip:objectName=filePath data source,absolutePath="\\web.config"'));
|
|
116
|
+
});
|
|
76
117
|
|
|
77
118
|
function checkParametersIfPresent(argumentString: string, argumentCheckArray: string[]): void {
|
|
78
119
|
for (const argument of argumentCheckArray) {
|
package/msdeployutility.js
CHANGED
|
@@ -111,9 +111,12 @@ function escapeQuotes(additionalArguments) {
|
|
|
111
111
|
let equalsSignEncountered = false;
|
|
112
112
|
for (let i = 0; i < arg.length; i++) {
|
|
113
113
|
const char = arg.charAt(i);
|
|
114
|
+
var connectionStringCheck = new RegExp("\\bdata\\s*source\\s*=", "i");
|
|
114
115
|
let quotedStringCheck = (char == separator && equalsSignEncountered && ((formattedArg.startsWith("'") && formattedArg.endsWith("'")) || (formattedArg.startsWith('"') && formattedArg.endsWith('"'))));
|
|
115
|
-
let commaSeperatorCheck = commaSeperatedCSEnabled ? quotedStringCheck : (char == separator && equalsSignEncountered);
|
|
116
|
+
let commaSeperatorCheck = commaSeperatedCSEnabled && connectionStringCheck.test(formattedArg) ? quotedStringCheck : (char == separator && equalsSignEncountered);
|
|
116
117
|
if (commaSeperatorCheck) {
|
|
118
|
+
let commaSeperatedCSEnabledTelemetry = ' {"CommaSeperatedConnectionStringFeatureFlagEnabled":"' + commaSeperatedCSEnabled + '"connectionStringCheck":"' + connectionStringCheck.test(formattedArg) + '"}';
|
|
119
|
+
tl.debug("formattedArg : " + formattedArg + commaSeperatedCSEnabledTelemetry);
|
|
117
120
|
equalsSignEncountered = false;
|
|
118
121
|
arg = arg.replace(formattedArg, escapeArg(formattedArg));
|
|
119
122
|
formattedArg = '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azure-pipelines-tasks-webdeployment-common",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.260.0",
|
|
4
4
|
"description": "Common Lib for MSDeploy Utility",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,8 +34,10 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/semver": "^7.5.4",
|
|
37
|
+
"@types/sinon": "^4.3.3",
|
|
37
38
|
"@types/winreg": "^1.2.34",
|
|
38
39
|
"nyc": "^15.1.0",
|
|
40
|
+
"sinon": "^19.0.2",
|
|
39
41
|
"typescript": "4.0.2"
|
|
40
42
|
}
|
|
41
43
|
}
|