Add /auth/status

This commit is contained in:
2022-09-18 15:04:33 +00:00
committed by GitHub
parent 35935e80a4
commit b00d326044
11 changed files with 88 additions and 19 deletions

1
Cargo.lock generated
View File

@@ -1331,6 +1331,7 @@ name = "pixiv_downloader"
version = "0.0.1"
dependencies = [
"RustyXML",
"anyhow",
"async-trait",
"atty",
"bindgen",

View File

@@ -6,6 +6,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = { version = "1.0", optional = true }
async-trait = { version = "0.1", optional = true }
atty = "0.2"
bytes = { version = "1.2", optional = true }
@@ -47,7 +48,7 @@ cmake = { version = "0.1", optional = true }
[features]
all = ["db", "db_sqlite", "exif", "ugoira", "server"]
avdict = ["bindgen", "cmake", "flagset"]
db = ["bytes"]
db = ["anyhow", "bytes"]
db_all = ["db", "db_sqlite"]
db_sqlite = ["rusqlite"]
exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"]

View File

@@ -12,14 +12,14 @@ pub use config::PixivDownloaderSqliteConfig;
pub use sqlite::{PixivDownloaderSqlite, SqliteError};
pub use traits::PixivDownloaderDb;
pub use user::User;
pub type PixivDownloaderDbError = Box<dyn std::fmt::Display + Send + Sync>;
pub type PixivDownloaderDbError = anyhow::Error;
use crate::{get_helper, gettext};
#[cfg(feature = "db_sqlite")]
impl From<SqliteError> for PixivDownloaderDbError {
fn from(e: SqliteError) -> Self {
Box::new(e)
PixivDownloaderDbError::msg(e)
}
}
@@ -30,7 +30,7 @@ compile_error!("No database backend is enabled.");
pub fn open_database() -> Result<Box<dyn PixivDownloaderDb + Send + Sync>, PixivDownloaderDbError> {
let cfg = get_helper().db();
if cfg.is_none() {
return Err(Box::new(String::from(gettext(
return Err(PixivDownloaderDbError::msg(String::from(gettext(
"No database configuration provided.",
))));
}
@@ -40,7 +40,9 @@ pub fn open_database() -> Result<Box<dyn PixivDownloaderDb + Send + Sync>, Pixiv
return Ok(Box::new(PixivDownloaderSqlite::new(&cfg)?));
}
}
Err(Box::new(String::from(gettext("Unknown database type."))))
Err(PixivDownloaderDbError::msg(String::from(gettext(
"Unknown database type.",
))))
}
/// Open the database and initialize it

View File

@@ -1,4 +1,4 @@
#[derive(derive_more::Display, derive_more::From)]
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum SqliteError {
DbError(rusqlite::Error),
DatabaseVersionTooNew,

View File

@@ -17,6 +17,8 @@ pub enum PixivDownloaderError {
Fanbox(crate::fanbox::error::FanboxAPIError),
#[cfg(feature = "avdict")]
AVDict(crate::avdict::AVDictError),
#[cfg(feature = "db")]
DbError(crate::db::PixivDownloaderDbError),
}
impl From<&str> for PixivDownloaderError {

3
src/server/auth/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
pub mod status;
pub use status::{AuthStatusContext, AuthStatusRoute};

54
src/server/auth/status.rs Normal file
View File

@@ -0,0 +1,54 @@
use super::super::preclude::*;
pub struct AuthStatusContext {
ctx: Arc<ServerContext>,
}
impl AuthStatusContext {
pub fn new(ctx: Arc<ServerContext>) -> Self {
Self { ctx }
}
}
#[async_trait]
impl ResponseJsonFor<Body> for AuthStatusContext {
async fn response_json(
&self,
req: Request<Body>,
) -> Result<Response<JsonValue>, PixivDownloaderError> {
filter_http_methods!(
req,
json::object! {},
true,
self.ctx,
allow_headers = [CONTENT_TYPE],
GET,
OPTIONS,
POST,
);
let has_root_user = self.ctx.db.get_user(0).await?.is_some();
Ok(builder.body(json::object! {"has_root_user": has_root_user})?)
}
}
pub struct AuthStatusRoute {
regex: Regex,
}
impl AuthStatusRoute {
pub fn new() -> Self {
Self {
regex: Regex::new(r"^(/+api)?/+auth(/+status(/.*)?)?$").unwrap(),
}
}
}
impl MatchRoute<Body, Body> for AuthStatusRoute {
fn get_route(&self, ctx: Arc<ServerContext>) -> Box<ResponseForType> {
Box::new(AuthStatusContext::new(ctx))
}
fn match_route(&self, req: &http::Request<Body>) -> bool {
self.regex.is_match(req.uri().path())
}
}

View File

@@ -1,6 +1,10 @@
/// Routes about authentication
pub mod auth;
pub mod context;
/// CORS Handle
pub mod cors;
/// Predefined includes
pub mod preclude;
/// Routes
pub mod route;
/// Services

11
src/server/preclude.rs Normal file
View File

@@ -0,0 +1,11 @@
pub use super::context::ServerContext;
pub use super::route::ResponseForType;
pub use super::traits::{MatchRoute, ResponseFor, ResponseJsonFor};
pub use crate::error::PixivDownloaderError;
pub use hyper::Body;
pub use hyper::Request;
pub use hyper::Response;
pub use json::JsonValue;
pub use proc_macros::filter_http_methods;
pub use regex::Regex;
pub use std::sync::Arc;

View File

@@ -1,3 +1,4 @@
use super::auth::*;
use super::context::ServerContext;
use super::traits::MatchRoute;
use super::traits::ResponseFor;
@@ -17,6 +18,7 @@ impl ServerRoutes {
pub fn new() -> Self {
let mut routes: Vec<Box<RouteType>> = Vec::new();
routes.push(Box::new(VersionRoute::new()));
routes.push(Box::new(AuthStatusRoute::new()));
Self { routes }
}

View File

@@ -1,15 +1,4 @@
use super::context::ServerContext;
use super::route::ResponseForType;
use super::traits::MatchRoute;
use super::traits::ResponseJsonFor;
use crate::error::PixivDownloaderError;
use hyper::Body;
use hyper::Request;
use hyper::Response;
use json::JsonValue;
use proc_macros::filter_http_methods;
use regex::Regex;
use std::sync::Arc;
use super::preclude::*;
pub struct VersionContext {
ctx: Arc<ServerContext>,
@@ -32,7 +21,7 @@ impl ResponseJsonFor<Body> for VersionContext {
json::object! {},
true,
self.ctx,
allow_headers = [CONTENT_TYPE, X_TOKEN],
allow_headers = [CONTENT_TYPE],
GET,
OPTIONS,
POST,