-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathauth0.rs
142 lines (121 loc) · 3.95 KB
/
auth0.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Auth0 example
//!
//! This example is the same as examples/graphql.rs example. The only difference is that in this example
//! every request made by the bridge are authenticated with a JWT token as Bearer authentication.
//!
//! Before run the command to run this example be sure redis is running. Otherwise run this command:
//!
//! ```shell
//! docker run -p 6379:6379 --name bridge_redis -d redis
//! ```
//!
//! Export needed variables:
//! ```shell
//! export TOKEN_URL='https://{tenant}.auth0.com/oauth/token'
//! export JWKS_URL='https://{tenant}/.well-known/jwks.json'
//! export CLIENT_ID={client_id}
//! export CLIENT_SECRET={client_secret}
//! export AUDIENCE={audience}
//! ```
//!
//! And then to run this example execute:
//!
//! ```shell
//! cargo run --example auth0 --features auth0
//! ```
use serde::{Deserialize, Serialize};
use prima_bridge::prelude::*;
use prima_bridge::ParsedGraphqlResponse;
const URL: &str = "https://api.graphql.jobs/";
const QUERY: &str = "query($input:JobsInput!){jobs(input:$input) {\nid\n title\n applyUrl\n}}";
#[tokio::main]
async fn main() {
let bridge: Bridge = Bridge::builder()
.with_refreshing_token(auth0::refreshing_token().await)
.await
.build(URL.parse().unwrap());
let slug: String = "backend-engineer".to_string();
let response: Response = GraphQLRequest::new(&bridge, (QUERY, Some(JobsRequest::new(slug))))
.expect("Failed to create graphql request for query")
.send()
.await
.expect("graphql request results in error");
// The response is something like:
// {
// "data": {
// "jobs": [
// {
// "id": "cjz1ipl9x009a0758hg68h7vy",
// "title": "Senior Fullstack Engineer - Platform",
// "applyUrl": "https://grnh.se/2d8f45d71"
// },
// ...
// ]
// }
// }
// Using `get_data` parse the response and select only desired field parsing into the type you
// defined, eg. `PeopleResponse`.
let response: ParsedGraphqlResponse<JobsResponse> = response
.parse_graphql_response::<JobsResponse>()
.expect("error parsing response");
let response: JobsResponse = response.expect("response is not completed");
println!(
"The first job received from `{}` is {:?}",
URL,
response.jobs.first().unwrap()
);
}
// Request
#[derive(Serialize, Debug)]
pub struct JobsRequest {
pub input: JobsInput,
}
impl JobsRequest {
pub fn new(slug: String) -> Self {
Self {
input: JobsInput { slug },
}
}
}
#[derive(Serialize, Debug)]
pub struct JobsInput {
pub slug: String,
}
// Response
#[derive(Deserialize, Debug)]
pub struct JobsResponse {
pub jobs: Vec<Job>,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")] // This is needed in order to rename `apply_url` into `applyUrl`
pub struct Job {
pub id: String,
pub title: String,
pub apply_url: String,
}
mod auth0 {
use std::time::Duration;
use prima_bridge::auth0::{cache::InMemoryCache, Auth0Client, RefreshingToken, StalenessCheckPercentage};
pub async fn refreshing_token() -> RefreshingToken {
let token_url: String = std::env::var("TOKEN_URL").unwrap();
let client_id: String = std::env::var("CLIENT_ID").unwrap();
let client_secret: String = std::env::var("CLIENT_SECRET").unwrap();
let audience: String = std::env::var("AUDIENCE").unwrap();
let auth0_client = Auth0Client::new(
token_url.parse().unwrap(),
reqwest::Client::default(),
client_id,
client_secret,
);
RefreshingToken::new(
auth0_client,
Duration::from_secs(10),
StalenessCheckPercentage::default(),
Box::new(InMemoryCache::default()),
audience,
None,
)
.await
.unwrap()
}
}