merge
This commit is contained in:
commit
046a724272
4209 changed files with 1186656 additions and 0 deletions
646
www/analytics/plugins/UsersManager/API.php
Normal file
646
www/analytics/plugins/UsersManager/API.php
Normal file
|
|
@ -0,0 +1,646 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\UsersManager;
|
||||
|
||||
use Exception;
|
||||
use Piwik\Access;
|
||||
use Piwik\Common;
|
||||
use Piwik\Config;
|
||||
use Piwik\Date;
|
||||
use Piwik\Option;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Site;
|
||||
use Piwik\Tracker\Cache;
|
||||
|
||||
/**
|
||||
* The UsersManager API lets you Manage Users and their permissions to access specific websites.
|
||||
*
|
||||
* You can create users via "addUser", update existing users via "updateUser" and delete users via "deleteUser".
|
||||
* There are many ways to list users based on their login "getUser" and "getUsers", their email "getUserByEmail",
|
||||
* or which users have permission (view or admin) to access the specified websites "getUsersWithSiteAccess".
|
||||
*
|
||||
* Existing Permissions are listed given a login via "getSitesAccessFromUser", or a website ID via "getUsersAccessFromSite",
|
||||
* or you can list all users and websites for a given permission via "getUsersSitesFromAccess". Permissions are set and updated
|
||||
* via the method "setUserAccess".
|
||||
* See also the documentation about <a href='http://piwik.org/docs/manage-users/' target='_blank'>Managing Users</a> in Piwik.
|
||||
*/
|
||||
class API extends \Piwik\Plugin\API
|
||||
{
|
||||
/**
|
||||
* @var Model
|
||||
*/
|
||||
private $model;
|
||||
|
||||
const PREFERENCE_DEFAULT_REPORT = 'defaultReport';
|
||||
const PREFERENCE_DEFAULT_REPORT_DATE = 'defaultReportDate';
|
||||
|
||||
static private $instance = null;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$this->model = new Model();
|
||||
}
|
||||
|
||||
/**
|
||||
* You can create your own Users Plugin to override this class.
|
||||
* Example of how you would overwrite the UsersManager_API with your own class:
|
||||
* Call the following in your plugin __construct() for example:
|
||||
*
|
||||
* Registry::set('UsersManager_API', \Piwik\Plugins\MyCustomUsersManager\API::getInstance());
|
||||
*
|
||||
* @throws Exception
|
||||
* @return \Piwik\Plugins\UsersManager\API
|
||||
*/
|
||||
static public function getInstance()
|
||||
{
|
||||
try {
|
||||
$instance = \Piwik\Registry::get('UsersManager_API');
|
||||
if (!($instance instanceof API)) {
|
||||
// Exception is caught below and corrected
|
||||
throw new Exception('UsersManager_API must inherit API');
|
||||
}
|
||||
self::$instance = $instance;
|
||||
} catch (Exception $e) {
|
||||
self::$instance = new self;
|
||||
\Piwik\Registry::set('UsersManager_API', self::$instance);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a user preference
|
||||
* @param string $userLogin
|
||||
* @param string $preferenceName
|
||||
* @param string $preferenceValue
|
||||
* @return void
|
||||
*/
|
||||
public function setUserPreference($userLogin, $preferenceName, $preferenceValue)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
|
||||
Option::set($this->getPreferenceId($userLogin, $preferenceName), $preferenceValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user preference
|
||||
* @param string $userLogin
|
||||
* @param string $preferenceName
|
||||
* @return bool|string
|
||||
*/
|
||||
public function getUserPreference($userLogin, $preferenceName)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
|
||||
|
||||
$optionValue = Option::get($this->getPreferenceId($userLogin, $preferenceName));
|
||||
if ($optionValue !== false) {
|
||||
return $optionValue;
|
||||
}
|
||||
return $this->getDefaultUserPreference($preferenceName, $userLogin);
|
||||
}
|
||||
|
||||
private function getPreferenceId($login, $preference)
|
||||
{
|
||||
return $login . '_' . $preference;
|
||||
}
|
||||
|
||||
private function getDefaultUserPreference($preferenceName, $login)
|
||||
{
|
||||
switch ($preferenceName) {
|
||||
case self::PREFERENCE_DEFAULT_REPORT:
|
||||
$viewableSiteIds = \Piwik\Plugins\SitesManager\API::getInstance()->getSitesIdWithAtLeastViewAccess($login);
|
||||
return reset($viewableSiteIds);
|
||||
case self::PREFERENCE_DEFAULT_REPORT_DATE:
|
||||
return Config::getInstance()->General['default_day'];
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all the users
|
||||
*
|
||||
* @param string $userLogins Comma separated list of users to select. If not specified, will return all users
|
||||
* @return array the list of all the users
|
||||
*/
|
||||
public function getUsers($userLogins = '')
|
||||
{
|
||||
Piwik::checkUserHasSomeAdminAccess();
|
||||
|
||||
$logins = array();
|
||||
if (!empty($userLogins)) {
|
||||
$logins = explode(',', $userLogins);
|
||||
}
|
||||
|
||||
$users = $this->model->getUsers($logins);
|
||||
|
||||
// Non Super user can only access login & alias
|
||||
if (!Piwik::hasUserSuperUserAccess()) {
|
||||
foreach ($users as &$user) {
|
||||
$user = array('login' => $user['login'], 'alias' => $user['alias']);
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all the users login
|
||||
*
|
||||
* @return array the list of all the users login
|
||||
*/
|
||||
public function getUsersLogin()
|
||||
{
|
||||
Piwik::checkUserHasSomeAdminAccess();
|
||||
|
||||
return $this->model->getUsersLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* For each user, returns the list of website IDs where the user has the supplied $access level.
|
||||
* If a user doesn't have the given $access to any website IDs,
|
||||
* the user will not be in the returned array.
|
||||
*
|
||||
* @param string Access can have the following values : 'view' or 'admin'
|
||||
*
|
||||
* @return array The returned array has the format
|
||||
* array(
|
||||
* login1 => array ( idsite1,idsite2),
|
||||
* login2 => array(idsite2),
|
||||
* ...
|
||||
* )
|
||||
*/
|
||||
public function getUsersSitesFromAccess($access)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
|
||||
$this->checkAccessType($access);
|
||||
|
||||
return $this->model->getUsersSitesFromAccess($access);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each user, returns his access level for the given $idSite.
|
||||
* If a user doesn't have any access to the $idSite ('noaccess'),
|
||||
* the user will not be in the returned array.
|
||||
*
|
||||
* @param int $idSite website ID
|
||||
*
|
||||
* @return array The returned array has the format
|
||||
* array(
|
||||
* login1 => 'view',
|
||||
* login2 => 'admin',
|
||||
* login3 => 'view',
|
||||
* ...
|
||||
* )
|
||||
*/
|
||||
public function getUsersAccessFromSite($idSite)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
|
||||
return $this->model->getUsersAccessFromSite($idSite);
|
||||
}
|
||||
|
||||
public function getUsersWithSiteAccess($idSite, $access)
|
||||
{
|
||||
Piwik::checkUserHasAdminAccess($idSite);
|
||||
$this->checkAccessType($access);
|
||||
|
||||
$logins = $this->model->getUsersLoginWithSiteAccess($idSite, $access);
|
||||
|
||||
if (empty($logins)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$logins = implode(',', $logins);
|
||||
return $this->getUsers($logins);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each website ID, returns the access level of the given $userLogin.
|
||||
* If the user doesn't have any access to a website ('noaccess'),
|
||||
* this website will not be in the returned array.
|
||||
* If the user doesn't have any access, the returned array will be an empty array.
|
||||
*
|
||||
* @param string $userLogin User that has to be valid
|
||||
*
|
||||
* @return array The returned array has the format
|
||||
* array(
|
||||
* idsite1 => 'view',
|
||||
* idsite2 => 'admin',
|
||||
* idsite3 => 'view',
|
||||
* ...
|
||||
* )
|
||||
*/
|
||||
public function getSitesAccessFromUser($userLogin)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$this->checkUserExists($userLogin);
|
||||
$this->checkUserHasNotSuperUserAccess($userLogin);
|
||||
|
||||
return $this->model->getSitesAccessFromUser($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user information (login, password md5, alias, email, date_registered, etc.)
|
||||
*
|
||||
* @param string $userLogin the user login
|
||||
*
|
||||
* @return array the user information
|
||||
*/
|
||||
public function getUser($userLogin)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
|
||||
$this->checkUserExists($userLogin);
|
||||
|
||||
return $this->model->getUser($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user information (login, password md5, alias, email, date_registered, etc.)
|
||||
*
|
||||
* @param string $userEmail the user email
|
||||
*
|
||||
* @return array the user information
|
||||
*/
|
||||
public function getUserByEmail($userEmail)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$this->checkUserEmailExists($userEmail);
|
||||
|
||||
return $this->model->getUserByEmail($userEmail);
|
||||
}
|
||||
|
||||
private function checkLogin($userLogin)
|
||||
{
|
||||
if ($this->userExists($userLogin)) {
|
||||
throw new Exception(Piwik::translate('UsersManager_ExceptionLoginExists', $userLogin));
|
||||
}
|
||||
|
||||
Piwik::checkValidLoginString($userLogin);
|
||||
}
|
||||
|
||||
private function checkEmail($email)
|
||||
{
|
||||
if ($this->userEmailExists($email)) {
|
||||
throw new Exception(Piwik::translate('UsersManager_ExceptionEmailExists', $email));
|
||||
}
|
||||
|
||||
if (!Piwik::isValidEmailString($email)) {
|
||||
throw new Exception(Piwik::translate('UsersManager_ExceptionInvalidEmail'));
|
||||
}
|
||||
}
|
||||
|
||||
private function getCleanAlias($alias, $userLogin)
|
||||
{
|
||||
if (empty($alias)) {
|
||||
$alias = $userLogin;
|
||||
}
|
||||
return $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a user in the database.
|
||||
* A user is defined by
|
||||
* - a login that has to be unique and valid
|
||||
* - a password that has to be valid
|
||||
* - an alias
|
||||
* - an email that has to be in a correct format
|
||||
*
|
||||
* @see userExists()
|
||||
* @see isValidLoginString()
|
||||
* @see isValidPasswordString()
|
||||
* @see isValidEmailString()
|
||||
*
|
||||
* @exception in case of an invalid parameter
|
||||
*/
|
||||
public function addUser($userLogin, $password, $email, $alias = false)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
|
||||
$this->checkLogin($userLogin);
|
||||
$this->checkEmail($email);
|
||||
|
||||
$password = Common::unsanitizeInputValue($password);
|
||||
UsersManager::checkPassword($password);
|
||||
|
||||
$alias = $this->getCleanAlias($alias, $userLogin);
|
||||
$passwordTransformed = UsersManager::getPasswordHash($password);
|
||||
|
||||
$token_auth = $this->getTokenAuth($userLogin, $passwordTransformed);
|
||||
|
||||
$this->model->addUser($userLogin, $passwordTransformed, $email, $alias, $token_auth, Date::now()->getDatetime());
|
||||
|
||||
// we reload the access list which doesn't yet take in consideration this new user
|
||||
Access::getInstance()->reloadAccess();
|
||||
Cache::deleteTrackerCache();
|
||||
|
||||
/**
|
||||
* Triggered after a new user is created.
|
||||
*
|
||||
* @param string $userLogin The new user's login handle.
|
||||
*/
|
||||
Piwik::postEvent('UsersManager.addUser.end', array($userLogin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable Super user access to the given user login. Note: When granting Super User access all previous
|
||||
* permissions of the user will be removed as the user gains access to everything.
|
||||
*
|
||||
* @param string $userLogin the user login.
|
||||
* @param bool|int $hasSuperUserAccess true or '1' to grant Super User access, false or '0' to remove Super User
|
||||
* access.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setSuperUserAccess($userLogin, $hasSuperUserAccess)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$this->checkUserIsNotAnonymous($userLogin);
|
||||
$this->checkUserExists($userLogin);
|
||||
|
||||
if (!$hasSuperUserAccess && $this->isUserTheOnlyUserHavingSuperUserAccess($userLogin)) {
|
||||
$message = Piwik::translate("UsersManager_ExceptionRemoveSuperUserAccessOnlySuperUser", $userLogin)
|
||||
. " "
|
||||
. Piwik::translate("UsersManager_ExceptionYouMustGrantSuperUserAccessFirst");
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
$this->model->deleteUserAccess($userLogin);
|
||||
$this->model->setSuperUserAccess($userLogin, $hasSuperUserAccess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether the current user has super user access or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSuperUserAccess()
|
||||
{
|
||||
return Piwik::hasUserSuperUserAccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all Super Users containing there userLogin and email address.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsersHavingSuperUserAccess()
|
||||
{
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
|
||||
return $this->model->getUsersHavingSuperUserAccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a user in the database.
|
||||
* Only login and password are required (case when we update the password).
|
||||
* When the password changes, the key token for this user will change, which could break
|
||||
* its API calls.
|
||||
*
|
||||
* @see addUser() for all the parameters
|
||||
*/
|
||||
public function updateUser($userLogin, $password = false, $email = false, $alias = false,
|
||||
$_isPasswordHashed = false)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin);
|
||||
$this->checkUserIsNotAnonymous($userLogin);
|
||||
$userInfo = $this->getUser($userLogin);
|
||||
|
||||
if (empty($password)) {
|
||||
$password = $userInfo['password'];
|
||||
} else {
|
||||
$password = Common::unsanitizeInputValue($password);
|
||||
if (!$_isPasswordHashed) {
|
||||
UsersManager::checkPassword($password);
|
||||
$password = UsersManager::getPasswordHash($password);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($alias)) {
|
||||
$alias = $userInfo['alias'];
|
||||
}
|
||||
|
||||
if (empty($email)) {
|
||||
$email = $userInfo['email'];
|
||||
}
|
||||
|
||||
if ($email != $userInfo['email']) {
|
||||
$this->checkEmail($email);
|
||||
}
|
||||
|
||||
$alias = $this->getCleanAlias($alias, $userLogin);
|
||||
$token_auth = $this->getTokenAuth($userLogin, $password);
|
||||
|
||||
$this->model->updateUser($userLogin, $password, $email, $alias, $token_auth);
|
||||
|
||||
Cache::deleteTrackerCache();
|
||||
|
||||
/**
|
||||
* Triggered after an existing user has been updated.
|
||||
*
|
||||
* @param string $userLogin The user's login handle.
|
||||
*/
|
||||
Piwik::postEvent('UsersManager.updateUser.end', array($userLogin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a user and all its access, given its login.
|
||||
*
|
||||
* @param string $userLogin the user login.
|
||||
*
|
||||
* @throws Exception if the user doesn't exist
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function deleteUser($userLogin)
|
||||
{
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$this->checkUserIsNotAnonymous($userLogin);
|
||||
if (!$this->userExists($userLogin)) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionDeleteDoesNotExist", $userLogin));
|
||||
}
|
||||
|
||||
if ($this->isUserTheOnlyUserHavingSuperUserAccess($userLogin)) {
|
||||
$message = Piwik::translate("UsersManager_ExceptionDeleteOnlyUserWithSuperUserAccess", $userLogin)
|
||||
. " "
|
||||
. Piwik::translate("UsersManager_ExceptionYouMustGrantSuperUserAccessFirst");
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
$this->model->deleteUserOnly($userLogin);
|
||||
$this->model->deleteUserAccess($userLogin);
|
||||
|
||||
Cache::deleteTrackerCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given userLogin is known in the database
|
||||
*
|
||||
* @param string $userLogin
|
||||
* @return bool true if the user is known
|
||||
*/
|
||||
public function userExists($userLogin)
|
||||
{
|
||||
if ($userLogin == 'anonymous') {
|
||||
return true;
|
||||
}
|
||||
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
Piwik::checkUserHasSomeViewAccess();
|
||||
|
||||
if ($userLogin == Piwik::getCurrentUserLogin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->model->userExists($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if user with given email (userEmail) is known in the database, or the Super User
|
||||
*
|
||||
* @param string $userEmail
|
||||
* @return bool true if the user is known
|
||||
*/
|
||||
public function userEmailExists($userEmail)
|
||||
{
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
|
||||
return $this->model->userEmailExists($userEmail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an access level to a given user for a list of websites ID.
|
||||
*
|
||||
* If access = 'noaccess' the current access (if any) will be deleted.
|
||||
* If access = 'view' or 'admin' the current access level is deleted and updated with the new value.
|
||||
*
|
||||
* @param string $userLogin The user login
|
||||
* @param string $access Access to grant. Must have one of the following value : noaccess, view, admin
|
||||
* @param int|array $idSites The array of idSites on which to apply the access level for the user.
|
||||
* If the value is "all" then we apply the access level to all the websites ID for which the current authentificated user has an 'admin' access.
|
||||
*
|
||||
* @throws Exception if the user doesn't exist
|
||||
* @throws Exception if the access parameter doesn't have a correct value
|
||||
* @throws Exception if any of the given website ID doesn't exist
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function setUserAccess($userLogin, $access, $idSites)
|
||||
{
|
||||
$this->checkAccessType($access);
|
||||
$this->checkUserExists($userLogin);
|
||||
$this->checkUserHasNotSuperUserAccess($userLogin);
|
||||
|
||||
if ($userLogin == 'anonymous'
|
||||
&& $access == 'admin'
|
||||
) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionAdminAnonymous"));
|
||||
}
|
||||
|
||||
// in case idSites is all we grant access to all the websites on which the current connected user has an 'admin' access
|
||||
if ($idSites === 'all') {
|
||||
$idSites = \Piwik\Plugins\SitesManager\API::getInstance()->getSitesIdWithAdminAccess();
|
||||
} // in case the idSites is an integer we build an array
|
||||
else {
|
||||
$idSites = Site::getIdSitesFromIdSitesString($idSites);
|
||||
}
|
||||
|
||||
if (empty($idSites)) {
|
||||
throw new Exception('Specify at least one website ID in &idSites=');
|
||||
}
|
||||
// it is possible to set user access on websites only for the websites admin
|
||||
// basically an admin can give the view or the admin access to any user for the websites he manages
|
||||
Piwik::checkUserHasAdminAccess($idSites);
|
||||
|
||||
$this->model->deleteUserAccess($userLogin, $idSites);
|
||||
|
||||
// if the access is noaccess then we don't save it as this is the default value
|
||||
// when no access are specified
|
||||
if ($access != 'noaccess') {
|
||||
$this->model->addUserAccess($userLogin, $access, $idSites);
|
||||
}
|
||||
|
||||
// we reload the access list which doesn't yet take in consideration this new user access
|
||||
Access::getInstance()->reloadAccess();
|
||||
Cache::deleteTrackerCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception is the user login doesn't exist
|
||||
*
|
||||
* @param string $userLogin user login
|
||||
* @throws Exception if the user doesn't exist
|
||||
*/
|
||||
private function checkUserExists($userLogin)
|
||||
{
|
||||
if (!$this->userExists($userLogin)) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionUserDoesNotExist", $userLogin));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception is the user email cannot be found
|
||||
*
|
||||
* @param string $userEmail user email
|
||||
* @throws Exception if the user doesn't exist
|
||||
*/
|
||||
private function checkUserEmailExists($userEmail)
|
||||
{
|
||||
if (!$this->userEmailExists($userEmail)) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionUserDoesNotExist", $userEmail));
|
||||
}
|
||||
}
|
||||
|
||||
private function checkUserIsNotAnonymous($userLogin)
|
||||
{
|
||||
if ($userLogin == 'anonymous') {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionEditAnonymous"));
|
||||
}
|
||||
}
|
||||
|
||||
private function checkUserHasNotSuperUserAccess($userLogin)
|
||||
{
|
||||
if (Piwik::hasTheUserSuperUserAccess($userLogin)) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionSuperUserAccess"));
|
||||
}
|
||||
}
|
||||
|
||||
private function checkAccessType($access)
|
||||
{
|
||||
$accessList = Access::getListAccess();
|
||||
|
||||
// do not allow to set the superUser access
|
||||
unset($accessList[array_search("superuser", $accessList)]);
|
||||
|
||||
if (!in_array($access, $accessList)) {
|
||||
throw new Exception(Piwik::translate("UsersManager_ExceptionAccessValues", implode(", ", $accessList)));
|
||||
}
|
||||
}
|
||||
|
||||
private function isUserTheOnlyUserHavingSuperUserAccess($userLogin)
|
||||
{
|
||||
$superUsers = $this->getUsersHavingSuperUserAccess();
|
||||
|
||||
return 1 >= count($superUsers) && Piwik::hasTheUserSuperUserAccess($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique MD5 for the given login & password
|
||||
*
|
||||
* @param string $userLogin Login
|
||||
* @param string $md5Password MD5ied string of the password
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function getTokenAuth($userLogin, $md5Password)
|
||||
{
|
||||
if (strlen($md5Password) != 32) {
|
||||
throw new Exception(Piwik::translate('UsersManager_ExceptionPasswordMD5HashExpected'));
|
||||
}
|
||||
return md5($userLogin . $md5Password);
|
||||
}
|
||||
}
|
||||
340
www/analytics/plugins/UsersManager/Controller.php
Normal file
340
www/analytics/plugins/UsersManager/Controller.php
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\UsersManager;
|
||||
|
||||
use Exception;
|
||||
use Piwik\API\ResponseBuilder;
|
||||
use Piwik\Common;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\LanguagesManager\LanguagesManager;
|
||||
use Piwik\Plugins\SitesManager\API as APISitesManager;
|
||||
use Piwik\Plugins\UsersManager\API as APIUsersManager;
|
||||
use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
|
||||
use Piwik\Site;
|
||||
use Piwik\Tracker\IgnoreCookie;
|
||||
use Piwik\Url;
|
||||
use Piwik\View;
|
||||
use Piwik\MetricsFormatter;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Controller extends \Piwik\Plugin\ControllerAdmin
|
||||
{
|
||||
static function orderByName($a, $b)
|
||||
{
|
||||
return strcmp($a['name'], $b['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* The "Manage Users and Permissions" Admin UI screen
|
||||
*/
|
||||
function index()
|
||||
{
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
|
||||
$view = new View('@UsersManager/index');
|
||||
|
||||
$IdSitesAdmin = APISitesManager::getInstance()->getSitesIdWithAdminAccess();
|
||||
$idSiteSelected = 1;
|
||||
|
||||
if (count($IdSitesAdmin) > 0) {
|
||||
$defaultWebsiteId = $IdSitesAdmin[0];
|
||||
$idSiteSelected = Common::getRequestVar('idSite', $defaultWebsiteId);
|
||||
}
|
||||
|
||||
if ($idSiteSelected === 'all') {
|
||||
$usersAccessByWebsite = array();
|
||||
$defaultReportSiteName = Piwik::translate('UsersManager_ApplyToAllWebsites');
|
||||
} else {
|
||||
$usersAccessByWebsite = APIUsersManager::getInstance()->getUsersAccessFromSite($idSiteSelected);
|
||||
$defaultReportSiteName = Site::getNameFor($idSiteSelected);
|
||||
}
|
||||
|
||||
// we dont want to display the user currently logged so that the user can't change his settings from admin to view...
|
||||
$currentlyLogged = Piwik::getCurrentUserLogin();
|
||||
$usersLogin = APIUsersManager::getInstance()->getUsersLogin();
|
||||
foreach ($usersLogin as $login) {
|
||||
if (!isset($usersAccessByWebsite[$login])) {
|
||||
$usersAccessByWebsite[$login] = 'noaccess';
|
||||
}
|
||||
}
|
||||
unset($usersAccessByWebsite[$currentlyLogged]);
|
||||
|
||||
// $usersAccessByWebsite is not supposed to contain unexistant logins, but it does when upgrading from some old Piwik version
|
||||
foreach ($usersAccessByWebsite as $login => $access) {
|
||||
if (!in_array($login, $usersLogin)) {
|
||||
unset($usersAccessByWebsite[$login]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ksort($usersAccessByWebsite);
|
||||
|
||||
$users = array();
|
||||
$superUsers = array();
|
||||
$usersAliasByLogin = array();
|
||||
|
||||
if (Piwik::isUserHasSomeAdminAccess()) {
|
||||
$view->showLastSeen = true;
|
||||
|
||||
$users = APIUsersManager::getInstance()->getUsers();
|
||||
foreach ($users as $index => $user) {
|
||||
$usersAliasByLogin[$user['login']] = $user['alias'];
|
||||
|
||||
$lastSeen = LastSeenTimeLogger::getLastSeenTimeForUser($user['login']);
|
||||
$users[$index]['last_seen'] = $lastSeen == 0
|
||||
? false : MetricsFormatter::getPrettyTimeFromSeconds(time() - $lastSeen);
|
||||
}
|
||||
|
||||
if (Piwik::hasUserSuperUserAccess()) {
|
||||
foreach ($users as $user) {
|
||||
if ($user['superuser_access']) {
|
||||
$superUsers[] = $user['login'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$view->anonymousHasViewAccess = $this->hasAnonymousUserViewAccess($usersAccessByWebsite);
|
||||
$view->idSiteSelected = $idSiteSelected;
|
||||
$view->defaultReportSiteName = $defaultReportSiteName;
|
||||
$view->users = $users;
|
||||
$view->superUserLogins = $superUsers;
|
||||
$view->usersAliasByLogin = $usersAliasByLogin;
|
||||
$view->usersCount = count($users) - 1;
|
||||
$view->usersAccessByWebsite = $usersAccessByWebsite;
|
||||
$websites = APISitesManager::getInstance()->getSitesWithAdminAccess();
|
||||
uasort($websites, array('Piwik\Plugins\UsersManager\Controller', 'orderByName'));
|
||||
$view->websites = $websites;
|
||||
$this->setBasicVariablesView($view);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
private function hasAnonymousUserViewAccess($usersAccessByWebsite)
|
||||
{
|
||||
$anonymousHasViewAccess = false;
|
||||
foreach ($usersAccessByWebsite as $login => $access) {
|
||||
if ($login == 'anonymous'
|
||||
&& $access != 'noaccess'
|
||||
) {
|
||||
$anonymousHasViewAccess = true;
|
||||
}
|
||||
}
|
||||
return $anonymousHasViewAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default date for Piwik reports
|
||||
*
|
||||
* @param string $user
|
||||
* @return string today, yesterday, week, month, year
|
||||
*/
|
||||
protected function getDefaultDateForUser($user)
|
||||
{
|
||||
return APIUsersManager::getInstance()->getUserPreference($user, APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The "User Settings" admin UI screen view
|
||||
*/
|
||||
public function userSettings()
|
||||
{
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
|
||||
$view = new View('@UsersManager/userSettings');
|
||||
|
||||
$userLogin = Piwik::getCurrentUserLogin();
|
||||
$user = APIUsersManager::getInstance()->getUser($userLogin);
|
||||
$view->userAlias = $user['alias'];
|
||||
$view->userEmail = $user['email'];
|
||||
|
||||
$defaultReport = APIUsersManager::getInstance()->getUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT);
|
||||
if ($defaultReport === false) {
|
||||
$defaultReport = $this->getDefaultWebsiteId();
|
||||
}
|
||||
$view->defaultReport = $defaultReport;
|
||||
|
||||
if ($defaultReport == 'MultiSites') {
|
||||
$view->defaultReportSiteName = Site::getNameFor($this->getDefaultWebsiteId());
|
||||
} else {
|
||||
$view->defaultReportSiteName = Site::getNameFor($defaultReport);
|
||||
}
|
||||
|
||||
$view->defaultDate = $this->getDefaultDateForUser($userLogin);
|
||||
$view->availableDefaultDates = array(
|
||||
'today' => Piwik::translate('General_Today'),
|
||||
'yesterday' => Piwik::translate('General_Yesterday'),
|
||||
'previous7' => Piwik::translate('General_PreviousDays', 7),
|
||||
'previous30' => Piwik::translate('General_PreviousDays', 30),
|
||||
'last7' => Piwik::translate('General_LastDays', 7),
|
||||
'last30' => Piwik::translate('General_LastDays', 30),
|
||||
'week' => Piwik::translate('General_CurrentWeek'),
|
||||
'month' => Piwik::translate('General_CurrentMonth'),
|
||||
'year' => Piwik::translate('General_CurrentYear'),
|
||||
);
|
||||
|
||||
$view->languages = APILanguagesManager::getInstance()->getAvailableLanguageNames();
|
||||
$view->currentLanguageCode = LanguagesManager::getLanguageCodeForCurrentUser();
|
||||
$view->ignoreCookieSet = IgnoreCookie::isIgnoreCookieFound();
|
||||
$this->initViewAnonymousUserSettings($view);
|
||||
$view->piwikHost = Url::getCurrentHost();
|
||||
$this->setBasicVariablesView($view);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
public function setIgnoreCookie()
|
||||
{
|
||||
Piwik::checkUserHasSomeViewAccess();
|
||||
Piwik::checkUserIsNotAnonymous();
|
||||
$this->checkTokenInUrl();
|
||||
|
||||
IgnoreCookie::setIgnoreCookie();
|
||||
Piwik::redirectToModule('UsersManager', 'userSettings', array('token_auth' => false));
|
||||
}
|
||||
|
||||
/**
|
||||
* The Super User can modify Anonymous user settings
|
||||
* @param View $view
|
||||
*/
|
||||
protected function initViewAnonymousUserSettings($view)
|
||||
{
|
||||
if (!Piwik::hasUserSuperUserAccess()) {
|
||||
return;
|
||||
}
|
||||
$userLogin = 'anonymous';
|
||||
|
||||
// Which websites are available to the anonymous users?
|
||||
$anonymousSitesAccess = APIUsersManager::getInstance()->getSitesAccessFromUser($userLogin);
|
||||
$anonymousSites = array();
|
||||
foreach ($anonymousSitesAccess as $info) {
|
||||
$idSite = $info['site'];
|
||||
$site = APISitesManager::getInstance()->getSiteFromId($idSite);
|
||||
// Work around manual website deletion
|
||||
if (!empty($site)) {
|
||||
$anonymousSites[$idSite] = $site;
|
||||
}
|
||||
}
|
||||
$view->anonymousSites = $anonymousSites;
|
||||
|
||||
// Which report is displayed by default to the anonymous user?
|
||||
$anonymousDefaultReport = APIUsersManager::getInstance()->getUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT);
|
||||
if ($anonymousDefaultReport === false) {
|
||||
if (empty($anonymousSites)) {
|
||||
$anonymousDefaultReport = Piwik::getLoginPluginName();
|
||||
} else {
|
||||
// we manually imitate what would happen, in case the anonymous user logs in
|
||||
// and is redirected to the first website available to him in the list
|
||||
// @see getDefaultWebsiteId()
|
||||
reset($anonymousSites);
|
||||
$anonymousDefaultReport = key($anonymousSites);
|
||||
}
|
||||
}
|
||||
$view->anonymousDefaultReport = $anonymousDefaultReport;
|
||||
|
||||
$view->anonymousDefaultDate = $this->getDefaultDateForUser($userLogin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records settings for the anonymous users (default report, default date)
|
||||
*/
|
||||
public function recordAnonymousUserSettings()
|
||||
{
|
||||
$response = new ResponseBuilder(Common::getRequestVar('format'));
|
||||
try {
|
||||
Piwik::checkUserHasSuperUserAccess();
|
||||
$this->checkTokenInUrl();
|
||||
|
||||
$anonymousDefaultReport = Common::getRequestVar('anonymousDefaultReport');
|
||||
$anonymousDefaultDate = Common::getRequestVar('anonymousDefaultDate');
|
||||
$userLogin = 'anonymous';
|
||||
APIUsersManager::getInstance()->setUserPreference($userLogin,
|
||||
APIUsersManager::PREFERENCE_DEFAULT_REPORT,
|
||||
$anonymousDefaultReport);
|
||||
APIUsersManager::getInstance()->setUserPreference($userLogin,
|
||||
APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE,
|
||||
$anonymousDefaultDate);
|
||||
$toReturn = $response->getResponse();
|
||||
} catch (Exception $e) {
|
||||
$toReturn = $response->getResponseException($e);
|
||||
}
|
||||
|
||||
return $toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records settings from the "User Settings" page
|
||||
* @throws Exception
|
||||
*/
|
||||
public function recordUserSettings()
|
||||
{
|
||||
$response = new ResponseBuilder(Common::getRequestVar('format'));
|
||||
try {
|
||||
$this->checkTokenInUrl();
|
||||
|
||||
$defaultReport = Common::getRequestVar('defaultReport');
|
||||
$defaultDate = Common::getRequestVar('defaultDate');
|
||||
$language = Common::getRequestVar('language');
|
||||
$userLogin = Piwik::getCurrentUserLogin();
|
||||
|
||||
$this->processPasswordChange($userLogin);
|
||||
|
||||
LanguagesManager::setLanguageForSession($language);
|
||||
APILanguagesManager::getInstance()->setLanguageForUser($userLogin, $language);
|
||||
|
||||
APIUsersManager::getInstance()->setUserPreference($userLogin,
|
||||
APIUsersManager::PREFERENCE_DEFAULT_REPORT,
|
||||
$defaultReport);
|
||||
APIUsersManager::getInstance()->setUserPreference($userLogin,
|
||||
APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE,
|
||||
$defaultDate);
|
||||
$toReturn = $response->getResponse();
|
||||
} catch (Exception $e) {
|
||||
$toReturn = $response->getResponseException($e);
|
||||
}
|
||||
|
||||
return $toReturn;
|
||||
}
|
||||
|
||||
private function processPasswordChange($userLogin)
|
||||
{
|
||||
$alias = Common::getRequestVar('alias');
|
||||
$email = Common::getRequestVar('email');
|
||||
$newPassword = false;
|
||||
$password = Common::getRequestvar('password', false);
|
||||
$passwordBis = Common::getRequestvar('passwordBis', false);
|
||||
if (!empty($password)
|
||||
|| !empty($passwordBis)
|
||||
) {
|
||||
if ($password != $passwordBis) {
|
||||
throw new Exception(Piwik::translate('Login_PasswordsDoNotMatch'));
|
||||
}
|
||||
$newPassword = $password;
|
||||
}
|
||||
|
||||
// UI disables password change on invalid host, but check here anyway
|
||||
if (!Url::isValidHost()
|
||||
&& $newPassword !== false
|
||||
) {
|
||||
throw new Exception("Cannot change password with untrusted hostname!");
|
||||
}
|
||||
|
||||
APIUsersManager::getInstance()->updateUser($userLogin, $newPassword, $email, $alias);
|
||||
if ($newPassword !== false) {
|
||||
$newPassword = Common::unsanitizeInputValue($newPassword);
|
||||
}
|
||||
|
||||
// logs the user in with the new password
|
||||
if ($newPassword !== false) {
|
||||
\Piwik\Registry::get('auth')->initSession($userLogin, md5($newPassword), $rememberMe = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
www/analytics/plugins/UsersManager/LastSeenTimeLogger.php
Normal file
72
www/analytics/plugins/UsersManager/LastSeenTimeLogger.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\UsersManager;
|
||||
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Common;
|
||||
use Piwik\Option;
|
||||
|
||||
/**
|
||||
* Class that logs the time the current user is accessing the current resource (which
|
||||
* is 'now') so it can be retrieved later.
|
||||
*/
|
||||
class LastSeenTimeLogger
|
||||
{
|
||||
const OPTION_PREFIX = 'UsersManager.lastSeen.';
|
||||
|
||||
/**
|
||||
* The amount of time in seconds that a last seen value is considered valid. We don't want
|
||||
* to update the database for every request made by every user, so we only do it if the time
|
||||
* has been at least this many seconds from the last known time.
|
||||
*/
|
||||
const LAST_TIME_SAVE_DELTA = 300;
|
||||
|
||||
/**
|
||||
* Saves the current time for a user as an option if the current request is for something
|
||||
* in the reporting UI, the current user is not anonymous and the time hasn't been saved
|
||||
* in the last 5 minutes.
|
||||
*/
|
||||
public function logCurrentUserLastSeenTime()
|
||||
{
|
||||
$module = Common::getRequestVar('module', false);
|
||||
$action = Common::getRequestVar('action', false);
|
||||
$currentUserLogin = Piwik::getCurrentUserLogin();
|
||||
|
||||
// only log time for non-anonymous visits to the reporting UI
|
||||
if ($module == 'API'
|
||||
|| $module == 'Proxy'
|
||||
|| $currentUserLogin == 'anonymous'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the last known time
|
||||
$optionName = self::OPTION_PREFIX . $currentUserLogin;
|
||||
$lastSeen = Option::get($optionName);
|
||||
|
||||
// do not log if last known time is less than N minutes from now (so we don't make too many
|
||||
// queries)
|
||||
if (time() - $lastSeen <= self::LAST_TIME_SAVE_DELTA) {
|
||||
return;
|
||||
}
|
||||
|
||||
// log last seen time (Note: autoload is important so the Option::get above does not result in
|
||||
// a separate query)
|
||||
Option::set($optionName, time(), $autoload = 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time a user was last seen or `false` if the user has never logged in.
|
||||
*/
|
||||
public static function getLastSeenTimeForUser($userName)
|
||||
{
|
||||
$optionName = self::OPTION_PREFIX . $userName;
|
||||
return Option::get($optionName);
|
||||
}
|
||||
}
|
||||
274
www/analytics/plugins/UsersManager/Model.php
Normal file
274
www/analytics/plugins/UsersManager/Model.php
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\UsersManager;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\Db;
|
||||
use Piwik\Piwik;
|
||||
|
||||
/**
|
||||
* The UsersManager API lets you Manage Users and their permissions to access specific websites.
|
||||
*
|
||||
* You can create users via "addUser", update existing users via "updateUser" and delete users via "deleteUser".
|
||||
* There are many ways to list users based on their login "getUser" and "getUsers", their email "getUserByEmail",
|
||||
* or which users have permission (view or admin) to access the specified websites "getUsersWithSiteAccess".
|
||||
*
|
||||
* Existing Permissions are listed given a login via "getSitesAccessFromUser", or a website ID via "getUsersAccessFromSite",
|
||||
* or you can list all users and websites for a given permission via "getUsersSitesFromAccess". Permissions are set and updated
|
||||
* via the method "setUserAccess".
|
||||
* See also the documentation about <a href='http://piwik.org/docs/manage-users/' target='_blank'>Managing Users</a> in Piwik.
|
||||
*/
|
||||
class Model
|
||||
{
|
||||
/**
|
||||
* Returns the list of all the users
|
||||
*
|
||||
* @param string[] $userLogins List of users to select. If empty, will return all users
|
||||
* @return array the list of all the users
|
||||
*/
|
||||
public function getUsers(array $userLogins)
|
||||
{
|
||||
$where = '';
|
||||
$bind = array();
|
||||
|
||||
if (!empty($userLogins)) {
|
||||
$where = 'WHERE login IN (' . Common::getSqlStringFieldsArray($userLogins) . ')';
|
||||
$bind = $userLogins;
|
||||
}
|
||||
|
||||
$users = Db::get()->fetchAll("SELECT *
|
||||
FROM " . Common::prefixTable("user") . "
|
||||
$where
|
||||
ORDER BY login ASC", $bind);
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all the users login
|
||||
*
|
||||
* @return array the list of all the users login
|
||||
*/
|
||||
public function getUsersLogin()
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT login
|
||||
FROM " . Common::prefixTable("user") . "
|
||||
ORDER BY login ASC");
|
||||
$return = array();
|
||||
foreach ($users as $login) {
|
||||
$return[] = $login['login'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getUsersSitesFromAccess($access)
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT login,idsite
|
||||
FROM " . Common::prefixTable("access")
|
||||
. " WHERE access = ?
|
||||
ORDER BY login, idsite", $access);
|
||||
|
||||
$return = array();
|
||||
foreach ($users as $user) {
|
||||
$return[$user['login']][] = $user['idsite'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getUsersAccessFromSite($idSite)
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT login,access
|
||||
FROM " . Common::prefixTable("access")
|
||||
. " WHERE idsite = ?", $idSite);
|
||||
|
||||
$return = array();
|
||||
foreach ($users as $user) {
|
||||
$return[$user['login']] = $user['access'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getUsersLoginWithSiteAccess($idSite, $access)
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT login
|
||||
FROM " . Common::prefixTable("access")
|
||||
. " WHERE idsite = ? AND access = ?", array($idSite, $access));
|
||||
|
||||
$logins = array();
|
||||
foreach ($users as $user) {
|
||||
$logins[] = $user['login'];
|
||||
}
|
||||
|
||||
return $logins;
|
||||
}
|
||||
|
||||
/**
|
||||
* For each website ID, returns the access level of the given $userLogin.
|
||||
* If the user doesn't have any access to a website ('noaccess'),
|
||||
* this website will not be in the returned array.
|
||||
* If the user doesn't have any access, the returned array will be an empty array.
|
||||
*
|
||||
* @param string $userLogin User that has to be valid
|
||||
*
|
||||
* @return array The returned array has the format
|
||||
* array(
|
||||
* idsite1 => 'view',
|
||||
* idsite2 => 'admin',
|
||||
* idsite3 => 'view',
|
||||
* ...
|
||||
* )
|
||||
*/
|
||||
public function getSitesAccessFromUser($userLogin)
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT idsite,access
|
||||
FROM " . Common::prefixTable("access")
|
||||
. " WHERE login = ?", $userLogin);
|
||||
|
||||
$return = array();
|
||||
foreach ($users as $user) {
|
||||
$return[] = array(
|
||||
'site' => $user['idsite'],
|
||||
'access' => $user['access'],
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getUser($userLogin)
|
||||
{
|
||||
return Db::get()->fetchRow("SELECT *
|
||||
FROM " . Common::prefixTable("user")
|
||||
. " WHERE login = ?", $userLogin);
|
||||
}
|
||||
|
||||
public function getUserByEmail($userEmail)
|
||||
{
|
||||
return Db::get()->fetchRow("SELECT *
|
||||
FROM " . Common::prefixTable("user")
|
||||
. " WHERE email = ?", $userEmail);
|
||||
}
|
||||
|
||||
public function getUserByTokenAuth($tokenAuth)
|
||||
{
|
||||
return Db::get()->fetchRow('SELECT *
|
||||
FROM ' . Common::prefixTable('user') . '
|
||||
WHERE token_auth = ?', $tokenAuth);
|
||||
}
|
||||
|
||||
public function addUser($userLogin, $passwordTransformed, $email, $alias, $tokenAuth, $dateRegistered)
|
||||
{
|
||||
$user = array(
|
||||
'login' => $userLogin,
|
||||
'password' => $passwordTransformed,
|
||||
'alias' => $alias,
|
||||
'email' => $email,
|
||||
'token_auth' => $tokenAuth,
|
||||
'date_registered' => $dateRegistered,
|
||||
'superuser_access' => 0
|
||||
);
|
||||
|
||||
Db::get()->insert(Common::prefixTable("user"), $user);
|
||||
}
|
||||
|
||||
public function setSuperUserAccess($userLogin, $hasSuperUserAccess)
|
||||
{
|
||||
Db::get()->update(Common::prefixTable("user"),
|
||||
array(
|
||||
'superuser_access' => $hasSuperUserAccess ? 1 : 0
|
||||
),
|
||||
"login = '$userLogin'"
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersHavingSuperUserAccess()
|
||||
{
|
||||
$users = Db::get()->fetchAll("SELECT login, email
|
||||
FROM " . Common::prefixTable("user") . "
|
||||
WHERE superuser_access = 1
|
||||
ORDER BY date_registered ASC");
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
public function updateUser($userLogin, $password, $email, $alias, $tokenAuth)
|
||||
{
|
||||
Db::get()->update(Common::prefixTable("user"),
|
||||
array(
|
||||
'password' => $password,
|
||||
'alias' => $alias,
|
||||
'email' => $email,
|
||||
'token_auth' => $tokenAuth
|
||||
),
|
||||
"login = '$userLogin'"
|
||||
);
|
||||
}
|
||||
|
||||
public function userExists($userLogin)
|
||||
{
|
||||
$count = Db::get()->fetchOne("SELECT count(*)
|
||||
FROM " . Common::prefixTable("user") . "
|
||||
WHERE login = ?", $userLogin);
|
||||
return $count != 0;
|
||||
}
|
||||
|
||||
public function userEmailExists($userEmail)
|
||||
{
|
||||
$count = Db::get()->fetchOne("SELECT count(*)
|
||||
FROM " . Common::prefixTable("user") . "
|
||||
WHERE email = ?", $userEmail);
|
||||
return $count != 0;
|
||||
}
|
||||
|
||||
public function addUserAccess($userLogin, $access, $idSites)
|
||||
{
|
||||
foreach ($idSites as $idsite) {
|
||||
Db::get()->insert(Common::prefixTable("access"),
|
||||
array("idsite" => $idsite,
|
||||
"login" => $userLogin,
|
||||
"access" => $access)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteUserOnly($userLogin)
|
||||
{
|
||||
Db::get()->query("DELETE FROM " . Common::prefixTable("user") . " WHERE login = ?", $userLogin);
|
||||
|
||||
/**
|
||||
* Triggered after a user has been deleted.
|
||||
*
|
||||
* This event should be used to clean up any data that is related to the now deleted user.
|
||||
* The **Dashboard** plugin, for example, uses this event to remove the user's dashboards.
|
||||
*
|
||||
* @param string $userLogin The login handle of the deleted user.
|
||||
*/
|
||||
Piwik::postEvent('UsersManager.deleteUser', array($userLogin));
|
||||
}
|
||||
|
||||
public function deleteUserAccess($userLogin, $idSites = null)
|
||||
{
|
||||
if (is_null($idSites)) {
|
||||
Db::get()->query("DELETE FROM " . Common::prefixTable("access") .
|
||||
" WHERE login = ?",
|
||||
array($userLogin));
|
||||
} else {
|
||||
foreach ($idSites as $idsite) {
|
||||
Db::get()->query("DELETE FROM " . Common::prefixTable("access") .
|
||||
" WHERE idsite = ? AND login = ?",
|
||||
array($idsite, $userLogin)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
154
www/analytics/plugins/UsersManager/UsersManager.php
Normal file
154
www/analytics/plugins/UsersManager/UsersManager.php
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\UsersManager;
|
||||
|
||||
use Exception;
|
||||
use Piwik\Db;
|
||||
use Piwik\Menu\MenuAdmin;
|
||||
use Piwik\Option;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\SettingsPiwik;
|
||||
|
||||
/**
|
||||
* Manage Piwik users
|
||||
*
|
||||
*/
|
||||
class UsersManager extends \Piwik\Plugin
|
||||
{
|
||||
const PASSWORD_MIN_LENGTH = 6;
|
||||
const PASSWORD_MAX_LENGTH = 26;
|
||||
|
||||
/**
|
||||
* @see Piwik\Plugin::getListHooksRegistered
|
||||
*/
|
||||
public function getListHooksRegistered()
|
||||
{
|
||||
return array(
|
||||
'Menu.Admin.addItems' => 'addMenu',
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
'SitesManager.deleteSite.end' => 'deleteSite',
|
||||
'Tracker.Cache.getSiteAttributes' => 'recordAdminUsersInCache',
|
||||
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
|
||||
'Platform.initialized' => 'onPlatformInitialized'
|
||||
);
|
||||
}
|
||||
|
||||
public function onPlatformInitialized()
|
||||
{
|
||||
$lastSeenTimeLogger = new LastSeenTimeLogger();
|
||||
$lastSeenTimeLogger->logCurrentUserLastSeenTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks when a website tracker cache is flushed (website/user updated, cache deleted, or empty cache)
|
||||
* Will record in the tracker config file the list of Admin token_auth for this website. This
|
||||
* will be used when the Tracking API is used with setIp(), setForceDateTime(), setVisitorId(), etc.
|
||||
*
|
||||
* @param $attributes
|
||||
* @param $idSite
|
||||
* @return void
|
||||
*/
|
||||
public function recordAdminUsersInCache(&$attributes, $idSite)
|
||||
{
|
||||
// add the 'hosts' entry in the website array
|
||||
$users = API::getInstance()->getUsersWithSiteAccess($idSite, 'admin');
|
||||
|
||||
$tokens = array();
|
||||
foreach ($users as $user) {
|
||||
$tokens[] = $user['token_auth'];
|
||||
}
|
||||
$attributes['admin_token_auth'] = $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete user preferences associated with a particular site
|
||||
*/
|
||||
public function deleteSite($idSite)
|
||||
{
|
||||
Option::deleteLike('%\_' . API::PREFERENCE_DEFAULT_REPORT, $idSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of plug-in specific JavaScript files to be imported by the asset manager
|
||||
*
|
||||
* @see Piwik\AssetManager
|
||||
*/
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "plugins/UsersManager/javascripts/usersManager.js";
|
||||
$jsFiles[] = "plugins/UsersManager/javascripts/usersSettings.js";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS files
|
||||
*/
|
||||
function getStylesheetFiles(&$stylesheets)
|
||||
{
|
||||
$stylesheets[] = "plugins/UsersManager/stylesheets/usersManager.less";
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin menu items
|
||||
*/
|
||||
function addMenu()
|
||||
{
|
||||
MenuAdmin::getInstance()->add('CoreAdminHome_MenuManage', 'UsersManager_MenuUsers',
|
||||
array('module' => 'UsersManager', 'action' => 'index'),
|
||||
Piwik::isUserHasSomeAdminAccess(),
|
||||
$order = 2);
|
||||
MenuAdmin::getInstance()->add('CoreAdminHome_MenuManage', 'UsersManager_MenuUserSettings',
|
||||
array('module' => 'UsersManager', 'action' => 'userSettings'),
|
||||
Piwik::isUserHasSomeViewAccess(),
|
||||
$order = 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the password is complex enough (at least 6 characters and max 26 characters)
|
||||
*
|
||||
* @param $input string
|
||||
* @return bool
|
||||
*/
|
||||
public static function isValidPasswordString($input)
|
||||
{
|
||||
if (!SettingsPiwik::isUserCredentialsSanityCheckEnabled()
|
||||
&& !empty($input)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
$l = strlen($input);
|
||||
return $l >= self::PASSWORD_MIN_LENGTH && $l <= self::PASSWORD_MAX_LENGTH;
|
||||
}
|
||||
|
||||
public static function checkPassword($password)
|
||||
{
|
||||
if (!self::isValidPasswordString($password)) {
|
||||
throw new Exception(Piwik::translate('UsersManager_ExceptionInvalidPassword', array(self::PASSWORD_MIN_LENGTH,
|
||||
self::PASSWORD_MAX_LENGTH)));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPasswordHash($password)
|
||||
{
|
||||
// if change here, should also edit the installation process
|
||||
// to change how the root pwd is saved in the config file
|
||||
return md5($password);
|
||||
}
|
||||
|
||||
public function getClientSideTranslationKeys(&$translationKeys)
|
||||
{
|
||||
$translationKeys[] = "General_OrCancel";
|
||||
$translationKeys[] = "General_Save";
|
||||
$translationKeys[] = "General_Done";
|
||||
$translationKeys[] = "UsersManager_DeleteConfirm";
|
||||
$translationKeys[] = "UsersManager_ConfirmGrantSuperUserAccess";
|
||||
$translationKeys[] = "UsersManager_ConfirmProhibitOtherUsersSuperUserAccess";
|
||||
$translationKeys[] = "UsersManager_ConfirmProhibitMySuperUserAccess";
|
||||
}
|
||||
}
|
||||
BIN
www/analytics/plugins/UsersManager/images/add.png
Normal file
BIN
www/analytics/plugins/UsersManager/images/add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
www/analytics/plugins/UsersManager/images/no-access.png
Normal file
BIN
www/analytics/plugins/UsersManager/images/no-access.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 653 B |
BIN
www/analytics/plugins/UsersManager/images/ok.png
Normal file
BIN
www/analytics/plugins/UsersManager/images/ok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 851 B |
302
www/analytics/plugins/UsersManager/javascripts/usersManager.js
Normal file
302
www/analytics/plugins/UsersManager/javascripts/usersManager.js
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
function sendUpdateUserAJAX(row) {
|
||||
var parameters = {};
|
||||
parameters.userLogin = $(row).children('#userLogin').html();
|
||||
var password = $(row).find('input#password').val();
|
||||
if (password != '-') parameters.password = password;
|
||||
parameters.email = $(row).find('input#email').val();
|
||||
parameters.alias = $(row).find('input#alias').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'UsersManager.updateUser'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams(parameters, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement();
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function sendDeleteUserAJAX(login) {
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'UsersManager.deleteUser'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams({userLogin: login}, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function sendAddUserAJAX(row) {
|
||||
var parameters = {};
|
||||
parameters.userLogin = $(row).find('input#useradd_login').val();
|
||||
parameters.password = $(row).find('input#useradd_password').val();
|
||||
parameters.email = $(row).find('input#useradd_email').val();
|
||||
parameters.alias = $(row).find('input#useradd_alias').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'UsersManager.addUser'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams(parameters, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function getIdSites() {
|
||||
return $('#usersManagerSiteSelect').attr('siteid');
|
||||
}
|
||||
|
||||
function sendUpdateUserAccess(login, access, successCallback) {
|
||||
var parameters = {};
|
||||
parameters.userLogin = login;
|
||||
parameters.access = access;
|
||||
parameters.idSites = getIdSites();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'UsersManager.setUserAccess'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams(parameters, 'POST');
|
||||
ajaxHandler.setCallback(successCallback);
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingUsersManagement');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorUsersManagement');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function submitOnEnter(e) {
|
||||
var key = e.keyCode || e.which;
|
||||
if (key == 13) {
|
||||
$(this).find('.adduser').click();
|
||||
$(this).find('.updateuser').click();
|
||||
}
|
||||
}
|
||||
|
||||
function launchAjaxRequest(self, successCallback) {
|
||||
sendUpdateUserAccess(
|
||||
$(self).parent().parent().find('#login').html(), //if changed change also the modal
|
||||
$(self).parent().attr('id'),
|
||||
successCallback
|
||||
);
|
||||
}
|
||||
|
||||
function updateSuperUserAccess(login, hasSuperUserAccess)
|
||||
{
|
||||
var parameters = {};
|
||||
parameters.userLogin = login;
|
||||
parameters.hasSuperUserAccess = hasSuperUserAccess ? 1: 0;
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'API',
|
||||
format: 'json',
|
||||
method: 'UsersManager.setSuperUserAccess'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams(parameters, 'POST');
|
||||
ajaxHandler.setCallback(function () {
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(_pk_translate('General_Done'), {
|
||||
placeat: '#superUserAccessUpdated',
|
||||
context: 'success',
|
||||
noclear: true,
|
||||
type: 'toast',
|
||||
style: {display: 'inline-block', marginTop: '10px', marginBottom: '30px'},
|
||||
id: 'usersManagerSuperUserAccessUpdated'
|
||||
});
|
||||
notification.scrollToNotification();
|
||||
piwikHelper.redirect();
|
||||
});
|
||||
ajaxHandler.setLoadingElement('#ajaxErrorSuperUsersManagement');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorSuperUsersManagement');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
function bindUpdateSuperUserAccess() {
|
||||
var login = $(this).parents('td').data('login');
|
||||
var hasAccess = parseInt($(this).data('hasaccess'), 10);
|
||||
|
||||
var message = 'UsersManager_ConfirmGrantSuperUserAccess';
|
||||
if (hasAccess && login == piwik.userLogin) {
|
||||
message = 'UsersManager_ConfirmProhibitMySuperUserAccess';
|
||||
} else if (hasAccess) {
|
||||
message = 'UsersManager_ConfirmProhibitOtherUsersSuperUserAccess';
|
||||
}
|
||||
|
||||
message = _pk_translate(message);
|
||||
message = message.replace('%s', login);
|
||||
|
||||
$('#superUserAccessConfirm h2').text(message);
|
||||
|
||||
piwikHelper.modalConfirm('#superUserAccessConfirm', {yes: function () {
|
||||
updateSuperUserAccess(login, !hasAccess);
|
||||
}});
|
||||
}
|
||||
|
||||
function bindUpdateAccess() {
|
||||
var self = this;
|
||||
// callback called when the ajax request Update the user permissions is successful
|
||||
function successCallback(response) {
|
||||
var mainDiv = $(self).parent().parent();
|
||||
var login = $('#login', mainDiv).text();
|
||||
mainDiv.find('.accessGranted')
|
||||
.attr("src", "plugins/UsersManager/images/no-access.png")
|
||||
.attr("class", "updateAccess")
|
||||
.click(bindUpdateAccess)
|
||||
;
|
||||
$(self)
|
||||
.attr('src', "plugins/UsersManager/images/ok.png")
|
||||
.attr('class', "accessGranted")
|
||||
;
|
||||
|
||||
var UI = require('piwik/UI');
|
||||
var notification = new UI.Notification();
|
||||
notification.show(_pk_translate('General_Done'), {
|
||||
placeat: '#accessUpdated',
|
||||
context: 'success',
|
||||
noclear: true,
|
||||
type: 'toast',
|
||||
style: {display: 'inline-block', marginTop: '10px'},
|
||||
id: 'usersManagerAccessUpdated'
|
||||
});
|
||||
|
||||
// reload if user anonymous was updated, since we display a Notice message when anon has view access
|
||||
if (login == 'anonymous') {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
var idSite = getIdSites();
|
||||
if (idSite == 'all') {
|
||||
var target = this;
|
||||
|
||||
//ask confirmation
|
||||
var userLogin = $(this).parent().parent().find('#login').text();
|
||||
$('#confirm').find('#login').text(userLogin); // if changed here change also the launchAjaxRequest
|
||||
|
||||
function onValidate() {
|
||||
launchAjaxRequest(target, successCallback);
|
||||
}
|
||||
|
||||
piwikHelper.modalConfirm('#confirm', {yes: onValidate})
|
||||
}
|
||||
else {
|
||||
launchAjaxRequest(this, successCallback);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
var alreadyEdited = [];
|
||||
// when click on edituser, the cells become editable
|
||||
$('.edituser')
|
||||
.click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
var idRow = $(this).attr('id');
|
||||
if (alreadyEdited[idRow] == 1) return;
|
||||
alreadyEdited[idRow] = 1;
|
||||
$('tr#' + idRow + ' .editable').each(
|
||||
// make the fields editable
|
||||
// change the EDIT button to VALID button
|
||||
function (i, n) {
|
||||
var contentBefore = $(n).text();
|
||||
var idName = $(n).attr('id');
|
||||
if (idName != 'userLogin') {
|
||||
var contentAfter = '<input id="' + idName + '" value="' + piwikHelper.htmlEntities(contentBefore) + '" size="25" />';
|
||||
$(n).html(contentAfter);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$(this)
|
||||
.toggle()
|
||||
.parent()
|
||||
.prepend($('<input type="submit" class="submit updateuser" value="' + _pk_translate('General_Save') + '" />')
|
||||
.click(function () {
|
||||
var onValidate = function () {
|
||||
sendUpdateUserAJAX($('tr#' + idRow));
|
||||
};
|
||||
if ($('tr#' + idRow).find('input#password').val() != '-') {
|
||||
piwikHelper.modalConfirm('#confirmPasswordChange', {yes: onValidate});
|
||||
} else {
|
||||
onValidate();
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
$('.editable').keypress(submitOnEnter);
|
||||
|
||||
$('td.editable')
|
||||
.click(function () { $(this).parent().find('.edituser').click(); });
|
||||
|
||||
// when click on deleteuser, the we ask for confirmation and then delete the user
|
||||
$('.deleteuser')
|
||||
.click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
var idRow = $(this).attr('id');
|
||||
var loginToDelete = $(this).parent().parent().find('#userLogin').html();
|
||||
$('#confirmUserRemove').find('h2').text(sprintf(_pk_translate('UsersManager_DeleteConfirm'), '"' + loginToDelete + '"'));
|
||||
piwikHelper.modalConfirm('#confirmUserRemove', {yes: function () { sendDeleteUserAJAX(loginToDelete); }});
|
||||
}
|
||||
);
|
||||
|
||||
$('.addrow').click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
$(this).toggle();
|
||||
|
||||
var numberOfRows = $('table#users')[0].rows.length;
|
||||
var newRowId = numberOfRows + 1;
|
||||
newRowId = 'row' + newRowId;
|
||||
|
||||
$($.parseHTML(' <tr id="' + newRowId + '">\
|
||||
<td><input id="useradd_login" value="login?" size="10" /></td>\
|
||||
<td><input id="useradd_password" value="password" size="10" /></td>\
|
||||
<td><input id="useradd_email" value="email@domain.com" size="15" /></td>\
|
||||
<td><input id="useradd_alias" value="alias" size="15" /></td>\
|
||||
<td>-</td>\
|
||||
<td>-</td>\
|
||||
<td><input type="submit" class="submit adduser" value="' + _pk_translate('General_Save') + '" /></td>\
|
||||
<td><span class="cancel">' + sprintf(_pk_translate('General_OrCancel'), "", "") + '</span></td>\
|
||||
</tr>'))
|
||||
.appendTo('#users')
|
||||
;
|
||||
$('#' + newRowId).keypress(submitOnEnter);
|
||||
$('.adduser').click(function () { sendAddUserAJAX($('tr#' + newRowId)); });
|
||||
$('.cancel').click(function () {
|
||||
piwikHelper.hideAjaxError();
|
||||
$(this).parents('tr').remove();
|
||||
$('.addrow').toggle();
|
||||
});
|
||||
});
|
||||
|
||||
$('#access .updateAccess')
|
||||
.click(bindUpdateAccess);
|
||||
|
||||
$('#superUserAccess .accessGranted, #superUserAccess .updateAccess').click(bindUpdateSuperUserAccess);
|
||||
|
||||
// when a site is selected, reload the page w/o showing the ajax loading element
|
||||
$('#usersManagerSiteSelect').bind('change', function (e, site) {
|
||||
if (site.id != piwik.idSite) {
|
||||
piwik.broadcast.propagateNewPage('segment=&idSite=' + site.id, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*!
|
||||
* Piwik - Web Analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
function sendUserSettingsAJAX() {
|
||||
var params;
|
||||
var defaultDate = $('input[name=defaultDate]:checked').val();
|
||||
if (defaultDate == 'today' || defaultDate == 'yesterday') {
|
||||
params = 'period=day&date=' + defaultDate;
|
||||
} else if (defaultDate.indexOf('last') >= 0
|
||||
|| defaultDate.indexOf('previous') >= 0) {
|
||||
params = 'period=range&date=' + defaultDate;
|
||||
} else {
|
||||
params = 'date=today&period=' + defaultDate;
|
||||
}
|
||||
|
||||
var alias = $('#alias').val();
|
||||
var email = $('#email').val();
|
||||
var password = $('#password').val();
|
||||
var passwordBis = $('#passwordBis').val();
|
||||
var defaultReport = $('input[name=defaultReport]:checked').val();
|
||||
|
||||
if (defaultReport == 1) {
|
||||
defaultReport = $('#defaultReportSiteSelector').attr('siteid');
|
||||
}
|
||||
var postParams = {};
|
||||
postParams.alias = alias;
|
||||
postParams.email = email;
|
||||
if (password) {
|
||||
postParams.password = password;
|
||||
}
|
||||
if (passwordBis) {
|
||||
postParams.passwordBis = passwordBis;
|
||||
}
|
||||
postParams.defaultReport = defaultReport;
|
||||
postParams.defaultDate = defaultDate;
|
||||
postParams.language = $('#userSettingsTable #language').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'UsersManager',
|
||||
format: 'json',
|
||||
action: 'recordUserSettings'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams(postParams, 'POST');
|
||||
ajaxHandler.redirectOnSuccess(params);
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingUserSettings');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorUserSettings');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
function sendAnonymousUserSettingsAJAX() {
|
||||
var anonymousDefaultReport = $('input[name=anonymousDefaultReport]:checked').val();
|
||||
if (anonymousDefaultReport == 1) {
|
||||
anonymousDefaultReport = $('#anonymousDefaultReportWebsite').find('option:selected').val();
|
||||
}
|
||||
var anonymousDefaultDate = $('input[name=anonymousDefaultDate]:checked').val();
|
||||
|
||||
var ajaxHandler = new ajaxHelper();
|
||||
ajaxHandler.addParams({
|
||||
module: 'UsersManager',
|
||||
format: 'json',
|
||||
action: 'recordAnonymousUserSettings'
|
||||
}, 'GET');
|
||||
ajaxHandler.addParams({
|
||||
anonymousDefaultReport: anonymousDefaultReport,
|
||||
anonymousDefaultDate: anonymousDefaultDate
|
||||
}, 'POST');
|
||||
ajaxHandler.redirectOnSuccess();
|
||||
ajaxHandler.setLoadingElement('#ajaxLoadingAnonymousUserSettings');
|
||||
ajaxHandler.setErrorElement('#ajaxErrorAnonymousUserSettings');
|
||||
ajaxHandler.send(true);
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#userSettingsSubmit').click(function () {
|
||||
if ($('#password').length > 0 && $('#password').val() != '') {
|
||||
piwikHelper.modalConfirm('#confirmPasswordChange', {yes: sendUserSettingsAJAX});
|
||||
} else {
|
||||
sendUserSettingsAJAX();
|
||||
}
|
||||
|
||||
});
|
||||
$('#userSettingsTable').find('input').keypress(function (e) {
|
||||
var key = e.keyCode || e.which;
|
||||
if (key == 13) {
|
||||
$('#userSettingsSubmit').click();
|
||||
}
|
||||
});
|
||||
|
||||
$('#anonymousUserSettingsSubmit').click(function () {
|
||||
sendAnonymousUserSettingsAJAX();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#users .editable:hover,
|
||||
#users .addrow:hover,
|
||||
#users .updateAccess:hover,
|
||||
#users .accessGranted:hover,
|
||||
#users .adduser:hover, .edituser:hover,
|
||||
#users .deleteuser:hover,
|
||||
#users .updateuser:hover,
|
||||
#users .cancel:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#sites.usersManager .sites_selector_title {
|
||||
display:inline-block;
|
||||
margin-top:5px;
|
||||
}
|
||||
|
||||
.old-ie #sites.usersManager .sites_selector_title {
|
||||
height: 30px;
|
||||
}
|
||||
210
www/analytics/plugins/UsersManager/templates/index.twig
Normal file
210
www/analytics/plugins/UsersManager/templates/index.twig
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
{% extends 'admin.twig' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2 piwik-enriched-headline
|
||||
help-url="http://piwik.org/docs/manage-users/">{{ 'UsersManager_ManageAccess'|translate }}</h2>
|
||||
<div id="sites" class="usersManager">
|
||||
<section class="sites_selector_container">
|
||||
<p>{{ 'UsersManager_MainDescription'|translate }}</p>
|
||||
|
||||
<div class="sites_selector_title">{{ 'SitesManager_Sites'|translate }}:</div>
|
||||
|
||||
{% set applyAllSitesText %}
|
||||
<strong>{{ 'UsersManager_ApplyToAllWebsites'|translate }}</strong>
|
||||
{% endset %}
|
||||
|
||||
<div piwik-siteselector
|
||||
class="sites_autocomplete"
|
||||
siteid="{{ idSiteSelected }}"
|
||||
sitename="{{ defaultReportSiteName }}"
|
||||
all-sites-text="{{ applyAllSitesText|raw }}"
|
||||
all-sites-location="top"
|
||||
id="usersManagerSiteSelect"
|
||||
switch-site-on-select="false"></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{% import 'ajaxMacros.twig' as ajax %}
|
||||
{{ ajax.errorDiv }}
|
||||
{{ ajax.loadingDiv }}
|
||||
|
||||
<div class="entityContainer" style="width:600px;">
|
||||
{% if anonymousHasViewAccess %}
|
||||
<div style="display:inline-block;margin-top:10px;" id="usersManagerAnonymousUserHasViewAccess">
|
||||
{{ ['UsersManager_AnonymousUserHasViewAccess'|translate("'anonymous'","'view'"), 'UsersManager_AnonymousUserHasViewAccess2'|translate]|join(' ')|notification({'placeAt': '#usersManagerAnonymousUserHasViewAccess', 'noclear': true}) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="entityTable dataTable" id="access" style="display:inline-table;width:500px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='first'>{{ 'UsersManager_User'|translate }}</th>
|
||||
<th>{{ 'UsersManager_Alias'|translate }}</th>
|
||||
<th>{{ 'UsersManager_PrivNone'|translate }}</th>
|
||||
<th>{{ 'UsersManager_PrivView'|translate }}</th>
|
||||
<th>{{ 'UsersManager_PrivAdmin'|translate }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% set accesValid %}<img src='plugins/UsersManager/images/ok.png' class='accessGranted' />{% endset %}
|
||||
{% set accesInvalid %}<img src='plugins/UsersManager/images/no-access.png' class='updateAccess' />{% endset %}
|
||||
{% set superUserAccess %}<span title="{{ 'UsersManager_ExceptionSuperUserAccess'|translate }}">N/A</span>{% endset %}
|
||||
{% for login,access in usersAccessByWebsite %}
|
||||
<tr>
|
||||
<td id='login'>{{ login }}</td>
|
||||
<td>{{ usersAliasByLogin[login]|raw }}</td>
|
||||
<td id='noaccess'>
|
||||
{% if login in superUserLogins %}
|
||||
{{ superUserAccess }}
|
||||
{% elseif access=='noaccess' and idSiteSelected != 'all' %}
|
||||
{{ accesValid }}
|
||||
{% else %}
|
||||
{{ accesInvalid }}
|
||||
{% endif %} </td>
|
||||
<td id='view'>
|
||||
{% if login in superUserLogins %}
|
||||
{{ superUserAccess }}
|
||||
{% elseif access == 'view' and idSiteSelected != 'all' %}
|
||||
{{ accesValid }}
|
||||
{% else %}
|
||||
{{ accesInvalid }}
|
||||
{% endif %} </td>
|
||||
<td id='admin'>
|
||||
{% if login in superUserLogins %}
|
||||
{{ superUserAccess }}
|
||||
{% elseif login == 'anonymous' %}
|
||||
N/A
|
||||
{% else %}
|
||||
{% if access == 'admin' and idSiteSelected != 'all' %}{{ accesValid }}{% else %}{{ accesInvalid }}{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="accessUpdated" style="vertical-align:top;"></div>
|
||||
</div>
|
||||
|
||||
<div class="ui-confirm" id="confirm">
|
||||
<h2>{{ 'UsersManager_ChangeAllConfirm'|translate("<span id='login'></span>")|raw }}</h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
|
||||
{% if userIsSuperUser %}
|
||||
<div class="ui-confirm" id="confirmUserRemove">
|
||||
<h2></h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
<div class="ui-confirm" id="confirmPasswordChange">
|
||||
<h2>{{ 'UsersManager_ChangePasswordConfirm'|translate }}</h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
<br/>
|
||||
<h2>{{ 'UsersManager_UsersManagement'|translate }}</h2>
|
||||
<p>{{ 'UsersManager_UsersManagementMainDescription'|translate }}
|
||||
{{ 'UsersManager_ThereAreCurrentlyNRegisteredUsers'|translate("<b>"~usersCount~"</b>")|raw }}</p>
|
||||
{% import 'ajaxMacros.twig' as ajax %}
|
||||
{{ ajax.errorDiv('ajaxErrorUsersManagement') }}
|
||||
{{ ajax.loadingDiv('ajaxLoadingUsersManagement') }}
|
||||
<div class="entityContainer" style="margin-bottom:50px;">
|
||||
<table class="entityTable dataTable" id="users">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'General_Username'|translate }}</th>
|
||||
<th>{{ 'General_Password'|translate }}</th>
|
||||
<th>{{ 'UsersManager_Email'|translate }}</th>
|
||||
<th>{{ 'UsersManager_Alias'|translate }}</th>
|
||||
<th>token_auth</th>
|
||||
{% if showLastSeen is defined and showLastSeen %}
|
||||
<th>{{ 'UsersManager_LastSeen'|translate }}</th>
|
||||
{% endif %}
|
||||
<th>{{ 'General_Edit'|translate }}</th>
|
||||
<th>{{ 'General_Delete'|translate }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for i,user in users %}
|
||||
{% if user.login != 'anonymous' %}
|
||||
<tr class="editable" id="row{{ i }}">
|
||||
<td id="userLogin" class="editable">{{ user.login }}</td>
|
||||
<td id="password" class="editable">-</td>
|
||||
<td id="email" class="editable">{{ user.email }}</td>
|
||||
<td id="alias" class="editable">{{ user.alias|raw }}</td>
|
||||
<td id="token_auth">{{ user.token_auth }}</td>
|
||||
{% if user.last_seen is defined %}
|
||||
<td id="last_seen">{% if user.last_seen is empty %}-{% else %}{{ 'General_TimeAgo'|translate(user.last_seen)|raw }}{% endif %}</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<span class="edituser link_but" id="row{{ i }}">
|
||||
<img title="{{ 'General_Edit'|translate }}" src='plugins/Zeitgeist/images/ico_edit.png'/>
|
||||
<span>{{ 'General_Edit'|translate }}</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="deleteuser link_but" id="row{{ i }}">
|
||||
<img title="{{ 'General_Delete'|translate }}" src='plugins/Zeitgeist/images/ico_delete.png'/>
|
||||
<span>{{ 'General_Delete'|translate }}</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="addrow"><img src='plugins/UsersManager/images/add.png'/> {{ 'UsersManager_AddUser'|translate }}</div>
|
||||
</div>
|
||||
|
||||
<h2 id="super_user_access">{{ 'UsersManager_SuperUserAccessManagement'|translate }}</h2>
|
||||
<p>{{ 'UsersManager_SuperUserAccessManagementMainDescription'|translate }} <br/>
|
||||
{{ 'UsersManager_SuperUserAccessManagementGrantMore'|translate }}</p>
|
||||
|
||||
{{ ajax.errorDiv('ajaxErrorSuperUsersManagement') }}
|
||||
{{ ajax.loadingDiv('ajaxLoadingSuperUsersManagement') }}
|
||||
|
||||
<table class="entityTable dataTable" id="superUserAccess" style="display:inline-table;width:400px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class='first'>{{ 'UsersManager_User'|translate }}</th>
|
||||
<th>{{ 'UsersManager_Alias'|translate }}</th>
|
||||
<th>{{ 'Installation_SuperUser'|translate }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% if users|length > 1 %}
|
||||
{% for login,alias in usersAliasByLogin if login != 'anonymous' %}
|
||||
<tr>
|
||||
<td id='login'>{{ login }}</td>
|
||||
<td>{{ alias|raw }}</td>
|
||||
<td id='superuser' data-login="{{ login|e('html_attr') }}">
|
||||
<img src='plugins/UsersManager/images/ok.png' class='accessGranted' data-hasaccess="1" {% if not (login in superUserLogins) %}style="display:none"{% endif %} />
|
||||
<img src='plugins/UsersManager/images/no-access.png' class='updateAccess' data-hasaccess="0" {% if login in superUserLogins %}style="display:none"{% endif %} />
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
{{ 'UsersManager_NoUsersExist'|translate }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="superUserAccessUpdated" style="vertical-align:top;"></div>
|
||||
|
||||
<div class="ui-confirm" id="superUserAccessConfirm">
|
||||
<h2> </h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
181
www/analytics/plugins/UsersManager/templates/userSettings.twig
Normal file
181
www/analytics/plugins/UsersManager/templates/userSettings.twig
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
{% extends 'admin.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<h2 piwik-enriched-headline>{{ 'UsersManager_MenuUserSettings'|translate }}</h2>
|
||||
|
||||
<br/>
|
||||
<div class="ui-confirm" id="confirmPasswordChange">
|
||||
<h2>{{ 'UsersManager_ChangePasswordConfirm'|translate }}</h2>
|
||||
<input role="yes" type="button" value="{{ 'General_Yes'|translate }}"/>
|
||||
<input role="no" type="button" value="{{ 'General_No'|translate }}"/>
|
||||
</div>
|
||||
|
||||
<table id='userSettingsTable' class="adminTable">
|
||||
<tr>
|
||||
<td><label for="username">{{ 'General_Username'|translate }} </label></td>
|
||||
<td>
|
||||
<input size="25" value="{{ userLogin }}" id="username" disabled="disabled"/>
|
||||
<span class='form-description'>{{ 'UsersManager_YourUsernameCannotBeChanged'|translate }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><label for="alias">{{ 'UsersManager_Alias'|translate }} </label></td>
|
||||
<td><input size="25" value="{{ userAlias }}" id="alias" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="email">{{ 'UsersManager_Email'|translate }} </label></td>
|
||||
<td><input size="25" value="{{ userEmail }}" id="email"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div style="margin-top: 5px;margin-bottom: 10px;">{{ 'General_Language'|translate }}</div></td>
|
||||
<td>
|
||||
<fieldset style="margin-top: 5px;margin-bottom: 10px;">
|
||||
<select name="language" id="language" onchange="if (this.value=='') window.open('?module=Proxy&action=redirect&url=http://piwik.org/translations/');">
|
||||
<option title="" value="">{{ 'LanguagesManager_AboutPiwikTranslations'|translate }}</option>
|
||||
{% for language in languages %}
|
||||
<option value="{{ language.code }}" {% if language.code == currentLanguageCode %}selected="selected"{% endif %}
|
||||
title="{{ language.name }} ({{ language.english_name }})">{{ language.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br />
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'UsersManager_ReportToLoadByDefault'|translate }}</td>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input id="defaultReportRadioAll" type="radio" value="MultiSites"
|
||||
name="defaultReport"{% if defaultReport=='MultiSites' %} checked="checked"{% endif %} />
|
||||
<label for="defaultReportRadioAll">{{ 'General_AllWebsitesDashboard'|translate }}</label><br/>
|
||||
<input id="defaultReportSpecific" type="radio" value="1"
|
||||
name="defaultReport"{% if defaultReport != 'MultiSites' %} checked="checked"{% endif %} />
|
||||
<label for="defaultReportSpecific" style="padding-right:12px;">{{ 'General_DashboardForASpecificWebsite'|translate }}</label>
|
||||
{% if defaultReport=='MultiSites' %}
|
||||
{% set defaultReportIdSite=1 %}
|
||||
{% else %}
|
||||
{% set defaultReportIdSite=defaultReport %}
|
||||
{% endif %}
|
||||
|
||||
<div piwik-siteselector
|
||||
class="sites_autocomplete"
|
||||
siteid="{{ defaultReportIdSite }}"
|
||||
sitename="{{ defaultReportSiteName }}"
|
||||
switch-site-on-select="false"
|
||||
show-all-sites-item="false"
|
||||
showselectedsite="true"
|
||||
id="defaultReportSiteSelector"></div>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'UsersManager_ReportDateToLoadByDefault'|translate }}</td>
|
||||
<td>
|
||||
<fieldset>
|
||||
{% for value,description in availableDefaultDates %}
|
||||
<input id="defaultDate-{{ loop.index }}" type="radio"{% if defaultDate==value %} checked="checked"{% endif %} value="{{ value }}" name="defaultDate"/>
|
||||
<label for="defaultDate-{{ loop.index }}">{{ description }}</label>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% if isValidHost is defined and isValidHost %}
|
||||
<tr>
|
||||
<td><label for="email">{{ 'General_ChangePassword'|translate }} </label></td>
|
||||
<td><input size="25" value="" autocomplete="off" id="password" type="password"/>
|
||||
<span class='form-description'>{{ 'UsersManager_IfYouWouldLikeToChangeThePasswordTypeANewOne'|translate }}</span>
|
||||
<br/><br/><input size="25" value="" autocomplete="off" id="passwordBis" type="password"/>
|
||||
<span class='form-description'> {{ 'UsersManager_TypeYourPasswordAgain'|translate }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
{% if isValidHost is not defined or not isValidHost %}
|
||||
<div id="injectedHostCannotChangePwd">
|
||||
{% set injectedHostCannotChangePwd %}
|
||||
{{ 'UsersManager_InjectedHostCannotChangePwd'|translate(invalidHost) }}
|
||||
{% if not isSuperUser %}{{ 'UsersManager_EmailYourAdministrator'|translate(invalidHostMailLinkStart,'</a>')|raw }}{% endif %}
|
||||
{% endset %}
|
||||
{{ injectedHostCannotChangePwd|notification({'raw': true, 'context': 'error', 'placeat': '#injectedHostCannotChangePwd', 'noclear': true}) }}
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
|
||||
{% import 'ajaxMacros.twig' as ajax %}
|
||||
{{ ajax.errorDiv('ajaxErrorUserSettings') }}
|
||||
{{ ajax.loadingDiv('ajaxLoadingUserSettings') }}
|
||||
<input type="submit" value="{{ 'General_Save'|translate }}" id="userSettingsSubmit" class="submit"/>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<h2 id="excludeCookie">{{ 'UsersManager_ExcludeVisitsViaCookie'|translate }}</h2>
|
||||
<p>
|
||||
{% if ignoreCookieSet %}
|
||||
{{ 'UsersManager_YourVisitsAreIgnoredOnDomain'|translate("<strong>", piwikHost, "</strong>")|raw }}
|
||||
{% else %}
|
||||
{{ 'UsersManager_YourVisitsAreNotIgnored'|translate("<strong>","</strong>")|raw }}
|
||||
{% endif %}
|
||||
</p>
|
||||
<span style="margin-left:20px;">
|
||||
<a href='{{ linkTo({'token_auth':token_auth, 'action':'setIgnoreCookie'}) }}#excludeCookie'>› {% if ignoreCookieSet %}{{ 'UsersManager_ClickHereToDeleteTheCookie'|translate }}
|
||||
{% else %}{{'UsersManager_ClickHereToSetTheCookieOnDomain'|translate(piwikHost) }}{% endif %}
|
||||
<br/>
|
||||
</a></span>
|
||||
|
||||
<br/><br/>
|
||||
{% if isSuperUser %}
|
||||
<h2>{{ 'UsersManager_MenuAnonymousUserSettings'|translate }}</h2>
|
||||
{% if anonymousSites|length == 0 %}
|
||||
<h3 class='form-description'><strong>{{ 'UsersManager_NoteNoAnonymousUserAccessSettingsWontBeUsed2'|translate }}</strong></h3>
|
||||
<br/>
|
||||
{% else %}
|
||||
<br/>
|
||||
{{ ajax.errorDiv('ajaxErrorAnonymousUserSettings') }}
|
||||
{{ ajax.loadingDiv('ajaxLoadingAnonymousUserSettings') }}
|
||||
<table id='anonymousUserSettingsTable' class="adminTable" style='width:850px;'>
|
||||
<tr>
|
||||
<td style="width:400px;">{{ 'UsersManager_WhenUsersAreNotLoggedInAndVisitPiwikTheyShouldAccess'|translate }}</td>
|
||||
<td>
|
||||
<fieldset>
|
||||
<input id="anonymousDefaultReport-login" type="radio" value="Login"
|
||||
name="anonymousDefaultReport"{% if anonymousDefaultReport==loginModule %} checked="checked"{% endif %} />
|
||||
<label for="anonymousDefaultReport-login">{{ 'UsersManager_TheLoginScreen'|translate }}</label><br/>
|
||||
<input id="anonymousDefaultReport-multisites" {% if anonymousSites is empty %}disabled="disabled" {% endif %}type="radio" value="MultiSites"
|
||||
name="anonymousDefaultReport"{% if anonymousDefaultReport=='MultiSites' %} checked="checked"{% endif %} />
|
||||
<label for="anonymousDefaultReport-multisites">{{ 'General_AllWebsitesDashboard'|translate }}</label><br/>
|
||||
|
||||
<input id="anonymousDefaultReport-specific" {% if anonymousSites is empty %}disabled="disabled" {% endif %}type="radio" value="1"
|
||||
name="anonymousDefaultReport"{% if anonymousDefaultReport>0 %} checked="checked"{% endif %} />
|
||||
<label for="anonymousDefaultReport-specific">{{ 'General_DashboardForASpecificWebsite'|translate }}</label>
|
||||
{% if anonymousSites is not empty %}
|
||||
<select id="anonymousDefaultReportWebsite">
|
||||
{% for info in anonymousSites %}
|
||||
<option value="{{ info.idsite }}" {% if anonymousDefaultReport==info.idsite %} selected="selected"{% endif %}>{{ info.name|raw }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ 'UsersManager_ForAnonymousUsersReportDateToLoadByDefault'|translate }}</td>
|
||||
<td>
|
||||
<fieldset>
|
||||
{% for value,description in availableDefaultDates %}
|
||||
<input id="anonymousDefaultDate-{{ loop.index }}" type="radio" {% if anonymousDefaultDate==value %}checked="checked" {% endif %}value="{{ value }}"
|
||||
name="anonymousDefaultDate"/>
|
||||
<label for="anonymousDefaultDate-{{ loop.index }}">{{ description }}</label>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<input type="submit" value="{{ 'General_Save'|translate }}" id="anonymousUserSettingsSubmit" class="submit"/>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue