Skip to content

Commit

Permalink
[core-auth] Add AzureSASCredential
Browse files Browse the repository at this point in the history
This change adds an interfance and supporting class for use by services
which support authentication used a shared acccess signature.

Fixes #13053
  • Loading branch information
ellismg committed Jan 11, 2021
1 parent cd97a78 commit 39214d8
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
12 changes: 12 additions & 0 deletions sdk/core/core-auth/review/core-auth.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export class AzureKeyCredential implements KeyCredential {
update(newKey: string): void;
}

// @public
export class AzureSASCredential implements SASCredential {
constructor(signature: string);
get signature(): string;
update(newSignature: string): void;
}

// @public
export interface GetTokenOptions {
abortSignal?: AbortSignalLike;
Expand All @@ -38,6 +45,11 @@ export interface KeyCredential {
readonly key: string;
}

// @public
export interface SASCredential {
readonly signature: string;
}

// @public
export interface SpanContext {
spanId: string;
Expand Down
57 changes: 57 additions & 0 deletions sdk/core/core-auth/src/azureSASCredential.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* Represents a credential defined by a static shared access signature.
*/
export interface SASCredential {
/**
* The value of the shared access signature represented as a string
*/
readonly signature: string;
}

/**
* A static-signature-based credential that supports updating
* the underlying signature value.
*/
export class AzureSASCredential implements SASCredential {
private _signature: string;

/**
* The value of the shared access signature to be used in authentication
*/
public get signature(): string {
return this._signature;
}

/**
* Create an instance of an AzureSASCredential for use
* with a service client.
*
* @param signature - The initial value of the shared access signature to use in authentication
*/
constructor(signature: string) {
if (!signature) {
throw new Error("shared access signature must be a non-empty string");
}

this._signature = signature;
}

/**
* Change the value of the signature.
*
* Updates will take effect upon the next request after
* updating the signature value.
*
* @param newSignature - The new shared access signature value to be used
*/
public update(newSignature: string): void {
if (!newSignature) {
throw new Error("shared access signature must be a non-empty string");
}

this._signature = newSignature;
}
}
1 change: 1 addition & 0 deletions sdk/core/core-auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license.

export { AzureKeyCredential, KeyCredential } from "./azureKeyCredential";
export { AzureSASCredential, SASCredential } from "./azureSASCredential";

export {
TokenCredential,
Expand Down
36 changes: 36 additions & 0 deletions sdk/core/core-auth/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import assert from "assert";

import { AzureKeyCredential } from "../src/azureKeyCredential";
import { AzureSASCredential } from "../src/azureSASCredential";
import { isTokenCredential } from "../src/tokenCredential";

describe("AzureKeyCredential", () => {
Expand All @@ -27,6 +28,41 @@ describe("AzureKeyCredential", () => {
});
});

describe("AzureSASCredential", () => {
it("credential constructor throws on invalid signature", () => {
assert.throws(() => {
void new AzureSASCredential("");
}, /shared access signature must be a non-empty string/);
assert.throws(() => {
void new AzureSASCredential((null as unknown) as string);
}, /shared access signature must be a non-empty string/);
assert.throws(() => {
void new AzureSASCredential((undefined as unknown) as string);
}, /shared access signature must be a non-empty string/);
});

it("credential correctly updates", () => {
const credential = new AzureSASCredential("credential1");
assert.equal(credential.signature, "credential1");
credential.update("credential2");
assert.equal(credential.signature, "credential2");
});

it("throws when upadting with an invalid signature", () => {
const credential = new AzureSASCredential("credential1");

assert.throws(() => {
credential.update("");
}, /shared access signature must be a non-empty string/);
assert.throws(() => {
credential.update((null as unknown) as string);
}, /shared access signature must be a non-empty string/);
assert.throws(() => {
credential.update((undefined as unknown) as string);
}, /shared access signature must be a non-empty string/);
});
});

describe("isTokenCredential", function() {
it("should return true for an object that resembles a TokenCredential", () => {
assert.ok(
Expand Down

0 comments on commit 39214d8

Please sign in to comment.