shlist

share and manage lists between multiple people
Log | Files | Refs

commit 4e6da10836c7bd1abf503115db08366fba88662a
parent 4203872ded00824905be20224e5a9bfcb41013b4
Author: kyle <kyle@0x30.net>
Date:   Mon, 28 Dec 2015 02:15:48 -0700

sl: split list_request into list_get and list_get_other

- having list_request get both lists your in and lists you can see was too much
  - split this into logical components list_get/list_get_other
  - also rid us of the double NULL \0\0 abomination
- start returning slightly different information for both new messages too
  - list_get exclusively gives back the number of complete items

Diffstat:
Mgen_msgs.sh | 11+++++++----
Mmsgs.pl | 25++++++++++++++-----------
Msl | 98+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mtests/bad_deviceid/server.log.good | 2++
Mtests/join_friends_list/server.log.good | 9++++-----
Mtests/join_friends_list/test.pl | 13+++++--------
Mtests/leave_list_self/server.log.good | 2+-
Mtests/leave_list_self/test.pl | 9++++-----
Mtests/list_request_basic/server.log.good | 17++++++++++-------
Mtests/list_request_basic/test.pl | 13+++++--------
Mtests/mutual_friends_basic/server.log.good | 6+++---
Mtests/mutual_friends_basic/test.pl | 14++++++--------
Mtests/payload_invalid/server.log.good | 1+
13 files changed, 123 insertions(+), 97 deletions(-)

