initial commit of slink
This commit is contained in:
+281
@@ -0,0 +1,281 @@
|
||||
use actix_identity::Identity;
|
||||
|
||||
use actix_web::{web, HttpResponse};
|
||||
use qrcodegen::{QrCode, QrCodeEcc};
|
||||
|
||||
use crate::ServerError;
|
||||
|
||||
use super::forms::LinkForm;
|
||||
use super::models::{Link, LoginUser, NewLink, NewUser, User};
|
||||
use argonautica::Verifier;
|
||||
use diesel::sqlite::SqliteConnection;
|
||||
use diesel::{prelude::*, result::Error::NotFound};
|
||||
use dotenv::dotenv;
|
||||
use tera::{Context, Tera};
|
||||
|
||||
fn establish_connection() -> Result<SqliteConnection, ServerError> {
|
||||
dotenv().ok();
|
||||
|
||||
let database_url = std::env::var("DATABASE_URL")?;
|
||||
|
||||
match SqliteConnection::establish(&database_url) {
|
||||
Ok(c) => Ok(c),
|
||||
Err(e) => {
|
||||
info!("Error connecting to database: {}, {}", database_url, e);
|
||||
Err(ServerError::User(
|
||||
"Error connecting to Database".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Show the list of all available links if a user is authenticated
|
||||
pub(crate) async fn index(
|
||||
tera: web::Data<Tera>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
use super::schema::links::dsl::links;
|
||||
use super::schema::users::dsl::users;
|
||||
if let Some(id) = id.identity() {
|
||||
let connection = establish_connection()?;
|
||||
let all_links: Vec<(Link, User)> = links.inner_join(users).load(&connection)?;
|
||||
|
||||
let mut data = Context::new();
|
||||
data.insert("name", &id);
|
||||
data.insert("title", "Links der Freien Hochschule Stuttgart");
|
||||
data.insert("links_per_users", &all_links);
|
||||
|
||||
let rendered = tera.render("index.html", &data)?;
|
||||
Ok(HttpResponse::Ok().body(rendered))
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn view_link(
|
||||
tera: web::Data<Tera>,
|
||||
id: Identity,
|
||||
link_id: web::Path<String>,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
println!("Viewing link!");
|
||||
use super::schema::links::dsl::{code, links};
|
||||
if let Some(id) = id.identity() {
|
||||
let connection = establish_connection()?;
|
||||
let link: Link = links
|
||||
.filter(code.eq(&link_id.0))
|
||||
.first::<Link>(&connection)?;
|
||||
|
||||
let qr =
|
||||
QrCode::encode_text(&format!("http://fhs.li/{}", &link_id.0), QrCodeEcc::Low).unwrap();
|
||||
let svg = qr.to_svg_string(4);
|
||||
|
||||
let mut data = Context::new();
|
||||
data.insert("name", &id);
|
||||
data.insert(
|
||||
"title",
|
||||
&format!("Links {} der Freien Hochschule Stuttgart", link_id.0),
|
||||
);
|
||||
data.insert("link", &link);
|
||||
data.insert("qr", &svg);
|
||||
|
||||
let rendered = tera.render("view_link.html", &data)?;
|
||||
Ok(HttpResponse::Ok().body(rendered))
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn signup(
|
||||
tera: web::Data<Tera>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
if let Some(id) = id.identity() {
|
||||
let mut data = Context::new();
|
||||
data.insert("title", "Sign Up");
|
||||
data.insert("name", &id);
|
||||
|
||||
let rendered = tera.render("signup.html", &data)?;
|
||||
Ok(HttpResponse::Ok().body(rendered))
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn process_signup(
|
||||
data: web::Form<NewUser>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
if let Some(_id) = id.identity() {
|
||||
use super::schema::users;
|
||||
|
||||
let connection = establish_connection()?;
|
||||
let new_user = NewUser::new(
|
||||
data.username.clone(),
|
||||
data.email.clone(),
|
||||
data.password.clone(),
|
||||
)?;
|
||||
|
||||
diesel::insert_into(users::table)
|
||||
.values(&new_user)
|
||||
.execute(&connection)?;
|
||||
|
||||
println!("{:?}", data);
|
||||
Ok(HttpResponse::Ok().body(format!("Successfully saved user: {}", data.username)))
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn login(
|
||||
tera: web::Data<Tera>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
let mut data = Context::new();
|
||||
data.insert("title", "Login");
|
||||
|
||||
if let Some(_id) = id.identity() {
|
||||
return Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/index/")
|
||||
.body("Redirect to /index/"));
|
||||
}
|
||||
|
||||
let rendered = tera.render("login.html", &data)?;
|
||||
Ok(HttpResponse::Ok().body(rendered))
|
||||
}
|
||||
|
||||
pub(crate) async fn process_login(
|
||||
data: web::Form<LoginUser>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
use super::schema::users::dsl::{username, users};
|
||||
|
||||
let connection = establish_connection()?;
|
||||
let user = users
|
||||
.filter(username.eq(&data.username))
|
||||
.first::<User>(&connection);
|
||||
|
||||
match user {
|
||||
Ok(u) => {
|
||||
dotenv().ok();
|
||||
let secret = std::env::var("SECRET_KEY")?;
|
||||
|
||||
let valid = Verifier::default()
|
||||
.with_hash(u.password)
|
||||
.with_password(data.password.clone())
|
||||
.with_secret_key(secret)
|
||||
.verify()?;
|
||||
|
||||
if valid {
|
||||
let session_token = u.username;
|
||||
id.remember(session_token);
|
||||
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/index/")
|
||||
.body("Redirect to /index/"))
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
Err(_e) => Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/")),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn logout(id: Identity) -> Result<HttpResponse, ServerError> {
|
||||
id.forget();
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
|
||||
pub(crate) async fn redirect(
|
||||
tera: web::Data<Tera>,
|
||||
data: web::Path<String>,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
use super::schema::links::dsl::{code, links};
|
||||
let connection = establish_connection()?;
|
||||
|
||||
let link = links.filter(code.eq(&data.0)).first::<Link>(&connection);
|
||||
match link {
|
||||
Ok(link) => Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, link.target.clone())
|
||||
.body(format!("Redirect to {}", link.target))),
|
||||
Err(NotFound) => {
|
||||
let mut data = Context::new();
|
||||
data.insert("title", "Wurde gelöscht");
|
||||
let rendered = tera.render("not_found.html", &data)?;
|
||||
Ok(HttpResponse::NotFound().body(rendered))
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn redirect_fhs() -> Result<HttpResponse, ServerError> {
|
||||
Ok(HttpResponse::TemporaryRedirect().set_header(
|
||||
actix_web::http::header::LOCATION,
|
||||
"https://www.freie-hochschule-stuttgart.de",
|
||||
).body("If you are not redirected automatically go to https://www.freie-hochschule-stuttgart.de"))
|
||||
}
|
||||
|
||||
pub(crate) async fn submission(
|
||||
tera: web::Data<Tera>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
if let Some(id) = id.identity() {
|
||||
let mut data = Context::new();
|
||||
data.insert("title", "Submit a Post");
|
||||
|
||||
data.insert("name", &id);
|
||||
let rendered = tera.render("submission.html", &data)?;
|
||||
return Ok(HttpResponse::Ok().body(rendered));
|
||||
}
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
|
||||
pub(crate) async fn process_submission(
|
||||
data: web::Form<LinkForm>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
if let Some(id) = id.identity() {
|
||||
use super::schema::users::dsl::{username, users};
|
||||
|
||||
let connection = establish_connection()?;
|
||||
let user: Result<User, diesel::result::Error> =
|
||||
users.filter(username.eq(id)).first(&connection);
|
||||
|
||||
match user {
|
||||
Ok(u) => {
|
||||
use super::schema::links;
|
||||
let new_post = NewLink::from_link_form(data.into_inner(), u.id);
|
||||
|
||||
diesel::insert_into(links::table)
|
||||
.values(&new_post)
|
||||
.execute(&connection)?;
|
||||
|
||||
return Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/index/")
|
||||
.body("Redirect to /index/"));
|
||||
}
|
||||
Err(_e) => Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/")),
|
||||
}
|
||||
} else {
|
||||
Ok(HttpResponse::TemporaryRedirect()
|
||||
.set_header(actix_web::http::header::LOCATION, "/login/")
|
||||
.body("Redirect to /login/"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user