mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 12:56:29 +00:00
Allow following a feed that isn't in rhizome yet, and override the displayed name
This commit is contained in:
parent
508e95436a
commit
9cb561229a
@ -220,8 +220,8 @@ public class ServalDClient implements ServalDHttpConnectionFactory {
|
||||
return list;
|
||||
}
|
||||
|
||||
public int meshmbAlterSubscription(Subscriber id, MeshMBCommon.SubscriptionAction action, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||
return MeshMBCommon.alterSubscription(this, id, action, peer);
|
||||
public int meshmbAlterSubscription(Subscriber id, MeshMBCommon.SubscriptionAction action, Subscriber peer, String name) throws ServalDInterfaceException, IOException {
|
||||
return MeshMBCommon.alterSubscription(this, id, action, peer, name);
|
||||
}
|
||||
|
||||
public MeshMBSubscriptionList meshmbSubscriptions(Subscriber identity) throws IOException, ServalDInterfaceException {
|
||||
|
@ -9,6 +9,7 @@ import org.servalproject.servaldna.Subscriber;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Created by jeremy on 5/10/16.
|
||||
@ -34,8 +35,15 @@ public class MeshMBCommon {
|
||||
return conn.getResponseCode();
|
||||
}
|
||||
|
||||
public static int alterSubscription(ServalDHttpConnectionFactory connector, Subscriber id, SubscriptionAction action, SigningKey peer) throws ServalDInterfaceException, IOException {
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection("/restful/meshmb/" + id.signingKey.toHex() + "/"+action.toString().toLowerCase()+"/" + peer.toHex());
|
||||
public static int alterSubscription(ServalDHttpConnectionFactory connector, Subscriber id, SubscriptionAction action, Subscriber peer, String name) throws ServalDInterfaceException, IOException {
|
||||
Vector<ServalDHttpConnectionFactory.QueryParam> parms = new Vector<>();
|
||||
parms.add(new ServalDHttpConnectionFactory.QueryParam("sender", peer.sid.toHex()));
|
||||
if (name!=null && !"".equals(name))
|
||||
parms.add(new ServalDHttpConnectionFactory.QueryParam("name", name));
|
||||
HttpURLConnection conn = connector.newServalDHttpConnection(
|
||||
"/restful/meshmb/"+id.signingKey.toHex()+"/"+peer.signingKey.toHex(),
|
||||
parms
|
||||
);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.connect();
|
||||
return conn.getResponseCode();
|
||||
|
67
meshmb.c
67
meshmb.c
@ -23,6 +23,7 @@ struct feed_metadata{
|
||||
};
|
||||
|
||||
#define FLAG_BLOCKED (1<<0)
|
||||
#define FLAG_OVERRIDDEN_NAME (1<<1)
|
||||
|
||||
struct meshmb_feeds{
|
||||
struct tree_root root;
|
||||
@ -242,6 +243,27 @@ static int activity_ack(struct meshmb_feeds *feeds, struct message_ply_ack *ack)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int replace_string(char **ptr, const char *new_value, ssize_t len, size_t max_len){
|
||||
if (!*ptr && (!new_value || !*new_value))
|
||||
return 0;
|
||||
|
||||
if (len == -1)
|
||||
len = strlen(new_value);
|
||||
if ((size_t)len >= max_len)
|
||||
len = max_len -1;
|
||||
|
||||
if (*ptr && *new_value && strn_str_cmp(new_value, len, *ptr) == 0)
|
||||
return 0;
|
||||
|
||||
if (*ptr){
|
||||
free((void*)*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
if (new_value && *new_value)
|
||||
*ptr = strn_edup(new_value, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int update_stats(struct meshmb_feeds *feeds, struct feed_metadata *metadata, struct message_ply_read *reader)
|
||||
{
|
||||
if (metadata->details.blocked)
|
||||
@ -269,19 +291,9 @@ static int update_stats(struct meshmb_feeds *feeds, struct feed_metadata *metada
|
||||
&& message_ply_read_open(reader, &metadata->bundle_id, NULL)!=0)
|
||||
return -1;
|
||||
|
||||
// TODO allow the user to specify an overridden name?
|
||||
if (metadata->details.name){
|
||||
free((void*)metadata->details.name);
|
||||
metadata->details.name = NULL;
|
||||
}
|
||||
metadata->details.ply.author = reader->author;
|
||||
|
||||
if (reader->name){
|
||||
size_t len = strlen(reader->name);
|
||||
if (len >= MAX_NAME_LEN)
|
||||
len = MAX_NAME_LEN -1;
|
||||
metadata->details.name = strn_edup(reader->name, len);
|
||||
}
|
||||
if (!metadata->details.overridden_name)
|
||||
replace_string((char **)&metadata->details.name, reader->name, -1, MAX_NAME_LEN);
|
||||
|
||||
reader->read.offset = reader->read.length;
|
||||
time_s_t timestamp = 0;
|
||||
@ -301,13 +313,7 @@ static int update_stats(struct meshmb_feeds *feeds, struct feed_metadata *metada
|
||||
break;
|
||||
|
||||
last_offset = reader->record_end_offset;
|
||||
|
||||
if (metadata->details.last_message)
|
||||
free((void*)metadata->details.last_message);
|
||||
size_t len = reader->record_length;
|
||||
if (len >= MAX_MSG_LEN)
|
||||
len = MAX_MSG_LEN -1;
|
||||
metadata->details.last_message = strn_edup((const char *)reader->record, len);
|
||||
replace_string((char **)&metadata->details.last_message, (const char *)reader->record, reader->record_length, MAX_MSG_LEN);
|
||||
metadata->details.timestamp = timestamp;
|
||||
break;
|
||||
}
|
||||
@ -391,7 +397,11 @@ static int write_metadata(void **record, void *context)
|
||||
len += sizeof (rhizome_bid_t);
|
||||
bcopy(metadata->details.ply.author.binary, &buffer[len], sizeof (sid_t));
|
||||
len += sizeof (sid_t);
|
||||
uint8_t flags = (metadata->details.blocked ? FLAG_BLOCKED : 0);
|
||||
uint8_t flags = 0;
|
||||
if (metadata->details.blocked)
|
||||
flags |= FLAG_BLOCKED;
|
||||
if (metadata->details.overridden_name)
|
||||
flags |= FLAG_OVERRIDDEN_NAME;
|
||||
buffer[len++]=flags;
|
||||
if (!metadata->details.blocked){
|
||||
len+=pack_uint(&buffer[len], metadata->size);
|
||||
@ -605,6 +615,7 @@ static int read_metadata(struct meshmb_feeds *feeds, struct rhizome_read *read)
|
||||
result->details.name = (name && *name) ? str_edup(name) : NULL;
|
||||
result->details.last_message = (msg && *msg) ? str_edup(msg) : NULL;
|
||||
result->details.timestamp = timestamp;
|
||||
result->details.overridden_name = (flags & FLAG_OVERRIDDEN_NAME) ? 1 : 0;
|
||||
|
||||
DEBUGF(meshmb, "Processed %u bytes of metadata for %s (%s)",
|
||||
offset,
|
||||
@ -685,7 +696,7 @@ int meshmb_open(keyring_identity *id, struct meshmb_feeds **feeds)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int meshmb_follow(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
int meshmb_follow(struct meshmb_feeds *feeds, const rhizome_bid_t *bid, const sid_t *author, const char *name)
|
||||
{
|
||||
struct feed_metadata *metadata;
|
||||
DEBUGF(meshmb, "Attempting to follow %s", alloca_tohex_rhizome_bid_t(*bid));
|
||||
@ -697,10 +708,16 @@ int meshmb_follow(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
bzero(&reader, sizeof(reader));
|
||||
update_stats(feeds, metadata, &reader);
|
||||
message_ply_read_close(&reader);
|
||||
|
||||
if (author && is_sid_t_any(metadata->details.ply.author))
|
||||
metadata->details.ply.author = *author;
|
||||
if (name && replace_string((char **)&metadata->details.name, name, -1, MAX_NAME_LEN))
|
||||
metadata->details.overridden_name = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int meshmb_block(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
int meshmb_block(struct meshmb_feeds *feeds, const rhizome_bid_t *bid, const sid_t *author)
|
||||
{
|
||||
struct feed_metadata *metadata;
|
||||
DEBUGF(meshmb, "Attempting to block %s", alloca_tohex_rhizome_bid_t(*bid));
|
||||
@ -715,8 +732,8 @@ int meshmb_block(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
free((void*)metadata->details.last_message);
|
||||
metadata->details.last_message = NULL;
|
||||
}
|
||||
if (is_all_matching(metadata->details.ply.author.binary, sizeof metadata->details.ply.author, 0))
|
||||
crypto_sign_to_sid(bid, &metadata->details.ply.author);
|
||||
if (author && is_sid_t_any(metadata->details.ply.author))
|
||||
metadata->details.ply.author = *author;
|
||||
if (!metadata->details.blocked)
|
||||
feeds->dirty = 1;
|
||||
metadata->details.blocked = 1;
|
||||
@ -724,7 +741,7 @@ int meshmb_block(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int meshmb_ignore(struct meshmb_feeds *feeds, rhizome_bid_t *bid)
|
||||
int meshmb_ignore(struct meshmb_feeds *feeds, const rhizome_bid_t *bid)
|
||||
{
|
||||
DEBUGF(meshmb, "Attempting to ignore %s", alloca_tohex_rhizome_bid_t(*bid));
|
||||
tree_walk_prefix(&feeds->root, bid->binary, sizeof *bid, free_feed, feeds);
|
||||
|
7
meshmb.h
7
meshmb.h
@ -15,6 +15,7 @@ struct meshmb_feed_details{
|
||||
const char *last_message;
|
||||
time_s_t timestamp;
|
||||
bool_t blocked:1;
|
||||
bool_t overridden_name:1;
|
||||
};
|
||||
|
||||
// threaded feed iterator state
|
||||
@ -40,9 +41,9 @@ void meshmb_close(struct meshmb_feeds *feeds);
|
||||
int meshmb_flush(struct meshmb_feeds *feeds);
|
||||
|
||||
// set / clear follow flag for this feed
|
||||
int meshmb_follow(struct meshmb_feeds *feeds, rhizome_bid_t *bid);
|
||||
int meshmb_ignore(struct meshmb_feeds *feeds, rhizome_bid_t *bid);
|
||||
int meshmb_block(struct meshmb_feeds *feeds, rhizome_bid_t *bid);
|
||||
int meshmb_follow(struct meshmb_feeds *feeds, const rhizome_bid_t *bid, const sid_t *sender, const char *name);
|
||||
int meshmb_ignore(struct meshmb_feeds *feeds, const rhizome_bid_t *bid);
|
||||
int meshmb_block(struct meshmb_feeds *feeds, const rhizome_bid_t *bid, const sid_t *sender);
|
||||
|
||||
// enumerate feeds, starting from restart_from
|
||||
typedef int (*meshmb_callback) (struct meshmb_feed_details *details, void *context);
|
||||
|
20
meshmb_cli.c
20
meshmb_cli.c
@ -213,13 +213,18 @@ static int app_meshmb_find(const struct cli_parsed *parsed, struct cli_context *
|
||||
|
||||
DEFINE_CMD(app_meshmb_follow, 0,
|
||||
"Follow, block or ignore a broadcast feed",
|
||||
"meshmb", "follow|ignore|block" KEYRING_PIN_OPTIONS, "<id>", "<peer>");
|
||||
"meshmb", "follow|ignore|block" KEYRING_PIN_OPTIONS, "<id>", "<peer>", "[<sender>]", "[<name>]");
|
||||
static int app_meshmb_follow(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
|
||||
{
|
||||
const char *peerhex;
|
||||
if (cli_arg(parsed, "peer", &peerhex, str_is_identity, "") == -1)
|
||||
const char *sidhex;
|
||||
const char *name;
|
||||
|
||||
if (cli_arg(parsed, "peer", &peerhex, str_is_identity, "") == -1
|
||||
|| cli_arg(parsed, "sender", &sidhex, str_is_subscriber_id, NULL) == -1)
|
||||
return -1;
|
||||
|
||||
cli_arg(parsed, "name", &name, NULL, NULL);
|
||||
int follow = cli_arg(parsed, "follow", NULL, NULL, NULL) == 0;
|
||||
int block = cli_arg(parsed, "block", NULL, NULL, NULL) == 0;
|
||||
|
||||
@ -227,14 +232,21 @@ static int app_meshmb_follow(const struct cli_parsed *parsed, struct cli_context
|
||||
if (str_to_identity_t(&peer, peerhex) == -1)
|
||||
return WHY("Invalid identity");
|
||||
|
||||
sid_t sender;
|
||||
bzero(&sender, sizeof sender);
|
||||
if (sidhex && *sidhex){
|
||||
if (str_to_sid_t(&sender, sidhex) == -1)
|
||||
return WHY("Invalid sender");
|
||||
}
|
||||
|
||||
struct meshmb_feeds *feeds = cli_feeds_open(parsed);
|
||||
|
||||
int ret = -1;
|
||||
if (feeds){
|
||||
if (block){
|
||||
ret = meshmb_block(feeds, &peer);
|
||||
ret = meshmb_block(feeds, &peer, (sidhex && *sidhex ? &sender : NULL));
|
||||
}else if (follow){
|
||||
ret = meshmb_follow(feeds, &peer);
|
||||
ret = meshmb_follow(feeds, &peer, (sidhex && *sidhex ? &sender : NULL), name);
|
||||
}else{
|
||||
ret = meshmb_ignore(feeds, &peer);
|
||||
}
|
||||
|
@ -498,14 +498,34 @@ static int restful_meshmb_follow_ignore(httpd_request *r, const char *remainder)
|
||||
int ret=-1;
|
||||
|
||||
if (session){
|
||||
const char *name = http_request_get_query_param(&r->http, "name");
|
||||
const char *sender_hex = http_request_get_query_param(&r->http, "sender");
|
||||
sid_t sender;
|
||||
bzero(&sender, sizeof sender);
|
||||
if (sender_hex && *sender_hex){
|
||||
if (str_to_sid_t(&sender, sender_hex) == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch(r->ui64){
|
||||
case FLAG_FOLLOW: ret = meshmb_follow(session->feeds, &r->u.meshmb_feeds.bundle_id); break;
|
||||
case FLAG_IGNORE: ret = meshmb_ignore(session->feeds, &r->u.meshmb_feeds.bundle_id); break;
|
||||
case FLAG_BLOCK: ret = meshmb_block (session->feeds, &r->u.meshmb_feeds.bundle_id); break;
|
||||
case FLAG_FOLLOW:
|
||||
ret = meshmb_follow(session->feeds, &r->u.meshmb_feeds.bundle_id,
|
||||
(sender_hex && *sender_hex) ? &sender : NULL,
|
||||
name);
|
||||
break;
|
||||
case FLAG_IGNORE:
|
||||
ret = meshmb_ignore(session->feeds, &r->u.meshmb_feeds.bundle_id);
|
||||
break;
|
||||
case FLAG_BLOCK:
|
||||
ret = meshmb_block (session->feeds, &r->u.meshmb_feeds.bundle_id,
|
||||
(sender_hex && *sender_hex) ? &sender : NULL);
|
||||
break;
|
||||
default:
|
||||
FATAL("Unexpected value");
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
if (ret!=-1
|
||||
&& meshmb_flush(session->feeds)!=-1){
|
||||
http_request_simple_response(&r->http, 201, "TODO, detailed response");
|
||||
|
@ -157,8 +157,8 @@ setup_meshmbBlock() {
|
||||
executeOk_servald meshmb follow $IDA1 $IDA3
|
||||
}
|
||||
test_meshmbBlock() {
|
||||
executeOk_servald meshmb block $IDA1 $IDA3
|
||||
executeOk_servald meshmb block $IDA1 $IDA4
|
||||
executeOk_servald meshmb block $IDA1 $IDA3 $SIDA3
|
||||
executeOk_servald meshmb block $IDA1 $IDA4 $SIDA4
|
||||
executeOk_servald meshmb activity $IDA1
|
||||
tfw_cat --stdout
|
||||
assertStdoutGrep --matches=1 "0:$IDA2:$SIDA2:Feed B:[0-9]\+:[0-9]\+:Message 1\$"
|
||||
|
Loading…
Reference in New Issue
Block a user