diff --git a/gen_msgs.sh b/gen_msgs.sh @@ -1,15 +1,18 @@ #!/bin/sh protocol_version=0 -msg_types="new_device - new_list +msg_types=" + new_device add_friend - list_request + new_list join_list leave_list + list_get + list_get_other list_items new_list_item - ok" + ok +" objc_path="ios/shlist/MsgTypes.h" perl_path="msgs.pl" diff --git a/msgs.pl b/msgs.pl @@ -1,39 +1,42 @@ #!/usr/bin/perl -# generated Sun Nov 22 23:36:41 MST 2015 +# generated Mon Dec 28 00:59:49 MST 2015 use strict; use warnings; our $protocol_ver = 0; our %msg_num = ( new_device => 0, - new_list => 1, - add_friend => 2, + add_friend => 1, + new_list => 2, join_list => 3, leave_list => 4, - list_items => 5, - new_list_item => 6, - list_request => 7, - ok => 8, + list_get => 5, + list_get_other => 6, + list_items => 7, + new_list_item => 8, + ok => 9, ); our @msg_str = ( 'new_device', - 'new_list', 'add_friend', + 'new_list', 'join_list', 'leave_list', + 'list_get', + 'list_get_other', 'list_items', 'new_list_item', - 'list_request', 'ok', ); our @msg_func = ( \&msg_new_device, - \&msg_new_list, \&msg_add_friend, + \&msg_new_list, \&msg_join_list, \&msg_leave_list, + \&msg_list_get, + \&msg_list_get_other, \&msg_list_items, \&msg_new_list_item, - \&msg_list_request, \&msg_ok, ); diff --git a/sl b/sl @@ -379,8 +379,8 @@ sub msg_delete_friend # $mutual_friends_delete_sth->execute($device_id, $device_id); } -# get both lists the device is in, and lists it can see -sub msg_list_request +# get lists that the device id is participating in +sub msg_list_get { my ($dbh, $sth_ref, $msg) = @_; my %sth = %$sth_ref; @@ -390,57 +390,81 @@ sub msg_list_request } my $devid_fp = fingerprint($msg); - log_print("list_request: gathering lists for '$devid_fp'\n"); + log_print("list_get: gathering lists for '$devid_fp'\n"); - my @direct_lists; - my @direct_list_ids; - # first get all lists this device id is a direct member of + my @lists; $sth{get_lists}->execute($msg); while (my ($list_id, $list_name) = $sth{get_lists}->fetchrow_array()) { - log_print("list_request: found list '$list_name' '$list_id'\n"); - # get all members of this list - my @list_members; + my $list_fp = fingerprint($list_id); + log_print("list_get: found list '$list_name' '$list_fp'\n"); + + # find all members of this list + my @members; $sth{get_list_members}->execute($list_id); - while (my ($member_device_id) = $sth{get_list_members}->fetchrow_array()) { - push @list_members, get_phone_number($dbh, $sth_ref, $member_device_id); - log_print("list_request: direct list: found member '$member_device_id'\n"); + while (my ($device_id) = $sth{get_list_members}->fetchrow_array()) { + push @members, get_phone_number($dbh, $sth_ref, $device_id); + } + my $members = join("\0", @members); + log_print("list_get: list has ". @members ." members\n"); + + # find how many items are complete in this list + my $num_items = 0; + $sth{get_list_items}->execute($list_id); + while (my @results = $sth{get_list_items}->fetchrow_array()) { + my (undef, $item_name, $item_status) = @results; + # XXX: actually check the item status + $num_items++; } - push @direct_list_ids, $list_id; - push @direct_lists, "$list_name:$list_id:" . join(":", @list_members); + log_print("list_get: list has $num_items items\n"); + + push @lists, "$list_id\0$list_name\0$num_items\0$members"; + } + + return "ok\0" . join("\n", @lists); +} + +# get friends lists that the device id isn't participating in +sub msg_list_get_other { + my ($dbh, $sth_ref, $msg) = @_; + my %sth = %$sth_ref; + + if (my $err = device_id_invalid($dbh, $sth_ref, $msg)) { + return "err\0$err"; } - my $out .= join("\0", @direct_lists); + my $devid_fp = fingerprint($msg); + log_print("list_get_other: gathering lists for '$devid_fp'\n"); - # separator between direct/indirect lists - $out .= "\0\0"; + my @list_ids; + $sth{get_lists}->execute($msg); + while (my ($list_id) = $sth{get_lists}->fetchrow_array()) { + push @list_ids, $list_id; + } - my @indirect_lists; + my @other_lists; # now calculate which lists this device id should see $sth{mutual_friend_select}->execute($msg); - while (my ($friend) = $sth{mutual_friend_select}->fetchrow_array()) { - log_print("list_request: found mutual friend '$friend'\n"); + while (my ($friend_id) = $sth{mutual_friend_select}->fetchrow_array()) { - # get all of my friends lists - $sth{get_lists}->execute($friend); + my $friend_fp = fingerprint($friend_id); + log_print("list_get_other: found mutual friend '$friend_fp'\n"); # we can't send device id's back to the client - my $friend_ph_num = get_phone_number($dbh, $sth_ref, $friend); + my $friend_phnum = get_phone_number($dbh, $sth_ref, $friend_id); + + # find all of my friends lists + $sth{get_lists}->execute($friend_id); + while (my ($id, $name) = $sth{get_lists}->fetchrow_array()) { - while (my ($list_id, $list_name) = - $sth{get_lists}->fetchrow_array()) { - if (grep {$_ eq $list_id} @direct_list_ids) { - next; - } - log_print("list_request: found mutual friends list '$list_name'\n"); + # filter out lists this device id is already in + next if (grep {$_ eq $id} @list_ids); - push @indirect_lists, "$list_name:$list_id:$friend_ph_num" + log_print("list_get_other: found list '$name'\n"); + push @other_lists, "$id\0$name\0$friend_phnum"; } } - $out .= join("\0", @indirect_lists); - - return "ok\0$out"; - # XXX: add time of last request to list (rate throttling)? + return "ok\0" . join("\n", @other_lists); } sub msg_list_items @@ -583,11 +607,11 @@ sub create_tables { $db_handle->do(qq{create table if not exists list_data( list_id int not null, name text not null, - quantity non null, status int not null default 0, - owner text not null, + quantity, + owner text, last_updated int not null, - primary key(list_id, name, owner), + primary key(list_id, name), foreign key(list_id) references lists(list_id), foreign key(owner) references devices(device_id)) }) or die $DBI::errstr; diff --git a/tests/bad_deviceid/server.log.good b/tests/bad_deviceid/server.log.good @@ -17,4 +17,6 @@ device_id: unknown device <base64> device_id: '&^%_invalid_base64' not base64 device_id: unknown device <base64> device_id: '&^%_invalid_base64' not base64 +device_id: unknown device <base64> +device_id: '&^%_invalid_base64' not base64 disconnected! diff --git a/tests/join_friends_list/server.log.good b/tests/join_friends_list/server.log.good @@ -9,11 +9,10 @@ add_friend: found mutual friendship join_list: device <base64> join_list: list <base64> join_list: device <base64> has been added to list <base64> -list_request: gathering lists for <base64> -list_request: found list <string> <base64> -list_request: direct list: found member <base64> -list_request: direct list: found member <base64> -list_request: found mutual friend <base64> +list_get: gathering lists for <base64> +list_get: found list <string> <base64> +list_get: list has 2 members +list_get: list has 0 items disconnected! new connection (pid = <digits>) ssl ok, ver = 'TLSv1_2' cipher = 'ECDHE-RSA-AES128-SHA256' diff --git a/tests/join_friends_list/test.pl b/tests/join_friends_list/test.pl @@ -38,15 +38,12 @@ send_msg($sock_2, 'join_list', "$device_id2\0$list_id"); check_status($msg_data, 'ok'); # device 2 requests its lists to make sure its committed to the list -send_msg($sock_2, 'list_request', $device_id2); -($msg_data) = recv_msg($sock_2, 'list_request'); +send_msg($sock_2, 'list_get', $device_id2); +($msg_data) = recv_msg($sock_2, 'list_get'); -my $request_data = check_status($msg_data, 'ok'); -my ($mine, $other) = split("\0\0", $request_data); +my $list = check_status($msg_data, 'ok'); +my ($id, $name, $num_items, @members) = split("\0", $list); -fail "unexpected other list '$other'" if ($other ne ''); -my ($name, $request_id, @members) = split(":", $mine); - -fail "request list id mismatch: '$request_id' ne '$list_id'" if ($request_id ne $list_id); +fail "request list id mismatch: '$id' ne '$list_id'" if ($id ne $list_id); fail "unexpected name '$name', expected '$list_name'" if ($name ne $list_name); fail "expected 2 list members, got ". @members if (@members != 2); diff --git a/tests/leave_list_self/server.log.good b/tests/leave_list_self/server.log.good @@ -9,5 +9,5 @@ leave_list: device <base64> leave_list: list <base64> leave_list: device <base64> has been removed from list <base64> leave_list: list <base64> is empty... deleting -list_request: gathering lists for <base64> +list_get: gathering lists for <base64> disconnected! diff --git a/tests/leave_list_self/test.pl b/tests/leave_list_self/test.pl @@ -31,9 +31,8 @@ my ($leave_id) = split("\0", $msg); fail "got leave data '$leave_id', expected $list_id" if ($leave_id ne $list_id); # verify we don't get this list back when requesting all lists -send_msg($sock, 'list_request', $device_id); -($msg_data) = recv_msg($sock, 'list_request'); +send_msg($sock, 'list_get', $device_id); +($msg_data) = recv_msg($sock, 'list_get'); -my $request_data = check_status($msg_data, 'ok'); -my ($direct, $other) = split("\0\0", $request_data); -fail "expected empty, got other" if ($direct ne "" || $other ne ""); +my $lists = check_status($msg_data, 'ok'); +fail "expected no lists" if ($lists ne ""); diff --git a/tests/list_request_basic/server.log.good b/tests/list_request_basic/server.log.good @@ -11,11 +11,14 @@ new_list: fingerprint = <base64> new_list: <string> new_list: adding first member devid = <base64> new_list: fingerprint = <base64> -list_request: gathering lists for <base64> -list_request: found list <string> <base64> -list_request: direct list: found member <base64> -list_request: found list <string> <base64> -list_request: direct list: found member <base64> -list_request: found list <string> <base64> -list_request: direct list: found member <base64> +list_get: gathering lists for <base64> +list_get: found list <string> <base64> +list_get: list has 1 members +list_get: list has 0 items +list_get: found list <string> <base64> +list_get: list has 1 members +list_get: list has 0 items +list_get: found list <string> <base64> +list_get: list has 1 members +list_get: list has 0 items disconnected! diff --git a/tests/list_request_basic/test.pl b/tests/list_request_basic/test.pl @@ -28,16 +28,13 @@ for my $name ("new list 1", "new list 2", "new list 3") { $list_id_map{$name} = $id; } -send_msg($sock, 'list_request', $device_id); -($msg_data) = recv_msg($sock, 'list_request'); - -my $list_data = check_status($msg_data, 'ok'); -my ($direct, $indirect) = split("\0\0", $list_data); -fail "got indirect lists, expected none" if (length($indirect) != 0); +send_msg($sock, 'list_get', $device_id); +($msg_data) = recv_msg($sock, 'list_get'); +my $lists = check_status($msg_data, 'ok'); my $num_lists = 0; -for my $l (split("\0", $direct)) { - my ($name, $id, @members) = split(":", $l); +for my $l (split("\n", $lists)) { + my ($id, $name, $num_items, @members) = split("\0", $l); unless ($name && $id && @members) { fail "response didn't send at least 3 fields"; } diff --git a/tests/mutual_friends_basic/server.log.good b/tests/mutual_friends_basic/server.log.good @@ -6,9 +6,9 @@ add_friend: <base64> adding <digits> add_friend: added friend is a member add_friend: friends device id is <base64> add_friend: found mutual friendship -list_request: gathering lists for <base64> -list_request: found mutual friend <base64> -list_request: found mutual friends list <string> +list_get_other: gathering lists for <base64> +list_get_other: found mutual friend <base64> +list_get_other: found list <string> disconnected! new connection (pid = <digits>) ssl ok, ver = 'TLSv1_2' cipher = 'ECDHE-RSA-AES128-SHA256' diff --git a/tests/mutual_friends_basic/test.pl b/tests/mutual_friends_basic/test.pl @@ -36,16 +36,14 @@ my $list_data = check_status($msg_data, 'ok'); my ($list_id) = split("\0", $list_data); # make sure socket 2 can see socket 1's list -send_msg($sock_2, 'list_request', $device_id2); -($msg_data) = recv_msg($sock_2, 'list_request'); - -my $request_data = check_status($msg_data, 'ok'); -my (undef, $other) = split("\0\0", $request_data); +send_msg($sock_2, 'list_get_other', $device_id2); +($msg_data) = recv_msg($sock_2, 'list_get_other'); +my $other_lists = check_status($msg_data, 'ok'); my $num_lists = 0; -for my $l (split("\0", $other)) { - my ($name, $id, @members) = split(":", $l); - unless ($name && $id && @members) { +for my $l (split("\n", $other_lists)) { + my ($id, $name, @members) = split("\0", $l); + unless ($id && $name && @members) { fail "response didn't send at least 3 fields"; } if ($list_id ne $id) { diff --git a/tests/payload_invalid/server.log.good b/tests/payload_invalid/server.log.good @@ -13,4 +13,5 @@ device_id: got empty device id device_id: got empty device id device_id: got empty device id device_id: got empty device id +device_id: got empty device id disconnected!