Impl /auth/token/extend

This commit is contained in:
2022-10-18 02:12:55 +00:00
committed by GitHub
parent 747872c265
commit b2c964c664
5 changed files with 74 additions and 4 deletions

View File

@@ -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?)

View File

@@ -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>;

View File

@@ -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, &params)
.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,
}
}

View File

@@ -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)

View File

@@ -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)])
}