fixes and functions
This commit is contained in:
1 parent
4643de4309
commit
a7329f5535
13 files changed
+330
-15
No files matched your search
+36
-1
@@ -22,6 +22,9 @@ pub const CSRF_HEADER: &str = "x-rustpad-csrf";
|
||||
|
||||
const CSRF_TOKEN_BYTES: usize = 32;
|
||||
const CSRF_TTL_SECONDS: i64 = 24 * 60 * 60;
|
||||
const RESOURCE_ACCESS_COOKIE_PREFIX: &str = "__Host-rustpad_access_";
|
||||
const RESOURCE_ACCESS_COOKIE_SUFFIX_LENGTH: usize = 24;
|
||||
const RESOURCE_ACCESS_TOKEN_LENGTH: usize = 64;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CsrfResponse {
|
||||
@@ -50,6 +53,26 @@ pub fn resource_token<'a>(headers: &'a HeaderMap, kind: &str, slug: &str) -> Opt
|
||||
cookie_value(headers, &name)
|
||||
}
|
||||
|
||||
pub(crate) fn resource_access_cookies(headers: &HeaderMap) -> Vec<(String, Option<String>)> {
|
||||
headers
|
||||
.get_all(header::COOKIE)
|
||||
.iter()
|
||||
.filter_map(|value| value.to_str().ok())
|
||||
.flat_map(|cookies| cookies.split(';'))
|
||||
.filter_map(|part| {
|
||||
let (name, value) = part.trim().split_once('=')?;
|
||||
if !valid_resource_access_cookie_name(name) {
|
||||
return None;
|
||||
}
|
||||
let value = value.trim();
|
||||
let token = (value.len() == RESOURCE_ACCESS_TOKEN_LENGTH
|
||||
&& value.bytes().all(|byte| byte.is_ascii_hexdigit()))
|
||||
.then(|| value.to_owned());
|
||||
Some((name.to_owned(), token))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn share_session_token<'a>(headers: &'a HeaderMap, kind: &str, slug: &str) -> Option<&'a str> {
|
||||
let name = share_session_cookie_name(kind, slug);
|
||||
cookie_value(headers, &name)
|
||||
@@ -63,6 +86,10 @@ pub fn clear_session_cookie() -> HeaderValue {
|
||||
clear_cookie(SESSION_COOKIE)
|
||||
}
|
||||
|
||||
pub(crate) fn clear_resource_access_cookie(name: &str) -> Option<HeaderValue> {
|
||||
valid_resource_access_cookie_name(name).then(|| clear_cookie(name))
|
||||
}
|
||||
|
||||
pub async fn csrf_token_endpoint(headers: HeaderMap) -> Response {
|
||||
let token = csrf_cookie_token(&headers)
|
||||
.filter(|value| valid_csrf_token(value))
|
||||
@@ -176,7 +203,15 @@ pub fn websocket_origin_allowed(headers: &HeaderMap) -> bool {
|
||||
|
||||
fn resource_cookie_name(kind: &str, slug: &str) -> String {
|
||||
let digest = Sha256::digest(format!("{kind}:{slug}").as_bytes());
|
||||
format!("__Host-rustpad_access_{}", hex::encode(&digest[..12]))
|
||||
format!("{RESOURCE_ACCESS_COOKIE_PREFIX}{}", hex::encode(&digest[..12]))
|
||||
}
|
||||
|
||||
fn valid_resource_access_cookie_name(name: &str) -> bool {
|
||||
name.strip_prefix(RESOURCE_ACCESS_COOKIE_PREFIX)
|
||||
.is_some_and(|suffix| {
|
||||
suffix.len() == RESOURCE_ACCESS_COOKIE_SUFFIX_LENGTH
|
||||
&& suffix.bytes().all(|byte| byte.is_ascii_hexdigit())
|
||||
})
|
||||
}
|
||||
|
||||
fn share_session_cookie_name(kind: &str, slug: &str) -> String {
|
||||
|
||||
Reference in new issue
Block a user