mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-30 10:32:55 +01:00
add CookieIdentityPolicy::http_only method (#102)
This commit is contained in:
parent
400d889116
commit
6ae147d190
4
.github/workflows/linux.yml
vendored
4
.github/workflows/linux.yml
vendored
@ -68,13 +68,13 @@ jobs:
|
|||||||
args: --all --all-features --no-fail-fast -- --nocapture
|
args: --all --all-features --no-fail-fast -- --nocapture
|
||||||
|
|
||||||
- name: Generate coverage file
|
- name: Generate coverage file
|
||||||
if: matrix.version == 'stable' && (github.ref == 'master' || github.event_name == 'pull_request')
|
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||||
run: |
|
run: |
|
||||||
cargo install cargo-tarpaulin --vers "^0.13"
|
cargo install cargo-tarpaulin --vers "^0.13"
|
||||||
cargo tarpaulin --out Xml --workspace --all-features
|
cargo tarpaulin --out Xml --workspace --all-features
|
||||||
|
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
if: matrix.version == 'stable' && (github.ref == 'master' || github.event_name == 'pull_request')
|
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v1
|
||||||
with:
|
with:
|
||||||
file: cobertura.xml
|
file: cobertura.xml
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
* Add method to set HttpOnly flag on cookie identity. [#102]
|
||||||
|
|
||||||
|
|
||||||
## 0.3.0 - 2020-09-11
|
## 0.3.0 - 2020-09-11
|
||||||
@ -24,3 +25,8 @@
|
|||||||
|
|
||||||
## 0.1.0 - 2019-06-xx
|
## 0.1.0 - 2019-06-xx
|
||||||
* Move identity middleware to separate crate
|
* Move identity middleware to separate crate
|
||||||
|
|
||||||
|
|
||||||
|
<!-- PR Links -->
|
||||||
|
|
||||||
|
[#102]: https://github.com/actix/actix-extras/pull/102
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![allow(clippy::needless_doctest_main)]
|
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -319,6 +318,7 @@ struct CookieIdentityInner {
|
|||||||
domain: Option<String>,
|
domain: Option<String>,
|
||||||
secure: bool,
|
secure: bool,
|
||||||
max_age: Option<Duration>,
|
max_age: Option<Duration>,
|
||||||
|
http_only: Option<bool>,
|
||||||
same_site: Option<SameSite>,
|
same_site: Option<SameSite>,
|
||||||
visit_deadline: Option<Duration>,
|
visit_deadline: Option<Duration>,
|
||||||
login_deadline: Option<Duration>,
|
login_deadline: Option<Duration>,
|
||||||
@ -327,14 +327,16 @@ struct CookieIdentityInner {
|
|||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
struct CookieValue {
|
struct CookieValue {
|
||||||
identity: String,
|
identity: String,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
login_timestamp: Option<SystemTime>,
|
login_timestamp: Option<SystemTime>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
visit_timestamp: Option<SystemTime>,
|
visit_timestamp: Option<SystemTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CookieIdentityExtention {
|
struct CookieIdentityExtension {
|
||||||
login_timestamp: Option<SystemTime>,
|
login_timestamp: Option<SystemTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +351,7 @@ impl CookieIdentityInner {
|
|||||||
domain: None,
|
domain: None,
|
||||||
secure: true,
|
secure: true,
|
||||||
max_age: None,
|
max_age: None,
|
||||||
|
http_only: None,
|
||||||
same_site: None,
|
same_site: None,
|
||||||
visit_deadline: None,
|
visit_deadline: None,
|
||||||
login_deadline: None,
|
login_deadline: None,
|
||||||
@ -382,6 +385,10 @@ impl CookieIdentityInner {
|
|||||||
cookie.set_max_age(max_age);
|
cookie.set_max_age(max_age);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(http_only) = self.http_only {
|
||||||
|
cookie.set_http_only(http_only);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(same_site) = self.same_site {
|
if let Some(same_site) = self.same_site {
|
||||||
cookie.set_same_site(same_site);
|
cookie.set_same_site(same_site);
|
||||||
}
|
}
|
||||||
@ -524,6 +531,12 @@ impl CookieIdentityPolicy {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the `http_only` field in the session cookie being built.
|
||||||
|
pub fn http_only(mut self, http_only: bool) -> Self {
|
||||||
|
Rc::get_mut(&mut self.0).unwrap().http_only = Some(http_only);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the `same_site` field in the session cookie being built.
|
/// Sets the `same_site` field in the session cookie being built.
|
||||||
pub fn same_site(mut self, same_site: SameSite) -> Self {
|
pub fn same_site(mut self, same_site: SameSite) -> Self {
|
||||||
Rc::get_mut(&mut self.0).unwrap().same_site = Some(same_site);
|
Rc::get_mut(&mut self.0).unwrap().same_site = Some(same_site);
|
||||||
@ -560,7 +573,7 @@ impl IdentityPolicy for CookieIdentityPolicy {
|
|||||||
}| {
|
}| {
|
||||||
if self.0.requires_oob_data() {
|
if self.0.requires_oob_data() {
|
||||||
req.extensions_mut()
|
req.extensions_mut()
|
||||||
.insert(CookieIdentityExtention { login_timestamp });
|
.insert(CookieIdentityExtension { login_timestamp });
|
||||||
}
|
}
|
||||||
identity
|
identity
|
||||||
},
|
},
|
||||||
@ -586,7 +599,7 @@ impl IdentityPolicy for CookieIdentityPolicy {
|
|||||||
} else if self.0.always_update_cookie() && id.is_some() {
|
} else if self.0.always_update_cookie() && id.is_some() {
|
||||||
let visit_timestamp = SystemTime::now();
|
let visit_timestamp = SystemTime::now();
|
||||||
let login_timestamp = if self.0.requires_oob_data() {
|
let login_timestamp = if self.0.requires_oob_data() {
|
||||||
let CookieIdentityExtention {
|
let CookieIdentityExtension {
|
||||||
login_timestamp: lt,
|
login_timestamp: lt,
|
||||||
} = res.request().extensions_mut().remove().unwrap();
|
} = res.request().extensions_mut().remove().unwrap();
|
||||||
lt
|
lt
|
||||||
@ -713,6 +726,37 @@ mod tests {
|
|||||||
assert_eq!(duration, c.max_age().unwrap());
|
assert_eq!(duration, c.max_age().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_http_only_same_site() {
|
||||||
|
let mut srv = test::init_service(
|
||||||
|
App::new()
|
||||||
|
.wrap(IdentityService::new(
|
||||||
|
CookieIdentityPolicy::new(&COOKIE_KEY_MASTER)
|
||||||
|
.domain("www.rust-lang.org")
|
||||||
|
.name(COOKIE_NAME)
|
||||||
|
.path("/")
|
||||||
|
.http_only(true)
|
||||||
|
.same_site(SameSite::None),
|
||||||
|
))
|
||||||
|
.service(web::resource("/login").to(|id: Identity| {
|
||||||
|
id.remember("test".to_string());
|
||||||
|
HttpResponse::Ok()
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let resp =
|
||||||
|
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
||||||
|
|
||||||
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
|
assert!(c.http_only().unwrap());
|
||||||
|
assert_eq!(SameSite::None, c.same_site().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_identity_max_age() {
|
async fn test_identity_max_age() {
|
||||||
let seconds = 60;
|
let seconds = 60;
|
||||||
|
Loading…
Reference in New Issue
Block a user