-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcredentials.rs
48 lines (39 loc) · 1.46 KB
/
credentials.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use lazy_regex::regex_is_match;
use rocket::data::{Data, FromData};
use rocket::serde::{json::Json, Deserialize, Serialize};
use rocket::{async_trait, data, outcome::Outcome, Request};
use unicode_segmentation::UnicodeSegmentation;
use super::*;
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub struct Credentials {
pub username: String,
pub password: String,
}
#[async_trait]
impl<'r> FromData<'r> for Credentials {
type Error = HttpError;
async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> {
use super::Error::*;
let outcome = Json::<Credentials>::from_data(req, data)
.await
.map(|json| json.into_inner())
.map_failure(|(status, error)| (status, error.into()));
// TODO cover these scenarios with tests
if let Outcome::Success(ref credentials) = outcome {
let size = credentials.username.graphemes(true).count();
let (min, max) = (1, 42);
if size < min || size > max {
return BadUsernameSize(min, max).into();
}
let size = credentials.password.graphemes(true).count();
let min = 8;
if size < min {
return BadPasswordSize(min).into();
}
if !regex_is_match!("^([A-Za-z]+)([0-9A-Za-z]*)$", &credentials.username) {
return BadUsername.into();
}
}
outcome
}
}