Start implementing administrative interface, add initial installation instructions to README, make soapbox.json into a server-created file

master
teknomunk 5 months ago
parent 48db4e78ab
commit ce178cd5a9

@ -18,5 +18,35 @@ USE AT YOUR OWN RISK.
# Dependencies
* libCURL
* OpenSSL
* C Compiler (test with GCC)
* Ruby (hopefully temporary)
* Globaly resolvable domain name
# Installation Instructions
Ensure you have system packages for the dependencies installed, then run the following code in
a terminal window:
````
git clone https://gitea.polaris-1.work/teknomunk/apogee.git
cd apogee
./build.sh
./apogee
````
If everything worked correctly, you should see something similar to the following:
````
Starting Apogee ActivityPub server...
Using port 21630 for web server
Starting section 6 (tor)
Starting section 0 (webserver)
Starting section 1 (inbox)
Starting section 2 (outbox)
Starting section 5 (fetch)
````
The listening port is chosen at random each time the program is run until setup, then the configured
port is used. Open a browser and navigate to http://${hostname-or-ip}:${port}/, then fill in the
required information.

@ -0,0 +1,45 @@
#include "controller/admin.h"
// Model
#include "src/model/server.h"
// View
// Controller
#include "src/controller/api/client_apps.h"
#include "http/server/request.h"
const char* view_checkbox( bool value )
{
return value ? "checked" : "";
}
bool route_admin_request( struct http_request* req )
{
// TODO: authenticate
if( !check_authentication_header(req) ) {
printf( "User-Agent: %s\n", http_request_get_header(req,"user-agent") );
http_request_send_headers( req, 401, "text/plain", true );
FILE* f = http_request_get_response_body( req );
fprintf( f, "Not authorized to use this endpoint.\n" );
return true;
}
if( http_request_route_term( req, "/server-setup" ) ) {
return handle_admin_server_setup(req);
}
return false;
}
// Route: /admin/server-setup
// Special: / (when server hasn't been configured)
bool handle_admin_server_setup( struct http_request* req )
{
http_request_send_headers( req, 200, "text/html", true );
FILE* f = http_request_get_response_body( req );
#include "view/admin/server-setup.html.inc"
return true;
}

@ -0,0 +1,9 @@
#pragma once
#include <stdbool.h>
struct http_request;
bool route_admin_request( struct http_request* req );
bool handle_admin_server_setup( struct http_request* req );

@ -17,6 +17,7 @@
#include "controller/inbox.h"
#include "controller/activity_pub.h"
#include "controller/api/emoji.h"
#include "controller/admin.h"
// Standard Library
#include <string.h>
@ -196,6 +197,13 @@ bool route_request( struct http_request* req )
}
} else if( http_request_route( req, "/nodeinfo" ) ) {
return route_nodeinfo(req);
} else if( http_request_route_term( req, "/instance/soapbox.json" ) ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
#include "view/soapbox.json.inc"
return true;
} else {
return route_asset(req);
}
@ -207,8 +215,12 @@ bool route_request( struct http_request* req )
return route_mastodon_api( req );
} else if( http_request_route( req, "/api/pleroma" ) ) {
return route_pleroma_api2( req );
} else if( http_request_route( req, "/admin" ) ) {
return route_admin_request( req );
} else if( inner( req ) ) {
return true;
} else if( http_request_route_term( req, "/" ) && !g_server->configured ) {
return handle_admin_server_setup( req );
} else {
return send_asset( req, "assets/soapbox/index.html" );
}

