Commit 32c87665 authored by Matthias Adrowski's avatar Matthias Adrowski
Browse files

[FEATURE] Add FQN to called Controller and skip deprecated paths

Since TYPO3 moved on to add ControllerFQN::class => action mappings,
we should add atleast one of the requirements. for the actions we could
add it on request as before, but without using switchable controllers.
in my testing this did not get cached away. Also fixed BearerToekn
calling
parent b00d6d14
......@@ -172,6 +172,15 @@ abstract class AbstractRestMiddleware implements LoggerAwareInterface, Middlewar
);
}
/**
*
* @return string
* @throws Exception
*/
protected function getActionName(): string {
return $this->pathSegments['verb'];
}
/**
* @param $data
* @param int $statusCode
......
......@@ -97,11 +97,12 @@ class RestAuthenticator extends AbstractRestMiddleware {
$httpMethod = $request->getMethod();
$actionName = $this->getCallableActionName($httpMethod);
$pureActionName = $this->getActionName();
/**
* when the client requests a bearer token, we don't need to do access checks etc. the user verification is done by the AuthServices
*/
if (!($this->pathSegments['entity'] === 'authentication' && $actionName === 'getbearertoken' && $httpMethod === 'POST')) {
if (!($this->pathSegments['entity'] === 'authentication' && $pureActionName === 'getbearertoken' && $httpMethod === 'POST')) {
$authenticated = $this->authenticationService->verifyRequest($this->requestHeaders);
......
......@@ -93,8 +93,13 @@ class RestDispatcher extends AbstractRestMiddleware {
$extensionName = $this->accessGroup['extensionName'];
$className = $this->getClassName();
$controllerName = $this->getControllerName();
$httpMethod = $request->getMethod();
$actionName = $this->getCallableActionName($httpMethod);
$pureActionName = $this->getActionName();
if($pureActionName === 'getbearertoken'){
$actionName = 'getBearerToken';
}
/** @var DataResolveService $dataResolveService */
$dataResolveService = GeneralUtility::makeInstance(DataResolveService::class);
......@@ -122,14 +127,12 @@ class RestDispatcher extends AbstractRestMiddleware {
*/
$typoscriptPluginConfiguration = 'sgRest.10.extensionName=' . $extensionName . PHP_EOL
. 'sgRest.10.vendorName=' . $vendorName . PHP_EOL
. 'sgRest.10.controller=' . $className . PHP_EOL
. 'sgRest.10.controller=' . $controllerName . PHP_EOL
. 'sgRest.10.action=' . $actionName . PHP_EOL
. 'sgRest.10.pluginName=Rest' . $apiKey . PHP_EOL
. 'sgRest.10.switchableControllerActions {' . PHP_EOL
. ' ' . $className . ' { ' . PHP_EOL
. ' ' . $className . ' = ' . $actionName . PHP_EOL
. ' }' . PHP_EOL
. '}' . PHP_EOL;
. 'sgRest.10.pluginName=Rest' . $apiKey . PHP_EOL;
# Set Action Name in $GLOBALS, will be read from \TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager::getControllerConfiguration
# to determin currently allowed Controller::Actions
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins']['Rest' . $apiKey]['controllers'][$className]['actions'][0] = $actionName;
ExtensionManagementUtility::addTypoScriptSetup($typoscriptPluginConfiguration);
$pluginNamespace = 'tx_' . strtolower($extensionName) . '_rest';
......@@ -150,13 +153,22 @@ class RestDispatcher extends AbstractRestMiddleware {
}
}
$queryParams[$pluginNamespace]['controller'] = $className;
$queryParams[$pluginNamespace]['controller'] = $controllerName;
$queryParams[$pluginNamespace]['action'] = $actionName;
$queryParams[$pluginNamespace]['format'] = $format;
$queryParams[$pluginNamespace]['extensionName'] = $extensionName;
$queryParams[$pluginNamespace]['extension'] = $extensionName;
$queryParams[$pluginNamespace]['vendor'] = $vendorName;
$queryParams[$pluginNamespace]['vendorName'] = $vendorName;
# Add both cases, with and without apiKey, since we seem to have inconsistencies
# with ususal and bearerToken alls
$queryParams[$pluginNamespace.$apiKey]['controller'] = $controllerName;
$queryParams[$pluginNamespace.$apiKey]['action'] = $actionName;
$queryParams[$pluginNamespace.$apiKey]['format'] = $format;
$queryParams[$pluginNamespace.$apiKey]['extensionName'] = $extensionName;
$queryParams[$pluginNamespace.$apiKey]['extension'] = $extensionName;
$queryParams[$pluginNamespace.$apiKey]['vendor'] = $vendorName;
$queryParams[$pluginNamespace.$apiKey]['vendorName'] = $vendorName;
if ($identifier) {
$queryParams[$pluginNamespace . $apiKey]['identifier'] = $identifier;
......
......@@ -79,7 +79,8 @@ class RegistrationService implements SingletonInterface {
$accessGroup['entities'][$entity] = [
'write' => $writeFields,
'read' => array_merge($writeFields, $readFields),
'httpPermissions' => $this->getHttpPermissionsConfiguration($entityConfiguration)
'httpPermissions' => $this->getHttpPermissionsConfiguration($entityConfiguration),
'classFQN' => $entityConfiguration['classFQN']
];
}
......@@ -117,18 +118,17 @@ class RegistrationService implements SingletonInterface {
protected function configurePluginForAccessGroup($apiKey): void {
$accessGroup = $this->getAccessGroupByApiKey($apiKey);
$vendorName = $accessGroup['vendorName'];
$extensionName = $accessGroup['extensionName'];
$controller = [];
foreach ($accessGroup['entities'] as $entity => $configuration) {
$controllerName = 'Rest\\' . ucfirst($apiKey) . '\\' . ucfirst($entity);
$controllerName = $configuration['classFQN'];
$controller[$controllerName] = '';
}
ExtensionUtility::configurePlugin(
'Service', 'Rest' . $apiKey, $controller, $controller
$extensionName, 'Rest' . $apiKey, $controller, $controller
);
}
......
......@@ -6,4 +6,5 @@ services:
SGalinski\SgRest\:
resource: '../Classes/*'
SGalinski\SgRest\Service\Authentication\AuthenticationServiceInterface: '@SGalinski\SgRest\Service\Authentication\BearerAuthenticationService'
# SGalinski\SgRest\Service\Authentication\AuthenticationServiceInterface: '@SGalinski\SgRest\Service\Authentication\BearerAuthenticationService'
SGalinski\SgRest\Service\Authentication\AuthenticationServiceInterface: '@SGalinski\SgRest\Service\Authentication\BasicAuthenticationService'
......@@ -178,6 +178,7 @@ $restRegistrationService->registerAccessGroup(
<accessGroupName>, // Example: "News" It's the name of the api, which is shown in the user TCA. See: "REST Authentication"
[
<entityName> => [ // Example: "news"
'classFQN' => Vendor\ExtensionName\Controller\Rest\<apiKeyWithCamelcase>\<entityNameWithCamelcase>Controller::class,
'read' => 'uid, title' // This allows that the API can read the fields "uid" and "title" from the entity "news",
'httpPermissions' => [
'deleteForVerbs' => TRUE,
......
......@@ -26,3 +26,23 @@ NEW:
```apacheconf
RewriteRule ^api/v1/(.*) /index.php?type=1595576052&tx_sgrest[request]=$1 [QSA]
```
## Version 5 Breaking Changes:
Instead of using an entity name for Plugin registration, we will use the corresponding
controller for registration, which will be added under classFQN key inside the Entity Configuration:
```php
$restRegistrationService->registerAccessGroup(
'authentication',
'SGalinski.sg_rest',
'Authentication',
[
'authentication' => [
// Add THIS
'classFQN' => \SGalinski\SgRest\Controller\Rest\Authentication\AuthenticationController::class,
'read' => 'uid, title'
]
]
);
```
......@@ -55,6 +55,7 @@ call_user_func(
'Authentication',
[
'authentication' => [
'classFQN' => \SGalinski\SgRest\Controller\Rest\Authentication\AuthenticationController::class,
'read' => 'uid, title'
]
]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment