forked from alemi/upub
feat: initial work on validating http signatures
This commit is contained in:
parent
d0816a0f6a
commit
6ea4f06d54
2 changed files with 38 additions and 7 deletions
|
@ -75,8 +75,8 @@ pub async fn post(
|
||||||
) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
) -> Result<JsonLD<serde_json::Value>, StatusCode> {
|
||||||
match auth {
|
match auth {
|
||||||
Identity::Anonymous => Err(StatusCode::UNAUTHORIZED),
|
Identity::Anonymous => Err(StatusCode::UNAUTHORIZED),
|
||||||
Identity::Server(_) => Err(StatusCode::NOT_IMPLEMENTED),
|
Identity::Remote(_) => Err(StatusCode::NOT_IMPLEMENTED),
|
||||||
Identity::User(uid) => if ctx.uid(id) == uid {
|
Identity::Local(uid) => if ctx.uid(id) == uid {
|
||||||
match activity.base_type() {
|
match activity.base_type() {
|
||||||
None => Err(StatusCode::BAD_REQUEST),
|
None => Err(StatusCode::BAD_REQUEST),
|
||||||
Some(BaseType::Link(_)) => Err(StatusCode::UNPROCESSABLE_ENTITY),
|
Some(BaseType::Link(_)) => Err(StatusCode::UNPROCESSABLE_ENTITY),
|
||||||
|
|
41
src/auth.rs
41
src/auth.rs
|
@ -6,8 +6,8 @@ use crate::{model, server::Context};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Identity {
|
pub enum Identity {
|
||||||
Anonymous,
|
Anonymous,
|
||||||
User(String),
|
Local(String),
|
||||||
Server(String),
|
Remote(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AuthIdentity(pub Identity);
|
pub struct AuthIdentity(pub Identity);
|
||||||
|
@ -36,7 +36,7 @@ where
|
||||||
.one(ctx.db())
|
.one(ctx.db())
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(Some(x)) => identity = Identity::User(x.actor),
|
Ok(Some(x)) => identity = Identity::Local(x.actor),
|
||||||
Ok(None) => return Err(StatusCode::UNAUTHORIZED),
|
Ok(None) => return Err(StatusCode::UNAUTHORIZED),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("failed querying user session: {e}");
|
tracing::error!("failed querying user session: {e}");
|
||||||
|
@ -45,8 +45,39 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check and validate HTTP signature
|
if let Some(sig) = parts
|
||||||
|
.headers
|
||||||
|
.get("Signature")
|
||||||
|
.map(|v| v.to_str().unwrap_or(""))
|
||||||
|
{
|
||||||
|
// TODO load pub key of actor and decode+verify signature
|
||||||
|
let decoded = "asd".to_string();
|
||||||
|
|
||||||
|
let mut key_id = None;
|
||||||
|
let mut headers = None;
|
||||||
|
let mut signature = None;
|
||||||
|
for frag in decoded.split(',') {
|
||||||
|
if frag.starts_with("keyId=") {
|
||||||
|
key_id = Some(frag.replace("keyId=\"", ""));
|
||||||
|
key_id.as_mut().unwrap().pop();
|
||||||
|
}
|
||||||
|
if frag.starts_with("signature=") {
|
||||||
|
signature = Some(frag.replace("signature=\"", ""));
|
||||||
|
signature.as_mut().unwrap().pop();
|
||||||
|
}
|
||||||
|
if frag.starts_with("headers=") {
|
||||||
|
let mut h = frag.replace("headers=\"", "");
|
||||||
|
h.pop();
|
||||||
|
headers = Some(h.split(' ').map(|x| x.to_string()).collect::<Vec<String>>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if key_id.is_none() || headers.is_none() || signature.is_none() {
|
||||||
|
tracing::warn!("malformed signature");
|
||||||
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(AuthIdentity(identity))
|
Ok(AuthIdentity(identity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue