Browse Source

fix sync friend info

pull/18/head
Sun 4 years ago
parent
commit
36921af9b4
  1. 2
      lib/global.dart
  2. 2
      lib/l10n/localizations_en.dart
  3. 2
      lib/l10n/localizations_zh.dart
  4. 9
      src/account.rs
  5. 110
      src/apps/chat/layer.rs
  6. 2
      src/apps/chat/models/friend.rs
  7. 27
      src/apps/chat/rpc.rs
  8. 1
      src/apps/wallet/rpc.rs
  9. 12
      src/group.rs

2
lib/global.dart

@ -1,5 +1,5 @@
class Global { class Global {
static String version = 'v0.2.0'; static String version = 'v0.5.0';
static String gid = '0000000000000000000000000000000000000000000000000000000000000000'; static String gid = '0000000000000000000000000000000000000000000000000000000000000000';
static String httpRpc = '127.0.0.1:8000'; static String httpRpc = '127.0.0.1:8000';
static String wsRpc = '127.0.0.1:8080'; static String wsRpc = '127.0.0.1:8080';

2
lib/l10n/localizations_en.dart

@ -301,7 +301,7 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get deviceQrcodeIntro => 'Tips: Scan to Login and sync, use it with care, and do not tell others'; String get deviceQrcodeIntro => 'Tips: Scan to Login and sync, use it with care, and do not tell others';
@override @override
String get about2 => 'An open source encrypted peer-to-peer session system would allow data to be sent securely from one terminal to another without going through third-party services.'; String get about2 => 'An open source encrypted peer-to-peer system for data security. Your place, your rules.';
@override @override
String get donate => 'Donate'; String get donate => 'Donate';
@override @override

2
lib/l10n/localizations_zh.dart

@ -301,7 +301,7 @@ class AppLocalizationsZh extends AppLocalizations {
@override @override
String get deviceQrcodeIntro => '扫码登陆与同步账户,小心使用,请勿告知他人'; String get deviceQrcodeIntro => '扫码登陆与同步账户,小心使用,请勿告知他人';
@override @override
String get about2 => '一款开源的加密对等通信系统,允许信息安全地从发送端经由网络直接到达接收端而不用经过第三方服务'; String get about2 => '属于自己的安全数据环境,你的地盘,你做主';
@override @override
String get donate => '捐助'; String get donate => '捐助';
@override @override

9
src/account.rs

@ -275,11 +275,11 @@ impl Account {
pub fn update_info(&self, db: &DStorage) -> Result<usize> { pub fn update_info(&self, db: &DStorage) -> Result<usize> {
let sql = format!( let sql = format!(
"UPDATE accounts SET name='{}', avatar='{}', wallet='{}', height={} WHERE id = {}", "UPDATE accounts SET name='{}', avatar='{}', wallet='{}', pub_height={} WHERE id = {}",
self.name, self.name,
base64::encode(&self.avatar), base64::encode(&self.avatar),
self.wallet, self.wallet,
self.pub_height + 1, self.pub_height,
self.id, self.id,
); );
db.update(&sql) db.update(&sql)
@ -314,12 +314,13 @@ pub(crate) struct User {
} }
impl User { impl User {
pub fn simple( pub fn new(
id: GroupId, id: GroupId,
addr: PeerId, addr: PeerId,
name: String, name: String,
avatar: Vec<u8>, avatar: Vec<u8>,
wallet: String, wallet: String,
height: i64,
) -> Self { ) -> Self {
Self { Self {
id, id,
@ -327,7 +328,7 @@ impl User {
name, name,
avatar, avatar,
wallet, wallet,
height: 0, height,
} }
} }

110
src/apps/chat/layer.rs

@ -17,6 +17,7 @@ use crate::layer::{Layer, Online};
use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH};
use crate::rpc::{ use crate::rpc::{
notice_menu, session_connect, session_create, session_last, session_lost, session_suspend, notice_menu, session_connect, session_create, session_last, session_lost, session_suspend,
session_update_name,
}; };
use crate::session::{connect_session, Session, SessionType}; use crate::session::{connect_session, Session, SessionType};
use crate::storage::{account_db, chat_db, session_db, write_avatar_sync}; use crate::storage::{account_db, chat_db, session_db, write_avatar_sync};
@ -38,10 +39,12 @@ pub(crate) enum LayerEvent {
Suspend(GroupId), Suspend(GroupId),
/// actived. extend BaseLayerEvent. /// actived. extend BaseLayerEvent.
Actived(GroupId), Actived(GroupId),
/// make friendship request. user is simple. /// make friendship request.
Request(User, String), /// params is name, remark, proof.
/// agree friendship request. user is simple. Request(String, String, Proof),
Agree(User, Proof), /// agree friendship request.
/// params is gid.
Agree(Proof),
/// reject friendship request. /// reject friendship request.
Reject, Reject,
/// receiver gid, sender gid, message. /// receiver gid, sender gid, message.
@ -199,7 +202,6 @@ impl LayerEvent {
bytes: Vec<u8>, bytes: Vec<u8>,
) -> Result<HandleResult> { ) -> Result<HandleResult> {
let event: LayerEvent = bincode::deserialize(&bytes)?; let event: LayerEvent = bincode::deserialize(&bytes)?;
let mut results = HandleResult::new(); let mut results = HandleResult::new();
match event { match event {
@ -219,77 +221,44 @@ impl LayerEvent {
let _ = layer.running_mut(&mgid)?.active(&fgid, false); let _ = layer.running_mut(&mgid)?.active(&fgid, false);
results.rpcs.push(session_connect(mgid, &sid, &addr)); results.rpcs.push(session_connect(mgid, &sid, &addr));
} }
LayerEvent::Request(remote, remark) => { LayerEvent::Request(name, remark, proof) => {
// 1. check verify.
proof.verify(&fgid, &addr, &layer.addr)?;
if load_friend(&layer.base, &mgid, &fgid).is_err() { if load_friend(&layer.base, &mgid, &fgid).is_err() {
// check if exist request. // check if exist request.
let db = chat_db(&layer.base, &mgid)?; let db = chat_db(&layer.base, &mgid)?;
if let Ok(req) = Request::get_id(&db, &remote.id) { if let Ok(req) = Request::get_id(&db, &fgid) {
Request::delete(&db, &req.id)?; // delete the old request. Request::delete(&db, &req.id)?; // delete the old request.
results.rpcs.push(rpc::request_delete(mgid, req.id)); results.rpcs.push(rpc::request_delete(mgid, req.id));
} }
let mut request = Request::new( let mut request = Request::new(fgid, addr, name, remark, false, true);
remote.id,
addr,
remote.name.clone(),
remark.clone(),
false,
true,
);
// save to db. // save to db.
request.insert(&db)?; request.insert(&db)?;
drop(db); drop(db);
// save the avatar.
write_avatar_sync(&layer.base, &mgid, &request.gid, remote.avatar.clone())?;
layer.group.write().await.broadcast(
&mgid,
InnerEvent::SessionRequestCreate(false, remote, remark),
REQUEST_TABLE_PATH,
request.id,
&mut results,
)?;
results.rpcs.push(rpc::request_create(mgid, &request)); results.rpcs.push(rpc::request_create(mgid, &request));
results.rpcs.push(notice_menu(mgid, &SessionType::Chat)); results.rpcs.push(notice_menu(mgid, &SessionType::Chat));
return Ok(results); return Ok(results);
} else { } else {
let group_lock = layer.group.read().await; let proof = layer.group.read().await.prove_addr(&mgid, &addr)?;
let me = group_lock.clone_user(&mgid)?; let msg = agree_message(proof, addr)?;
let proof = group_lock.prove_addr(&mgid, &addr)?;
drop(group_lock);
let msg = agree_message(proof, me, addr)?;
results.layers.push((mgid, fgid, msg)); results.layers.push((mgid, fgid, msg));
} }
} }
LayerEvent::Agree(remote, proof) => { LayerEvent::Agree(proof) => {
// 0. check verify. // 0. check verify.
proof.verify(&fgid, &addr, &layer.addr)?; proof.verify(&fgid, &addr, &layer.addr)?;
// 1. check friendship. // 1. check friendship.
if load_friend(&layer.base, &mgid, &fgid).is_err() { if load_friend(&layer.base, &mgid, &fgid).is_err() {
// agree request for friend. // 2. agree request for friend.
let db = chat_db(&layer.base, &mgid)?; let db = chat_db(&layer.base, &mgid)?;
if let Ok(mut request) = Request::get_id(&db, &remote.id) { if let Ok(mut r) = Request::get_id(&db, &fgid) {
layer.group.write().await.broadcast( r.is_over = true;
&mgid, r.is_ok = true;
InnerEvent::SessionRequestHandle( r.update(&db)?;
request.gid, let friend = Friend::from_remote(&db, fgid, r.name, addr, "".to_owned())?;
true, results.rpcs.push(rpc::request_agree(mgid, r.id, &friend));
remote.avatar.clone(),
),
REQUEST_TABLE_PATH,
request.id,
&mut results,
)?;
request.is_over = true;
request.is_ok = true;
request.update(&db)?;
let request_id = request.id;
let friend =
Friend::from_remote(&db, remote.id, remote.name, addr, remote.wallet)?;
write_avatar_sync(&layer.base, &mgid, &remote.id, remote.avatar)?;
results
.rpcs
.push(rpc::request_agree(mgid, request_id, &friend));
// ADD NEW SESSION. // ADD NEW SESSION.
let s_db = session_db(&layer.base, &mgid)?; let s_db = session_db(&layer.base, &mgid)?;
@ -361,17 +330,20 @@ impl LayerEvent {
} }
} }
LayerEvent::InfoRes(remote) => { LayerEvent::InfoRes(remote) => {
let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?; let (sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?;
let avatar = remote.avatar.clone(); let avatar = remote.avatar.clone();
let db = chat_db(&layer.base, &mgid)?; let db = chat_db(&layer.base, &mgid)?;
let mut f = Friend::get(&db, &fid)?; let mut f = Friend::get(&db, &fid)?;
let name = remote.name.clone();
f.name = remote.name; f.name = remote.name;
f.addr = remote.addr;
f.wallet = remote.wallet; f.wallet = remote.wallet;
f.height = remote.height; f.height = remote.height;
f.remote_update(&db)?; f.remote_update(&db)?;
drop(db); drop(db);
write_avatar_sync(&layer.base, &mgid, &remote.id, remote.avatar)?; write_avatar_sync(&layer.base, &mgid, &remote.id, remote.avatar)?;
results.rpcs.push(rpc::friend_info(mgid, &f));
let _ = Session::update_name(&session_db(&layer.base, &mgid)?, &sid, &name);
results.rpcs.push(session_update_name(mgid, &sid, &name));
layer.group.write().await.broadcast( layer.group.write().await.broadcast(
&mgid, &mgid,
@ -380,7 +352,6 @@ impl LayerEvent {
f.id, f.id,
&mut results, &mut results,
)?; )?;
results.rpcs.push(rpc::friend_info(mgid, &f));
} }
LayerEvent::Close => { LayerEvent::Close => {
let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?; let (_sid, fid) = layer.get_running_remote_id(&mgid, &fgid)?;
@ -440,24 +411,25 @@ fn update_friend(base: &PathBuf, mgid: &GroupId, fgid: &GroupId, addr: &PeerId)
Ok(friend) Ok(friend)
} }
pub(super) fn req_message(layer: &mut Layer, me: User, request: Request) -> SendType { pub(super) fn req_message(
layer: &mut Layer,
gid: GroupId,
name: String,
proof: Proof,
request: Request,
) -> SendType {
// update delivery. // update delivery.
let uid = layer.delivery.len() as u64 + 1; let uid = layer.delivery.len() as u64 + 1;
layer.delivery.insert(uid, (me.id, request.id)); layer.delivery.insert(uid, (gid, request.id));
let req = LayerEvent::Request(me, request.remark); let req = LayerEvent::Request(name, request.remark, proof);
let data = bincode::serialize(&req).unwrap_or(vec![]); let data = bincode::serialize(&req).unwrap_or(vec![]);
SendType::Event(uid, request.addr, data) SendType::Event(uid, request.addr, data)
} }
pub(super) fn reject_message( pub(super) fn reject_message(layer: &mut Layer, tid: i64, addr: PeerId, gid: GroupId) -> SendType {
layer: &mut Layer,
tid: i64,
addr: PeerId,
me_id: GroupId,
) -> SendType {
let data = bincode::serialize(&LayerEvent::Reject).unwrap_or(vec![]); let data = bincode::serialize(&LayerEvent::Reject).unwrap_or(vec![]);
let uid = layer.delivery.len() as u64 + 1; let uid = layer.delivery.len() as u64 + 1;
layer.delivery.insert(uid, (me_id, tid)); layer.delivery.insert(uid, (gid, tid));
SendType::Event(uid, addr, data) SendType::Event(uid, addr, data)
} }
@ -479,8 +451,8 @@ pub(crate) fn chat_conn(proof: Proof, addr: Peer) -> SendType {
SendType::Connect(0, addr, data) SendType::Connect(0, addr, data)
} }
pub(super) fn agree_message(proof: Proof, me: User, addr: PeerId) -> Result<SendType> { pub(super) fn agree_message(proof: Proof, addr: PeerId) -> Result<SendType> {
let data = bincode::serialize(&LayerEvent::Agree(me, proof)).unwrap_or(vec![]); let data = bincode::serialize(&LayerEvent::Agree(proof)).unwrap_or(vec![]);
Ok(SendType::Event(0, addr, data)) Ok(SendType::Event(0, addr, data))
} }

2
src/apps/chat/models/friend.rs

@ -208,7 +208,7 @@ impl Friend {
pub fn remote_update(&self, db: &DStorage) -> Result<usize> { pub fn remote_update(&self, db: &DStorage) -> Result<usize> {
let sql = format!( let sql = format!(
"UPDATE friends SET addr='{}', name='{}', wallet='{}', height={}, is_closed = false, is_deleted = false WHERE id = {}", "UPDATE friends SET addr='{}', name='{}', wallet='{}', height={}, is_closed = false WHERE id = {}",
self.addr.to_hex(), self.addr.to_hex(),
self.name, self.name,
self.wallet, self.wallet,

27
src/apps/chat/rpc.rs

@ -9,13 +9,12 @@ use tdn::types::{
use chat_types::MessageType; use chat_types::MessageType;
use crate::account::User;
use crate::event::InnerEvent; use crate::event::InnerEvent;
use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH}; use crate::migrate::consensus::{FRIEND_TABLE_PATH, MESSAGE_TABLE_PATH, REQUEST_TABLE_PATH};
use crate::rpc::{session_create, sleep_waiting_close_stable, RpcState}; use crate::rpc::{session_create, sleep_waiting_close_stable, RpcState};
use crate::storage::{chat_db, delete_avatar, session_db}; use crate::storage::{chat_db, delete_avatar, session_db};
use super::layer::{update_session, LayerEvent}; use super::layer::{agree_message, reject_message, req_message, update_session, LayerEvent};
use super::{Friend, Message, Request}; use super::{Friend, Message, Request};
#[inline] #[inline]
@ -267,7 +266,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
false, false,
); );
let me = state.group.read().await.clone_user(&gid)?; let group_lock = state.group.read().await;
let name = group_lock.username(&gid)?;
let proof = group_lock.prove_addr(&gid, &remote_addr)?;
drop(group_lock);
let mut layer_lock = state.layer.write().await; let mut layer_lock = state.layer.write().await;
let db = chat_db(layer_lock.base(), &gid)?; let db = chat_db(layer_lock.base(), &gid)?;
@ -286,22 +288,10 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let mut results = HandleResult::rpc(json!(request.to_rpc())); let mut results = HandleResult::rpc(json!(request.to_rpc()));
state.group.write().await.broadcast(
&gid,
InnerEvent::SessionRequestCreate(
true,
User::simple(remote_gid, remote_addr, remote_name, vec![], "".to_owned()),
remark,
),
REQUEST_TABLE_PATH,
request.id,
&mut results,
)?;
results.layers.push(( results.layers.push((
gid, gid,
remote_gid, remote_gid,
super::layer::req_message(&mut layer_lock, me, request), req_message(&mut layer_lock, gid, name, proof, request),
)); ));
drop(layer_lock); drop(layer_lock);
@ -316,7 +306,6 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let id = params[0].as_i64().ok_or(RpcError::ParseError)?; let id = params[0].as_i64().ok_or(RpcError::ParseError)?;
let mut group_lock = state.group.write().await; let mut group_lock = state.group.write().await;
let me = group_lock.clone_user(&gid)?;
let db = chat_db(group_lock.base(), &gid)?; let db = chat_db(group_lock.base(), &gid)?;
let mut request = Request::get(&db, &id)?; let mut request = Request::get(&db, &id)?;
let mut results = HandleResult::new(); let mut results = HandleResult::new();
@ -343,7 +332,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
results.rpcs.push(session_create(gid, &session)); results.rpcs.push(session_create(gid, &session));
let proof = group_lock.prove_addr(&gid, &friend.addr)?; let proof = group_lock.prove_addr(&gid, &friend.addr)?;
let msg = super::layer::agree_message(proof, me, friend.addr)?; let msg = agree_message(proof, friend.addr)?;
results.layers.push((gid, friend.gid, msg)); results.layers.push((gid, friend.gid, msg));
Ok(results) Ok(results)
@ -362,7 +351,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
req.is_over = true; req.is_over = true;
req.update(&db)?; req.update(&db)?;
drop(db); drop(db);
let msg = super::layer::reject_message(&mut layer_lock, id, req.addr, gid); let msg = reject_message(&mut layer_lock, id, req.addr, gid);
drop(layer_lock); drop(layer_lock);
let mut results = HandleResult::layer(gid, req.gid, msg); let mut results = HandleResult::layer(gid, req.gid, msg);

1
src/apps/wallet/rpc.rs

@ -596,6 +596,7 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler<RpcState>) {
let mut group_lock = state.group.write().await; let mut group_lock = state.group.write().await;
let account = group_lock.account_mut(&gid)?; let account = group_lock.account_mut(&gid)?;
account.wallet = address.chain.update_main(&address.address, &account.wallet); account.wallet = address.chain.update_main(&address.address, &account.wallet);
account.pub_height = account.pub_height + 1;
account.update_info(&a_db)?; account.update_info(&a_db)?;
drop(group_lock); drop(group_lock);
Ok(HandleResult::new()) Ok(HandleResult::new())

12
src/group.rs

@ -428,18 +428,27 @@ impl Group {
pub fn clone_user(&self, gid: &GroupId) -> Result<User> { pub fn clone_user(&self, gid: &GroupId) -> Result<User> {
if let Some(u) = self.accounts.get(gid) { if let Some(u) = self.accounts.get(gid) {
Ok(User::simple( Ok(User::new(
u.gid, u.gid,
self.addr, self.addr,
u.name.clone(), u.name.clone(),
u.avatar.clone(), u.avatar.clone(),
u.wallet.clone(), u.wallet.clone(),
u.pub_height,
)) ))
} else { } else {
Err(anyhow!("user missing.")) Err(anyhow!("user missing."))
} }
} }
pub fn username(&self, gid: &GroupId) -> Result<String> {
if let Some(u) = self.accounts.get(gid) {
Ok(u.name.clone())
} else {
Err(anyhow!("user missing."))
}
}
pub fn list_users(&self) -> &HashMap<GroupId, Account> { pub fn list_users(&self) -> &HashMap<GroupId, Account> {
&self.accounts &self.accounts
} }
@ -502,6 +511,7 @@ impl Group {
if avatar.len() > 0 { if avatar.len() > 0 {
account.avatar = avatar; account.avatar = avatar;
} }
account.pub_height = account.pub_height + 1;
account.update_info(&account_db)?; account.update_info(&account_db)?;
account_db.close() account_db.close()
} }

Loading…
Cancel
Save