agent_framework_purview/auth.rs
1//! Authentication: a self-contained, bring-your-own bearer token trait.
2//!
3//! # Auth burden
4//!
5//! The Python reference (`PurviewClient`) accepts an `azure-identity`
6//! `TokenCredential` or `AsyncTokenCredential` directly, so it inherits
7//! whatever credential chain the caller already has configured
8//! (`DefaultAzureCredential`, `InteractiveBrowserCredential`, a managed
9//! identity, ...). This crate has no `azure_identity`-equivalent dependency
10//! to accept, and per this work package's brief is deliberately
11//! **self-contained**: it defines its own minimal [`TokenProvider`] trait
12//! rather than depending on `agent-framework-azure`'s `TokenCredential` (a
13//! near-identical trait one layer up), so this crate has no dependency on
14//! any other provider crate in this workspace.
15//!
16//! Bring a Microsoft Graph bearer token with the
17//! `https://graph.microsoft.com/.default` scope (or the equivalent for a
18//! custom [`PurviewSettings::graph_base_uri`](crate::settings::PurviewSettings::graph_base_uri) —
19//! see [`PurviewSettings::get_scopes`](crate::settings::PurviewSettings::get_scopes)),
20//! carrying the `dataSecurityAndGovernance` Graph permission described in
21//! the Python package's README. [`StaticTokenProvider`] is provided for a
22//! fixed/pre-fetched token (tests, short-lived scripts, or externally-managed
23//! refresh).
24
25use async_trait::async_trait;
26
27use agent_framework_core::error::Result;
28
29/// Supplies bearer tokens for Microsoft Graph (Purview) requests. See the
30/// module docs for why this trait exists instead of reusing another crate's.
31#[async_trait]
32pub trait TokenProvider: Send + Sync {
33 /// Fetch a bearer token to send as `Authorization: Bearer <token>`.
34 async fn get_token(&self) -> Result<String>;
35}
36
37/// A [`TokenProvider`] that always returns the same, pre-fetched token.
38#[derive(Debug, Clone)]
39pub struct StaticTokenProvider {
40 token: String,
41}
42
43impl StaticTokenProvider {
44 /// Wrap a fixed bearer token.
45 pub fn new(token: impl Into<String>) -> Self {
46 Self {
47 token: token.into(),
48 }
49 }
50}
51
52#[async_trait]
53impl TokenProvider for StaticTokenProvider {
54 async fn get_token(&self) -> Result<String> {
55 Ok(self.token.clone())
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[tokio::test]
64 async fn static_token_provider_returns_configured_token() {
65 let provider = StaticTokenProvider::new("my-token");
66 assert_eq!(provider.get_token().await.unwrap(), "my-token");
67 }
68}