This commit is contained in:
2022-09-25 07:16:19 +00:00
committed by GitHub
parent 89e08ab968
commit dfa9ba5576
4 changed files with 67 additions and 10 deletions

7
Cargo.lock generated
View File

@@ -733,6 +733,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "html_parser"
version = "0.6.3"
@@ -1366,6 +1372,7 @@ dependencies = [
"futures-util",
"getopts",
"gettext",
"hex",
"html_parser",
"http",
"http-content-range",

View File

@@ -21,6 +21,7 @@ flagset = { version = "0.4", optional = true }
futures-util = "0.3"
getopts = "0.2"
gettext = "0.4"
hex = { version = "0.4", optional = true }
html_parser = "0.6.3"
http = "0.2"
http-content-range = "0.1"
@@ -55,7 +56,7 @@ db = ["anyhow", "async-trait", "bytes"]
db_all = ["db", "db_sqlite"]
db_sqlite = ["rusqlite"]
exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"]
server = ["async-trait", "base64", "db", "hyper", "multipart", "openssl"]
server = ["async-trait", "base64", "db", "hex", "hyper", "multipart", "openssl"]
ugoira = ["avdict", "bindgen", "cmake", "link-cplusplus"]
[patch.crates-io]

View File

@@ -36,15 +36,24 @@ impl AuthUserContext {
.get_params()
.await
.try_err3(-1002, gettext("Failed to get parameters:"))?;
if root_user.is_some() {
self.ctx
.verify_token(&req, &params)
.await
.try_err3(-403, gettext("Failed to verify the token:"))?;
}
let user = if root_user.is_some() {
Some(
self.ctx
.verify_token(&req, &params)
.await
.try_err3(-403, gettext("Failed to verify the token:"))?,
)
} else {
None
};
match &self.action {
Some(act) => match act {
AuthUserAction::Add => {
if root_user.is_some() {
if !user.as_ref().expect("User not found:").is_admin {
return Err((9, gettext("Admin privileges required.")).into());
}
}
let name = params
.get("name")
.try_err((1, gettext("No user's name specified.")))?;

View File

@@ -1,12 +1,13 @@
use super::auth::RSAKey;
use super::cors::CorsContext;
use super::params::RequestParams;
use crate::db::{open_and_init_database, PixivDownloaderDb};
use crate::db::{open_and_init_database, PixivDownloaderDb, User};
use crate::error::PixivDownloaderError;
use crate::get_helper;
use crate::gettext;
use futures_util::lock::Mutex;
use hyper::{Body, Request};
use std::collections::BTreeMap;
pub struct ServerContext {
pub cors: CorsContext,
@@ -30,7 +31,7 @@ impl ServerContext {
&self,
req: &Request<Body>,
params: &RequestParams,
) -> Result<(), PixivDownloaderError> {
) -> Result<User, PixivDownloaderError> {
let mut token_id = None;
match req.headers().get("X-TOKEN-ID") {
Some(v) => {
@@ -43,16 +44,55 @@ impl ServerContext {
None => {}
},
}
let mut sign = None;
match req.headers().get("X-SIGN") {
Some(v) => {
sign.replace(v.to_str()?.to_owned());
}
None => match params.get("sign") {
Some(v) => {
sign.replace(v.to_owned());
}
None => {}
},
}
let token_id = match token_id {
Some(token_id) => token_id,
None => return Err(PixivDownloaderError::from(gettext("Token id not found."))),
}
.parse::<u64>()?;
let sign = match sign {
Some(sign) => sign,
None => return Err(PixivDownloaderError::from(gettext("Sign not found."))),
};
let token = self
.db
.get_token(token_id)
.await?
.ok_or(gettext("Token not found."))?;
Ok(())
let mut par = BTreeMap::new();
for (k, v) in params.params.iter() {
if k == "sign" || k == "token_id" {
continue;
}
par.insert(k, v);
}
let mut sha = openssl::sha::Sha512::new();
sha.update(token.token.as_bytes());
for (k, v) in par {
for v in v {
sha.update(k.as_bytes());
sha.update(v.as_bytes());
}
}
let sha = hex::encode(sha.finish());
if sign != sha {
return Err(PixivDownloaderError::from(gettext("Sign not match.")));
}
Ok(self
.db
.get_user(token.user_id)
.await?
.ok_or(gettext("No corresponding user was found."))?)
}
}