Skip to content

Commit dc2ff76

Browse files
committed
Use absolute URLs in the OAuth 2.0 security scheme in the API spec
1 parent 4396ba1 commit dc2ff76

File tree

2 files changed

+63
-28
lines changed

2 files changed

+63
-28
lines changed

crates/handlers/src/admin/mod.rs

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -81,35 +81,57 @@ fn finish(t: TransformOpenApi) -> TransformOpenApi {
8181
),
8282
..Default::default()
8383
})
84+
.security_scheme("oauth2", oauth_security_scheme(None))
8485
.security_scheme(
85-
"oauth2",
86-
SecurityScheme::OAuth2 {
87-
flows: OAuth2Flows {
88-
client_credentials: Some(OAuth2Flow::ClientCredentials {
89-
refresh_url: Some(OAuth2TokenEndpoint::PATH.to_owned()),
90-
token_url: OAuth2TokenEndpoint::PATH.to_owned(),
91-
scopes: IndexMap::from([(
92-
"urn:mas:admin".to_owned(),
93-
"Grant access to the admin API".to_owned(),
94-
)]),
95-
}),
96-
authorization_code: Some(OAuth2Flow::AuthorizationCode {
97-
authorization_url: OAuth2AuthorizationEndpoint::PATH.to_owned(),
98-
refresh_url: Some(OAuth2TokenEndpoint::PATH.to_owned()),
99-
token_url: OAuth2TokenEndpoint::PATH.to_owned(),
100-
scopes: IndexMap::from([(
101-
"urn:mas:admin".to_owned(),
102-
"Grant access to the admin API".to_owned(),
103-
)]),
104-
}),
105-
implicit: None,
106-
password: None,
107-
},
108-
description: None,
86+
"token",
87+
SecurityScheme::Http {
88+
scheme: "bearer".to_owned(),
89+
bearer_format: None,
90+
description: Some("An access token with access to the admin API".to_owned()),
10991
extensions: IndexMap::default(),
11092
},
11193
)
11294
.security_requirement_scopes("oauth2", ["urn:mas:admin"])
95+
.security_requirement_scopes("bearer", ["urn:mas:admin"])
96+
}
97+
98+
fn oauth_security_scheme(url_builder: Option<&UrlBuilder>) -> SecurityScheme {
99+
let (authorization_url, token_url) = if let Some(url_builder) = url_builder {
100+
(
101+
url_builder.oauth_authorization_endpoint().to_string(),
102+
url_builder.oauth_token_endpoint().to_string(),
103+
)
104+
} else {
105+
(
106+
OAuth2AuthorizationEndpoint::PATH.to_owned(),
107+
OAuth2TokenEndpoint::PATH.to_owned(),
108+
)
109+
};
110+
111+
let scopes = IndexMap::from([(
112+
"urn:mas:admin".to_owned(),
113+
"Grant access to the admin API".to_owned(),
114+
)]);
115+
116+
SecurityScheme::OAuth2 {
117+
flows: OAuth2Flows {
118+
client_credentials: Some(OAuth2Flow::ClientCredentials {
119+
refresh_url: Some(token_url.clone()),
120+
token_url: token_url.clone(),
121+
scopes: scopes.clone(),
122+
}),
123+
authorization_code: Some(OAuth2Flow::AuthorizationCode {
124+
authorization_url,
125+
refresh_url: Some(token_url.clone()),
126+
token_url,
127+
scopes,
128+
}),
129+
implicit: None,
130+
password: None,
131+
},
132+
description: None,
133+
extensions: IndexMap::default(),
134+
}
113135
}
114136

115137
pub fn router<S>() -> (OpenApi, Router<S>)
@@ -146,10 +168,13 @@ where
146168
move |State(url_builder): State<UrlBuilder>| {
147169
// Let's set the servers to the HTTP base URL
148170
let mut api = api.clone();
149-
api.servers = vec![Server {
150-
url: url_builder.http_base().to_string(),
151-
..Server::default()
152-
}];
171+
172+
let _ = TransformOpenApi::new(&mut api)
173+
.server(Server {
174+
url: url_builder.http_base().to_string(),
175+
..Server::default()
176+
})
177+
.security_scheme("oauth2", oauth_security_scheme(Some(&url_builder)));
153178

154179
std::future::ready(Json(api))
155180
}

docs/api/spec.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,11 @@
25422542
}
25432543
}
25442544
}
2545+
},
2546+
"token": {
2547+
"type": "http",
2548+
"scheme": "bearer",
2549+
"description": "An access token with access to the admin API"
25452550
}
25462551
},
25472552
"schemas": {
@@ -3725,6 +3730,11 @@
37253730
"oauth2": [
37263731
"urn:mas:admin"
37273732
]
3733+
},
3734+
{
3735+
"bearer": [
3736+
"urn:mas:admin"
3737+
]
37283738
}
37293739
],
37303740
"tags": [

0 commit comments

Comments
 (0)