From 6972ee52751b2aa930b70e7490a1f64439f75a74 Mon Sep 17 00:00:00 2001 From: Danilo Pereira Date: Wed, 22 Nov 2017 13:34:09 -0200 Subject: [PATCH 1/5] Add allow credentials support --- src/lib.rs | 58 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bf40f15..1ca8896 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,8 @@ //! for a full usage example. extern crate iron; -#[macro_use] extern crate log; +#[macro_use] +extern crate log; use std::collections::HashSet; @@ -61,6 +62,7 @@ use iron::headers; /// The struct that holds the CORS configuration. pub struct CorsMiddleware { allowed_hosts: Option>, + allow_credentials: bool, } impl CorsMiddleware { @@ -68,15 +70,21 @@ impl CorsMiddleware { pub fn with_whitelist(allowed_hosts: HashSet) -> Self { CorsMiddleware { allowed_hosts: Some(allowed_hosts), + allow_credentials: false, } } + pub fn allow_credentials(&mut self) { + self.allow_credentials = true; + } + /// Allow all origins to access the resource. The /// `Access-Control-Allow-Origin` header of the response will be set to /// `*`. pub fn with_allow_any() -> Self { CorsMiddleware { allowed_hosts: None, + allow_credentials: false, } } } @@ -85,11 +93,13 @@ impl AroundMiddleware for CorsMiddleware { fn around(self, handler: Box) -> Box { match self.allowed_hosts { Some(allowed_hosts) => Box::new(CorsHandlerWhitelist { - handler: handler, - allowed_hosts: allowed_hosts, + handler, + allowed_hosts, + allow_credentials: self.allow_credentials, }), None => Box::new(CorsHandlerAllowAny { - handler: handler, + handler, + allow_credentials: self.allow_credentials, }), } } @@ -99,17 +109,23 @@ impl AroundMiddleware for CorsMiddleware { struct CorsHandlerWhitelist { handler: Box, allowed_hosts: HashSet, + allow_credentials: bool, } /// Handler if allowing any origin. struct CorsHandlerAllowAny { handler: Box, + allow_credentials: bool, } impl CorsHandlerWhitelist { fn add_cors_header(&self, headers: &mut headers::Headers, origin: &headers::Origin) { let header = format_cors_origin(origin); headers.set(headers::AccessControlAllowOrigin::Value(header)); + + if self.allow_credentials { + headers.set(headers::AccessControlAllowCredentials) + } } fn add_cors_preflight_headers(&self, @@ -117,7 +133,6 @@ impl CorsHandlerWhitelist { origin: &headers::Origin, acrm: &headers::AccessControlRequestMethod, acrh: Option<&headers::AccessControlRequestHeaders>) { - self.add_cors_header(headers, origin); // Copy the method requested by the browser in the allowed methods header @@ -155,7 +170,7 @@ impl CorsHandlerWhitelist { } // If we don't have an Access-Control-Request-Method header, treat as a possible OPTION CORS call - return self.process_possible_cors_request(req, origin) + return self.process_possible_cors_request(req, origin); } fn process_possible_cors_request(&self, req: &mut Request, origin: headers::Origin) -> IronResult { @@ -165,8 +180,14 @@ impl CorsHandlerWhitelist { if may_process { // Everything OK, process request and add CORS header to response self.handler.handle(req) - .map(|mut res| { self.add_cors_header(&mut res.headers, &origin); res }) - .map_err(|mut err| { self.add_cors_header(&mut err.response.headers, &origin); err }) + .map(|mut res| { + self.add_cors_header(&mut res.headers, &origin); + res + }) + .map_err(|mut err| { + self.add_cors_header(&mut err.response.headers, &origin); + err + }) } else { // Not adding headers warn!("Got disallowed CORS request from {}", &origin.host.hostname); @@ -203,13 +224,16 @@ impl Handler for CorsHandlerWhitelist { impl CorsHandlerAllowAny { fn add_cors_header(&self, headers: &mut headers::Headers) { headers.set(headers::AccessControlAllowOrigin::Any); + + if self.allow_credentials { + headers.set(headers::AccessControlAllowCredentials) + } } fn add_cors_preflight_headers(&self, headers: &mut headers::Headers, acrm: &headers::AccessControlRequestMethod, acrh: Option<&headers::AccessControlRequestHeaders>) { - self.add_cors_header(headers); // Copy the method requested by the browser into the allowed methods header @@ -239,13 +263,19 @@ impl CorsHandlerAllowAny { } // If we don't have an Access-Control-Request-Method header, treat as a possible OPTION CORS call - return self.process_possible_cors_request(req) + return self.process_possible_cors_request(req); } fn process_possible_cors_request(&self, req: &mut Request) -> IronResult { self.handler.handle(req) - .map(|mut res| { self.add_cors_header(&mut res.headers); res }) - .map_err(|mut err| { self.add_cors_header(&mut err.response.headers); err }) + .map(|mut res| { + self.add_cors_header(&mut res.headers); + res + }) + .map_err(|mut err| { + self.add_cors_header(&mut err.response.headers); + err + }) } } @@ -259,7 +289,7 @@ impl Handler for CorsHandlerAllowAny { match req.headers.get::() { None => { self.handler.handle(req) - }, + } Some(_) => { match req.method { //If is an OPTION request, check for preflight @@ -267,7 +297,7 @@ impl Handler for CorsHandlerAllowAny { // If is not an OPTION request, we assume a normal CORS (no preflight) _ => self.process_possible_cors_request(req), } - }, + } } } } From 43805f10e49e176279b2b90878abe0763938d0a3 Mon Sep 17 00:00:00 2001 From: Danilo Pereira Date: Thu, 23 Nov 2017 10:07:11 -0200 Subject: [PATCH 2/5] Remove allow credentials setter --- src/lib.rs | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1ca8896..8436d9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,6 @@ use iron::headers; /// The struct that holds the CORS configuration. pub struct CorsMiddleware { allowed_hosts: Option>, - allow_credentials: bool, } impl CorsMiddleware { @@ -70,21 +69,15 @@ impl CorsMiddleware { pub fn with_whitelist(allowed_hosts: HashSet) -> Self { CorsMiddleware { allowed_hosts: Some(allowed_hosts), - allow_credentials: false, } } - pub fn allow_credentials(&mut self) { - self.allow_credentials = true; - } - /// Allow all origins to access the resource. The /// `Access-Control-Allow-Origin` header of the response will be set to /// `*`. pub fn with_allow_any() -> Self { CorsMiddleware { allowed_hosts: None, - allow_credentials: false, } } } @@ -95,11 +88,9 @@ impl AroundMiddleware for CorsMiddleware { Some(allowed_hosts) => Box::new(CorsHandlerWhitelist { handler, allowed_hosts, - allow_credentials: self.allow_credentials, }), None => Box::new(CorsHandlerAllowAny { handler, - allow_credentials: self.allow_credentials, }), } } @@ -109,23 +100,18 @@ impl AroundMiddleware for CorsMiddleware { struct CorsHandlerWhitelist { handler: Box, allowed_hosts: HashSet, - allow_credentials: bool, + } /// Handler if allowing any origin. struct CorsHandlerAllowAny { handler: Box, - allow_credentials: bool, } impl CorsHandlerWhitelist { fn add_cors_header(&self, headers: &mut headers::Headers, origin: &headers::Origin) { let header = format_cors_origin(origin); headers.set(headers::AccessControlAllowOrigin::Value(header)); - - if self.allow_credentials { - headers.set(headers::AccessControlAllowCredentials) - } } fn add_cors_preflight_headers(&self, @@ -133,6 +119,7 @@ impl CorsHandlerWhitelist { origin: &headers::Origin, acrm: &headers::AccessControlRequestMethod, acrh: Option<&headers::AccessControlRequestHeaders>) { + self.add_cors_header(headers, origin); // Copy the method requested by the browser in the allowed methods header @@ -224,10 +211,6 @@ impl Handler for CorsHandlerWhitelist { impl CorsHandlerAllowAny { fn add_cors_header(&self, headers: &mut headers::Headers) { headers.set(headers::AccessControlAllowOrigin::Any); - - if self.allow_credentials { - headers.set(headers::AccessControlAllowCredentials) - } } fn add_cors_preflight_headers(&self, From 1fa586442f5e0b221ebf5511003e3abb4d3415fc Mon Sep 17 00:00:00 2001 From: Danilo Pereira Date: Thu, 23 Nov 2017 10:38:25 -0200 Subject: [PATCH 3/5] Add builder with support for the "allow-credentials" --- src/lib.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8436d9c..89be2da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,9 +59,37 @@ use iron::method::Method; use iron::status; use iron::headers; +/// The struct that builds a CorsMiddleware +pub struct CorsMiddlewareBuilder { + allowed_hosts: Option>, + allow_credentials: bool +} + +impl CorsMiddlewareBuilder { + pub fn new() -> Self { + CorsMiddlewareBuilder{allow_credentials: false, allowed_hosts: None} + } + + /// Specify which origin hosts are allowed to access the resource. + pub fn allowed_hosts(&mut self, allowed_hosts: HashSet) -> &mut Self { + self.allowed_hosts = Some(allowed_hosts); + self + } + /// Specify Access-Control-Allow-Credentials + pub fn allow_credentials(&mut self, allow_credentials: bool) -> &mut Self { + self.allow_credentials = allow_credentials; + self + } + + pub fn build(self) -> CorsMiddleware { + CorsMiddleware{allowed_hosts: self.allowed_hosts, allow_credentials: self.allow_credentials } + } +} + /// The struct that holds the CORS configuration. pub struct CorsMiddleware { allowed_hosts: Option>, + allow_credentials: bool, } impl CorsMiddleware { @@ -69,6 +97,7 @@ impl CorsMiddleware { pub fn with_whitelist(allowed_hosts: HashSet) -> Self { CorsMiddleware { allowed_hosts: Some(allowed_hosts), + allow_credentials: false, } } @@ -78,6 +107,7 @@ impl CorsMiddleware { pub fn with_allow_any() -> Self { CorsMiddleware { allowed_hosts: None, + allow_credentials: false, } } } @@ -88,9 +118,11 @@ impl AroundMiddleware for CorsMiddleware { Some(allowed_hosts) => Box::new(CorsHandlerWhitelist { handler, allowed_hosts, + allow_credentials: self.allow_credentials, }), None => Box::new(CorsHandlerAllowAny { handler, + allow_credentials: self.allow_credentials, }), } } @@ -100,18 +132,23 @@ impl AroundMiddleware for CorsMiddleware { struct CorsHandlerWhitelist { handler: Box, allowed_hosts: HashSet, - + allow_credentials: bool, } /// Handler if allowing any origin. struct CorsHandlerAllowAny { handler: Box, + allow_credentials: bool, } impl CorsHandlerWhitelist { fn add_cors_header(&self, headers: &mut headers::Headers, origin: &headers::Origin) { let header = format_cors_origin(origin); headers.set(headers::AccessControlAllowOrigin::Value(header)); + + if self.allow_credentials { + headers.set(headers::AccessControlAllowCredentials) + } } fn add_cors_preflight_headers(&self, @@ -211,6 +248,10 @@ impl Handler for CorsHandlerWhitelist { impl CorsHandlerAllowAny { fn add_cors_header(&self, headers: &mut headers::Headers) { headers.set(headers::AccessControlAllowOrigin::Any); + + if self.allow_credentials { + headers.set(headers::AccessControlAllowCredentials) + } } fn add_cors_preflight_headers(&self, From 72abd0be21082c4fa34ea5f65b292d7e3716bcdf Mon Sep 17 00:00:00 2001 From: Danilo Pereira Date: Thu, 23 Nov 2017 10:48:20 -0200 Subject: [PATCH 4/5] Bug Fix in builder. --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 89be2da..fca6f88 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -81,8 +81,8 @@ impl CorsMiddlewareBuilder { self } - pub fn build(self) -> CorsMiddleware { - CorsMiddleware{allowed_hosts: self.allowed_hosts, allow_credentials: self.allow_credentials } + pub fn build(&self) -> CorsMiddleware { + CorsMiddleware{allowed_hosts: self.allowed_hosts.clone(), allow_credentials: self.allow_credentials } } } From 76f7ea9c6defcba416d5e0f96c56e073e3fe4af9 Mon Sep 17 00:00:00 2001 From: Danilo Pereira Date: Thu, 23 Nov 2017 23:07:54 -0200 Subject: [PATCH 5/5] Reformat --- src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fca6f88..b6580e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,7 +67,7 @@ pub struct CorsMiddlewareBuilder { impl CorsMiddlewareBuilder { pub fn new() -> Self { - CorsMiddlewareBuilder{allow_credentials: false, allowed_hosts: None} + CorsMiddlewareBuilder { allow_credentials: false, allowed_hosts: None } } /// Specify which origin hosts are allowed to access the resource. @@ -82,7 +82,7 @@ impl CorsMiddlewareBuilder { } pub fn build(&self) -> CorsMiddleware { - CorsMiddleware{allowed_hosts: self.allowed_hosts.clone(), allow_credentials: self.allow_credentials } + CorsMiddleware { allowed_hosts: self.allowed_hosts.clone(), allow_credentials: self.allow_credentials } } } @@ -156,7 +156,6 @@ impl CorsHandlerWhitelist { origin: &headers::Origin, acrm: &headers::AccessControlRequestMethod, acrh: Option<&headers::AccessControlRequestHeaders>) { - self.add_cors_header(headers, origin); // Copy the method requested by the browser in the allowed methods header