Skip to content

Commit

Permalink
[Identity] Update error messages for AzurePipelinesCredential (#30387)
Browse files Browse the repository at this point in the history
  • Loading branch information
KarishmaGhiya committed Jul 31, 2024
1 parent f1ecbf9 commit d9870f4
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 34 deletions.
79 changes: 45 additions & 34 deletions sdk/identity/identity/src/credentials/azurePipelinesCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { checkTenantId } from "../util/tenantIdUtils";
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { AzurePipelinesCredentialOptions } from "./azurePipelinesCredentialOptions";
import { IdentityClient } from "../client/identityClient";
import { PipelineResponse } from "@azure/core-rest-pipeline";

const credentialName = "AzurePipelinesCredential";
const logger = credentialLogger(credentialName);
Expand Down Expand Up @@ -113,41 +114,51 @@ export class AzurePipelinesCredential implements TokenCredential {
}),
});
const response = await this.identityClient.sendRequest(request);
const text = response.bodyAsText;
if (!text) {
logger.error(
`${credentialName}: Authenticated Failed. Received null token from OIDC request. Response status- ${
response.status
}. Complete response - ${JSON.stringify(response)}`,
);
throw new AuthenticationError(
response.status,
`${credentialName}: Authenticated Failed. Received null token from OIDC request. Response status- ${
response.status
}. Complete response - ${JSON.stringify(response)}`,
);
}
try {
const result = JSON.parse(text);
if (result?.oidcToken) {
return result.oidcToken;
} else {
let errorMessage = `${credentialName}: Authentication Failed. oidcToken field not detected in the response.`;
if (response.status !== 200) {
errorMessage += `Response = ${JSON.stringify(result)}`;
}
logger.error(errorMessage);
throw new AuthenticationError(response.status, errorMessage);
return handleOidcResponse(response);
}
}

export function handleOidcResponse(response: PipelineResponse): string {
const text = response.bodyAsText;
if (!text) {
logger.error(
`${credentialName}: Authentication Failed. Received null token from OIDC request. Response status- ${
response.status
}. Complete response - ${JSON.stringify(response)}`,
);
throw new AuthenticationError(response.status, {
error: `${credentialName}: Authentication Failed. Received null token from OIDC request.`,
error_description: `${JSON.stringify(
response,
)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
});
}
try {
const result = JSON.parse(text);
if (result?.oidcToken) {
return result.oidcToken;
} else {
const errorMessage = `${credentialName}: Authentication Failed. oidcToken field not detected in the response.`;
let errorDescription = ``;
if (response.status !== 200) {
errorDescription = `Complete response - ${JSON.stringify(
result,
)}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`;
}
} catch (e: any) {
logger.error(e.message);
logger.error(
`${credentialName}: Authentication Failed. oidcToken field not detected in the response. Response = ${text}`,
);
throw new AuthenticationError(
response.status,
`${credentialName}: Authentication Failed. oidcToken field not detected in the response. Response = ${text}`,
);
logger.error(errorMessage);
logger.error(errorDescription);
throw new AuthenticationError(response.status, {
error: errorMessage,
error_description: errorDescription,
});
}
} catch (e: any) {
const errorDetails = `${credentialName}: Authentication Failed. oidcToken field not detected in the response.`;
logger.error(`Response from service = ${text} and error message = ${e.message}`);
logger.error(errorDetails);
throw new AuthenticationError(response.status, {
error: errorDetails,
error_description: `Response = ${text}. See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/azurepipelinescredential/troubleshoot`,
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import {
PipelineResponse,
createHttpHeaders,
createPipelineRequest,
} from "@azure/core-rest-pipeline";
import { handleOidcResponse } from "../../../src/credentials/azurePipelinesCredential";
import { assert } from "@azure-tools/test-utils";

describe("AzurePipelinesCredential (internal)", function () {
let response: PipelineResponse;
beforeEach(function () {
response = {
request: createPipelineRequest({
url: "https://domoreexp.visualstudio.com/11ac29bc-5a99-400b-b225-01839ab0c9df/_apis/distributedtask/hubs/build/plans/f8b9f114-0f05-49aa-bd84-d1f0197f47a1/jobs/30ea8d6c-7fd8-521d-25e4-72f1dd901d33/oidctoken?api-version=7.1&serviceConnectionId=REDACTED",
headers: createHttpHeaders({
"content-type": "application/json",
authorization: "REDACTED",
"accept-encoding": "gzip,deflate",
"user-agent":
"azsdk-js-identity/4.3.0-beta.3 core-rest-pipeline/1.12.0 Node/v20.11.0 OS/(x64-Linux-5.15.0-1067-azure)",
"x-ms-client-request-id": "54730b40-5c44-48db-ad98-666c8dabb48d",
}),
method: "POST",
}),
status: 400,
headers: createHttpHeaders(),
};
});

it("throws expected Authentication Error", function () {
assert.throws(
() => handleOidcResponse(response),
/AzurePipelinesCredential: Authentication Failed. Received null token from OIDC request. Status code: 400/,
);
});
it("throws expected error message with a service connection not found error", function () {
response.bodyAsText = "No service connection found with identifier frwerhq-241242-vsdkf-jw";
assert.throws(
() => handleOidcResponse(response),
/AzurePipelinesCredential: Authentication Failed. oidcToken field not detected in the response. Status code: 400[\s\S]*No service connection found with identifier/,
);
});
});

0 comments on commit d9870f4

Please sign in to comment.