mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Auth api response tells you who you are now
This commit is contained in:
parent
dfe5d668a4
commit
066fa8648d
@ -1,22 +0,0 @@
|
|||||||
// Copyright 2022 Jeremy Wall (Jeremy@marzhilsltudios.com)
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
use sqlx::{migrate, SqlitePool};
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub async fn run_migration(pool: Arc<SqlitePool>) {
|
|
||||||
sqlx::migrate!("./migrations")
|
|
||||||
.run(pool.as_ref())
|
|
||||||
.await
|
|
||||||
.expect("Unable to run migratins");
|
|
||||||
}
|
|
@ -18,20 +18,43 @@ use async_session::{Session, SessionStore};
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::Extension,
|
extract::Extension,
|
||||||
http::{header, HeaderMap, StatusCode},
|
http::{header, HeaderMap, StatusCode},
|
||||||
response::IntoResponse,
|
|
||||||
};
|
};
|
||||||
use axum_auth::AuthBasic;
|
use axum_auth::AuthBasic;
|
||||||
use cookie::{Cookie, SameSite};
|
use cookie::{Cookie, SameSite};
|
||||||
use secrecy::Secret;
|
use secrecy::Secret;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::{debug, error, info, instrument};
|
use tracing::{debug, error, info, instrument};
|
||||||
|
|
||||||
use super::storage::{self, AuthStore};
|
use super::storage::{self, AuthStore, UserCreds};
|
||||||
|
|
||||||
|
// FIXME(jwall): This needs to live in a client integration library.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum AccountResponse {
|
||||||
|
Success { user_id: String },
|
||||||
|
Err { message: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UserCreds> for AccountResponse {
|
||||||
|
fn from(auth: UserCreds) -> Self {
|
||||||
|
Self::Success {
|
||||||
|
user_id: auth.user_id().to_owned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a str> for AccountResponse {
|
||||||
|
fn from(msg: &'a str) -> Self {
|
||||||
|
Self::Err {
|
||||||
|
message: msg.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(skip_all, fields(user=%auth.0.0))]
|
#[instrument(skip_all, fields(user=%auth.0.0))]
|
||||||
pub async fn handler(
|
pub async fn handler(
|
||||||
auth: AuthBasic,
|
auth: AuthBasic,
|
||||||
Extension(session_store): Extension<Arc<storage::SqliteStore>>,
|
Extension(session_store): Extension<Arc<storage::SqliteStore>>,
|
||||||
) -> impl IntoResponse {
|
) -> (StatusCode, HeaderMap, axum::Json<AccountResponse>) {
|
||||||
// NOTE(jwall): It is very important that you do **not** log the password
|
// NOTE(jwall): It is very important that you do **not** log the password
|
||||||
// here. We convert the AuthBasic into UserCreds immediately to help prevent
|
// here. We convert the AuthBasic into UserCreds immediately to help prevent
|
||||||
// that. Do not circumvent that protection.
|
// that. Do not circumvent that protection.
|
||||||
@ -44,28 +67,31 @@ pub async fn handler(
|
|||||||
let mut session = Session::new();
|
let mut session = Session::new();
|
||||||
if let Err(err) = session.insert("user_id", auth.user_id()) {
|
if let Err(err) = session.insert("user_id", auth.user_id()) {
|
||||||
error!(?err, "Unable to insert user id into session");
|
error!(?err, "Unable to insert user id into session");
|
||||||
|
let resp: AccountResponse = "Unable to insert user id into session".into();
|
||||||
return (
|
return (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
headers,
|
headers,
|
||||||
"Unable to insert user id into session",
|
axum::Json::from(resp),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// 2. Store the session in the store.
|
// 2. Store the session in the store.
|
||||||
let cookie_value = match session_store.store_session(session).await {
|
let cookie_value = match session_store.store_session(session).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(?err, "Unable to store session in session store");
|
error!(?err, "Unable to store session in session store");
|
||||||
|
let resp: AccountResponse = "Unable to store session in session store".into();
|
||||||
return (
|
return (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
headers,
|
headers,
|
||||||
"Unable to store session in session store",
|
axum::Json::from(resp),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
error!("Unable to create session cookie");
|
error!("Unable to create session cookie");
|
||||||
|
let resp: AccountResponse = "Unable to create session cookie".into();
|
||||||
return (
|
return (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
headers,
|
headers,
|
||||||
"Unable to create session cookie",
|
axum::Json::from(resp),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(Some(value)) => value,
|
Ok(Some(value)) => value,
|
||||||
@ -79,25 +105,24 @@ pub async fn handler(
|
|||||||
let parsed_cookie = match cookie.to_string().parse() {
|
let parsed_cookie = match cookie.to_string().parse() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(?err, "Unable to parse session cookie");
|
error!(?err, "Unable to parse session cookie");
|
||||||
|
let resp: AccountResponse = "Unable to parse session cookie".into();
|
||||||
return (
|
return (
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
headers,
|
headers,
|
||||||
"Unable to parse session cookie",
|
axum::Json::from(resp),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(parsed_cookie) => parsed_cookie,
|
Ok(parsed_cookie) => parsed_cookie,
|
||||||
};
|
};
|
||||||
headers.insert(header::SET_COOKIE, parsed_cookie);
|
headers.insert(header::SET_COOKIE, parsed_cookie);
|
||||||
// Respond with 200 OK
|
// Respond with 200 OK
|
||||||
(StatusCode::OK, headers, "Login Successful")
|
let resp: AccountResponse = auth.into();
|
||||||
|
(StatusCode::OK, headers, axum::Json::from(resp))
|
||||||
} else {
|
} else {
|
||||||
debug!("Invalid credentials");
|
debug!("Invalid credentials");
|
||||||
let headers = HeaderMap::new();
|
let headers = HeaderMap::new();
|
||||||
(
|
let resp: AccountResponse = "Invalid user id or password".into();
|
||||||
StatusCode::UNAUTHORIZED,
|
(StatusCode::UNAUTHORIZED, headers, axum::Json::from(resp))
|
||||||
headers,
|
|
||||||
"Invalid user id or password",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user