[fractal] api: Create types for well-known request
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] api: Create types for well-known request
- Date: Mon, 15 Apr 2019 15:50:38 +0000 (UTC)
commit 2a659b3962d6c52c07dee15cfdfeb6217a9284d1
Author: Christopher Davis <brainblasted disroot org>
Date: Sat Mar 23 21:32:15 2019 -0700
api: Create types for well-known request
Instead of asking for the identity server and homeserver
url for login, we can ask the users to give us a domain
and make a request to .well-known/matrix/client. This
will give us the identity server and the true url for
the homeserver.
See https://matrix.org/docs/spec/client_server/latest#well-known-uri for details
fractal-matrix-api/src/backend/mod.rs | 2 +-
fractal-matrix-api/src/backend/register.rs | 18 +++++++++++
fractal-matrix-api/src/model/register.rs | 48 +++++++++++++++++++++++++++++-
3 files changed, 66 insertions(+), 2 deletions(-)
---
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index 7487c7d4..0e1c7a4f 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -14,7 +14,7 @@ use crate::cache::CacheMap;
mod directory;
mod media;
-mod register;
+pub mod register;
mod room;
mod stickers;
mod sync;
diff --git a/fractal-matrix-api/src/backend/register.rs b/fractal-matrix-api/src/backend/register.rs
index 4193957e..a393093b 100644
--- a/fractal-matrix-api/src/backend/register.rs
+++ b/fractal-matrix-api/src/backend/register.rs
@@ -11,6 +11,7 @@ use crate::types::LoginRequest;
use crate::types::LoginResponse;
use crate::types::RegisterRequest;
use crate::types::RegisterResponse;
+use crate::types::WellKnownResponse;
use crate::backend::types::BKResponse;
use crate::backend::types::Backend;
@@ -158,3 +159,20 @@ pub fn register(bk: &Backend, user: String, password: String, server: &str) -> R
Ok(())
}
+
+pub fn get_well_known(domain: &str) -> Result<WellKnownResponse, Error> {
+ let well_known = Url::parse(domain)?.join(".well-known/matrix/client")?;
+
+ // NOTE: The query! macro doesn't like what we're
+ // trying to do, so this implements what we need
+
+ let handle = thread::spawn(move || json_q("get", &well_known, &json!(null)));
+
+ match handle.join() {
+ Ok(r) => match r {
+ Ok(val) => serde_json::from_value(val).map_err(|_| Error::BackendError),
+ Err(e) => Err(e.into()),
+ },
+ _ => Err(Error::BackendError),
+ }
+}
diff --git a/fractal-matrix-api/src/model/register.rs b/fractal-matrix-api/src/model/register.rs
index 82a33cde..cbd7a666 100644
--- a/fractal-matrix-api/src/model/register.rs
+++ b/fractal-matrix-api/src/model/register.rs
@@ -1,6 +1,6 @@
use super::{AuthenticationData, Identifier, Medium, UserIdentifier};
use crate::globals;
-use serde::{Deserialize, Serialize};
+use serde::{de, Deserialize, Deserializer, Serialize};
use std::ops::Not;
#[derive(Clone, Debug, Serialize)]
@@ -83,3 +83,49 @@ pub struct RegisterResponse {
pub access_token: Option<String>,
pub device_id: Option<String>,
}
+
+#[derive(Clone, Debug, Deserialize)]
+#[serde(default, tag = "type")]
+pub struct WellKnownResponse {
+ #[serde(deserialize_with = "extract_base_url", rename = "m.homeserver")]
+ pub homeserver: Option<String>,
+ #[serde(deserialize_with = "extract_base_url", rename = "m.identity_server")]
+ pub identity_server: Option<String>,
+}
+
+impl Default for WellKnownResponse {
+ fn default() -> Self {
+ // Identity server is usually vector.im if not specified
+ Self {
+ homeserver: None,
+ identity_server: Some("https://vector.im".to_owned()),
+ }
+ }
+}
+
+fn extract_base_url<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ struct BaseUrlVisitor;
+
+ impl<'de> de::Visitor<'de> for BaseUrlVisitor {
+ type Value = Option<String>;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ formatter.write_str("an object with a base_url key")
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: de::MapAccess<'de>,
+ {
+ let res = map
+ .next_entry::<String, String>()?
+ .and_then(|(key, value)| if key == "base_url" { Some(value) } else { None });
+ Ok(res)
+ }
+ }
+
+ deserializer.deserialize_any(BaseUrlVisitor)
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]