Skip to content

Commit 8111bcb

Browse files
[Metrics Advisor] Api Key rotation (Azure#13490)
Co-authored-by: Jeremy Meng <yumeng@microsoft.com>
1 parent 7f6b4ef commit 8111bcb

File tree

3 files changed

+98
-13
lines changed

3 files changed

+98
-13
lines changed

sdk/metricsadvisor/ai-metrics-advisor/review/ai-metrics-advisor.api.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,10 +1041,10 @@ export interface MetricsAdvisorClientOptions extends PipelineOptions {
10411041
// @public
10421042
export class MetricsAdvisorKeyCredential {
10431043
constructor(subscriptionKey: string, apiKey: string);
1044-
// (undocumented)
1045-
readonly apiKey: string;
1046-
// (undocumented)
1047-
readonly subscriptionKey: string;
1044+
get apiKey(): string;
1045+
get subscriptionKey(): string;
1046+
updateApiKey(apiKey: string): void;
1047+
updateSubscriptionKey(subscriptionKey: string): void;
10481048
}
10491049

10501050
// @public

sdk/metricsadvisor/ai-metrics-advisor/src/metricsAdvisorKeyCredentialPolicy.ts

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,73 @@ const X_API_KEY_HEADER_NAME = "x-api-key";
1818
* Credential used to authenticate and authorize with Metrics Advisor service
1919
*/
2020
export class MetricsAdvisorKeyCredential {
21+
/**
22+
* Subscription access key from the Azure portal
23+
*/
24+
private _subscriptionKey: string;
25+
26+
/**
27+
* API key from the Metrics Advisor web portal
28+
*/
29+
private _apiKey: string;
30+
2131
/**
2232
* Creates an instance of MetricsAdvisorKeyCredential
2333
*
2434
* @param subscriptionKey - Subscription access key from the Azure portal
2535
* @param apiKey - API key from the Metrics Advisor web portal
2636
*/
27-
constructor(readonly subscriptionKey: string, readonly apiKey: string) {}
37+
constructor(subscriptionKey: string, apiKey: string) {
38+
if (!subscriptionKey || !apiKey) {
39+
throw new RangeError("Subscription Key or Api Key doesn't have a valid value");
40+
}
41+
this._subscriptionKey = subscriptionKey;
42+
this._apiKey = apiKey;
43+
}
44+
45+
/**
46+
* Get Api Key
47+
*/
48+
public get apiKey(): string {
49+
return this._apiKey;
50+
}
51+
52+
/**
53+
* Get Subscription key
54+
*/
55+
public get subscriptionKey(): string {
56+
return this._subscriptionKey;
57+
}
58+
59+
/**
60+
* Change the value of the subscription key.
61+
*
62+
* Updates will take effect upon the next request after
63+
* updating the key value.
64+
*
65+
* @param subscriptionKey - The new subscription key value to be used
66+
*/
67+
public updateSubscriptionKey(subscriptionKey: string): void {
68+
if (!subscriptionKey) {
69+
throw new RangeError("subscriptionKey must be a non-empty string");
70+
}
71+
this._subscriptionKey = subscriptionKey;
72+
}
73+
74+
/**
75+
* Change the value of the api key.
76+
*
77+
* Updates will take effect upon the next request after
78+
* updating the key value.
79+
*
80+
* @param apiKey - The new api key value to be used
81+
*/
82+
public updateApiKey(apiKey: string): void {
83+
if (!apiKey) {
84+
throw new RangeError("apiKey must be a non-empty string");
85+
}
86+
this._apiKey = apiKey;
87+
}
2888
}
2989

3090
/**
@@ -46,26 +106,21 @@ export function createMetricsAdvisorKeyCredentialPolicy(
46106
* using the appropriate header
47107
*/
48108
class MetricsAdvisorKeyCredentialPolicy extends BaseRequestPolicy {
49-
private subscriptionKey: string;
50-
private apiKey: string;
51-
52109
constructor(
53110
nextPolicy: RequestPolicy,
54111
options: RequestPolicyOptionsLike,
55-
credential: MetricsAdvisorKeyCredential
112+
private _credential: MetricsAdvisorKeyCredential
56113
) {
57114
super(nextPolicy, options);
58-
this.subscriptionKey = credential.subscriptionKey;
59-
this.apiKey = credential.apiKey;
60115
}
61116

62117
public async sendRequest(webResource: WebResourceLike): Promise<HttpOperationResponse> {
63118
if (!webResource) {
64119
throw new Error("webResource cannot be null or undefined");
65120
}
66121

67-
webResource.headers.set(API_KEY_HEADER_NAME, this.subscriptionKey);
68-
webResource.headers.set(X_API_KEY_HEADER_NAME, this.apiKey);
122+
webResource.headers.set(API_KEY_HEADER_NAME, this._credential.subscriptionKey);
123+
webResource.headers.set(X_API_KEY_HEADER_NAME, this._credential.apiKey);
69124
return this._nextPolicy.sendRequest(webResource);
70125
}
71126
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
import { assert } from "chai";
5+
6+
import { MetricsAdvisorKeyCredential } from "../../src";
7+
import { testEnv } from "./util/recordedClients";
8+
9+
describe("MetricsAdvisorKeyCredential", () => {
10+
let credential: MetricsAdvisorKeyCredential;
11+
12+
beforeEach(function() {
13+
credential = new MetricsAdvisorKeyCredential(
14+
testEnv.METRICS_ADVISOR_SUBSCRIPTION_KEY,
15+
testEnv.METRICS_ADVISOR_API_KEY
16+
);
17+
});
18+
19+
it("update subscriptionKey", async function() {
20+
const newSubscriptionKey = "Abc";
21+
credential.updateSubscriptionKey(newSubscriptionKey);
22+
assert.equal(credential.subscriptionKey, newSubscriptionKey);
23+
});
24+
25+
it("update apiKey", async function() {
26+
const newApiKey = "Abcdef";
27+
credential.updateApiKey(newApiKey);
28+
assert.equal(credential.apiKey, newApiKey);
29+
});
30+
});

0 commit comments

Comments
 (0)