diff options
author | Vika <vika@fireburn.ru> | 2021-05-04 17:05:51 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2021-05-04 17:07:25 +0300 |
commit | 08c09aaa055c05228855eed8cded9fdfe4939c0f (patch) | |
tree | 792ba1d2a3b3af7a837135aa90620d8f689d7ebd /src/micropub/get.rs | |
download | kittybox-08c09aaa055c05228855eed8cded9fdfe4939c0f.tar.zst |
Initial commit
Working features: - Sending posts from the database - Reading posts from the database - Responding with MF2-JSON (only in debug mode!) - Not locking the database when not needed - All database actions are atomic (except for a small race where UIDs can clash, but that's not gonna happen often) TODOs: - Send webmentions - Send syndication requests - Send WebSub notifications - Make tombstones for deleted posts (update adding dt-deleted) - Rich reply contexts (possibly on the frontend part?) - Frontend? - Fix UID race Code maintenance TODOs: - Split the database module - Finish implementing the in-memory test database - Make RedisDatabase unit tests launch their own Redis instances (see redis-rs/tests/support/mod.rs for more info) - Write more unit-tests!!!
Diffstat (limited to 'src/micropub/get.rs')
-rw-r--r-- | src/micropub/get.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/micropub/get.rs b/src/micropub/get.rs new file mode 100644 index 0000000..9a12316 --- /dev/null +++ b/src/micropub/get.rs @@ -0,0 +1,86 @@ +use tide::prelude::{Deserialize, json}; +use tide::{Request, Response, Result}; +use crate::ApplicationState; +use crate::database::{MicropubChannel,Storage}; +use crate::indieauth::User; + +#[derive(Deserialize)] +struct QueryOptions { + q: String, + url: Option<String> +} + +pub async fn get_handler<Backend>(req: Request<ApplicationState<Backend>>) -> Result +where + Backend: Storage + Send + Sync +{ + let user = req.ext::<User>().unwrap(); + let backend = &req.state().storage; + let media_endpoint = &req.state().media_endpoint; + let query = req.query::<QueryOptions>().unwrap_or(QueryOptions { q: "".to_string(), url: None }); + match &*query.q { + "config" => { + let channels: Vec<MicropubChannel>; + match backend.get_channels(&user).await { + Ok(chans) => channels = chans, + Err(err) => return Ok(Response::builder(500).body(json!({ + "error": "database_error", + "error_description": format!("Couldn't fetch channel list from the database: {:?}", err) + })).build()) + } + Ok(Response::builder(200).body(json!({ + "q": ["source", "config", "channel"], + "channels": channels, + "media-endpoint": media_endpoint + })).build()) + }, + "channel" => { + let channels: Vec<MicropubChannel>; + match backend.get_channels(&user).await { + Ok(chans) => channels = chans, + Err(err) => return Ok(Response::builder(500).body(json!({ + "error": "database_error", + "error_description": format!("Couldn't fetch channel list from the database: {:?}", err) + })).build()) + } + return Ok(Response::builder(200).body(json!(channels)).build()) + } + "source" => { + if user.check_scope("create") || user.check_scope("update") || user.check_scope("delete") || user.check_scope("undelete") { + if let Some(url) = query.url { + match backend.get_post(&url).await { + Ok(post) => if let Some(post) = post { + return Ok(Response::builder(200).body(post).build()) + } else { + return Ok(Response::builder(404).build()) + }, + Err(err) => return Ok(Response::builder(500).body(json!({ + "error": "database_error", + "error_description": err + })).build()) + } + } else { + return Ok(Response::builder(400).body(json!({ + "error": "invalid_request", + "error_description": "Please provide `url`." + })).build()) + } + } else { + Ok(Response::builder(401).body(json!({ + "error": "insufficient_scope", + "error_description": "You don't have the required scopes to proceed.", + "scope": "update" + })).build()) + } + }, + // Errors + "" => Ok(Response::builder(400).body(json!({ + "error": "invalid_request", + "error_description": "No ?q= parameter specified. Try ?q=config maybe?" + })).build()), + _ => Ok(Response::builder(400).body(json!({ + "error": "invalid_request", + "error_description": "Unsupported ?q= query. Try ?q=config and see the q array for supported values." + })).build()) + } +} |