Start work on issuing an Update for the owner account, discard Undo(Like) that are for statuses that are not local, discard more invalid requests, make avatar served locally

master
teknomunk 1 year ago
parent e333da9802
commit 7f2e089b86

@ -149,16 +149,29 @@ static bool handle_command_test( struct cli_request* req )
struct status* s = status_from_id( 1164 );
struct ap_activity* note = ap_activity_create_note( s );
struct ap_activity* note2 = ap_activity_dup( note );
struct ap_activity* create = ap_activity_create_Create( note );
ap_activity_save(create);
//account_deliver_activity_to_followers( owner_account, create );
printf( "note = " );
ap_activity_write_to_FILE( note, stdout );
printf( "\nnote2 = " );
ap_activity_write_to_FILE( note2, stdout );
printf( "\ncreate = " );
ap_activity_write_to_FILE( create, stdout );
printf( "\n" );
ap_activity_free(create);
ap_activity_free(note);
ap_activity_free(note2);
status_free(s);
account_free(owner_account);
return true;
}
bool handle_command_account_sync( struct cli_request* req, int account_id )
@ -172,6 +185,16 @@ bool handle_command_account_sync( struct cli_request* req, int account_id )
return true;
}
bool handle_command_update( struct cli_request* req )
{
int res = cli_route_command( req, "update", 0, "update" );
if( res != 1 ) { return !!res; }
struct account* owner = account_from_id( owner_account_id );
account_update(owner);
account_free(owner);
return true;
}
bool handle_command_account( struct cli_request* req )
{
@ -211,6 +234,7 @@ void handle_command( char** argv, int argc )
|| handle_command_account(&req)
|| handle_command_reindex(&req)
|| handle_command_test(&req)
|| handle_command_update(&req)
) { return; }
printf( "Unknown command %s\n", argv[1] );

