Document and simplify

This commit is contained in:
Dietrich 2021-06-16 10:45:23 +02:00 committed by Franz Dietrich
parent 38800bb33c
commit f7f10c5577
5 changed files with 89 additions and 203 deletions

View File

@ -1,7 +0,0 @@
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct LinkForm {
pub title: String,
pub target: String,
pub code: String,
}

View File

@ -1,6 +1,5 @@
extern crate sqlx; extern crate sqlx;
pub mod forms;
pub mod models; pub mod models;
pub mod queries; pub mod queries;
mod views; mod views;
@ -206,7 +205,6 @@ static_loader! {
/// ///
/// # Errors /// # Errors
/// This produces a [`ServerError`] if: /// This produces a [`ServerError`] if:
/// * Tera failed to build its templates
/// * The server failed to bind to the designated port. /// * The server failed to bind to the designated port.
#[allow(clippy::future_not_send, clippy::too_many_lines)] #[allow(clippy::future_not_send, clippy::too_many_lines)]
pub async fn webservice( pub async fn webservice(

View File

@ -1,6 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use crate::{forms::LinkForm, Secret, ServerConfig, ServerError}; use crate::{Secret, ServerConfig, ServerError};
use argonautica::Hasher; use argonautica::Hasher;
use async_trait::async_trait; use async_trait::async_trait;
@ -14,6 +14,7 @@ use shared::{
use sqlx::Row; use sqlx::Row;
use tracing::{error, info, instrument}; use tracing::{error, info, instrument};
/// The operations a User should support.
#[async_trait] #[async_trait]
pub trait UserDbOperations<T> { pub trait UserDbOperations<T> {
async fn get_user(id: i64, server_config: &ServerConfig) -> Result<T, ServerError>; async fn get_user(id: i64, server_config: &ServerConfig) -> Result<T, ServerError>;
@ -31,6 +32,10 @@ pub trait UserDbOperations<T> {
#[async_trait] #[async_trait]
impl UserDbOperations<Self> for User { impl UserDbOperations<Self> for User {
/// get a user by its id
///
/// # Errors
/// fails with [`ServerError`] if the user does not exist or the database cannot be acessed.
#[instrument()] #[instrument()]
async fn get_user(id: i64, server_config: &ServerConfig) -> Result<Self, ServerError> { async fn get_user(id: i64, server_config: &ServerConfig) -> Result<Self, ServerError> {
let user = sqlx::query!("Select * from users where id = ? ", id) let user = sqlx::query!("Select * from users where id = ? ", id)
@ -70,6 +75,10 @@ impl UserDbOperations<Self> for User {
user.map_err(ServerError::Database) user.map_err(ServerError::Database)
} }
/// get all users
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed.
#[instrument()] #[instrument()]
async fn get_all_users(server_config: &ServerConfig) -> Result<Vec<Self>, ServerError> { async fn get_all_users(server_config: &ServerConfig) -> Result<Vec<Self>, ServerError> {
let user = sqlx::query("Select * from users") let user = sqlx::query("Select * from users")
@ -91,6 +100,10 @@ impl UserDbOperations<Self> for User {
user.map_err(ServerError::Database) user.map_err(ServerError::Database)
} }
/// change a user
///
/// # Errors
/// fails with [`ServerError`] if the user does not exist, some constraints are not satisfied or the database cannot be acessed.
#[instrument()] #[instrument()]
async fn update_user(&self, server_config: &ServerConfig) -> Result<(), ServerError> { async fn update_user(&self, server_config: &ServerConfig) -> Result<(), ServerError> {
let role_i64 = self.role.to_i64(); let role_i64 = self.role.to_i64();
@ -129,6 +142,10 @@ impl UserDbOperations<Self> for User {
Ok(()) Ok(())
} }
/// set the language setting of a user
///
/// # Errors
/// fails with [`ServerError`] if the user does not exist or the database cannot be acessed.
#[instrument()] #[instrument()]
async fn set_language( async fn set_language(
self, self,
@ -161,6 +178,8 @@ impl UserDbOperations<Self> for User {
} }
} }
/// Relevant parameters when creating a new user
/// Use the [`NewUser::new`] constructor to store the password encrypted. Otherwise it will not work.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct NewUser { pub struct NewUser {
pub username: String, pub username: String,
@ -171,6 +190,8 @@ pub struct NewUser {
impl NewUser { impl NewUser {
/// Create a new user that can then be inserted in the database /// Create a new user that can then be inserted in the database
/// ///
/// The password is encrypted using the secret before creating.
///
/// # Errors /// # Errors
/// fails with [`ServerError`] if the password could not be encrypted. /// fails with [`ServerError`] if the password could not be encrypted.
#[instrument()] #[instrument()]
@ -189,6 +210,9 @@ impl NewUser {
}) })
} }
/// encrypt the password.
///
/// This function uses the Secret from the config settings to encrypt the password
#[instrument()] #[instrument()]
pub(crate) fn hash_password(password: &str, secret: &Secret) -> Result<String, ServerError> { pub(crate) fn hash_password(password: &str, secret: &Secret) -> Result<String, ServerError> {
dotenv().ok(); dotenv().ok();
@ -223,6 +247,7 @@ impl NewUser {
} }
} }
/// Operations that should be supported by links
#[async_trait] #[async_trait]
pub trait LinkDbOperations<T> { pub trait LinkDbOperations<T> {
async fn get_link_by_code(code: &str, server_config: &ServerConfig) -> Result<T, ServerError>; async fn get_link_by_code(code: &str, server_config: &ServerConfig) -> Result<T, ServerError>;
@ -236,6 +261,10 @@ pub trait LinkDbOperations<T> {
#[async_trait] #[async_trait]
impl LinkDbOperations<Self> for Link { impl LinkDbOperations<Self> for Link {
/// Get a link by its code (the short url code)
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed or the link is not found.
#[instrument()] #[instrument()]
async fn get_link_by_code( async fn get_link_by_code(
code: &str, code: &str,
@ -251,6 +280,11 @@ impl LinkDbOperations<Self> for Link {
tracing::info!("Found link: {:?}", &link); tracing::info!("Found link: {:?}", &link);
link.map_err(ServerError::Database) link.map_err(ServerError::Database)
} }
/// Get a link by its id
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed or the link is not found.
#[instrument()] #[instrument()]
async fn get_link_by_id(id: i64, server_config: &ServerConfig) -> Result<Self, ServerError> { async fn get_link_by_id(id: i64, server_config: &ServerConfig) -> Result<Self, ServerError> {
let link = sqlx::query_as!(Self, "Select * from links where id = ? ", id) let link = sqlx::query_as!(Self, "Select * from links where id = ? ", id)
@ -260,6 +294,10 @@ impl LinkDbOperations<Self> for Link {
link.map_err(ServerError::Database) link.map_err(ServerError::Database)
} }
/// Delete a link by its code
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed or the link is not found.
#[instrument()] #[instrument()]
async fn delete_link_by_code( async fn delete_link_by_code(
code: &str, code: &str,
@ -271,6 +309,11 @@ impl LinkDbOperations<Self> for Link {
Ok(()) Ok(())
} }
/// Update a link with new values, carful when changing the code the old link becomes invalid.
/// This could be a problem when it is printed or published somewhere.
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed or the link is not found.
#[instrument()] #[instrument()]
async fn update_link(&self, server_config: &ServerConfig) -> Result<(), ServerError> { async fn update_link(&self, server_config: &ServerConfig) -> Result<(), ServerError> {
info!("{:?}", self); info!("{:?}", self);
@ -299,6 +342,7 @@ impl LinkDbOperations<Self> for Link {
} }
} }
/// Relevant parameters when creating a new link.
#[derive(Serialize, Debug)] #[derive(Serialize, Debug)]
pub struct NewLink { pub struct NewLink {
pub title: String, pub title: String,
@ -309,15 +353,7 @@ pub struct NewLink {
} }
impl NewLink { impl NewLink {
pub(crate) fn from_link_form(form: LinkForm, uid: i64) -> Self { /// Take a [`LinkDelta`] and create a [`NewLink`] instance. `created_at` is populated with the current time.
Self {
title: form.title,
target: form.target,
code: form.code,
author: uid,
created_at: chrono::Local::now().naive_utc(),
}
}
pub(crate) fn from_link_delta(link: LinkDelta, uid: i64) -> Self { pub(crate) fn from_link_delta(link: LinkDelta, uid: i64) -> Self {
Self { Self {
title: link.title, title: link.title,
@ -328,6 +364,10 @@ impl NewLink {
} }
} }
/// Insert the new link into the database
///
/// # Errors
/// fails with [`ServerError`] if the database cannot be acessed or constraints are not met.
pub(crate) async fn insert(self, server_config: &ServerConfig) -> Result<(), ServerError> { pub(crate) async fn insert(self, server_config: &ServerConfig) -> Result<(), ServerError> {
sqlx::query!( sqlx::query!(
"Insert into links ( "Insert into links (
@ -348,6 +388,7 @@ impl NewLink {
} }
} }
/// Whenever a link is clicked the click is registered for statistical purposes.
#[derive(Serialize)] #[derive(Serialize)]
pub struct NewClick { pub struct NewClick {
pub link: i64, pub link: i64,

View File

@ -1,7 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use actix_identity::Identity; use actix_identity::Identity;
use actix_web::web;
use enum_map::EnumMap; use enum_map::EnumMap;
use serde::Serialize; use serde::Serialize;
use shared::{ use shared::{
@ -17,12 +16,11 @@ use tracing::{info, instrument, warn};
use super::models::NewUser; use super::models::NewUser;
use crate::{ use crate::{
forms::LinkForm,
models::{LinkDbOperations, NewClick, NewLink, UserDbOperations}, models::{LinkDbOperations, NewClick, NewLink, UserDbOperations},
ServerConfig, ServerError, ServerConfig, ServerError,
}; };
/// The possible roles a user could have. /// This type is used to guard the Roles. The typesystem enforces that the user can only be extracted if permissions are considered.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum RoleGuard { pub enum RoleGuard {
NotAuthenticated, NotAuthenticated,
@ -34,10 +32,10 @@ pub enum RoleGuard {
impl RoleGuard { impl RoleGuard {
fn create(user: &User) -> Self { fn create(user: &User) -> Self {
match user.role { match user.role {
shared::apirequests::users::Role::NotAuthenticated => Self::NotAuthenticated, Role::NotAuthenticated => Self::NotAuthenticated,
shared::apirequests::users::Role::Disabled => Self::Disabled, Role::Disabled => Self::Disabled,
shared::apirequests::users::Role::Regular => Self::Regular { user: user.clone() }, Role::Regular => Self::Regular { user: user.clone() },
shared::apirequests::users::Role::Admin => Self::Admin { user: user.clone() }, Role::Admin => Self::Admin { user: user.clone() },
} }
} }
/// Determin if the user is admin or the given user id is his own. This is used for things where users can edit or view their own entries, whereas admins can do so for all entries. /// Determin if the user is admin or the given user id is his own. This is used for things where users can edit or view their own entries, whereas admins can do so for all entries.
@ -50,7 +48,7 @@ impl RoleGuard {
} }
} }
/// queries the user matching the given [`actix_identity::Identity`] and determins its authentication and permission level. Returns a [`Role`] containing the user if it is authenticated. /// queries the user matching the given [`actix_identity::Identity`] and determins its authentication and permission level. Returns a [`RoleGuard`] containing the user if it is authenticated.
/// ///
/// # Errors /// # Errors
/// Fails only if there are issues using the database. /// Fails only if there are issues using the database.
@ -78,6 +76,8 @@ pub struct ListWithOwner<T> {
/// Returns a List of `FullLink` meaning `Links` enriched by their author and statistics. This returns all links if the user is either Admin or Regular user. /// Returns a List of `FullLink` meaning `Links` enriched by their author and statistics. This returns all links if the user is either Admin or Regular user.
/// ///
/// Todo: this function only naively protects agains SQL-injections use better variants.
///
/// # Errors /// # Errors
/// Fails with [`ServerError`] if access to the database fails. /// Fails with [`ServerError`] if access to the database fails.
#[instrument(skip(id))] #[instrument(skip(id))]
@ -153,6 +153,9 @@ pub async fn list_all_allowed(
} }
} }
/// Generate a filter statement for the SQL-Query according to the parameters...
///
/// Todo: this function only naively protects agains SQL-injections use better variants.
fn generate_filter_sql(filters: &EnumMap<LinkOverviewColumns, Filter>) -> String { fn generate_filter_sql(filters: &EnumMap<LinkOverviewColumns, Filter>) -> String {
let mut result = String::new(); let mut result = String::new();
let filterstring = filters let filterstring = filters
@ -190,6 +193,8 @@ fn generate_filter_sql(filters: &EnumMap<LinkOverviewColumns, Filter>) -> String
} }
result result
} }
/// A macro to translate the Ordering Type into a sql ordering string.
macro_rules! ts { macro_rules! ts {
($ordering:expr) => { ($ordering:expr) => {
match $ordering { match $ordering {
@ -198,6 +203,8 @@ macro_rules! ts {
}; };
}; };
} }
/// Generate a order statement for the SQL-Query according to the parameters...
fn generate_order_sql(order: &Operation<LinkOverviewColumns, Ordering>) -> String { fn generate_order_sql(order: &Operation<LinkOverviewColumns, Ordering>) -> String {
let filterstring = match order.column { let filterstring = match order.column {
LinkOverviewColumns::Code => { LinkOverviewColumns::Code => {
@ -219,10 +226,10 @@ fn generate_order_sql(order: &Operation<LinkOverviewColumns, Ordering>) -> Strin
filterstring filterstring
} }
/// Only admins can list all users /// Only admins can list all users other users will only see themselves.
/// ///
/// # Errors /// # Errors
/// Fails with [`ServerError`] if access to the database fails or this user does not have permissions. /// Fails with [`ServerError`] if access to the database fails.
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn list_users( pub async fn list_users(
id: &Identity, id: &Identity,
@ -265,6 +272,9 @@ pub async fn list_users(
} }
} }
/// Generate a filter statement for the SQL-Query according to the parameters...
///
/// Todo: this function only naively protects agains SQL-injections use better variants.
fn generate_filter_users_sql(filters: &EnumMap<UserOverviewColumns, Filter>) -> String { fn generate_filter_users_sql(filters: &EnumMap<UserOverviewColumns, Filter>) -> String {
let mut result = String::new(); let mut result = String::new();
let filterstring = filters let filterstring = filters
@ -296,6 +306,8 @@ fn generate_filter_users_sql(filters: &EnumMap<UserOverviewColumns, Filter>) ->
} }
result result
} }
/// Generate a order statement for the SQL-Query according to the parameters...
fn generate_order_users_sql(order: &Operation<UserOverviewColumns, Ordering>) -> String { fn generate_order_users_sql(order: &Operation<UserOverviewColumns, Ordering>) -> String {
let filterstring = match order.column { let filterstring = match order.column {
UserOverviewColumns::Id => { UserOverviewColumns::Id => {
@ -372,42 +384,7 @@ pub async fn get_user_by_name(
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn create_user( pub async fn create_user(
id: &Identity, id: &Identity,
data: &web::Form<NewUser>, data: UserDelta,
server_config: &ServerConfig,
) -> Result<Item<User>, ServerError> {
info!("Creating a User: {:?}", &data);
let auth = authenticate(id, server_config).await?;
match auth {
RoleGuard::Admin { user } => {
let new_user = NewUser::new(
data.username.clone(),
data.email.clone(),
&data.password,
&server_config.secret,
)?;
new_user.insert_user(server_config).await?;
// querry the new user
let new_user = get_user_by_name(&data.username, server_config).await?;
Ok(Item {
user,
item: new_user,
})
}
RoleGuard::Regular { .. } | RoleGuard::Disabled | RoleGuard::NotAuthenticated => {
Err(ServerError::User("Permission denied!".to_owned()))
}
}
}
/// Create a new user and save it to the database
///
/// # Errors
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions or the user already exists.
#[instrument(skip(id))]
pub async fn create_user_json(
id: &Identity,
data: &web::Json<UserDelta>,
server_config: &ServerConfig, server_config: &ServerConfig,
) -> Result<Item<User>, ServerError> { ) -> Result<Item<User>, ServerError> {
info!("Creating a User: {:?}", &data); info!("Creating a User: {:?}", &data);
@ -448,6 +425,7 @@ pub async fn create_user_json(
} }
} }
} }
/// Take a [`actix_web::web::Form<NewUser>`] and update the corresponding entry in the database. /// Take a [`actix_web::web::Form<NewUser>`] and update the corresponding entry in the database.
/// The password is only updated if a new password of at least 4 characters is provided. /// The password is only updated if a new password of at least 4 characters is provided.
/// The `user_id` is never changed. /// The `user_id` is never changed.
@ -456,9 +434,9 @@ pub async fn create_user_json(
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed. /// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed.
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn update_user_json( pub async fn update_user(
id: &Identity, id: &Identity,
data: &web::Json<UserDelta>, data: &UserDelta,
server_config: &ServerConfig, server_config: &ServerConfig,
) -> Result<Item<User>, ServerError> { ) -> Result<Item<User>, ServerError> {
let auth = authenticate(id, server_config).await?; let auth = authenticate(id, server_config).await?;
@ -469,10 +447,10 @@ pub async fn update_user_json(
RoleGuard::Admin { .. } | RoleGuard::Regular { .. } => { RoleGuard::Admin { .. } | RoleGuard::Regular { .. } => {
info!("Updating userinfo: "); info!("Updating userinfo: ");
let password = match &data.password { let password = match &data.password {
Some(password) => { Some(password) if password.len() > 4 => {
Secret::new(NewUser::hash_password(password, &server_config.secret)?) Secret::new(NewUser::hash_password(password, &server_config.secret)?)
} }
None => unmodified_user.password, _ => unmodified_user.password,
}; };
let new_user = User { let new_user = User {
id: uid, id: uid,
@ -501,61 +479,6 @@ pub async fn update_user_json(
} }
} }
/// Take a [`actix_web::web::Form<NewUser>`] and update the corresponding entry in the database.
/// The password is only updated if a new password of at least 4 characters is provided.
/// The `user_id` is never changed.
///
/// # Errors
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed.
#[allow(clippy::missing_panics_doc)]
#[instrument(skip(id))]
pub async fn update_user(
id: &Identity,
user_id: &str,
server_config: &ServerConfig,
data: &web::Form<NewUser>,
) -> Result<Item<User>, ServerError> {
if let Ok(uid) = user_id.parse::<i64>() {
let auth = authenticate(id, server_config).await?;
let unmodified_user = User::get_user(uid, server_config).await?;
if auth.admin_or_self(uid) {
match auth {
RoleGuard::Admin { .. } | RoleGuard::Regular { .. } => {
info!("Updating userinfo: ");
let password = if data.password.len() > 3 {
Secret::new(NewUser::hash_password(
&data.password,
&server_config.secret,
)?)
} else {
unmodified_user.password
};
let new_user = User {
id: uid,
username: data.username.clone(),
email: data.email.clone(),
password,
role: unmodified_user.role,
language: unmodified_user.language,
};
new_user.update_user(server_config).await?;
let changed_user = User::get_user(uid, server_config).await?;
Ok(Item {
user: changed_user.clone(),
item: changed_user,
})
}
RoleGuard::NotAuthenticated | RoleGuard::Disabled => {
unreachable!("Should be unreachable because of the `admin_or_self`")
}
}
} else {
Err(ServerError::User("Not a valid UID".to_owned()))
}
} else {
Err(ServerError::User("Permission denied".to_owned()))
}
}
/// Demote an admin user to a normal user or promote a normal user to admin privileges. /// Demote an admin user to a normal user or promote a normal user to admin privileges.
/// ///
/// # Errors /// # Errors
@ -707,44 +630,6 @@ pub async fn delete_link(
} }
} }
/// Update a link if the user is admin or it is its own link.
///
/// # Errors
/// Fails with [`ServerError`] if access to the database fails or this user does not have permissions.
#[instrument(skip(id))]
pub async fn update_link(
id: &Identity,
link_code: &str,
data: web::Form<LinkForm>,
server_config: &ServerConfig,
) -> Result<Item<Link>, ServerError> {
info!("Changing link to: {:?} {:?}", &data, &link_code);
let auth = authenticate(id, server_config).await?;
match auth {
RoleGuard::Admin { .. } | RoleGuard::Regular { .. } => {
let query: Item<Link> = get_link(id, link_code, server_config).await?;
if auth.admin_or_self(query.item.author) {
let mut link = query.item;
let LinkForm {
title,
target,
code,
} = data.into_inner();
link.code = code.clone();
link.target = target;
link.title = title;
link.update_link(server_config).await?;
get_link(id, &code, server_config).await
} else {
Err(ServerError::User("Not Allowed".to_owned()))
}
}
RoleGuard::Disabled | RoleGuard::NotAuthenticated => {
Err(ServerError::User("Not Allowed".to_owned()))
}
}
}
/// Create a new link /// Create a new link
/// ///
/// # Errors /// # Errors
@ -752,7 +637,7 @@ pub async fn update_link(
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn create_link( pub async fn create_link(
id: &Identity, id: &Identity,
data: web::Form<LinkForm>, data: LinkDelta,
server_config: &ServerConfig, server_config: &ServerConfig,
) -> Result<Item<Link>, ServerError> { ) -> Result<Item<Link>, ServerError> {
let auth = authenticate(id, server_config).await?; let auth = authenticate(id, server_config).await?;
@ -760,38 +645,7 @@ pub async fn create_link(
RoleGuard::Admin { user } | RoleGuard::Regular { user } => { RoleGuard::Admin { user } | RoleGuard::Regular { user } => {
let code = data.code.clone(); let code = data.code.clone();
info!("Creating link for: {}", &code); info!("Creating link for: {}", &code);
let new_link = NewLink::from_link_form(data.into_inner(), user.id); let new_link = NewLink::from_link_delta(data, user.id);
info!("Creating link for: {:?}", &new_link);
new_link.insert(server_config).await?;
let new_link: Link = get_link_simple(&code, server_config).await?;
Ok(Item {
user,
item: new_link,
})
}
RoleGuard::Disabled | RoleGuard::NotAuthenticated => {
Err(ServerError::User("Permission denied!".to_owned()))
}
}
}
/// Create a new link
///
/// # Errors
/// Fails with [`ServerError`] if access to the database fails or this user does not have permissions.
#[instrument(skip(id))]
pub async fn create_link_json(
id: &Identity,
data: web::Json<LinkDelta>,
server_config: &ServerConfig,
) -> Result<Item<Link>, ServerError> {
let auth = authenticate(id, server_config).await?;
match auth {
RoleGuard::Admin { user } | RoleGuard::Regular { user } => {
let code = data.code.clone();
info!("Creating link for: {}", &code);
let new_link = NewLink::from_link_delta(data.into_inner(), user.id);
info!("Creating link for: {:?}", &new_link); info!("Creating link for: {:?}", &new_link);
new_link.insert(server_config).await?; new_link.insert(server_config).await?;
@ -812,9 +666,9 @@ pub async fn create_link_json(
/// # Errors /// # Errors
/// Fails with [`ServerError`] if access to the database fails or this user does not have permissions. /// Fails with [`ServerError`] if access to the database fails or this user does not have permissions.
#[instrument(skip(ident))] #[instrument(skip(ident))]
pub async fn update_link_json( pub async fn update_link(
ident: &Identity, ident: &Identity,
data: web::Json<LinkDelta>, data: LinkDelta,
server_config: &ServerConfig, server_config: &ServerConfig,
) -> Result<Item<Link>, ServerError> { ) -> Result<Item<Link>, ServerError> {
let auth = authenticate(ident, server_config).await?; let auth = authenticate(ident, server_config).await?;
@ -829,7 +683,7 @@ pub async fn update_link_json(
target, target,
code, code,
.. ..
} = data.into_inner(); } = data;
link.code = code.clone(); link.code = code.clone();
link.target = target; link.target = target;
link.title = title; link.title = title;

View File

@ -178,11 +178,11 @@ pub async fn download_png(
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn process_create_user_json( pub async fn process_create_user_json(
config: web::Data<crate::ServerConfig>, config: web::Data<crate::ServerConfig>,
form: web::Json<UserDelta>, data: web::Json<UserDelta>,
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api"); info!("Listing Users to Json api");
match queries::create_user_json(&id, &form, &config).await { match queries::create_user(&id, data.into_inner(), &config).await {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message {
message: format!("Successfully saved user: {}", item.item.username), message: format!("Successfully saved user: {}", item.item.username),
}))), }))),
@ -197,7 +197,7 @@ pub async fn process_update_user_json(
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api"); info!("Listing Users to Json api");
match queries::update_user_json(&id, &form, &config).await { match queries::update_user(&id, &form, &config).await {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message {
message: format!("Successfully saved user: {}", item.item.username), message: format!("Successfully saved user: {}", item.item.username),
}))), }))),
@ -360,7 +360,7 @@ pub async fn process_create_link_json(
data: web::Json<LinkDelta>, data: web::Json<LinkDelta>,
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
let new_link = queries::create_link_json(&id, data, &config).await; let new_link = queries::create_link(&id, data.into_inner(), &config).await;
match new_link { match new_link {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message {
message: format!("Successfully saved link: {}", item.item.code), message: format!("Successfully saved link: {}", item.item.code),
@ -375,7 +375,7 @@ pub async fn process_update_link_json(
data: web::Json<LinkDelta>, data: web::Json<LinkDelta>,
id: Identity, id: Identity,
) -> Result<HttpResponse, ServerError> { ) -> Result<HttpResponse, ServerError> {
let new_link = queries::update_link_json(&id, data, &config).await; let new_link = queries::update_link(&id, data.into_inner(), &config).await;
match new_link { match new_link {
Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message { Ok(item) => Ok(HttpResponse::Ok().json2(&Status::Success(Message {
message: format!("Successfully updated link: {}", item.item.code), message: format!("Successfully updated link: {}", item.item.code),