mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-07 02:55:19 +00:00
Implement stack for Swagger Context (#612)
This commit is contained in:
parent
7e494e52ab
commit
b6fc29050d
@ -198,7 +198,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs"));
|
||||
supportingFiles.add(new SupportingFile("models.mustache", "src", "models.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-mod.mustache", "src/server", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-auth.mustache", "src/server", "auth.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-context.mustache", "src/server", "context.rs"));
|
||||
supportingFiles.add(new SupportingFile("client-mod.mustache", "src/client", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("mimetypes.mustache", "src", "mimetypes.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-server.mustache", "examples", "server.rs"));
|
||||
|
@ -19,7 +19,7 @@ chrono = { version = "0.4", features = ["serde"] }
|
||||
futures = "0.1"
|
||||
hyper = {version = "0.11", optional = true}
|
||||
hyper-tls = {version = "0.1.2", optional = true}
|
||||
swagger = "0.12.1"
|
||||
swagger = "1.0.1"
|
||||
|
||||
# Not required by example server.
|
||||
#
|
||||
|
@ -55,7 +55,7 @@ fn main() {
|
||||
.get_matches();
|
||||
|
||||
let service_fn =
|
||||
{{{externCrateName}}}::server::auth::NewService::<_, EmptyContext>::new(
|
||||
{{{externCrateName}}}::server::context::NewAddContext::<_, EmptyContext>::new(
|
||||
AllowAllAuthenticator::new(
|
||||
server_lib::NewService::new(),
|
||||
"cosmo"
|
||||
|
@ -8,76 +8,72 @@ use swagger::auth::{Authorization, AuthData, Scopes};
|
||||
use swagger::{Has, Pop, Push, XSpanIdString};
|
||||
use Api;
|
||||
|
||||
pub struct NewService<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
pub struct NewAddContext<T, A>
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<C>,
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<T, C> NewService<T, C>
|
||||
impl<T, A, B, C, D> NewAddContext<T, A>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error> + 'static,
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::NewService<Request = (Request, D), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
pub fn new(inner: T) -> NewService<T, C> {
|
||||
NewService {
|
||||
pub fn new(inner: T) -> NewAddContext<T, A> {
|
||||
NewAddContext {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::server::NewService for NewService<T, C>
|
||||
impl<T, A, B, C, D> hyper::server::NewService for NewAddContext<T, A>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error> + 'static,
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::NewService<Request = (Request, D), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = Error;
|
||||
type Instance = Service<T::Instance, C>;
|
||||
type Instance = AddContext<T::Instance, A>;
|
||||
|
||||
fn new_service(&self) -> Result<Self::Instance, io::Error> {
|
||||
self.inner.new_service().map(|s| Service::new(s))
|
||||
self.inner.new_service().map(|s| AddContext::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// Middleware to extract authentication data from request
|
||||
pub struct Service<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
pub struct AddContext<T, A>
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<C>,
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<T, C> Service<T, C>
|
||||
impl<T, A, B, C, D> AddContext<T, A>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::Service<Request = (Request, D), Response = Response, Error = Error>,
|
||||
{
|
||||
pub fn new(inner: T) -> Service<T, C> {
|
||||
Service {
|
||||
pub fn new(inner: T) -> AddContext<T, A> {
|
||||
AddContext {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::server::Service for Service<T, C>
|
||||
impl<T, A, B, C, D> hyper::server::Service for AddContext<T, A>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::Service<Request = (Request, D), Response = Response, Error = Error>,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
@ -85,27 +81,29 @@ impl<T, C> hyper::server::Service for Service<T, C>
|
||||
type Future = T::Future;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
let context = C::default().push(XSpanIdString::get_or_generate(&req));
|
||||
let context = A::default().push(XSpanIdString::get_or_generate(&req));
|
||||
|
||||
{{#authMethods}}
|
||||
{{#isBasic}}
|
||||
{
|
||||
use hyper::header::{Authorization, Basic, Bearer};
|
||||
use hyper::header::{Authorization as HyperAuth, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(basic) = req.headers().get::<Authorization<Basic>>().cloned() {
|
||||
if let Some(basic) = req.headers().get::<HyperAuth<Basic>>().cloned() {
|
||||
let auth_data = AuthData::Basic(basic.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{{/isBasic}}
|
||||
{{#isOAuth}}
|
||||
{
|
||||
use hyper::header::{Authorization, Basic, Bearer};
|
||||
use hyper::header::{Authorization as HyperAuth, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(bearer) = req.headers().get::<Authorization<Bearer>>().cloned() {
|
||||
if let Some(bearer) = req.headers().get::<HyperAuth<Bearer>>().cloned() {
|
||||
let auth_data = AuthData::Bearer(bearer.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
@ -117,6 +115,7 @@ impl<T, C> hyper::server::Service for Service<T, C>
|
||||
if let Some(header) = req.headers().get::<ApiKey{{-index}}>().cloned() {
|
||||
let auth_data = AuthData::ApiKey(header.0);
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
@ -130,6 +129,7 @@ impl<T, C> hyper::server::Service for Service<T, C>
|
||||
if let Some(key) = key {
|
||||
let auth_data = AuthData::ApiKey(key);
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
@ -137,7 +137,8 @@ impl<T, C> hyper::server::Service for Service<T, C>
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
|
||||
let context = context.push(None);
|
||||
let context = context.push(None::<AuthData>);
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
|
||||
pub mod auth;
|
||||
pub mod context;
|
||||
|
||||
header! { (Warning, "Warning") => [String] }
|
||||
|
||||
@ -370,3 +370,13 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> Clone for Service<T, C>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Service {
|
||||
api_impl: self.api_impl.clone(),
|
||||
marker: self.marker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ chrono = { version = "0.4", features = ["serde"] }
|
||||
futures = "0.1"
|
||||
hyper = {version = "0.11", optional = true}
|
||||
hyper-tls = {version = "0.1.2", optional = true}
|
||||
swagger = "0.12.1"
|
||||
swagger = "1.0.1"
|
||||
|
||||
# Not required by example server.
|
||||
#
|
||||
|
@ -55,7 +55,7 @@ fn main() {
|
||||
.get_matches();
|
||||
|
||||
let service_fn =
|
||||
petstore_api::server::auth::NewService::<_, EmptyContext>::new(
|
||||
petstore_api::server::context::NewAddContext::<_, EmptyContext>::new(
|
||||
AllowAllAuthenticator::new(
|
||||
server_lib::NewService::new(),
|
||||
"cosmo"
|
||||
|
@ -1,131 +0,0 @@
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
use std::default::Default;
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode};
|
||||
use server::url::form_urlencoded;
|
||||
use swagger::auth::{Authorization, AuthData, Scopes};
|
||||
use swagger::{Has, Pop, Push, XSpanIdString};
|
||||
use Api;
|
||||
|
||||
pub struct NewService<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<T, C> NewService<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
pub fn new(inner: T) -> NewService<T, C> {
|
||||
NewService {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::server::NewService for NewService<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::NewService<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = Error;
|
||||
type Instance = Service<T::Instance, C>;
|
||||
|
||||
fn new_service(&self) -> Result<Self::Instance, io::Error> {
|
||||
self.inner.new_service().map(|s| Service::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// Middleware to extract authentication data from request
|
||||
pub struct Service<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<T, C> Service<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
{
|
||||
pub fn new(inner: T) -> Service<T, C> {
|
||||
Service {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::server::Service for Service<T, C>
|
||||
where
|
||||
C: Default + Push<XSpanIdString>,
|
||||
C::Result: Push<Option<AuthData>>,
|
||||
T: hyper::server::Service<Request = (Request, <C::Result as Push<Option<AuthData>>>::Result), Response = Response, Error = Error>,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = Error;
|
||||
type Future = T::Future;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
let context = C::default().push(XSpanIdString::get_or_generate(&req));
|
||||
|
||||
{
|
||||
header! { (ApiKey1, "api_key") => [String] }
|
||||
if let Some(header) = req.headers().get::<ApiKey1>().cloned() {
|
||||
let auth_data = AuthData::ApiKey(header.0);
|
||||
let context = context.push(Some(auth_data));
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
let key = form_urlencoded::parse(req.query().unwrap_or_default().as_bytes())
|
||||
.filter(|e| e.0 == "api_key_query")
|
||||
.map(|e| e.1.clone().into_owned())
|
||||
.nth(0);
|
||||
if let Some(key) = key {
|
||||
let auth_data = AuthData::ApiKey(key);
|
||||
let context = context.push(Some(auth_data));
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
use hyper::header::{Authorization, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(basic) = req.headers().get::<Authorization<Basic>>().cloned() {
|
||||
let auth_data = AuthData::Basic(basic.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
use hyper::header::{Authorization, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(bearer) = req.headers().get::<Authorization<Bearer>>().cloned() {
|
||||
let auth_data = AuthData::Bearer(bearer.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
|
||||
let context = context.push(None);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
132
samples/server/petstore/rust-server/src/server/context.rs
Normal file
132
samples/server/petstore/rust-server/src/server/context.rs
Normal file
@ -0,0 +1,132 @@
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
use std::default::Default;
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode};
|
||||
use server::url::form_urlencoded;
|
||||
use swagger::auth::{Authorization, AuthData, Scopes};
|
||||
use swagger::{Has, Pop, Push, XSpanIdString};
|
||||
use Api;
|
||||
|
||||
pub struct NewAddContext<T, A>
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<T, A, B, C, D> NewAddContext<T, A>
|
||||
where
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::NewService<Request = (Request, D), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
pub fn new(inner: T) -> NewAddContext<T, A> {
|
||||
NewAddContext {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A, B, C, D> hyper::server::NewService for NewAddContext<T, A>
|
||||
where
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::NewService<Request = (Request, D), Response = Response, Error = Error> + 'static,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = Error;
|
||||
type Instance = AddContext<T::Instance, A>;
|
||||
|
||||
fn new_service(&self) -> Result<Self::Instance, io::Error> {
|
||||
self.inner.new_service().map(|s| AddContext::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
/// Middleware to extract authentication data from request
|
||||
pub struct AddContext<T, A>
|
||||
{
|
||||
inner: T,
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<T, A, B, C, D> AddContext<T, A>
|
||||
where
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::Service<Request = (Request, D), Response = Response, Error = Error>,
|
||||
{
|
||||
pub fn new(inner: T) -> AddContext<T, A> {
|
||||
AddContext {
|
||||
inner,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A, B, C, D> hyper::server::Service for AddContext<T, A>
|
||||
where
|
||||
A: Default + Push<XSpanIdString, Result=B>,
|
||||
B: Push<Option<AuthData>, Result=C>,
|
||||
C: Push<Option<Authorization>, Result=D>,
|
||||
T: hyper::server::Service<Request = (Request, D), Response = Response, Error = Error>,
|
||||
{
|
||||
type Request = Request;
|
||||
type Response = Response;
|
||||
type Error = Error;
|
||||
type Future = T::Future;
|
||||
|
||||
fn call(&self, req: Self::Request) -> Self::Future {
|
||||
let context = A::default().push(XSpanIdString::get_or_generate(&req));
|
||||
|
||||
{
|
||||
header! { (ApiKey1, "api_key") => [String] }
|
||||
if let Some(header) = req.headers().get::<ApiKey1>().cloned() {
|
||||
let auth_data = AuthData::ApiKey(header.0);
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
let key = form_urlencoded::parse(req.query().unwrap_or_default().as_bytes())
|
||||
.filter(|e| e.0 == "api_key_query")
|
||||
.map(|e| e.1.clone().into_owned())
|
||||
.nth(0);
|
||||
if let Some(key) = key {
|
||||
let auth_data = AuthData::ApiKey(key);
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
use hyper::header::{Authorization as HyperAuth, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(basic) = req.headers().get::<HyperAuth<Basic>>().cloned() {
|
||||
let auth_data = AuthData::Basic(basic.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
{
|
||||
use hyper::header::{Authorization as HyperAuth, Basic, Bearer};
|
||||
use std::ops::Deref;
|
||||
if let Some(bearer) = req.headers().get::<HyperAuth<Bearer>>().cloned() {
|
||||
let auth_data = AuthData::Bearer(bearer.deref().clone());
|
||||
let context = context.push(Some(auth_data));
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
||||
|
||||
let context = context.push(None::<AuthData>);
|
||||
let context = context.push(None::<Authorization>);
|
||||
return self.inner.call((req, context));
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ use {Api,
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
|
||||
pub mod auth;
|
||||
pub mod context;
|
||||
|
||||
header! { (Warning, "Warning") => [String] }
|
||||
|
||||
@ -2939,3 +2939,13 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> Clone for Service<T, C>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Service {
|
||||
api_impl: self.api_impl.clone(),
|
||||
marker: self.marker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user