OAuth passing tests.

This commit is contained in:
Mauro D
2023-05-14 12:34:49 +00:00
parent 0959a6d737
commit 63cbb70dbc
10 changed files with 667 additions and 46 deletions

View File

@@ -65,9 +65,9 @@ impl crate::Config {
.property("jmap.session.cache.ttl")?
.unwrap_or(Duration::from_secs(3600)),
rate_authenticated: settings
.property_or_static("jmap.rate-limit.authenticated.rate", "1000/1s")?,
.property_or_static("jmap.rate-limit.account.rate", "1000/1s")?,
rate_authenticate_req: settings
.property_or_static("jmap.rate-limit.authenticate.rate", "10/1s")?,
.property_or_static("jmap.rate-limit.authentication.rate", "10/1s")?,
rate_anonymous: settings
.property_or_static("jmap.rate-limit.anonymous.rate", "100/1s")?,
rate_use_forwarded: settings

View File

@@ -86,11 +86,11 @@ impl JMAP {
Ok(None) => RequestError::not_found().into_http_response(),
Err(err) => {
tracing::error!(event = "error",
context = "blob_store",
account_id = account_id.document_id(),
blob_id = ?blob_id,
error = ?err,
"Failed to download blob");
context = "blob_store",
account_id = account_id.document_id(),
blob_id = ?blob_id,
error = ?err,
"Failed to download blob");
RequestError::internal_server_error().into_http_response()
}
};
@@ -161,48 +161,40 @@ impl JMAP {
match (path.next().unwrap_or(""), req.method()) {
("", &Method::GET) => {
// Limit anonymous requests
if let Err(err) = self.is_anonymous_allowed(remote_addr) {
return err.into_http_response();
return match self.is_anonymous_allowed(remote_addr) {
Ok(_) => self.handle_user_device_auth(req).await,
Err(err) => err.into_http_response(),
}
todo!()
}
("", &Method::POST) => {
// Limit authentication requests
if let Err(err) = self.is_auth_allowed(remote_addr) {
return err.into_http_response();
return match self.is_auth_allowed(remote_addr) {
Ok(_) => self.handle_user_device_auth_post(req).await,
Err(err) => err.into_http_response(),
}
todo!()
}
("code", &Method::GET) => {
// Limit anonymous requests
if let Err(err) = self.is_anonymous_allowed(remote_addr) {
return err.into_http_response();
return match self.is_anonymous_allowed(remote_addr) {
Ok(_) => self.handle_user_code_auth(req).await,
Err(err) => err.into_http_response(),
}
todo!()
}
("code", &Method::POST) => {
// Limit authentication requests
if let Err(err) = self.is_auth_allowed(remote_addr) {
return err.into_http_response();
return match self.is_auth_allowed(remote_addr) {
Ok(_) => self.handle_user_code_auth_post(req).await,
Err(err) => err.into_http_response(),
}
todo!()
}
("device", &Method::POST) => {
// Limit anonymous requests
if let Err(err) = self.is_anonymous_allowed(remote_addr) {
return err.into_http_response();
return match self.is_anonymous_allowed(remote_addr) {
Ok(_) => self.handle_device_auth(req, instance).await,
Err(err) => err.into_http_response(),
}
todo!()
}
("token", &Method::POST) => {
// Limit anonymous requests
if let Err(err) = self.is_anonymous_allowed(remote_addr) {
return err.into_http_response();
return match self.is_anonymous_allowed(remote_addr) {
Ok(_) => self.handle_token_request(req).await,
Err(err) => err.into_http_response(),
}
todo!()
}
_ => (),
}
@@ -306,7 +298,7 @@ pub async fn fetch_body(
let mut bytes = Vec::with_capacity(1024);
while let Some(Ok(frame)) = req.frame().await {
if let Some(data) = frame.data_ref() {
if bytes.len() + data.len() < max_size {
if bytes.len() + data.len() <= max_size {
bytes.extend_from_slice(data);
} else {
return Err(RequestError::limit(RequestLimitError::Size));
@@ -409,8 +401,15 @@ impl ToHttpResponse for UploadResponse {
impl ToHttpResponse for RequestError {
fn into_http_response(self) -> HttpResponse {
JsonResponse::with_status(StatusCode::from_u16(self.status).unwrap(), self)
.into_http_response()
hyper::Response::builder()
.status(StatusCode::from_u16(self.status).unwrap())
.header(header::CONTENT_TYPE, "application/problem+json")
.body(
Full::new(Bytes::from(serde_json::to_string(&self).unwrap()))
.map_err(|never| match never {})
.boxed(),
)
.unwrap()
}
}

View File

@@ -25,7 +25,7 @@ use super::{
impl JMAP {
// Code authorization flow, handles an authorization request
pub async fn handle_user_code_auth(req: &mut HttpRequest) -> HttpResponse {
pub async fn handle_user_code_auth(&self, req: &mut HttpRequest) -> HttpResponse {
let params = form_urlencoded::parse(req.uri().query().unwrap_or_default().as_bytes())
.into_owned()
.collect::<HashMap<_, _>>();

View File

@@ -199,7 +199,7 @@ impl JMAP {
),
rate_limit_auth: LruCache::with_capacity(
config
.property("jmap.rate-limit.authenticated.size")
.property("jmap.rate-limit.account.size")
.failed("Invalid property")
.unwrap_or(1024),
),

View File

@@ -23,6 +23,7 @@ impl JMAP {
let sort_as_tree = request.arguments.sort_as_tree.unwrap_or(false);
let filter_as_tree = request.arguments.filter_as_tree.unwrap_or(false);
let mut filters = Vec::with_capacity(request.filter.len());
let mailbox_ids = self.mailbox_get_or_create(account_id).await?;
for cond in std::mem::take(&mut request.filter) {
match cond {
@@ -100,11 +101,7 @@ impl JMAP {
&& (paginate.is_some()
|| (response.total.map_or(false, |total| total > 0) && filter_as_tree))
{
for document_id in self
.get_document_ids(account_id, Collection::Mailbox)
.await?
.unwrap_or_default()
{
for document_id in mailbox_ids {
let parent_id = self
.get_property::<Object<Value>>(
account_id,