Question: Accessing `State` in `OpenApiFromRequest` Similar to `FromRequest`
NewtTheWolf opened this issue · 4 comments
Hello rocket_okapi
team,
I'm currently working on the zitadel-rust
project and generating OpenAPI documentation using the OpenApiFromRequest
trait. You can find the relevant PR here: smartive/zitadel-rust#559.
In this project, I need to configure the SecurityScheme
for OpenID Connect, and the authority URL for this configuration is stored in Rocket's State
.
In a typical request guard implementation using FromRequest
, I can access the request
object and retrieve the configuration from State
like this:
#[async_trait]
impl<'request> FromRequest<'request> for &'request IntrospectedUser {
type Error = &'request IntrospectionGuardError;
async fn from_request(request: &'request Request<'_>) -> Outcome<Self, Self::Error> {
// Accessing the authorization header
let auth: Vec<_> = request.headers().get("authorization").collect();
if auth.len() > 1 {
return Outcome::Error((Status::BadRequest, &IntrospectionGuardError::InvalidHeader));
} else if auth is_empty() {
return Outcome::Error((Status::Unauthorized, &IntrospectionGuardError::Unauthorized));
}
let token = auth[0];
if !token.starts_with("Bearer ") {
return Outcome::Error((Status::Unauthorized, &IntrospectionGuardError::WrongScheme));
}
// Accessing the configuration from State
let config = request.rocket().state::<IntrospectionConfig>();
if config is_none() {
return Outcome::Error((Status::InternalServerError, &IntrospectionGuardError::MissingConfig));
}
// Further processing...
}
}
However, when working within the OpenApiFromRequest
trait, I haven't found a way to similarly access the request
object or State
to retrieve the configuration data. Currently, I'm using figment
to extract the configuration, like this:
let config: IntrospectionRocketConfig = figment
.extract()
.expect("authority must be set in Rocket.toml");
But I would prefer to directly access the State
via the request
, similar to how it's done in FromRequest
, to keep consistency and avoid duplicating configuration extraction logic.
My Question:
Is it possible to access the request
object within OpenApiFromRequest
, or is there another recommended way to retrieve the State
while generating OpenAPI documentation with rocket_okapi
?
Thank you for your assistance!
Hey, sorry for the late reply. But the request
object is never available in rocket_okapi
or OpenApiFromRequest
This is because the openapi.json
file is generated at the time the macro is called. So it has no knowledge of anything happening at runtime. So it does not relay on/or see any request.
For some info: https://github.com/GREsau/okapi?tab=readme-ov-file#how-it-works
I see your MR got merged. So if this issue is no longer needed, you can close it.
Hey @ralpha thx for your response
yes the PR got merged, but the issue is still here
so everything happens in the Compile Time what also makes sense
So the way to go would be to use the Rocket Config file or something simmilar that can be accesed via the Compile time if i am right?
You can do something during run time too, but although a bunch is done during compile time.
The moment the macro is called openapi_get_routes![]
or similar you can some things.
But what exactly do you want to do? You want to change the OpenApi file depending on the Rocket.toml
file?
You can always just intercept the spec and then link it yourself.
For example here.
okapi/examples/custom_schema/src/main.rs
Line 50 in 5614a85
But you can even replace the
mount_endpoints_and_merged_docs!
to get even more control.Line 170 in 5614a85
Line 164-168 creates all endpoint links.
Line 170-173 merges everything into 1 spec.
Line 175-182 mount so the
openapi.json
file is added to Rocket.
So if you want change any of that you can just create your own macro.
But if you describe your problem a bit more, I might be able to point you to exactly to what you can do.
Also does the https://github.com/GREsau/okapi/tree/master/examples/secure_request_guard example not describe what you want to do?