@@ -81,35 +81,61 @@ fn finish(t: TransformOpenApi) -> TransformOpenApi {
81
81
) ,
82
82
..Default :: default ( )
83
83
} )
84
+ . security_scheme ( "oauth2" , oauth_security_scheme ( None ) )
84
85
. 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 ( ) ) ,
109
91
extensions : IndexMap :: default ( ) ,
110
92
} ,
111
93
)
112
94
. 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
+ }
113
139
}
114
140
115
141
pub fn router < S > ( ) -> ( OpenApi , Router < S > )
@@ -146,10 +172,13 @@ where
146
172
move |State ( url_builder) : State < UrlBuilder > | {
147
173
// Let's set the servers to the HTTP base URL
148
174
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) ) ) ;
153
182
154
183
std:: future:: ready ( Json ( api) )
155
184
}
0 commit comments