From ddcd423e6fbbee901473f63e75fce644d9a52c2e Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Mon, 6 Apr 2020 22:57:58 +0200
Subject: [PATCH] feat: random tokens, sessions, guest usernames and device ids

---
 Cargo.lock   |  3 ++-
 Cargo.toml   |  1 +
 src/main.rs  | 39 +++++++++++++++++++++++++++------------
 src/utils.rs |  8 ++++++++
 4 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 2978456aa..cd519ba2c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -607,6 +607,7 @@ dependencies = [
  "js_int",
  "log",
  "pretty_env_logger",
+ "rand",
  "rocket",
  "ruma-api",
  "ruma-client-api",
@@ -1051,7 +1052,7 @@ dependencies = [
 [[package]]
 name = "ruma-client-api"
 version = "0.7.2"
-source = "git+https://github.com/ruma/ruma-client-api.git#fe92c2940a2db80509e9a9f162c0f68f3ec3d0a4"
+source = "git+https://github.com/ruma/ruma-client-api.git#dc582758e4f846b3751d84d21eb321e8eb4faf51"
 dependencies = [
  "http",
  "js_int",
diff --git a/Cargo.toml b/Cargo.toml
index 631e6eeaf..7fda8ee36 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,3 +23,4 @@ ruma-signatures = { git = "https://github.com/ruma/ruma-signatures.git" }
 ruma-federation-api = "0.0.1"
 serde = "1.0.106"
 tokio = "0.2.16"
+rand = "0.7.3"
diff --git a/src/main.rs b/src/main.rs
index 2d8794349..6b975341c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,7 +19,7 @@
         membership::join_room_by_id,
         message::create_message_event,
         room::create_room,
-        session::login,
+        session::{get_login_types, login},
         state::{create_state_event_for_empty_key, create_state_event_for_key},
         sync::sync_events,
     },
@@ -31,6 +31,11 @@
 use serde_json::json;
 use std::{collections::HashMap, convert::TryInto, path::PathBuf};
 
+const DEVICE_ID_LENGTH: usize = 16;
+const SESSION_ID_LENGTH: usize = 16;
+const TOKEN_LENGTH: usize = 16;
+const GUEST_NAME_LENGTH: usize = 16;
+
 #[get("/_matrix/client/versions")]
 fn get_supported_versions_route() -> MatrixResult<get_supported_versions::Response> {
     MatrixResult(Ok(get_supported_versions::Response {
@@ -47,14 +52,14 @@ fn register_route(
     if body.auth.is_none() {
         return MatrixResult(Err(Error {
             kind: ErrorKind::InvalidUsername,
-            message: serde_json::to_string(&json!({
+            message: json!({
                 "flows": [
                     { "stages": [ "m.login.dummy" ] },
                 ],
                 "params": {},
-                "session": "TODO:randomsessionid",
-            }))
-            .unwrap(),
+                "session": utils::random_string(SESSION_ID_LENGTH),
+            })
+            .to_string(),
             status_code: http::StatusCode::UNAUTHORIZED,
         }));
     }
@@ -62,7 +67,9 @@ fn register_route(
     // Validate user id
     let user_id: UserId = match (*format!(
         "@{}:{}",
-        body.username.clone().unwrap_or("randomname".to_owned()),
+        body.username
+            .clone()
+            .unwrap_or_else(|| utils::random_string(GUEST_NAME_LENGTH)),
         data.hostname()
     ))
     .try_into()
@@ -95,13 +102,13 @@ fn register_route(
     let device_id = body
         .device_id
         .clone()
-        .unwrap_or_else(|| "TODO:randomdeviceid".to_owned());
+        .unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH));
 
     // Add device
     data.device_add(&user_id, &device_id);
 
     // Generate new token for the device
-    let token = "TODO:randomtoken".to_owned();
+    let token = utils::random_string(TOKEN_LENGTH);
     data.token_replace(&user_id, &device_id, token.clone());
 
     MatrixResult(Ok(register::Response {
@@ -112,6 +119,13 @@ fn register_route(
     }))
 }
 
+#[get("/_matrix/client/r0/login", data = "<_body>")]
+fn get_login_route(_body: Ruma<login::Request>) -> MatrixResult<get_login_types::Response> {
+    MatrixResult(Ok(get_login_types::Response {
+        flows: vec![get_login_types::LoginType::Password],
+    }))
+}
+
 #[post("/_matrix/client/r0/login", data = "<body>")]
 fn login_route(data: State<Data>, body: Ruma<login::Request>) -> MatrixResult<login::Response> {
     // Validate login method
@@ -167,22 +181,22 @@ fn login_route(data: State<Data>, body: Ruma<login::Request>) -> MatrixResult<lo
     let device_id = body
         .device_id
         .clone()
-        .unwrap_or("TODO:randomdeviceid".to_owned());
+        .unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH));
 
     // Add device
     data.device_add(&user_id, &device_id);
 
     // Generate a new token for the device
-    let token = "TODO:randomtoken".to_owned();
+    let token = utils::random_string(TOKEN_LENGTH);
     data.token_replace(&user_id, &device_id, token.clone());
 
-    return MatrixResult(Ok(login::Response {
+    MatrixResult(Ok(login::Response {
         user_id,
         access_token: token,
         home_server: Some(data.hostname().to_owned()),
         device_id,
         well_known: None,
-    }));
+    }))
 }
 
 #[post("/_matrix/client/r0/createRoom", data = "<body>")]
@@ -388,6 +402,7 @@ fn main() {
             routes![
                 get_supported_versions_route,
                 register_route,
+                get_login_route,
                 login_route,
                 create_room_route,
                 get_alias_route,
diff --git a/src/utils.rs b/src/utils.rs
index 19f3f0224..b32b0f68b 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,3 +1,4 @@
+use rand::prelude::*;
 use std::{
     convert::TryInto,
     time::{SystemTime, UNIX_EPOCH},
@@ -32,3 +33,10 @@ pub fn u64_from_bytes(bytes: &[u8]) -> u64 {
 pub fn string_from_bytes(bytes: &[u8]) -> String {
     String::from_utf8(bytes.to_vec()).expect("bytes are valid utf8")
 }
+
+pub fn random_string(length: usize) -> String {
+    thread_rng()
+        .sample_iter(&rand::distributions::Alphanumeric)
+        .take(length)
+        .collect()
+}
-- 
GitLab