mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-06-06 05:49:01 +08:00
Impl /auth/token/extend
This commit is contained in:
@@ -233,6 +233,19 @@ impl PixivDownloaderSqlite {
|
||||
Ok(af > 0)
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn _extend_token(
|
||||
tx: &Transaction,
|
||||
id: u64,
|
||||
expired_at: &DateTime<Utc>,
|
||||
) -> Result<(), SqliteError> {
|
||||
tx.execute(
|
||||
"UPDATE token SET expired_at = ? WHERE id = ?;",
|
||||
(expired_at, id),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get all exists tables
|
||||
async fn _get_exists_table(&self) -> Result<HashMap<String, ()>, SqliteError> {
|
||||
let con = self.db.lock().await;
|
||||
@@ -618,6 +631,19 @@ impl PixivDownloaderDb for PixivDownloaderSqlite {
|
||||
Ok(re)
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
async fn extend_token(
|
||||
&self,
|
||||
id: u64,
|
||||
expired_at: &DateTime<Utc>,
|
||||
) -> Result<(), PixivDownloaderDbError> {
|
||||
let mut db = self.db.lock().await;
|
||||
let mut tx = db.transaction()?;
|
||||
Self::_extend_token(&mut tx, id, expired_at)?;
|
||||
tx.commit()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
async fn get_token(&self, id: u64) -> Result<Option<Token>, PixivDownloaderDbError> {
|
||||
Ok(self.get_token(id).await?)
|
||||
|
||||
@@ -65,6 +65,15 @@ pub trait PixivDownloaderDb {
|
||||
/// All tokens of the user will be deleted.
|
||||
async fn delete_user(&self, id: u64) -> Result<bool, PixivDownloaderDbError>;
|
||||
#[cfg(feature = "server")]
|
||||
/// Extend a token's expiration time
|
||||
/// * `id` - The token ID
|
||||
/// * `expired_at` - The token's new expiration time
|
||||
async fn extend_token(
|
||||
&self,
|
||||
id: u64,
|
||||
expired_at: &DateTime<Utc>,
|
||||
) -> Result<(), PixivDownloaderDbError>;
|
||||
#[cfg(feature = "server")]
|
||||
/// Get token by ID
|
||||
/// * `id` - The token ID
|
||||
async fn get_token(&self, id: u64) -> Result<Option<Token>, PixivDownloaderDbError>;
|
||||
|
||||
@@ -12,6 +12,8 @@ pub enum AuthTokenAction {
|
||||
Add,
|
||||
/// Delete a token
|
||||
Delete,
|
||||
/// Extend a token's expire time
|
||||
Extend,
|
||||
}
|
||||
|
||||
pub struct AuthTokenContext {
|
||||
@@ -121,6 +123,22 @@ impl AuthTokenContext {
|
||||
}
|
||||
Ok(data)
|
||||
}
|
||||
AuthTokenAction::Extend => {
|
||||
let token = self
|
||||
.ctx
|
||||
.verify_token2(&req, ¶ms)
|
||||
.await
|
||||
.try_err3(-403, gettext("Failed to verify the token:"))?;
|
||||
let expired_at = chrono::Utc::now() + chrono::Duration::days(30);
|
||||
self.ctx
|
||||
.db
|
||||
.extend_token(token.id, &expired_at)
|
||||
.await
|
||||
.try_err3(-1001, gettext("Failed to operate the database:"))?;
|
||||
Ok(
|
||||
json::object! { "id": token.id, "user_id": token.user_id, "created_at": token.created_at.timestamp(), "expired_at": expired_at.timestamp() },
|
||||
)
|
||||
}
|
||||
},
|
||||
None => {
|
||||
panic!("No action specified for AuthTokenContext.");
|
||||
@@ -191,7 +209,7 @@ pub struct AuthTokenRoute {
|
||||
impl AuthTokenRoute {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
regex: Regex::new(r"^(/+api)?/+auth/+token(/+(add|delete))?$").unwrap(),
|
||||
regex: Regex::new(r"^(/+api)?/+auth/+token(/+(add|delete|extend))?$").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,6 +239,7 @@ impl MatchRoute<Body, Body> for AuthTokenRoute {
|
||||
match m {
|
||||
"add" => Some(AuthTokenAction::Add),
|
||||
"delete" => Some(AuthTokenAction::Delete),
|
||||
"extend" => Some(AuthTokenAction::Extend),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::auth::RSAKey;
|
||||
use super::cors::CorsContext;
|
||||
use super::params::RequestParams;
|
||||
use super::result::JSONResult;
|
||||
use crate::db::{open_and_init_database, PixivDownloaderDb, User};
|
||||
use crate::db::{open_and_init_database, PixivDownloaderDb, Token, User};
|
||||
use crate::error::PixivDownloaderError;
|
||||
use crate::ext::json::ToJson2;
|
||||
use crate::get_helper;
|
||||
@@ -52,11 +52,11 @@ impl ServerContext {
|
||||
Ok(builder.body(re.to_json2())?)
|
||||
}
|
||||
|
||||
pub async fn verify_token(
|
||||
pub async fn verify_token2(
|
||||
&self,
|
||||
req: &Request<Body>,
|
||||
params: &RequestParams,
|
||||
) -> Result<User, PixivDownloaderError> {
|
||||
) -> Result<Token, PixivDownloaderError> {
|
||||
let mut token_id = None;
|
||||
match req.headers().get("X-TOKEN-ID") {
|
||||
Some(v) => {
|
||||
@@ -121,6 +121,15 @@ impl ServerContext {
|
||||
if sign != sha {
|
||||
return Err(PixivDownloaderError::from(gettext("Sign not match.")));
|
||||
}
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
pub async fn verify_token(
|
||||
&self,
|
||||
req: &Request<Body>,
|
||||
params: &RequestParams,
|
||||
) -> Result<User, PixivDownloaderError> {
|
||||
let token = self.verify_token2(req, params).await?;
|
||||
Ok(self
|
||||
.db
|
||||
.get_user(token.user_id)
|
||||
|
||||
@@ -668,5 +668,12 @@ pub async fn test(ctx: &UnitTestContext) -> Result<[(u64, Vec<u8>); 2], PixivDow
|
||||
assert_eq!(result2.as_bool(), Some(true));
|
||||
let result2 = JSONResult::from_json(&result[format!("{}", token4_id)])?.unwrap();
|
||||
assert_eq!(result2.as_bool(), Some(true));
|
||||
let re = ctx
|
||||
.request_json2_sign("/auth/token/extend", &json::object! {}, &token2, token2_id)
|
||||
.await?
|
||||
.unwrap();
|
||||
let result = JSONResult::from_json(re)?.unwrap();
|
||||
assert_eq!(result["user_id"].as_u64(), Some(1));
|
||||
assert_eq!(result["id"].as_u64(), Some(token2_id));
|
||||
Ok([(token_id, token), (token2_id, token2)])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user