mirror of
https://github.com/actix/actix-web.git
synced 2024-12-21 07:36:43 +00:00
migrate actix-identity
This commit is contained in:
parent
ff62facc0d
commit
3646725cf6
3 changed files with 342 additions and 293 deletions
|
@ -35,7 +35,7 @@ members = [
|
||||||
#"actix-files",
|
#"actix-files",
|
||||||
#"actix-framed",
|
#"actix-framed",
|
||||||
#"actix-session",
|
#"actix-session",
|
||||||
#"actix-identity",
|
"actix-identity",
|
||||||
#"actix-multipart",
|
#"actix-multipart",
|
||||||
#"actix-web-actors",
|
#"actix-web-actors",
|
||||||
"actix-web-codegen",
|
"actix-web-codegen",
|
||||||
|
|
|
@ -17,14 +17,14 @@ name = "actix_identity"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = { version = "1.0.9", default-features = false, features = ["secure-cookies"] }
|
actix-web = { version = "2.0.0-alpha.1", default-features = false, features = ["secure-cookies"] }
|
||||||
actix-service = "0.4.2"
|
actix-service = "1.0.0-alpha.1"
|
||||||
futures = "0.3.1"
|
futures = "0.3.1"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "0.2.2"
|
actix-rt = "1.0.0-alpha.1"
|
||||||
actix-http = "0.2.11"
|
actix-http = "0.3.0-alpha.1"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
|
@ -47,12 +47,13 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::future::Future;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::task::{Context, Poll};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use actix_service::{Service, Transform};
|
use actix_service::{Service, Transform};
|
||||||
use futures::future::{ok, Either, FutureResult};
|
use futures::future::{ok, FutureExt, LocalBoxFuture, Ready};
|
||||||
use futures::{Future, IntoFuture, Poll};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
|
|
||||||
|
@ -165,21 +166,21 @@ where
|
||||||
impl FromRequest for Identity {
|
impl FromRequest for Identity {
|
||||||
type Config = ();
|
type Config = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = Result<Identity, Error>;
|
type Future = Ready<Result<Identity, Error>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||||
Ok(Identity(req.clone()))
|
ok(Identity(req.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Identity policy definition.
|
/// Identity policy definition.
|
||||||
pub trait IdentityPolicy: Sized + 'static {
|
pub trait IdentityPolicy: Sized + 'static {
|
||||||
/// The return type of the middleware
|
/// The return type of the middleware
|
||||||
type Future: IntoFuture<Item = Option<String>, Error = Error>;
|
type Future: Future<Output = Result<Option<String>, Error>>;
|
||||||
|
|
||||||
/// The return type of the middleware
|
/// The return type of the middleware
|
||||||
type ResponseFuture: IntoFuture<Item = (), Error = Error>;
|
type ResponseFuture: Future<Output = Result<(), Error>>;
|
||||||
|
|
||||||
/// Parse the session from request and load data from a service identity.
|
/// Parse the session from request and load data from a service identity.
|
||||||
fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
|
fn from_request(&self, request: &mut ServiceRequest) -> Self::Future;
|
||||||
|
@ -234,7 +235,7 @@ where
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Transform = IdentityServiceMiddleware<S, T>;
|
type Transform = IdentityServiceMiddleware<S, T>;
|
||||||
type Future = FutureResult<Self::Transform, Self::InitError>;
|
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||||
|
|
||||||
fn new_transform(&self, service: S) -> Self::Future {
|
fn new_transform(&self, service: S) -> Self::Future {
|
||||||
ok(IdentityServiceMiddleware {
|
ok(IdentityServiceMiddleware {
|
||||||
|
@ -261,46 +262,39 @@ where
|
||||||
type Request = ServiceRequest;
|
type Request = ServiceRequest;
|
||||||
type Response = ServiceResponse<B>;
|
type Response = ServiceResponse<B>;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;
|
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
|
||||||
self.service.borrow_mut().poll_ready()
|
self.service.borrow_mut().poll_ready(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
|
||||||
let srv = self.service.clone();
|
let srv = self.service.clone();
|
||||||
let backend = self.backend.clone();
|
let backend = self.backend.clone();
|
||||||
|
let fut = self.backend.from_request(&mut req);
|
||||||
|
|
||||||
Box::new(
|
async move {
|
||||||
self.backend.from_request(&mut req).into_future().then(
|
match fut.await {
|
||||||
move |res| match res {
|
|
||||||
Ok(id) => {
|
Ok(id) => {
|
||||||
req.extensions_mut()
|
req.extensions_mut()
|
||||||
.insert(IdentityItem { id, changed: false });
|
.insert(IdentityItem { id, changed: false });
|
||||||
|
|
||||||
Either::A(srv.borrow_mut().call(req).and_then(move |mut res| {
|
let mut res = srv.borrow_mut().call(req).await?;
|
||||||
let id =
|
let id = res.request().extensions_mut().remove::<IdentityItem>();
|
||||||
res.request().extensions_mut().remove::<IdentityItem>();
|
|
||||||
|
|
||||||
if let Some(id) = id {
|
if let Some(id) = id {
|
||||||
Either::A(
|
match backend.to_response(id.id, id.changed, &mut res).await {
|
||||||
backend
|
|
||||||
.to_response(id.id, id.changed, &mut res)
|
|
||||||
.into_future()
|
|
||||||
.then(move |t| match t {
|
|
||||||
Ok(_) => Ok(res),
|
Ok(_) => Ok(res),
|
||||||
Err(e) => Ok(res.error_response(e)),
|
Err(e) => Ok(res.error_response(e)),
|
||||||
}),
|
}
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Either::B(ok(res))
|
Ok(res)
|
||||||
}
|
}
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
Err(err) => Either::B(ok(req.error_response(err))),
|
Err(err) => Ok(req.error_response(err)),
|
||||||
},
|
}
|
||||||
),
|
}
|
||||||
)
|
.boxed_local()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,11 +541,11 @@ impl CookieIdentityPolicy {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdentityPolicy for CookieIdentityPolicy {
|
impl IdentityPolicy for CookieIdentityPolicy {
|
||||||
type Future = Result<Option<String>, Error>;
|
type Future = Ready<Result<Option<String>, Error>>;
|
||||||
type ResponseFuture = Result<(), Error>;
|
type ResponseFuture = Ready<Result<(), Error>>;
|
||||||
|
|
||||||
fn from_request(&self, req: &mut ServiceRequest) -> Self::Future {
|
fn from_request(&self, req: &mut ServiceRequest) -> Self::Future {
|
||||||
Ok(self.0.load(req).map(
|
ok(self.0.load(req).map(
|
||||||
|CookieValue {
|
|CookieValue {
|
||||||
identity,
|
identity,
|
||||||
login_timestamp,
|
login_timestamp,
|
||||||
|
@ -603,7 +597,7 @@ impl IdentityPolicy for CookieIdentityPolicy {
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
Ok(())
|
ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +607,7 @@ mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
use actix_web::test::{self, TestRequest};
|
use actix_web::test::{self, block_on, TestRequest};
|
||||||
use actix_web::{web, App, Error, HttpResponse};
|
use actix_web::{web, App, Error, HttpResponse};
|
||||||
|
|
||||||
const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
|
const COOKIE_KEY_MASTER: [u8; 32] = [0; 32];
|
||||||
|
@ -622,6 +616,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity() {
|
fn test_identity() {
|
||||||
|
block_on(async {
|
||||||
let mut srv = test::init_service(
|
let mut srv = test::init_service(
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(IdentityService::new(
|
.wrap(IdentityService::new(
|
||||||
|
@ -650,13 +645,20 @@ mod tests {
|
||||||
HttpResponse::BadRequest()
|
HttpResponse::BadRequest()
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
);
|
)
|
||||||
let resp =
|
.await;
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/index").to_request());
|
let resp = test::call_service(
|
||||||
|
&mut srv,
|
||||||
|
TestRequest::with_uri("/index").to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
let resp =
|
let resp = test::call_service(
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request());
|
&mut srv,
|
||||||
|
TestRequest::with_uri("/login").to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
let c = resp.response().cookies().next().unwrap().to_owned();
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
|
|
||||||
|
@ -665,7 +667,8 @@ mod tests {
|
||||||
TestRequest::with_uri("/index")
|
TestRequest::with_uri("/index")
|
||||||
.cookie(c.clone())
|
.cookie(c.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::CREATED);
|
assert_eq!(resp.status(), StatusCode::CREATED);
|
||||||
|
|
||||||
let resp = test::call_service(
|
let resp = test::call_service(
|
||||||
|
@ -673,13 +676,16 @@ mod tests {
|
||||||
TestRequest::with_uri("/logout")
|
TestRequest::with_uri("/logout")
|
||||||
.cookie(c.clone())
|
.cookie(c.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert!(resp.headers().contains_key(header::SET_COOKIE))
|
assert!(resp.headers().contains_key(header::SET_COOKIE))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_max_age_time() {
|
fn test_identity_max_age_time() {
|
||||||
|
block_on(async {
|
||||||
let duration = Duration::days(1);
|
let duration = Duration::days(1);
|
||||||
let mut srv = test::init_service(
|
let mut srv = test::init_service(
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -695,17 +701,23 @@ mod tests {
|
||||||
id.remember("test".to_string());
|
id.remember("test".to_string());
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
})),
|
})),
|
||||||
);
|
)
|
||||||
let resp =
|
.await;
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request());
|
let resp = test::call_service(
|
||||||
|
&mut srv,
|
||||||
|
TestRequest::with_uri("/login").to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
||||||
let c = resp.response().cookies().next().unwrap().to_owned();
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
assert_eq!(duration, c.max_age().unwrap());
|
assert_eq!(duration, c.max_age().unwrap());
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_max_age() {
|
fn test_identity_max_age() {
|
||||||
|
block_on(async {
|
||||||
let seconds = 60;
|
let seconds = 60;
|
||||||
let mut srv = test::init_service(
|
let mut srv = test::init_service(
|
||||||
App::new()
|
App::new()
|
||||||
|
@ -721,16 +733,21 @@ mod tests {
|
||||||
id.remember("test".to_string());
|
id.remember("test".to_string());
|
||||||
HttpResponse::Ok()
|
HttpResponse::Ok()
|
||||||
})),
|
})),
|
||||||
);
|
)
|
||||||
let resp =
|
.await;
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/login").to_request());
|
let resp = test::call_service(
|
||||||
|
&mut srv,
|
||||||
|
TestRequest::with_uri("/login").to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert_eq!(resp.status(), StatusCode::OK);
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
assert!(resp.headers().contains_key(header::SET_COOKIE));
|
||||||
let c = resp.response().cookies().next().unwrap().to_owned();
|
let c = resp.response().cookies().next().unwrap().to_owned();
|
||||||
assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap());
|
assert_eq!(Duration::seconds(seconds as i64), c.max_age().unwrap());
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_identity_server<
|
async fn create_identity_server<
|
||||||
F: Fn(CookieIdentityPolicy) -> CookieIdentityPolicy + Sync + Send + Clone + 'static,
|
F: Fn(CookieIdentityPolicy) -> CookieIdentityPolicy + Sync + Send + Clone + 'static,
|
||||||
>(
|
>(
|
||||||
f: F,
|
f: F,
|
||||||
|
@ -754,6 +771,7 @@ mod tests {
|
||||||
web::Json(identity)
|
web::Json(identity)
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn legacy_login_cookie(identity: &'static str) -> Cookie<'static> {
|
fn legacy_login_cookie(identity: &'static str) -> Cookie<'static> {
|
||||||
|
@ -786,15 +804,8 @@ mod tests {
|
||||||
jar.get(COOKIE_NAME).unwrap().clone()
|
jar.get(COOKIE_NAME).unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_logged_in(response: &mut ServiceResponse, identity: Option<&str>) {
|
async fn assert_logged_in(response: ServiceResponse, identity: Option<&str>) {
|
||||||
use bytes::BytesMut;
|
let bytes = test::read_body(response).await;
|
||||||
use futures::Stream;
|
|
||||||
let bytes =
|
|
||||||
test::block_on(response.take_body().fold(BytesMut::new(), |mut b, c| {
|
|
||||||
b.extend(c);
|
|
||||||
Ok::<_, Error>(b)
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
let resp: Option<String> = serde_json::from_slice(&bytes[..]).unwrap();
|
let resp: Option<String> = serde_json::from_slice(&bytes[..]).unwrap();
|
||||||
assert_eq!(resp.as_ref().map(|s| s.borrow()), identity);
|
assert_eq!(resp.as_ref().map(|s| s.borrow()), identity);
|
||||||
}
|
}
|
||||||
|
@ -874,106 +885,130 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_legacy_cookie_is_set() {
|
fn test_identity_legacy_cookie_is_set() {
|
||||||
let mut srv = create_identity_server(|c| c);
|
block_on(async {
|
||||||
|
let mut srv = create_identity_server(|c| c).await;
|
||||||
let mut resp =
|
let mut resp =
|
||||||
test::call_service(&mut srv, TestRequest::with_uri("/").to_request());
|
test::call_service(&mut srv, TestRequest::with_uri("/").to_request())
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN);
|
assert_legacy_login_cookie(&mut resp, COOKIE_LOGIN);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_legacy_cookie_works() {
|
fn test_identity_legacy_cookie_works() {
|
||||||
let mut srv = create_identity_server(|c| c);
|
block_on(async {
|
||||||
|
let mut srv = create_identity_server(|c| c).await;
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, Some(COOKIE_LOGIN));
|
.await;
|
||||||
assert_no_login_cookie(&mut resp);
|
assert_no_login_cookie(&mut resp);
|
||||||
|
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() {
|
fn test_identity_legacy_cookie_rejected_if_visit_timestamp_needed() {
|
||||||
let mut srv = create_identity_server(|c| c.visit_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() {
|
fn test_identity_legacy_cookie_rejected_if_login_timestamp_needed() {
|
||||||
let mut srv = create_identity_server(|c| c.login_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
let cookie = legacy_login_cookie(COOKIE_LOGIN);
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_rejected_if_login_timestamp_needed() {
|
fn test_identity_cookie_rejected_if_login_timestamp_needed() {
|
||||||
let mut srv = create_identity_server(|c| c.login_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now()));
|
let cookie = login_cookie(COOKIE_LOGIN, None, Some(SystemTime::now()));
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_rejected_if_visit_timestamp_needed() {
|
fn test_identity_cookie_rejected_if_visit_timestamp_needed() {
|
||||||
let mut srv = create_identity_server(|c| c.visit_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_rejected_if_login_timestamp_too_old() {
|
fn test_identity_cookie_rejected_if_login_timestamp_too_old() {
|
||||||
let mut srv = create_identity_server(|c| c.login_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
let cookie = login_cookie(
|
let cookie = login_cookie(
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
Some(SystemTime::now() - Duration::days(180).to_std().unwrap()),
|
||||||
|
@ -984,19 +1019,23 @@ mod tests {
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NewTimestamp,
|
LoginTimestampCheck::NewTimestamp,
|
||||||
VisitTimeStampCheck::NoTimestamp,
|
VisitTimeStampCheck::NoTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_rejected_if_visit_timestamp_too_old() {
|
fn test_identity_cookie_rejected_if_visit_timestamp_too_old() {
|
||||||
let mut srv = create_identity_server(|c| c.visit_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.visit_deadline(Duration::days(90))).await;
|
||||||
let cookie = login_cookie(
|
let cookie = login_cookie(
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
None,
|
None,
|
||||||
|
@ -1007,36 +1046,44 @@ mod tests {
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, None);
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::NoTimestamp,
|
LoginTimestampCheck::NoTimestamp,
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, None).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_not_updated_on_login_deadline() {
|
fn test_identity_cookie_not_updated_on_login_deadline() {
|
||||||
let mut srv = create_identity_server(|c| c.login_deadline(Duration::days(90)));
|
block_on(async {
|
||||||
|
let mut srv =
|
||||||
|
create_identity_server(|c| c.login_deadline(Duration::days(90))).await;
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
let cookie = login_cookie(COOKIE_LOGIN, Some(SystemTime::now()), None);
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
&mut srv,
|
&mut srv,
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, Some(COOKIE_LOGIN));
|
.await;
|
||||||
assert_no_login_cookie(&mut resp);
|
assert_no_login_cookie(&mut resp);
|
||||||
|
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_identity_cookie_updated_on_visit_deadline() {
|
fn test_identity_cookie_updated_on_visit_deadline() {
|
||||||
|
block_on(async {
|
||||||
let mut srv = create_identity_server(|c| {
|
let mut srv = create_identity_server(|c| {
|
||||||
c.visit_deadline(Duration::days(90))
|
c.visit_deadline(Duration::days(90))
|
||||||
.login_deadline(Duration::days(90))
|
.login_deadline(Duration::days(90))
|
||||||
});
|
})
|
||||||
|
.await;
|
||||||
let timestamp = SystemTime::now() - Duration::days(1).to_std().unwrap();
|
let timestamp = SystemTime::now() - Duration::days(1).to_std().unwrap();
|
||||||
let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp));
|
let cookie = login_cookie(COOKIE_LOGIN, Some(timestamp), Some(timestamp));
|
||||||
let mut resp = test::call_service(
|
let mut resp = test::call_service(
|
||||||
|
@ -1044,13 +1091,15 @@ mod tests {
|
||||||
TestRequest::with_uri("/")
|
TestRequest::with_uri("/")
|
||||||
.cookie(cookie.clone())
|
.cookie(cookie.clone())
|
||||||
.to_request(),
|
.to_request(),
|
||||||
);
|
)
|
||||||
assert_logged_in(&mut resp, Some(COOKIE_LOGIN));
|
.await;
|
||||||
assert_login_cookie(
|
assert_login_cookie(
|
||||||
&mut resp,
|
&mut resp,
|
||||||
COOKIE_LOGIN,
|
COOKIE_LOGIN,
|
||||||
LoginTimestampCheck::OldTimestamp(timestamp),
|
LoginTimestampCheck::OldTimestamp(timestamp),
|
||||||
VisitTimeStampCheck::NewTimestamp,
|
VisitTimeStampCheck::NewTimestamp,
|
||||||
);
|
);
|
||||||
|
assert_logged_in(resp, Some(COOKIE_LOGIN)).await;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue