Skip to content

Commit

Permalink
Merge pull request #5 from slovensko-digital/bugfix/response-headers
Browse files Browse the repository at this point in the history
fix configuration attlasian + fix cross headers
  • Loading branch information
DominikBohucak authored Oct 1, 2023
2 parents 3eb9222 + d15d074 commit b6ab3d4
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 126 deletions.
76 changes: 56 additions & 20 deletions application/public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

$app = AppFactory::create();


// Add Error Handling Middleware
//$app->addErrorMiddleware(true, true, false);

function procesJsonRequest($request): Request
{
$contentType = $request->getHeaderLine('Content-Type');
Expand All @@ -26,26 +30,38 @@ function procesJsonRequest($request): Request
return $request;
}

function callAtlassian(HandlerInterface $handler, Request $request, Response $response): Response
{
$headers = [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Access-Control-Allow-Origin' => '*',
];
function callAtlassian(
HandlerInterface $handler,
Request $request,
Response $response,
$accept = 'application/json',
$contentType = 'application/json'
): Response {
$headers = [];
$headers["Access-Control-Allow-Origin"] = "*";
$headers['Access-Control-Allow-Methods'] = "*";
$headers['Access-Control-Allow-Headers'] = 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Recaptcha-Token,Recaptcha-Action';
$headers['Access-Control-Allow-Credentials'] = "true";
$headers['Access-Control-Max-Age'] = 86400;
$headers['Content-Type'] = $contentType;
$headers['Accept'] = $accept;

try {
$request = procesJsonRequest($request);
$response = $handler->handle($request);
return new \GuzzleHttp\Psr7\Response(
$response->getStatusCode(),
$headers,
$response->getBody()
$response->getBody()->getContents()
);
} catch (\Exception $e) {
$response = $response->withStatus(500);
$response->getBody()->write($e->getMessage());
return new \GuzzleHttp\Psr7\Response(
500,
$headers,
json_encode([
'error' => $e->getMessage()
])
);
}
return $response;
}

$app->get('/test/ping', function (Request $request, Response $response, $args) {
Expand All @@ -54,30 +70,50 @@ function callAtlassian(HandlerInterface $handler, Request $request, Response $re
return $response;
});

$app->get('/test/auth', function (Request $request, Response $response, $args) {
$app->post('/test/auth', function (Request $request, Response $response, $args) {
$handler = new TestAuthHandler();
return callAtlassian($handler, $request, $response);
return $handler->handle($request);
});

$app->options('/test/auth', function (Request $request, Response $response, $args) {
$handler = new TestAuthHandler();
return $handler->handle($request);
});

$app->post('/test/form', function (Request $request, Response $response, $args) {
$handler = new TestFormHandler();
return $handler->handle($request);
});

$app->options('/test/form', function (Request $request, Response $response, $args) {
$handler = new TestFormHandler();
return $handler->handle($request);
});

$app->get('/issue/search', function (Request $request, Response $response, $args) {
$handler = new GetIssueSearchHandler();
$request = procesJsonRequest($request);
return callAtlassian($handler, $request, $response);
});

$app->post('/issue/idea', function (Request $request, Response $response, $args) {
$handler = new SendIdeaHandler();
return callAtlassian($handler, $request, $response);
return callAtlassian($handler, $request, $response, 'multipart/form-data');
});

$app->options('/issue/idea', function (Request $request, Response $response, $args) {
$handler = new SendIdeaHandler();
return callAtlassian($handler, $request, $response, 'multipart/form-data');
});

$app->post('/issue/problem', function (Request $request, Response $response, $args) {
$handler = new SendProblemHandler();
return callAtlassian($handler, $request, $response);
return callAtlassian($handler, $request, $response, 'multipart/form-data');
});

$app->get('/issue', function (Request $request, Response $response, $args) {
$request = procesJsonRequest($request);
$response->getBody()->write("Hello world!");
return $response;
$app->options('/issue/problem', function (Request $request, Response $response, $args) {
$handler = new SendProblemHandler();
return callAtlassian($handler, $request, $response, 'multipart/form-data');
});

$app->run();
72 changes: 45 additions & 27 deletions application/src/Handler/AbstractHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,61 @@

namespace App\Handler;

use App\Service\AtlassianApiService;
use App\Traits\RecaptchaTrait;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\UploadedFile;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class AbstractHandler implements HandlerInterface
{
protected function validRecaptcha(?string $token, ?string $action) {
$secretKey = getenv('recaptcha_secret');

if (isset($_POST['email']) && $_POST['email']) {
$email = filter_var($_POST['email'], FILTER_SANITIZE_STRING);
} else {
// set error message and redirect back to form...
header('location: subscribe_newsletter_form.php');
exit;
}
use RecaptchaTrait;
protected AtlassianApiService $atlassianApi;

// call curl to POST request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' => $secretKey, 'response' => $token)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$arrResponse = json_decode($response, true);

// verify the response
if($arrResponse["success"] == '1' && $arrResponse["action"] == $action && $arrResponse["score"] >= 0.5) {
return true;
} else {
return false;
}
public function __construct()
{
$this->atlassianApi = new AtlassianApiService();
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
return new Response();
}
}

protected function getApiResponseHeaders(): array
{
$headers = [];

$headers["Access-Control-Allow-Origin"] = "*";
$headers['Access-Control-Allow-Methods'] = "*";
$headers['Access-Control-Allow-Headers'] = 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Recaptcha-Token,Recaptcha-Action';
$headers['Access-Control-Allow-Credentials'] = "true";
$headers['Access-Control-Max-Age'] = 86400;
$headers['Content-Type'] = 'application/json';
$headers['Accept'] = 'application/json';
return $headers;
}

public function getFilesFromRequest(ServerRequestInterface $request): array
{
$uploadedFiles = $request->getUploadedFiles();
$files = [];

/**
* @var UploadedFile $image
*/
foreach ($uploadedFiles as $image) {

if ($image->getError() === UPLOAD_ERR_OK) {
$file = [
"name" => 'file',
"contents" => (string)$image->getStream(),
'filename' => $image->getClientFilename(),
];
$files[] = $file;
}
}
return $files;
}
}
8 changes: 0 additions & 8 deletions application/src/Handler/GetIssueSearchHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,12 @@

namespace App\Handler;

use App\Service\AtlassianApiService;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class GetIssueSearchHandler extends AbstractHandler
{
private AtlassianApiService $atlassianApi;

public function __construct()
{
$this->atlassianApi = new AtlassianApiService();
}

/**
* @throws GuzzleException
*/
Expand Down
82 changes: 82 additions & 0 deletions application/src/Handler/IssueHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace App\Handler;

use App\Model\AtlassianIdeaModel;
use App\Service\AtlassianApiService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\UploadedFile;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class IssueHandler extends AbstractHandler
{
private string $issueClassName = AtlassianIdeaModel::class;

public function getFilesFromRequest(ServerRequestInterface $request): array
{
$uploadedFiles = $request->getUploadedFiles();
$files = [];

/**
* @var UploadedFile $image
*/
foreach ($uploadedFiles as $image) {

if ($image->getError() === UPLOAD_ERR_OK) {
$file = [
"name" => 'file',
"contents" => (string)$image->getStream(),
'filename' => $image->getClientFilename(),
];
$files[] = $file;
}
}
return $files;
}

public function addIssueAttachments(array $files, string $issueId): ?ResponseInterface
{
if (empty($files)) return null;
/* @var AtlassianApiService $attlasianApi */
$tempResponse = $this->atlassianApi->CreateAttachment($files);
$tempResponseData = json_decode($tempResponse->getBody()->getContents(), true);
$attachmentIds = [];
foreach ($tempResponseData['temporaryAttachments'] ?? [] as $attachment) {
$attachmentIds[] = $attachment['temporaryAttachmentId'];
}
return $this->atlassianApi->addIssueAttachments($issueId, $attachmentIds);
}


public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = $request->getParsedBody();
$token = $request->getHeader('Recaptcha-Token')[0] ?? null;
$action = $request->getHeader('Recaptcha-Action')[0] ?? null;

try {
if ($this->validRecaptcha($token, $action)) {
$issueData = new $this->issueClassName();
$issueData->fromArray($data);
$issueResponse = $this->atlassianApi->sendIssue($issueData);

$files = $this->getFilesFromRequest($request);
if ($issueResponse->getStatusCode() === 201 && !empty($files)) {
$issue = json_decode($issueResponse->getBody()->getContents(), true);
$this->addIssueAttachments($files, $issue['issueId']);
}

return $issueResponse;
}
} catch (Exception | GuzzleException $e) {
return new Response(401, [], json_encode([$e->getMessage()]));
}

return new Response(401, [], json_encode(['error' => 'DATA_INVALID']));
}
}
30 changes: 2 additions & 28 deletions application/src/Handler/SendIdeaHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,8 @@
namespace App\Handler;

use App\Model\AtlassianIdeaModel;
use App\Service\AtlassianApiService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

final class SendIdeaHandler extends AbstractHandler
final class SendIdeaHandler extends IssueHandler
{
private AtlassianApiService $atlassianApi;

public function __construct()
{
$this->atlassianApi = new AtlassianApiService();
}

/**
* @throws GuzzleException
* @throws Exception
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = $request->getParsedBody();
if ($this->validRecaptcha($data['token'] ?? null, $data['action'] ?? null)) {
$issueData = new AtlassianIdeaModel();
$issueData->fromArray($data);
return $this->atlassianApi->sendIssue($issueData);
}
return new Response(401, [], 'DATA_INVALID');
}
private string $issueClassName = AtlassianIdeaModel::class;
}
32 changes: 3 additions & 29 deletions application/src/Handler/SendProblemHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,8 @@
namespace App\Handler;

use App\Model\AtlassianProblemModel;
use App\Service\AtlassianApiService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

final class SendProblemHandler extends AbstractHandler
final class SendProblemHandler extends IssueHandler
{
private AtlassianApiService $atlassianApi;

public function __construct()
{
$this->atlassianApi = new AtlassianApiService();
}

/**
* @throws GuzzleException
* @throws Exception
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$data = $request->getParsedBody();
if ($this->validRecaptcha($data['token'] ?? null, $data['action'] ?? null)) {
$problemData = new AtlassianProblemModel();
$problemData->fromArray($data);
return $this->atlassianApi->sendIssue($problemData);
}
return new Response(401, [], 'DATA_INVALID');
}
}
private string $issueClassName = AtlassianProblemModel::class;
}
Loading

0 comments on commit b6ab3d4

Please sign in to comment.