Implement webfinger lookup for following accounts not already local

master
teknomunk 1 year ago
parent aad7a1f82f
commit 9e6e2cf556

@ -4,7 +4,6 @@
// Submodules
#include "json/json.h"
#include "json/layout.h"
#include "http/client/client.h"
#include "ffdb/fs_list.h"
#include "ffdb/hash_index.h"
#include "ffdb/trie.h"
@ -29,6 +28,7 @@
#include <stddef.h>
#include <sys/stat.h>
#include <time.h>
bool pull_remote_file( const char* filename, const char* uri );
static const char* safe( const char* value, const char* other )
{
@ -203,14 +203,15 @@ void account_index_webfinger( struct account* a )
snprintf( webfinger_name, 512, "%s@%s", a->handle, a->server );
hash_index_set( "data/accounts/webfinger", webfinger_name, a->id );
}
char* webfinger_query( const char* handle, const char* rel, const char* type );
struct account* account_from_webfinger( const char* handle )
{
//printf( "account_from_webfinger( %s )\n", handle );
int id;
if( !hash_index_get( "data/accounts/webfinger", handle, &id ) ) {
printf( "! No account id for %s\n", handle );
printf( "! TODO: implement webfinger lookup\n" );
return NULL;
char* account_uri = webfinger_query( handle, "self", "application/activity+json" );
struct account* a = account_from_uri_or_fetch( account_uri );
free(account_uri);
return a;
}
return account_from_id(id);
@ -344,7 +345,6 @@ static void create_account_skeleton( int account_id )
fs_list_set( format( b, 512, "data/accounts/%d/timeline/HEAD", account_id ), 0 );
}
bool pull_remote_file( const char* filename, const char* uri );
struct account* account_fetch_from_uri( const char* uri )
{
if( !uri ) { return NULL; }

@ -0,0 +1,107 @@
#include "http/client/client.h"
#include "json/layout.h"
#include "format.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
struct link
{
char* href;
char* rel;
char* type;
};
#define OBJ_TYPE struct link
static struct json_object_field link_layout[] = {
JSON_FIELD_STRING( href, true ),
JSON_FIELD_STRING( rel, true ),
JSON_FIELD_STRING( type, true ),
JSON_FIELD_END,
};
#undef OBJ_TYPE
void link_free( struct link* l )
{
if( !l ) { return; }
free(l->href);
free(l->type);
free(l->rel);
}
JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( link );
struct result
{
struct {
struct link** items;
int count;
} links;
};
#define OBJ_TYPE struct result
static struct json_object_field result_layout[] = {
JSON_FIELD_ARRAY_OF_TYPE( links, true, link_type ),
JSON_FIELD_END,
};
#undef OBJ_TYPE
char* webfinger_query( const char* handle, const char* rel, const char* type )
{
char handle2[512];
strncpy( handle2, handle, 512 );
char* server = NULL;
char* username = strtok_r( handle2, "@", &server );
char url[512];
mkdir( "data/webfinger/", 0755 );
const char* uri = format( url, sizeof(url), "https://%s/.well-known/webfinger?resource=acct:%s", server, handle );
char filename[512];
snprintf( filename, sizeof(filename), "data/webfinger/%s.json", handle );
printf( "* Fetching %s\n", uri );
char tmp_filename[512];
FILE* f = fopen(format(tmp_filename,512,"%s.tmp",filename),"w");
long status_code = -1;
const void* request[] = {
HTTP_REQ_URL, uri,
HTTP_REQ_OUTFILE, f,
HTTP_REQ_RESULT_STATUS, &status_code,
NULL,
};
if( !http_client_do( request ) ) {
printf( "! Unable to fetch %s\n", uri );
fclose(f);
return NULL;
}
printf( "status_code = %d\n", status_code );
if( status_code != 200 ) {
fclose(f);
return NULL;
}
fclose(f);
rename(tmp_filename,filename);
// Get the href value requested
struct result r;
memset(&r,0,sizeof(r));
json_read_object_layout_from_file( filename, result_layout, &r );
char* value = NULL;
for( int i = 0; i < r.links.count; ++i ) {
if( 0 == strcmp( rel, r.links.items[i]->rel ) ) {
if( 0 == strcmp( type, r.links.items[i]->type ) ) {
free(value);
value = strdup(r.links.items[i]->href);
}
}
link_free(r.links.items[i]);
}
free(r.links.items);
return value;
}
Loading…
Cancel
Save