primo commit

This commit is contained in:
2024-12-17 17:34:10 +01:00
commit e650f8df99
16435 changed files with 2451012 additions and 0 deletions

View File

@ -0,0 +1,96 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_privacy
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Privacy\Administrator\Controller;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\FormController;
use Joomla\CMS\Router\Route;
use Joomla\Component\Privacy\Administrator\Model\ConsentsModel;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Consents management controller class.
*
* @since 3.9.0
*/
class ConsentsController extends FormController
{
/**
* Method to invalidate specific consents.
*
* @return void
*
* @since 3.9.0
*/
public function invalidate()
{
// Check for request forgeries
$this->checkToken();
$ids = (array) $this->input->get('cid', [], 'int');
// Remove zero values resulting from input filter
$ids = array_filter($ids);
if (empty($ids)) {
$this->app->enqueueMessage(Text::_('JERROR_NO_ITEMS_SELECTED'), CMSApplication::MSG_ERROR);
} else {
/** @var ConsentsModel $model */
$model = $this->getModel();
if (!$model->invalidate($ids)) {
$this->setMessage($model->getError());
} else {
$this->setMessage(Text::plural('COM_PRIVACY_N_CONSENTS_INVALIDATED', \count($ids)));
}
}
$this->setRedirect(Route::_('index.php?option=com_privacy&view=consents', false));
}
/**
* Method to invalidate all consents of a specific subject.
*
* @return void
*
* @since 3.9.0
*/
public function invalidateAll()
{
// Check for request forgeries
$this->checkToken();
$filters = $this->input->get('filter', [], 'array');
$this->setRedirect(Route::_('index.php?option=com_privacy&view=consents', false));
if (isset($filters['subject']) && $filters['subject'] != '') {
$subject = $filters['subject'];
} else {
$this->app->enqueueMessage(Text::_('JERROR_NO_ITEMS_SELECTED'));
return;
}
/** @var ConsentsModel $model */
$model = $this->getModel();
if (!$model->invalidateAll($subject)) {
$this->setMessage($model->getError());
}
$this->setMessage(Text::_('COM_PRIVACY_CONSENTS_INVALIDATED_ALL'));
}
}

View File

@ -0,0 +1,124 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_privacy
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Privacy\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\Response\JsonResponse;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Session\Session;
use Joomla\Component\Privacy\Administrator\Model\RequestsModel;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Privacy Controller
*
* @since 3.9.0
*/
class DisplayController extends BaseController
{
/**
* The default view.
*
* @var string
* @since 3.9.0
*/
protected $default_view = 'requests';
/**
* Method to display a view.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe URL parameters and their variable types.
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
*
* @return $this
*
* @since 3.9.0
*/
public function display($cachable = false, $urlparams = [])
{
// Get the document object.
$document = $this->app->getDocument();
// Set the default view name and format from the Request.
$vName = $this->input->get('view', $this->default_view);
$vFormat = $document->getType();
$lName = $this->input->get('layout', 'default', 'string');
// Get and render the view.
if ($view = $this->getView($vName, $vFormat)) {
$model = $this->getModel($vName);
$view->setModel($model, true);
if ($vName === 'request') {
// For the default layout, we need to also push the action logs model into the view
if ($lName === 'default') {
$logsModel = $this->app->bootComponent('com_actionlogs')
->getMVCFactory()->createModel('Actionlogs', 'Administrator', ['ignore_request' => true]);
// Set default ordering for the context
$logsModel->setState('list.fullordering', 'a.log_date DESC');
// And push the model into the view
$view->setModel($logsModel, false);
}
// For the edit layout, if mail sending is disabled then redirect back to the list view as the form is unusable in this state
if ($lName === 'edit' && !$this->app->get('mailonline', 1)) {
$this->setRedirect(
Route::_('index.php?option=com_privacy&view=requests', false),
Text::_('COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'),
'warning'
);
return $this;
}
}
$view->setLayout($lName);
// Push document object into the view.
$view->document = $document;
$view->display();
}
return $this;
}
/**
* Fetch and report number urgent privacy requests in JSON format, for AJAX requests
*
* @return void
*
* @since 3.9.0
*/
public function getNumberUrgentRequests()
{
// Check for a valid token. If invalid, send a 403 with the error message.
if (!Session::checkToken('get')) {
$this->app->setHeader('status', 403, true);
$this->app->sendHeaders();
echo new JsonResponse(new \Exception(Text::_('JINVALID_TOKEN'), 403));
$this->app->close();
}
/** @var RequestsModel $model */
$model = $this->getModel('requests');
$numberUrgentRequests = $model->getNumberUrgentRequests();
echo new JsonResponse(['number_urgent_requests' => $numberUrgentRequests]);
}
}

