webdav token regeneration
This commit is contained in:
@@ -37,8 +37,7 @@ use tower::util::ServiceExt;
|
||||
use uuid::Uuid;
|
||||
|
||||
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
||||
const RESET_DATABASE_SQL: &str =
|
||||
"DROP SCHEMA IF EXISTS tenant CASCADE;\n\
|
||||
const RESET_DATABASE_SQL: &str = "DROP SCHEMA IF EXISTS tenant CASCADE;\n\
|
||||
DROP SCHEMA IF EXISTS shared CASCADE;\n\
|
||||
DROP SCHEMA IF EXISTS public CASCADE;\n\
|
||||
CREATE SCHEMA public;\n\
|
||||
|
||||
@@ -54,6 +54,20 @@ async fn webdav_token_api_crud() -> Result<()> {
|
||||
assert_eq!(created.info.label.as_deref(), Some("dav"));
|
||||
assert!(created.info.last_used_at.is_none());
|
||||
|
||||
let regenerate_response = app
|
||||
.post_json(
|
||||
&format!("/api/profile/webdav-tokens/{token_id}/regenerate"),
|
||||
&json!({}),
|
||||
Some(&access_token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(regenerate_response.status(), StatusCode::OK);
|
||||
let regenerate_body = body_to_vec(regenerate_response.into_body()).await?;
|
||||
let regenerated: CreateTokenResponse = serde_json::from_slice(®enerate_body)?;
|
||||
assert_eq!(regenerated.info.id, token_id);
|
||||
assert_ne!(regenerated.token, created.token);
|
||||
assert!(regenerated.info.last_used_at.is_none());
|
||||
|
||||
let list_response = app
|
||||
.get("/api/profile/webdav-tokens", Some(&access_token))
|
||||
.await?;
|
||||
@@ -106,9 +120,10 @@ async fn webdav_basic_auth_uses_tokens() -> Result<()> {
|
||||
let token_id = created.info.id;
|
||||
|
||||
let router = webdav::create_router().with_state(app.state.clone());
|
||||
let original_secret = created.token.clone();
|
||||
let auth_header = format!(
|
||||
"Basic {}",
|
||||
BASE64.encode(format!("{}:{}", username, created.token))
|
||||
BASE64.encode(format!("{}:{}", username, original_secret))
|
||||
);
|
||||
|
||||
let propfind = Method::from_bytes(b"PROPFIND")?;
|
||||
@@ -131,6 +146,57 @@ async fn webdav_basic_auth_uses_tokens() -> Result<()> {
|
||||
.await?;
|
||||
assert!(used.is_some());
|
||||
|
||||
let regenerate_response = app
|
||||
.post_json(
|
||||
&format!("/api/profile/webdav-tokens/{token_id}/regenerate"),
|
||||
&json!({}),
|
||||
Some(&access_token),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(regenerate_response.status(), StatusCode::OK);
|
||||
let regenerate_body = body_to_vec(regenerate_response.into_body()).await?;
|
||||
let regenerated: CreateTokenResponse = serde_json::from_slice(®enerate_body)?;
|
||||
assert_ne!(regenerated.token, original_secret);
|
||||
|
||||
let unused_after_regen = app
|
||||
.with_conn(move |conn| {
|
||||
let record = webdav_tokens::table
|
||||
.find(token_id)
|
||||
.first::<WebdavToken>(conn)?;
|
||||
Ok::<_, anyhow::Error>(record.last_used_at)
|
||||
})
|
||||
.await?;
|
||||
assert!(unused_after_regen.is_none());
|
||||
|
||||
let old_secret_request = Request::builder()
|
||||
.method(propfind.clone())
|
||||
.uri("/")
|
||||
.header(
|
||||
header::AUTHORIZATION,
|
||||
format!(
|
||||
"Basic {}",
|
||||
BASE64.encode(format!("{}:{}", username, original_secret))
|
||||
),
|
||||
)
|
||||
.header("depth", "0")
|
||||
.body(Body::empty())?;
|
||||
let old_secret_response = router.clone().oneshot(old_secret_request).await?;
|
||||
assert_eq!(old_secret_response.status(), StatusCode::UNAUTHORIZED);
|
||||
|
||||
let new_secret_header = format!(
|
||||
"Basic {}",
|
||||
BASE64.encode(format!("{}:{}", username, regenerated.token))
|
||||
);
|
||||
|
||||
let success_request = Request::builder()
|
||||
.method(propfind.clone())
|
||||
.uri("/")
|
||||
.header(header::AUTHORIZATION, new_secret_header.clone())
|
||||
.header("depth", "0")
|
||||
.body(Body::empty())?;
|
||||
let response = router.clone().oneshot(success_request).await?;
|
||||
assert_eq!(response.status(), StatusCode::MULTI_STATUS);
|
||||
|
||||
let delete_response = app
|
||||
.delete(
|
||||
&format!("/api/profile/webdav-tokens/{token_id}"),
|
||||
@@ -142,7 +208,7 @@ async fn webdav_basic_auth_uses_tokens() -> Result<()> {
|
||||
let failure_request = Request::builder()
|
||||
.method(propfind)
|
||||
.uri("/")
|
||||
.header(header::AUTHORIZATION, auth_header)
|
||||
.header(header::AUTHORIZATION, new_secret_header)
|
||||
.header("depth", "0")
|
||||
.body(Body::empty())?;
|
||||
let response = router.oneshot(failure_request).await?;
|
||||
|
||||
Reference in New Issue
Block a user