security upgrade
This commit is contained in:
+47
-18
@@ -94,10 +94,10 @@ pub async fn pad_info(
|
||||
.ok_or_else(ApiError::not_found_note)?;
|
||||
ensure_private_resource_access(
|
||||
&state,
|
||||
&headers,
|
||||
"pad",
|
||||
&pad.slug,
|
||||
pad.is_private,
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await?;
|
||||
let (global_color, note_color) = editor_colors(&state, &headers, "pad", &slug).await?;
|
||||
@@ -238,8 +238,9 @@ pub async fn publish_pad_page(
|
||||
&state,
|
||||
&slug,
|
||||
payload.password.as_deref(),
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(&headers, "pad", &slug, payload.access_token.as_deref()),
|
||||
bearer_token(&headers),
|
||||
&headers,
|
||||
)
|
||||
.await?;
|
||||
let level = if db::verify_pad_password(&pad, payload.password.as_deref())
|
||||
@@ -251,7 +252,7 @@ pub async fn publish_pad_page(
|
||||
&state,
|
||||
"pad",
|
||||
&slug,
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(&headers, "pad", &slug, payload.access_token.as_deref()),
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await?
|
||||
@@ -287,8 +288,14 @@ pub async fn publish_note_page(
|
||||
&workspace_slug,
|
||||
¬e_slug,
|
||||
payload.password.as_deref(),
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(
|
||||
&headers,
|
||||
"workspace",
|
||||
&workspace_slug,
|
||||
payload.access_token.as_deref(),
|
||||
),
|
||||
bearer_token(&headers),
|
||||
&headers,
|
||||
)
|
||||
.await?;
|
||||
let level = if db::verify_workspace_password(&workspace, payload.password.as_deref())
|
||||
@@ -300,7 +307,12 @@ pub async fn publish_note_page(
|
||||
&state,
|
||||
"workspace",
|
||||
&workspace_slug,
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(
|
||||
&headers,
|
||||
"workspace",
|
||||
&workspace_slug,
|
||||
payload.access_token.as_deref(),
|
||||
),
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await?
|
||||
@@ -339,7 +351,6 @@ async fn ensure_public_page_access(
|
||||
page: &db::PublishedPage,
|
||||
) -> Result<(), ApiError> {
|
||||
let password = page_password(headers);
|
||||
let bearer = bearer_token(headers);
|
||||
if let Some(pad_id) = page.pad_id {
|
||||
if db::pad_public_page_unprotected(&state.db, pad_id).await? {
|
||||
return Ok(());
|
||||
@@ -358,10 +369,13 @@ async fn ensure_public_page_access(
|
||||
let pad = db::find_pad(&state.db, &slug)
|
||||
.await?
|
||||
.ok_or_else(ApiError::not_found_note)?;
|
||||
if db::verify_pad_password(&pad, password) {
|
||||
if has_header_resource_access(state, headers, "pad", &slug).await? {
|
||||
return Ok(());
|
||||
}
|
||||
if verify_resource_access_token(state, "pad", &slug, bearer).await? {
|
||||
let password_ok = db::verify_pad_password(&pad, password);
|
||||
check_resource_password_attempt(state, headers, "pad", &slug, password, password_ok)
|
||||
.await?;
|
||||
if password_ok {
|
||||
return Ok(());
|
||||
}
|
||||
return if pad.password_hash.is_some() {
|
||||
@@ -392,10 +406,20 @@ async fn ensure_public_page_access(
|
||||
let workspace = db::find_workspace(&state.db, &slug)
|
||||
.await?
|
||||
.ok_or_else(ApiError::not_found_workspace)?;
|
||||
if db::verify_workspace_password(&workspace, password) {
|
||||
if has_header_resource_access(state, headers, "workspace", &slug).await? {
|
||||
return Ok(());
|
||||
}
|
||||
if verify_resource_access_token(state, "workspace", &slug, bearer).await? {
|
||||
let password_ok = db::verify_workspace_password(&workspace, password);
|
||||
check_resource_password_attempt(
|
||||
state,
|
||||
headers,
|
||||
"workspace",
|
||||
&slug,
|
||||
password,
|
||||
password_ok,
|
||||
)
|
||||
.await?;
|
||||
if password_ok {
|
||||
return Ok(());
|
||||
}
|
||||
return if workspace.password_hash.is_some() {
|
||||
@@ -476,8 +500,9 @@ pub async fn pad_history(
|
||||
&state,
|
||||
&slug,
|
||||
payload.password.as_deref(),
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(&headers, "pad", &slug, payload.access_token.as_deref()),
|
||||
bearer_token(&headers),
|
||||
&headers,
|
||||
)
|
||||
.await?;
|
||||
let revisions = db::list_pad_revisions(&state.db, pad.id)
|
||||
@@ -501,8 +526,9 @@ pub async fn pad_restore(
|
||||
&state,
|
||||
&slug,
|
||||
payload.password.as_deref(),
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(&headers, "pad", &slug, payload.access_token.as_deref()),
|
||||
bearer_token(&headers),
|
||||
&headers,
|
||||
)
|
||||
.await?;
|
||||
let level = if db::verify_pad_password(&pad, payload.password.as_deref())
|
||||
@@ -514,7 +540,7 @@ pub async fn pad_restore(
|
||||
&state,
|
||||
"pad",
|
||||
&slug,
|
||||
payload.access_token.as_deref(),
|
||||
resource_request_token(&headers, "pad", &slug, payload.access_token.as_deref()),
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await?
|
||||
@@ -555,6 +581,7 @@ pub(super) async fn authorized_pad(
|
||||
password: Option<&str>,
|
||||
access_token: Option<&str>,
|
||||
bearer: Option<&str>,
|
||||
headers: &HeaderMap,
|
||||
) -> Result<db::Pad, ApiError> {
|
||||
let pad = db::find_pad(&state.db, slug)
|
||||
.await?
|
||||
@@ -563,11 +590,13 @@ pub(super) async fn authorized_pad(
|
||||
if pad.is_private != 0 && token_level == AccessLevel::None {
|
||||
return Err(ApiError::not_found_note());
|
||||
}
|
||||
if pad.password_hash.is_some()
|
||||
&& !db::verify_pad_password(&pad, password)
|
||||
&& token_level == AccessLevel::None
|
||||
{
|
||||
return Err(ApiError::forbidden("Password required or incorrect."));
|
||||
if pad.password_hash.is_some() && token_level < AccessLevel::Write {
|
||||
let password_ok = db::verify_pad_password(&pad, password);
|
||||
check_resource_password_attempt(state, headers, "pad", slug, password, password_ok)
|
||||
.await?;
|
||||
if token_level == AccessLevel::None && !password_ok {
|
||||
return Err(ApiError::forbidden("Password required or incorrect."));
|
||||
}
|
||||
}
|
||||
Ok(pad)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user