Commit a54e4762 authored by tec's avatar tec

Add start of account verification

parent a8a035eb
use chrono::{
prelude::{SecondsFormat, Utc},
DateTime,
};
use rand::Rng;
use serenity::model::user::User;
use std::str;
lazy_static! {
static ref key: [u8; 32] = rand::thread_rng().gen::<[u8; 32]>();
}
fn encrypt(plaintext: &str) -> &str {
return plaintext;
}
fn decrypt(ciphertext: &str) -> &str {
return ciphertext;
}
pub fn generate_token<'a>(discord_user: &User, username: &str) -> String {
// if username doesn't exist : throw error
let timestamp = Utc::now().to_rfc3339();
let payload = format!(
"{},{},{}",
timestamp,
discord_user.id.0.to_string(),
username
);
info!("Token generated for {}: {}", discord_user.name, &payload);
encrypt(&payload).to_string()
}
#[derive(Debug)]
pub enum TokenError {
DiscordIdMismatch,
TokenExpired,
}
impl std::fmt::Display for TokenError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub fn parse_token(discord_user: &User, token: &str) -> Result<String, TokenError> {
let token_components: Vec<_> = decrypt(token).splitn(3, ',').collect();
info!(
"Verification attempt from '{}'(uid: {}) for account '{}' with token from {}",
discord_user.name, token_components[1], token_components[2], token_components[0]
);
let token_timestamp =
DateTime::parse_from_rfc3339(token_components[0]).expect("Invalid date format");
let token_discord_user = token_components[1];
let token_username = token_components[2];
if token_discord_user != discord_user.id.0.to_string() {
warn!("... attempt failed : DiscordID mismatch");
return Err(TokenError::DiscordIdMismatch);
}
let time_delta_seconds = Utc::now().timestamp() - token_timestamp.timestamp();
if time_delta_seconds > 5 * 60 {
warn!(
"... attempt failed : token expired ({} seconds old)",
time_delta_seconds
);
return Err(TokenError::TokenExpired);
}
info!(
"... verification successful (token {} seconds old)",
time_delta_seconds
);
return Ok(token_username.to_owned());
}
......@@ -6,6 +6,7 @@ use serenity::{
};
use crate::config::CONFIG;
use crate::token_management::*;
macro_rules! e {
($error: literal, $x:expr) => {
......@@ -59,48 +60,63 @@ impl Commands {
);
return;
}
// token stuff
e!(
"Error sending message: {:?}",
// TODO convert to email
msg.channel_id
.say(&ctx.http, generate_token(&msg.author, name))
);
e!("Error deleting register message: {:?}", msg.delete(ctx));
}
pub fn verify(ctx: Context, msg: Message, content: &str) {
let token = content;
// if token is valid
e!(
"Unable to get member: {:?}",
serenity::model::id::GuildId(CONFIG.server_id)
.member(ctx.http.clone(), msg.author.id)
.map(|mut member| {
e!(
"Unable to remove role: {:?}",
member.remove_role(&ctx.http, CONFIG.unregistered_member_role)
);
e!(
"Unable to edit nickname: {:?}",
member
.edit(&ctx.http, |m| {
let mut rng = rand::thread_rng();
m.nickname(format!(
"{}, {}",
name,
[
"The Big Cheese",
"The One and Only",
"The Exalted One",
"not to be trusted",
"The Scoundrel",
"A big fish in a small pond",
][rng.gen_range(0, 5)]
));
m
})
.map(|()| {
e!(
"Unable to add role: {:?}",
member.add_role(&ctx.http, CONFIG.registered_member_role)
);
})
);
})
);
match parse_token(&msg.author, content) {
Ok(name) => {
e!(
"Unable to get member: {:?}",
serenity::model::id::GuildId(CONFIG.server_id)
.member(ctx.http.clone(), msg.author.id)
.map(|mut member| {
e!(
"Unable to remove role: {:?}",
member.remove_role(&ctx.http, CONFIG.unregistered_member_role)
);
e!(
"Unable to edit nickname: {:?}",
member.edit(&ctx.http, |m| {
let mut rng = rand::thread_rng();
m.nickname(format!(
"{}, {}",
name,
[
"The Big Cheese",
"The One and Only",
"The Exalted One",
"not to be trusted",
"The Scoundrel",
"A big fish in a small pond",
][rng.gen_range(0, 5)]
));
m
})
);
let new_msg = msg
.channel_id
.say(&ctx.http, "Verification succesful")
.expect("Error sending message");
e!(
"Error deleting register message: {:?}",
new_msg.delete(&ctx)
);
})
);
}
Err(reason) => e!(
"Error sending message: {:?}",
msg.channel_id
.say(&ctx.http, format!("Verification error: {:?}", reason))
),
}
e!("Error deleting register message: {:?}", msg.delete(&ctx));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment