Skip to content

Commit 6872f63

Browse files
committed
fix(api): audit moved resources
1 parent f244b5e commit 6872f63

2 files changed

Lines changed: 53 additions & 3 deletions

File tree

bootstrap/helpers/api.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
use App\Enums\BuildPackTypes;
44
use App\Enums\RedirectTypes;
55
use App\Enums\StaticImageTypes;
6+
use App\Models\Environment;
67
use App\Rules\ValidGitBranch;
78
use App\Support\ValidationPatterns;
89
use Illuminate\Database\Eloquent\Collection;
910
use Illuminate\Database\Eloquent\Model;
11+
use Illuminate\Http\JsonResponse;
1012
use Illuminate\Http\Request;
1113
use Illuminate\Support\Facades\Gate;
14+
use Illuminate\Support\Facades\Validator;
1215
use Illuminate\Validation\Rule;
1316

1417
function getTeamIdFromToken()
@@ -173,10 +176,10 @@ function sharedDataApplications()
173176
];
174177
}
175178

176-
function moveResourceToEnvironment(Request $request, $resource, string $resourceType, int $teamId): \Illuminate\Http\JsonResponse
179+
function moveResourceToEnvironment(Request $request, $resource, string $resourceType, int $teamId): JsonResponse
177180
{
178181

179-
$validator = \Illuminate\Support\Facades\Validator::make($request->all(), [
182+
$validator = Validator::make($request->all(), [
180183
'environment_uuid' => 'required|string',
181184
]);
182185

@@ -195,7 +198,7 @@ function moveResourceToEnvironment(Request $request, $resource, string $resource
195198
], 422);
196199
}
197200

198-
$newEnvironment = \App\Models\Environment::ownedByCurrentTeamAPI($teamId)
201+
$newEnvironment = Environment::ownedByCurrentTeamAPI($teamId)
199202
->whereUuid($request->environment_uuid)
200203
->first();
201204

@@ -209,8 +212,20 @@ function moveResourceToEnvironment(Request $request, $resource, string $resource
209212
return response()->json(['message' => "$resourceType is already in this environment."], 400);
210213
}
211214

215+
$oldEnvironment = $resource->environment()->with('project')->first();
216+
212217
$resource->update(['environment_id' => $newEnvironment->id]);
213218

219+
auditLog('api.'.str($resourceType)->lower()->value().'.moved', [
220+
'team_id' => $teamId,
221+
'resource_uuid' => $resource->uuid,
222+
'resource_type' => str($resourceType)->lower()->value(),
223+
'from_project_uuid' => $oldEnvironment?->project?->uuid,
224+
'from_environment_uuid' => $oldEnvironment?->uuid,
225+
'to_project_uuid' => $newEnvironment->project->uuid,
226+
'to_environment_uuid' => $newEnvironment->uuid,
227+
]);
228+
214229
return response()->json([
215230
'message' => "$resourceType moved successfully.",
216231
'uuid' => $resource->uuid,

tests/Feature/MoveResourceApiTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Illuminate\Foundation\Testing\RefreshDatabase;
1616
use Illuminate\Http\Request;
1717
use Illuminate\Support\Facades\Gate;
18+
use Illuminate\Support\Facades\Log;
1819

1920
uses(RefreshDatabase::class);
2021

@@ -62,6 +63,40 @@
6263
expect($application->environment_id)->toBe($this->targetEnvironment->id);
6364
});
6465

66+
test('writes audit log when application is moved', function () {
67+
$application = Application::factory()->create([
68+
'environment_id' => $this->environment->id,
69+
'destination_id' => $this->destination->id,
70+
'destination_type' => $this->destination->getMorphClass(),
71+
]);
72+
73+
$auditChannel = Mockery::mock();
74+
$auditChannel->shouldReceive('info')
75+
->once()
76+
->with('api.application.moved', Mockery::on(function (array $context) use ($application) {
77+
return $context['event'] === 'api.application.moved'
78+
&& $context['resource_uuid'] === $application->uuid
79+
&& $context['resource_type'] === 'application'
80+
&& $context['from_environment_uuid'] === $this->environment->uuid
81+
&& $context['to_environment_uuid'] === $this->targetEnvironment->uuid
82+
&& $context['from_project_uuid'] === $this->project->uuid
83+
&& $context['to_project_uuid'] === $this->targetProject->uuid;
84+
}));
85+
86+
Log::shouldReceive('channel')->with('audit')->andReturn($auditChannel);
87+
Log::shouldReceive('warning')->andReturnNull();
88+
89+
$this->actingAs($this->user);
90+
91+
$request = Request::create('/', 'POST', [
92+
'environment_uuid' => $this->targetEnvironment->uuid,
93+
]);
94+
95+
$response = moveResourceToEnvironment($request, $application, 'Application', $this->team->id);
96+
97+
expect($response->getStatusCode())->toBe(200);
98+
});
99+
65100
test('returns 404 when application not found', function () {
66101
$response = $this->withHeaders([
67102
'Authorization' => 'Bearer '.$this->bearerToken,

0 commit comments

Comments
 (0)