diff options
author | matthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2007-07-24 16:57:04 +0400 |
---|---|---|
committer | matthieu_ <matthieu_@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2007-07-24 16:57:04 +0400 |
commit | a105bf4d9021d0e0f003d06418e6002fc7cfb16e (patch) | |
tree | 83a11cf9d9f02aaa41b0b7c93674eea72abe7912 /modules | |
parent | e7c34bf93ae288f17ec1402660e9e5a83e1cb72e (diff) |
First code commit
(from subclipse)
Diffstat (limited to 'modules')
-rwxr-xr-x | modules/Access.php | 167 | ||||
-rwxr-xr-x | modules/Apiable.php | 21 | ||||
-rwxr-xr-x | modules/Config.php | 26 | ||||
-rwxr-xr-x | modules/ErrorHandler.php | 35 | ||||
-rwxr-xr-x | modules/Log.php | 20 | ||||
-rwxr-xr-x | modules/Piwik.php | 166 | ||||
-rwxr-xr-x | modules/PublicApi.php | 217 | ||||
-rwxr-xr-x | modules/SitesManager.php | 194 | ||||
-rwxr-xr-x | modules/UsersManager.php | 190 |
9 files changed, 1036 insertions, 0 deletions
diff --git a/modules/Access.php b/modules/Access.php new file mode 100755 index 0000000000..7f1e9c4744 --- /dev/null +++ b/modules/Access.php @@ -0,0 +1,167 @@ +<?php +class Piwik_Access +{ + private $acl = null; + private $rolesByIdsite = null; + private $idsitesByRole = null; + private $identity = null; //login + private $isSuperUser = false; + + const SUCCESS_SUPERUSER_AUTH_CODE = 42; + + static private $availableRoles = array('anonymous', 'view', 'admin', 'superuser'); + + public function __construct( $auth) + { + $this->auth = $auth; + $this->loadRoles(); + } + + private function loadRoles() + { + $rolesByIdsite = $idsitesByRole = array(); + + // roles = array ( idsite => roleIdSite, idsite2 => roleIdSite2) + $result = $this->auth->authenticate(); + + // case the superUser is logged in + if($result->getCode() == Piwik_Access::SUCCESS_SUPERUSER_AUTH_CODE) + { + $this->isSuperUser = true; + $sitesId = Piwik_SitesManager::getAllSitesId(); + foreach($sitesId as $idSite) + { + $rolesByIdsite[$idSite] = 'superuser'; + $idsitesByRole['superuser'][] = $idSite; + } + } + // valid authentification (normal user logged in) + elseif($result->isValid()) + { + $this->identity = $result->getIdentity(); + + $db = Zend_Registry::get('db'); + $rolesRaw = $db->fetchAll("SELECT role, idsite FROM ".Piwik::prefixTable('role'). + " WHERE login=?", $this->identity); + + foreach($rolesRaw as $role) + { + $rolesByIdsite[$role['idsite']] = $role['role']; + $idsitesByRole[$role['role']][] = $role['idsite']; + } + } + + $this->rolesByIdsite = $rolesByIdsite; + $this->idsitesByRole = $idsitesByRole; + } + + static public function getListRoles() + { + return self::$availableRoles; + } + + private function isRoleAllowed( $roleRequired, $idSite ) + { + // if no role specified, the current role is anonymous + $role = 'anonymous'; + + if(isset($this->rolesByIdsite[$idSite])) + { + $role = $this->rolesByIdsite[$idSite]; + } + + switch($roleRequired) + { + case 'anonymous': + return true; + break; + + case 'view': + return ($role == 'view' || $role == 'admin' || $role == 'superuser'); + break; + + case 'admin': + return ($role == 'admin' || $role == 'superuser'); + break; + + case 'superuser': + return ($role == 'superuser'); + break; + } + } + + public function getIdsitesWithViewAccess() + { + return $this->idsitesByRole['view']; + } + public function getIdsitesWithAdminAccess() + { + return array_merge( + $this->idsitesByRole['view'], + $this->idsitesByRole['admin']); + + } + // is the current authentificated user allowed to access + // the method with the idsite given the minimumRole + // false means no IdSite provided to the method. null means apply the method to all the websites on which the user has + // the access required. + public function isAllowed( $minimumRole, $idSites = false ) + { + // *use cases + // view + 1/2/3 with 1/2 view and 3 anonymous => refused + // view + 1/2/3 with 1/2 view and 3 admin => allowed + // view + 1/2/3 with 1/2 anonymous and 3 admin => refused + // view + null with 1/2 anonymous and 3 admin => allowed + // admin + null with 1/2 view => refused + // admin + 1 with 1 view => refused + // admin + 1 with 1 admin => allowed + // admin + null with 1 admin => allowed + // superuser + 1 with 1 admin => refused + if(is_null($idSites)) + { + if(isset($this->idsitesByRole[$minimumRole])) + { + $idSites = $this->idsitesByRole[$minimumRole]; + } + else + { + $idSites = array(); + } + } + + // when the method called doesn't accept an IdSite parameter, then we must be a superUser + if($idSites === false) + { + if(!$this->isSuperUser) + { + throw new Exception("Access to this resource requires a 'superuser' role."); + } + } + else + { + if(!is_array($idSites)) + { + $idSites = array($idSites); + } + + // when the method called accepts an IdSite parameter, then we test that the user has a minimumRole matching + // for at least one website. For example, if the minimumRole is "admin" then the user must have at least + // one "admin" role for a website to be allowed to execute the method. + // Then the method itself must take care of restricting its scope on the website with the "admin" right. + elseif(count($idSites) > 0) + { + foreach($idSites as $idsite) + { + if(!$this->isRoleAllowed($minimumRole, $idsite)) + { + throw new Exception("Access to this resource requires a '$minimumRole' role for the idsite = $idsite."); + } + } + } + } + + return true; + } +} + +?> diff --git a/modules/Apiable.php b/modules/Apiable.php new file mode 100755 index 0000000000..824f2d8aee --- /dev/null +++ b/modules/Apiable.php @@ -0,0 +1,21 @@ +<?php +class Piwik_Apiable +{ + protected function __construct() + { + } + + public function getMinimumRoleRequired( $methodName ) + { + if(isset($this->roles[$methodName])) + { + $minimumRole = $this->roles[$methodName]; + } + else + { + $minimumRole = 'superuser'; + } + return $minimumRole; + } +} +?>
\ No newline at end of file diff --git a/modules/Config.php b/modules/Config.php new file mode 100755 index 0000000000..267a71e3ba --- /dev/null +++ b/modules/Config.php @@ -0,0 +1,26 @@ +<?php +class Piwik_Config extends Zend_Config_Ini +{ + function __construct() + { + $pathIniFile = PIWIK_INCLUDE_PATH . '/config/config.ini'; + + parent::__construct($pathIniFile, null, true); + + Zend_Registry::set('config', $this); + + $this->setPrefixTables(); + } + + public function setTestEnvironment() + { + $this->database = $this->database_tests; + $this->setPrefixTables(); + } + + public function setPrefixTables() + { + Zend_Registry::set('tablesPrefix', $this->database->tables_prefix); + } +} +?> diff --git a/modules/ErrorHandler.php b/modules/ErrorHandler.php new file mode 100755 index 0000000000..5a30682815 --- /dev/null +++ b/modules/ErrorHandler.php @@ -0,0 +1,35 @@ +<?php +function Piwik_ErrorHandler($errno, $errstr, $errfile, $errline) +{ + $errno = $errno & error_reporting(); + if($errno == 0) return; + if(!defined('E_STRICT')) define('E_STRICT', 2048); + if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096); + print "\n<div style='word-wrap: break-word; border: 3px solid red; padding:4px; width:70%; background-color:#FFFF96;'><b>"; + switch($errno){ + case E_ERROR: print "Error"; break; + case E_WARNING: print "Warning"; break; + case E_PARSE: print "Parse Error"; break; + case E_NOTICE: print "Notice"; break; + case E_CORE_ERROR: print "Core Error"; break; + case E_CORE_WARNING: print "Core Warning"; break; + case E_COMPILE_ERROR: print "Compile Error"; break; + case E_COMPILE_WARNING: print "Compile Warning"; break; + case E_USER_ERROR: print "User Error"; break; + case E_USER_WARNING: print "User Warning"; break; + case E_USER_NOTICE: print "User Notice"; break; + case E_STRICT: print "Strict Notice"; break; + case E_RECOVERABLE_ERROR: print "Recoverable Error"; break; + default: print "Unknown error ($errno)"; break; + } + print ":</b> <i>$errstr</i> in <b>$errfile</b> on line <b>$errline</b>\n"; + print("<br><br>Backtrace --><DIV style='font-family:Courier;font-size:10pt'>"); + + ob_start(); + debug_print_backtrace(); + $out1 = ob_get_clean(); + print(str_replace("\n", "<br>", $out1)); + print("</div><br><br>"); + print "\n</pre></div><br>"; +} +?> diff --git a/modules/Log.php b/modules/Log.php new file mode 100755 index 0000000000..169364e388 --- /dev/null +++ b/modules/Log.php @@ -0,0 +1,20 @@ +<?php +Zend_Loader::loadClass('Zend_Log'); +Zend_Loader::loadClass('Zend_Registry'); + +class Piwik_Log extends Zend_Log +{ + function __construct() + { + parent::__construct(); + + Zend_Loader::loadClass('Zend_Log_Writer_Stream'); + $writer = new Zend_Log_Writer_Stream('php://output'); + $formatter = new Zend_Log_Formatter_Simple('%message% <br>' . PHP_EOL); + $writer->setFormatter($formatter); + $this->addWriter($writer); + Zend_Registry::set('logger', $this); + } +} + +?> diff --git a/modules/Piwik.php b/modules/Piwik.php new file mode 100755 index 0000000000..b5b7b20afd --- /dev/null +++ b/modules/Piwik.php @@ -0,0 +1,166 @@ +<?php + +class Piwik +{ + const CLASSES_PREFIX = "Piwik_"; + + static public function log($message, $priority = Zend_Log::NOTICE) + { + Zend_Registry::get('logger')->log($message . PHP_EOL, $priority); + } + + static public function getTablesCreateSql() + { + $config = Zend_Registry::get('config'); + $prefixTables = $config->database->tables_prefix; + $tables = array( + 'user' => "CREATE TABLE {$prefixTables}user ( + login VARCHAR(20) NOT NULL, + password CHAR(32) NOT NULL, + alias VARCHAR(45) NOT NULL, + email VARCHAR(100) NOT NULL, + token_auth CHAR(32) NOT NULL, + date_registered TIMESTAMP NOT NULL, + PRIMARY KEY(login) + ) + ", + + 'role' => "CREATE TABLE {$prefixTables}role ( + login VARCHAR(20) NOT NULL, + idsite INTEGER UNSIGNED NOT NULL, + role VARCHAR(10) NULL, + PRIMARY KEY(login, idsite) + ) + ", + + 'site' => "CREATE TABLE {$prefixTables}site ( + idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(90) NOT NULL, + main_url VARCHAR(255) NOT NULL, + PRIMARY KEY(idsite) + ) + ", + + 'site_url' => "CREATE TABLE {$prefixTables}site_url ( + idsite INTEGER(10) UNSIGNED NOT NULL, + url VARCHAR(255) NOT NULL, + PRIMARY KEY(idsite, url) + ) + ", + + ); + return $tables; + } + + static public function prefixClass( $class ) + { + if(substr_count($class, Piwik::CLASSES_PREFIX) > 0) + { + return $class; + } + return Piwik::CLASSES_PREFIX.$class; + } + + static public function prefixTable( $table ) + { + $config = Zend_Registry::get('config'); + $prefixTables = $config->database->tables_prefix; + return $prefixTables . $table; + } + + static public function getTablesNames() + { + $aTables = array_keys(self::getTablesCreateSql()); + $config = Zend_Registry::get('config'); + $prefixTables = $config->database->tables_prefix; + $return = array(); + foreach($aTables as $table) + { + $return[] = $prefixTables.$table; + } + return $return; + } + + static public function getTablesInstalled() + { + $allMyTables = self::getTablesNames(); + + $db = Zend_Registry::get('db'); + $allTables = $db->fetchCol('SHOW TABLES'); + + $intersect = array_intersect($allTables, $allMyTables); + + return $intersect; + } + + static public function createDatabase() + { + $db = Zend_Registry::get('db'); + $dbName = Zend_Registry::get('config')->database->dbname; + $db->query("CREATE DATABASE IF NOT EXISTS ".$dbName); + } + + static public function dropDatabase() + { + $db = Zend_Registry::get('db'); + $dbName = Zend_Registry::get('config')->database->dbname; + $db->query("DROP DATABASE IF EXISTS ".$dbName); + } + + + static public function createDatabaseObject() + { + $config = Zend_Registry::get('config'); + $db = Zend_Db::factory($config->database->adapter, $config->database->toArray()); + Zend_Db_Table::setDefaultAdapter($db); + Zend_Registry::set('db', $db); + } + + static public function createLogObject() + { + $log = new Piwik_Log; + } + static public function createConfigObject() + { + $config = new Piwik_Config; + + assert(count($config) != 0); + } + + static public function createTables() + { + $db = Zend_Registry::get('db'); + + $config = Zend_Registry::get('config'); + $prefixTables = $config->database->tables_prefix; + + Piwik::log("Creating ". implode(", ", self::getTablesNames())); + + $tablesToCreate = self::getTablesCreateSql(); + + $tablesAlreadyInstalled = self::getTablesInstalled(); + + foreach($tablesToCreate as $tableName => $tableSql) + { + $tableName = $prefixTables . $tableName; + + // if the table doesn't exist already + if(!in_array($tableName, $tablesAlreadyInstalled)) + { + $db->query( $tableSql ); + } + } + } + + static public function uninstall() + { + // delete tables + //create tables + $db = Zend_Registry::get('db'); + + Piwik::log("Droping ". implode(", ", self::getTablesNames())); + + $db->query( "DROP TABLE IF EXISTS ". implode(", ", self::getTablesNames()) ); + } +} +?> diff --git a/modules/PublicApi.php b/modules/PublicApi.php new file mode 100755 index 0000000000..c536e1025b --- /dev/null +++ b/modules/PublicApi.php @@ -0,0 +1,217 @@ +<?php +class Piwik_PublicApi +{ + static $classCalled = null; + private $api = null; + + private $methodsNotToPublish = array('getMinimumRoleRequired'); + + static private $instance = null; + protected function __construct() + {} + + static public function getInstance() + { + if (self::$instance == null) + { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + public function registerClass( $class ) + { + Zend_Loader::loadClass($class); + + $rClass = new ReflectionClass($class); + + if(!$rClass->isSubclassOf(new ReflectionClass("Piwik_Apiable"))) + { + throw new Exception("To publish its public methods in the API, the class '$class' must be a subclass of 'Piwik_Apiable'."); + } + + Piwik::log("List of the public methods for the class $class"); + + $rMethods = $rClass->getMethods(); + foreach($rMethods as $method) + { + if($method->isPublic() + && !$method->isConstructor() + && !in_array($method->getName(), $this->methodsNotToPublish ) + ) + { + $name = $method->getName(); + + $parameters = $method->getParameters(); + + $aParameters = array(); + foreach($parameters as $parameter) + { + $nameVariable = $parameter->getName(); + + $defaultValue = ''; + if($parameter->isDefaultValueAvailable()) + { + $defaultValue = $parameter->getDefaultValue(); + } + + $aParameters[$nameVariable] = $defaultValue; + } + $this->api[$class][$name]['parameters'] = $aParameters; + $this->api[$class][$name]['numberOfRequiredParameters'] = $method->getNumberOfRequiredParameters(); + + Piwik::log("- $name is public ".$this->getStrListParameters($class, $name)); + } + } + } + + private function getStrListParameters($class, $name) + { + $aParameters = $this->getParametersList($class, $name); + $asParameters = array(); + foreach($aParameters as $nameVariable=> $defaultValue) + { + $str = $nameVariable; + if(!empty($defaultValue)) + { + $str .= " = $defaultValue"; + } + $asParameters[] = $str; + } + $sParameters = implode(", ", $asParameters); + return "[$sParameters]"; + } + private function getParametersList($class, $name) + { + return $this->api[$class][$name]['parameters']; + } + private function getNumberOfRequiredParameters($class, $name) + { + return $this->api[$class][$name]['numberOfRequiredParameters']; + } + + private function isMethodAvailable( $className, $methodName) + { + return isset($this->api[$className][$methodName]); + } + public function __get($name) + { + self::$classCalled = $name; + return $this; + } + + private function getIdSitesParameter($class, $name, $parameters) + { + $paramsDefaultValues = $this->getParametersList($class, $name); + $parametersNames = array_keys($paramsDefaultValues); + $parametersNames = array_map("strtolower", $parametersNames); + + $sitesIdToLookFor = array("idsites", "idsite", "sitesid", "siteid", "siteids"); + + $newlyFound = false; + $found = false; + foreach($sitesIdToLookFor as $strIdSite) + { + $newlyFound = array_search($strIdSite, $parametersNames); + if($newlyFound !== false + && $found !== false) + { + throw new Exception(" + It seems that the parameters list ".$this->getStrListParameters($class, $name)." contains two potential IdSite parameters. + Please rename the method parameters so that only one IdSite can be found in the method parameters list. + The following string are considered as being idSite parameter names : [".implode(", ", $sitesIdToLookFor)."]" ); + } + elseif($newlyFound !== false) + { + $found = $newlyFound; + } + } + + if($found===false) + { + return false; + } + else + { + if(isset($parameters[$found])) + { + $parameters[$found]; + } + else + { + $values = array_values($paramsDefaultValues); + if(isset($values[$found])) + { + return $values[$found]; + } + else + { + exit("must test this case and the other ones..."); + } + } + } + } + + private function checkNumberOfParametersMatch($className, $methodName, $parameters) + { + $nbParamsGiven = count($parameters); + $nbParamsRequired = $this->getNumberOfRequiredParameters($className, $methodName); + + if($nbParamsGiven < $nbParamsRequired) + { + throw new Exception("The number of parameters provided ($nbParamsGiven) is less than the number of required parameters ($nbParamsRequired) for this method. + Please check the method API."); + } + elseif($nbParamsGiven > $nbParamsRequired) + { + throw new Exception("The number of parameters provided ($nbParamsGiven) is greater than the number of required parameters ($nbParamsRequired) for this method. + Please check the method API."); + } + return true; + + } + public function __call($methodName, $parameters ) + { + assert(!is_null(self::$classCalled)); + + $args = @implode(", ", $parameters); + + $className = Piwik::prefixClass(self::$classCalled); + if(!method_exists("$className", "getInstance")) + { + throw new Exception("Objects that provide an API must be Singleton and have a 'static public function getInstance()' method."); + } + $object = null; + eval("\$object = $className::getInstance();"); + + // check method exists + if(!$this->isMethodAvailable($className, $methodName)) + { + throw new Exception("The method '$methodName' does not exist or is not available in the module '".self::$classCalled."'."); + } + Piwik::log("Calling ".self::$classCalled.".$methodName [$args]"); + + try { + // first check number of parameters do match + $this->checkNumberOfParametersMatch($className, $methodName, $parameters); + + $idSites = $this->getIdSitesParameter($className, $methodName, $parameters); + + $access = Zend_Registry::get('access'); + $access->isAllowed( $object->getMinimumRoleRequired($methodName), $idSites); + Piwik::log('Access granted!'); + + // call the method + call_user_func(array($object, $methodName), $parameters); + } + catch( Exception $e) + { + Piwik::log("Error during API call...". $e->getMessage()); + exit; + } + + self::$classCalled = null; + } +} +?>
\ No newline at end of file diff --git a/modules/SitesManager.php b/modules/SitesManager.php new file mode 100755 index 0000000000..9ffd74b61f --- /dev/null +++ b/modules/SitesManager.php @@ -0,0 +1,194 @@ +<?php + +class Piwik_SitesManager extends Piwik_APIable +{ + static private $instance = null; + protected function __construct() + { + parent::__construct(); + } + + static public function getInstance() + { + if (self::$instance == null) + { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + protected $roles = array( + 'getSites' => 'anonymous', + 'getSitesId' => 'anonymous', + 'getSiteUrlsFromId' => 'view', + 'replaceSiteUrls' => 'admin', + 'siteExists' => 'anonymous', + ); + + static private function checkName($name) + { + if(empty($name)) + { + throw new Exception("The site name can't be empty."); + } + } + + static private function checkUrls($aUrls) + { + foreach($aUrls as $url) + { + if(!self::isValidUrl($url)) + { + throw new Exception("The url '$url' is not a valid URL."); + } + } + } + + static private function cleanParameterUrls( $aUrls ) + { + if(!is_array($aUrls)) + { + $aUrls = array($aUrls); + } + foreach($aUrls as &$url) + { + $url = self::removeTrailingSlash($url); + } + return $aUrls; + } + + static private function checkIdsite($idsite) + { + if(!is_int($idsite) + || $idsite <= 0) + { + throw new Exception("Idsite must be an integer > 0."); + } + + if(!self::siteExists($idsite)) + { + throw new Exception("The site with Idsite = $idsite doesn't exist."); + } + } + + static public function addSite( $name, $aUrls ) + { + self::checkName($name); + $aUrls = self::cleanParameterUrls($aUrls); + self::checkUrls($aUrls); + + if(count($aUrls) == 0) + { + throw new Exception("You must specify at least one URL for the site."); + } + + $db = Zend_Registry::get('db'); + + $url = $aUrls[0]; + $aUrls = array_slice($aUrls, 1); + + $db->insert(Piwik::prefixTable("site"), array( + 'name' => $name, + 'main_url' => $url, + ) + ); + + $idSite = $db->lastInsertId(); + + self::insertSiteUrls($idSite, $aUrls); + } + + static private function insertSiteUrls($idSite, $aUrls) + { + $db = Zend_Registry::get('db'); + foreach($aUrls as $url) + { + $db->insert(Piwik::prefixTable("site_url"), array( + 'idsite' => $idSite, + 'url' => $url + ) + ); + } + } + + static public function addSiteUrls( $idsite, $aUrls) + { + $urls = self::getSiteUrlsFromId($idsite); + $toInsert = array_diff($aUrls, $urls); + self::insertSiteUrls($idsite, $toInsert); + } + + static public function replaceSiteUrls( $idsite, $aUrls) + { + self::checkIdsite($idsite); + $aUrls = self::cleanParameterUrls($aUrls); + self::checkUrls($aUrls); + + self::deleteSiteUrls($idsite); + self::addSiteUrls($idsite, $aUrls); + } + + static private function deleteSiteUrls($idsite) + { + $db = Zend_Registry::get('db'); + $db->query("DELETE FROM ".Piwik::prefixTable("site_url") ." WHERE idsite = ?", $idsite); + } + + static public function getSites() + { + $db = Zend_Registry::get('db'); + $sites = $db->fetchAll("SELECT * FROM ".Piwik::prefixTable("site")); + return $sites; + } + + static public function getSiteUrlsFromId( $idsite ) + { + $db = Zend_Registry::get('db'); + $urls = $db->fetchCol("SELECT url FROM ".Piwik::prefixTable("site_url"). " WHERE idsite = ?", $idsite); + return $urls; + } + static public function getSitesId() + { + $sites = self::getSites(); + $aSitesId = array(); + foreach($sites as $site) + { + $aSitesId[] = $site["idsite"]; + } + return $aSitesId; + } + + static public function getAllSitesId() + { + $db = Zend_Registry::get('db'); + $idSites = $db->fetchCol("SELECT idsite FROM ".Piwik::prefixTable('site')); + return $idSites; + } + + static public function getSitesIdWithAdminAccess() + { + return array(); + } + + static public function siteExists( $idsite ) + { + $sites = self::getSitesId(); + return in_array($idsite, $sites); + } + + static private function removeTrailingSlash($url) + { + // if there is a final slash, we take the URL without this slash (expected URL format) + if($url[strlen($url)-1] == '/') + { + $url = substr($url,0,strlen($url)-1); + } + return $url; + } + static private function isValidUrl( $url ) + { + return ereg('^http[s]?://[A-Za-z0-9\/_.-]', $url); + } +} +?> diff --git a/modules/UsersManager.php b/modules/UsersManager.php new file mode 100755 index 0000000000..a09fd57f28 --- /dev/null +++ b/modules/UsersManager.php @@ -0,0 +1,190 @@ +<?php +// +// getSiteFromId( id ) +// getSiteFromUrl( mainUrl ) +// getSites( accessType ) +// getNumberOfSites() +// getNumberOfSitesWithAdminAccess() +Zend_Loader::loadClass("Piwik_Access"); + + +class Piwik_UsersManager extends Piwik_APIable +{ +// +// getUsersExtended() +// +// getUserFromLogin( login ) +// getUserFromEmail( email ) +// + static private $instance = null; + protected function __construct() + { + parent::__construct(); + } + + static public function getInstance() + { + if (self::$instance == null) + { + $c = __CLASS__; + self::$instance = new $c(); + } + return self::$instance; + } + + static public function getUsers() + { + $db = Zend_Registry::get('db'); + $prefix = Zend_Registry::get("tablesPrefix"); + $users = $db->fetchCol("SELECT login FROM ".Piwik::prefixTable("user")); + return $users; + } + + static public function addUser( $userLogin, $password, $alias, $email ) + { + if(self::userExists($userLogin)) + { + throw new Exception("Login $login already exists."); + } + if(!self::isValidLoginString($userLogin)) + { + throw new Exception("The login must contain only letters, numbers, or the characters '_' or '-' or '.'."); + } + if(!self::isValidPasswordString($password)) + { + throw new Exception("The password must contain at least 6 characters including at least one number."); + } + if(!self::isValidEmailString($email)) + { + throw new Exception("The email doesn't have a valid format."); + } + + $db = Zend_Registry::get('db'); + + $db->insert( Piwik::prefixTable("user"), array( + 'login' => $userLogin, + 'password' => md5($password), + 'alias' => $alias, + 'email' => $email, + 'token_auth' => self::getTokenAuth($userLogin,$password) + ) + ); + + + } + + static public function deleteUser( $userLogin ) + { + if(!self::userExists($userLogin)) + { + throw new Exception("User $userLogin doesn't exist therefore it can't be deleted."); + } + + $db = Zend_Registry::get('db'); + $db->query("DELETE FROM ".Piwik::prefixTable("user")." WHERE login = ?", $userLogin); + + } + + static public function userExists( $userLogin ) + { + $aLogins = self::getUsers(); + return in_array($userLogin, $aLogins); + } + + // role = anonymous / view / admin / superuser + static public function setUserRole( $role, $userLogin, $idSites = null) + { + $roles = Piwik_Access::getListRoles(); + // do not allow to set the superUser role + unset($roles[array_search("superuser", $roles)]); + + if(!in_array($role,$roles)) + { + throw new Exception("The parameter role must have one of the following values : [ ". implode(", ", $roles)." ]"); + } + if(!self::userExists($userLogin)) + { + throw new Exception("User '$userLogin' doesn't exist."); + } + + if(is_null($idSites)) + { + $idSites = Piwik_SitesManager::getSitesIdWithAdminAccess(); + } + elseif(!is_array($idSites)) + { + $idSites = array($idSites); + } + + foreach($idSites as $idsite) + { + if( !is_null($idsite) + && !Piwik_SitesManager::siteExists($idsite)) + { + throw new Exception("Site id = $idsite doesn't exist."); + } + } + + // delete UserRole + $db = Zend_Registry::get('db'); + + foreach($idSites as $idsite) + { + $db->query( "DELETE FROM ".Piwik::prefixTable("role"). + " WHERE idsite = ? AND login = ?", + array($idsite, $userLogin) + ); + } + + // if the role is anonymous then we don't save it as this is the default value + // when no role are specified + if($role != "anonymous") + { + foreach($idSites as $idsite) + { + $db->insert( Piwik::prefixTable("role"), + array( "idsite" => $idsite, + "login" => $userLogin, + "role" => $role) + ); + } + } + + } + + static private function getTokenAuth($userLogin, $password) + { + return md5($userLogin . $password . time()); + + } + static private function isValidEmailString( $email ) + { + return (preg_match('/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z]{2,4}$/', $email) > 0); + } + + static private function isValidLoginString( $input ) + { + return preg_match('/^[A-Za-z0-9\_\.-]*$/', $input) > 0; + } + + static private function isValidPasswordString( $input ) + { + $isNumeric = false; + + $l = strlen($input); + if( $l < 6) + { + return false; + } + + for($i = 0; $i < $l ; $i++) + { + if(is_numeric($input[$i])) + { + $isNumeric=true; + } + } + return $isNumeric; + } + +}
\ No newline at end of file |