some quick documentation
This commit is contained in:
parent
8d297920fb
commit
87cfccb4f7
@ -1,3 +1,5 @@
|
||||
//! Koreader Progress Sync API.
|
||||
|
||||
use poem::{
|
||||
error::ResponseError,
|
||||
http::StatusCode,
|
||||
@ -19,17 +21,20 @@ use crate::{
|
||||
error_response,
|
||||
};
|
||||
|
||||
/// Data for registering a new user.
|
||||
#[derive(Object, Deserialize)]
|
||||
struct RegisterRequest {
|
||||
username: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
/// Answer after registering a new user.
|
||||
#[derive(Object, Serialize)]
|
||||
struct UserCreated {
|
||||
username: String,
|
||||
}
|
||||
|
||||
/// Datafor pushing progress.
|
||||
#[derive(Debug, Clone, Object, Deserialize)]
|
||||
pub struct DocumentUpdate {
|
||||
pub device: String,
|
||||
@ -39,6 +44,7 @@ pub struct DocumentUpdate {
|
||||
pub progress: String,
|
||||
}
|
||||
|
||||
/// Answer when pulling progress.
|
||||
#[derive(Debug, Clone, Object, Deserialize)]
|
||||
pub struct DocumentProgress {
|
||||
pub device: String,
|
||||
@ -70,6 +76,9 @@ pub struct Api;
|
||||
|
||||
#[OpenApi]
|
||||
impl Api {
|
||||
/// Register a new user.
|
||||
///
|
||||
/// If a user of that id already exist, return a conflict.
|
||||
#[oai(path = "/users/create", method = "post")]
|
||||
async fn register(
|
||||
&self,
|
||||
@ -88,11 +97,13 @@ impl Api {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return OK if a user authenticated successfully.
|
||||
#[oai(path = "/users/auth", method = "get", transform = "authorize")]
|
||||
async fn login(&self) -> Result<payload::Response<()>> {
|
||||
Ok(payload::Response::new(()).status(StatusCode::OK))
|
||||
}
|
||||
|
||||
/// Push new progress.
|
||||
#[oai(path = "/syncs/progress", method = "put", transform = "authorize")]
|
||||
async fn push_progress(
|
||||
&self,
|
||||
@ -108,6 +119,7 @@ impl Api {
|
||||
Ok(payload::Response::new(()).status(StatusCode::OK))
|
||||
}
|
||||
|
||||
/// Pull progress for document with id `doc_id`.
|
||||
#[oai(
|
||||
path = "/syncs/progress/:doc_id",
|
||||
method = "get",
|
||||
|
@ -1,6 +1,10 @@
|
||||
//! Global application state.
|
||||
|
||||
use crate::{cli::Config, db::Db};
|
||||
|
||||
pub struct AppState {
|
||||
/// Application configuration.
|
||||
pub config: Config,
|
||||
/// Database connection.
|
||||
pub db: Db,
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
//! Poem middleware for koreader progress sync authentication.
|
||||
//!
|
||||
//! Authentication works with two headers:
|
||||
//! - x-auth-user: username
|
||||
//! - x-auth-key: md5 hashed password
|
||||
|
||||
use poem::{
|
||||
error::ResponseError, http::StatusCode, Endpoint, EndpointExt, Error, Middleware, Request,
|
||||
Result,
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! Data access and persistence.
|
||||
|
||||
use ::entity::{document, user};
|
||||
use migration::{Migrator, MigratorTrait};
|
||||
use sea_orm::{
|
||||
@ -16,6 +18,7 @@ pub enum DataStoreError {
|
||||
DatabaseError(#[from] DbErr),
|
||||
}
|
||||
|
||||
/// Document progress to insert/update.
|
||||
#[derive(Debug)]
|
||||
pub struct DocumentInsert {
|
||||
id: String,
|
||||
@ -44,6 +47,7 @@ pub struct Db {
|
||||
}
|
||||
|
||||
impl Db {
|
||||
/// Add a new user and return an error if one with `id` already exists.
|
||||
pub async fn add_user(&self, id: &str, key: &str) -> Result<user::Model, DataStoreError> {
|
||||
let user = user::ActiveModel {
|
||||
id: Set(id.to_owned()),
|
||||
@ -53,10 +57,13 @@ impl Db {
|
||||
Ok(user.insert(&self.connection).await?)
|
||||
}
|
||||
|
||||
/// Get user with id `id` or None if they do not exist.
|
||||
pub async fn get_user(&self, id: &str) -> Result<Option<user::Model>, DataStoreError> {
|
||||
Ok(user::Entity::find_by_id(id).one(&self.connection).await?)
|
||||
}
|
||||
|
||||
/// Get the progress for document with id `doc_id` from user with id `user_id` or None if that
|
||||
/// combination does not exist.
|
||||
pub async fn get_position(
|
||||
&self,
|
||||
user_id: &str,
|
||||
@ -69,6 +76,9 @@ impl Db {
|
||||
.await?)
|
||||
}
|
||||
|
||||
/// Update progress for document with id `doc_id` from user with id `user_id`.
|
||||
///
|
||||
/// Set the progress timestamp to now.
|
||||
pub async fn update_position(&self, doc: &DocumentInsert) -> Result<(), DataStoreError> {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
let now = PrimitiveDateTime::new(now.date(), now.time());
|
||||
@ -93,6 +103,7 @@ impl Db {
|
||||
}
|
||||
}
|
||||
|
||||
/// Connect to the database and return the opened connectoin pool.
|
||||
pub async fn connect(connection_string: &str) -> Result<Db, DataStoreError> {
|
||||
let connection: DatabaseConnection = Database::connect(connection_string).await?;
|
||||
Migrator::up(&connection, None).await?;
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! Error handling for the sync service.
|
||||
|
||||
use poem::{http::StatusCode, Body, Response};
|
||||
use poem_openapi::Object;
|
||||
use serde::Serialize;
|
||||
@ -11,6 +13,8 @@ struct ErrorResponse {
|
||||
message: String,
|
||||
}
|
||||
|
||||
/// Log `error` on the server side with a generated id and send back a sanitized error message with
|
||||
/// the same id.
|
||||
pub fn create_and_log<F>(error: impl Error, cb: F) -> Response
|
||||
where
|
||||
F: Fn() -> (String, StatusCode),
|
||||
|
@ -1,3 +1,5 @@
|
||||
//! Implementation of a koreader progress sync server.
|
||||
|
||||
use anyhow::Result;
|
||||
use api::Api;
|
||||
use app_state::AppState;
|
||||
@ -18,6 +20,7 @@ pub mod cli;
|
||||
pub mod db;
|
||||
pub mod error_response;
|
||||
|
||||
/// Run the progress sync server.
|
||||
pub async fn run(args: &Config, db_url: &str) -> Result<()> {
|
||||
let db = db::connect(db_url).await?;
|
||||
let app_state = Arc::new(AppState {
|
||||
|
Loading…
Reference in New Issue
Block a user