init: copied over stuff from shuttlecraft/identity
This commit is contained in:
commit
846ddb52f8
9 changed files with 588 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
22
Cargo.toml
Normal file
22
Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "argon2-creds"
|
||||
version = "0.1.0"
|
||||
authors = ["realaravinth <realaravinth@batsense.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "argon2_creds"
|
||||
path = "src/lib.rs"
|
||||
|
||||
|
||||
[dependencies]
|
||||
rust-argon2 = "0.8.3"
|
||||
derive_more = "0.99.11"
|
||||
unicode-normalization = "0.1.6"
|
||||
ammonia = "3.1.0"
|
||||
validator = "0.12.0"
|
||||
validator_derive = "0.12.0"
|
||||
lazy_static = "1.4.0"
|
||||
regex = { version = "1.3.9", features = [ "perf-inline", "perf-dfa", "perf-literal", "perf-cache", "perf"]}
|
||||
rand = "0.8.0"
|
46
src/errors.rs
Normal file
46
src/errors.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use std::convert::From;
|
||||
|
||||
use derive_more::{Display, Error};
|
||||
use validator::ValidationErrors;
|
||||
|
||||
/// Errors that can occur when processing credentials
|
||||
#[derive(Debug, PartialEq, Display, Clone, Error)]
|
||||
#[cfg(not(tarpaulin_include))]
|
||||
pub enum CredsError {
|
||||
/// when the value passed contains profainity
|
||||
#[display(fmt = "the value you passed contains profainity")]
|
||||
ProfainityError,
|
||||
|
||||
/// when the value passed contains characters not present
|
||||
/// in [UsernameCaseMapped](https://tools.ietf.org/html/rfc8265#page-7)
|
||||
/// profile
|
||||
#[display(fmt = "username_case_mapped violation")]
|
||||
UsernameCaseMappedError,
|
||||
|
||||
/// when the value passed contains blacklisted words
|
||||
/// see [blacklist](https://github.com/shuttlecraft/The-Big-Username-Blacklist)
|
||||
#[display(fmt = "contains blacklisted words")]
|
||||
BlacklistError,
|
||||
|
||||
/// email validation error
|
||||
#[display(fmt = "The value passed in not an email")]
|
||||
NotAnEmail,
|
||||
|
||||
/// Errors from argon2
|
||||
#[display(fmt = "{}", _0)]
|
||||
Argon2Error(argon2::Error),
|
||||
}
|
||||
|
||||
impl From<argon2::Error> for CredsError {
|
||||
fn from(e: argon2::Error) -> CredsError {
|
||||
CredsError::Argon2Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidationErrors> for CredsError {
|
||||
fn from(_: ValidationErrors) -> CredsError {
|
||||
CredsError::NotAnEmail
|
||||
}
|
||||
}
|
||||
|
||||
pub type CredsResult<V> = std::result::Result<V, crate::errors::CredsError>;
|
32
src/filters/blacklist.rs
Normal file
32
src/filters/blacklist.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use crate::errors::{CredsError, CredsResult};
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
|
||||
pub fn forbidden(target: &str) -> CredsResult<()> {
|
||||
static BLACKLIST: &'static str = r"[^!@#$%^&*]*(.htaccess|.htpasswd|.well-known|400|401|403|404|405|406|407|408|409|410|411|412|413|414|415|416|417|421|422|423|424|426|428|429|431|500|501|502|503|504|505|506|507|508|509|510|511|_domainkey|about|about-us|abuse|access|account|accounts|ad|add|admin|administration|administrator|ads|ads.txt|advertise|advertising|aes128-ctr|aes128-gcm|aes192-ctr|aes256-ctr|aes256-gcm|affiliate|affiliates|ajax|alert|alerts|alpha|amp|analytics|api|app|app-ads.txt|apps|asc|assets|atom|auth|authentication|authorize|autoconfig|autodiscover|avatar|backup|banner|banners|bbs|beta|billing|billings|blog|blogs|board|bookmark|bookmarks|broadcasthost|business|buy|cache|calendar|campaign|captcha|careers|cart|cas|categories|category|cdn|cgi|cgi-bin|chacha20-poly1305|change|channel|channels|chart|chat|checkout|clear|client|close|cloud|cms|com|comment|comments|community|compare|compose|config|connect|contact|contest|cookies|copy|copyright|count|cp|cpanel|create|crossdomain.xml|css|curve25519-sha256|customer|customers|customize|dashboard|db|deals|debug|delete|desc|destroy|dev|developer|developers|diffie-hellman-group-exchange-sha256|diffie-hellman-group14-sha1|disconnect|discuss|dns|dns0|dns1|dns2|dns3|dns4|docs|documentation|domain|download|downloads|downvote|draft|drop|ecdh-sha2-nistp256|ecdh-sha2-nistp384|ecdh-sha2-nistp521|edit|editor|email|enterprise|error|errors|event|events|example|exception|exit|explore|export|extensions|false|family|faq|faqs|favicon.ico|features|feed|feedback|feeds|file|files|filter|follow|follower|followers|following|fonts|forgot|forgot-password|forgotpassword|form|forms|forum|forums|friend|friends|ftp|get|git|go|graphql|group|groups|guest|guidelines|guides|head|header|help|hide|hmac-sha|hmac-sha1|hmac-sha1-etm|hmac-sha2-256|hmac-sha2-256-etm|hmac-sha2-512|hmac-sha2-512-etm|home|host|hosting|hostmaster|htpasswd|http|httpd|https|humans.txt|icons|images|imap|img|import|index|info|insert|investors|invitations|invite|invites|invoice|is|isatap|issues|it|jobs|join|js|json|keybase.txt|learn|legal|license|licensing|like|limit|live|load|local|localdomain|localhost|lock|login|logout|lost-password|m|mail|mail0|mail1|mail2|mail3|mail4|mail5|mail6|mail7|mail8|mail9|mailer-daemon|mailerdaemon|map|marketing|marketplace|master|me|media|member|members|message|messages|metrics|mis|mobile|moderator|modify|more|mx|mx1|my|net|network|new|news|newsletter|newsletters|next|nil|no-reply|nobody|noc|none|noreply|notification|notifications|ns|ns0|ns1|ns2|ns3|ns4|ns5|ns6|ns7|ns8|ns9|null|oauth|oauth2|offer|offers|online|openid|order|orders|overview|owa|owner|page|pages|partners|passwd|password|pay|payment|payments|photo|photos|pixel|plans|plugins|policies|policy|pop|pop3|popular|portal|portfolio|post|postfix|postmaster|poweruser|preferences|premium|press|previous|pricing|print|privacy|privacy-policy|private|prod|product|production|profile|profiles|project|projects|public|purchase|put|quota|redirect|reduce|refund|refunds|register|registration|remove|replies|reply|report|request|request-password|reset|reset-password|response|return|returns|review|reviews|robots.txt|root|rootuser|rsa-sha2-2|rsa-sha2-512|rss|rules|sales|save|script|sdk|search|secure|security|select|services|session|sessions|settings|setup|share|shift|shop|signin|signup|site|sitemap|sites|smtp|sort|source|sql|ssh|ssh-rsa|ssl|ssladmin|ssladministrator|sslwebmaster|stage|staging|stat|static|statistics|stats|status|store|style|styles|stylesheet|stylesheets|subdomain|subscribe|sudo|super|superuser|support|survey|sync|sysadmin|system|tablet|tag|tags|team|telnet|terms|terms-of-use|test|testimonials|theme|themes|today|tools|topic|topics|tour|training|translate|translations|trending|trial|true|umac-128|umac-128-etm|umac-64|umac-64-etm|undefined|unfollow|unlike|unsubscribe|update|upgrade|usenet|user|username|users|uucp|var|verify|video|view|void|vote|vpn|webmail|webmaster|website|widget|widgets|wiki|wpad|write|www|www-data|www1|www2|www3|www4|you|yourname|yourusername|zlib)[^!@#$%^&*]*";
|
||||
lazy_static! {
|
||||
static ref RE_BLACKLIST: Regex =
|
||||
Regex::new(BLACKLIST).expect("coudln't setup blacklist filter");
|
||||
}
|
||||
if RE_BLACKLIST.is_match(&target) {
|
||||
Err(CredsError::BlacklistError)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_forbidden() {
|
||||
let illegal = "zlib";
|
||||
let legal = "rust";
|
||||
let illegal2 = ".htaccess_yolo";
|
||||
|
||||
assert_eq!(forbidden(legal), Ok(()));
|
||||
assert_eq!(forbidden(illegal), Err(CredsError::BlacklistError));
|
||||
assert_eq!(forbidden(illegal2), Err(CredsError::BlacklistError));
|
||||
}
|
||||
}
|
24
src/filters/mod.rs
Normal file
24
src/filters/mod.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
mod blacklist;
|
||||
mod profainity;
|
||||
mod user_case_mapped;
|
||||
|
||||
pub use blacklist::forbidden;
|
||||
pub use profainity::beep;
|
||||
pub use user_case_mapped::filter;
|
51
src/filters/profainity.rs
Normal file
51
src/filters/profainity.rs
Normal file
File diff suppressed because one or more lines are too long
29
src/filters/user_case_mapped.rs
Normal file
29
src/filters/user_case_mapped.rs
Normal file
File diff suppressed because one or more lines are too long
175
src/lib.rs
Normal file
175
src/lib.rs
Normal file
|
@ -0,0 +1,175 @@
|
|||
pub mod errors;
|
||||
mod filters;
|
||||
|
||||
use ammonia::clean;
|
||||
use argon2::{self, Config, ThreadMode, Variant, Version};
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
use validator::Validate;
|
||||
use validator_derive::Validate;
|
||||
|
||||
use errors::*;
|
||||
|
||||
pub use filters::{beep, filter, forbidden};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct UnvalidatedRegisterCreds {
|
||||
pub username: String,
|
||||
pub email_id: Option<String>,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Validate)]
|
||||
pub struct RegisterCreds {
|
||||
pub username: String,
|
||||
#[validate(email)]
|
||||
pub email_id: Option<String>,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl UnvalidatedRegisterCreds {
|
||||
pub fn process(&self) -> CredsResult<RegisterCreds> {
|
||||
let creds = RegisterCreds::default()
|
||||
.set_email(&self.email_id)?
|
||||
.set_username(&self.username)
|
||||
.validate_fields()?
|
||||
.set_password(&self.password)?
|
||||
.build();
|
||||
Ok(creds)
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterCreds {
|
||||
pub fn set_username<'a>(&'a mut self, username: &str) -> &'a mut Self {
|
||||
self.username = clean(username)
|
||||
.to_lowercase()
|
||||
.nfc()
|
||||
.collect::<String>()
|
||||
.trim()
|
||||
.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_email<'a>(&'a mut self, email_id: &Option<String>) -> CredsResult<&'a mut Self> {
|
||||
if let Some(email) = email_id {
|
||||
self.email_id = Some(email.trim().to_owned());
|
||||
self.validate()?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn validate_fields<'a>(&'a mut self) -> CredsResult<&'a mut Self> {
|
||||
filter(&self.username)?;
|
||||
forbidden(&self.username)?;
|
||||
beep(&self.username)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn set_password<'a>(&'a mut self, password: &str) -> CredsResult<&'a mut Self> {
|
||||
// let config = Config {
|
||||
// variant: Variant::Argon2i,
|
||||
// version: Version::Version13,
|
||||
// mem_cost: SETTINGS.password_difficulty.mem_cost,
|
||||
// time_cost: SETTINGS.password_difficulty.time_cost,
|
||||
// lanes: SETTINGS.password_difficulty.lanes,
|
||||
// thread_mode: ThreadMode::Parallel,
|
||||
// secret: &[],
|
||||
// ad: &[],
|
||||
// hash_length: 32,
|
||||
// };
|
||||
let config = Config::default();
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let salt: String = std::iter::repeat(())
|
||||
.map(|()| rng.sample(Alphanumeric))
|
||||
.map(char::from)
|
||||
.take(32)
|
||||
.collect();
|
||||
|
||||
self.password = argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &config)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn build(&mut self) -> Self {
|
||||
self.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn utils_register_builer() {
|
||||
let registered_creds = RegisterCreds::default()
|
||||
.set_password("password")
|
||||
.unwrap()
|
||||
.set_username("realaravinth")
|
||||
.set_email(&Some("batman@we.net".into()))
|
||||
.unwrap()
|
||||
.validate_fields()
|
||||
.unwrap()
|
||||
.build();
|
||||
|
||||
assert_eq!(registered_creds.username, "realaravinth");
|
||||
assert_eq!(registered_creds.email_id, Some("batman@we.net".into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_register_email_err() {
|
||||
let mut email_err = RegisterCreds::default()
|
||||
.set_password("password")
|
||||
.unwrap()
|
||||
.set_username("realaravinth")
|
||||
.build();
|
||||
assert_eq!(
|
||||
email_err.set_email(&Some("sdfasdf".into())),
|
||||
Err(CredsError::NotAnEmail)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_organisation() {
|
||||
let password = "somepassword";
|
||||
let org = RegisterCreds::default()
|
||||
.set_email(&Some("batman@we.net".into()))
|
||||
.unwrap()
|
||||
.set_username("Realaravinth")
|
||||
.validate_fields()
|
||||
.unwrap()
|
||||
.set_password(password)
|
||||
.unwrap()
|
||||
.build();
|
||||
|
||||
assert_eq!(org.username, "realaravinth");
|
||||
|
||||
assert!(
|
||||
argon2::verify_encoded(&org.password, password.as_bytes()).unwrap(),
|
||||
"verify hahsing"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_profane_organisation() {
|
||||
let mut profane_org = RegisterCreds::default();
|
||||
profane_org.set_username("fuck");
|
||||
|
||||
assert_eq!(
|
||||
profane_org.validate_fields(),
|
||||
Err(CredsError::ProfainityError)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_forbidden_organisation() {
|
||||
let mut forbidden_org = RegisterCreds::default()
|
||||
.set_username("htaccessasnc")
|
||||
.build();
|
||||
|
||||
assert_eq!(
|
||||
forbidden_org.validate_fields(),
|
||||
Err(CredsError::BlacklistError)
|
||||
);
|
||||
}
|
||||
}
|
207
src/payload.rs
Normal file
207
src/payload.rs
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use ammonia::clean;
|
||||
use argon2::{self, Config, ThreadMode, Variant, Version};
|
||||
use pow_sha256::PoW;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
use validator::Validate;
|
||||
use validator_derive::Validate;
|
||||
|
||||
use super::{beep, filter, forbidden};
|
||||
use crate::errors::*;
|
||||
use crate::SETTINGS;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub struct UnvalidatedRegisterCreds {
|
||||
pub username: String,
|
||||
pub email_id: Option<String>,
|
||||
pub password: String,
|
||||
pub pow: PoW<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Validate, Deserialize, Serialize)]
|
||||
pub struct RegisterCreds {
|
||||
pub username: String,
|
||||
#[validate(email)]
|
||||
pub email_id: Option<String>,
|
||||
pub password: String,
|
||||
}
|
||||
//impl AsRef<RegisterCreds> for RegisterCreds {
|
||||
// fn as_ref(&self) -> &RegisterCreds {
|
||||
// &self
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//impl AsMut<RegisterCreds> for RegisterCreds {
|
||||
// fn as_mut<'a>(&'a mut self) -> &'a mut Self {
|
||||
// &mut self
|
||||
// }
|
||||
//}
|
||||
impl UnvalidatedRegisterCreds {
|
||||
pub fn process(&self) -> ServiceResult<RegisterCreds> {
|
||||
let creds = RegisterCreds::new()
|
||||
.set_email(&self.email_id)?
|
||||
.set_username(&self.username)
|
||||
.validate_fields()?
|
||||
.set_password(&self.password)?
|
||||
.build();
|
||||
Ok(creds)
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterCreds {
|
||||
// pub fn create_register_creds<'a>(&'a mut self) -> ServiceResult<Self> {
|
||||
// let creds = RegisterCreds::new()
|
||||
// .set_email(&u_creds.email_id)?
|
||||
// .set_username(&u_creds.username)
|
||||
// .validate_fields()?
|
||||
// .set_password(&u_creds.password)?
|
||||
// .build();
|
||||
// Ok(creds)
|
||||
// }
|
||||
fn new() -> Self {
|
||||
let registered_creds: RegisterCreds = Default::default();
|
||||
registered_creds
|
||||
}
|
||||
|
||||
fn set_username<'a>(&'a mut self, username: &str) -> &'a mut Self {
|
||||
self.username = clean(username)
|
||||
.to_lowercase()
|
||||
.nfc()
|
||||
.collect::<String>()
|
||||
.trim()
|
||||
.to_owned();
|
||||
self
|
||||
}
|
||||
|
||||
fn set_email<'a>(&'a mut self, email_id: &Option<String>) -> ServiceResult<&'a mut Self> {
|
||||
if let Some(email) = email_id {
|
||||
self.email_id = Some(email.trim().to_owned());
|
||||
self.validate()?;
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn validate_fields<'a>(&'a mut self) -> ServiceResult<&'a mut Self> {
|
||||
filter(&self.username)?;
|
||||
forbidden(&self.username)?;
|
||||
beep(&self.username)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn set_password<'a>(&'a mut self, password: &str) -> ServiceResult<&'a mut Self> {
|
||||
let config = Config {
|
||||
variant: Variant::Argon2i,
|
||||
version: Version::Version13,
|
||||
mem_cost: SETTINGS.password_difficulty.mem_cost,
|
||||
time_cost: SETTINGS.password_difficulty.time_cost,
|
||||
lanes: SETTINGS.password_difficulty.lanes,
|
||||
thread_mode: ThreadMode::Parallel,
|
||||
secret: &[],
|
||||
ad: &[],
|
||||
hash_length: 32,
|
||||
};
|
||||
|
||||
let salt: String = thread_rng().sample_iter(&Alphanumeric).take(32).collect();
|
||||
self.password = argon2::hash_encoded(password.as_bytes(), salt.as_bytes(), &config)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn build(&mut self) -> Self {
|
||||
self.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn utils_register_builer() {
|
||||
let registered_creds = RegisterCreds::new()
|
||||
.set_password("password")
|
||||
.unwrap()
|
||||
.set_username("realaravinth")
|
||||
.set_email(&Some("batman@we.net".into()))
|
||||
.unwrap()
|
||||
.validate_fields()
|
||||
.unwrap()
|
||||
.build();
|
||||
|
||||
assert_eq!(registered_creds.username, "realaravinth");
|
||||
assert_eq!(registered_creds.email_id, Some("batman@we.net".into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_register_email_err() {
|
||||
let mut email_err = RegisterCreds::new()
|
||||
.set_password("password")
|
||||
.unwrap()
|
||||
.set_username("realaravinth")
|
||||
.build();
|
||||
assert_eq!(
|
||||
email_err.set_email(&Some("sdfasdf".into())),
|
||||
Err(ServiceError::NotAnEmail)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_organisation() {
|
||||
let password = "somepassword";
|
||||
let org = RegisterCreds::new()
|
||||
.set_email(&Some("batman@we.net".into()))
|
||||
.unwrap()
|
||||
.set_username("Realaravinth")
|
||||
.validate_fields()
|
||||
.unwrap()
|
||||
.set_password(password)
|
||||
.unwrap()
|
||||
.build();
|
||||
|
||||
assert_eq!(org.username, "realaravinth");
|
||||
|
||||
assert!(
|
||||
argon2::verify_encoded(&org.password, password.as_bytes()).unwrap(),
|
||||
"verify hahsing"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_profane_organisation() {
|
||||
let mut profane_org = RegisterCreds::new();
|
||||
profane_org.set_username("fuck");
|
||||
|
||||
assert_eq!(
|
||||
profane_org.validate_fields(),
|
||||
Err(ServiceError::UsernameError)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn utils_create_new_forbidden_organisation() {
|
||||
let mut forbidden_org = RegisterCreds::new().set_username("htaccessasnc").build();
|
||||
|
||||
assert_eq!(
|
||||
forbidden_org.validate_fields(),
|
||||
Err(ServiceError::UsernameError)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue