diff --git a/actix/src/auth.rs b/actix/src/auth.rs index 1aacd98..870732e 100644 --- a/actix/src/auth.rs +++ b/actix/src/auth.rs @@ -1,19 +1,21 @@ use actix_session::Session; use std::{env, time::SystemTime}; +// Validate a given password pub fn validate(session: Session) -> bool { // If there's no password provided, just return true if env::var("password").is_err() { return true; } - if let Ok(token) = session.get::("session-token") { + if let Ok(token) = session.get::("chhoto-url-auth") { check(token) } else { false } } +// Check a token cryptographically fn check(token: Option) -> bool { if let Some(token_body) = token { let token_parts: Vec<&str> = token_body.split(';').collect(); @@ -26,15 +28,16 @@ fn check(token: Option) -> bool { .duration_since(SystemTime::UNIX_EPOCH) .expect("Time went backwards!") .as_secs(); - token_text == "session-token" && time_now < token_time + 1209600 // There are 1209600 seconds in 14 days + token_text == "chhoto-url-auth" && time_now < token_time + 1209600 // There are 1209600 seconds in 14 days } } else { false } } +// Generate a new cryptographic token pub fn gen_token() -> String { - let token_text = String::from("session-token"); + let token_text = String::from("chhoto-url-auth"); let time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .expect("Time went backwards!") diff --git a/actix/src/database.rs b/actix/src/database.rs index 020c92c..79c9b29 100644 --- a/actix/src/database.rs +++ b/actix/src/database.rs @@ -1,6 +1,7 @@ use rusqlite::Connection; use serde::Serialize; +// Struct for encoding a DB row #[derive(Serialize)] pub struct DBRow { shortlink: String, @@ -8,6 +9,7 @@ pub struct DBRow { hits: i64, } +// Find a single URL pub fn find_url(shortlink: &str, db: &Connection) -> Option { let mut statement = db .prepare_cached("SELECT long_url FROM urls WHERE short_url = ?1") @@ -18,6 +20,7 @@ pub fn find_url(shortlink: &str, db: &Connection) -> Option { .ok() } +// Get all URLs in DB pub fn getall(db: &Connection) -> Vec { let mut statement = db .prepare_cached("SELECT * FROM urls") @@ -44,6 +47,7 @@ pub fn getall(db: &Connection) -> Vec { links } +// Add a hit when site is visited pub fn add_hit(shortlink: &str, db: &Connection) { db.execute( "UPDATE urls SET hits = hits + 1 WHERE short_url = ?1", @@ -52,6 +56,7 @@ pub fn add_hit(shortlink: &str, db: &Connection) { .expect("Error updating hit count."); } +// Insert a new link pub fn add_link(shortlink: String, longlink: String, db: &Connection) -> bool { db.execute( "INSERT INTO urls (long_url, short_url, hits) VALUES (?1, ?2, ?3)", @@ -60,6 +65,7 @@ pub fn add_link(shortlink: String, longlink: String, db: &Connection) -> bool { .is_ok() } +// Delete and existing link pub fn delete_link(shortlink: String, db: &Connection) -> bool { if let Ok(delta) = db.execute("DELETE FROM urls WHERE short_url = ?1", [shortlink]) { delta > 0 @@ -68,6 +74,7 @@ pub fn delete_link(shortlink: String, db: &Connection) -> bool { } } +// Open the DB, and create schema if missing pub fn open_db(path: String) -> Connection { let db = Connection::open(path).expect("Unable to open database!"); // Create table if it doesn't exist diff --git a/actix/src/main.rs b/actix/src/main.rs index 8c64a76..ac6b443 100644 --- a/actix/src/main.rs +++ b/actix/src/main.rs @@ -108,8 +108,8 @@ async fn login(req: String, session: Session) -> HttpResponse { } // Return Ok if no password was set on the server side session - .insert("session-token", auth::gen_token()) - .expect("Error inserting session-token."); + .insert("chhoto-url-auth", auth::gen_token()) + .expect("Error inserting auth token."); HttpResponse::Ok().body("Correct password!") } diff --git a/actix/src/utils.rs b/actix/src/utils.rs index 5a4f9c2..cd94de8 100644 --- a/actix/src/utils.rs +++ b/actix/src/utils.rs @@ -7,12 +7,14 @@ use std::env; use crate::database; -#[derive(Deserialize, Default, PartialEq)] +// Struct for reading link pairs sent during API call +#[derive(Deserialize)] struct URLPair { shortlink: String, longlink: String, } +// Request the DB for searching an URL pub fn get_longurl(shortlink: String, db: &Connection) -> Option { if validate_link(&shortlink) { database::find_url(shortlink.as_str(), db) @@ -21,21 +23,25 @@ pub fn get_longurl(shortlink: String, db: &Connection) -> Option { } } +// Only have a-z, 0-9, - and _ as valid characters in a shortlink fn validate_link(link: &str) -> bool { let re = Regex::new("^[a-z0-9-_]+$").expect("Regex generation failed."); re.is_match(link) } +// Request the DB for all URLs pub fn getall(db: &Connection) -> String { let links = database::getall(db); serde_json::to_string(&links).expect("Failure during creation of json from db.") } +// Make checks and then request the DB to add a new URL entry pub fn add_link(req: String, db: &Connection) -> (bool, String) { let mut chunks: URLPair; if let Ok(json) = serde_json::from_str(&req) { chunks = json; } else { + // shorturl should always be supplied, even if empty return (false, String::from("Invalid request!")); } @@ -64,6 +70,7 @@ pub fn add_link(req: String, db: &Connection) -> (bool, String) { } } +// Check if link, and request DB to delete it if exists pub fn delete_link(shortlink: String, db: &Connection) -> bool { if validate_link(shortlink.as_str()) { database::delete_link(shortlink, db) @@ -72,6 +79,7 @@ pub fn delete_link(shortlink: String, db: &Connection) -> bool { } } +// Generate a random link using either adjective-name pair (default) of a slug or a-z, 0-9 fn gen_link(style: String, len: usize) -> String { #[rustfmt::skip] static ADJECTIVES: [&str; 108] = ["admiring", "adoring", "affectionate", "agitated", "amazing", "angry", "awesome", "beautiful",