@ -94,6 +94,15 @@ static bool route_undo_Announce( struct ap_activity* act )
status_free(s);
return false;
}
static bool route_undo_Like( struct ap_activity* act )
{
struct status* s = NULL;
s = status_from_uri( act->object.ptr->id );
if( !s ) { return true; } // Satus not local, discard
status_free(s);
return false;
}
static bool route_undo_activity( struct ap_activity* act )
{
@ -109,6 +118,7 @@ static bool route_undo_activity( struct ap_activity* act )
switch( act->object.ptr->type ) {
case apat_follow: return route_undo_follow( act );
case apat_announce: return route_undo_Announce( act );
case apat_like: return route_undo_Like( act );
default:
printf( "Unhandled object activity type %d in undo\n", act->object.ptr->type );
return false;
@ -312,10 +322,15 @@ static bool route_create( struct ap_activity* act )
check_is_follower:
// Get actor account
actor_account = account_from_uri_or_fetch( obj->actor );
char* actor_uri = obj->actor;
if( !actor_uri ) {
actor_uri = obj->attributed_to;
obj->actor = strdup(actor_uri);
}
actor_account = account_from_uri_or_fetch( actor_uri );
if( !actor_account ) {
printf( "! Unable to fetch %s\n", obj->actor );
goto failed;
printf( "! Unable to fetch %s\n", actor_uri );
goto discard;
}
owner_account = account_from_id( owner_account_id );
@ -326,14 +341,17 @@ check_is_follower:
if( !follows_me && !mentions_me ) {
// Discard without action
printf( "Discarding create. follows_me=%c, mentions_me=%c\n", follows_me ? 'T' : 'F', mentions_me ? 'T' : 'F' );
result = true;
goto cleanup;
goto discard;
}
// Create local status
s = status_from_uri( obj->id );
if( !s ) {
s = status_from_activity(obj);
if( !s ) {
printf( "! Failed to load status from activity\n" );
goto discard;
}
status_save_new(s);
}
@ -363,6 +381,7 @@ check_is_follower:
//status_add_to_timeline( s, federated_timeline_id );
status_add_to_timeline( s, actor_account->id );
discard:
result = true;
cleanup:
account_free(actor_account);
@ -466,14 +485,13 @@ static bool process_one()
// Discard delete requests
if( act->type == apat_delete ) {
step_tail = true;
goto discard;
}
// Validate signature
env->validated = http_signature_validate( env, "post /inbox", act->actor );
if( !env->validated ) { goto failed; }
if( !env->validated ) { goto discard; }
printf( "Processing %d\n", id );
step_tail = route_activity( act );
@ -493,6 +511,7 @@ failed:
result = false;
goto finished;
discard:
step_tail = true;
result = true;
goto finished;
}

@ -120,7 +120,7 @@ static bool process_envelope( struct outbox_envelope* env )
http_signature_free( &hs );
if( status_code == 200 ) {
if( status_code == 200 || status_code == 202 ) {
printf( "Submitted successfully\n" );
env->sent = true;
outbox_envelope_save(env);

@ -78,6 +78,17 @@ static bool show_owner_profile_page( struct http_request* req )
return true;
}
static bool handle_avatar( struct http_request* req )
{
FILE* f = fopen("data/owner/avatar.png","r");
if( f ) {
fclose(f);
return http_request_send_file( req, "data/owner/avatar.png", "image/png" );
}
return false;
}
bool route_owner( struct http_request* req )
{
if( http_request_route( req, "/actor" ) ) {
@ -90,6 +101,8 @@ bool route_owner( struct http_request* req )
return handle_followers(req);
} else if( http_request_route_term( req, "/collections/featured" ) ) {
return handle_featured(req);
} else if( http_request_route_term( req, "/avatar.blob" ) ) {
return handle_avatar(req);
} else if( http_request_route_term( req, "" ) ) {
return show_owner_profile_page(req);
}

@ -161,6 +161,8 @@ static int lookup_account_id_from_uri( const char* uri )
struct account* account_from_uri( const char* uri )
{
if( !uri ) { return NULL; }
struct account* result = NULL;
// Handle owner as special case
@ -182,6 +184,8 @@ struct account* account_from_uri( const char* uri )
}
struct account* account_from_uri_or_fetch( const char* uri )
{
if( !uri ) { return NULL; }
struct account* res = account_from_uri(uri);
if( res ) { return res; }
@ -328,6 +332,7 @@ static void create_account_skeleton( int account_id )
struct account* account_fetch_from_uri( const char* uri )
{
if( !uri ) { return NULL; }
int account_id = lookup_account_id_from_uri( uri );
if( -1 == account_id ) {
@ -517,7 +522,7 @@ void account_announce( struct account* a, struct status* s )
account_deliver_activity_to_followers( a, act, &oel );
account_deliver_activity( origin_post_account, act, &oel );
printf( "Delivering to %s inboxes\n", oel.count );
printf( "Delivering to %d inboxes\n", oel.count );
outbox_envelope_list_save(&oel);
outbox_envelope_list_free_composite(&oel);
@ -671,3 +676,15 @@ bool account_does_follow( struct account* a, int account_id )
return result;
}
void account_update( struct account* a )
{
struct ap_activity* act;
act = malloc(sizeof(*act));
memset(act,0,sizeof(*act));
act->type = apat_update;
act->actor = strdup(a->account_url);
ap_activity_write_to_FILE( act, stdout );
}

@ -6,6 +6,9 @@
struct crypto_keys;
struct status;
struct ap_activity;
struct ap_account;
struct outbox_envelope;
struct outbox_envelope_list;
enum {
system_account_id = -1,
@ -62,38 +65,36 @@ void account_index_webfinger( struct account* a );
struct account* account_from_id( int id );
struct account* account_from_uri( const char* uri );
struct account* account_from_uri_or_fetch( const char* uri );
struct account* account_from_webfinger( const char* handle );
struct account* account_fetch_from_uri( const char* uri );
struct account* account_new();
struct account* account_from_uri_or_fetch( const char* uri );
struct account* account_fetch_from_uri( const char* uri );
void account_free( struct account* a );
void account_save( struct account* a );
// Update from external activity pub data
bool account_sync_from_activity_pub( unsigned int id );
bool account_sync_from_activity( struct account* a, struct ap_activity* act );
struct ap_account;
struct ap_account* account_activity_pub_data( struct account* a );
struct outbox_envelope;
struct outbox_envelope_list;
void account_deliver_activity( struct account* a, struct ap_activity* act, struct outbox_envelope_list* oel );
void account_deliver_activity_to_followers( struct account* a, struct ap_activity* act, struct outbox_envelope_list* oel );
// Data requests
struct crypto_keys* account_get_public_key( struct account* a, const char* key_name );
struct crypto_keys* account_get_private_key( struct account* a );
void account_add_follower( struct account* a, struct account* follower );
void account_remove_follower( struct account* a, struct account* follower );
void account_follow( struct account* a, struct account* to_follow );
void account_unfollow( struct account* a, struct account* to_unfollow );
void account_list_followers( struct account* a, int offset, int limit, void* id_array );
void account_list_following( struct account* a, int offset, int limit, void* id_array );
struct ap_account* account_activity_pub_data( struct account* a );
struct ap_activity* account_activity_pub( struct account* a );
// Local actions
void account_add_follower( struct account* a, struct account* follower );
void account_remove_follower( struct account* a, struct account* follower );
void account_move( struct account* a, const char* new_uri );
bool account_does_follow( struct account* a, int account_id );
// Federated actions
void account_deliver_activity( struct account* a, struct ap_activity* act, struct outbox_envelope_list* oel );
void account_deliver_activity_to_followers( struct account* a, struct ap_activity* act, struct outbox_envelope_list* oel );
void account_announce( struct account* a, struct status* s );
bool account_does_follow( struct account* a, int account_id );
void account_follow( struct account* a, struct account* to_follow );
void account_unfollow( struct account* a, struct account* to_unfollow );
void account_update( struct account* a );

@ -33,6 +33,7 @@ struct ap_activity* ap_activity_dup( struct ap_activity* act )
new_act->local_id = act->local_id;
new_act->type = act->type;
new_act->actor = strdup(act->actor);
new_act->attributed_to = safe_strdup(act->attributed_to);
new_act->published = act->published;
new_act->in_reply_to = safe_strdup( act->in_reply_to );
@ -369,6 +370,7 @@ struct ap_activity* ap_activity_create_Create( struct ap_activity* object )
fs_list_set( "data/activities/HEAD", id );
struct ap_activity* act = ap_activity_new();
act->local_id = id;
act->type = apat_create;
act->id = aformat( "https://%s/activity/%d", g_server_name, id );
act->object.tag = apaot_activity;

@ -160,6 +160,7 @@ bool http_signature_validate( struct ap_envelope* env, const char* request_targe
char* date_header = NULL;
struct crypto_keys* keys = NULL;
bool result = false;
char* hash_line = NULL;
// Get the Signature header
for( int i = 0; i < env->headers.count; ++i ) {
@ -252,7 +253,6 @@ bool http_signature_validate( struct ap_envelope* env, const char* request_targe
}
// Create the hash line
char* hash_line = NULL;
size_t hash_line_size = 0;
FILE* hl = open_memstream( &hash_line, &hash_line_size );

@ -31,7 +31,7 @@ static struct json_object_field status_layout[] = {
JSON_FIELD_BOOL( stub, false ),
JSON_FIELD_BOOL( remote, false ),
// DO NOT INCLUDE field content
JSON_FIELD_STRING( content, false ),
JSON_FIELD_STRING( source, false ),
JSON_FIELD_BOOL( pinned, false ),
JSON_FIELD_DATETIME( published, false ),
@ -80,13 +80,13 @@ static FILE* open_status_data_file( unsigned int id, const char* mode )
f = fopen( get_status_data_filename(id,filename,sizeof(filename)), mode );
if( f ) {
printf( "Using new location at %s\n", filename );
//printf( "Using new location at %s\n", filename );
return f;
}
f = fopen( format(filename,sizeof(filename), "data/statuses/%d.json", id), mode );
if( f ) {
printf( "Using existing location at %s\n", filename );
//printf( "Using existing location at %s\n", filename );
return f;
}
}
@ -180,6 +180,10 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_activity* act )
s->source = safe_strdup(act->source.content);
s->url = strdup( act->id );
if( !s->source ) {
printf( "? No source, using content directly\n" );
s->content = safe_strdup(act->content.content);
}
// Erase existing media
for( int i = 0; i < s->media.count; ++i ) {

@ -3,8 +3,9 @@
"application": null,
"bookmarked": false,
"card": null,
"created_at": %( json_write_date_time_string( s->published, f ); ),
"content": %( json_write_string(f,status_render_source(s)); ),
"created_at": %( json_write_date_time_string( s->published, f ); ),
"edited_at": null,
"emojis": [],
"favourited": false,
"favourites_count": %d{ s->likes.count },
@ -35,10 +36,10 @@
"mentions": [%( for( int i = 0; i < s->mentions.count; ++i ) { )
%( struct account* mention = account_from_id( s->mentions.items[i] ); )
%s{ i != 0 ? "," : "" }{
"id": "%d{mention->id}",
"username": "%s{mention->handle}",
"acct": "%s{mention->handle}@%s{mention->server}",
"url": "%s{mention->account_url}"
"id": "%d{mention->id}",
"url": "%s{mention->account_url}",
"username": "%s{mention->handle}"
}
%( account_free(mention); )
%( } )],

Loading…
Cancel
Save