This commit is contained in:
Nicole Tietz-Sokolskaya 2024-06-01 15:54:43 -04:00
parent 0d2c1bacf9
commit af51f3f38f
12 changed files with 55 additions and 38 deletions

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use pique::models::users::{self, NewUser};
use pique::db::establish_connection; use pique::db::establish_connection;
use pique::models::users::{self, NewUser};
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use rand::{distributions::DistString, thread_rng}; use rand::{distributions::DistString, thread_rng};
@ -27,13 +27,7 @@ pub async fn main() -> Result<()> {
password password
} }
}; };
handle_create_user(&db_url, NewUser::new( handle_create_user(&db_url, NewUser::new(name, username, email, password)).await?
name,
username,
email,
password,
))
.await?
} }
AdminCommand::ListUsers => handle_list_users(&db_url).await?, AdminCommand::ListUsers => handle_list_users(&db_url).await?,
}; };

View file

@ -21,5 +21,8 @@ where
E: std::error::Error, E: std::error::Error,
{ {
error!(?err, "internal error"); error!(?err, "internal error");
(StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error".into()) (
StatusCode::INTERNAL_SERVER_ERROR,
"Internal Server Error".into(),
)
} }

View file

@ -26,7 +26,8 @@ async fn render_documents_page(ctx: Context, user: User) -> Result<Response, (St
let mut db = ctx.db_pool.get().map_err(internal_error)?; let mut db = ctx.db_pool.get().map_err(internal_error)?;
let documents = let documents =
permissions::query::accessible_documents(&mut db, &user.id).map_err(internal_error)?; permissions::query::accessible_documents(&mut db, &user.id).map_err(internal_error)?;
let projects = permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?; let projects =
permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! { let values = context! {
user => user, user => user,
@ -117,14 +118,16 @@ pub async fn edit_document_page(
&user.id, &user.id,
&id.to_string(), &id.to_string(),
Permission::Write, Permission::Write,
).map_err(internal_error)?; )
.map_err(internal_error)?;
if !document_allowed { if !document_allowed {
return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); return Err((StatusCode::FORBIDDEN, "permission denied".to_owned()));
} }
let document = documents::query::by_id(&mut db, &id.to_string()).map_err(internal_error)?; let document = documents::query::by_id(&mut db, &id.to_string()).map_err(internal_error)?;
let projects = permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?; let projects =
permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! { let values = context! {
user => user, user => user,
@ -159,7 +162,8 @@ pub async fn edit_document_submit(
&user.id, &user.id,
&document_id.to_string(), &document_id.to_string(),
Permission::Write, Permission::Write,
).map_err(internal_error)?; )
.map_err(internal_error)?;
if !document_allowed { if !document_allowed {
return Err((StatusCode::FORBIDDEN, "permission denied".to_owned())); return Err((StatusCode::FORBIDDEN, "permission denied".to_owned()));
@ -170,7 +174,8 @@ pub async fn edit_document_submit(
&document_id.to_string(), &document_id.to_string(),
form.title.to_owned(), form.title.to_owned(),
form.content.to_owned(), form.content.to_owned(),
).map_err(internal_error)?; )
.map_err(internal_error)?;
Ok(Redirect::to("/documents").into_response()) Ok(Redirect::to("/documents").into_response())
} }

View file

@ -1,10 +1,10 @@
use thiserror::Error; use thiserror::Error;
pub mod users; pub mod documents;
pub mod project_memberships;
pub mod projects; pub mod projects;
pub mod types; pub mod types;
pub mod project_memberships; pub mod users;
pub mod documents;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum DbError { pub enum DbError {

View file

@ -42,7 +42,10 @@ impl NewDocument {
pub mod query { pub mod query {
use super::*; use super::*;
pub fn create(db: &mut SqliteConnection, new_document: NewDocument) -> Result<Document, DbError> { pub fn create(
db: &mut SqliteConnection,
new_document: NewDocument,
) -> Result<Document, DbError> {
diesel::insert_into(dsl::documents) diesel::insert_into(dsl::documents)
.values(&new_document) .values(&new_document)
.execute(db)?; .execute(db)?;
@ -54,19 +57,25 @@ pub mod query {
Ok(document) Ok(document)
} }
pub fn update(db: &mut SqliteConnection, document_id: &str, title: String, content: String) -> Result<Document, DbError> { pub fn update(
db: &mut SqliteConnection,
document_id: &str,
title: String,
content: String,
) -> Result<Document, DbError> {
diesel::update(dsl::documents.filter(dsl::id.eq(document_id))) diesel::update(dsl::documents.filter(dsl::id.eq(document_id)))
.set((dsl::title.eq(title), dsl::content.eq(content))) .set((dsl::title.eq(title), dsl::content.eq(content)))
.execute(db)?; .execute(db)?;
let document = dsl::documents let document = dsl::documents.filter(dsl::id.eq(document_id)).first(db)?;
.filter(dsl::id.eq(document_id))
.first(db)?;
Ok(document) Ok(document)
} }
pub fn by_id(db: &mut SqliteConnection, document_id: &str) -> Result<Option<Document>, DbError> { pub fn by_id(
db: &mut SqliteConnection,
document_id: &str,
) -> Result<Option<Document>, DbError> {
let document = dsl::documents let document = dsl::documents
.filter(dsl::id.eq(document_id)) .filter(dsl::id.eq(document_id))
.first::<Document>(db) .first::<Document>(db)

View file

@ -63,10 +63,10 @@ pub struct NewProjectMembership {
} }
pub mod query { pub mod query {
use diesel::SqliteConnection;
use super::*; use super::*;
use diesel::SqliteConnection;
pub fn create ( pub fn create(
db: &mut SqliteConnection, db: &mut SqliteConnection,
user_id: &str, user_id: &str,
project_id: &str, project_id: &str,

View file

@ -1,5 +1,5 @@
use diesel::prelude::*; use diesel::prelude::*;
use serde::{Serialize}; use serde::Serialize;
use crate::schema::projects::dsl; use crate::schema::projects::dsl;
use uuid::Uuid; use uuid::Uuid;

View file

@ -0,0 +1 @@

View file

@ -51,7 +51,6 @@ impl<'a> Query<'a> {
} }
pub fn all(&mut self) -> Result<Vec<User>, DbError> { pub fn all(&mut self) -> Result<Vec<User>, DbError> {
let user_list = dsl::users.load::<User>(self.db)?; let user_list = dsl::users.load::<User>(self.db)?;
Ok(user_list) Ok(user_list)
} }
@ -62,7 +61,9 @@ impl<'a> Query<'a> {
} }
pub fn by_username(&mut self, username: &str) -> Result<User, DbError> { pub fn by_username(&mut self, username: &str) -> Result<User, DbError> {
let user = dsl::users.filter(dsl::username.eq(username)).first::<User>(self.db)?; let user = dsl::users
.filter(dsl::username.eq(username))
.first::<User>(self.db)?;
Ok(user) Ok(user)
} }
@ -71,7 +72,9 @@ impl<'a> Query<'a> {
.values(&new_user) .values(&new_user)
.execute(self.db)?; .execute(self.db)?;
let new_user = dsl::users.filter(dsl::id.eq(&new_user.id)).first::<User>(self.db)?; let new_user = dsl::users
.filter(dsl::id.eq(&new_user.id))
.first::<User>(self.db)?;
Ok(new_user) Ok(new_user)
} }

View file

@ -39,9 +39,4 @@ diesel::table! {
} }
} }
diesel::allow_tables_to_appear_in_same_query!( diesel::allow_tables_to_appear_in_same_query!(documents, project_memberships, projects, users,);
documents,
project_memberships,
projects,
users,
);

View file

@ -1,7 +1,11 @@
use async_trait::async_trait; use async_trait::async_trait;
use axum_login::{AuthUser, AuthnBackend, UserId}; use axum_login::{AuthUser, AuthnBackend, UserId};
use crate::{models::{self, users, DbError}, password, prelude::*}; use crate::{
models::{self, users, DbError},
password,
prelude::*,
};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Credentials { pub struct Credentials {

View file

@ -1,6 +1,6 @@
use minijinja::{Error, ErrorKind};
use free_icons::IconAttrs; use free_icons::IconAttrs;
use minijinja::{path_loader, Environment}; use minijinja::{path_loader, Environment};
use minijinja::{Error, ErrorKind};
use minijinja_autoreload::AutoReloader; use minijinja_autoreload::AutoReloader;
pub fn make_template_loader(auto_reload: bool) -> AutoReloader { pub fn make_template_loader(auto_reload: bool) -> AutoReloader {
@ -30,5 +30,8 @@ pub fn heroicon_filter(name: String, classes: Option<String>) -> Result<String,
.fill("none") .fill("none")
.stroke_color("currentColor"); .stroke_color("currentColor");
free_icons::heroicons(&name, true, attrs).ok_or(Error::new(ErrorKind::TemplateNotFound, "cannot find template for requested icon")) free_icons::heroicons(&name, true, attrs).ok_or(Error::new(
ErrorKind::TemplateNotFound,
"cannot find template for requested icon",
))
} }