mirror of
https://github.com/SinTan1729/chhoto-url
synced 2024-12-25 23:28:37 -06:00
chg: Move all the services into their own file
This commit is contained in:
parent
e55c6f82b4
commit
0b50a7c261
2 changed files with 162 additions and 145 deletions
|
@ -1,20 +1,16 @@
|
||||||
// SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com>
|
// SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use actix_files::{Files, NamedFile};
|
use actix_files::Files;
|
||||||
use actix_session::{storage::CookieSessionStore, Session, SessionMiddleware};
|
use actix_session::{storage::CookieSessionStore, SessionMiddleware};
|
||||||
use actix_web::{
|
use actix_web::{cookie::Key, middleware, web, App, HttpServer};
|
||||||
cookie::Key,
|
|
||||||
delete, get,
|
|
||||||
http::StatusCode,
|
|
||||||
middleware, post,
|
|
||||||
web::{self, Redirect},
|
|
||||||
App, Either, HttpResponse, HttpServer, Responder,
|
|
||||||
};
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use std::{env, io::Result};
|
use std::{env, io::Result};
|
||||||
|
|
||||||
|
// Import modules
|
||||||
mod auth;
|
mod auth;
|
||||||
mod database;
|
mod database;
|
||||||
|
mod services;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
// This struct represents state
|
// This struct represents state
|
||||||
|
@ -22,132 +18,6 @@ struct AppState {
|
||||||
db: Connection,
|
db: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the version number
|
|
||||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
// Define the routes
|
|
||||||
|
|
||||||
// Add new links
|
|
||||||
#[post("/api/new")]
|
|
||||||
async fn add_link(req: String, data: web::Data<AppState>, session: Session) -> HttpResponse {
|
|
||||||
if env::var("public_mode") == Ok(String::from("Enable")) || auth::validate(session) {
|
|
||||||
let out = utils::add_link(req, &data.db);
|
|
||||||
if out.0 {
|
|
||||||
HttpResponse::Created().body(out.1)
|
|
||||||
} else {
|
|
||||||
HttpResponse::Conflict().body(out.1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
HttpResponse::Unauthorized().body("Not logged in!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return all active links
|
|
||||||
#[get("/api/all")]
|
|
||||||
async fn getall(data: web::Data<AppState>, session: Session) -> HttpResponse {
|
|
||||||
if auth::validate(session) {
|
|
||||||
HttpResponse::Ok().body(utils::getall(&data.db))
|
|
||||||
} else {
|
|
||||||
let body = if env::var("public_mode") == Ok(String::from("Enable")) {
|
|
||||||
"Using public mode."
|
|
||||||
} else {
|
|
||||||
"Not logged in!"
|
|
||||||
};
|
|
||||||
HttpResponse::Unauthorized().body(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the site URL
|
|
||||||
#[get("/api/siteurl")]
|
|
||||||
async fn siteurl() -> HttpResponse {
|
|
||||||
let site_url = env::var("site_url")
|
|
||||||
.ok()
|
|
||||||
.filter(|s| !s.trim().is_empty())
|
|
||||||
.unwrap_or(String::from("unset"));
|
|
||||||
HttpResponse::Ok().body(site_url)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the version number
|
|
||||||
#[get("/api/version")]
|
|
||||||
async fn version() -> HttpResponse {
|
|
||||||
HttpResponse::Ok().body(VERSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 404 error page
|
|
||||||
async fn error404() -> impl Responder {
|
|
||||||
NamedFile::open_async("./resources/static/404.html")
|
|
||||||
.await
|
|
||||||
.customize()
|
|
||||||
.with_status(StatusCode::NOT_FOUND)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle a given shortlink
|
|
||||||
#[get("/{shortlink}")]
|
|
||||||
async fn link_handler(shortlink: web::Path<String>, data: web::Data<AppState>) -> impl Responder {
|
|
||||||
let shortlink_str = shortlink.to_string();
|
|
||||||
if let Some(longlink) = utils::get_longurl(shortlink_str, &data.db) {
|
|
||||||
let redirect_method = env::var("redirect_method").unwrap_or(String::from("PERMANENT"));
|
|
||||||
database::add_hit(shortlink.as_str(), &data.db);
|
|
||||||
if redirect_method == "TEMPORARY" {
|
|
||||||
Either::Left(Redirect::to(longlink))
|
|
||||||
} else {
|
|
||||||
// Defaults to permanent redirection
|
|
||||||
Either::Left(Redirect::to(longlink).permanent())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Either::Right(
|
|
||||||
NamedFile::open_async("./resources/static/404.html")
|
|
||||||
.await
|
|
||||||
.customize()
|
|
||||||
.with_status(StatusCode::NOT_FOUND),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle login
|
|
||||||
#[post("/api/login")]
|
|
||||||
async fn login(req: String, session: Session) -> HttpResponse {
|
|
||||||
if let Ok(password) = env::var("password") {
|
|
||||||
if password != req {
|
|
||||||
eprintln!("Failed login attempt!");
|
|
||||||
return HttpResponse::Unauthorized().body("Wrong password!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return Ok if no password was set on the server side
|
|
||||||
session
|
|
||||||
.insert("chhoto-url-auth", auth::gen_token())
|
|
||||||
.expect("Error inserting auth token.");
|
|
||||||
HttpResponse::Ok().body("Correct password!")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle logout
|
|
||||||
#[delete("/api/logout")]
|
|
||||||
async fn logout(session: Session) -> HttpResponse {
|
|
||||||
if session.remove("chhoto-url-auth").is_some() {
|
|
||||||
HttpResponse::Ok().body("Logged out!")
|
|
||||||
} else {
|
|
||||||
HttpResponse::Unauthorized().body("You don't seem to be logged in.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a given shortlink
|
|
||||||
#[delete("/api/del/{shortlink}")]
|
|
||||||
async fn delete_link(
|
|
||||||
shortlink: web::Path<String>,
|
|
||||||
data: web::Data<AppState>,
|
|
||||||
session: Session,
|
|
||||||
) -> HttpResponse {
|
|
||||||
if auth::validate(session) {
|
|
||||||
if utils::delete_link(shortlink.to_string(), &data.db) {
|
|
||||||
HttpResponse::Ok().body(format!("Deleted {shortlink}"))
|
|
||||||
} else {
|
|
||||||
HttpResponse::NotFound().body("Not found!")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
HttpResponse::Unauthorized().body("Not logged in!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("warn"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("warn"));
|
||||||
|
@ -179,16 +49,16 @@ async fn main() -> Result<()> {
|
||||||
.app_data(web::Data::new(AppState {
|
.app_data(web::Data::new(AppState {
|
||||||
db: database::open_db(db_location.clone()),
|
db: database::open_db(db_location.clone()),
|
||||||
}))
|
}))
|
||||||
.service(link_handler)
|
.service(services::link_handler)
|
||||||
.service(getall)
|
.service(services::getall)
|
||||||
.service(siteurl)
|
.service(services::siteurl)
|
||||||
.service(version)
|
.service(services::version)
|
||||||
.service(add_link)
|
.service(services::add_link)
|
||||||
.service(delete_link)
|
.service(services::delete_link)
|
||||||
.service(login)
|
.service(services::login)
|
||||||
.service(logout)
|
.service(services::logout)
|
||||||
.service(Files::new("/", "./resources/").index_file("index.html"))
|
.service(Files::new("/", "./resources/").index_file("index.html"))
|
||||||
.default_service(web::get().to(error404))
|
.default_service(actix_web::web::get().to(services::error404))
|
||||||
})
|
})
|
||||||
.bind(("0.0.0.0", port))?
|
.bind(("0.0.0.0", port))?
|
||||||
.run()
|
.run()
|
||||||
|
|
147
actix/src/services.rs
Normal file
147
actix/src/services.rs
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use actix_files::NamedFile;
|
||||||
|
use actix_session::Session;
|
||||||
|
use actix_web::{
|
||||||
|
delete, get,
|
||||||
|
http::StatusCode,
|
||||||
|
post,
|
||||||
|
web::{self, Redirect},
|
||||||
|
Either, HttpResponse, Responder,
|
||||||
|
};
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use crate::auth;
|
||||||
|
use crate::database;
|
||||||
|
use crate::utils;
|
||||||
|
use crate::AppState;
|
||||||
|
|
||||||
|
// Store the version number
|
||||||
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
// Define the routes
|
||||||
|
|
||||||
|
// Add new links
|
||||||
|
#[post("/api/new")]
|
||||||
|
pub async fn add_link(req: String, data: web::Data<AppState>, session: Session) -> HttpResponse {
|
||||||
|
if env::var("public_mode") == Ok(String::from("Enable")) || auth::validate(session) {
|
||||||
|
let out = utils::add_link(req, &data.db);
|
||||||
|
if out.0 {
|
||||||
|
HttpResponse::Created().body(out.1)
|
||||||
|
} else {
|
||||||
|
HttpResponse::Conflict().body(out.1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpResponse::Unauthorized().body("Not logged in!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return all active links
|
||||||
|
#[get("/api/all")]
|
||||||
|
pub async fn getall(data: web::Data<AppState>, session: Session) -> HttpResponse {
|
||||||
|
if auth::validate(session) {
|
||||||
|
HttpResponse::Ok().body(utils::getall(&data.db))
|
||||||
|
} else {
|
||||||
|
let body = if env::var("public_mode") == Ok(String::from("Enable")) {
|
||||||
|
"Using public mode."
|
||||||
|
} else {
|
||||||
|
"Not logged in!"
|
||||||
|
};
|
||||||
|
HttpResponse::Unauthorized().body(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the site URL
|
||||||
|
#[get("/api/siteurl")]
|
||||||
|
pub async fn siteurl() -> HttpResponse {
|
||||||
|
let site_url = env::var("site_url")
|
||||||
|
.ok()
|
||||||
|
.filter(|s| !s.trim().is_empty())
|
||||||
|
.unwrap_or(String::from("unset"));
|
||||||
|
HttpResponse::Ok().body(site_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the version number
|
||||||
|
#[get("/api/version")]
|
||||||
|
pub async fn version() -> HttpResponse {
|
||||||
|
HttpResponse::Ok().body(VERSION)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 404 error page
|
||||||
|
pub async fn error404() -> impl Responder {
|
||||||
|
NamedFile::open_async("./resources/static/404.html")
|
||||||
|
.await
|
||||||
|
.customize()
|
||||||
|
.with_status(StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle a given shortlink
|
||||||
|
#[get("/{shortlink}")]
|
||||||
|
pub async fn link_handler(
|
||||||
|
shortlink: web::Path<String>,
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let shortlink_str = shortlink.to_string();
|
||||||
|
if let Some(longlink) = utils::get_longurl(shortlink_str, &data.db) {
|
||||||
|
let redirect_method = env::var("redirect_method").unwrap_or(String::from("PERMANENT"));
|
||||||
|
database::add_hit(shortlink.as_str(), &data.db);
|
||||||
|
if redirect_method == "TEMPORARY" {
|
||||||
|
Either::Left(Redirect::to(longlink))
|
||||||
|
} else {
|
||||||
|
// Defaults to permanent redirection
|
||||||
|
Either::Left(Redirect::to(longlink).permanent())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Either::Right(
|
||||||
|
NamedFile::open_async("./resources/static/404.html")
|
||||||
|
.await
|
||||||
|
.customize()
|
||||||
|
.with_status(StatusCode::NOT_FOUND),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle login
|
||||||
|
#[post("/api/login")]
|
||||||
|
pub async fn login(req: String, session: Session) -> HttpResponse {
|
||||||
|
if let Ok(password) = env::var("password") {
|
||||||
|
if password != req {
|
||||||
|
eprintln!("Failed login attempt!");
|
||||||
|
return HttpResponse::Unauthorized().body("Wrong password!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return Ok if no password was set on the server side
|
||||||
|
session
|
||||||
|
.insert("chhoto-url-auth", auth::gen_token())
|
||||||
|
.expect("Error inserting auth token.");
|
||||||
|
HttpResponse::Ok().body("Correct password!")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle logout
|
||||||
|
#[delete("/api/logout")]
|
||||||
|
pub async fn logout(session: Session) -> HttpResponse {
|
||||||
|
if session.remove("chhoto-url-auth").is_some() {
|
||||||
|
HttpResponse::Ok().body("Logged out!")
|
||||||
|
} else {
|
||||||
|
HttpResponse::Unauthorized().body("You don't seem to be logged in.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a given shortlink
|
||||||
|
#[delete("/api/del/{shortlink}")]
|
||||||
|
pub async fn delete_link(
|
||||||
|
shortlink: web::Path<String>,
|
||||||
|
data: web::Data<AppState>,
|
||||||
|
session: Session,
|
||||||
|
) -> HttpResponse {
|
||||||
|
if auth::validate(session) {
|
||||||
|
if utils::delete_link(shortlink.to_string(), &data.db) {
|
||||||
|
HttpResponse::Ok().body(format!("Deleted {shortlink}"))
|
||||||
|
} else {
|
||||||
|
HttpResponse::NotFound().body("Not found!")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpResponse::Unauthorized().body("Not logged in!")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue