authentication middleware handles redirects
This commit is contained in:
parent
f10c620040
commit
4158147f84
10 changed files with 294 additions and 50 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -2679,6 +2679,7 @@ dependencies = [
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
|
"urlencoding",
|
||||||
"uuid",
|
"uuid",
|
||||||
"validator",
|
"validator",
|
||||||
]
|
]
|
||||||
|
@ -2963,6 +2964,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlencoding"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "utf-8"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
|
|
@ -54,6 +54,7 @@ log = "0.4"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
|
||||||
url = "2.2"
|
url = "2.2"
|
||||||
|
urlencoding = "2.1.0"
|
||||||
|
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
uuid = { version="0.8.2", features = ["v4"]}
|
uuid = { version="0.8.2", features = ["v4"]}
|
||||||
|
|
|
@ -25,12 +25,29 @@ use crate::errors::*;
|
||||||
use crate::AppData;
|
use crate::AppData;
|
||||||
|
|
||||||
pub mod routes {
|
pub mod routes {
|
||||||
|
use crate::middleware::auth::GetLoginRoute;
|
||||||
|
use url::Url;
|
||||||
pub struct Auth {
|
pub struct Auth {
|
||||||
pub logout: &'static str,
|
pub logout: &'static str,
|
||||||
pub login: &'static str,
|
pub login: &'static str,
|
||||||
pub register: &'static str,
|
pub register: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetLoginRoute for Auth {
|
||||||
|
fn get_login_route(&self, src: Option<&str>) -> String {
|
||||||
|
if let Some(redirect_to) = src {
|
||||||
|
let mut url = Url::parse("http://x/").unwrap();
|
||||||
|
url.set_path(self.login);
|
||||||
|
url.query_pairs_mut()
|
||||||
|
.append_pair("redirect_to", redirect_to);
|
||||||
|
let path = format!("{}/?{}", url.path(), url.query().unwrap());
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
self.login.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Auth {
|
impl Auth {
|
||||||
pub const fn new() -> Auth {
|
pub const fn new() -> Auth {
|
||||||
let login = "/api/v1/admin/signin";
|
let login = "/api/v1/admin/signin";
|
||||||
|
|
|
@ -51,7 +51,7 @@ pub mod runners {
|
||||||
let mut uuid;
|
let mut uuid;
|
||||||
let now = OffsetDateTime::now_utc();
|
let now = OffsetDateTime::now_utc();
|
||||||
|
|
||||||
payload.difficulties.sort();
|
payload.difficulties.sort_unstable();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
uuid = get_uuid();
|
uuid = get_uuid();
|
||||||
|
@ -121,11 +121,45 @@ async fn add(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::api::v1::bench::{Bench, Submission};
|
use crate::api::v1::bench::Submission;
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
|
use crate::middleware::auth::GetLoginRoute;
|
||||||
use crate::tests::*;
|
use crate::tests::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
use actix_web::{http::header, test};
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_bench_register_works() {
|
||||||
|
let data = Data::new().await;
|
||||||
|
let app = get_app!(data).await;
|
||||||
|
let signin_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
test::TestRequest::get()
|
||||||
|
.uri(V1_API_ROUTES.benches.register)
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(signin_resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
let redirect_to = Some("foo");
|
||||||
|
|
||||||
|
let signin_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
test::TestRequest::get()
|
||||||
|
.uri(&V1_API_ROUTES.benches.get_login_route(redirect_to))
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(signin_resp.status(), StatusCode::FOUND);
|
||||||
|
let headers = signin_resp.headers();
|
||||||
|
assert_eq!(
|
||||||
|
headers.get(header::LOCATION).unwrap(),
|
||||||
|
redirect_to.as_ref().unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_add_campaign() {
|
async fn test_add_campaign() {
|
||||||
const NAME: &str = "testadminuser";
|
const NAME: &str = "testadminuser";
|
||||||
|
@ -136,29 +170,6 @@ mod tests {
|
||||||
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
|
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
|
||||||
const THREADS: i32 = 4;
|
const THREADS: i32 = 4;
|
||||||
|
|
||||||
let benches = vec![
|
|
||||||
Bench {
|
|
||||||
difficulty: 1,
|
|
||||||
duration: 1.00,
|
|
||||||
},
|
|
||||||
Bench {
|
|
||||||
difficulty: 2,
|
|
||||||
duration: 2.00,
|
|
||||||
},
|
|
||||||
Bench {
|
|
||||||
difficulty: 3,
|
|
||||||
duration: 3.00,
|
|
||||||
},
|
|
||||||
Bench {
|
|
||||||
difficulty: 4,
|
|
||||||
duration: 4.00,
|
|
||||||
},
|
|
||||||
Bench {
|
|
||||||
difficulty: 5,
|
|
||||||
duration: 5.00,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let data = Data::new().await;
|
let data = Data::new().await;
|
||||||
delete_user(NAME, &data).await;
|
delete_user(NAME, &data).await;
|
||||||
|
@ -181,7 +192,7 @@ mod tests {
|
||||||
device_user_provided: DEVICE_USER_PROVIDED.into(),
|
device_user_provided: DEVICE_USER_PROVIDED.into(),
|
||||||
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
|
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
|
||||||
threads: THREADS,
|
threads: THREADS,
|
||||||
benches: benches.clone(),
|
benches: BENCHES.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let _proof =
|
let _proof =
|
||||||
|
|
|
@ -30,8 +30,8 @@ pub fn services(cfg: &mut ServiceConfig) {
|
||||||
campaigns::services(cfg);
|
campaigns::services(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_admin_check_login() -> crate::CheckLogin {
|
pub fn get_admin_check_login() -> crate::CheckLogin<auth::routes::Auth> {
|
||||||
crate::CheckLogin::new(crate::V1_API_ROUTES.admin.auth.register)
|
crate::CheckLogin::new(crate::V1_API_ROUTES.admin.auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod routes {
|
pub mod routes {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use std::borrow::Cow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use actix_identity::Identity;
|
use actix_identity::Identity;
|
||||||
use actix_web::{web, HttpResponse, Responder};
|
use actix_web::{http, web, HttpResponse, Responder};
|
||||||
use futures::future::try_join_all;
|
use futures::future::try_join_all;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::types::time::OffsetDateTime;
|
use sqlx::types::time::OffsetDateTime;
|
||||||
|
@ -29,6 +29,9 @@ use crate::errors::*;
|
||||||
use crate::AppData;
|
use crate::AppData;
|
||||||
|
|
||||||
pub mod routes {
|
pub mod routes {
|
||||||
|
|
||||||
|
use crate::middleware::auth::GetLoginRoute;
|
||||||
|
|
||||||
pub struct Benches {
|
pub struct Benches {
|
||||||
pub submit: &'static str,
|
pub submit: &'static str,
|
||||||
pub register: &'static str,
|
pub register: &'static str,
|
||||||
|
@ -36,6 +39,25 @@ pub mod routes {
|
||||||
pub scope: &'static str,
|
pub scope: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetLoginRoute for Benches {
|
||||||
|
fn get_login_route(&self, src: Option<&str>) -> String {
|
||||||
|
if let Some(redirect_to) = src {
|
||||||
|
// uri::Builder::new().path_and_query(
|
||||||
|
format!(
|
||||||
|
"{}?redirect_to={}",
|
||||||
|
self.register,
|
||||||
|
urlencoding::encode(redirect_to)
|
||||||
|
)
|
||||||
|
// let mut url: Uri = self.register.parse().unwrap();
|
||||||
|
// url.qu
|
||||||
|
// url.query_pairs_mut()
|
||||||
|
// .append_pair("redirect_to", redirect_to);
|
||||||
|
} else {
|
||||||
|
self.register.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Benches {
|
impl Benches {
|
||||||
pub const fn new() -> Benches {
|
pub const fn new() -> Benches {
|
||||||
let submit = "/api/v1/benches/{campaign_id}/submit";
|
let submit = "/api/v1/benches/{campaign_id}/submit";
|
||||||
|
@ -50,10 +72,10 @@ pub mod routes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn submit_route(&self, campaign_id: &str) -> String {
|
pub fn submit_route(&self, campaign_id: &str) -> String {
|
||||||
self.submit.replace("{campaign_id}", &campaign_id)
|
self.submit.replace("{campaign_id}", campaign_id)
|
||||||
}
|
}
|
||||||
pub fn fetch_routes(&self, campaign_id: &str) -> String {
|
pub fn fetch_routes(&self, campaign_id: &str) -> String {
|
||||||
self.fetch.replace("{campaign_id}", &campaign_id)
|
self.fetch.replace("{campaign_id}", campaign_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,11 +121,27 @@ pub mod runners {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Query {
|
||||||
|
pub redirect_to: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[my_codegen::get(path = "crate::V1_API_ROUTES.benches.register")]
|
#[my_codegen::get(path = "crate::V1_API_ROUTES.benches.register")]
|
||||||
async fn register(data: AppData, id: Identity) -> ServiceResult<impl Responder> {
|
async fn register(
|
||||||
|
data: AppData,
|
||||||
|
id: Identity,
|
||||||
|
path: web::Query<Query>,
|
||||||
|
) -> ServiceResult<HttpResponse> {
|
||||||
let uuid = runners::register_runner(&data).await?;
|
let uuid = runners::register_runner(&data).await?;
|
||||||
id.remember(uuid.to_string());
|
id.remember(uuid.to_string());
|
||||||
Ok(HttpResponse::Ok())
|
let path = path.into_inner();
|
||||||
|
if let Some(redirect_to) = path.redirect_to {
|
||||||
|
Ok(HttpResponse::Found()
|
||||||
|
.insert_header((http::header::LOCATION, redirect_to))
|
||||||
|
.finish())
|
||||||
|
} else {
|
||||||
|
Ok(HttpResponse::Ok().into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -126,8 +164,8 @@ pub struct SubmissionProof {
|
||||||
pub proof: String,
|
pub proof: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_check_login() -> crate::CheckLogin {
|
fn get_check_login() -> crate::CheckLogin<routes::Benches> {
|
||||||
crate::CheckLogin::new(crate::V1_API_ROUTES.benches.register)
|
crate::CheckLogin::new(crate::V1_API_ROUTES.benches)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[my_codegen::post(
|
#[my_codegen::post(
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use actix_http::body::AnyBody;
|
use actix_http::body::AnyBody;
|
||||||
use actix_identity::Identity;
|
use actix_identity::Identity;
|
||||||
use actix_service::{Service, Transform};
|
use actix_service::{Service, Transform};
|
||||||
|
@ -24,43 +26,50 @@ use actix_web::{http, Error, FromRequest, HttpResponse};
|
||||||
|
|
||||||
use futures::future::{ok, Either, Ready};
|
use futures::future::{ok, Either, Ready};
|
||||||
|
|
||||||
pub struct CheckLogin {
|
pub trait GetLoginRoute {
|
||||||
login: &'static str,
|
fn get_login_route(&self, src: Option<&str>) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckLogin {
|
pub struct CheckLogin<T: GetLoginRoute> {
|
||||||
pub fn new(login: &'static str) -> Self {
|
login: Rc<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: GetLoginRoute> CheckLogin<T> {
|
||||||
|
pub fn new(login: T) -> Self {
|
||||||
|
let login = Rc::new(login);
|
||||||
Self { login }
|
Self { login }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Transform<S, ServiceRequest> for CheckLogin
|
impl<S, GT> Transform<S, ServiceRequest> for CheckLogin<GT>
|
||||||
where
|
where
|
||||||
S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
|
S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
|
GT: GetLoginRoute,
|
||||||
{
|
{
|
||||||
type Response = ServiceResponse<AnyBody>;
|
type Response = ServiceResponse<AnyBody>;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Transform = CheckLoginMiddleware<S>;
|
type Transform = CheckLoginMiddleware<S, GT>;
|
||||||
type InitError = ();
|
type InitError = ();
|
||||||
type Future = Ready<Result<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(CheckLoginMiddleware {
|
ok(CheckLoginMiddleware {
|
||||||
service,
|
service,
|
||||||
login: self.login,
|
login: self.login.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct CheckLoginMiddleware<S> {
|
pub struct CheckLoginMiddleware<S, GT> {
|
||||||
service: S,
|
service: S,
|
||||||
login: &'static str,
|
login: Rc<GT>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Service<ServiceRequest> for CheckLoginMiddleware<S>
|
impl<S, GT> Service<ServiceRequest> for CheckLoginMiddleware<S, GT>
|
||||||
where
|
where
|
||||||
S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
|
S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
|
GT: GetLoginRoute,
|
||||||
{
|
{
|
||||||
type Response = ServiceResponse<AnyBody>;
|
type Response = ServiceResponse<AnyBody>;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
@ -80,12 +89,134 @@ where
|
||||||
let req = ServiceRequest::from_parts(r, pl);
|
let req = ServiceRequest::from_parts(r, pl);
|
||||||
Either::Left(self.service.call(req))
|
Either::Left(self.service.call(req))
|
||||||
} else {
|
} else {
|
||||||
let req = ServiceRequest::from_parts(r, pl); //.ok().unwrap();
|
let path = r.uri().path_and_query().map(|path| path.as_str());
|
||||||
|
let path = self.login.get_login_route(path);
|
||||||
|
let req = ServiceRequest::from_parts(r, pl);
|
||||||
Either::Right(ok(req.into_response(
|
Either::Right(ok(req.into_response(
|
||||||
HttpResponse::Found()
|
HttpResponse::Found()
|
||||||
.insert_header((http::header::LOCATION, self.login))
|
.insert_header((http::header::LOCATION, path))
|
||||||
.finish(),
|
.finish(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use crate::api::v1::bench::Submission;
|
||||||
|
use crate::data::Data;
|
||||||
|
use crate::middleware::auth::GetLoginRoute;
|
||||||
|
use crate::tests::*;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
use actix_web::{http::header, test};
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn auth_middleware_works() {
|
||||||
|
fn make_uri(path: &str, queries: &Option<Vec<(&str, &str)>>) -> String {
|
||||||
|
let mut url = Url::parse("http://x/").unwrap();
|
||||||
|
let final_path;
|
||||||
|
url.set_path(path);
|
||||||
|
|
||||||
|
if let Some(queries) = queries {
|
||||||
|
{
|
||||||
|
let mut query_pairs = url.query_pairs_mut();
|
||||||
|
queries.iter().for_each(|(k, v)| {
|
||||||
|
query_pairs.append_pair(k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
final_path = format!("{}?{}", url.path(), url.query().unwrap());
|
||||||
|
} else {
|
||||||
|
final_path = url.path().to_string();
|
||||||
|
}
|
||||||
|
final_path
|
||||||
|
}
|
||||||
|
|
||||||
|
const NAME: &str = "testmiddlewareuser";
|
||||||
|
const EMAIL: &str = "testuserupda@testmiddlewareuser.com";
|
||||||
|
const PASSWORD: &str = "longpassword2";
|
||||||
|
const DEVICE_USER_PROVIDED: &str = "foo";
|
||||||
|
const DEVICE_SOFTWARE_RECOGNISED: &str = "Foobar.v2";
|
||||||
|
const THREADS: i32 = 4;
|
||||||
|
let queries = Some(vec![
|
||||||
|
("foo", "bar"),
|
||||||
|
("src", "/x/y/z"),
|
||||||
|
("with_q", "/a/b/c/?goo=x"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
{
|
||||||
|
let data = Data::new().await;
|
||||||
|
delete_user(NAME, &data).await;
|
||||||
|
}
|
||||||
|
let (data, _creds, signin_resp) =
|
||||||
|
register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
|
let cookies = get_cookie!(signin_resp);
|
||||||
|
let survey = get_survey_user(data.clone()).await;
|
||||||
|
let survey_cookie = get_cookie!(survey);
|
||||||
|
|
||||||
|
let campaign = create_new_campaign(NAME, data.clone(), cookies.clone()).await;
|
||||||
|
|
||||||
|
let bench_submit_route =
|
||||||
|
V1_API_ROUTES.benches.submit_route(&campaign.campaign_id);
|
||||||
|
let bench_routes = vec![
|
||||||
|
(&bench_submit_route, queries.clone()),
|
||||||
|
(&bench_submit_route, None),
|
||||||
|
];
|
||||||
|
|
||||||
|
let app = get_app!(data).await;
|
||||||
|
|
||||||
|
// let campaign_routes = vec![
|
||||||
|
// (Some(V1_API_ROUTES.camp.submit), queries.clone()),
|
||||||
|
// (None, None),
|
||||||
|
// (Some(V1_API_ROUTES.benches.submit), None),
|
||||||
|
// ];
|
||||||
|
|
||||||
|
let bench_submit_payload = Submission {
|
||||||
|
device_user_provided: DEVICE_USER_PROVIDED.into(),
|
||||||
|
device_software_recognised: DEVICE_SOFTWARE_RECOGNISED.into(),
|
||||||
|
threads: THREADS,
|
||||||
|
benches: BENCHES.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (from, query) in bench_routes.iter() {
|
||||||
|
let route = make_uri(from, query);
|
||||||
|
let signin_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
post_request!(&bench_submit_payload, &route).to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(signin_resp.status(), StatusCode::FOUND);
|
||||||
|
|
||||||
|
let redirect_to = V1_API_ROUTES.benches.get_login_route(Some(&route));
|
||||||
|
let headers = signin_resp.headers();
|
||||||
|
assert_eq!(headers.get(header::LOCATION).unwrap(), &redirect_to);
|
||||||
|
|
||||||
|
let add_feedback_resp = test::call_service(
|
||||||
|
&app,
|
||||||
|
post_request!(&bench_submit_payload, &route)
|
||||||
|
.cookie(survey_cookie.clone())
|
||||||
|
.to_request(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert_eq!(add_feedback_resp.status(), StatusCode::OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let signin_resp = test::call_service(
|
||||||
|
// &app,
|
||||||
|
// test::TestRequest::get()
|
||||||
|
// .uri(V1_API_ROUTES.benches.get_login_route(redirect_to).as_ref().unwrap())
|
||||||
|
// .to_request(),
|
||||||
|
// )
|
||||||
|
// .await;
|
||||||
|
// assert_eq!(signin_resp.status(), StatusCode::FOUND);
|
||||||
|
// let headers = signin_resp.headers();
|
||||||
|
// assert_eq!(
|
||||||
|
// headers.get(header::LOCATION).unwrap(),
|
||||||
|
// redirect_to.as_ref().unwrap()
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
|
@ -126,8 +126,8 @@ mod tests {
|
||||||
for file in [
|
for file in [
|
||||||
assets::LOGO.path,
|
assets::LOGO.path,
|
||||||
assets::HEADSETS.path,
|
assets::HEADSETS.path,
|
||||||
&*crate::JS,
|
*crate::JS,
|
||||||
&*crate::GLUE,
|
*crate::GLUE,
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
{
|
{
|
||||||
|
|
28
src/tests.rs
28
src/tests.rs
|
@ -20,6 +20,7 @@ use std::sync::Arc;
|
||||||
use actix_web::cookie::Cookie;
|
use actix_web::cookie::Cookie;
|
||||||
use actix_web::test;
|
use actix_web::test;
|
||||||
use actix_web::{dev::ServiceResponse, error::ResponseError, http::StatusCode};
|
use actix_web::{dev::ServiceResponse, error::ResponseError, http::StatusCode};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ use crate::api::v1::admin::{
|
||||||
auth::runners::{Login, Register},
|
auth::runners::{Login, Register},
|
||||||
campaigns::{AddCapmaign, AddCapmaignResp},
|
campaigns::{AddCapmaign, AddCapmaignResp},
|
||||||
};
|
};
|
||||||
use crate::api::v1::bench::{BenchConfig, Submission, SubmissionProof};
|
use crate::api::v1::bench::{Bench, BenchConfig, Submission, SubmissionProof};
|
||||||
use crate::data::Data;
|
use crate::data::Data;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::V1_API_ROUTES;
|
use crate::V1_API_ROUTES;
|
||||||
|
@ -396,3 +397,28 @@ pub async fn submit_bench(
|
||||||
// assert_eq!(get_feedback_resp.status(), StatusCode::OK);
|
// assert_eq!(get_feedback_resp.status(), StatusCode::OK);
|
||||||
// test::read_body_json(get_feedback_resp).await
|
// test::read_body_json(get_feedback_resp).await
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref BENCHES: Vec<Bench> = vec![
|
||||||
|
Bench {
|
||||||
|
difficulty: 1,
|
||||||
|
duration: 1.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 2,
|
||||||
|
duration: 2.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 3,
|
||||||
|
duration: 3.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 4,
|
||||||
|
duration: 4.00,
|
||||||
|
},
|
||||||
|
Bench {
|
||||||
|
difficulty: 5,
|
||||||
|
duration: 5.00,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
13
templates/vendor.ts
Normal file
13
templates/vendor.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* mCaptcha is a PoW based DoS protection software.
|
||||||
|
* This is the frontend web component of the mCaptcha system
|
||||||
|
* Copyright © 2021 Aravinth Manivnanan <realaravinth@batsense.net>.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by Apache 2.0 or MIT license.
|
||||||
|
* You shoud have received a copy of MIT and Apache 2.0 along with
|
||||||
|
* this program. If not, see <https://spdx.org/licenses/MIT.html> for
|
||||||
|
* MIT or <http://www.apache.org/licenses/LICENSE-2.0> for Apache.
|
||||||
|
*/
|
||||||
|
import * as glue from 'mcaptcha-glue'
|
||||||
|
|
||||||
|
glue.init()
|
Loading…
Add table
Reference in a new issue