Skip to content

Commit 449f358

Browse files
authored
Add azd credential to DefaultAzureCredential (#2563)
1 parent 92bc173 commit 449f358

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

sdk/identity/azure_identity/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
## 0.24.0 (Unreleased)
44

55
### Features Added
6-
- 'AzureDeveloperCliCredential' authenticates the identity logged in to the [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/overview).
6+
7+
- `AzureDeveloperCliCredential` authenticates the identity logged in to the [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/overview).
8+
- Added the `AzureDeveloperCliCredential` to the `DefaultAzureCredential`.
79

810
### Breaking Changes
911

sdk/identity/azure_identity/src/azure_developer_cli_credential.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// cspell:ignore SYSTEMROOT workdir
55

6-
use crate::{env::Env, validate_scope, validate_tenant_id};
6+
use crate::{env::Env, validate_scope, validate_tenant_id, TokenCredentialOptions};
77
use azure_core::{
88
credentials::{AccessToken, Secret, TokenCredential},
99
error::{Error, ErrorKind},
@@ -146,6 +146,15 @@ impl TokenCredential for AzureDeveloperCliCredential {
146146
}
147147
}
148148

149+
impl From<TokenCredentialOptions> for AzureDeveloperCliCredentialOptions {
150+
fn from(options: TokenCredentialOptions) -> Self {
151+
Self {
152+
executor: Some(options.executor.clone()),
153+
..Default::default()
154+
}
155+
}
156+
}
157+
149158
#[cfg(test)]
150159
mod tests {
151160
use super::*;

sdk/identity/azure_identity/src/credentials/default_azure_credentials.rs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
#[cfg(not(target_arch = "wasm32"))]
5-
use crate::AzureCliCredential;
64
use crate::{credentials::cache::TokenCache, TokenCredentialOptions};
75
#[cfg(not(target_arch = "wasm32"))]
6+
use crate::{AzureCliCredential, AzureDeveloperCliCredential};
7+
#[cfg(not(target_arch = "wasm32"))]
88
use azure_core::error::ResultExt;
99
use azure_core::{
1010
credentials::{AccessToken, TokenCredential},
@@ -17,6 +17,8 @@ pub struct DefaultAzureCredentialBuilder {
1717
options: TokenCredentialOptions,
1818
#[cfg(not(target_arch = "wasm32"))]
1919
include_azure_cli_credential: bool,
20+
#[cfg(not(target_arch = "wasm32"))]
21+
include_azure_developer_cli_credential: bool,
2022
}
2123

2224
#[cfg_attr(target_arch = "wasm32", allow(clippy::derivable_impls))]
@@ -26,6 +28,8 @@ impl Default for DefaultAzureCredentialBuilder {
2628
options: TokenCredentialOptions::default(),
2729
#[cfg(not(target_arch = "wasm32"))]
2830
include_azure_cli_credential: true,
31+
#[cfg(not(target_arch = "wasm32"))]
32+
include_azure_developer_cli_credential: true,
2933
}
3034
}
3135
}
@@ -41,13 +45,20 @@ impl DefaultAzureCredentialBuilder {
4145
self
4246
}
4347

44-
/// Exclude using credential from the cli
48+
/// Exclude authenticating using the Azure CLI (az).
4549
#[cfg(not(target_arch = "wasm32"))]
4650
pub fn exclude_azure_cli_credential(&mut self) -> &mut Self {
4751
self.include_azure_cli_credential = false;
4852
self
4953
}
5054

55+
/// Exclude authenticating using the Azure Developer CLI (azd).
56+
#[cfg(not(target_arch = "wasm32"))]
57+
pub fn exclude_azure_developer_cli_credential(&mut self) -> &mut Self {
58+
self.include_azure_developer_cli_credential = false;
59+
self
60+
}
61+
5162
/// Get a list of the credential types to include.
5263
fn included(&self) -> Vec<DefaultAzureCredentialType> {
5364
#[cfg_attr(target_arch = "wasm32", allow(unused_mut))]
@@ -56,6 +67,10 @@ impl DefaultAzureCredentialBuilder {
5667
if self.include_azure_cli_credential {
5768
sources.push(DefaultAzureCredentialType::AzureCli);
5869
}
70+
#[cfg(not(target_arch = "wasm32"))]
71+
if self.include_azure_developer_cli_credential {
72+
sources.push(DefaultAzureCredentialType::AzureDeveloperCli);
73+
}
5974
sources
6075
}
6176

@@ -80,6 +95,14 @@ impl DefaultAzureCredentialBuilder {
8095
sources.push(DefaultAzureCredentialKind::AzureCli(credential));
8196
}
8297
}
98+
#[cfg(not(target_arch = "wasm32"))]
99+
DefaultAzureCredentialType::AzureDeveloperCli => {
100+
if let Ok(credential) =
101+
AzureDeveloperCliCredential::new(Some(self.options.clone().into()))
102+
{
103+
sources.push(DefaultAzureCredentialKind::AzureDeveloperCli(credential));
104+
}
105+
}
83106
#[cfg(target_arch = "wasm32")]
84107
_ => {
85108
return Err(Error::with_message(ErrorKind::Credential, || {
@@ -112,14 +135,19 @@ impl DefaultAzureCredentialBuilder {
112135
enum DefaultAzureCredentialType {
113136
#[cfg(not(target_arch = "wasm32"))]
114137
AzureCli,
138+
#[cfg(not(target_arch = "wasm32"))]
139+
AzureDeveloperCli,
115140
}
116141

117142
/// Types of `TokenCredential` supported by `DefaultAzureCredential`
118143
#[derive(Debug)]
119144
pub(crate) enum DefaultAzureCredentialKind {
120145
#[cfg(not(target_arch = "wasm32"))]
121-
/// `TokenCredential` from Azure CLI.
146+
/// `TokenCredential` from Azure CLI (az).
122147
AzureCli(Arc<AzureCliCredential>),
148+
#[cfg(not(target_arch = "wasm32"))]
149+
/// `TokenCredential` from Azure Developer CLI (azd).
150+
AzureDeveloperCli(Arc<AzureDeveloperCliCredential>),
123151
}
124152

125153
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send), allow(unused_variables))]
@@ -134,6 +162,13 @@ impl TokenCredential for DefaultAzureCredentialKind {
134162
"error getting token credential from Azure CLI",
135163
)
136164
}
165+
#[cfg(not(target_arch = "wasm32"))]
166+
DefaultAzureCredentialKind::AzureDeveloperCli(credential) => {
167+
credential.get_token(scopes).await.context(
168+
ErrorKind::Credential,
169+
"error getting token credential from Azure Developer CLI",
170+
)
171+
}
137172
#[cfg(target_arch = "wasm32")]
138173
_ => {
139174
return Err(Error::with_message(ErrorKind::Credential, || {
@@ -240,6 +275,8 @@ mod tests {
240275
let builder = DefaultAzureCredentialBuilder::new();
241276
#[cfg(not(target_arch = "wasm32"))]
242277
assert!(builder.include_azure_cli_credential);
278+
#[cfg(not(target_arch = "wasm32"))]
279+
assert!(builder.include_azure_developer_cli_credential);
243280

244281
#[cfg(not(target_arch = "wasm32"))]
245282
{
@@ -248,9 +285,18 @@ mod tests {
248285
assert!(!builder.include_azure_cli_credential);
249286
}
250287

288+
#[cfg(not(target_arch = "wasm32"))]
289+
{
290+
let mut builder = DefaultAzureCredentialBuilder::new();
291+
builder.exclude_azure_developer_cli_credential();
292+
assert!(!builder.include_azure_developer_cli_credential);
293+
}
294+
251295
let builder = DefaultAzureCredentialBuilder::new();
252296
#[cfg(not(target_arch = "wasm32"))]
253297
assert!(builder.include_azure_cli_credential);
298+
#[cfg(not(target_arch = "wasm32"))]
299+
assert!(builder.include_azure_developer_cli_credential);
254300
}
255301

256302
#[test]
@@ -259,7 +305,10 @@ mod tests {
259305
let builder = DefaultAzureCredentialBuilder::new();
260306
assert_eq!(
261307
builder.included(),
262-
vec![DefaultAzureCredentialType::AzureCli,]
308+
vec![
309+
DefaultAzureCredentialType::AzureCli,
310+
DefaultAzureCredentialType::AzureDeveloperCli
311+
]
263312
);
264313
}
265314

@@ -268,6 +317,7 @@ mod tests {
268317
fn test_exclude_azure_cli_credential() {
269318
let mut builder = DefaultAzureCredentialBuilder::new();
270319
builder.exclude_azure_cli_credential();
320+
builder.exclude_azure_developer_cli_credential();
271321
assert!(builder.included().is_empty());
272322
}
273323
}

0 commit comments

Comments
 (0)