0cb24b4759
access.xml: 12 component-specific actions added: - mokosuitecross.crosspost (auto cross-post on publish) - mokosuitecross.crosspost.manual (manually create posts) - mokosuitecross.delete.remote (delete from remote platforms) - mokosuitecross.services.manage (create/edit/delete services) - mokosuitecross.services.credentials (view decrypted credentials) - mokosuitecross.templates.manage (create/edit/delete templates) - mokosuitecross.logs.view (view activity logs) - mokosuitecross.logs.purge (purge old logs) - mokosuitecross.queue.manage (manage post queue) - mokosuitecross.queue.export (export posts as CSV) - mokosuitecross.dispatch (trigger REST API dispatch) - mokosuitecross.migrate (run Perfect Publisher migration) config.xml: permissions fieldset with rules field for admin UI. Enforcement: - DisplayController: core.manage gate on all views - ServicesController: publish/delete ACL checks - TemplatesController: publish/delete ACL checks - PostsController: queue.export permission - ServiceController: services.manage for test connection - DispatchController: dispatch permission for REST API - All list views: preferences button gated by core.admin - All edit views: save/apply buttons gated by section permission - MokoSuiteCrossHelper::getActions() centralizes ACL lookups
105 lines
3.5 KiB
PHP
105 lines
3.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @package MokoSuiteCross
|
|
* @subpackage com_mokosuitecross
|
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
|
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
|
* @license GNU General Public License version 3 or later; see LICENSE
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
namespace Joomla\Component\MokoSuiteCross\Administrator\Controller;
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\Language\Text;
|
|
use Joomla\CMS\MVC\Controller\FormController;
|
|
use Joomla\CMS\Plugin\PluginHelper;
|
|
use Joomla\CMS\Response\JsonResponse;
|
|
use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface;
|
|
|
|
class ServiceController extends FormController
|
|
{
|
|
/**
|
|
* Test connection to a service by validating its credentials.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function testConnection(): void
|
|
{
|
|
$this->checkToken();
|
|
|
|
if (!$this->app->getIdentity()->authorise('mokosuitecross.services.manage', 'com_mokosuitecross')) {
|
|
throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403);
|
|
}
|
|
|
|
$app = $this->app;
|
|
$id = (int) $this->input->getInt('id', 0);
|
|
|
|
try {
|
|
if ($id <= 0) {
|
|
throw new \RuntimeException(Text::_('COM_MOKOSUITECROSS_TEST_CONNECTION_NO_SERVICE'));
|
|
}
|
|
|
|
// Load the service record
|
|
$db = Factory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select('*')
|
|
->from($db->quoteName('#__mokosuitecross_services'))
|
|
->where($db->quoteName('id') . ' = ' . $id);
|
|
$db->setQuery($query);
|
|
$service = $db->loadObject();
|
|
|
|
if (!$service) {
|
|
throw new \RuntimeException(Text::_('COM_MOKOSUITECROSS_TEST_CONNECTION_NOT_FOUND'));
|
|
}
|
|
|
|
// Get service plugins via dispatcher (Joomla 5+ Event ArrayAccess pattern)
|
|
PluginHelper::importPlugin('mokosuitecross');
|
|
|
|
$servicePlugins = [];
|
|
$event = new \Joomla\Event\Event('onMokoSuiteCrossGetServices', [$servicePlugins]);
|
|
$app->getDispatcher()->dispatch('onMokoSuiteCrossGetServices', $event);
|
|
|
|
$idx = 1;
|
|
|
|
while (isset($event[$idx])) {
|
|
$servicePlugins[] = $event[$idx];
|
|
$idx++;
|
|
}
|
|
|
|
// Find the matching plugin
|
|
$plugin = null;
|
|
|
|
foreach ($servicePlugins as $sp) {
|
|
if ($sp instanceof MokoSuiteCrossServiceInterface && $sp->getServiceType() === $service->service_type) {
|
|
$plugin = $sp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$plugin) {
|
|
throw new \RuntimeException(Text::sprintf('COM_MOKOSUITECROSS_TEST_CONNECTION_NO_PLUGIN', $service->service_type));
|
|
}
|
|
|
|
// Decode credentials and validate
|
|
$credentials = \Joomla\Component\MokoSuiteCross\Administrator\Helper\CredentialHelper::decrypt($service->credentials ?: '');
|
|
$result = $plugin->validateCredentials($credentials);
|
|
|
|
$app->mimeType = 'application/json';
|
|
$app->setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
|
|
echo new JsonResponse($result);
|
|
} catch (\Throwable $e) {
|
|
$app->mimeType = 'application/json';
|
|
$app->setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
|
|
echo new JsonResponse(['error' => $e->getMessage()]);
|
|
}
|
|
|
|
$app->close();
|
|
}
|
|
}
|