fix clippy issues
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Hamcha 2023-07-07 00:29:55 +02:00
parent 089163f79d
commit 9d6586063d
Signed by: hamcha
GPG Key ID: 1669C533B8CF6D89
8 changed files with 40 additions and 47 deletions

View File

@ -10,7 +10,7 @@ use crate::http::error::ApiError;
use super::{hash::random, user::User};
pub const USER_NOT_FOUND: ApiError<'static> = ApiError::ClientError {
pub const USER_NOT_FOUND: ApiError<'static> = ApiError::Client {
status: StatusCode::UNAUTHORIZED,
code: "user-not-found",
message: "The logged-in user was not found",
@ -49,7 +49,7 @@ impl Session {
Ok(Self {
id: result.id,
actor: user_id,
secret: secret,
secret,
created_at: now,
expires_at: now + duration,
})
@ -109,7 +109,7 @@ impl Session {
}
}
pub async fn refresh(self: Self, pool: &Pool<Postgres>, duration: Duration) -> Result<Self> {
pub async fn refresh(self, pool: &Pool<Postgres>, duration: Duration) -> Result<Self> {
let expires_at = (Utc::now() + duration).naive_utc();
sqlx::query!(
@ -123,13 +123,13 @@ impl Session {
Ok(Session { expires_at, ..self })
}
pub fn token(self: &Self) -> String {
pub fn token(&self) -> String {
format!("{}:{}", self.id.as_u128(), self.secret)
}
pub fn parse_token(token: &str) -> Result<(Uuid, String)> {
let (uuid_str, token_str) = token
.split_once(":")
.split_once(':')
.ok_or_else(|| anyhow!("malformed token"))?;
Ok((
Uuid::from_u128(uuid_str.parse::<u128>()?),
@ -137,7 +137,7 @@ impl Session {
))
}
pub async fn destroy(self: Self, pool: &Pool<Postgres>) -> Result<()> {
pub async fn destroy(&self, pool: &Pool<Postgres>) -> Result<()> {
sqlx::query!("DELETE FROM sessions WHERE id = $1", self.id)
.execute(pool)
.await?;
@ -152,7 +152,7 @@ impl Session {
Ok(result.rows_affected())
}
pub fn cookie(self: &Self, domain: &str, secure: bool) -> String {
pub fn cookie(&self, domain: &str, secure: bool) -> String {
Cookie::build("session", self.token())
.domain(domain)
.secure(secure)

View File

@ -10,5 +10,5 @@ pub enum Error {
IdentifierNotAvailable,
#[error("Database error: {0}")]
DatabaseError(#[from] sqlx::Error),
QueryFailed(#[from] sqlx::Error),
}

View File

@ -63,7 +63,7 @@ impl SiteRepository for Database {
})?;
if result.rows_affected() == 0 {
return Err(Error::NotFound.into());
return Err(Error::NotFound);
}
Ok(())
@ -90,7 +90,7 @@ impl SiteRepository for Database {
};
if result.rows_affected() == 0 {
return Err(Error::NotFound.into());
return Err(Error::NotFound);
}
Ok(())

View File

@ -10,12 +10,12 @@ use thiserror::Error;
use crate::content;
// Generic errors
const ERR_NOT_FOUND: ApiError<'static> = ApiError::ClientError {
const ERR_NOT_FOUND: ApiError<'static> = ApiError::Client {
status: StatusCode::NOT_FOUND,
code: "not-found",
message: "resource not found",
};
const ERR_NOT_AVAILABLE: ApiError<'static> = ApiError::ClientError {
const ERR_NOT_AVAILABLE: ApiError<'static> = ApiError::Client {
status: StatusCode::CONFLICT,
code: "id-not-available",
message: "the chosen identifier is not available",
@ -24,41 +24,41 @@ const ERR_NOT_AVAILABLE: ApiError<'static> = ApiError::ClientError {
#[derive(Error, Debug)]
pub enum ApiError<'a> {
#[error("client error: <{code}> {message}")]
ClientError {
Client {
status: StatusCode,
code: &'a str,
message: &'a str,
},
#[error("unexpected internal error: {0}")]
InternalError(#[from] anyhow::Error),
Internal(#[from] anyhow::Error),
#[error("database returnede error: {0}")]
DatabaseError(#[from] sqlx::Error),
Database(#[from] sqlx::Error),
#[error("incoming JSON format error: {0}")]
JSONFormatError(#[from] JsonRejection),
JSONFormat(#[from] JsonRejection),
}
impl IntoResponse for ApiError<'_> {
fn into_response(self) -> Response {
match self {
ApiError::InternalError(err) => (
ApiError::Internal(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({"code":"server-error", "message": err.to_string()})),
)
.into_response(),
ApiError::DatabaseError(err) => (
ApiError::Database(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(json!({"code":"server-error", "message": err.to_string()})),
)
.into_response(),
ApiError::ClientError {
ApiError::Client {
status,
code,
message,
} => (status, Json(json!({"code":code, "message": message}))).into_response(),
ApiError::JSONFormatError(rejection) => {
ApiError::JSONFormat(rejection) => {
let status = match rejection {
JsonRejection::JsonDataError(_) => StatusCode::UNPROCESSABLE_ENTITY,
JsonRejection::JsonSyntaxError(_) => StatusCode::BAD_REQUEST,
@ -80,7 +80,7 @@ impl From<content::Error> for ApiError<'_> {
match err {
content::Error::NotFound => ERR_NOT_FOUND,
content::Error::IdentifierNotAvailable => ERR_NOT_AVAILABLE,
content::Error::DatabaseError(err) => err.into(),
content::Error::QueryFailed(err) => err.into(),
}
}
}

View File

@ -22,16 +22,14 @@ use crate::{
state::AppState,
};
pub const INVALID_SESSION: ApiError = ApiError::ClientError {
pub const INVALID_SESSION: ApiError = ApiError::Client {
status: StatusCode::UNAUTHORIZED,
code: "authentication-required",
message: "Please log-in and submit a valid session as a cookie",
};
fn extract_session_token(header: &HeaderValue) -> Result<(Uuid, String)> {
Ok(Session::parse_token(
Cookie::parse(header.to_str()?)?.value(),
)?)
Session::parse_token(Cookie::parse(header.to_str()?)?.value())
}
pub struct RequireUser(pub User);
@ -78,18 +76,17 @@ pub async fn refresh_sessions<B>(
.get(COOKIE)
.and_then(|header| extract_session_token(header).ok())
{
if let Some(Some((session, user))) = Session::find(&state.database, session_id).await.ok() {
if let Ok(Some((session, user))) = Session::find(&state.database, session_id).await {
// session validity requirements: secret must match, session must not have been expired
if session.secret == session_secret && session.expires_at >= Utc::now().naive_utc() {
// in the future we might wanna change the session secret, if we do, do it here!
if let Some((session, user)) = session
if let Ok((session, user)) = session
.refresh(
&state.database,
Duration::seconds(state.config.session_duration),
)
.await
.map(|s| (s, user))
.ok()
{
let extensions = req.extensions_mut();
extensions.insert(session.clone());

View File

@ -24,10 +24,10 @@ async fn bootstrap(State(state): State<Arc<AppState>>) -> impl IntoResponse {
.map_err(anyhow::Error::from)?;
if !empty {
return Err(ApiError::ClientError {
return Err(ApiError::Client {
status: StatusCode::BAD_REQUEST,
code: "already-setup".into(),
message: "The instance was already bootstrapped".into(),
code: "already-setup",
message: "The instance was already bootstrapped",
});
}
@ -36,7 +36,7 @@ async fn bootstrap(State(state): State<Arc<AppState>>) -> impl IntoResponse {
User::create(
&state.database,
&username,
username,
&password,
&[ROLE_SUPERADMIN].to_vec(),
)

View File

@ -35,10 +35,10 @@ async fn login(
.map_err(ApiError::from)?;
let invalid = || -> ApiError {
ApiError::ClientError {
ApiError::Client {
status: StatusCode::UNAUTHORIZED,
code: "invalid-login".into(),
message: "No matching user was found".into(),
code: "invalid-login",
message: "No matching user was found",
}
};
@ -52,7 +52,7 @@ async fn login(
let session = Session::create(
&state.database,
user.id,
Duration::seconds(state.config.session_duration.into()),
Duration::seconds(state.config.session_duration),
)
.await
.map_err(ApiError::from)?;
@ -64,7 +64,7 @@ async fn login(
response.headers_mut().insert(
SET_COOKIE,
session
.cookie(state.config.domain().as_str(), state.config.secure())
.cookie(&state.config.domain(), state.config.secure())
.parse()
.map_err(anyhow::Error::from)?,
);
@ -85,7 +85,7 @@ async fn logout(
let mut response: Response = Json(json!({ "ok": true })).into_response();
response.headers_mut().insert(
SET_COOKIE,
Session::cookie_for_delete(state.config.domain().as_str(), state.config.secure())
Session::cookie_for_delete(&state.config.domain(), state.config.secure())
.parse()
.map_err(anyhow::Error::from)?,
);

View File

@ -1,5 +1,5 @@
use axum::{
extract::{Path, State},
extract::Path,
response::IntoResponse,
routing::{get, post},
Json, Router,
@ -7,10 +7,7 @@ use axum::{
use std::sync::Arc;
use crate::{
content::page::PageRepository,
database::Database,
http::{error::ApiError, session::RequireUser},
state::AppState,
content::page::PageRepository, database::Database, http::error::ApiError, state::AppState,
};
async fn get_page<Repo: PageRepository>(
@ -20,10 +17,9 @@ async fn get_page<Repo: PageRepository>(
Ok(Json(repository.get_page_from_url(&site, &slug).await?))
}
async fn create_page<Repo: PageRepository>(
repository: Repo,
Path(site): Path<String>,
RequireUser(user): RequireUser,
async fn create_page<Repo: PageRepository>(//repository: Repo,
//Path(site): Path<String>,
//RequireUser(user): RequireUser,
) -> Result<impl IntoResponse, ApiError<'static>> {
Ok(Json("todo"))
}