test(api): assert target env authorization on moves
This commit is contained in:
parent
676161a627
commit
f244b5e25d
3 changed files with 418 additions and 7 deletions
255
openapi.json
255
openapi.json
|
|
@ -3364,6 +3364,91 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"\/applications\/{uuid}\/move": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Applications"
|
||||||
|
],
|
||||||
|
"summary": "Move",
|
||||||
|
"description": "Move application to another project\/environment. This is a purely organizational change \u2014 running containers are not affected. Note: after moving, the application will pick up shared environment variables from the new environment on the next deployment.",
|
||||||
|
"operationId": "move-application-by-uuid",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "uuid",
|
||||||
|
"in": "path",
|
||||||
|
"description": "UUID of the application.",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "Target environment to move the application to.",
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"environment_uuid"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "UUID of the target environment."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Application moved successfully.",
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Application moved successfully."
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"project_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#\/components\/responses\/401"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#\/components\/responses\/400"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#\/components\/responses\/404"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#\/components\/responses\/422"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"\/applications\/{uuid}\/storages": {
|
"\/applications\/{uuid}\/storages": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -6494,6 +6579,91 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"\/databases\/{uuid}\/move": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Databases"
|
||||||
|
],
|
||||||
|
"summary": "Move",
|
||||||
|
"description": "Move database to another project\/environment. This is a purely organizational change \u2014 running containers are not affected. Note: after moving, the database will pick up shared environment variables from the new environment on the next deployment.",
|
||||||
|
"operationId": "move-database-by-uuid",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "uuid",
|
||||||
|
"in": "path",
|
||||||
|
"description": "UUID of the database.",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "Target environment to move the database to.",
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"environment_uuid"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "UUID of the target environment."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Database moved successfully.",
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Database moved successfully."
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"project_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#\/components\/responses\/401"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#\/components\/responses\/400"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#\/components\/responses\/404"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#\/components\/responses\/422"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"\/databases\/{uuid}\/start": {
|
"\/databases\/{uuid}\/start": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -12982,6 +13152,91 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"\/services\/{uuid}\/move": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Services"
|
||||||
|
],
|
||||||
|
"summary": "Move",
|
||||||
|
"description": "Move service to another project\/environment. This is a purely organizational change \u2014 running containers are not affected. Note: after moving, the service will pick up shared environment variables from the new environment on the next deployment.",
|
||||||
|
"operationId": "move-service-by-uuid",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "uuid",
|
||||||
|
"in": "path",
|
||||||
|
"description": "UUID of the service.",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "Target environment to move the service to.",
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"required": [
|
||||||
|
"environment_uuid"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "UUID of the target environment."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Service moved successfully.",
|
||||||
|
"content": {
|
||||||
|
"application\/json": {
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Service moved successfully."
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"project_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"environment_uuid": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"$ref": "#\/components\/responses\/401"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"$ref": "#\/components\/responses\/400"
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"$ref": "#\/components\/responses\/404"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#\/components\/responses\/422"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearerAuth": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"\/services\/{uuid}\/start": {
|
"\/services\/{uuid}\/start": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
|
||||||
153
openapi.yaml
153
openapi.yaml
|
|
@ -2141,6 +2141,57 @@ paths:
|
||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
'/applications/{uuid}/move':
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Applications
|
||||||
|
summary: Move
|
||||||
|
description: 'Move application to another project/environment. This is a purely organizational change — running containers are not affected. Note: after moving, the application will pick up shared environment variables from the new environment on the next deployment.'
|
||||||
|
operationId: move-application-by-uuid
|
||||||
|
parameters:
|
||||||
|
-
|
||||||
|
name: uuid
|
||||||
|
in: path
|
||||||
|
description: 'UUID of the application.'
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: 'Target environment to move the application to.'
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- environment_uuid
|
||||||
|
properties:
|
||||||
|
environment_uuid:
|
||||||
|
type: string
|
||||||
|
description: 'UUID of the target environment.'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: 'Application moved successfully.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
message: { type: string, example: 'Application moved successfully.' }
|
||||||
|
uuid: { type: string }
|
||||||
|
project_uuid: { type: string }
|
||||||
|
environment_uuid: { type: string }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
'422':
|
||||||
|
$ref: '#/components/responses/422'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
'/applications/{uuid}/storages':
|
'/applications/{uuid}/storages':
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -4248,6 +4299,57 @@ paths:
|
||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
'/databases/{uuid}/move':
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Databases
|
||||||
|
summary: Move
|
||||||
|
description: 'Move database to another project/environment. This is a purely organizational change — running containers are not affected. Note: after moving, the database will pick up shared environment variables from the new environment on the next deployment.'
|
||||||
|
operationId: move-database-by-uuid
|
||||||
|
parameters:
|
||||||
|
-
|
||||||
|
name: uuid
|
||||||
|
in: path
|
||||||
|
description: 'UUID of the database.'
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: 'Target environment to move the database to.'
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- environment_uuid
|
||||||
|
properties:
|
||||||
|
environment_uuid:
|
||||||
|
type: string
|
||||||
|
description: 'UUID of the target environment.'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: 'Database moved successfully.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
message: { type: string, example: 'Database moved successfully.' }
|
||||||
|
uuid: { type: string }
|
||||||
|
project_uuid: { type: string }
|
||||||
|
environment_uuid: { type: string }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
'422':
|
||||||
|
$ref: '#/components/responses/422'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
'/databases/{uuid}/start':
|
'/databases/{uuid}/start':
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
@ -8232,6 +8334,57 @@ paths:
|
||||||
security:
|
security:
|
||||||
-
|
-
|
||||||
bearerAuth: []
|
bearerAuth: []
|
||||||
|
'/services/{uuid}/move':
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Services
|
||||||
|
summary: Move
|
||||||
|
description: 'Move service to another project/environment. This is a purely organizational change — running containers are not affected. Note: after moving, the service will pick up shared environment variables from the new environment on the next deployment.'
|
||||||
|
operationId: move-service-by-uuid
|
||||||
|
parameters:
|
||||||
|
-
|
||||||
|
name: uuid
|
||||||
|
in: path
|
||||||
|
description: 'UUID of the service.'
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: 'Target environment to move the service to.'
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
required:
|
||||||
|
- environment_uuid
|
||||||
|
properties:
|
||||||
|
environment_uuid:
|
||||||
|
type: string
|
||||||
|
description: 'UUID of the target environment.'
|
||||||
|
type: object
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: 'Service moved successfully.'
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
properties:
|
||||||
|
message: { type: string, example: 'Service moved successfully.' }
|
||||||
|
uuid: { type: string }
|
||||||
|
project_uuid: { type: string }
|
||||||
|
environment_uuid: { type: string }
|
||||||
|
type: object
|
||||||
|
'401':
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/400'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/404'
|
||||||
|
'422':
|
||||||
|
$ref: '#/components/responses/422'
|
||||||
|
security:
|
||||||
|
-
|
||||||
|
bearerAuth: []
|
||||||
'/services/{uuid}/start':
|
'/services/{uuid}/start':
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\Environment;
|
use App\Models\Environment;
|
||||||
|
use App\Models\EnvironmentVariable;
|
||||||
use App\Models\InstanceSettings;
|
use App\Models\InstanceSettings;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
|
@ -10,7 +11,9 @@
|
||||||
use App\Models\StandalonePostgresql;
|
use App\Models\StandalonePostgresql;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
|
||||||
uses(RefreshDatabase::class);
|
uses(RefreshDatabase::class);
|
||||||
|
|
@ -124,7 +127,9 @@
|
||||||
$response->assertStatus(404);
|
$response->assertStatus(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('returns 403 when target environment update is denied', function () {
|
test('authorizes the target environment before moving', function () {
|
||||||
|
$this->actingAs($this->user);
|
||||||
|
|
||||||
$application = Application::factory()->create([
|
$application = Application::factory()->create([
|
||||||
'environment_id' => $this->environment->id,
|
'environment_id' => $this->environment->id,
|
||||||
'destination_id' => $this->destination->id,
|
'destination_id' => $this->destination->id,
|
||||||
|
|
@ -141,14 +146,12 @@
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$request = Request::create('/', 'POST', [
|
||||||
'Authorization' => 'Bearer '.$this->bearerToken,
|
|
||||||
'Content-Type' => 'application/json',
|
|
||||||
])->postJson("/api/v1/applications/{$application->uuid}/move", [
|
|
||||||
'environment_uuid' => $this->targetEnvironment->uuid,
|
'environment_uuid' => $this->targetEnvironment->uuid,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response->assertForbidden();
|
expect(fn () => moveResourceToEnvironment($request, $application, 'Application', $this->team->id))
|
||||||
|
->toThrow(AuthorizationException::class);
|
||||||
|
|
||||||
$application->refresh();
|
$application->refresh();
|
||||||
expect($application->environment_id)->toBe($this->environment->id);
|
expect($application->environment_id)->toBe($this->environment->id);
|
||||||
|
|
@ -178,7 +181,7 @@
|
||||||
'destination_type' => $this->destination->getMorphClass(),
|
'destination_type' => $this->destination->getMorphClass(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
\App\Models\EnvironmentVariable::create([
|
EnvironmentVariable::create([
|
||||||
'key' => 'TEST_VAR',
|
'key' => 'TEST_VAR',
|
||||||
'value' => 'test-value',
|
'value' => 'test-value',
|
||||||
'resourceable_type' => Application::class,
|
'resourceable_type' => Application::class,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue