aboutsummaryrefslogtreecommitdiffstats
path: root/atuin-server/src/handlers
diff options
context:
space:
mode:
authorConrad Ludgate <conradludgate@gmail.com>2023-06-12 09:04:35 +0100
committerGitHub <noreply@github.com>2023-06-12 09:04:35 +0100
commit8655c93853506acf05f6ae4e58bfc2c6198be254 (patch)
tree22d20b35636ad2eb717d58c93ae07378adbb76eb /atuin-server/src/handlers
parentMake Ctrl-d behaviour match other tools (#1040) (diff)
downloadatuin-8655c93853506acf05f6ae4e58bfc2c6198be254.zip
refactor server to allow pluggable db and tracing (#1036)
* refactor server to allow pluggable db and tracing * clean up * fix descriptions * remove dependencies
Diffstat (limited to 'atuin-server/src/handlers')
-rw-r--r--atuin-server/src/handlers/history.rs44
-rw-r--r--atuin-server/src/handlers/status.rs5
-rw-r--r--atuin-server/src/handlers/user.rs22
3 files changed, 46 insertions, 25 deletions
diff --git a/atuin-server/src/handlers/history.rs b/atuin-server/src/handlers/history.rs
index 1c9dff5f..bb0aa321 100644
--- a/atuin-server/src/handlers/history.rs
+++ b/atuin-server/src/handlers/history.rs
@@ -10,18 +10,20 @@ use tracing::{debug, error, instrument};
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
use crate::{
- calendar::{TimePeriod, TimePeriodInfo},
- database::Database,
- models::{NewHistory, User},
- router::AppState,
+ router::{AppState, UserAuth},
utils::client_version_min,
};
+use atuin_server_database::{
+ calendar::{TimePeriod, TimePeriodInfo},
+ models::NewHistory,
+ Database,
+};
use atuin_common::api::*;
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn count<DB: Database>(
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
) -> Result<Json<CountResponse>, ErrorResponseStatus<'static>> {
let db = &state.0.database;
@@ -42,7 +44,7 @@ pub async fn count<DB: Database>(
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn list<DB: Database>(
req: Query<SyncHistoryRequest>,
- user: User,
+ UserAuth(user): UserAuth,
headers: HeaderMap,
state: State<AppState<DB>>,
) -> Result<Json<SyncHistoryResponse>, ErrorResponseStatus<'static>> {
@@ -101,7 +103,7 @@ pub async fn list<DB: Database>(
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn delete<DB: Database>(
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
Json(req): Json<DeleteHistoryRequest>,
) -> Result<Json<MessageResponse>, ErrorResponseStatus<'static>> {
@@ -123,13 +125,15 @@ pub async fn delete<DB: Database>(
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn add<DB: Database>(
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
Json(req): Json<Vec<AddHistoryRequest>>,
) -> Result<(), ErrorResponseStatus<'static>> {
+ let State(AppState { database, settings }) = state;
+
debug!("request to add {} history items", req.len());
- let history: Vec<NewHistory> = req
+ let mut history: Vec<NewHistory> = req
.into_iter()
.map(|h| NewHistory {
client_id: h.id,
@@ -140,8 +144,24 @@ pub async fn add<DB: Database>(
})
.collect();
- let db = &state.0.database;
- if let Err(e) = db.add_history(&history).await {
+ history.retain(|h| {
+ // keep if within limit, or limit is 0 (unlimited)
+ let keep = h.data.len() <= settings.max_history_length || settings.max_history_length == 0;
+
+ // Don't return an error here. We want to insert as much of the
+ // history list as we can, so log the error and continue going.
+ if !keep {
+ tracing::warn!(
+ "history too long, got length {}, max {}",
+ h.data.len(),
+ settings.max_history_length
+ );
+ }
+
+ keep
+ });
+
+ if let Err(e) = database.add_history(&history).await {
error!("failed to add history: {}", e);
return Err(ErrorResponse::reply("failed to add history")
@@ -155,7 +175,7 @@ pub async fn add<DB: Database>(
pub async fn calendar<DB: Database>(
Path(focus): Path<String>,
Query(params): Query<HashMap<String, u64>>,
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
) -> Result<Json<HashMap<u64, TimePeriodInfo>>, ErrorResponseStatus<'static>> {
let focus = focus.as_str();
diff --git a/atuin-server/src/handlers/status.rs b/atuin-server/src/handlers/status.rs
index 97c02886..d9b6afaf 100644
--- a/atuin-server/src/handlers/status.rs
+++ b/atuin-server/src/handlers/status.rs
@@ -3,7 +3,8 @@ use http::StatusCode;
use tracing::instrument;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::{database::Database, models::User, router::AppState};
+use crate::router::{AppState, UserAuth};
+use atuin_server_database::Database;
use atuin_common::api::*;
@@ -11,7 +12,7 @@ const VERSION: &str = env!("CARGO_PKG_VERSION");
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn status<DB: Database>(
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
) -> Result<Json<StatusResponse>, ErrorResponseStatus<'static>> {
let db = &state.0.database;
diff --git a/atuin-server/src/handlers/user.rs b/atuin-server/src/handlers/user.rs
index e67828e4..75081155 100644
--- a/atuin-server/src/handlers/user.rs
+++ b/atuin-server/src/handlers/user.rs
@@ -16,10 +16,10 @@ use tracing::{debug, error, info, instrument};
use uuid::Uuid;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
-use crate::{
- database::Database,
- models::{NewSession, NewUser, User},
- router::AppState,
+use crate::router::{AppState, UserAuth};
+use atuin_server_database::{
+ models::{NewSession, NewUser},
+ Database, DbError,
};
use reqwest::header::CONTENT_TYPE;
@@ -64,11 +64,11 @@ pub async fn get<DB: Database>(
let db = &state.0.database;
let user = match db.get_user(username.as_ref()).await {
Ok(user) => user,
- Err(sqlx::Error::RowNotFound) => {
+ Err(DbError::NotFound) => {
debug!("user not found: {}", username);
return Err(ErrorResponse::reply("user not found").with_status(StatusCode::NOT_FOUND));
}
- Err(err) => {
+ Err(DbError::Other(err)) => {
error!("database error: {}", err);
return Err(ErrorResponse::reply("database error")
.with_status(StatusCode::INTERNAL_SERVER_ERROR));
@@ -152,7 +152,7 @@ pub async fn register<DB: Database>(
#[instrument(skip_all, fields(user.id = user.id))]
pub async fn delete<DB: Database>(
- user: User,
+ UserAuth(user): UserAuth,
state: State<AppState<DB>>,
) -> Result<Json<DeleteUserResponse>, ErrorResponseStatus<'static>> {
debug!("request to delete user {}", user.id);
@@ -175,10 +175,10 @@ pub async fn login<DB: Database>(
let db = &state.0.database;
let user = match db.get_user(login.username.borrow()).await {
Ok(u) => u,
- Err(sqlx::Error::RowNotFound) => {
+ Err(DbError::NotFound) => {
return Err(ErrorResponse::reply("user not found").with_status(StatusCode::NOT_FOUND));
}
- Err(e) => {
+ Err(DbError::Other(e)) => {
error!("failed to get user {}: {}", login.username.clone(), e);
return Err(ErrorResponse::reply("database error")
@@ -188,11 +188,11 @@ pub async fn login<DB: Database>(
let session = match db.get_user_session(&user).await {
Ok(u) => u,
- Err(sqlx::Error::RowNotFound) => {
+ Err(DbError::NotFound) => {
debug!("user session not found for user id={}", user.id);
return Err(ErrorResponse::reply("user not found").with_status(StatusCode::NOT_FOUND));
}
- Err(err) => {
+ Err(DbError::Other(err)) => {
error!("database error for user {}: {}", login.username, err);
return Err(ErrorResponse::reply("database error")
.with_status(StatusCode::INTERNAL_SERVER_ERROR));