fix(docs): comment out execute for now

- Due to security concerns, execute is disabled, so we need to comment out the code as well to update the docs.
This commit is contained in:
peaklabs-dev
2025-04-01 20:57:20 +02:00
parent c6b7779c82
commit 1384de7566
3 changed files with 184 additions and 304 deletions

View File

@@ -2881,198 +2881,198 @@ class ApplicationsController extends Controller
); );
} }
#[OA\Post( // #[OA\Post(
summary: 'Execute Command', // summary: 'Execute Command',
description: "Execute a command on the application's current container.", // description: "Execute a command on the application's current container.",
path: '/applications/{uuid}/execute', // path: '/applications/{uuid}/execute',
operationId: 'execute-command-application', // operationId: 'execute-command-application',
security: [ // security: [
['bearerAuth' => []], // ['bearerAuth' => []],
], // ],
tags: ['Applications'], // tags: ['Applications'],
parameters: [ // parameters: [
new OA\Parameter( // new OA\Parameter(
name: 'uuid', // name: 'uuid',
in: 'path', // in: 'path',
description: 'UUID of the application.', // description: 'UUID of the application.',
required: true, // required: true,
schema: new OA\Schema( // schema: new OA\Schema(
type: 'string', // type: 'string',
format: 'uuid', // format: 'uuid',
) // )
), // ),
], // ],
requestBody: new OA\RequestBody( // requestBody: new OA\RequestBody(
required: true, // required: true,
description: 'Command to execute.', // description: 'Command to execute.',
content: new OA\MediaType( // content: new OA\MediaType(
mediaType: 'application/json', // mediaType: 'application/json',
schema: new OA\Schema( // schema: new OA\Schema(
type: 'object', // type: 'object',
properties: [ // properties: [
'command' => ['type' => 'string', 'description' => 'Command to execute.'], // 'command' => ['type' => 'string', 'description' => 'Command to execute.'],
], // ],
), // ),
), // ),
), // ),
responses: [ // responses: [
new OA\Response( // new OA\Response(
response: 200, // response: 200,
description: "Execute a command on the application's current container.", // description: "Execute a command on the application's current container.",
content: [ // content: [
new OA\MediaType( // new OA\MediaType(
mediaType: 'application/json', // mediaType: 'application/json',
schema: new OA\Schema( // schema: new OA\Schema(
type: 'object', // type: 'object',
properties: [ // properties: [
'message' => ['type' => 'string', 'example' => 'Command executed.'], // 'message' => ['type' => 'string', 'example' => 'Command executed.'],
'response' => ['type' => 'string'], // 'response' => ['type' => 'string'],
] // ]
) // )
), // ),
] // ]
), // ),
new OA\Response( // new OA\Response(
response: 401, // response: 401,
ref: '#/components/responses/401', // ref: '#/components/responses/401',
), // ),
new OA\Response( // new OA\Response(
response: 400, // response: 400,
ref: '#/components/responses/400', // ref: '#/components/responses/400',
), // ),
new OA\Response( // new OA\Response(
response: 404, // response: 404,
ref: '#/components/responses/404', // ref: '#/components/responses/404',
), // ),
] // ]
)] // )]
public function execute_command_by_uuid(Request $request) // public function execute_command_by_uuid(Request $request)
{ // {
// TODO: Need to review this from security perspective, to not allow arbitrary command execution // // TODO: Need to review this from security perspective, to not allow arbitrary command execution
$allowedFields = ['command']; // $allowedFields = ['command'];
$teamId = getTeamIdFromToken(); // $teamId = getTeamIdFromToken();
if (is_null($teamId)) { // if (is_null($teamId)) {
return invalidTokenResponse(); // return invalidTokenResponse();
} // }
$uuid = $request->route('uuid'); // $uuid = $request->route('uuid');
if (! $uuid) { // if (! $uuid) {
return response()->json(['message' => 'UUID is required.'], 400); // return response()->json(['message' => 'UUID is required.'], 400);
} // }
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first(); // $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
if (! $application) { // if (! $application) {
return response()->json(['message' => 'Application not found.'], 404); // return response()->json(['message' => 'Application not found.'], 404);
} // }
$return = validateIncomingRequest($request); // $return = validateIncomingRequest($request);
if ($return instanceof \Illuminate\Http\JsonResponse) { // if ($return instanceof \Illuminate\Http\JsonResponse) {
return $return; // return $return;
} // }
$validator = customApiValidator($request->all(), [ // $validator = customApiValidator($request->all(), [
'command' => 'string|required', // 'command' => 'string|required',
]); // ]);
$extraFields = array_diff(array_keys($request->all()), $allowedFields); // $extraFields = array_diff(array_keys($request->all()), $allowedFields);
if ($validator->fails() || ! empty($extraFields)) { // if ($validator->fails() || ! empty($extraFields)) {
$errors = $validator->errors(); // $errors = $validator->errors();
if (! empty($extraFields)) { // if (! empty($extraFields)) {
foreach ($extraFields as $field) { // foreach ($extraFields as $field) {
$errors->add($field, 'This field is not allowed.'); // $errors->add($field, 'This field is not allowed.');
} // }
} // }
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => $errors, // 'errors' => $errors,
], 422); // ], 422);
} // }
$container = getCurrentApplicationContainerStatus($application->destination->server, $application->id)->firstOrFail(); // $container = getCurrentApplicationContainerStatus($application->destination->server, $application->id)->firstOrFail();
$status = getContainerStatus($application->destination->server, $container['Names']); // $status = getContainerStatus($application->destination->server, $container['Names']);
if ($status !== 'running') { // if ($status !== 'running') {
return response()->json([ // return response()->json([
'message' => 'Application is not running.', // 'message' => 'Application is not running.',
], 400); // ], 400);
} // }
$commands = collect([ // $commands = collect([
executeInDocker($container['Names'], $request->command), // executeInDocker($container['Names'], $request->command),
]); // ]);
$res = instant_remote_process(command: $commands, server: $application->destination->server); // $res = instant_remote_process(command: $commands, server: $application->destination->server);
return response()->json([ // return response()->json([
'message' => 'Command executed.', // 'message' => 'Command executed.',
'response' => $res, // 'response' => $res,
]); // ]);
} // }
private function validateDataApplications(Request $request, Server $server) // private function validateDataApplications(Request $request, Server $server)
{ // {
$teamId = getTeamIdFromToken(); // $teamId = getTeamIdFromToken();
// Validate ports_mappings // // Validate ports_mappings
if ($request->has('ports_mappings')) { // if ($request->has('ports_mappings')) {
$ports = []; // $ports = [];
foreach (explode(',', $request->ports_mappings) as $portMapping) { // foreach (explode(',', $request->ports_mappings) as $portMapping) {
$port = explode(':', $portMapping); // $port = explode(':', $portMapping);
if (in_array($port[0], $ports)) { // if (in_array($port[0], $ports)) {
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => [ // 'errors' => [
'ports_mappings' => 'The first number before : should be unique between mappings.', // 'ports_mappings' => 'The first number before : should be unique between mappings.',
], // ],
], 422); // ], 422);
} // }
$ports[] = $port[0]; // $ports[] = $port[0];
} // }
} // }
// Validate custom_labels // // Validate custom_labels
if ($request->has('custom_labels')) { // if ($request->has('custom_labels')) {
if (! isBase64Encoded($request->custom_labels)) { // if (! isBase64Encoded($request->custom_labels)) {
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => [ // 'errors' => [
'custom_labels' => 'The custom_labels should be base64 encoded.', // 'custom_labels' => 'The custom_labels should be base64 encoded.',
], // ],
], 422); // ], 422);
} // }
$customLabels = base64_decode($request->custom_labels); // $customLabels = base64_decode($request->custom_labels);
if (mb_detect_encoding($customLabels, 'ASCII', true) === false) { // if (mb_detect_encoding($customLabels, 'ASCII', true) === false) {
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => [ // 'errors' => [
'custom_labels' => 'The custom_labels should be base64 encoded.', // 'custom_labels' => 'The custom_labels should be base64 encoded.',
], // ],
], 422); // ], 422);
} // }
} // }
if ($request->has('domains') && $server->isProxyShouldRun()) { // if ($request->has('domains') && $server->isProxyShouldRun()) {
$uuid = $request->uuid; // $uuid = $request->uuid;
$fqdn = $request->domains; // $fqdn = $request->domains;
$fqdn = str($fqdn)->replaceEnd(',', '')->trim(); // $fqdn = str($fqdn)->replaceEnd(',', '')->trim();
$fqdn = str($fqdn)->replaceStart(',', '')->trim(); // $fqdn = str($fqdn)->replaceStart(',', '')->trim();
$errors = []; // $errors = [];
$fqdn = str($fqdn)->trim()->explode(',')->map(function ($domain) use (&$errors) { // $fqdn = str($fqdn)->trim()->explode(',')->map(function ($domain) use (&$errors) {
if (filter_var($domain, FILTER_VALIDATE_URL) === false) { // if (filter_var($domain, FILTER_VALIDATE_URL) === false) {
$errors[] = 'Invalid domain: '.$domain; // $errors[] = 'Invalid domain: '.$domain;
} // }
return str($domain)->trim()->lower(); // return str($domain)->trim()->lower();
}); // });
if (count($errors) > 0) { // if (count($errors) > 0) {
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => $errors, // 'errors' => $errors,
], 422); // ], 422);
} // }
if (checkIfDomainIsAlreadyUsed($fqdn, $teamId, $uuid)) { // if (checkIfDomainIsAlreadyUsed($fqdn, $teamId, $uuid)) {
return response()->json([ // return response()->json([
'message' => 'Validation failed.', // 'message' => 'Validation failed.',
'errors' => [ // 'errors' => [
'domains' => 'One of the domain is already used.', // 'domains' => 'One of the domain is already used.',
], // ],
], 422); // ], 422);
} // }
} // }
} // }
} }

