Skip to content

Commit

Permalink
Use AAD auth for scm access if available (#90)
Browse files Browse the repository at this point in the history
* Use AAD auth for scm access if available

* Update AzureAppServiceUtility.ts
  • Loading branch information
ahmelsayed authored Apr 24, 2023
1 parent 0ab5252 commit 2699858
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 16 deletions.
4 changes: 2 additions & 2 deletions packages/appservice-rest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "azure-actions-appservice-rest",
"version": "1.3.9",
"version": "1.3.10",
"description": "Azure resource manager and kudu node rest module",
"keywords": [
"appservice",
Expand Down Expand Up @@ -29,7 +29,7 @@
"@actions/core": "^1.1.10",
"@actions/io": "^1.0.1",
"@types/node": "^14.14.31",
"azure-actions-webclient": "^1.1.0",
"azure-actions-webclient": "^1.1.1",
"copy": "^0.3.2",
"fs": "0.0.1-security",
"util": "^0.12.1",
Expand Down
6 changes: 5 additions & 1 deletion packages/appservice-rest/src/Arm/azure-app-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ export class AzureAppService {
}
}

public getAccessToken(): Promise<string> {
return this._client.getAccessToken();
}

public async getApplicationSettings(force?: boolean): Promise<AzureAppServiceConfigurationDetails> {
if(force || !this._appServiceApplicationSetings) {
this._appServiceApplicationSetings = await this._getApplicationSettings();
Expand Down Expand Up @@ -604,4 +608,4 @@ export class AzureAppService {
setTimeout(resolve, sleepDurationInSeconds * 1000);
});
}
}
}
12 changes: 7 additions & 5 deletions packages/appservice-rest/src/Kudu/KuduServiceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ import core = require('@actions/core');

export class KuduServiceClient {
private _scmUri;
private _accesssToken: string;
private _accessToken: string;
private _accessTokenType: "Basic" | "Bearer";
private _cookie: string[];
private _webClient: WebClient;

constructor(scmUri: string, accessToken: string) {
this._accesssToken = accessToken;
constructor(scmUri: string, accessToken: string, accessTokenType: "Basic" | "Bearer") {
this._accessToken = accessToken;
this._accessTokenType = accessTokenType;
this._scmUri = scmUri;
this._webClient = new WebClient();
}

public async beginRequest(request: WebRequest, reqOptions?: WebRequestOptions, contentType?: string): Promise<WebResponse> {
request.headers = request.headers || {};
request.headers["Authorization"] = "Basic " + this._accesssToken;
request.headers["Authorization"] = `${this._accessTokenType} ${this._accessToken}`
request.headers['Content-Type'] = contentType || 'application/json; charset=utf-8';

if(!!this._cookie) {
Expand Down Expand Up @@ -71,4 +73,4 @@ export class KuduServiceClient {
public getScmUri(): string {
return this._scmUri;
}
}
}
12 changes: 8 additions & 4 deletions packages/appservice-rest/src/Kudu/azure-app-kudu-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ export const KUDU_DEPLOYMENT_CONSTANTS = {
export class Kudu {
private _client: KuduServiceClient;

constructor(scmUri: string, username: string, password: string) {
var base64EncodedCredential = (new Buffer(username + ':' + password).toString('base64'));
this._client = new KuduServiceClient(scmUri, base64EncodedCredential);
constructor(scmUri: string, credentials: {username: string, password: string} | string) {
const accessToken = typeof credentials === 'string'
? credentials
: (new Buffer(credentials.username + ':' + credentials.password).toString('base64'));
const accessTokenType = typeof credentials === 'string' ? "Bearer" : "Basic"

this._client = new KuduServiceClient(scmUri, accessToken, accessTokenType);
}

public async updateDeployment(requestBody: any): Promise<string> {
Expand Down Expand Up @@ -406,4 +410,4 @@ export class Kudu {
setTimeout(resolve, sleepDurationInSeconds * 1000);
});
}
}
}
20 changes: 17 additions & 3 deletions packages/appservice-rest/src/Utilities/AzureAppServiceUtility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,29 @@ export class AzureAppServiceUtility {
}

public async getKuduService(): Promise<Kudu> {
try {
const token = await this._appService.getAccessToken()
if (!!token) {
console.log(`::add-mask::${token}`);
const app = await this._appService.get()
const scmUri = (app.properties["hostNameSslStates"] || []).find(n => n.hostType == "Repository");
if (!!scmUri) {
return new Kudu(`https://${scmUri["name"]}`, token)
}
}
} catch (e) {
console.log('Error getting accessToken. Falling back to publishing profile: ' + e);
}

var publishingCredentials = await this._appService.getPublishingCredentials();
if(publishingCredentials.properties["scmUri"]) {
let userName = publishingCredentials.properties["publishingUserName"];
let username = publishingCredentials.properties["publishingUserName"];
let password = publishingCredentials.properties["publishingPassword"];

// masking kudu password
console.log(`::add-mask::${password}`);

return new Kudu(publishingCredentials.properties["scmUri"], userName, password);
return new Kudu(publishingCredentials.properties["scmUri"], { username, password });
}

throw Error('KUDU SCM details are empty');
Expand Down Expand Up @@ -151,4 +165,4 @@ export class AzureAppServiceUtility {

return isNewValueUpdated;
}
}
}
2 changes: 1 addition & 1 deletion packages/webclient/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "azure-actions-webclient",
"version": "1.1.0",
"version": "1.1.1",
"description": "Authorize to azure and make rest calls",
"keywords": [
"webclient",
Expand Down
4 changes: 4 additions & 0 deletions packages/webclient/src/AzureRestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ export class ServiceClient {
return response;
}

public getAccessToken(): Promise<string> {
return this._authorizer.getToken()
}

private _sleep(sleepDurationInSeconds: number): Promise<any> {
return new Promise((resolve) => {
setTimeout(resolve, sleepDurationInSeconds * 1000);
Expand Down

0 comments on commit 2699858

Please sign in to comment.