Skip to content

Commit 2f7ab45

Browse files
committed
Finish integration into Neos, provider wrapper script
0 parents  commit 2f7ab45

12 files changed

Lines changed: 245 additions & 0 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
namespace Flowpack\Prunner\Controller;
3+
4+
use Neos\Flow\Annotations as Flow;
5+
6+
class BackendController extends \Neos\Flow\Mvc\Controller\ActionController
7+
{
8+
9+
public function indexAction()
10+
{
11+
12+
}
13+
14+
public function frameAction()
15+
{
16+
17+
}
18+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
namespace Flowpack\Prunner\Controller;
3+
4+
use Firebase\JWT\JWT;
5+
use GuzzleHttp\Client;
6+
use Neos\Flow\Annotations as Flow;
7+
use Symfony\Component\Yaml\Exception\ParseException;
8+
use Symfony\Component\Yaml\Yaml;
9+
10+
class ProxyController extends \Neos\Flow\Mvc\Controller\ActionController
11+
{
12+
13+
/**
14+
* @Flow\InjectConfiguration(path="apiBaseUrl")
15+
* @var string
16+
*/
17+
protected $apiBaseUrl;
18+
19+
/**
20+
* @Flow\InjectConfiguration(path="directory")
21+
* @var string
22+
*/
23+
protected $directory;
24+
25+
/**
26+
* @Flow\InjectConfiguration(path="jwtSecret")
27+
* @var string
28+
*/
29+
protected $jwtSecret;
30+
31+
/**
32+
* @Flow\Inject
33+
* @var \Neos\Flow\Security\Context
34+
*/
35+
protected $context;
36+
37+
public function indexAction(string $path, string $subpath)
38+
{
39+
// Simple workaround to have slashes in route parts...
40+
$apiPath = $path;
41+
if ($subpath !== '') {
42+
$apiPath .= '/' . $subpath;
43+
}
44+
$url = rtrim($this->apiBaseUrl, '/') . '/' . $apiPath;
45+
46+
// Create JWT token for user
47+
48+
if (!empty($this->jwtSecret)) {
49+
$jwtSecret = $this->jwtSecret;
50+
} else {
51+
try {
52+
// Try to parse prunner config to get JWT secret
53+
$config = Yaml::parseFile($this->directory . '/.prunner.yml');
54+
$jwtSecret = $config['jwt_secret'];
55+
} catch (ParseException $e) {
56+
$this->response->setContentType('application/json');
57+
$this->response->setStatusCode(500);
58+
return json_encode(['error' => 'Invalid prunner configuration']);
59+
}
60+
}
61+
62+
$accountIdentifier = $this->context->getAccount()->getAccountIdentifier();
63+
64+
// Generate JWT token on the fly with expiration in 60 seconds
65+
$authToken = JWT::encode([
66+
'sub' => $accountIdentifier,
67+
'exp' => time() + 60
68+
], $jwtSecret, 'HS256');
69+
70+
$client = new Client();
71+
$response = $client->request($this->request->getHttpRequest()->getMethod(), $url, [
72+
'headers' => [
73+
'Authorization' => 'Bearer ' . $authToken
74+
],
75+
'body' => $this->request->getHttpRequest()->getBody(),
76+
'http_errors' => false
77+
]);
78+
79+
$this->response->setContentType('application/json');
80+
$this->response->setStatusCode($response->getStatusCode());
81+
82+
return $response->getBody();
83+
}
84+
}

Configuration/Policy.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
privilegeTargets:
2+
'Neos\Neos\Security\Authorization\Privilege\ModulePrivilege':
3+
'Flowpack.Prunner:BackendModule':
4+
matcher: 'administration/prunner'
5+
6+
'Neos\Flow\Security\Authorization\Privilege\Method\MethodPrivilege':
7+
'Flowpack.Prunner:ApiProxy':
8+
label: Perform proxy requests to prunner API
9+
matcher: 'method(Flowpack\Prunner\Controller\ProxyController->indexAction())'
10+
11+
roles:
12+
'Neos.Neos:Administrator':
13+
privileges:
14+
-
15+
privilegeTarget: 'Flowpack.Prunner:BackendModule'
16+
permission: GRANT
17+
-
18+
privilegeTarget: 'Flowpack.Prunner:ApiProxy'
19+
permission: GRANT

Configuration/Routes.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-
2+
name: 'Prunner Frame'
3+
uriPattern: 'neos/prunner/frame'
4+
defaults:
5+
'@package': 'Flowpack.Prunner'
6+
'@controller': 'Backend'
7+
'@format': 'html'
8+
'@action': 'frame'
9+
appendExceedingArguments: true
10+
11+
-
12+
name: 'Prunner API Proxy'
13+
uriPattern: 'neos/prunner/proxy/{path}(/{subpath})'
14+
defaults:
15+
'@package': 'Flowpack.Prunner'
16+
'@controller': 'Proxy'
17+
'@format': 'json'
18+
'@action': 'index'
19+
subpath: ''
20+
appendExceedingArguments: true

Configuration/Settings.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Flowpack:
2+
Prunner:
3+
# Base URL to prunner API
4+
apiBaseUrl: 'http://localhost:9009/'
5+
# Working directory of prunner for loading config
6+
directory: '%FLOW_PATH_ROOT%'
7+
# Explicitly set JWT secret if prunner config is not accessible
8+
jwtSecret: ~
9+
10+
Neos:
11+
Neos:
12+
modules:
13+
'administration':
14+
submodules:
15+
'prunner':
16+
label: 'Prunner'
17+
controller: 'Flowpack\Prunner\Controller\BackendController'
18+
description: 'Run custom pipelines with tasks'
19+
icon: 'fas fa-exchange'
20+
21+
Flow:
22+
security:
23+
authentication:
24+
providers:
25+
'Neos.Neos:Backend':
26+
requestPatterns:
27+
'Flowpack.Prunner:Controllers':
28+
pattern: 'ControllerObjectName'
29+
patternOptions:
30+
controllerObjectNamePattern: 'Flowpack\Prunner\Controller\.*'
31+
mvc:
32+
routes:
33+
'Flowpack.Prunner':
34+
position: 'before Neos.Neos'

Resources/Private/Scripts/prunner

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
3+
SCRIPTS_DIR=$(dirname "$(realpath $0)")
4+
5+
OS_TYPE=$(uname -s)
6+
ARCH_TYPE=$(uname -m)
7+
8+
# Make a very simple check if we have a bundled binary for the right OS / architecture
9+
BIN_TARGET="$SCRIPTS_DIR/../Bin/$OS_TYPE/$ARCH_TYPE/prunner"
10+
11+
if [ -f "$BIN_TARGET" ]; then
12+
$BIN_TARGET
13+
else
14+
echo "Unsupported OS or architecture"
15+
exit 1
16+
fi
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div data-component="PrunnerUi" data-prop-api-base-url="/neos/prunner/proxy/" data-prop-extra-api-headers="{f:format.json(value: {X-Flow-Csrftoken: '{f:security.csrfToken()}'})}"></div>
2+
<script src="{f:uri.resource(path: 'resource://Flowpack.Prunner/Public/prunner-ui/index.js')}"></script>
3+
<link rel="stylesheet" type="text/css" href="{f:uri.resource(path: 'resource://Flowpack.Prunner/Public/prunner-ui/index.css')}" />
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{namespace neos=Neos\Neos\ViewHelpers}
2+
<div class="neos-content neos-container-fluid" style="height: calc(100vh - 200px)">
3+
<iframe src="/neos/prunner/frame" width="100%" height="100%"></iframe>
4+
</div>

Resources/Public/prunner-ui/index.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Resources/Public/prunner-ui/index.js

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)