mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-01 00:31:09 +00:00
Use simplified Snowflake ID generation
This prevents leaking server information to client with little effort.
This commit is contained in:
parent
59d51937da
commit
a7f260027d
5 changed files with 36 additions and 12 deletions
|
@ -179,7 +179,7 @@ paths:
|
|||
200:
|
||||
content:
|
||||
application/json:
|
||||
type: integer
|
||||
type: string
|
||||
description: Created chat id (cid).
|
||||
400:
|
||||
description: Body is invalid or fails the verification.
|
||||
|
|
|
@ -23,7 +23,7 @@ CREATE TABLE IF NOT EXISTS `room_member` (
|
|||
CREATE INDEX IF NOT EXISTS `member_room` ON `room_member` (`uid` ASC, `rid` ASC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `room_item` (
|
||||
`cid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
`cid` INTEGER NOT NULL PRIMARY KEY,
|
||||
`rid` INTEGER NOT NULL REFERENCES `room` ON DELETE CASCADE,
|
||||
`uid` INTEGER NOT NULL REFERENCES `user` ON DELETE RESTRICT,
|
||||
`timestamp` INTEGER NOT NULL,
|
||||
|
|
|
@ -10,7 +10,7 @@ static INIT_SQL: &str = include_str!("../schema.sql");
|
|||
|
||||
// Simple and stupid version check for now.
|
||||
// `echo -n 'blahd-database-0' | sha256sum | head -c5` || version
|
||||
const APPLICATION_ID: i32 = 0xd9e_8401;
|
||||
const APPLICATION_ID: i32 = 0xd9e_8402;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Database {
|
||||
|
|
21
blahd/src/id.rs
Normal file
21
blahd/src/id.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
/// Id generation.
|
||||
/// Ref: https://en.wikipedia.org/wiki/Snowflake_ID
|
||||
/// FIXME: Currently we assume no more than one request in a single millisecond.
|
||||
use std::time::SystemTime;
|
||||
|
||||
use blah::types::Id;
|
||||
|
||||
pub trait IdExt {
|
||||
fn gen() -> Self;
|
||||
}
|
||||
|
||||
impl IdExt for Id {
|
||||
fn gen() -> Self {
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.expect("after UNIX epoch");
|
||||
let timestamp_ms = timestamp.as_millis() as i64;
|
||||
assert!(timestamp_ms > 0);
|
||||
Id(timestamp_ms << 16)
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ use blah::types::{
|
|||
use config::Config;
|
||||
use database::Database;
|
||||
use ed25519_dalek::SIGNATURE_LENGTH;
|
||||
use id::IdExt;
|
||||
use middleware::{ApiError, MaybeAuth, ResultExt as _, SignedJson};
|
||||
use parking_lot::Mutex;
|
||||
use rusqlite::{named_params, params, Connection, OptionalExtension, Row, ToSql};
|
||||
|
@ -30,6 +31,7 @@ mod middleware;
|
|||
mod config;
|
||||
mod database;
|
||||
mod event;
|
||||
mod id;
|
||||
mod utils;
|
||||
|
||||
/// Blah Chat Server
|
||||
|
@ -356,17 +358,18 @@ async fn room_create(
|
|||
};
|
||||
|
||||
let txn = conn.transaction()?;
|
||||
let rid = Id::gen();
|
||||
txn.execute(
|
||||
r"
|
||||
INSERT INTO `room` (`title`, `attrs`)
|
||||
VALUES (:title, :attrs)
|
||||
INSERT INTO `room` (`rid`, `title`, `attrs`)
|
||||
VALUES (:rid, :title, :attrs)
|
||||
",
|
||||
named_params! {
|
||||
":rid": rid,
|
||||
":title": params.signee.payload.title,
|
||||
":attrs": params.signee.payload.attrs,
|
||||
},
|
||||
)?;
|
||||
let rid = Id(txn.last_insert_rowid());
|
||||
let mut insert_user = txn.prepare(
|
||||
r"
|
||||
INSERT INTO `user` (`userkey`)
|
||||
|
@ -664,7 +667,7 @@ async fn room_post_item(
|
|||
st: ArcState,
|
||||
R(Path(rid), _): RE<Path<Id>>,
|
||||
SignedJson(chat): SignedJson<ChatPayload>,
|
||||
) -> Result<Json<u64>, ApiError> {
|
||||
) -> Result<Json<Id>, ApiError> {
|
||||
if rid != chat.signee.payload.room {
|
||||
return Err(error_response!(
|
||||
StatusCode::BAD_REQUEST,
|
||||
|
@ -705,13 +708,14 @@ async fn room_post_item(
|
|||
));
|
||||
};
|
||||
|
||||
let cid = conn.query_row(
|
||||
let cid = Id::gen();
|
||||
conn.execute(
|
||||
r"
|
||||
INSERT INTO `room_item` (`rid`, `uid`, `timestamp`, `nonce`, `sig`, `rich_text`)
|
||||
VALUES (:rid, :uid, :timestamp, :nonce, :sig, :rich_text)
|
||||
RETURNING `cid`
|
||||
INSERT INTO `room_item` (`cid`, `rid`, `uid`, `timestamp`, `nonce`, `sig`, `rich_text`)
|
||||
VALUES (:cid, :rid, :uid, :timestamp, :nonce, :sig, :rich_text)
|
||||
",
|
||||
named_params! {
|
||||
":cid": cid,
|
||||
":rid": rid,
|
||||
":uid": uid,
|
||||
":timestamp": chat.signee.timestamp,
|
||||
|
@ -719,7 +723,6 @@ async fn room_post_item(
|
|||
":rich_text": &chat.signee.payload.rich_text,
|
||||
":sig": chat.sig,
|
||||
},
|
||||
|row| row.get::<_, u64>(0),
|
||||
)?;
|
||||
|
||||
// FIXME: Optimize this to not traverses over all members.
|
||||
|
|
Loading…
Add table
Reference in a new issue