View File

@ -0,0 +1,403 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_privacy
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Privacy\Administrator\Controller;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\FormController;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
use Joomla\Component\Privacy\Administrator\Model\ExportModel;
use Joomla\Component\Privacy\Administrator\Model\RemoveModel;
use Joomla\Component\Privacy\Administrator\Model\RequestModel;
use Joomla\Component\Privacy\Administrator\Table\RequestTable;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Request management controller class.
*
* @since 3.9.0
*/
class RequestController extends FormController
{
/**
* Method to complete a request.
*
* @param string $key The name of the primary key of the URL variable.
* @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
*
* @return boolean
*
* @since 3.9.0
*/
public function complete($key = null, $urlVar = null)
{
// Check for request forgeries.
$this->checkToken();
/** @var RequestModel $model */
$model = $this->getModel();
/** @var RequestTable $table */
$table = $model->getTable();
// Determine the name of the primary key for the data.
if (empty($key)) {
$key = $table->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary key.
if (empty($urlVar)) {
$urlVar = $key;
}
$recordId = $this->input->getInt($urlVar);
$item = $model->getItem($recordId);
// Ensure this record can transition to the requested state
if (!$this->canTransition($item, '2')) {
$this->setMessage(Text::_('COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED'), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Build the data array for the update
$data = [
$key => $recordId,
'status' => '2',
];
// Access check.
if (!$this->allowSave($data, $key)) {
$this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Attempt to save the data.
if (!$model->save($data)) {
// Redirect back to the edit screen.
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Log the request completed
$model->logRequestCompleted($recordId);
$this->setMessage(Text::_('COM_PRIVACY_REQUEST_COMPLETED'));
$url = 'index.php?option=com_privacy&view=requests';
// Check if there is a return value
$return = $this->input->get('return', null, 'base64');
if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(Route::_($url, false));
return true;
}
/**
* Method to email the data export for a request.
*
* @return boolean
*
* @since 3.9.0
*/
public function emailexport()
{
// Check for request forgeries.
$this->checkToken('get');
/** @var ExportModel $model */
$model = $this->getModel('Export');
$recordId = $this->input->getUint('id');
if (!$model->emailDataExport($recordId)) {
// Redirect back to the edit screen.
$this->setMessage(Text::sprintf('COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED', $model->getError()), 'error');
} else {
$this->setMessage(Text::_('COM_PRIVACY_EXPORT_EMAILED'));
}
$url = 'index.php?option=com_privacy&view=requests';
// Check if there is a return value
$return = $this->input->get('return', null, 'base64');
if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(Route::_($url, false));
return true;
}
/**
* Method to export the data for a request.
*
* @return $this
*
* @since 3.9.0
*/
public function export()
{
$this->input->set('view', 'export');
return $this->display();
}
/**
* Method to invalidate a request.
*
* @param string $key The name of the primary key of the URL variable.
* @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
*
* @return boolean
*
* @since 3.9.0
*/
public function invalidate($key = null, $urlVar = null)
{
// Check for request forgeries.
$this->checkToken();
/** @var RequestModel $model */
$model = $this->getModel();
/** @var RequestTable $table */
$table = $model->getTable();
// Determine the name of the primary key for the data.
if (empty($key)) {
$key = $table->getKeyName();
}
// To avoid data collisions the urlVar may be different from the primary key.
if (empty($urlVar)) {
$urlVar = $key;
}
$recordId = $this->input->getInt($urlVar);
$item = $model->getItem($recordId);
// Ensure this record can transition to the requested state
if (!$this->canTransition($item, '-1')) {
$this->setMessage(Text::_('COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED'), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Build the data array for the update
$data = [
$key => $recordId,
'status' => '-1',
];
// Access check.
if (!$this->allowSave($data, $key)) {
$this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Attempt to save the data.
if (!$model->save($data)) {
// Redirect back to the edit screen.
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
// Log the request invalidated
$model->logRequestInvalidated($recordId);
$this->setMessage(Text::_('COM_PRIVACY_REQUEST_INVALIDATED'));
$url = 'index.php?option=com_privacy&view=requests';
// Check if there is a return value
$return = $this->input->get('return', null, 'base64');
if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(Route::_($url, false));
return true;
}
/**
* Method to remove the user data for a privacy remove request.
*
* @return boolean
*
* @since 3.9.0
*/
public function remove()
{
// Check for request forgeries.
$this->checkToken('request');
/** @var RemoveModel $model */
$model = $this->getModel('Remove');
$recordId = $this->input->getUint('id');
if (!$model->removeDataForRequest($recordId)) {
// Redirect back to the edit screen.
$this->setMessage(Text::sprintf('COM_PRIVACY_ERROR_REMOVE_DATA_FAILED', $model->getError()), 'error');
$this->setRedirect(
Route::_(
'index.php?option=com_privacy&view=request&id=' . $recordId,
false
)
);
return false;
}
$this->setMessage(Text::_('COM_PRIVACY_DATA_REMOVED'));
$url = 'index.php?option=com_privacy&view=requests';
// Check if there is a return value
$return = $this->input->get('return', null, 'base64');
if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
$url = base64_decode($return);
}
// Redirect to the list screen.
$this->setRedirect(Route::_($url, false));
return true;
}
/**
* Function that allows child controller access to model data after the data has been saved.
*
* @param BaseDatabaseModel $model The data model object.
* @param array $validData The validated data.
*
* @return void
*
* @since 3.9.0
*/
protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
{
// This hook only processes new items
if (!$model->getState($model->getName() . '.new', false)) {
return;
}
if (!$model->logRequestCreated($model->getState($model->getName() . '.id'))) {
if ($error = $model->getError()) {
$this->app->enqueueMessage($error, 'warning');
}
}
if (!$model->notifyUserAdminCreatedRequest($model->getState($model->getName() . '.id'))) {
if ($error = $model->getError()) {
$this->app->enqueueMessage($error, 'warning');
}
} else {
$this->app->enqueueMessage(Text::_('COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER'));
}
}
/**
* Method to determine if an item can transition to the specified status.
*
* @param object $item The item being updated.
* @param string $newStatus The new status of the item.
*
* @return boolean
*
* @since 3.9.0
*/
private function canTransition($item, $newStatus)
{
switch ($item->status) {
case '0':
// A pending item can only move to invalid through this controller due to the requirement for a user to confirm the request
return $newStatus === '-1';
case '1':
// A confirmed item can be marked completed or invalid
return \in_array($newStatus, ['-1', '2'], true);
case '-1':
case '2':
default:
// An item which is already in an invalid or complete state cannot transition, likewise if we don't know the state don't change anything
return false;
}
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_privacy
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Privacy\Administrator\Controller;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
/**
* Requests management controller class.
*
* @since 3.9.0
*/
class RequestsController extends AdminController
{
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return BaseDatabaseModel|boolean Model object on success; otherwise false on failure.
*
* @since 3.9.0
*/
public function getModel($name = 'Request', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
}