mirror of
https://github.com/SinTan1729/chhoto-url
synced 2024-12-26 23:58:35 -06:00
docs: Added some comments and changed the token name
This commit is contained in:
parent
0469f9b933
commit
ca14c02e70
4 changed files with 24 additions and 6 deletions
|
@ -1,19 +1,21 @@
|
||||||
use actix_session::Session;
|
use actix_session::Session;
|
||||||
use std::{env, time::SystemTime};
|
use std::{env, time::SystemTime};
|
||||||
|
|
||||||
|
// Validate a given password
|
||||||
pub fn validate(session: Session) -> bool {
|
pub fn validate(session: Session) -> bool {
|
||||||
// If there's no password provided, just return true
|
// If there's no password provided, just return true
|
||||||
if env::var("password").is_err() {
|
if env::var("password").is_err() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(token) = session.get::<String>("session-token") {
|
if let Ok(token) = session.get::<String>("chhoto-url-auth") {
|
||||||
check(token)
|
check(token)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check a token cryptographically
|
||||||
fn check(token: Option<String>) -> bool {
|
fn check(token: Option<String>) -> bool {
|
||||||
if let Some(token_body) = token {
|
if let Some(token_body) = token {
|
||||||
let token_parts: Vec<&str> = token_body.split(';').collect();
|
let token_parts: Vec<&str> = token_body.split(';').collect();
|
||||||
|
@ -26,15 +28,16 @@ fn check(token: Option<String>) -> bool {
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.expect("Time went backwards!")
|
.expect("Time went backwards!")
|
||||||
.as_secs();
|
.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 {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a new cryptographic token
|
||||||
pub fn gen_token() -> String {
|
pub fn gen_token() -> String {
|
||||||
let token_text = String::from("session-token");
|
let token_text = String::from("chhoto-url-auth");
|
||||||
let time = SystemTime::now()
|
let time = SystemTime::now()
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
.expect("Time went backwards!")
|
.expect("Time went backwards!")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
// Struct for encoding a DB row
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct DBRow {
|
pub struct DBRow {
|
||||||
shortlink: String,
|
shortlink: String,
|
||||||
|
@ -8,6 +9,7 @@ pub struct DBRow {
|
||||||
hits: i64,
|
hits: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find a single URL
|
||||||
pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
||||||
let mut statement = db
|
let mut statement = db
|
||||||
.prepare_cached("SELECT long_url FROM urls WHERE short_url = ?1")
|
.prepare_cached("SELECT long_url FROM urls WHERE short_url = ?1")
|
||||||
|
@ -18,6 +20,7 @@ pub fn find_url(shortlink: &str, db: &Connection) -> Option<String> {
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all URLs in DB
|
||||||
pub fn getall(db: &Connection) -> Vec<DBRow> {
|
pub fn getall(db: &Connection) -> Vec<DBRow> {
|
||||||
let mut statement = db
|
let mut statement = db
|
||||||
.prepare_cached("SELECT * FROM urls")
|
.prepare_cached("SELECT * FROM urls")
|
||||||
|
@ -44,6 +47,7 @@ pub fn getall(db: &Connection) -> Vec<DBRow> {
|
||||||
links
|
links
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a hit when site is visited
|
||||||
pub fn add_hit(shortlink: &str, db: &Connection) {
|
pub fn add_hit(shortlink: &str, db: &Connection) {
|
||||||
db.execute(
|
db.execute(
|
||||||
"UPDATE urls SET hits = hits + 1 WHERE short_url = ?1",
|
"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.");
|
.expect("Error updating hit count.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert a new link
|
||||||
pub fn add_link(shortlink: String, longlink: String, db: &Connection) -> bool {
|
pub fn add_link(shortlink: String, longlink: String, db: &Connection) -> bool {
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO urls (long_url, short_url, hits) VALUES (?1, ?2, ?3)",
|
"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()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete and existing link
|
||||||
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
||||||
if let Ok(delta) = db.execute("DELETE FROM urls WHERE short_url = ?1", [shortlink]) {
|
if let Ok(delta) = db.execute("DELETE FROM urls WHERE short_url = ?1", [shortlink]) {
|
||||||
delta > 0
|
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 {
|
pub fn open_db(path: String) -> Connection {
|
||||||
let db = Connection::open(path).expect("Unable to open database!");
|
let db = Connection::open(path).expect("Unable to open database!");
|
||||||
// Create table if it doesn't exist
|
// Create table if it doesn't exist
|
||||||
|
|
|
@ -108,8 +108,8 @@ async fn login(req: String, session: Session) -> HttpResponse {
|
||||||
}
|
}
|
||||||
// Return Ok if no password was set on the server side
|
// Return Ok if no password was set on the server side
|
||||||
session
|
session
|
||||||
.insert("session-token", auth::gen_token())
|
.insert("chhoto-url-auth", auth::gen_token())
|
||||||
.expect("Error inserting session-token.");
|
.expect("Error inserting auth token.");
|
||||||
HttpResponse::Ok().body("Correct password!")
|
HttpResponse::Ok().body("Correct password!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,14 @@ use std::env;
|
||||||
|
|
||||||
use crate::database;
|
use crate::database;
|
||||||
|
|
||||||
#[derive(Deserialize, Default, PartialEq)]
|
// Struct for reading link pairs sent during API call
|
||||||
|
#[derive(Deserialize)]
|
||||||
struct URLPair {
|
struct URLPair {
|
||||||
shortlink: String,
|
shortlink: String,
|
||||||
longlink: String,
|
longlink: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request the DB for searching an URL
|
||||||
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
||||||
if validate_link(&shortlink) {
|
if validate_link(&shortlink) {
|
||||||
database::find_url(shortlink.as_str(), db)
|
database::find_url(shortlink.as_str(), db)
|
||||||
|
@ -21,21 +23,25 @@ pub fn get_longurl(shortlink: String, db: &Connection) -> Option<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only have a-z, 0-9, - and _ as valid characters in a shortlink
|
||||||
fn validate_link(link: &str) -> bool {
|
fn validate_link(link: &str) -> bool {
|
||||||
let re = Regex::new("^[a-z0-9-_]+$").expect("Regex generation failed.");
|
let re = Regex::new("^[a-z0-9-_]+$").expect("Regex generation failed.");
|
||||||
re.is_match(link)
|
re.is_match(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Request the DB for all URLs
|
||||||
pub fn getall(db: &Connection) -> String {
|
pub fn getall(db: &Connection) -> String {
|
||||||
let links = database::getall(db);
|
let links = database::getall(db);
|
||||||
serde_json::to_string(&links).expect("Failure during creation of json from 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) {
|
pub fn add_link(req: String, db: &Connection) -> (bool, String) {
|
||||||
let mut chunks: URLPair;
|
let mut chunks: URLPair;
|
||||||
if let Ok(json) = serde_json::from_str(&req) {
|
if let Ok(json) = serde_json::from_str(&req) {
|
||||||
chunks = json;
|
chunks = json;
|
||||||
} else {
|
} else {
|
||||||
|
// shorturl should always be supplied, even if empty
|
||||||
return (false, String::from("Invalid request!"));
|
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 {
|
pub fn delete_link(shortlink: String, db: &Connection) -> bool {
|
||||||
if validate_link(shortlink.as_str()) {
|
if validate_link(shortlink.as_str()) {
|
||||||
database::delete_link(shortlink, db)
|
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 {
|
fn gen_link(style: String, len: usize) -> String {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static ADJECTIVES: [&str; 108] = ["admiring", "adoring", "affectionate", "agitated", "amazing", "angry", "awesome", "beautiful",
|
static ADJECTIVES: [&str; 108] = ["admiring", "adoring", "affectionate", "agitated", "amazing", "angry", "awesome", "beautiful",
|
||||||
|
|
Loading…
Reference in a new issue