@ -38,6 +38,7 @@ int main( int argc, char* argv[], char* envp[] )
int code = 0;
if( g_server->section == -1 ) {
printf( "Starting Apogee ActivityPub server...\n" );
printf( "Using port %d for web server\n", g_server->http_settings.bind_port );
process_start_section(6);
// Make sure we have a hidden service hostname

@ -29,6 +29,8 @@ static struct json_object_field app_args_layout[] = {
JSON_FIELD_INTEGER( outbox_discard_limit, false ),
JSON_FIELD_BOOL( develop, false ),
JSON_FIELD_BOOL( enabled, false ),
JSON_FIELD_BOOL( configured, false ),
JSON_FIELD_END,
};
#undef OBJ_TYPE
@ -87,6 +89,12 @@ struct app_args* app_args_new( int argc, char** argv )
// Sections by number
if( sscanf(arg,"--section=%d",&args->section) ) { goto next_arg; }
// Override server port
if( sscanf(arg,"--listen=%d",&args->http_settings.bind_port) ) {
printf( "Listening on port %d\n", args->http_settings.bind_port );
goto next_arg;
}
// Sections by name
if( ( argv[i][0] == '-' ) && ( argv[i][1] == '-' ) ) {
for( int i = 0; i <= process_get_max_section(); ++i ) {
@ -122,4 +130,9 @@ void app_args_release( struct app_args* args )
free(args->user_agent);
free(args);
}
void app_args_save()
{
// TODO: save server settings to disk
json_write_object_layout_to_file( "data/server.json", "\t", app_args_layout, g_server );
}

@ -21,9 +21,12 @@ struct app_args
int outbox_discard_limit;
bool develop;
bool enabled;
bool configured;
};
struct app_args* app_args_new( int argc, char** argv );
void app_args_release( struct app_args* args );
void app_args_save();
extern struct app_args* g_server;

@ -130,7 +130,7 @@ static void redirect_io( int section )
const char* section_name_str = process_get_section_name(section);
if( !section_name_str ) { return; }
mkdir( "data/logs", 0640 );
mkdir( "data/logs", 0750 );
char filename[512];
snprintf( filename,512, "data/logs/%s.log", section_name_str );

@ -0,0 +1,76 @@
<html>%(/*
vim: filetype=html
*/)
<body>
<h1>Welcome to Apogee</h1>
<p>
Apogee is a single-user Activity Pub federated server intended for self-hosting.
</p>
<h2>Server Settings</h2>
<form method="POST" action="/admin/">
<h3>HTTP</h3>
<table width='100%%'>
<tr>
<td width="15%%"><b>Domain Name:</b></td>
<td><input name="domain" type="text" value="%s{ g_server->domain ? g_server->domain : "" }"/></td>
<td></td>
<tr>
<td><b>Listen Address:</b></td>
<td><input name="address" type="text" value="%s{ g_server->http_settings.bind_address ? g_server->http_settings.bind_address : "0.0.0.0" }"/></td>
<td></td>
</tr>
<tr>
<td><b>Listen Port:</b></td>
<td><input name="port" type="text" value="%d{ g_server->http_settings.bind_port }" /></td>
<td></td>
</tr>
<tr>
<td><b>User Agent:</b></td>
<td><input name="useragent" type="text" value="%s{ g_server->user_agent }" /></td>
<td></td>
</tr>
</table>
<h3>Tor</h3>
<table width='100%%'>
<tr>
<td width="15%%"><b>Disable:<b></td>
<td><input name="disable_tor" type="checkbox" %s{ view_checkbox(g_server->disable_tor) }/></td>
<td></td>
</tr>
<tr>
<td><b>SOCKS Port:<b></td>
<td><input name="socks_port" type="text" value="%d{ g_server->tor_socks_port }" /></td>
<td></td>
</tr>
</table>
<h3>Other</h3>
<table width='100%%'>
<tr>
<td width="15%%"><b>Outbox Discard Limit:</b></td>
<td><input name="outbox_discard_limit" type="text" value="%d{ g_server->outbox_discard_limit }" /></td>
<td></td>
</tr>
<tr>
<td><b>Debug Mode:</b></td>
<td><input name="debug" type="checkbox" %s{ view_checkbox(g_server->debug) }/></td>
<td>Greatly increases server verbosity</td>
</tr>
<tr>
<td><b>Developer Mode:</b></td>
<td><input name="develop" type="checkbox" %s{ view_checkbox(g_server->develop) }/></td>
<td>Change server behavior to suit developers</td>
</tr>
<tr>
<td><b>Server Enabled:</b></td>
<td><input name="enabled" type="checkbox" %s{ view_checkbox( g_server->enabled ) }/></td>
<td>Turn the entire server off</td>
</tr>
</table>
<br/>
<input type="submit" />
</form>
</body>
</html>

@ -0,0 +1,33 @@
{
"logo":"/instance/images/logo.png",
"brandColor": "#0482d8",
"promoPanel":{
"items":[
{
"icon": "area-chart",
"text": "Site stats",
"url": "https://fediverse.network/%s{ g_server->domain }"
},
{
"icon": "admin",
"text": "Server Settings",
"url": "/admin/server-settings"
}
]
},
"defaultSettings": {
"autoPlayGif": false,
"themeMode": "light"
},
"copyright": "♡2020. Copying is an act of love. Please copy and share.",
"navlinks": {
"homeFooter":[
{ "title": "About", "url": "/about" },
{ "title": "Terms of Service", "url": "/about/tos" },
{ "title": "Privacy Policy", "url": "/about/privacy" },
{ "title": "DMCA", "url": "/about/dmca" },
{ "title": "Source Code", "url": "/about#opensource" }
]
},
"allowedEmoji": ["🤔", "😂", "😭", "😡", "🥰", "👍🏼", "👎🏼", "🔥", "😩", "🍆"]
}
Loading…
Cancel
Save