@@ -81,35 +81,61 @@ 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+ // This is a dirty fix for Swagger UI: when it joins the URLs with the
106+ // base URL, if the path starts with a slash, it will go to the root of
107+ // the domain instead of the API root.
108+ // It works if we make it explicitly relative
109+ (
110+ format ! ( ".{}" , OAuth2AuthorizationEndpoint :: PATH ) ,
111+ format ! ( ".{}" , OAuth2TokenEndpoint :: PATH ) ,
112+ )
113+ } ;
114+
115+ let scopes = IndexMap :: from ( [ (
116+ "urn:mas:admin" . to_owned ( ) ,
117+ "Grant access to the admin API" . to_owned ( ) ,
118+ ) ] ) ;
119+
120+ SecurityScheme :: OAuth2 {
121+ flows : OAuth2Flows {
122+ client_credentials : Some ( OAuth2Flow :: ClientCredentials {
123+ refresh_url : Some ( token_url. clone ( ) ) ,
124+ token_url : token_url. clone ( ) ,
125+ scopes : scopes. clone ( ) ,
126+ } ) ,
127+ authorization_code : Some ( OAuth2Flow :: AuthorizationCode {
128+ authorization_url,
129+ refresh_url : Some ( token_url. clone ( ) ) ,
130+ token_url,
131+ scopes,
132+ } ) ,
133+ implicit : None ,
134+ password : None ,
135+ } ,
136+ description : None ,
137+ extensions : IndexMap :: default ( ) ,
138+ }
113139}
114140
115141pub fn router < S > ( ) -> ( OpenApi , Router < S > )
@@ -146,10 +172,13 @@ where
146172 move |State ( url_builder) : State < UrlBuilder > | {
147173 // Let's set the servers to the HTTP base URL
148174 let mut api = api. clone ( ) ;
149- api. servers = vec ! [ Server {
150- url: url_builder. http_base( ) . to_string( ) ,
151- ..Server :: default ( )
152- } ] ;
175+
176+ let _ = TransformOpenApi :: new ( & mut api)
177+ . server ( Server {
178+ url : url_builder. http_base ( ) . to_string ( ) ,
179+ ..Server :: default ( )
180+ } )
181+ . security_scheme ( "oauth2" , oauth_security_scheme ( Some ( & url_builder) ) ) ;
153182
154183 std:: future:: ready ( Json ( api) )
155184 }
0 commit comments