mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Add bundle author to feed metadata
This commit is contained in:
parent
a0dbe115aa
commit
5ccff053c2
@ -2,18 +2,19 @@ package org.servalproject.servaldna.meshmb;
|
||||
|
||||
import org.servalproject.servaldna.BundleId;
|
||||
import org.servalproject.servaldna.SigningKey;
|
||||
import org.servalproject.servaldna.Subscriber;
|
||||
|
||||
/**
|
||||
* Created by jeremy on 11/01/17.
|
||||
*/
|
||||
public class MeshMBSubscription {
|
||||
public final SigningKey id;
|
||||
public final Subscriber subscriber;
|
||||
public final String name;
|
||||
public final long timestamp;
|
||||
public final String lastMessage;
|
||||
|
||||
public MeshMBSubscription(SigningKey id, String name, long timestamp, String lastMessage){
|
||||
this.id = id;
|
||||
public MeshMBSubscription(Subscriber subscriber, String name, long timestamp, String lastMessage){
|
||||
this.subscriber = subscriber;
|
||||
this.name = name;
|
||||
this.lastMessage = lastMessage;
|
||||
this.timestamp = timestamp;
|
||||
|
@ -6,6 +6,7 @@ import org.servalproject.servaldna.ServalDHttpConnectionFactory;
|
||||
import org.servalproject.servaldna.ServalDInterfaceException;
|
||||
import org.servalproject.servaldna.SigningKey;
|
||||
import org.servalproject.servaldna.Subscriber;
|
||||
import org.servalproject.servaldna.SubscriberId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@ -21,6 +22,7 @@ public class MeshMBSubscriptionList extends AbstractJsonList<MeshMBSubscription,
|
||||
public MeshMBSubscriptionList(ServalDHttpConnectionFactory httpConnector, Subscriber identity){
|
||||
super(httpConnector, new JSONTableScanner()
|
||||
.addColumn("id", SigningKey.class)
|
||||
.addColumn("author", SubscriberId.class)
|
||||
.addColumn("name", String.class)
|
||||
.addColumn("timestamp", Long.class)
|
||||
.addColumn("last_message", String.class)
|
||||
@ -35,7 +37,9 @@ public class MeshMBSubscriptionList extends AbstractJsonList<MeshMBSubscription,
|
||||
@Override
|
||||
protected MeshMBSubscription factory(Map<String, Object> row, long rowCount) throws ServalDInterfaceException {
|
||||
return new MeshMBSubscription(
|
||||
(SigningKey) row.get("id"),
|
||||
new Subscriber((SubscriberId)row.get("author"),
|
||||
(SigningKey) row.get("id"),
|
||||
true),
|
||||
(String) row.get("name"),
|
||||
(Long) row.get("timestamp"),
|
||||
(String) row.get("last_message")
|
||||
|
50
meshmb.c
50
meshmb.c
@ -60,6 +60,7 @@ static void update_stats(struct meshmb_feeds *feeds, struct feed_metadata *metad
|
||||
free((void*)metadata->details.name);
|
||||
metadata->details.name = NULL;
|
||||
}
|
||||
metadata->details.author = reader->author;
|
||||
|
||||
if (reader->name){
|
||||
size_t len = strlen(reader->name);
|
||||
@ -147,9 +148,12 @@ static int write_metadata(void **record, void *context)
|
||||
unsigned msg_len = (metadata->details.last_message ? strlen(metadata->details.last_message) : 0) + 1;
|
||||
assert(msg_len <= MAX_MSG_LEN);
|
||||
|
||||
uint8_t buffer[sizeof (rhizome_bid_t) + 1 + 12*4 + name_len + msg_len];
|
||||
bcopy(metadata->ply.bundle_id.binary, buffer, sizeof (rhizome_bid_t));
|
||||
size_t len = sizeof (rhizome_bid_t);
|
||||
uint8_t buffer[sizeof (rhizome_bid_t) + sizeof (sid_t) + 1 + 12*4 + name_len + msg_len];
|
||||
size_t len = 0;
|
||||
bcopy(metadata->ply.bundle_id.binary, &buffer[len], sizeof (rhizome_bid_t));
|
||||
len += sizeof (rhizome_bid_t);
|
||||
bcopy(metadata->details.author.binary, &buffer[len], sizeof (sid_t));
|
||||
len += sizeof (sid_t);
|
||||
buffer[len++]=0;// flags?
|
||||
len+=pack_uint(&buffer[len], metadata->size);
|
||||
len+=pack_uint(&buffer[len], metadata->size - metadata->last_message_offset);
|
||||
@ -166,7 +170,11 @@ static int write_metadata(void **record, void *context)
|
||||
buffer[len]=0;
|
||||
len+=msg_len;
|
||||
assert(len < sizeof buffer);
|
||||
DEBUGF(meshmb, "Write %u bytes of metadata for %s", len, alloca_tohex_rhizome_bid_t(metadata->ply.bundle_id));
|
||||
DEBUGF(meshmb, "Write %u bytes of metadata for %s/%s",
|
||||
len,
|
||||
alloca_tohex_rhizome_bid_t(metadata->ply.bundle_id),
|
||||
alloca_tohex_sid_t(metadata->details.author)
|
||||
);
|
||||
return rhizome_write_buffer(write, buffer, len);
|
||||
}
|
||||
|
||||
@ -267,7 +275,7 @@ static int read_metadata(struct meshmb_feeds *feeds, struct rhizome_read *read)
|
||||
{
|
||||
struct rhizome_read_buffer buff;
|
||||
bzero(&buff, sizeof(buff));
|
||||
uint8_t buffer[sizeof (rhizome_bid_t) + 12*3 + MAX_NAME_LEN + MAX_MSG_LEN];
|
||||
uint8_t buffer[sizeof (rhizome_bid_t) + sizeof (sid_t) + 12*3 + MAX_NAME_LEN + MAX_MSG_LEN];
|
||||
|
||||
uint8_t version=0xFF;
|
||||
if (rhizome_read_buffered(read, &buff, &version, 1)==-1)
|
||||
@ -291,40 +299,46 @@ static int read_metadata(struct meshmb_feeds *feeds, struct rhizome_read *read)
|
||||
const rhizome_bid_t *bid = (const rhizome_bid_t *)&buffer[0];
|
||||
unsigned offset = sizeof(rhizome_bid_t);
|
||||
if (offset >= (unsigned)bytes)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
|
||||
const sid_t *author = (const sid_t *)&buffer[offset];
|
||||
offset+= sizeof(sid_t);
|
||||
if (offset >= (unsigned)bytes)
|
||||
goto error;
|
||||
|
||||
//uint8_t flags = buffer[offset++];
|
||||
offset++;
|
||||
if (offset >= (unsigned)bytes)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
|
||||
if ((unpacked = unpack_uint(buffer+offset, bytes-offset, &size)) == -1)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
offset += unpacked;
|
||||
|
||||
if ((unpacked = unpack_uint(buffer+offset, bytes-offset, &delta)) == -1)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
offset += unpacked;
|
||||
last_message_offset = size - delta;
|
||||
|
||||
if ((unpacked = unpack_uint(buffer+offset, bytes-offset, &delta)) == -1)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
offset += unpacked;
|
||||
last_seen = size - delta;
|
||||
|
||||
if ((unpacked = unpack_uint(buffer+offset, bytes-offset, ×tamp)) == -1)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
offset += unpacked;
|
||||
|
||||
const char *name = (const char *)&buffer[offset];
|
||||
while(buffer[offset++]){
|
||||
if (offset >= (unsigned)bytes)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
}
|
||||
|
||||
const char *msg = (const char *)&buffer[offset];
|
||||
while(buffer[offset++]){
|
||||
if (offset >= (unsigned)bytes)
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
goto error;
|
||||
}
|
||||
|
||||
read->offset += offset - bytes;
|
||||
@ -336,14 +350,22 @@ static int read_metadata(struct meshmb_feeds *feeds, struct rhizome_read *read)
|
||||
result->last_seen = last_seen;
|
||||
result->size = size;
|
||||
result->details.bundle_id = *bid;
|
||||
result->details.author = *author;
|
||||
result->details.name = (name && *name) ? str_edup(name) : NULL;
|
||||
result->details.last_message = (msg && *msg) ? str_edup(msg) : NULL;
|
||||
result->details.timestamp = timestamp;
|
||||
|
||||
DEBUGF(meshmb, "Processed %u bytes of metadata for %s", offset, alloca_tohex_rhizome_bid_t(result->ply.bundle_id));
|
||||
DEBUGF(meshmb, "Processed %u bytes of metadata for %s",
|
||||
offset,
|
||||
alloca_tohex_rhizome_bid_t(result->ply.bundle_id),
|
||||
alloca_tohex_sid_t(result->details.author)
|
||||
);
|
||||
}
|
||||
feeds->dirty = 0;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return WHY("Buffer overflow while parsing metadata");
|
||||
}
|
||||
|
||||
int meshmb_open(keyring_identity *id, struct meshmb_feeds **feeds)
|
||||
|
1
meshmb.h
1
meshmb.h
@ -11,6 +11,7 @@ enum meshmb_send_status{
|
||||
// details of a feed that you are following
|
||||
struct meshmb_feed_details{
|
||||
rhizome_bid_t bundle_id;
|
||||
sid_t author;
|
||||
const char *name;
|
||||
const char *last_message;
|
||||
time_s_t timestamp;
|
||||
|
17
meshmb_cli.c
17
meshmb_cli.c
@ -140,6 +140,7 @@ static int app_meshmb_find(const struct cli_parsed *parsed, struct cli_context *
|
||||
const char *names[]={
|
||||
"_id",
|
||||
"id",
|
||||
"author",
|
||||
"version",
|
||||
"date",
|
||||
"name"
|
||||
@ -154,6 +155,20 @@ static int app_meshmb_find(const struct cli_parsed *parsed, struct cli_context *
|
||||
rhizome_manifest *m = cursor.manifest;
|
||||
cli_put_long(context, m->rowid, ":");
|
||||
cli_put_hexvalue(context, m->keypair.public_key.binary, sizeof m->keypair.public_key.binary, ":");
|
||||
|
||||
switch (m->authorship) {
|
||||
case AUTHOR_NOT_CHECKED:
|
||||
case AUTHOR_AUTHENTIC:
|
||||
case AUTHOR_LOCAL:
|
||||
case AUTHOR_REMOTE:
|
||||
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
||||
break;
|
||||
|
||||
default:
|
||||
cli_put_string(context, NULL, ":");
|
||||
break;
|
||||
}
|
||||
|
||||
cli_put_long(context, m->version, ":");
|
||||
cli_put_long(context, m->has_date ? m->date : 0, ":");
|
||||
cli_put_string(context, m->name, "\n");
|
||||
@ -232,6 +247,7 @@ static int list_callback(struct meshmb_feed_details *details, void *context)
|
||||
enum_context->rowcount++;
|
||||
cli_put_long(enum_context->context, enum_context->rowcount, ":");
|
||||
cli_put_string(enum_context->context, alloca_tohex_rhizome_bid_t(details->bundle_id), ":");
|
||||
cli_put_string(enum_context->context, alloca_tohex_sid_t(details->author), ":");
|
||||
cli_put_string(enum_context->context, details->name, ":");
|
||||
cli_put_long(enum_context->context, details->timestamp ? (long)(gettime() - details->timestamp) : (long)-1, ":");
|
||||
cli_put_string(enum_context->context, details->last_message, "\n");
|
||||
@ -271,6 +287,7 @@ static int app_meshmb_list(const struct cli_parsed *parsed, struct cli_context *
|
||||
const char *names[]={
|
||||
"_id",
|
||||
"id",
|
||||
"author",
|
||||
"name",
|
||||
"age",
|
||||
"last_message"
|
||||
|
@ -508,6 +508,8 @@ static int restful_feedlist_enum(struct meshmb_feed_details *details, void *cont
|
||||
strbuf_puts(state->buffer, "\n[");
|
||||
strbuf_json_hex(state->buffer, details->bundle_id.binary, sizeof details->bundle_id.binary);
|
||||
strbuf_puts(state->buffer, ",");
|
||||
strbuf_json_hex(state->buffer, details->author.binary, sizeof details->author.binary);
|
||||
strbuf_puts(state->buffer, ",");
|
||||
strbuf_json_string(state->buffer, details->name);
|
||||
strbuf_puts(state->buffer, ",");
|
||||
strbuf_sprintf(state->buffer, "%d", details->timestamp);
|
||||
@ -530,6 +532,7 @@ static int restful_meshmb_feedlist_json_content_chunk(struct http_request *hr, s
|
||||
httpd_request *r = (httpd_request *) hr;
|
||||
const char *headers[] = {
|
||||
"id",
|
||||
"author",
|
||||
"name",
|
||||
"timestamp",
|
||||
"last_message"
|
||||
|
@ -17,6 +17,7 @@ static int message_ply_load_manifest(const keyring_identity *id, struct message_
|
||||
if (!m->haveSecret || m->authorship != AUTHOR_AUTHENTIC)
|
||||
return -1;
|
||||
assert(m->author_identity == id);
|
||||
ply->author=m->author;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -58,6 +59,7 @@ static int message_ply_fill_manifest(const keyring_identity *id, const sid_t *re
|
||||
assert(m->haveSecret);
|
||||
assert(!recipient || m->payloadEncryption == PAYLOAD_ENCRYPTED);
|
||||
ply->bundle_id = m->keypair.public_key;
|
||||
ply->author = m->author;
|
||||
ply->found = ply->known_bid = 1;
|
||||
}
|
||||
return ret;
|
||||
@ -142,6 +144,7 @@ int message_ply_read_open(struct message_ply_read *ply, const rhizome_bid_t *bid
|
||||
&& rhizome_open_decrypt_read(m, &ply->read) == RHIZOME_PAYLOAD_STATUS_STORED){
|
||||
|
||||
assert(m->filesize != RHIZOME_SIZE_UNSET);
|
||||
ply->author = m->author;
|
||||
ply->read.offset = ply->read.length = m->filesize;
|
||||
if (m->name && *m->name)
|
||||
ply->name = str_edup(m->name);
|
||||
|
@ -11,6 +11,7 @@
|
||||
// the manifest details for one ply
|
||||
struct message_ply {
|
||||
rhizome_bid_t bundle_id;
|
||||
sid_t author;
|
||||
uint64_t version;
|
||||
uint64_t tail;
|
||||
uint64_t size;
|
||||
@ -26,6 +27,8 @@ struct message_ply_read {
|
||||
struct rhizome_read_buffer buff;
|
||||
// copy of the manifest name field
|
||||
const char *name;
|
||||
// copy of the manifest author
|
||||
sid_t author;
|
||||
// details of the current record
|
||||
uint64_t record_end_offset;
|
||||
uint16_t record_length;
|
||||
|
@ -76,7 +76,7 @@ static void cli_put_manifest(struct cli_context *context, const rhizome_manifest
|
||||
cli_field_name(context, ".secret", ":");
|
||||
cli_put_string(context, secret, "\n");
|
||||
}
|
||||
if (m->authorship == AUTHOR_AUTHENTIC) {
|
||||
if (m->authorship == AUTHOR_AUTHENTIC || m->authorship == AUTHOR_REMOTE) {
|
||||
cli_field_name(context, ".author", ":");
|
||||
cli_put_string(context, alloca_tohex_sid_t(m->author), "\n");
|
||||
}
|
||||
|
20
tests/meshmb
20
tests/meshmb
@ -65,10 +65,10 @@ setup_meshmbListFeeds() {
|
||||
test_meshmbListFeeds() {
|
||||
executeOk_servald meshmb find
|
||||
tfw_cat --stdout
|
||||
assertStdoutGrep --matches=1 "^_id:id:version:date:name$"
|
||||
assertStdoutGrep --matches=1 ":${IDA1}:"
|
||||
assertStdoutGrep --matches=1 ":${IDA2}:"
|
||||
assertStdoutGrep --matches=1 ":${IDA3}:"
|
||||
assertStdoutGrep --matches=1 "^_id:id:author:version:date:name$"
|
||||
assertStdoutGrep --matches=1 ":${IDA1}:${SIDA1}:"
|
||||
assertStdoutGrep --matches=1 ":${IDA2}:${SIDA2}:"
|
||||
assertStdoutGrep --matches=1 ":${IDA3}:${SIDA3}:"
|
||||
assertStdoutLineCount '==' 5
|
||||
}
|
||||
|
||||
@ -85,16 +85,16 @@ setup_meshmbFollow() {
|
||||
test_meshmbFollow() {
|
||||
executeOk_servald meshmb follow $IDA1 $IDA2
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=1 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA2:$SIDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA3:$SIDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
executeOk_servald meshmb follow $IDA1 $IDA3
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=1 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA2:$SIDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:$SIDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
executeOk_servald meshmb ignore $IDA1 $IDA2
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=0 ":$IDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA2:$SIDA2:Feed B:[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:$SIDA3:Feed C:[0-9]\+:Message 3\$"
|
||||
}
|
||||
|
||||
runTests "$@"
|
||||
|
@ -113,8 +113,8 @@ test_MeshMBRestFollow() {
|
||||
--request POST \
|
||||
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/follow/$IDA2"
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=1 ":$IDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA3::[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA2:$SIDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA3:$SIDA3::[0-9]\+:Message 3\$"
|
||||
executeOk curl \
|
||||
-H "Expect:" \
|
||||
--silent --fail --show-error \
|
||||
@ -123,8 +123,8 @@ test_MeshMBRestFollow() {
|
||||
--request POST \
|
||||
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/follow/$IDA3"
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=1 ":$IDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3::[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA2:$SIDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:$SIDA3::[0-9]\+:Message 3\$"
|
||||
executeOk curl \
|
||||
-H "Expect:" \
|
||||
--silent --fail --show-error \
|
||||
@ -133,8 +133,8 @@ test_MeshMBRestFollow() {
|
||||
--request POST \
|
||||
"http://$addr_localhost:$PORTA/restful/meshmb/$IDA1/ignore/$IDA2"
|
||||
executeOk_servald meshmb list following $IDA1
|
||||
assertStdoutGrep --matches=0 ":$IDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3::[0-9]\+:Message 3\$"
|
||||
assertStdoutGrep --matches=0 ":$IDA2:$SIDA2::[0-9]\+:Message 2\$"
|
||||
assertStdoutGrep --matches=1 ":$IDA3:$SIDA3::[0-9]\+:Message 3\$"
|
||||
}
|
||||
|
||||
doc_MeshMBRestFeeds="Restful list subscribed feeds"
|
||||
|
Loading…
Reference in New Issue
Block a user