Now accounts are federalized
This commit is contained in:
parent
0fc124b55b
commit
fddfe65b7b
19
app/Http/Controllers/AP/APActorController.php
Normal file
19
app/Http/Controllers/AP/APActorController.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
|
||||
class APActorController extends Controller
|
||||
{
|
||||
public function user (User $user)
|
||||
{
|
||||
$actor = $user->actor ()->get ();
|
||||
$response = Actor::build_response ($actor->first ());
|
||||
return response ()->json ($response)->header ("Content-Type", "application/activity+json");
|
||||
}
|
||||
}
|
18
app/Http/Controllers/AP/APInboxController.php
Normal file
18
app/Http/Controllers/AP/APInboxController.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class APInboxController extends Controller
|
||||
{
|
||||
public function inbox (User $user)
|
||||
{
|
||||
Log::info ("APInboxController@index");
|
||||
}
|
||||
}
|
18
app/Http/Controllers/AP/APOutboxController.php
Normal file
18
app/Http/Controllers/AP/APOutboxController.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class APOutboxController extends Controller
|
||||
{
|
||||
public function outbox (User $user)
|
||||
{
|
||||
Log::info ("APOutboxController@index");
|
||||
}
|
||||
}
|
45
app/Http/Controllers/AP/APWebfingerController.php
Normal file
45
app/Http/Controllers/AP/APWebfingerController.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\AP;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class APWebfingerController extends Controller
|
||||
{
|
||||
public function webfinger ()
|
||||
{
|
||||
$resource = request ()->input ("resource");
|
||||
if (!isset ($resource)) {
|
||||
return response ()->json ([ "error" => "missing resource parameter" ], 400);
|
||||
}
|
||||
|
||||
$host = parse_url ($resource, PHP_URL_HOST);
|
||||
$user = explode (":", $resource);
|
||||
if (count ($user) != 2) {
|
||||
return response ()->json ([ "error" => "invalid resource parameter" ], 400);
|
||||
}
|
||||
|
||||
$user = $user[1];
|
||||
$user = explode ("@", $user);
|
||||
if (count ($user) != 2) {
|
||||
return response ()->json ([ "error" => "invalid resource parameter" ], 400);
|
||||
}
|
||||
|
||||
$user = $user[0];
|
||||
$actual_user = User::where ("name", $user)->first ();
|
||||
$webfinger = [
|
||||
"subject" => $resource,
|
||||
"links" => [
|
||||
[
|
||||
"rel" => "self",
|
||||
"type" => "application/activity+json",
|
||||
"href" => $actual_user->actor ()->first ()->actor_id
|
||||
]
|
||||
]
|
||||
];
|
||||
return response ()->json ($webfinger)->header ("Content-Type", "application/jrd+json");
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Actor;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserController extends Controller
|
||||
@ -26,6 +28,8 @@ class UserController extends Controller
|
||||
]);
|
||||
|
||||
$user = User::create ($incoming_fields);
|
||||
$actor = new Actor ();
|
||||
$actor->create_from_user ($user);
|
||||
auth ()->login ($user);
|
||||
|
||||
return redirect ()->route ("home")->with ("success", "You have successfuly signed up!");
|
||||
|
106
app/Models/Actor.php
Normal file
106
app/Models/Actor.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
|
||||
class Actor extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
"user_id",
|
||||
|
||||
"type",
|
||||
"actor_id",
|
||||
|
||||
"following",
|
||||
"followers",
|
||||
|
||||
"liked",
|
||||
|
||||
"inbox",
|
||||
"outbox",
|
||||
|
||||
"sharedInbox",
|
||||
|
||||
"preferredUsername",
|
||||
"name",
|
||||
"summary",
|
||||
|
||||
"public_key",
|
||||
"private_key"
|
||||
];
|
||||
|
||||
public function create_from_user (User $user)
|
||||
{
|
||||
$app_url = Config::get ("app.url");
|
||||
|
||||
$config = [
|
||||
"private_key_bits" => 4096,
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA
|
||||
];
|
||||
|
||||
$res = openssl_pkey_new ($config);
|
||||
openssl_pkey_export ($res, $private_key);
|
||||
|
||||
$public_key = openssl_pkey_get_details ($res);
|
||||
|
||||
return $this->create ([
|
||||
"user_id" => $user->id,
|
||||
|
||||
"type" => "Person",
|
||||
"actor_id" => $app_url . "/ap/v1/user/" . $user->name,
|
||||
|
||||
"following" => $app_url . "/ap/v1/user/" . $user->name . "/following",
|
||||
"followers" => $app_url . "/ap/v1/user/" . $user->name . "/followers",
|
||||
|
||||
"liked" => $app_url . "/ap/v1/user/" . $user->name . "/liked",
|
||||
|
||||
"inbox" => $app_url . "/ap/v1/user/" . $user->name . "/inbox",
|
||||
"outbox" => $app_url . "/ap/v1/user/" . $user->name . "/outbox",
|
||||
|
||||
"sharedInbox" => $app_url . "/ap/v1/inbox",
|
||||
|
||||
"preferredUsername" => $user->name,
|
||||
"name" => $user->name,
|
||||
"summary" => "",
|
||||
|
||||
"public_key" => $public_key["key"],
|
||||
"private_key" => $private_key
|
||||
]);
|
||||
}
|
||||
|
||||
public static function build_response (Actor $actor)
|
||||
{
|
||||
return [
|
||||
"@context" => [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1"
|
||||
],
|
||||
"id" => $actor->actor_id,
|
||||
"type" => $actor->type,
|
||||
|
||||
"following" => $actor->following,
|
||||
"followers" => $actor->followers,
|
||||
|
||||
"liked" => $actor->liked,
|
||||
|
||||
"inbox" => $actor->inbox,
|
||||
"outbox" => $actor->outbox,
|
||||
|
||||
"sharedInbox" => $actor->sharedInbox,
|
||||
|
||||
"preferredUsername" => $actor->preferredUsername,
|
||||
"name" => $actor->name,
|
||||
"summary" => $actor->summary,
|
||||
|
||||
"publicKey" => [
|
||||
"id" => $actor->actor_id . "#main-key",
|
||||
"owner" => $actor->actor_id,
|
||||
"publicKeyPem" => $actor->public_key
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
@ -53,4 +53,9 @@ class User extends Authenticatable
|
||||
return $value ? "/storage/avatars/" . $value : "/resources/img/default.jpg";
|
||||
});
|
||||
}
|
||||
|
||||
public function actor ()
|
||||
{
|
||||
return $this->hasOne (Actor::class);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('actors', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->foreignId ("user_id")->nullable ()->constrained ()->onDelete ("cascade");
|
||||
|
||||
$table->string ("type")->nullable ();
|
||||
$table->string ("actor_id")->unique ();
|
||||
|
||||
$table->string ("following")->nullable ();
|
||||
$table->string ("followers")->nullable ();
|
||||
|
||||
$table->string ("liked")->nullable ();
|
||||
|
||||
$table->string ("inbox")->nullable ();
|
||||
$table->string ("outbox")->nullable ();
|
||||
|
||||
$table->string ("sharedInbox")->nullable ();
|
||||
|
||||
$table->string ("preferredUsername")->nullable ();
|
||||
$table->string ("name")->nullable ();
|
||||
$table->string ("summary")->nullable ();
|
||||
|
||||
$table->string ("public_key")->nullable ();
|
||||
$table->string ("private_key")->nullable ();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('actors');
|
||||
}
|
||||
};
|
@ -22,12 +22,12 @@
|
||||
|
||||
<form action="#" method="POST">
|
||||
@csrf
|
||||
<input type="text" name="name" placeholder="Username" required><br>
|
||||
<input type="text" name="name" placeholder="Username" value="{{ old ('name') }}" required><br>
|
||||
@error('username')
|
||||
<div class="error">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
<input type="email" name="email" placeholder="Email" required><br>
|
||||
<input type="email" name="email" placeholder="Email" value="{{ old ('email') }}" required><br>
|
||||
@error('email')
|
||||
<div class="error">{{ $message }}</div>
|
||||
@enderror
|
||||
|
17
routes/api.php
Normal file
17
routes/api.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
use App\Http\Controllers\AP\APActorController;
|
||||
use App\Http\Controllers\AP\APWebfingerController;
|
||||
|
||||
use App\Http\Controllers\AP\APInboxController;
|
||||
use App\Http\Controllers\AP\APOutboxController;
|
||||
|
||||
Route::get ("/.well-known/webfinger", [ APWebfingerController::class, "webfinger" ])->name ("ap.webfinger");
|
||||
|
||||
Route::prefix ("/ap/v1")->group (function () {
|
||||
Route::get ("/user/{user:name}", [ APActorController::class, "user" ])->name ("ap.user");
|
||||
Route::post ("/user/{user:name}/inbox", [ APInboxController::class, "inbox" ])->name ("ap.inbox");
|
||||
Route::post ("/user/{user:name}/outbox", [ APOutboxController::class, "outbox" ])->name ("ap.outbox");
|
||||
});
|
@ -13,3 +13,5 @@ Route::get ("/auth/signup", [ UserController::class, "signup" ])->name ("signup"
|
||||
Route::get ("/auth/logout", [ UserController::class, "logout" ])->name ("logout")->middleware ("auth");
|
||||
Route::post ("/auth/signup", [ UserController::class, "do_signup" ])->middleware ("guest");
|
||||
Route::post ("/auth/login", [ UserController::class, "do_login" ])->middleware ("guest");
|
||||
|
||||
require __DIR__ . "/api.php";
|
||||
|
Loading…
x
Reference in New Issue
Block a user