| Current Path : /home/wuectly/www/03cbe/ |
| Current File : /home/wuectly/www/03cbe/plugins.tar |
index.html 0000604 00000000037 15245362375 0006551 0 ustar 00 <!DOCTYPE html><title></title>
twofactorauth/yubikey/yubikey.php 0000604 00000020512 15245362375 0013321 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.yubikey
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla! Two Factor Authentication using Yubikey Plugin
*
* @since 3.2
*/
class PlgTwofactorauthYubikey extends JPlugin
{
/**
* Affects constructor behavior. If true, language files will be loaded automatically.
*
* @var boolean
* @since 3.2
*/
protected $autoloadLanguage = true;
/**
* Method name
*
* @var string
* @since 3.2
*/
protected $methodName = 'yubikey';
/**
* This method returns the identification object for this two factor
* authentication plugin.
*
* @return stdClass An object with public properties method and title
*
* @since 3.2
*/
public function onUserTwofactorIdentify()
{
$section = (int) $this->params->get('section', 3);
$current_section = 0;
try
{
$app = JFactory::getApplication();
if ($app->isClient('administrator'))
{
$current_section = 2;
}
elseif ($app->isClient('site'))
{
$current_section = 1;
}
}
catch (Exception $exc)
{
$current_section = 0;
}
if (!($current_section & $section))
{
return false;
}
return (object) array(
'method' => $this->methodName,
'title' => JText::_('PLG_TWOFACTORAUTH_YUBIKEY_METHOD_TITLE'),
);
}
/**
* Shows the configuration page for this two factor authentication method.
*
* @param object $otpConfig The two factor auth configuration object
* @param integer $userId The numeric user ID of the user whose form we'll display
*
* @return boolean|string False if the method is not ours, the HTML of the configuration page otherwise
*
* @see UsersModelUser::getOtpConfig
* @since 3.2
*/
public function onUserTwofactorShowConfiguration($otpConfig, $userId = null)
{
if ($otpConfig->method === $this->methodName)
{
// This method is already activated. Reuse the same Yubikey ID.
$yubikey = $otpConfig->config['yubikey'];
}
else
{
// This methods is not activated yet. We'll need a Yubikey TOTP to setup this Yubikey.
$yubikey = '';
}
// Is this a new TOTP setup? If so, we'll have to show the code validation field.
$new_totp = $otpConfig->method !== $this->methodName;
// Start output buffering
@ob_start();
// Include the form.php from a template override. If none is found use the default.
$path = FOFPlatform::getInstance()->getTemplateOverridePath('plg_twofactorauth_yubikey', true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($path . '/form.php'))
{
include_once $path . '/form.php';
}
else
{
include_once __DIR__ . '/tmpl/form.php';
}
// Stop output buffering and get the form contents
$html = @ob_get_clean();
// Return the form contents
return array(
'method' => $this->methodName,
'form' => $html,
);
}
/**
* The save handler of the two factor configuration method's configuration
* page.
*
* @param string $method The two factor auth method for which we'll show the config page
*
* @return boolean|stdClass False if the method doesn't match or we have an error, OTP config object if it succeeds
*
* @see UsersModelUser::setOtpConfig
* @since 3.2
*/
public function onUserTwofactorApplyConfiguration($method)
{
if ($method !== $this->methodName)
{
return false;
}
// Get a reference to the input data object
$input = JFactory::getApplication()->input;
// Load raw data
$rawData = $input->get('jform', array(), 'array');
if (!isset($rawData['twofactor']['yubikey']))
{
return false;
}
$data = $rawData['twofactor']['yubikey'];
// Warn if the securitycode is empty
if (array_key_exists('securitycode', $data) && empty($data['securitycode']))
{
try
{
JFactory::getApplication()->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'), 'error');
}
catch (Exception $exc)
{
// This only happens when we are in a CLI application. We cannot
// enqueue a message, so just do nothing.
}
return false;
}
// Validate the Yubikey OTP
$check = $this->validateYubikeyOtp($data['securitycode']);
if (!$check)
{
JFactory::getApplication()->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED'), 'error');
// Check failed. Do not change two factor authentication settings.
return false;
}
// Remove the last 32 digits and store the rest in the user configuration parameters
$yubikey = substr($data['securitycode'], 0, -32);
// Check succeeded; return an OTP configuration object
$otpConfig = (object) array(
'method' => $this->methodName,
'config' => array(
'yubikey' => $yubikey
),
'otep' => array()
);
return $otpConfig;
}
/**
* This method should handle any two factor authentication and report back
* to the subject.
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
*
* @return boolean True if the user is authorised with this two-factor authentication method
*
* @since 3.2
*/
public function onUserTwofactorAuthenticate($credentials, $options)
{
// Get the OTP configuration object
$otpConfig = $options['otp_config'];
// Make sure it's an object
if (empty($otpConfig) || !is_object($otpConfig))
{
return false;
}
// Check if we have the correct method
if ($otpConfig->method !== $this->methodName)
{
return false;
}
// Check if there is a security code
if (empty($credentials['secretkey']))
{
return false;
}
// Check if the Yubikey starts with the configured Yubikey user string
$yubikey_valid = $otpConfig->config['yubikey'];
$yubikey = substr($credentials['secretkey'], 0, -32);
$check = $yubikey === $yubikey_valid;
if ($check)
{
$check = $this->validateYubikeyOtp($credentials['secretkey']);
}
return $check;
}
/**
* Validates a Yubikey OTP against the Yubikey servers
*
* @param string $otp The OTP generated by your Yubikey
*
* @return boolean True if it's a valid OTP
*
* @since 3.2
*/
public function validateYubikeyOtp($otp)
{
$server_queue = array(
'api.yubico.com',
'api2.yubico.com',
'api3.yubico.com',
'api4.yubico.com',
'api5.yubico.com',
);
shuffle($server_queue);
$gotResponse = false;
$check = false;
$token = JSession::getFormToken();
$nonce = md5($token . uniqid(mt_rand()));
while (!$gotResponse && !empty($server_queue))
{
$server = array_shift($server_queue);
$uri = new JUri('https://' . $server . '/wsapi/2.0/verify');
// I don't see where this ID is used?
$uri->setVar('id', 1);
// The OTP we read from the user
$uri->setVar('otp', $otp);
// This prevents a REPLAYED_OTP status of the token doesn't change
// after a user submits an invalid OTP
$uri->setVar('nonce', $nonce);
// Minimum service level required: 50% (at least 50% of the YubiCloud
// servers must reply positively for the OTP to validate)
$uri->setVar('sl', 50);
// Timeou waiting for YubiCloud servers to reply: 5 seconds.
$uri->setVar('timeout', 5);
try
{
$http = JHttpFactory::getHttp();
$response = $http->get($uri->toString(), null, 6);
if (!empty($response))
{
$gotResponse = true;
}
else
{
continue;
}
}
catch (Exception $exc)
{
// No response, continue with the next server
continue;
}
}
// No server replied; we can't validate this OTP
if (!$gotResponse)
{
return false;
}
// Parse response
$lines = explode("\n", $response->body);
$data = array();
foreach ($lines as $line)
{
$line = trim($line);
$parts = explode('=', $line, 2);
if (count($parts) < 2)
{
continue;
}
$data[$parts[0]] = $parts[1];
}
// Validate the response - We need an OK message reply
if ($data['status'] !== 'OK')
{
return false;
}
// Validate the response - We need a confidence level over 50%
if ($data['sl'] < 50)
{
return false;
}
// Validate the response - The OTP must match
if ($data['otp'] !== $otp)
{
return false;
}
// Validate the response - The token must match
if ($data['nonce'] !== $nonce)
{
return false;
}
return true;
}
}
twofactorauth/yubikey/yubikey.xml 0000604 00000002564 15245362375 0013341 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="twofactorauth" method="upgrade">
<name>plg_twofactorauth_yubikey</name>
<author>Joomla! Project</author>
<creationDate>September 2013</creationDate>
<copyright>(C) 2013 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.2.0</version>
<description>PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION</description>
<files>
<filename plugin="yubikey">yubikey.php</filename>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">en-GB.plg_twofactorauth_yubikey.ini</language>
<language tag="en-GB">en-GB.plg_twofactorauth_yubikey.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="section"
type="radio"
label="PLG_TWOFACTORAUTH_YUBIKEY_SECTION_LABEL"
description="PLG_TWOFACTORAUTH_YUBIKEY_SECTION_DESC"
default="3"
filter="integer"
class="btn-group"
>
<option value="1">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_SITE</option>
<option value="2">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_ADMIN</option>
<option value="3">PLG_TWOFACTORAUTH_YUBIKEY_SECTION_BOTH</option>
</field>
</fieldset>
</fields>
</config>
</extension>
twofactorauth/yubikey/tmpl/form.php 0000604 00000002145 15245362375 0013561 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.yubikey.tmpl
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
?>
<div class="well">
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_INTRO') ?>
</div>
<?php if ($new_totp): ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_STEP1_HEAD') ?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_STEP1_TEXT') ?>
</p>
<div class="control-group">
<label class="control-label" for="yubikeysecuritycode">
<?php echo JText::_('PLG_TWOFACTORAUTH_YUBIKEY_SECURITYCODE') ?>
</label>
<div class="controls">
<input type="text" class="input-medium" name="jform[twofactor][yubikey][securitycode]" id="yubikeysecuritycode" autocomplete="0">
</div>
</div>
</fieldset>
<?php else: ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_RESET_HEAD') ?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_RESET_TEXT') ?>
</p>
</fieldset>
<?php endif; ?>
twofactorauth/totp/totp.xml 0000604 00000002557 15245362375 0012155 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="twofactorauth" method="upgrade">
<name>plg_twofactorauth_totp</name>
<author>Joomla! Project</author>
<creationDate>August 2013</creationDate>
<copyright>(C) 2013 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.2.0</version>
<description>PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION</description>
<files>
<filename plugin="totp">totp.php</filename>
<folder>postinstall</folder>
<folder>tmpl</folder>
</files>
<languages>
<language tag="en-GB">en-GB.plg_twofactorauth_totp.ini</language>
<language tag="en-GB">en-GB.plg_twofactorauth_totp.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="section"
type="radio"
label="PLG_TWOFACTORAUTH_TOTP_SECTION_LABEL"
description="PLG_TWOFACTORAUTH_TOTP_SECTION_DESC"
default="3"
filter="integer"
class="btn-group"
>
<option value="1">PLG_TWOFACTORAUTH_TOTP_SECTION_SITE</option>
<option value="2">PLG_TWOFACTORAUTH_TOTP_SECTION_ADMIN</option>
<option value="3">PLG_TWOFACTORAUTH_TOTP_SECTION_BOTH</option>
</field>
</fieldset>
</fields>
</config>
</extension>
twofactorauth/totp/totp.php 0000604 00000017041 15245362375 0012136 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla! Two Factor Authentication using Google Authenticator TOTP Plugin
*
* @since 3.2
*/
class PlgTwofactorauthTotp extends JPlugin
{
/**
* Affects constructor behavior. If true, language files will be loaded automatically.
*
* @var boolean
* @since 3.2
*/
protected $autoloadLanguage = true;
/**
* Method name
*
* @var string
* @since 3.2
*/
protected $methodName = 'totp';
/**
* This method returns the identification object for this two factor
* authentication plugin.
*
* @return stdClass An object with public properties method and title
*
* @since 3.2
*/
public function onUserTwofactorIdentify()
{
$section = (int) $this->params->get('section', 3);
$current_section = 0;
try
{
$app = JFactory::getApplication();
if ($app->isClient('administrator'))
{
$current_section = 2;
}
elseif ($app->isClient('site'))
{
$current_section = 1;
}
}
catch (Exception $exc)
{
$current_section = 0;
}
if (!($current_section & $section))
{
return false;
}
return (object) array(
'method' => $this->methodName,
'title' => JText::_('PLG_TWOFACTORAUTH_TOTP_METHOD_TITLE')
);
}
/**
* Shows the configuration page for this two factor authentication method.
*
* @param object $otpConfig The two factor auth configuration object
* @param integer $userId The numeric user ID of the user whose form we'll display
*
* @return boolean|string False if the method is not ours, the HTML of the configuration page otherwise
*
* @see UsersModelUser::getOtpConfig
* @since 3.2
*/
public function onUserTwofactorShowConfiguration($otpConfig, $userId = null)
{
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
if ($otpConfig->method === $this->methodName)
{
// This method is already activated. Reuse the same secret key.
$secret = $otpConfig->config['code'];
}
else
{
// This methods is not activated yet. Create a new secret key.
$secret = $totp->generateSecret();
}
// These are used by Google Authenticator to tell accounts apart
$username = JFactory::getUser($userId)->username;
$hostname = JUri::getInstance()->getHost();
// This is the URL to the QR code for Google Authenticator
$url = sprintf("otpauth://totp/%s@%s?secret=%s", $username, $hostname, $secret);
// Is this a new TOTP setup? If so, we'll have to show the code validation field.
$new_totp = $otpConfig->method !== 'totp';
// Start output buffering
@ob_start();
// Include the form.php from a template override. If none is found use the default.
$path = FOFPlatform::getInstance()->getTemplateOverridePath('plg_twofactorauth_totp', true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($path . '/form.php'))
{
include_once $path . '/form.php';
}
else
{
include_once __DIR__ . '/tmpl/form.php';
}
// Stop output buffering and get the form contents
$html = @ob_get_clean();
// Return the form contents
return array(
'method' => $this->methodName,
'form' => $html
);
}
/**
* The save handler of the two factor configuration method's configuration
* page.
*
* @param string $method The two factor auth method for which we'll show the config page
*
* @return boolean|stdClass False if the method doesn't match or we have an error, OTP config object if it succeeds
*
* @see UsersModelUser::setOtpConfig
* @since 3.2
*/
public function onUserTwofactorApplyConfiguration($method)
{
if ($method !== $this->methodName)
{
return false;
}
// Get a reference to the input data object
$input = JFactory::getApplication()->input;
// Load raw data
$rawData = $input->get('jform', array(), 'array');
if (!isset($rawData['twofactor']['totp']))
{
return false;
}
$data = $rawData['twofactor']['totp'];
// Warn if the securitycode is empty
if (array_key_exists('securitycode', $data) && empty($data['securitycode']))
{
try
{
$app = JFactory::getApplication();
$app->enqueueMessage(JText::_('PLG_TWOFACTORAUTH_TOTP_ERR_VALIDATIONFAILED'), 'error');
}
catch (Exception $exc)
{
// This only happens when we are in a CLI application. We cannot
// enqueue a message, so just do nothing.
}
return false;
}
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
// Check the security code entered by the user (exact time slot match)
$code = $totp->getCode($data['key']);
$check = $code === $data['securitycode'];
/*
* If the check fails, test the previous 30 second slot. This allow the
* user to enter the security code when it's becoming red in Google
* Authenticator app (reaching the end of its 30 second lifetime)
*/
if (!$check)
{
$time = time() - 30;
$code = $totp->getCode($data['key'], $time);
$check = $code === $data['securitycode'];
}
/*
* If the check fails, test the next 30 second slot. This allows some
* time drift between the authentication device and the server
*/
if (!$check)
{
$time = time() + 30;
$code = $totp->getCode($data['key'], $time);
$check = $code === $data['securitycode'];
}
if (!$check)
{
// Check failed. Do not change two factor authentication settings.
return false;
}
// Check succeeded; return an OTP configuration object
$otpConfig = (object) array(
'method' => 'totp',
'config' => array(
'code' => $data['key']
),
'otep' => array()
);
return $otpConfig;
}
/**
* This method should handle any two factor authentication and report back
* to the subject.
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
*
* @return boolean True if the user is authorised with this two-factor authentication method
*
* @since 3.2
*/
public function onUserTwofactorAuthenticate($credentials, $options)
{
// Get the OTP configuration object
$otpConfig = $options['otp_config'];
// Make sure it's an object
if (empty($otpConfig) || !is_object($otpConfig))
{
return false;
}
// Check if we have the correct method
if ($otpConfig->method !== $this->methodName)
{
return false;
}
// Check if there is a security code
if (empty($credentials['secretkey']))
{
return false;
}
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new FOFEncryptTotp(30, 6, 10);
// Check the code
$code = $totp->getCode($otpConfig->config['code']);
$check = $code === $credentials['secretkey'];
/*
* If the check fails, test the previous 30 second slot. This allow the
* user to enter the security code when it's becoming red in Google
* Authenticator app (reaching the end of its 30 second lifetime)
*/
if (!$check)
{
$time = time() - 30;
$code = $totp->getCode($otpConfig->config['code'], $time);
$check = $code === $credentials['secretkey'];
}
/*
* If the check fails, test the next 30 second slot. This allows some
* time drift between the authentication device and the server
*/
if (!$check)
{
$time = time() + 30;
$code = $totp->getCode($otpConfig->config['code'], $time);
$check = $code === $credentials['secretkey'];
}
return $check;
}
}
twofactorauth/totp/tmpl/form.php 0000604 00000005756 15245362375 0013101 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp.tmpl
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Factory;
HTMLHelper::_('script', 'plg_twofactorauth_totp/qrcode.min.js', array('version' => 'auto', 'relative' => true));
$js = "
(function(document)
{
document.addEventListener('DOMContentLoaded', function()
{
var qr = qrcode(0, 'H');
qr.addData('" . $url . "');
qr.make();
document.getElementById('totp-qrcode').innerHTML = qr.createImgTag(4);
});
})(document);
";
Factory::getDocument()->addScriptDeclaration($js);
?>
<input type="hidden" name="jform[twofactor][totp][key]" value="<?php echo $secret ?>" />
<div class="well">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_INTRO') ?>
</div>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_HEAD') ?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_TEXT') ?>
</p>
<ul>
<li>
<a href="<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1_LINK') ?>" target="_blank" rel="noopener noreferrer">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1') ?>
</a>
</li>
<li>
<a href="<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2_LINK') ?>" target="_blank" rel="noopener noreferrer">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2') ?>
</a>
</li>
</ul>
<div class="alert">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP1_WARN') ?>
</div>
</fieldset>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_HEAD') ?>
</legend>
<div class="span6">
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_TEXT') ?>
</p>
<table class="table table-striped">
<tr>
<td>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_ACCOUNT') ?>
</td>
<td>
<?php echo $username ?>@<?php echo $hostname ?>
</td>
</tr>
<tr>
<td>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_KEY') ?>
</td>
<td>
<?php echo $secret ?>
</td>
</tr>
</table>
</div>
<div class="span6">
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_ALTTEXT') ?>
<br />
<div id="totp-qrcode"></div>
</p>
</div>
<div class="clearfix"></div>
<div class="alert alert-info">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP2_RESET') ?>
</div>
</fieldset>
<?php if ($new_totp): ?>
<fieldset>
<legend>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_HEAD') ?>
</legend>
<p>
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_TEXT') ?>
</p>
<div class="control-group">
<label class="control-label" for="totpsecuritycode">
<?php echo JText::_('PLG_TWOFACTORAUTH_TOTP_STEP3_SECURITYCODE') ?>
</label>
<div class="controls">
<input type="text" class="input-small" name="jform[twofactor][totp][securitycode]" id="totpsecuritycode" autocomplete="0">
</div>
</div>
</fieldset>
<?php endif; ?>
twofactorauth/totp/postinstall/actions.php 0000604 00000003525 15245362375 0015166 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Twofactorauth.totp
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*
* This file contains the functions used by the com_postinstall code to deliver
* the necessary post-installation messages concerning the activation of the
* two-factor authentication code.
*/
/**
* Checks if the plugin is enabled. If not it returns true, meaning that the
* message concerning two factor authentication should be displayed.
*
* @return integer
*
* @since 3.2
*/
function twofactorauth_postinstall_condition()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' . $db->q('plugin'))
->where($db->qn('enabled') . ' = 1')
->where($db->qn('folder') . ' = ' . $db->q('twofactorauth'));
$db->setQuery($query);
$enabled_plugins = $db->loadObjectList();
return count($enabled_plugins) === 0;
}
/**
* Enables the two factor authentication plugin and redirects the user to their
* user profile page so that they can enable two factor authentication on their
* account.
*
* @return void
*
* @since 3.2
*/
function twofactorauth_postinstall_action()
{
// Enable the plugin
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->update($db->qn('#__extensions'))
->set($db->qn('enabled') . ' = 1')
->where($db->qn('type') . ' = ' . $db->q('plugin'))
->where($db->qn('folder') . ' = ' . $db->q('twofactorauth'));
$db->setQuery($query);
$db->execute();
// Clean cache.
JFactory::getCache()->clean('com_plugins');
// Redirect the user to their profile editor page
$url = 'index.php?option=com_users&task=user.edit&id=' . JFactory::getUser()->id;
JFactory::getApplication()->redirect($url);
}
authentication/ldap/ldap.xml 0000604 00000010756 15245362375 0012166 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="authentication" method="upgrade">
<name>plg_authentication_ldap</name>
<author>Joomla! Project</author>
<creationDate>November 2005</creationDate>
<copyright>(C) 2005 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.0.0</version>
<description>PLG_LDAP_XML_DESCRIPTION</description>
<files>
<filename plugin="ldap">ldap.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_authentication_ldap.ini</language>
<language tag="en-GB">en-GB.plg_authentication_ldap.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="host"
type="text"
label="PLG_LDAP_FIELD_HOST_LABEL"
description="PLG_LDAP_FIELD_HOST_DESC"
size="20"
/>
<field
name="port"
type="number"
label="PLG_LDAP_FIELD_PORT_LABEL"
description="PLG_LDAP_FIELD_PORT_DESC"
min="1"
max="65535"
default="389"
hint="389"
validate="number"
filter="integer"
size="5"
/>
<field
name="use_ldapV3"
type="radio"
label="PLG_LDAP_FIELD_V3_LABEL"
description="PLG_LDAP_FIELD_V3_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="negotiate_tls"
type="radio"
label="PLG_LDAP_FIELD_NEGOCIATE_LABEL"
description="PLG_LDAP_FIELD_NEGOCIATE_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="ignore_reqcert_tls"
type="radio"
label="PLG_LDAP_FIELD_IGNORE_REQCERT_TLS_LABEL"
description="PLG_LDAP_FIELD_IGNORE_REQCERT_TLS_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="no_referrals"
type="radio"
label="PLG_LDAP_FIELD_REFERRALS_LABEL"
description="PLG_LDAP_FIELD_REFERRALS_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="auth_method"
type="list"
label="PLG_LDAP_FIELD_AUTHMETHOD_LABEL"
description="PLG_LDAP_FIELD_AUTHMETHOD_DESC"
default="bind"
>
<option value="search">PLG_LDAP_FIELD_VALUE_BINDSEARCH</option>
<option value="bind">PLG_LDAP_FIELD_VALUE_BINDUSER</option>
</field>
<field
name="base_dn"
type="text"
label="PLG_LDAP_FIELD_BASEDN_LABEL"
description="PLG_LDAP_FIELD_BASEDN_DESC"
size="20"
/>
<field
name="search_string"
type="text"
label="PLG_LDAP_FIELD_SEARCHSTRING_LABEL"
description="PLG_LDAP_FIELD_SEARCHSTRING_DESC"
size="20"
/>
<field
name="users_dn"
type="text"
label="PLG_LDAP_FIELD_USERSDN_LABEL"
description="PLG_LDAP_FIELD_USERSDN_DESC"
size="20"
/>
<field
name="username"
type="text"
label="PLG_LDAP_FIELD_USERNAME_LABEL"
description="PLG_LDAP_FIELD_USERNAME_DESC"
size="20"
/>
<field
name="password"
type="password"
label="PLG_LDAP_FIELD_PASSWORD_LABEL"
description="PLG_LDAP_FIELD_PASSWORD_DESC"
size="20"
/>
<field
name="ldap_fullname"
type="text"
label="PLG_LDAP_FIELD_FULLNAME_LABEL"
description="PLG_LDAP_FIELD_FULLNAME_DESC"
default="fullName"
size="20"
/>
<field
name="ldap_email"
type="text"
label="PLG_LDAP_FIELD_EMAIL_LABEL"
description="PLG_LDAP_FIELD_EMAIL_DESC"
default="mail"
size="20"
/>
<field
name="ldap_uid"
type="text"
label="PLG_LDAP_FIELD_UID_LABEL"
description="PLG_LDAP_FIELD_UID_DESC"
default="uid"
size="20"
/>
<field
name="ldap_debug"
type="radio"
label="PLG_LDAP_FIELD_LDAPDEBUG_LABEL"
description="PLG_LDAP_FIELD_LDAPDEBUG_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</fieldset>
</fields>
</config>
</extension>
authentication/ldap/ldap.php 0000604 00000011767 15245362375 0012160 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Authentication.ldap
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\Ldap\LdapClient;
/**
* LDAP Authentication Plugin
*
* @since 1.5
*/
class PlgAuthenticationLdap extends JPlugin
{
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param object &$response Authentication response object
*
* @return boolean
*
* @since 1.5
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
$userdetails = null;
$success = 0;
$userdetails = array();
// For JLog
$response->type = 'LDAP';
// Strip null bytes from the password
$credentials['password'] = str_replace(chr(0), '', $credentials['password']);
// LDAP does not like Blank passwords (tries to Anon Bind which is bad)
if (empty($credentials['password']))
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
return false;
}
// Load plugin params info
$ldap_email = $this->params->get('ldap_email');
$ldap_fullname = $this->params->get('ldap_fullname');
$ldap_uid = $this->params->get('ldap_uid');
$auth_method = $this->params->get('auth_method');
$ldap = new LdapClient($this->params);
if (!$ldap->connect())
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NOT_CONNECT');
return;
}
switch ($auth_method)
{
case 'search':
{
// Bind using Connect Username/password
// Force anon bind to mitigate misconfiguration like [#7119]
if ($this->params->get('username', '') !== '')
{
$bindtest = $ldap->bind();
}
else
{
$bindtest = $ldap->anonymous_bind();
}
if ($bindtest)
{
// Search for users DN
$binddata = $this->searchByString(
str_replace(
'[search]',
str_replace(';', '\3b', $ldap->escape($credentials['username'], null, LDAP_ESCAPE_FILTER)),
$this->params->get('search_string')
),
$ldap
);
if (isset($binddata[0], $binddata[0]['dn']))
{
// Verify Users Credentials
$success = $ldap->bind($binddata[0]['dn'], $credentials['password'], 1);
// Get users details
$userdetails = $binddata;
}
else
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
}
}
else
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NOT_CONNECT');
}
} break;
case 'bind':
{
// We just accept the result here
$success = $ldap->bind($ldap->escape($credentials['username'], null, LDAP_ESCAPE_DN), $credentials['password']);
if ($success)
{
$userdetails = $this->searchByString(
str_replace(
'[search]',
str_replace(';', '\3b', $ldap->escape($credentials['username'], null, LDAP_ESCAPE_FILTER)),
$this->params->get('search_string')
),
$ldap
);
}
else
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_INVALID_PASS');
}
} break;
}
if (!$success)
{
$response->status = JAuthentication::STATUS_FAILURE;
if ($response->error_message === '')
{
$response->error_message = JText::_('JGLOBAL_AUTH_INVALID_PASS');
}
}
else
{
// Grab some details from LDAP and return them
if (isset($userdetails[0][$ldap_uid][0]))
{
$response->username = $userdetails[0][$ldap_uid][0];
}
if (isset($userdetails[0][$ldap_email][0]))
{
$response->email = $userdetails[0][$ldap_email][0];
}
if (isset($userdetails[0][$ldap_fullname][0]))
{
$response->fullname = $userdetails[0][$ldap_fullname][0];
}
else
{
$response->fullname = $credentials['username'];
}
// Were good - So say so.
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
}
$ldap->close();
}
/**
* Shortcut method to build a LDAP search based on a semicolon separated string
*
* Note that this method requires that semicolons which should be part of the search term to be escaped
* to correctly split the search string into separate lookups
*
* @param string $search search string of search values
* @param LdapClient $ldap The LDAP client
*
* @return array Search results
*
* @since 3.8.2
*/
private static function searchByString($search, LdapClient $ldap)
{
$results = explode(';', $search);
foreach ($results as $key => $result)
{
$results[$key] = '(' . str_replace('\3b', ';', $result) . ')';
}
return $ldap->search($results);
}
}
authentication/gmail/gmail.php 0000604 00000014535 15245362375 0012476 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Authentication.gmail
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Authentication\AuthenticationResponse;
use Joomla\Registry\Registry;
/**
* GMail Authentication Plugin
*
* @since 1.5
*/
class PlgAuthenticationGMail extends JPlugin
{
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param AuthenticationResponse &$response Authentication response object
*
* @return void
*
* @since 1.5
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
// Load plugin language
$this->loadLanguage();
// No backend authentication
if (JFactory::getApplication()->isClient('administrator') && !$this->params->get('backendLogin', 0))
{
return;
}
$success = false;
$curlParams = array(
'follow_location' => true,
'transport.curl' => array(
CURLOPT_SSL_VERIFYPEER => $this->params->get('verifypeer', 1)
),
);
$transportParams = new Registry($curlParams);
try
{
$http = JHttpFactory::getHttp($transportParams, 'curl');
}
catch (RuntimeException $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->type = 'GMail';
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', JText::_('JGLOBAL_AUTH_CURL_NOT_INSTALLED'));
return;
}
// Check if we have a username and password
if ($credentials['username'] === '' || $credentials['password'] === '')
{
$response->type = 'GMail';
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', JText::_('JGLOBAL_AUTH_USER_BLACKLISTED'));
return;
}
$blacklist = explode(',', $this->params->get('user_blacklist', ''));
// Check if the username isn't blacklisted
if (in_array($credentials['username'], $blacklist))
{
$response->type = 'GMail';
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', JText::_('JGLOBAL_AUTH_USER_BLACKLISTED'));
return;
}
$suffix = $this->params->get('suffix', '');
$applysuffix = $this->params->get('applysuffix', 0);
$offset = strpos($credentials['username'], '@');
// Check if we want to do suffix stuff, typically for Google Apps for Your Domain
if ($suffix && $applysuffix)
{
if ($applysuffix == 1 && $offset === false)
{
// Apply suffix if missing
$credentials['username'] .= '@' . $suffix;
}
elseif ($applysuffix == 2)
{
// Always use suffix
if ($offset)
{
// If we already have an @, get rid of it and replace it
$credentials['username'] = substr($credentials['username'], 0, $offset);
}
$credentials['username'] .= '@' . $suffix;
}
}
$headers = array(
'Authorization' => 'Basic ' . base64_encode($credentials['username'] . ':' . $credentials['password'])
);
try
{
$result = $http->get('https://mail.google.com/mail/feed/atom', $headers);
}
catch (Exception $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->type = 'GMail';
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', JText::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED'));
return;
}
$code = $result->code;
switch ($code)
{
case 200 :
$message = JText::_('JGLOBAL_AUTH_ACCESS_GRANTED');
$success = true;
break;
case 401 :
$message = JText::_('JGLOBAL_AUTH_ACCESS_DENIED');
break;
default :
$message = JText::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED');
break;
}
$response->type = 'GMail';
if (!$success)
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', $message);
return;
}
if (strpos($credentials['username'], '@') === false)
{
if ($suffix)
{
// If there is a suffix then we want to apply it
$email = $credentials['username'] . '@' . $suffix;
}
else
{
// If there isn't a suffix just use the default gmail one
$email = $credentials['username'] . '@gmail.com';
}
}
else
{
// The username looks like an email address (probably is) so use that
$email = $credentials['username'];
}
// Extra security checks with existing local accounts
$db = JFactory::getDbo();
$localUsernameChecks = array(strstr($email, '@', true), $email);
$query = $db->getQuery(true)
->select('id, activation, username, email, block')
->from('#__users')
->where('username IN(' . implode(',', array_map(array($db, 'quote'), $localUsernameChecks)) . ')'
. ' OR email = ' . $db->quote($email)
);
$db->setQuery($query);
if ($localUsers = $db->loadObjectList())
{
foreach ($localUsers as $localUser)
{
// Local user exists with same username but different email address
if ($email !== $localUser->email)
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::sprintf('JGLOBAL_AUTH_FAILED', JText::_('PLG_GMAIL_ERROR_LOCAL_USERNAME_CONFLICT'));
return;
}
else
{
// Existing user disabled locally
if ($localUser->block || !empty($localUser->activation))
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_ACCESS_DENIED');
return;
}
// We will always keep the local username for existing accounts
$credentials['username'] = $localUser->username;
break;
}
}
}
elseif (JFactory::getApplication()->isClient('administrator'))
{
// We wont' allow backend access without local account
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JERROR_LOGIN_DENIED');
return;
}
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
$response->email = $email;
// Reset the username to what we ended up using
$response->username = $credentials['username'];
$response->fullname = $credentials['username'];
}
}
authentication/gmail/gmail.xml 0000604 00000004454 15245362375 0012506 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="authentication" method="upgrade">
<name>plg_authentication_gmail</name>
<author>Joomla! Project</author>
<creationDate>February 2006</creationDate>
<copyright>(C) 2006 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.0.0</version>
<description>PLG_GMAIL_XML_DESCRIPTION</description>
<files>
<filename plugin="gmail">gmail.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_authentication_gmail.ini</language>
<language tag="en-GB">en-GB.plg_authentication_gmail.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="applysuffix"
type="list"
label="PLG_GMAIL_FIELD_APPLYSUFFIX_LABEL"
description="PLG_GMAIL_FIELD_APPLYSUFFIX_DESC"
default="0"
filter="integer"
>
<option value="0">PLG_GMAIL_FIELD_VALUE_NOAPPLYSUFFIX</option>
<option value="1">PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXMISSING</option>
<option value="2">PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXALWAYS</option>
</field>
<field
name="suffix"
type="text"
label="PLG_GMAIL_FIELD_SUFFIX_LABEL"
description="PLG_GMAIL_FIELD_SUFFIX_DESC"
size="20"
showon="applysuffix:1,2"
/>
<field
name="verifypeer"
type="radio"
label="PLG_GMAIL_FIELD_VERIFYPEER_LABEL"
description="PLG_GMAIL_FIELD_VERIFYPEER_DESC"
default="1"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="user_blacklist"
type="text"
label="PLG_GMAIL_FIELD_USER_BLACKLIST_LABEL"
description="PLG_GMAIL_FIELD_USER_BLACKLIST_DESC"
size="20"
/>
<field
name="backendLogin"
type="radio"
label="PLG_GMAIL_FIELD_BACKEND_LOGIN_LABEL"
description="PLG_GMAIL_FIELD_BACKEND_LOGIN_DESC"
default="0"
filter="integer"
class="btn-group btn-group-yesno"
>
<option value="1">JENABLED</option>
<option value="0">JDISABLED</option>
</field>
</fieldset>
</fields>
</config>
</extension>
authentication/joomla/joomla.php 0000604 00000013766 15245362375 0013063 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Authentication.joomla
*
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla Authentication plugin
*
* @since 1.5
*/
class PlgAuthenticationJoomla extends JPlugin
{
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param object &$response Authentication response object
*
* @return void
*
* @since 1.5
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
$response->type = 'Joomla';
// Joomla does not like blank passwords
if (empty($credentials['password']))
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED');
return;
}
// Get a database object
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('id, password')
->from('#__users')
->where('username=' . $db->quote($credentials['username']));
$db->setQuery($query);
$result = $db->loadObject();
if ($result)
{
$match = JUserHelper::verifyPassword($credentials['password'], $result->password, $result->id);
if ($match === true)
{
// Bring this in line with the rest of the system
$user = JUser::getInstance($result->id);
$response->email = $user->email;
$response->fullname = $user->name;
if (JFactory::getApplication()->isClient('administrator'))
{
$response->language = $user->getParam('admin_language');
}
else
{
$response->language = $user->getParam('language');
}
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
}
else
{
// Invalid password
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_INVALID_PASS');
}
}
else
{
// Let's hash the entered password even if we don't have a matching user for some extra response time
// By doing so, we mitigate side channel user enumeration attacks
JUserHelper::hashPassword($credentials['password']);
// Invalid user
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
}
// Check the two factor authentication
if ($response->status === JAuthentication::STATUS_SUCCESS)
{
$methods = JAuthenticationHelper::getTwoFactorMethods();
if (count($methods) <= 1)
{
// No two factor authentication method is enabled
return;
}
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_users/models', 'UsersModel');
/** @var UsersModelUser $model */
$model = JModelLegacy::getInstance('User', 'UsersModel', array('ignore_request' => true));
// Load the user's OTP (one time password, a.k.a. two factor auth) configuration
if (!array_key_exists('otp_config', $options))
{
$otpConfig = $model->getOtpConfig($result->id);
$options['otp_config'] = $otpConfig;
}
else
{
$otpConfig = $options['otp_config'];
}
// Check if the user has enabled two factor authentication
if (empty($otpConfig->method) || ($otpConfig->method === 'none'))
{
// Warn the user if they are using a secret code but they have not
// enabled two factor auth in their account.
if (!empty($credentials['secretkey']))
{
try
{
$app = JFactory::getApplication();
$this->loadLanguage();
$app->enqueueMessage(JText::_('PLG_AUTH_JOOMLA_ERR_SECRET_CODE_WITHOUT_TFA'), 'warning');
}
catch (Exception $exc)
{
// This happens when we are in CLI mode. In this case
// no warning is issued
return;
}
}
return;
}
// Try to validate the OTP
FOFPlatform::getInstance()->importPlugin('twofactorauth');
$otpAuthReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate', array($credentials, $options));
$check = false;
/*
* This looks like noob code but DO NOT TOUCH IT and do not convert
* to in_array(). During testing in_array() inexplicably returned
* null when the OTEP begins with a zero! o_O
*/
if (!empty($otpAuthReplies))
{
foreach ($otpAuthReplies as $authReply)
{
$check = $check || $authReply;
}
}
// Fall back to one time emergency passwords
if (!$check)
{
// Did the user use an OTEP instead?
if (empty($otpConfig->otep))
{
if (empty($otpConfig->method) || ($otpConfig->method === 'none'))
{
// Two factor authentication is not enabled on this account.
// Any string is assumed to be a valid OTEP.
return;
}
else
{
/*
* Two factor authentication enabled and no OTEPs defined. The
* user has used them all up. Therefore anything they enter is
* an invalid OTEP.
*/
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_INVALID_SECRETKEY');
return;
}
}
// Clean up the OTEP (remove dashes, spaces and other funny stuff
// our beloved users may have unwittingly stuffed in it)
$otep = $credentials['secretkey'];
$otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT);
$otep = str_replace('-', '', $otep);
$check = false;
// Did we find a valid OTEP?
if (in_array($otep, $otpConfig->otep))
{
// Remove the OTEP from the array
$otpConfig->otep = array_diff($otpConfig->otep, array($otep));
$model->setOtpConfig($result->id, $otpConfig);
// Return true; the OTEP was a valid one
$check = true;
}
}
if (!$check)
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_INVALID_SECRETKEY');
}
}
}
}
authentication/joomla/joomla.xml 0000604 00000001444 15245362375 0013062 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="authentication" method="upgrade">
<name>plg_authentication_joomla</name>
<author>Joomla! Project</author>
<creationDate>November 2005</creationDate>
<copyright>(C) 2005 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.0.0</version>
<description>PLG_AUTH_JOOMLA_XML_DESCRIPTION</description>
<files>
<filename plugin="joomla">joomla.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_authentication_joomla.ini</language>
<language tag="en-GB">en-GB.plg_authentication_joomla.sys.ini</language>
</languages>
</extension>
authentication/cookie/cookie.php 0000604 00000026743 15245362375 0013042 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Authentication.cookie
*
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Joomla Authentication plugin
*
* @since 3.2
* @note Code based on http://jaspan.com/improved_persistent_login_cookie_best_practice
* and http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
*/
class PlgAuthenticationCookie extends JPlugin
{
/**
* Application object
*
* @var JApplicationCms
* @since 3.2
*/
protected $app;
/**
* Database object
*
* @var JDatabaseDriver
* @since 3.2
*/
protected $db;
/**
* Reports the privacy related capabilities for this plugin to site administrators.
*
* @return array
*
* @since 3.9.0
*/
public function onPrivacyCollectAdminCapabilities()
{
$this->loadLanguage();
return array(
JText::_('PLG_AUTHENTICATION_COOKIE') => array(
JText::_('PLG_AUTH_COOKIE_PRIVACY_CAPABILITY_COOKIE'),
)
);
}
/**
* This method should handle any authentication and report back to the subject
*
* @param array $credentials Array holding the user credentials
* @param array $options Array of extra options
* @param object &$response Authentication response object
*
* @return boolean
*
* @since 3.2
*/
public function onUserAuthenticate($credentials, $options, &$response)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
// Get cookie
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue)
{
$cookieName = JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
}
if (!$cookieValue)
{
return false;
}
$cookieArray = explode('.', $cookieValue);
// Check for valid cookie value
if (count($cookieArray) !== 2)
{
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
JLog::add('Invalid cookie detected.', JLog::WARNING, 'error');
return false;
}
$response->type = 'Cookie';
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
// Remove expired tokens
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('time') . ' < ' . $this->db->quote(time()));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// We aren't concerned with errors from this query, carry on
}
// Find the matching record if it exists.
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('user_id', 'token', 'series', 'time')))
->from($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
->order($this->db->quoteName('time') . ' DESC');
try
{
$results = $this->db->setQuery($query)->loadObjectList();
}
catch (RuntimeException $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
if (count($results) !== 1)
{
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
// We have a user with one cookie with a valid series and a corresponding record in the database.
if (!JUserHelper::verifyPassword($cookieArray[0], $results[0]->token))
{
/*
* This is a real attack!
* Either the series was guessed correctly or a cookie was stolen and used twice (once by attacker and once by victim).
* Delete all tokens for this user!
*/
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($results[0]->user_id));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// Log an alert for the site admin
JLog::add(
sprintf('Failed to delete cookie token for user %s with the following error: %s', $results[0]->user_id, $e->getMessage()),
JLog::WARNING,
'security'
);
}
// Destroy the cookie in the browser.
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
// Issue warning by email to user and/or admin?
JLog::add(JText::sprintf('PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED', $results[0]->user_id), JLog::WARNING, 'security');
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
// Make sure there really is a user with this name and get the data for the session.
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('id', 'username', 'password')))
->from($this->db->quoteName('#__users'))
->where($this->db->quoteName('username') . ' = ' . $this->db->quote($results[0]->user_id))
->where($this->db->quoteName('requireReset') . ' = 0');
try
{
$result = $this->db->setQuery($query)->loadObject();
}
catch (RuntimeException $e)
{
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
if ($result)
{
// Bring this in line with the rest of the system
$user = JUser::getInstance($result->id);
// Set response data.
$response->username = $result->username;
$response->email = $user->email;
$response->fullname = $user->name;
$response->password = $result->password;
$response->language = $user->getParam('language');
// Set response status.
$response->status = JAuthentication::STATUS_SUCCESS;
$response->error_message = '';
}
else
{
$response->status = JAuthentication::STATUS_FAILURE;
$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
}
}
/**
* We set the authentication cookie only after login is successfully finished.
* We set a new cookie either for a user with no cookies or one
* where the user used a cookie to authenticate.
*
* @param array $options Array holding options
*
* @return boolean True on success
*
* @since 3.2
*/
public function onUserAfterLogin($options)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
if (isset($options['responseType']) && $options['responseType'] === 'Cookie')
{
// Logged in using a cookie
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
// We need the old data to get the existing series
$cookieValue = $this->app->input->cookie->get($cookieName);
// Try with old cookieName (pre 3.6.0) if not found
if (!$cookieValue)
{
$oldCookieName = JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($oldCookieName);
// Destroy the old cookie in the browser
$this->app->input->cookie->set($oldCookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
}
$cookieArray = explode('.', $cookieValue);
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
}
elseif (!empty($options['remember']))
{
// Remember checkbox is set
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
// Create a unique series which will be used over the lifespan of the cookie
$unique = false;
$errorCount = 0;
do
{
$series = JUserHelper::genRandomPassword(20);
$query = $this->db->getQuery(true)
->select($this->db->quoteName('series'))
->from($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
try
{
$results = $this->db->setQuery($query)->loadResult();
if ($results === null)
{
$unique = true;
}
}
catch (RuntimeException $e)
{
$errorCount++;
// We'll let this query fail up to 5 times before giving up, there's probably a bigger issue at this point
if ($errorCount === 5)
{
return false;
}
}
}
while ($unique === false);
}
else
{
return false;
}
// Get the parameter values
$lifetime = $this->params->get('cookie_lifetime', 60) * 24 * 60 * 60;
$length = $this->params->get('key_length', 16);
// Generate new cookie
$token = JUserHelper::genRandomPassword($length);
$cookieValue = $token . '.' . $series;
// Overwrite existing cookie with new value
$this->app->input->cookie->set(
$cookieName,
$cookieValue,
time() + $lifetime,
$this->app->get('cookie_path', '/'),
$this->app->get('cookie_domain', ''),
$this->app->isHttpsForced(),
true
);
$query = $this->db->getQuery(true);
if (!empty($options['remember']))
{
// Create new record
$query
->insert($this->db->quoteName('#__user_keys'))
->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
->set($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
->set($this->db->quoteName('time') . ' = ' . (time() + $lifetime));
}
else
{
// Update existing record with new token
$query
->update($this->db->quoteName('#__user_keys'))
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
}
$hashedToken = JUserHelper::hashPassword($token);
$query->set($this->db->quoteName('token') . ' = ' . $this->db->quote($hashedToken));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
return false;
}
return true;
}
/**
* This is where we delete any authentication cookie when a user logs out
*
* @param array $options Array holding options (length, timeToExpiration)
*
* @return boolean True on success
*
* @since 3.2
*/
public function onUserAfterLogout($options)
{
// No remember me for admin
if ($this->app->isClient('administrator'))
{
return false;
}
$cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent();
$cookieValue = $this->app->input->cookie->get($cookieName);
// There are no cookies to delete.
if (!$cookieValue)
{
return true;
}
$cookieArray = explode('.', $cookieValue);
// Filter series since we're going to use it in the query
$filter = new JFilterInput;
$series = $filter->clean($cookieArray[1], 'ALNUM');
// Remove the record from the database
$query = $this->db->getQuery(true)
->delete('#__user_keys')
->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
try
{
$this->db->setQuery($query)->execute();
}
catch (RuntimeException $e)
{
// We aren't concerned with errors from this query, carry on
}
// Destroy the cookie
$this->app->input->cookie->set($cookieName, '', 1, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain', ''));
return true;
}
}
authentication/cookie/cookie.xml 0000604 00000002772 15245362375 0013047 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.2" type="plugin" group="authentication" method="upgrade">
<name>plg_authentication_cookie</name>
<author>Joomla! Project</author>
<creationDate>July 2013</creationDate>
<copyright>(C) 2013 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.0.0</version>
<description>PLG_AUTH_COOKIE_XML_DESCRIPTION</description>
<files>
<filename plugin="cookie">cookie.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_authentication_cookie.ini</language>
<language tag="en-GB">en-GB.plg_authentication_cookie.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="cookie_lifetime"
type="number"
label="PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL"
description="PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_DESC"
default="60"
filter="integer"
required="true"
/>
<field
name="key_length"
type="list"
label="PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_LABEL"
description="PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_DESC"
default="16"
filter="integer"
required="true"
>
<option value="8">8</option>
<option value="16">16</option>
<option value="32">32</option>
<option value="64">64</option>
</field>
</fieldset>
</fields>
</config>
</extension>
sampledata/blog/blog.php 0000604 00000076003 15245362375 0011254 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Sampledata.Blog
*
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Multilanguage;
use Joomla\CMS\Session\Session;
/**
* Sampledata - Blog Plugin
*
* @since 3.8.0
*/
class PlgSampledataBlog extends JPlugin
{
/**
* Database object
*
* @var JDatabaseDriver
*
* @since 3.8.0
*/
protected $db;
/**
* Application object
*
* @var JApplicationCms
*
* @since 3.8.0
*/
protected $app;
/**
* Affects constructor behavior. If true, language files will be loaded automatically.
*
* @var boolean
*
* @since 3.8.0
*/
protected $autoloadLanguage = true;
/**
* Holds the menuitem model
*
* @var MenusModelItem
*
* @since 3.8.0
*/
private $menuItemModel;
/**
* Get an overview of the proposed sampledata.
*
* @return boolean True on success.
*
* @since 3.8.0
*/
public function onSampledataGetOverview()
{
if (!Factory::getUser()->authorise('core.create', 'com_content'))
{
return;
}
$data = new stdClass;
$data->name = $this->_name;
$data->title = JText::_('PLG_SAMPLEDATA_BLOG_OVERVIEW_TITLE');
$data->description = JText::_('PLG_SAMPLEDATA_BLOG_OVERVIEW_DESC');
$data->icon = 'broadcast';
$data->steps = 3;
return $data;
}
/**
* First step to enter the sampledata. Content.
*
* @return array or void Will be converted into the JSON response to the module.
*
* @since 3.8.0
*/
public function onAjaxSampledataApplyStep1()
{
if (!Session::checkToken('get') || $this->app->input->get('type') != $this->_name)
{
return;
};
if (!JComponentHelper::isEnabled('com_content') || !Factory::getUser()->authorise('core.create', 'com_content'))
{
$response = array();
$response['success'] = true;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_SKIPPED', 1, 'com_content');
return $response;
}
// Get some metadata.
$access = (int) $this->app->get('access', 1);
$user = JFactory::getUser();
// Detect language to be used.
$language = Multilanguage::isEnabled() ? JFactory::getLanguage()->getTag() : '*';
$langSuffix = ($language !== '*') ? ' (' . $language . ')' : '';
// Add Include Paths.
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_content/models/', 'ContentModel');
JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_content/tables/');
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/models/', 'CategoriesModel');
JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables/');
// Create "blog" category.
$categoryModel = JModelLegacy::getInstance('Category', 'CategoriesModel');
$catIds = array();
$categoryTitle = JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_CATEGORY_0_TITLE');
$alias = JApplicationHelper::stringURLSafe($categoryTitle);
// Set unicodeslugs if alias is empty
if (trim(str_replace('-', '', $alias) == ''))
{
$unicode = JFactory::getConfig()->set('unicodeslugs', 1);
$alias = JApplicationHelper::stringURLSafe($categoryTitle);
JFactory::getConfig()->set('unicodeslugs', $unicode);
}
$category = array(
'title' => $categoryTitle . $langSuffix,
'parent_id' => 1,
'id' => 0,
'published' => 1,
'access' => $access,
'created_user_id' => $user->id,
'extension' => 'com_content',
'level' => 1,
'alias' => $alias . $langSuffix,
'associations' => array(),
'description' => '',
'language' => $language,
'params' => '',
);
try
{
if (!$categoryModel->save($category))
{
throw new Exception($categoryModel->getError());
}
}
catch (Exception $e)
{
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 1, $e->getMessage());
return $response;
}
// Get ID from category we just added
$catIds[] = $categoryModel->getItem()->id;
// Create "help" category.
$categoryTitle = JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_CATEGORY_1_TITLE');
$alias = JApplicationHelper::stringURLSafe($categoryTitle);
// Set unicodeslugs if alias is empty
if (trim(str_replace('-', '', $alias) == ''))
{
$unicode = JFactory::getConfig()->set('unicodeslugs', 1);
$alias = JApplicationHelper::stringURLSafe($categoryTitle);
JFactory::getConfig()->set('unicodeslugs', $unicode);
}
$category = array(
'title' => $categoryTitle . $langSuffix,
'parent_id' => 1,
'id' => 0,
'published' => 1,
'access' => $access,
'created_user_id' => $user->id,
'extension' => 'com_content',
'level' => 1,
'alias' => $alias . $langSuffix,
'associations' => array(),
'description' => '',
'language' => $language,
'params' => '',
);
try
{
if (!$categoryModel->save($category))
{
throw new Exception($categoryModel->getError());
}
}
catch (Exception $e)
{
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 1, $e->getMessage());
return $response;
}
// Get ID from category we just added
$catIds[] = $categoryModel->getItem()->id;
// Create Articles.
$articleModel = JModelLegacy::getInstance('Article', 'ContentModel');
$articles = array(
array(
'catid' => $catIds[1],
'ordering' => 2,
),
array(
'catid' => $catIds[1],
'ordering' => 1,
'access' => 3,
),
array(
'catid' => $catIds[0],
'ordering' => 2,
),
array(
'catid' => $catIds[0],
'ordering' => 1,
),
array(
'catid' => $catIds[0],
'ordering' => 0,
),
array(
'catid' => $catIds[0],
'ordering' => 0,
),
);
foreach ($articles as $i => $article)
{
// Set values from language strings.
$title = JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_' . $i . '_TITLE');
$alias = JApplicationHelper::stringURLSafe($title);
$article['title'] = $title . $langSuffix;
$article['introtext'] = JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_' . $i . '_INTROTEXT');
$article['fulltext'] = JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_' . $i . '_FULLTEXT');
// Set values which are always the same.
$article['id'] = 0;
$article['created_user_id'] = $user->id;
$article['alias'] = JApplicationHelper::stringURLSafe($article['title']);
// Set unicodeslugs if alias is empty
if (trim(str_replace('-', '', $alias) == ''))
{
$unicode = JFactory::getConfig()->set('unicodeslugs', 1);
$article['alias'] = JApplicationHelper::stringURLSafe($article['title']);
JFactory::getConfig()->set('unicodeslugs', $unicode);
}
$article['language'] = $language;
$article['associations'] = array();
$article['state'] = 1;
$article['featured'] = 0;
$article['images'] = '';
$article['metakey'] = '';
$article['metadesc'] = '';
$article['xreference'] = '';
if (!isset($article['access']))
{
$article['access'] = $access;
}
if (!$articleModel->save($article))
{
JFactory::getLanguage()->load('com_content');
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 1, JText::_($articleModel->getError()));
return $response;
}
// Get ID from article we just added
$ids[] = $articleModel->getItem()->id;
}
$this->app->setUserState('sampledata.blog.articles', $ids);
$this->app->setUserState('sampledata.blog.articles.catids', $catIds);
$response = new stdClass;
$response->success = true;
$response->message = JText::_('PLG_SAMPLEDATA_BLOG_STEP1_SUCCESS');
return $response;
}
/**
* Second step to enter the sampledata. Menus.
*
* @return array or void Will be converted into the JSON response to the module.
*
* @since 3.8.0
*/
public function onAjaxSampledataApplyStep2()
{
if (!Session::checkToken('get') || $this->app->input->get('type') != $this->_name)
{
return;
}
if (!JComponentHelper::isEnabled('com_menus') || !Factory::getUser()->authorise('core.create', 'com_menus'))
{
$response = array();
$response['success'] = true;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_SKIPPED', 2, 'com_menus');
return $response;
}
// Detect language to be used.
$language = Multilanguage::isEnabled() ? JFactory::getLanguage()->getTag() : '*';
$langSuffix = ($language !== '*') ? ' (' . $language . ')' : '';
// Create the menu types.
$menuTable = JTable::getInstance('Type', 'JTableMenu');
$menuTypes = array();
for ($i = 0; $i <= 2; $i++)
{
$menu = array(
'id' => 0,
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_' . $i . '_TITLE') . $langSuffix,
'description' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_' . $i . '_DESCRIPTION'),
);
// Calculate menutype. The number of characters allowed is 24.
$type = JHtml::_('string.truncate', $menu['title'], 23, true, false);
$menu['menutype'] = $i . $type;
try
{
$menuTable->load();
$menuTable->bind($menu);
if (!$menuTable->check())
{
throw new Exception($menuTable->getError());
}
$menuTable->store();
}
catch (Exception $e)
{
JFactory::getLanguage()->load('com_menus');
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 2, $e->getMessage());
return $response;
}
$menuTypes[] = $menuTable->menutype;
}
// Storing IDs in UserState for later usage.
$this->app->setUserState('sampledata.blog.menutypes', $menuTypes);
// Get previously entered Data from UserStates.
$articleIds = $this->app->getUserState('sampledata.blog.articles');
// Get MenuItemModel.
JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php');
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_menus/models/', 'MenusModel');
JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_menus/tables/');
$this->menuItemModel = JModelLegacy::getInstance('Item', 'MenusModel');
// Get previously entered categories ids
$catids = $this->app->getUserState('sampledata.blog.articles.catids');
// Insert menuitems level 1.
$menuItems = array(
array(
'menutype' => $menuTypes[0],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_0_TITLE'),
'link' => 'index.php?option=com_content&view=category&layout=blog&id=' . $catids[0],
'component_id' => 22,
'params' => array(
'layout_type' => 'blog',
'show_category_title' => 0,
'num_leading_articles' => 4,
'num_intro_articles' => 0,
'num_columns' => 1,
'num_links' => 2,
'multi_column_order' => 1,
'orderby_sec' => 'rdate',
'order_date' => 'published',
'show_pagination' => 2,
'show_pagination_results' => 1,
'show_category' => 0,
'info_bloc_position' => 0,
'show_publish_date' => 0,
'show_hits' => 0,
'show_feed_link' => 1,
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[0],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_1_TITLE'),
'link' => 'index.php?option=com_content&view=article&id=' . $articleIds[0],
'component_id' => 22,
'params' => array(
'info_block_position' => 0,
'show_category' => 0,
'link_category' => 0,
'show_author' => 0,
'show_create_date' => 0,
'show_publish_date' => 0,
'show_hits' => 0,
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[0],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_2_TITLE'),
'link' => 'index.php?option=com_users&view=login',
'component_id' => 25,
'params' => array(
'logindescription_show' => 1,
'logoutdescription_show' => 1,
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_3_TITLE'),
'link' => 'index.php?option=com_content&view=form&layout=edit',
'component_id' => 22,
'access' => 3,
'params' => array(
'enable_category' => 1,
'catid' => $catids[0],
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_4_TITLE'),
'link' => 'index.php?option=com_content&view=article&id=' . $articleIds[1],
'component_id' => 22,
'params' => array(
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_5_TITLE'),
'link' => 'administrator',
'type' => 'url',
'component_id' => 0,
'browserNav' => 1,
'access' => 3,
'params' => array(
'menu_text' => 1,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_6_TITLE'),
'link' => 'index.php?option=com_users&view=profile&layout=edit',
'component_id' => 25,
'access' => 2,
'params' => array(
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_7_TITLE'),
'link' => 'index.php?option=com_users&view=login',
'component_id' => 25,
'params' => array(
'logindescription_show' => 1,
'logoutdescription_show' => 1,
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
);
try
{
$menuIdsLevel1 = $this->addMenuItems($menuItems, 1);
}
catch (Exception $e)
{
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 2, $e->getMessage());
return $response;
}
// Insert another level 1.
$menuItems = array(
array(
'menutype' => $menuTypes[2],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_8_TITLE'),
'link' => 'index.php?option=com_users&view=login',
'component_id' => 25,
'params' => array(
'login_redirect_url' => 'index.php?Itemid=' . $menuIdsLevel1[0],
'logindescription_show' => 1,
'logoutdescription_show' => 1,
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
);
try
{
$menuIdsLevel1 = array_merge($menuIdsLevel1, $this->addMenuItems($menuItems, 1));
}
catch (Exception $e)
{
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 2, $e->getMessage());
return $response;
}
// Insert menuitems level 2.
$menuItems = array(
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_9_TITLE'),
'link' => 'index.php?option=com_config&view=config&controller=config.display.config',
'parent_id' => $menuIdsLevel1[4],
'component_id' => 23,
'access' => 6,
'params' => array(
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
array(
'menutype' => $menuTypes[1],
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_10_TITLE'),
'link' => 'index.php?option=com_config&view=templates&controller=config.display.templates',
'parent_id' => $menuIdsLevel1[4],
'component_id' => 23,
'params' => array(
'menu_text' => 1,
'show_page_heading' => 0,
'secure' => 0,
),
),
);
try
{
$this->addMenuItems($menuItems, 2);
}
catch (Exception $e)
{
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 2, $e->getMessage());
return $response;
}
$response = array();
$response['success'] = true;
$response['message'] = JText::_('PLG_SAMPLEDATA_BLOG_STEP2_SUCCESS');
return $response;
}
/**
* Third step to enter the sampledata. Modules.
*
* @return array or void Will be converted into the JSON response to the module.
*
* @since 3.8.0
*/
public function onAjaxSampledataApplyStep3()
{
if (!Session::checkToken('get') || $this->app->input->get('type') != $this->_name)
{
return;
}
if (!JComponentHelper::isEnabled('com_modules') || !Factory::getUser()->authorise('core.create', 'com_modules'))
{
$response = array();
$response['success'] = true;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_SKIPPED', 3, 'com_modules');
return $response;
}
// Detect language to be used.
$language = Multilanguage::isEnabled() ? JFactory::getLanguage()->getTag() : '*';
$langSuffix = ($language !== '*') ? ' (' . $language . ')' : '';
// Add Include Paths.
JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_modules/models/', 'ModulesModelModule');
JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_modules/tables/');
$model = JModelLegacy::getInstance('Module', 'ModulesModel');
$access = (int) $this->app->get('access', 1);
// Get previously entered Data from UserStates
$menuTypes = $this->app->getUserState('sampledata.blog.menutypes');
$catids = $this->app->getUserState('sampledata.blog.articles.catids');
$modules = array(
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_0_TITLE'),
'ordering' => 1,
'position' => 'position-1',
'module' => 'mod_menu',
'showtitle' => 0,
'params' => array(
'menutype' => $menuTypes[0],
'startLevel' => 1,
'endLevel' => 0,
'showAllChildren' => 0,
'class_sfx' => ' nav-pills',
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'itemid',
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_1_TITLE'),
'ordering' => 1,
'position' => 'position-1',
'module' => 'mod_menu',
'access' => 3,
'showtitle' => 0,
'params' => array(
'menutype' => $menuTypes[1],
'startLevel' => 1,
'endLevel' => 0,
'showAllChildren' => 1,
'class_sfx' => ' nav-pills',
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'itemid',
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_2_TITLE'),
'ordering' => 6,
'position' => 'position-7',
'module' => 'mod_syndicate',
'showtitle' => 0,
'params' => array(
'display_text' => 1,
'text' => 'My Blog',
'format' => 'rss',
'layout' => '_:default',
'cache' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_3_TITLE'),
'ordering' => 4,
'position' => 'position-7',
'module' => 'mod_articles_archive',
'params' => array(
'count' => 10,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'static',
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_4_TITLE'),
'ordering' => 5,
'position' => 'position-7',
'module' => 'mod_articles_popular',
'params' => array(
'catid' => $catids[0],
'count' => 5,
'show_front' => 1,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'static',
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_5_TITLE'),
'ordering' => 2,
'position' => 'position-7',
'module' => 'mod_articles_category',
'params' => array(
'mode' => 'normal',
'show_on_article_page' => 0,
'show_front' => 'show',
'count' => 6,
'category_filtering_type' => 1,
'catid' => $catids[0],
'show_child_category_articles' => 0,
'levels' => 1,
'author_filtering_type' => 1,
'author_alias_filtering_type' => 1,
'date_filtering' => 'off',
'date_field' => 'a.created',
'relative_date' => 30,
'article_ordering' => 'a.created',
'article_ordering_direction' => 'DESC',
'article_grouping' => 'none',
'article_grouping_direction' => 'krsort',
'month_year_format' => 'F Y',
'item_heading' => 5,
'link_titles' => 1,
'show_date' => 0,
'show_date_field' => 'created',
'show_date_format' => JText::_('DATE_FORMAT_LC5'),
'show_category' => 0,
'show_hits' => 0,
'show_author' => 0,
'show_introtext' => 0,
'introtext_limit' => 100,
'show_readmore' => 0,
'show_readmore_title' => 1,
'readmore_limit' => 15,
'layout' => '_:default',
'owncache' => 1,
'cache_time' => 900,
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_6_TITLE'),
'ordering' => 1,
'position' => 'footer',
'module' => 'mod_menu',
'showtitle' => 0,
'params' => array(
'menutype' => $menuTypes[2],
'startLevel' => 1,
'endLevel' => 0,
'showAllChildren' => 0,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'itemid',
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_7_TITLE'),
'ordering' => 1,
'position' => 'position-0',
'module' => 'mod_search',
'params' => array(
'width' => 20,
'button_pos' => 'right',
'opensearch' => 1,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'itemid',
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_8_TITLE'),
'content' => '<p><img src="images/headers/raindrops.jpg" alt="" /></p>',
'ordering' => 1,
'position' => 'position-3',
'module' => 'mod_custom',
'showtitle' => 0,
'params' => array(
'prepare_content' => 1,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'static',
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_9_TITLE'),
'ordering' => 1,
'position' => 'position-7',
'module' => 'mod_tags_popular',
'params' => array(
'maximum' => 8,
'timeframe' => 'alltime',
'order_value' => 'count',
'order_direction' => 1,
'display_count' => 0,
'no_results_text' => 0,
'minsize' => 1,
'maxsize' => 2,
'layout' => '_:default',
'owncache' => 1,
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_10_TITLE'),
'ordering' => 0,
'position' => '',
'module' => 'mod_tags_similar',
'params' => array(
'maximum' => 5,
'matchtype' => 'any',
'layout' => '_:default',
'owncache' => 1,
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_11_TITLE'),
'ordering' => 4,
'position' => 'cpanel',
'module' => 'mod_stats_admin',
'access' => 6,
'client_id' => 1,
'params' => array(
'serverinfo' => 1,
'siteinfo' => 1,
'counter' => 0,
'increase' => 0,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'cachemode' => 'static',
'module_tag' => 'div',
'bootstrap_size' => 6,
'header_tag' => 'h3',
'style' => 0,
),
),
array(
'title' => JText::_('PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_12_TITLE'),
'ordering' => 1,
'position' => 'postinstall',
'module' => 'mod_feed',
'client_id' => 1,
'params' => array(
'rssurl' => 'https://www.joomla.org/announcements/release-news.feed',
'rssrtl' => 0,
'rsstitle' => 1,
'rssdesc' => 1,
'rssimage' => 1,
'rssitems' => 3,
'rssitemdesc' => 1,
'word_count' => 0,
'layout' => '_:default',
'cache' => 1,
'cache_time' => 900,
'module_tag' => 'div',
'bootstrap_size' => 0,
'header_tag' => 'h3',
'style' => 0,
),
),
);
foreach ($modules as $module)
{
// Append language suffix to title.
$module['title'] .= $langSuffix;
// Set values which are always the same.
$module['id'] = 0;
$module['asset_id'] = 0;
$module['language'] = $language;
$module['note'] = '';
$module['published'] = 1;
$module['assignment'] = 0;
if (!isset($module['content']))
{
$module['content'] = '';
}
if (!isset($module['access']))
{
$module['access'] = $access;
}
if (!isset($module['showtitle']))
{
$module['showtitle'] = 1;
}
if (!isset($module['client_id']))
{
$module['client_id'] = 0;
}
if (!$model->save($module))
{
JFactory::getLanguage()->load('com_modules');
$response = array();
$response['success'] = false;
$response['message'] = JText::sprintf('PLG_SAMPLEDATA_BLOG_STEP_FAILED', 3, JText::_($model->getError()));
return $response;
}
}
$response = array();
$response['success'] = true;
$response['message'] = JText::_('PLG_SAMPLEDATA_BLOG_STEP3_SUCCESS');
return $response;
}
/**
* Adds menuitems.
*
* @param array $menuItems Array holding the menuitems arrays.
* @param integer $level Level in the category tree.
*
* @return array IDs of the inserted menuitems.
*
* @since 3.8.0
*
* @throws Exception
*/
private function addMenuItems(array $menuItems, $level)
{
$itemIds = array();
$access = (int) $this->app->get('access', 1);
$user = JFactory::getUser();
// Detect language to be used.
$language = Multilanguage::isEnabled() ? JFactory::getLanguage()->getTag() : '*';
$langSuffix = ($language !== '*') ? ' (' . $language . ')' : '';
foreach ($menuItems as $menuItem)
{
// Reset item.id in model state.
$this->menuItemModel->setState('item.id', 0);
// Set values which are always the same.
$menuItem['id'] = 0;
$menuItem['created_user_id'] = $user->id;
$menuItem['alias'] = JApplicationHelper::stringURLSafe($menuItem['title']);
// Set unicodeslugs if alias is empty
if (trim(str_replace('-', '', $menuItem['alias']) == ''))
{
$unicode = JFactory::getConfig()->set('unicodeslugs', 1);
$menuItem['alias'] = JApplicationHelper::stringURLSafe($menuItem['title']);
JFactory::getConfig()->set('unicodeslugs', $unicode);
}
// Append language suffix to title.
$menuItem['title'] .= $langSuffix;
$menuItem['published'] = 1;
$menuItem['language'] = $language;
$menuItem['note'] = '';
$menuItem['img'] = '';
$menuItem['associations'] = array();
$menuItem['client_id'] = 0;
$menuItem['level'] = $level;
$menuItem['home'] = 0;
// Set browserNav to default if not set
if (!isset($menuItem['browserNav']))
{
$menuItem['browserNav'] = 0;
}
// Set access to default if not set
if (!isset($menuItem['access']))
{
$menuItem['access'] = $access;
}
// Set type to 'component' if not set
if (!isset($menuItem['type']))
{
$menuItem['type'] = 'component';
}
// Set template_style_id to global if not set
if (!isset($menuItem['template_style_id']))
{
$menuItem['template_style_id'] = 0;
}
// Set parent_id to root (1) if not set
if (!isset($menuItem['parent_id']))
{
$menuItem['parent_id'] = 1;
}
if (!$this->menuItemModel->save($menuItem))
{
// Try two times with another alias (-1 and -2).
$menuItem['alias'] .= '-1';
if (!$this->menuItemModel->save($menuItem))
{
$menuItem['alias'] = substr_replace($menuItem['alias'], '2', -1);
if (!$this->menuItemModel->save($menuItem))
{
throw new Exception($menuItem['title'] . ' => ' . $menuItem['alias'] . ' : ' . $this->menuItemModel->getError());
}
}
}
// Get ID from menuitem we just added
$itemIds[] = $this->menuItemModel->getstate('item.id');
}
return $itemIds;
}
}
sampledata/blog/blog.xml 0000604 00000001504 15245362375 0011257 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.8" type="plugin" group="sampledata" method="upgrade">
<name>plg_sampledata_blog</name>
<author>Joomla! Project</author>
<creationDate>July 2017</creationDate>
<copyright>(C) 2017 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.8.0</version>
<description>PLG_SAMPLEDATA_BLOG_XML_DESCRIPTION</description>
<files>
<filename plugin="blog">blog.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_sampledata_blog.ini</language>
<language tag="en-GB">en-GB.plg_sampledata_blog.sys.ini</language>
</languages>
<config>
<fields name="params">
</fields>
</config>
</extension>
privacy/content/content.php 0000604 00000003210 15245362375 0012062 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.content
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
/**
* Privacy plugin managing Joomla user content data
*
* @since 3.9.0
*/
class PlgPrivacyContent extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user content data
*
* This event will collect data for the content core table
*
* - Content custom fields
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user)
{
return array();
}
$domains = array();
$domain = $this->createDomain('user_content', 'joomla_user_content_data');
$domains[] = $domain;
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__content'))
->where($this->db->quoteName('created_by') . ' = ' . (int) $user->id)
->order($this->db->quoteName('ordering') . ' ASC');
$items = $this->db->setQuery($query)->loadObjectList();
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray((array) $item));
}
$domains[] = $this->createCustomFieldsDomain('com_content.article', $items);
return $domains;
}
}
privacy/content/content.xml 0000604 00000001415 15245362375 0012100 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.9" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_content</name>
<author>Joomla! Project</author>
<creationDate>July 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONTENT_XML_DESCRIPTION</description>
<files>
<filename plugin="content">content.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_content.ini</language>
<language tag="en-GB">en-GB.plg_privacy_content.sys.ini</language>
</languages>
</extension>
privacy/contact/contact.php 0000604 00000003457 15245362375 0012041 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.contact
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
/**
* Privacy plugin managing Joomla user contact data
*
* @since 3.9.0
*/
class PlgPrivacyContact extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user contact data
*
* This event will collect data for the contact core tables:
*
* - Contact custom fields
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user && !$request->email)
{
return array();
}
$domains = array();
$domain = $this->createDomain('user_contact', 'joomla_user_contact_data');
$domains[] = $domain;
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__contact_details'))
->order($this->db->quoteName('ordering') . ' ASC');
if ($user)
{
$query->where($this->db->quoteName('user_id') . ' = ' . (int) $user->id);
}
else
{
$query->where($this->db->quoteName('email_to') . ' = ' . $this->db->quote($request->email));
}
$items = $this->db->setQuery($query)->loadObjectList();
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray((array) $item));
}
$domains[] = $this->createCustomFieldsDomain('com_contact.contact', $items);
return $domains;
}
}
privacy/contact/contact.xml 0000604 00000001415 15245362375 0012042 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.9" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_contact</name>
<author>Joomla! Project</author>
<creationDate>July 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONTACT_XML_DESCRIPTION</description>
<files>
<filename plugin="contact">contact.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_contact.ini</language>
<language tag="en-GB">en-GB.plg_privacy_contact.sys.ini</language>
</languages>
</extension>
privacy/user/user.xml 0000604 00000001372 15245362375 0010712 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_user</name>
<author>Joomla! Project</author>
<creationDate>May 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_USER_XML_DESCRIPTION</description>
<files>
<filename plugin="user">user.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_user.ini</language>
<language tag="en-GB">en-GB.plg_privacy_user.sys.ini</language>
</languages>
</extension>
privacy/user/user.php 0000604 00000013507 15245362375 0010704 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.user
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\User\UserHelper;
use Joomla\Utilities\ArrayHelper;
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
JLoader::register('PrivacyRemovalStatus', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/removal/status.php');
/**
* Privacy plugin managing Joomla user data
*
* @since 3.9.0
*/
class PlgPrivacyUser extends PrivacyPlugin
{
/**
* Performs validation to determine if the data associated with a remove information request can be processed
*
* This event will not allow a super user account to be removed
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyRemovalStatus
*
* @since 3.9.0
*/
public function onPrivacyCanRemoveData(PrivacyTableRequest $request, JUser $user = null)
{
$status = new PrivacyRemovalStatus;
if (!$user)
{
return $status;
}
if ($user->authorise('core.admin'))
{
$status->canRemove = false;
$status->reason = JText::_('PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER');
}
return $status;
}
/**
* Processes an export request for Joomla core user data
*
* This event will collect data for the following core tables:
*
* - #__users (excluding the password, otpKey, and otep columns)
* - #__user_notes
* - #__user_profiles
* - User custom fields
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user)
{
return array();
}
/** @var JTableUser $userTable */
$userTable = JUser::getTable();
$userTable->load($user->id);
$domains = array();
$domains[] = $this->createUserDomain($userTable);
$domains[] = $this->createNotesDomain($userTable);
$domains[] = $this->createProfileDomain($userTable);
$domains[] = $this->createCustomFieldsDomain('com_users.user', array($userTable));
return $domains;
}
/**
* Removes the data associated with a remove information request
*
* This event will pseudoanonymise the user account
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return void
*
* @since 3.9.0
*/
public function onPrivacyRemoveData(PrivacyTableRequest $request, JUser $user = null)
{
// This plugin only processes data for registered user accounts
if (!$user)
{
return;
}
$pseudoanonymisedData = array(
'name' => 'User ID ' . $user->id,
'username' => bin2hex(random_bytes(12)),
'email' => 'UserID' . $user->id . 'removed@email.invalid',
'block' => true,
);
$user->bind($pseudoanonymisedData);
$user->save();
// Destroy all sessions for the user account
UserHelper::destroyUserSessions($user->id);
}
/**
* Create the domain for the user notes data
*
* @param JTableUser $user The JTableUser object to process
*
* @return PrivacyExportDomain
*
* @since 3.9.0
*/
private function createNotesDomain(JTableUser $user)
{
$domain = $this->createDomain('user_notes', 'joomla_user_notes_data');
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__user_notes'))
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($user->id));
$items = $this->db->setQuery($query)->loadAssocList();
// Remove user ID columns
foreach (array('user_id', 'created_user_id', 'modified_user_id') as $column)
{
$items = ArrayHelper::dropColumn($items, $column);
}
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray($item, $item['id']));
}
return $domain;
}
/**
* Create the domain for the user profile data
*
* @param JTableUser $user The JTableUser object to process
*
* @return PrivacyExportDomain
*
* @since 3.9.0
*/
private function createProfileDomain(JTableUser $user)
{
$domain = $this->createDomain('user_profile', 'joomla_user_profile_data');
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__user_profiles'))
->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($user->id))
->order($this->db->quoteName('ordering') . ' ASC');
$items = $this->db->setQuery($query)->loadAssocList();
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray($item));
}
return $domain;
}
/**
* Create the domain for the user record
*
* @param JTableUser $user The JTableUser object to process
*
* @return PrivacyExportDomain
*
* @since 3.9.0
*/
private function createUserDomain(JTableUser $user)
{
$domain = $this->createDomain('users', 'joomla_users_data');
$domain->addItem($this->createItemForUserTable($user));
return $domain;
}
/**
* Create an item object for a JTableUser object
*
* @param JTableUser $user The JTableUser object to convert
*
* @return PrivacyExportItem
*
* @since 3.9.0
*/
private function createItemForUserTable(JTableUser $user)
{
$data = array();
$exclude = array('password', 'otpKey', 'otep');
foreach (array_keys($user->getFields()) as $fieldName)
{
if (!in_array($fieldName, $exclude))
{
$data[$fieldName] = $user->$fieldName;
}
}
return $this->createItemFromArray($data, $user->id);
}
}
privacy/actionlogs/actionlogs.xml 0000604 00000001437 15245362375 0013264 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_actionlogs</name>
<author>Joomla! Project</author>
<creationDate>July 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION</description>
<files>
<filename plugin="actionlogs">actionlogs.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_actionlogs.ini</language>
<language tag="en-GB">en-GB.plg_privacy_actionlogs.sys.ini</language>
</languages>
</extension>
privacy/actionlogs/actionlogs.php 0000604 00000003334 15245362375 0013251 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.actionlogs
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php');
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
/**
* Privacy plugin managing Joomla actionlogs data
*
* @since 3.9.0
*/
class PlgPrivacyActionlogs extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core actionlog data
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user)
{
return array();
}
$domain = $this->createDomain('user_action_logs', 'joomla_user_action_logs_data');
$query = $this->db->getQuery(true)
->select('a.*, u.name')
->from('#__action_logs AS a')
->innerJoin('#__users AS u ON a.user_id = u.id')
->where($this->db->quoteName('a.user_id') . ' = ' . (int) $user->id);
$this->db->setQuery($query);
$data = $this->db->loadObjectList();
if (!count($data))
{
return array();
}
$data = ActionlogsHelper::getCsvData($data);
$isFirst = true;
foreach ($data as $item)
{
if ($isFirst)
{
$isFirst = false;
continue;
}
$domain->addItem($this->createItemFromArray($item));
}
return array($domain);
}
}
privacy/consents/consents.php 0000604 00000002761 15245362375 0012440 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.consents
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
/**
* Privacy plugin managing Joomla user consent data
*
* @since 3.9.0
*/
class PlgPrivacyConsents extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user consent data
*
* This event will collect data for the core `#__privacy_consents` table
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user)
{
return array();
}
$domain = $this->createDomain('consents', 'joomla_consent_data');
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__privacy_consents'))
->where($this->db->quoteName('user_id') . ' = ' . (int) $user->id)
->order($this->db->quoteName('created') . ' ASC');
$items = $this->db->setQuery($query)->loadAssocList();
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray($item));
}
return array($domain);
}
}
privacy/consents/consents.xml 0000604 00000001423 15245362375 0012443 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.9" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_consents</name>
<author>Joomla! Project</author>
<creationDate>July 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_CONSENTS_XML_DESCRIPTION</description>
<files>
<filename plugin="consents">consents.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_consents.ini</language>
<language tag="en-GB">en-GB.plg_privacy_consents.sys.ini</language>
</languages>
</extension>
privacy/message/message.php 0000604 00000003045 15245362375 0012014 0 ustar 00 <?php
/**
* @package Joomla.Plugin
* @subpackage Privacy.message
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
JLoader::register('PrivacyPlugin', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/plugin.php');
/**
* Privacy plugin managing Joomla user messages
*
* @since 3.9.0
*/
class PlgPrivacyMessage extends PrivacyPlugin
{
/**
* Processes an export request for Joomla core user message
*
* This event will collect data for the message table
*
* @param PrivacyTableRequest $request The request record being processed
* @param JUser $user The user account associated with this request if available
*
* @return PrivacyExportDomain[]
*
* @since 3.9.0
*/
public function onPrivacyExportRequest(PrivacyTableRequest $request, JUser $user = null)
{
if (!$user)
{
return array();
}
$domain = $this->createDomain('user_messages', 'joomla_user_messages_data');
$query = $this->db->getQuery(true)
->select('*')
->from($this->db->quoteName('#__messages'))
->where($this->db->quoteName('user_id_from') . ' = ' . (int) $user->id)
->orWhere($this->db->quoteName('user_id_to') . ' = ' . (int) $user->id)
->order($this->db->quoteName('date_time') . ' ASC');
$items = $this->db->setQuery($query)->loadAssocList();
foreach ($items as $item)
{
$domain->addItem($this->createItemFromArray($item));
}
return array($domain);
}
}
privacy/message/message.xml 0000604 00000001415 15245362375 0012024 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.9" type="plugin" group="privacy" method="upgrade">
<name>plg_privacy_message</name>
<author>Joomla! Project</author>
<creationDate>July 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_PRIVACY_MESSAGE_XML_DESCRIPTION</description>
<files>
<filename plugin="message">message.php</filename>
</files>
<languages>
<language tag="en-GB">en-GB.plg_privacy_message.ini</language>
<language tag="en-GB">en-GB.plg_privacy_message.sys.ini</language>
</languages>
</extension>
acymailing/share/share.xml 0000604 00000007222 15245362375 0011622 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" version="2.5" method="upgrade" group="acymailing">
<name>AcyMailing : share on social networks</name>
<creationDate>August 2010</creationDate>
<version>1.0.0</version>
<author>Acyba</author>
<authorEmail>dev@acyba.com</authorEmail>
<authorUrl>http://www.acyba.com</authorUrl>
<copyright>Copyright (C) 2009-2018 ACYBA SAS - All rights reserved..</copyright>
<license>GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html</license>
<description>This plugin enables you to add a share icon for social networks</description>
<files>
<filename plugin="share">share.php</filename>
</files>
<params addpath="/components/com_acymailing/params">
<param name="help" type="help" label="Help" description="Click on the help button to get some help" default="plugin-share"/>
<param name="template" type="radio" default="component" label="Display the online version" description="Select if you want to display the online version (when the user will share your link on the social network) without any Joomla module (no template) or inside your default Joomla Template">
<option value="standard">Standard template</option>
<option value="component">No template</option>
</param>
<param name="picturefb" type="text" label="Facebook picture - DEPRECATED" default="media/com_acymailing/images/facebookshare.png" />
<param name="picturetwitter" type="text" label="Twitter picture - DEPRECATED" default="media/com_acymailing/images/twittershare.png" />
<param name="picturelinkedin" type="text" label="LinkedIn picture - DEPRECATED" default="media/com_acymailing/images/linkedin.png" />
<param name="picturegoogleplus" type="text" label="Google+ picture - DEPRECATED" default="media/com_acymailing/images/google_plusshare.png" />
<param name="frontendaccess" type="list" default="all" label="Front-end Access" description="You can restrict the access to this tag system with this option">
<option value="all">Always display this tag system</option>
<option value="none">Don't display this tag system on the front-end</option>
</param>
</params>
<config>
<fields name="params" addfieldpath="/components/com_acymailing/params">
<fieldset name="basic">
<field name="help" type="help" label="Help" description="Click on the help button to get some help" default="plugin-share"/>
<field name="template" type="radio" default="component" label="Display the online version" description="Select if you want to display the online version (when the user will share your link on the social network) without any Joomla module (no template) or inside your default Joomla Template">
<option value="standard">Standard template</option>
<option value="component">No template</option>
</field>
<field name="picturefb" type="text" label="Facebook picture - DEPRECATED" default="media/com_acymailing/images/facebookshare.png" />
<field name="picturetwitter" type="text" label="Twitter picture - DEPRECATED" default="media/com_acymailing/images/twittershare.png" />
<field name="picturelinkedin" type="text" label="LinkedIn picture - DEPRECATED" default="media/com_acymailing/images/linkedin.png" />
<field name="picturegoogleplus" type="text" label="Google+ picture - DEPRECATED" default="media/com_acymailing/images/google_plusshare.png" />
<field name="frontendaccess" type="list" default="all" label="Front-end Access" description="You can restrict the access to this tag system with this option">
<option value="all">Always display this tag system</option>
<option value="none">Don't display this tag system on the front-end</option>
</field>
</fieldset>
</fields>
</config>
</extension>
acymailing/share/share.php 0000604 00000021016 15245362375 0011606 0 ustar 00 <?php
/**
* @package AcyMailing for Joomla!
* @version 5.9.6
* @author acyba.com
* @copyright (C) 2009-2018 ACYBA S.A.R.L. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
class plgAcymailingShare extends JPlugin{
var $pictresults = array();
function __construct(&$subject, $config){
parent::__construct($subject, $config);
if(!isset($this->params)){
$plugin = JPluginHelper::getPlugin('acymailing', 'share');
$this->params = new acyParameter($plugin->params);
}
}
function acymailing_getPluginType(){
if($this->params->get('frontendaccess') == 'none' && !acymailing_isAdmin()) return;
$onePlugin = new stdClass();
$onePlugin->name = acymailing_translation_sprintf('SOCIAL_SHARE', '...');
$onePlugin->function = 'acymailingtagshare_show';
$onePlugin->help = 'plugin-share';
return $onePlugin;
}
function _getPictures($folder){
$allFolders = acymailing_getFolders($folder);
foreach($allFolders as $oneFolder){
$this->_getPictures($folder.DS.$oneFolder);
}
$allFiles = acymailing_getFiles($folder, $this->regex);
foreach($allFiles as $oneFile){
$this->pictresults[substr($oneFile, 0, 4)][$oneFile.filesize($folder.DS.$oneFile)] = $folder.DS.$oneFile;
}
}
function acymailingtagshare_show(){
$uploadFolders = acymailing_getFilesFolder('upload', true);
$uploadFolder = acymailing_getVar('string', 'currentFolder', $uploadFolders[0]);
$uploadPath = acymailing_cleanPath(ACYMAILING_ROOT.trim(str_replace('/', DS, trim($uploadFolder)), DS));
$uploadedFile = acymailing_getVar('array', 'socialfile', array(), 'files');
if(!empty($uploadedFile) && !empty($uploadedFile['name'])){
$uploadedFile['name'] = acymailing_getVar('string', 'socialchoice').substr($uploadedFile['name'], strrpos($uploadedFile['name'], '.'));
acymailing_importFile($uploadedFile, $uploadPath, true, 150);
}
$networks = array();
$networks['facebook'] = 'Facebook';
$networks['linkedin'] = 'LinkedIn';
$networks['twitter'] = 'Twitter';
$networks['google'] = 'Google+';
$networks['print'] = acymailing_translation('ACY_PRINT');
$k = 0;
$this->regex = '('.implode('|', array_keys($networks)).').*(png|gif|jpeg|jpg)';
$this->_getPictures(ACYMAILING_MEDIA);
$socialList = array();
$socialList[] = acymailing_selectOption('facebook', 'Facebook');
$socialList[] = acymailing_selectOption('linkedIn', 'LinkedIn');
$socialList[] = acymailing_selectOption('twitter', 'Twitter');
$socialList[] = acymailing_selectOption('google', 'Google+');
$socialChoice = acymailing_select($socialList, 'socialchoice', 'size="1" style="width:100px;"');
?>
<br style="clear:both;">
<div class="onelineblockoptions">
<span class="acyblocktitle"><?php echo acymailing_translation('UPLOAD_NEW_IMAGE'); ?></span>
<table>
<tr>
<td style="padding: 5px;"><?php echo $socialChoice; ?></td>
<td style="padding: 5px;"><input type="file" name="socialfile"></td>
<td style="padding: 5px;"><input class="acymailing_button_grey" type="submit" value="Upload"></td>
</tr>
</table>
</div>
<?php
foreach($networks as $name => $desc){
$shortName = substr($name, 0, 4);
if(empty($this->pictresults[$shortName])) continue;
if($desc == acymailing_translation('ACY_PRINT')){
$legendTxt = $desc;
}else{
$legendTxt = acymailing_translation_sprintf('SOCIAL_SHARE', $desc);
}
echo '<div class="onelineblockoptions">
<span class="acyblocktitle">'.$legendTxt.'</span>';
foreach($this->pictresults[$shortName] as $onePict){
$imgPath = preg_replace('#^'.preg_quote(ACYMAILING_ROOT, '#').'#i', ACYMAILING_LIVE, $onePict);
$imgPath = str_replace(DS, '/', $imgPath);
if($desc == acymailing_translation('ACY_PRINT')){
$insertedtag = '<a target="_blank" href="{print:newsletter}" title="'.acymailing_translation('ACY_PRINT').'" ><img src="'.$imgPath.'" alt="'.$desc.'" /></a>';
}else{
$insertedtag = '<a target="_blank" href="{sharelink:'.$name.'}" title="'.acymailing_translation_sprintf('SOCIAL_SHARE', $desc).'" ><img src="'.$imgPath.'" alt="'.$desc.'" /></a>';
}
echo '<img style="max-width:200px;cursor:pointer;padding:5px;" onclick="setTag(\''.htmlentities($insertedtag).'\');insertTag();" src="'.$imgPath.'" />';
}
echo '</div>';
$k = 1 - $k;
}
}
function acymailing_replacetags(&$email, $send = true){
if(acymailing_getVar('none', 'task', '') == 'replacetags') return;
$this->_print($email, $send);
$this->_shareButtons($email, $send);
}
function _shareButtons(&$email, $send = true){
$match = '#(?:{|%7B)(share|sharelink):(.*)(?:}|%7D)#Ui';
$variables = array('body', 'altbody');
$found = false;
$results = array();
foreach($variables as $var){
if(empty($email->$var)) continue;
$found = preg_match_all($match, $email->$var, $results[$var]) || $found;
if(empty($results[$var][0])) unset($results[$var]);
}
if(!$found) return;
$archiveLink = acymailing_frontendLink('index.php?option=com_acymailing&ctrl=archive&task=view&mailid='.$email->mailid, false, $this->params->get('template', 'component') == 'component' ? true : false);
if(empty($email->published)){
$archiveLink .= (strpos($archiveLink, '?') ? '&' : '?').'time='.time();
}
$tags = array();
foreach($results as $var => $allresults){
foreach($allresults[0] as $numres => $tagname){
if(isset($tags[$tagname])) continue;
$arguments = explode('|', $allresults[2][$numres]);
$tag = new stdClass();
$tag->network = $arguments[0];
for($i = 1, $a = count($arguments); $i < $a; $i++){
$args = explode(':', $arguments[$i]);
if(isset($args[1])){
$tag->{$args[0]} = $args[1];
}else{
$tag->{$args[0]} = true;
}
}
$link = '';
if($tag->network == 'facebook'){
$link = 'http://www.facebook.com/sharer.php?u='.urlencode($archiveLink).'&t='.urlencode($email->subject);
$tags[$tagname] = '<a target="_blank" href="'.$link.'" title="'.acymailing_translation_sprintf('SOCIAL_SHARE', 'Facebook').'"><img alt="Facebook" src="'.ACYMAILING_LIVE.$this->params->get('picturefb', 'media/com_acymailing/images/facebookshare.png').'" /></a>';
}elseif($tag->network == 'twitter'){
$text = acymailing_translation_sprintf('SHARE_TEXT', $archiveLink);
$link = 'http://twitter.com/home?status='.urlencode($text);
$tags[$tagname] = '<a target="_blank" href="'.$link.'" title="'.acymailing_translation_sprintf('SOCIAL_SHARE', 'Twitter').'"><img alt="Twitter" src="'.ACYMAILING_LIVE.$this->params->get('picturetwitter', 'media/com_acymailing/images/twittershare.png').'" /></a>';
}elseif($tag->network == 'linkedin'){
$link = 'http://www.linkedin.com/shareArticle?mini=true&url='.urlencode($archiveLink).'&title='.urlencode($email->subject);
$tags[$tagname] = '<a target="_blank" href="'.$link.'" title="'.acymailing_translation_sprintf('SOCIAL_SHARE', 'LinkedIn').'"><img alt="LinkedIn" src="'.ACYMAILING_LIVE.$this->params->get('picturelinkedin', 'media/com_acymailing/images/linkedin.png').'" /></a>';
}elseif($tag->network == 'google'){
$link = 'https://plus.google.com/share?url='.urlencode($archiveLink);
$tags[$tagname] = '<a target="_blank" href="'.$link.'" title="'.acymailing_translation_sprintf('SOCIAL_SHARE', 'Google+').'"><img alt="Google+" src="'.ACYMAILING_LIVE.$this->params->get('picturegoogleplus', 'media/com_acymailing/images/google_plusshare.png').'" /></a>';
}
if($allresults[1][$numres] == 'sharelink'){
$tags[$tagname] = $link;
}
if(file_exists(ACYMAILING_MEDIA.'plugins'.DS.'share.php')){
ob_start();
require(ACYMAILING_MEDIA.'plugins'.DS.'share.php');
$tags[$tagname] = ob_get_clean();
}
}
}
$email->body = str_replace(array_keys($tags), $tags, $email->body);
$email->altbody = str_replace(array_keys($tags), '', $email->altbody);
}
private function _print(&$email, $send = true){
$variables = array('subject', 'body', 'altbody');
$acypluginsHelper = acymailing_get('helper.acyplugins');
$tags = $acypluginsHelper->extractTags($email, 'print');
$archiveLink = acymailing_frontendLink('index.php?option=com_acymailing&ctrl=archive&task=view&mailid='.$email->mailid, true, $this->params->get('template', 'component') == 'component' ? true : false);
$addkey = (!empty($email->key)) ? '&key='.$email->key : '';
$adduserkey = '&subid={subtag:subid}-{subtag:key}';
$link = $archiveLink.'&print=1'.$addkey.$adduserkey;
foreach($variables as $var){
if(empty($email->$var)) continue;
$email->$var = str_replace(array_keys($tags), $link, $email->$var);
}
}
}//endclass
acymailing/share/index.html 0000604 00000000054 15245362375 0011767 0 ustar 00 <html><body bgcolor="#FFFFFF"></body></html>