Skip to content

Commit 0520014

Browse files
committed
Add support for tracking when an activity event is triggered from an API key
1 parent 92c1c16 commit 0520014

File tree

7 files changed

+87
-0
lines changed

7 files changed

+87
-0
lines changed

app/Http/Kernel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Pterodactyl\Http\Middleware\LanguageMiddleware;
1717
use Illuminate\Foundation\Http\Kernel as HttpKernel;
1818
use Illuminate\Routing\Middleware\SubstituteBindings;
19+
use Pterodactyl\Http\Middleware\Activity\TrackAPIKey;
1920
use Illuminate\Session\Middleware\AuthenticateSession;
2021
use Illuminate\View\Middleware\ShareErrorsFromSession;
2122
use Pterodactyl\Http\Middleware\MaintenanceMiddleware;
@@ -68,6 +69,7 @@ class Kernel extends HttpKernel
6869
EnsureStatefulRequests::class,
6970
'auth:sanctum',
7071
IsValidJson::class,
72+
TrackAPIKey::class,
7173
RequireTwoFactorAuthentication::class,
7274
AuthenticateIPAccess::class,
7375
],
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Middleware\Activity;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Pterodactyl\Models\ApiKey;
8+
use Pterodactyl\Facades\LogTarget;
9+
10+
class TrackAPIKey
11+
{
12+
/**
13+
* Determines if the authenticated user making this request is using an actual
14+
* API key, or it is just a cookie authenticated session. This data is set in a
15+
* request singleton so that all tracked activity log events are properly associated
16+
* with the given API key.
17+
*
18+
* @return mixed
19+
*/
20+
public function handle(Request $request, Closure $next)
21+
{
22+
if ($request->user()) {
23+
$token = $request->user()->currentAccessToken();
24+
25+
LogTarget::setApiKeyId($token instanceof ApiKey ? $token->id : null);
26+
}
27+
28+
return $next($request);
29+
}
30+
}

app/Models/ActivityLog.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Pterodactyl\Events\ActivityLogged;
99
use Illuminate\Database\Eloquent\Builder;
1010
use Illuminate\Database\Eloquent\MassPrunable;
11+
use Illuminate\Database\Eloquent\Relations\HasOne;
1112
use Illuminate\Database\Eloquent\Relations\MorphTo;
1213
use Illuminate\Database\Eloquent\Model as IlluminateModel;
1314

@@ -21,11 +22,13 @@
2122
* @property string|null $description
2223
* @property string|null $actor_type
2324
* @property int|null $actor_id
25+
* @property int|null $api_key_id
2426
* @property \Illuminate\Support\Collection|null $properties
2527
* @property \Carbon\Carbon $timestamp
2628
* @property IlluminateModel|\Eloquent $actor
2729
* @property \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\ActivityLogSubject[] $subjects
2830
* @property int|null $subjects_count
31+
* @property \Pterodactyl\Models\ApiKey|null $apiKey
2932
*
3033
* @method static Builder|ActivityLog forActor(\Illuminate\Database\Eloquent\Model $actor)
3134
* @method static Builder|ActivityLog forEvent(string $action)
@@ -34,6 +37,7 @@
3437
* @method static Builder|ActivityLog query()
3538
* @method static Builder|ActivityLog whereActorId($value)
3639
* @method static Builder|ActivityLog whereActorType($value)
40+
* @method static Builder|ActivityLog whereApiKeyId($value)
3741
* @method static Builder|ActivityLog whereBatch($value)
3842
* @method static Builder|ActivityLog whereDescription($value)
3943
* @method static Builder|ActivityLog whereEvent($value)
@@ -86,6 +90,11 @@ public function subjects()
8690
return $this->hasMany(ActivityLogSubject::class);
8791
}
8892

93+
public function apiKey(): HasOne
94+
{
95+
return $this->hasOne(ApiKey::class, 'id', 'api_key_id');
96+
}
97+
8998
public function scopeForEvent(Builder $builder, string $action): Builder
9099
{
91100
return $builder->where('event', $action);

app/Services/Activity/ActivityLogService.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ protected function getActivity(): ActivityLog
210210
'ip' => Request::ip(),
211211
'batch_uuid' => $this->batch->uuid(),
212212
'properties' => Collection::make([]),
213+
'api_key_id' => $this->targetable->apiKeyId(),
213214
]);
214215

215216
if ($subject = $this->targetable->subject()) {

app/Services/Activity/ActivityLogTargetableService.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class ActivityLogTargetableService
1010

1111
protected ?Model $subject = null;
1212

13+
protected ?int $apiKeyId = null;
14+
1315
public function setActor(Model $actor): void
1416
{
1517
$this->actor = $actor;
@@ -20,6 +22,11 @@ public function setSubject(Model $subject): void
2022
$this->subject = $subject;
2123
}
2224

25+
public function setApiKeyId(?int $apiKeyId): void
26+
{
27+
$this->apiKeyId = $apiKeyId;
28+
}
29+
2330
public function actor(): ?Model
2431
{
2532
return $this->actor;
@@ -30,9 +37,15 @@ public function subject(): ?Model
3037
return $this->subject;
3138
}
3239

40+
public function apiKeyId(): ?int
41+
{
42+
return $this->apiKeyId;
43+
}
44+
3345
public function reset(): void
3446
{
3547
$this->actor = null;
3648
$this->subject = null;
49+
$this->apiKeyId = null;
3750
}
3851
}

app/Transformers/Api/Client/ActivityLogTransformer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public function transform(ActivityLog $model): array
1919
return [
2020
'batch' => $model->batch,
2121
'event' => $model->event,
22+
'is_api' => !is_null($model->api_key_id),
2223
'ip' => $model->ip,
2324
'description' => $model->description,
2425
'properties' => $model->properties ? $model->properties->toArray() : [],
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Schema;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Database\Migrations\Migration;
6+
7+
return new class () extends Migration {
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('activity_logs', function (Blueprint $table) {
16+
$table->unsignedInteger('api_key_id')->nullable()->after('actor_id');
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('activity_logs', function (Blueprint $table) {
28+
$table->dropColumn('api_key_id');
29+
});
30+
}
31+
};

0 commit comments

Comments
 (0)