View File

@@ -2771,80 +2771,6 @@
] ]
} }
}, },
"\/applications\/{uuid}\/execute": {
"post": {
"tags": [
"Applications"
],
"summary": "Execute Command",
"description": "Execute a command on the application's current container.",
"operationId": "execute-command-application",
"parameters": [
{
"name": "uuid",
"in": "path",
"description": "UUID of the application.",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"description": "Command to execute.",
"required": true,
"content": {
"application\/json": {
"schema": {
"properties": {
"command": {
"type": "string",
"description": "Command to execute."
}
},
"type": "object"
}
}
}
},
"responses": {
"200": {
"description": "Execute a command on the application's current container.",
"content": {
"application\/json": {
"schema": {
"properties": {
"message": {
"type": "string",
"example": "Command executed."
},
"response": {
"type": "string"
}
},
"type": "object"
}
}
}
},
"401": {
"$ref": "#\/components\/responses\/401"
},
"400": {
"$ref": "#\/components\/responses\/400"
},
"404": {
"$ref": "#\/components\/responses\/404"
}
},
"security": [
{
"bearerAuth": []
}
]
}
},
"\/databases": { "\/databases": {
"get": { "get": {
"tags": [ "tags": [

View File

@@ -1905,52 +1905,6 @@ paths:
security: security:
- -
bearerAuth: [] bearerAuth: []
'/applications/{uuid}/execute':
post:
tags:
- Applications
summary: 'Execute Command'
description: "Execute a command on the application's current container."
operationId: execute-command-application
parameters:
-
name: uuid
in: path
description: 'UUID of the application.'
required: true
schema:
type: string
format: uuid
requestBody:
description: 'Command to execute.'
required: true
content:
application/json:
schema:
properties:
command:
type: string
description: 'Command to execute.'
type: object
responses:
'200':
description: "Execute a command on the application's current container."
content:
application/json:
schema:
properties:
message: { type: string, example: 'Command executed.' }
response: { type: string }
type: object
'401':
$ref: '#/components/responses/401'
'400':
$ref: '#/components/responses/400'
'404':
$ref: '#/components/responses/404'
security:
-
bearerAuth: []
/databases: /databases:
get: get:
tags: tags: