protected function execute(InputInterface $input, OutputInterface $output)
 {
     $this->recreateContainerWithWebEnvironment();
     $this->initHostAndQueryString($input);
     if ($this->isTestModeEnabled()) {
         $indexFile = '/tests/PHPUnit/proxy/';
         $this->resetDatabase();
     } else {
         $indexFile = '/';
     }
     $indexFile .= 'index.php';
     if (!empty($_GET['pid'])) {
         $process = new Process($_GET['pid']);
         if ($process->hasFinished()) {
             return;
         }
         $process->startProcess();
     }
     if ($input->getOption('superuser')) {
         StaticContainer::addDefinitions(array('observers.global' => \DI\add(array(array('Environment.bootstrapped', function () {
             Access::getInstance()->setSuperUserAccess(true);
         })))));
     }
     require_once PIWIK_INCLUDE_PATH . $indexFile;
     if (!empty($process)) {
         $process->finishProcess();
     }
 }
Exemple #2
0
 private function makeSureTestRunsInContextOfAnonymousUser()
 {
     Piwik::postEvent('Request.initAuthenticationObject');
     $access = Access::getInstance();
     $this->hasSuperUserAccess = $access->hasSuperUserAccess();
     $access->setSuperUserAccess(false);
     $access->reloadAccess(StaticContainer::get('Piwik\\Auth'));
     Request::reloadAuthUsingTokenAuth(array('token_auth' => 'anonymous'));
 }
Exemple #3
0
 public function setUp()
 {
     parent::setUp();
     $access = Access::getInstance();
     $access->setSuperUserAccess(true);
     $this->idSiteAccess = APISitesManager::getInstance()->addSite("test", "http://test");
     \Piwik\Plugin\Manager::getInstance()->loadPlugins(array('MultiSites', 'VisitsSummary', 'Actions'));
     \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
 }
 public function test_PiwikUserIsNotCreated_IfPiwikUserAlreadyExists()
 {
     Access::getInstance()->setSuperUserAccess(true);
     UsersManagerAPI::getInstance()->addUser(self::TEST_LOGIN, self::TEST_PASS, '*****@*****.**', $alias = false);
     Access::getInstance()->setSuperUserAccess(false);
     $this->authenticateViaLdap();
     $user = Db::fetchRow("SELECT login, password, alias, email, token_auth FROM " . Common::prefixTable('user') . " WHERE login = ?", array(self::TEST_LOGIN));
     $this->assertNotEmpty($user);
     $this->assertEquals(array('login' => self::TEST_LOGIN, 'password' => md5(self::TEST_PASS), 'alias' => self::TEST_LOGIN, 'email' => '*****@*****.**', 'token_auth' => UsersManagerAPI::getInstance()->getTokenAuth(self::TEST_LOGIN, md5(self::TEST_PASS))), $user);
     $this->assertNoAccessInDb();
 }
 /**
  * NOTE: This test must be last since the new sites that get added are added in
  *       random order.
  */
 public function testDynamicResolverSitesCreated()
 {
     self::$fixture->logVisitsWithDynamicResolver();
     // reload access so new sites are viewable
     Access::getInstance()->setSuperUserAccess(true);
     // make sure sites aren't created twice
     $piwikDotNet = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.net');
     $this->assertEquals(1, count($piwikDotNet));
     $anothersiteDotCom = API::getInstance()->getSitesIdFromSiteUrl('http://anothersite.com');
     $this->assertEquals(1, count($anothersiteDotCom));
     $whateverDotCom = API::getInstance()->getSitesIdFromSiteUrl('http://whatever.com');
     $this->assertEquals(1, count($whateverDotCom));
 }
Exemple #6
0
 public function setUp()
 {
     // drop all tables
     Db::dropAllTables();
     // download data dump if url supplied
     if (is_file($this->dumpUrl)) {
         $dumpPath = $this->dumpUrl;
     } else {
         $dumpPath = PIWIK_INCLUDE_PATH . '/tmp/logdump.sql.gz';
         $bufferSize = 1024 * 1024;
         $dump = fopen($this->dumpUrl, 'rb');
         $outfile = fopen($dumpPath, 'wb');
         $bytesRead = 0;
         while (!feof($dump)) {
             fwrite($outfile, fread($dump, $bufferSize), $bufferSize);
             $bytesRead += $bufferSize;
         }
         fclose($dump);
         fclose($outfile);
         if ($bytesRead <= 40 * 1024 * 1024) {
             // sanity check
             throw new Exception("Could not download sql dump!");
         }
     }
     // unzip the dump
     if (substr($dumpPath, -3) === ".gz") {
         $deflatedDumpPath = PIWIK_INCLUDE_PATH . '/tmp/logdump.sql';
         // TODO: should depend on name of URL
         exec("gunzip -c \"" . $dumpPath . "\" > \"{$deflatedDumpPath}\"", $output, $return);
         if ($return !== 0) {
             throw new Exception("gunzip failed: " . implode("\n", $output));
         }
     } else {
         $deflatedDumpPath = $dumpPath;
     }
     // load the data into the correct database
     $user = Config::getInstance()->database['username'];
     $password = Config::getInstance()->database['password'];
     Config::getInstance()->database['tables_prefix'] = $this->tablesPrefix;
     $cmd = "mysql -u \"{$user}\" \"--password={$password}\" {$this->dbName} < \"" . $deflatedDumpPath . "\" 2>&1";
     exec($cmd, $output, $return);
     if ($return !== 0) {
         throw new Exception("Failed to load sql dump: " . implode("\n", $output));
     }
     // make sure archiving will be called
     Rules::setBrowserTriggerArchiving(true);
     // reload access
     Access::getInstance()->reloadAccess();
     $this->getTestEnvironment()->configOverride = array('database' => array('tables_prefix' => $this->tablesPrefix));
     $this->getTestEnvironment()->save();
 }
Exemple #7
0
 public function setUserDefaultReportPreference()
 {
     // We initialize the default report user preference for each user (if it hasn't been inited before) for performance,
     // doing this lets us avoid loading all siteIds (which can be 50k or more) when this preference is requested.
     // getting the user preference can be called quite often when generating links etc (to get defaultWebsiteId).
     $usersModel = $this->usersModel;
     $usersManagerApi = $this->usersManagerApi;
     Access::getInstance()->doAsSuperUser(function () use($usersModel, $usersManagerApi) {
         $allUsers = $usersModel->getUsers(array());
         foreach ($allUsers as $user) {
             $usersManagerApi->initUserPreferenceWithDefault($user['login'], API::PREFERENCE_DEFAULT_REPORT);
         }
     });
 }
 /**
  * Setup the database and create the base tables for all tests
  */
 public function setUp()
 {
     parent::setUp();
     static::$fixture->extraDefinitions = array_merge(static::provideContainerConfigBeforeClass(), $this->provideContainerConfig());
     static::$fixture->createEnvironmentInstance();
     Db::createDatabaseObject();
     Fixture::loadAllPlugins(new TestingEnvironmentVariables(), get_class($this), self::$fixture->extraPluginsToLoad);
     Access::getInstance()->setSuperUserAccess(true);
     if (!empty(self::$tableData)) {
         self::restoreDbTables(self::$tableData);
     }
     PiwikCache::getEagerCache()->flushAll();
     PiwikCache::getTransientCache()->flushAll();
     MenuAbstract::clearMenus();
 }
 /**
  * NOTE: This test must be last since the new sites that get added are added in
  *       random order.
  * NOTE: This test combines two tests in order to avoid executing the log importer another time.
  *       If the log importer were refactored, the invalid requests test could be a unit test in
  *       python.
  */
 public function test_LogImporter_CreatesSitesWhenDynamicResolverUsed_AndReportsOnInvalidRequests()
 {
     $this->simulateInvalidTrackerRequest();
     $output = self::$fixture->logVisitsWithDynamicResolver($maxPayloadSize = 3);
     // reload access so new sites are viewable
     Access::getInstance()->setSuperUserAccess(true);
     // make sure sites aren't created twice
     $piwikDotNet = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.net');
     $this->assertEquals(1, count($piwikDotNet));
     $anothersiteDotCom = API::getInstance()->getSitesIdFromSiteUrl('http://anothersite.com');
     $this->assertEquals(1, count($anothersiteDotCom));
     $whateverDotCom = API::getInstance()->getSitesIdFromSiteUrl('http://whatever.com');
     $this->assertEquals(1, count($whateverDotCom));
     // make sure invalid requests are reported correctly
     $this->assertContains('The Piwik tracker identified 2 invalid requests on lines: 10, 11', $output);
     $this->assertContains("The following lines were not tracked by Piwik, either due to a malformed tracker request or error in the tracker:\n\n10, 11", $output);
 }
Exemple #10
0
 public function setUp()
 {
     // drop all tables
     Db::dropAllTables();
     // download data dump if url supplied
     if (is_file($this->dumpUrl)) {
         $dumpPath = $this->dumpUrl;
     } else {
         $dumpPath = PIWIK_INCLUDE_PATH . '/tmp/logdump.sql.gz';
         $bytesRead = $this->downloadDumpInPath($dumpPath);
         // sanity check
         if ($bytesRead <= 40 * 1024 * 1024) {
             $str = "Could not download sql dump! You can manually download %s into %s";
             throw new Exception(sprintf($str, $this->dumpUrl, $dumpPath));
         }
     }
     // unzip the dump
     if (substr($dumpPath, -3) === ".gz") {
         $deflatedDumpPath = PIWIK_INCLUDE_PATH . '/tmp/logdump.sql';
         // TODO: should depend on name of URL
         exec("gunzip -c \"" . $dumpPath . "\" > \"{$deflatedDumpPath}\"", $output, $return);
         if ($return !== 0) {
             throw new Exception("gunzip failed: " . implode("\n", $output));
         }
     } else {
         $deflatedDumpPath = $dumpPath;
     }
     // load the data into the correct database
     $user = Config::getInstance()->database['username'];
     $password = Config::getInstance()->database['password'];
     $host = Config::getInstance()->database['host'];
     Config::getInstance()->database['tables_prefix'] = $this->tablesPrefix;
     $cmd = "mysql -h \"{$host}\" -u \"{$user}\" \"--password={$password}\" {$this->dbName} < \"" . $deflatedDumpPath . "\" 2>&1";
     exec($cmd, $output, $return);
     if ($return !== 0) {
         throw new Exception("Failed to load sql dump: " . implode("\n", $output));
     }
     // make sure archiving will be called
     Rules::setBrowserTriggerArchiving(true);
     // reload access
     Access::getInstance()->reloadAccess();
     $testVars = new TestingEnvironmentVariables();
     $testVars->configOverride = array('database' => array('tables_prefix' => $this->tablesPrefix));
     $testVars->save();
 }
Exemple #11
0
 public static function updateComponents(Updater $updater, $componentsWithUpdateFile)
 {
     $warnings = array();
     $errors = array();
     $deactivatedPlugins = array();
     $coreError = false;
     if (!empty($componentsWithUpdateFile)) {
         $currentAccess = Access::getInstance();
         $hasSuperUserAccess = $currentAccess->hasSuperUserAccess();
         if (!$hasSuperUserAccess) {
             $currentAccess->setSuperUserAccess(true);
         }
         // if error in any core update, show message + help message + EXIT
         // if errors in any plugins updates, show them on screen, disable plugins that errored + CONTINUE
         // if warning in any core update or in any plugins update, show message + CONTINUE
         // if no error or warning, success message + CONTINUE
         foreach ($componentsWithUpdateFile as $name => $filenames) {
             try {
                 $warnings = array_merge($warnings, $updater->update($name));
             } catch (UpdaterErrorException $e) {
                 $errors[] = $e->getMessage();
                 if ($name == 'core') {
                     $coreError = true;
                     break;
                 } elseif (\Piwik\Plugin\Manager::getInstance()->isPluginActivated($name)) {
                     \Piwik\Plugin\Manager::getInstance()->deactivatePlugin($name);
                     $deactivatedPlugins[] = $name;
                 }
             }
         }
         if (!$hasSuperUserAccess) {
             $currentAccess->setSuperUserAccess(false);
         }
     }
     Filesystem::deleteAllCacheOnUpdate();
     $result = array('warnings' => $warnings, 'errors' => $errors, 'coreError' => $coreError, 'deactivatedPlugins' => $deactivatedPlugins);
     /**
      * Triggered after Piwik has been updated.
      */
     Piwik::postEvent('CoreUpdater.update.end');
     return $result;
 }
Exemple #12
0
 public function performSetUp($setupEnvironmentOnly = false)
 {
     // TODO: don't use static var, use test env var for this
     TestingEnvironmentManipulator::$extraPluginsToLoad = $this->extraPluginsToLoad;
     $this->dbName = $this->getDbName();
     if ($this->persistFixtureData) {
         $this->dropDatabaseInSetUp = false;
         $this->dropDatabaseInTearDown = false;
         $this->overwriteExisting = false;
         $this->removeExistingSuperUser = false;
     }
     $testEnv = $this->getTestEnvironment();
     $testEnv->testCaseClass = $this->testCaseClass;
     $testEnv->fixtureClass = get_class($this);
     $testEnv->dbName = $this->dbName;
     $testEnv->extraDiEnvironments = $this->extraDiEnvironments;
     foreach ($this->extraTestEnvVars as $name => $value) {
         $testEnv->{$name} = $value;
     }
     $testEnv->save();
     $this->createEnvironmentInstance();
     if ($this->dbName === false) {
         // must be after test config is created
         $this->dbName = self::getConfig()->database['dbname'];
     }
     try {
         static::connectWithoutDatabase();
         if ($this->dropDatabaseInSetUp || $this->resetPersistedFixture) {
             $this->dropDatabase();
         }
         DbHelper::createDatabase($this->dbName);
         DbHelper::disconnectDatabase();
         Tracker::disconnectCachedDbConnection();
         // reconnect once we're sure the database exists
         self::getConfig()->database['dbname'] = $this->dbName;
         Db::createDatabaseObject();
         Db::get()->query("SET wait_timeout=28800;");
         DbHelper::createTables();
         self::getPluginManager()->unloadPlugins();
     } catch (Exception $e) {
         static::fail("TEST INITIALIZATION FAILED: " . $e->getMessage() . "\n" . $e->getTraceAsString());
     }
     include "DataFiles/Providers.php";
     if (!$this->isFixtureSetUp()) {
         DbHelper::truncateAllTables();
     }
     // We need to be SU to create websites for tests
     Access::getInstance()->setSuperUserAccess();
     Cache::deleteTrackerCache();
     self::resetPluginsInstalledConfig();
     $testEnvironment = $this->getTestEnvironment();
     static::loadAllPlugins($testEnvironment, $this->testCaseClass, $this->extraPluginsToLoad);
     self::updateDatabase();
     self::installAndActivatePlugins($testEnvironment);
     $_GET = $_REQUEST = array();
     $_SERVER['HTTP_REFERER'] = '';
     FakeAccess::$superUserLogin = '******';
     File::$invalidateOpCacheBeforeRead = true;
     if ($this->configureComponents) {
         IPAnonymizer::deactivate();
         $dntChecker = new DoNotTrackHeaderChecker();
         $dntChecker->deactivate();
     }
     if ($this->createSuperUser) {
         self::createSuperUser($this->removeExistingSuperUser);
         if (!Access::getInstance() instanceof FakeAccess) {
             $this->loginAsSuperUser();
         }
         APILanguageManager::getInstance()->setLanguageForUser('superUserLogin', 'en');
     }
     SettingsPiwik::overwritePiwikUrl(self::getTestRootUrl());
     if ($setupEnvironmentOnly) {
         return;
     }
     PiwikCache::getTransientCache()->flushAll();
     if ($this->overwriteExisting || !$this->isFixtureSetUp()) {
         $this->setUp();
         $this->markFixtureSetUp();
         $this->log("Database {$this->dbName} marked as successfully set up.");
     } else {
         $this->log("Using existing database {$this->dbName}.");
     }
 }
Exemple #13
0
 public function test_reloadAccess_DoesNotRemoveSuperUserAccess_IfUsedInDoAsSuperUser()
 {
     Access::getInstance()->setSuperUserAccess(false);
     Access::doAsSuperUser(function () {
         $access = Access::getInstance();
         Core_AccessTest::assertTrue($access->hasSuperUserAccess());
         $access->reloadAccess();
         Core_AccessTest::assertTrue($access->hasSuperUserAccess());
     });
 }
 /**
  * @return array|bool
  */
 protected function updateComponents()
 {
     Access::getInstance();
     return Access::doAsSuperUser(function () {
         $updater = new Updater();
         $componentsWithUpdateFile = $updater->getComponentUpdates();
         if (empty($componentsWithUpdateFile)) {
             return false;
         }
         $result = $updater->updateComponents($componentsWithUpdateFile);
         return $result;
     });
 }
 /**
  * @group Plugins
  */
 public function testGetSitesIdFromSiteUrlUser()
 {
     $idsite = API::getInstance()->addSite("site1", array("http://www.piwik.net", "http://piwik.com"));
     $idsite = API::getInstance()->addSite("site2", array("http://piwik.com", "http://piwik.net"));
     $idsite = API::getInstance()->addSite("site3", array("http://piwik.com", "http://piwik.org"));
     $saveAccess = Access::getInstance();
     APIUsersManager::getInstance()->addUser("user1", "geqgegagae", "*****@*****.**", "alias");
     APIUsersManager::getInstance()->setUserAccess("user1", "view", array(1));
     APIUsersManager::getInstance()->addUser("user2", "geqgegagae", "*****@*****.**", "alias");
     APIUsersManager::getInstance()->setUserAccess("user2", "view", array(1));
     APIUsersManager::getInstance()->setUserAccess("user2", "admin", array(3));
     APIUsersManager::getInstance()->addUser("user3", "geqgegagae", "*****@*****.**", "alias");
     APIUsersManager::getInstance()->setUserAccess("user3", "view", array(1, 2));
     APIUsersManager::getInstance()->setUserAccess("user3", "admin", array(3));
     $pseudoMockAccess = new FakeAccess();
     FakeAccess::$superUser = false;
     FakeAccess::$identity = 'user1';
     FakeAccess::setIdSitesView(array(1));
     FakeAccess::setIdSitesAdmin(array());
     Access::setSingletonInstance($pseudoMockAccess);
     $idsites = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.com');
     $this->assertEquals(1, count($idsites));
     // testing URL normalization
     $idsites = API::getInstance()->getSitesIdFromSiteUrl('http://www.piwik.com');
     $this->assertEquals(1, count($idsites));
     $idsites = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.net');
     $this->assertEquals(1, count($idsites));
     $pseudoMockAccess = new FakeAccess();
     FakeAccess::$superUser = false;
     FakeAccess::$identity = 'user2';
     FakeAccess::setIdSitesView(array(1));
     FakeAccess::setIdSitesAdmin(array(3));
     Access::setSingletonInstance($pseudoMockAccess);
     $idsites = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.com');
     $this->assertEquals(2, count($idsites));
     $pseudoMockAccess = new FakeAccess();
     FakeAccess::$superUser = false;
     FakeAccess::$identity = 'user3';
     FakeAccess::setIdSitesView(array(1, 2));
     FakeAccess::setIdSitesAdmin(array(3));
     Access::setSingletonInstance($pseudoMockAccess);
     $idsites = API::getInstance()->getSitesIdFromSiteUrl('http://piwik.com');
     $this->assertEquals(3, count($idsites));
     Access::setSingletonInstance($saveAccess);
 }
Exemple #16
0
 /**
  * Constructor.
  *
  * @param string $templateFile The template file to load. Must be in the following format:
  *                             `"@MyPlugin/templateFileName"`. Note the absence of .twig
  *                             from the end of the name.
  */
 public function __construct($templateFile)
 {
     $templateExt = '.twig';
     if (substr($templateFile, -strlen($templateExt)) !== $templateExt) {
         $templateFile .= $templateExt;
     }
     $this->template = $templateFile;
     $this->initializeTwig();
     $this->piwik_version = Version::VERSION;
     $this->userLogin = Piwik::getCurrentUserLogin();
     $this->isSuperUser = Access::getInstance()->hasSuperUserAccess();
     try {
         $this->piwikUrl = SettingsPiwik::getPiwikUrl();
     } catch (Exception $ex) {
         // pass (occurs when DB cannot be connected to, perhaps piwik URL cache should be stored in config file...)
     }
 }
Exemple #17
0
 /** Do cookie authentication. This way, the token can remain secret. */
 private function authenticate($idSite)
 {
     /**
      * Triggered immediately before the user is authenticated.
      *
      * This event can be used by plugins that provide their own authentication mechanism
      * to make that mechanism available. Subscribers should set the `'Piwik\Auth'` object in
      * the container to an object that implements the {@link Piwik\Auth} interface.
      *
      * **Example**
      *
      *     use Piwik\Container\StaticContainer;
      *
      *     public function initAuthenticationObject($activateCookieAuth)
      *     {
      *         StaticContainer::getContainer()->set('Piwik\Auth', new LDAPAuth($activateCookieAuth));
      *     }
      *
      * @param bool $activateCookieAuth Whether authentication based on `$_COOKIE` values should
      *                                        be allowed.
      */
     Piwik::postEvent('Request.initAuthenticationObject', array($activateCookieAuth = true));
     $auth = StaticContainer::get('Piwik\\Auth');
     $success = Access::getInstance()->reloadAccess($auth);
     if (!$success) {
         throw new Exception('Authentication failed');
     }
     Piwik::checkUserHasViewAccess($idSite);
 }
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     $tmpPath = StaticContainer::get('path.tmp');
     $directoriesToCheck = array($tmpPath, $tmpPath . '/assets/', $tmpPath . '/cache/', $tmpPath . '/logs/', $tmpPath . '/tcpdf/', $tmpPath . '/templates_c/');
     Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
     $this->handleMaintenanceMode();
     $this->handleProfiler();
     $this->handleSSLRedirection();
     Plugin\Manager::getInstance()->loadPluginTranslations();
     Plugin\Manager::getInstance()->loadActivatedPlugins();
     // try to connect to the database
     try {
         Db::createDatabaseObject();
         Db::fetchAll("SELECT DATABASE()");
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot connect to the database.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from creating and testing the database
          *                             connection.
          */
         Piwik::postEvent('Db.cannotConnectToDb', array($exception), $pending = true);
         throw $exception;
     }
     // try to get an option (to check if data can be queried)
     try {
         Option::get('TestingIfDatabaseConnectionWorked');
     } catch (Exception $exception) {
         if (self::shouldRethrowException()) {
             throw $exception;
         }
         Log::debug($exception);
         /**
          * Triggered when Piwik cannot access database data.
          *
          * This event can be used to start the installation process or to display a custom error
          * message.
          *
          * @param Exception $exception The exception thrown from trying to get an option value.
          */
         Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
         throw $exception;
     }
     // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
     Access::getInstance();
     /**
      * Triggered just after the platform is initialized and plugins are loaded.
      *
      * This event can be used to do early initialization.
      *
      * _Note: At this point the user is not authenticated yet._
      */
     Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
     $this->throwIfPiwikVersionIsOlderThanDBSchema();
     \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
     // ensure the current Piwik URL is known for later use
     if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
         SettingsPiwik::getPiwikUrl();
     }
     /**
      * Triggered before the user is authenticated, when the global authentication object
      * should be created.
      *
      * Plugins that provide their own authentication implementation should use this event
      * to set the global authentication object (which must derive from {@link Piwik\Auth}).
      *
      * **Example**
      *
      *     Piwik::addAction('Request.initAuthenticationObject', function() {
      *         StaticContainer::getContainer()->set('Piwik\Auth', new MyAuthImplementation());
      *     });
      */
     Piwik::postEvent('Request.initAuthenticationObject');
     try {
         $authAdapter = StaticContainer::get('Piwik\\Auth');
     } catch (Exception $e) {
         $message = "Authentication object cannot be found in the container. Maybe the Login plugin is not activated?\n                        <br />You can activate the plugin by adding:<br />\n                        <code>Plugins[] = Login</code><br />\n                        under the <code>[Plugins]</code> section in your config/config.ini.php";
         $ex = new AuthenticationFailedException($message);
         $ex->setIsHtmlMessage();
         throw $ex;
     }
     Access::getInstance()->reloadAccess($authAdapter);
     // Force the auth to use the token_auth if specified, so that embed dashboard
     // and all other non widgetized controller methods works fine
     if (Common::getRequestVar('token_auth', false, 'string') !== false) {
         Request::reloadAuthUsingTokenAuth();
     }
     SettingsServer::raiseMemoryLimitIfNecessary();
     \Piwik\Plugin\Manager::getInstance()->postLoadPlugins();
     /**
      * Triggered after the platform is initialized and after the user has been authenticated, but
      * before the platform has handled the request.
      *
      * Piwik uses this event to check for updates to Piwik.
      */
     Piwik::postEvent('Platform.initialized');
 }
Exemple #19
0
 /**
  * Sets up access instance.
  */
 public static function createAccessInstance()
 {
     Access::setSingletonInstance(null);
     Access::getInstance();
     Piwik::postEvent('Request.initAuthenticationObject');
 }
Exemple #20
0
 /**
  * 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->checkUserIsNotSuperUser($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();
     } 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->deleteUserAccess($userLogin, $idSites);
     // delete UserAccess
     $db = Db::get();
     // 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') {
         foreach ($idSites as $idsite) {
             $db->insert(Common::prefixTable("access"), array("idsite" => $idsite, "login" => $userLogin, "access" => $access));
         }
     }
     // we reload the access list which doesn't yet take in consideration this new user access
     Access::getInstance()->reloadAccess();
     Cache::deleteTrackerCache();
 }
Exemple #21
0
 private static function shouldReloadAuthUsingTokenAuth($request)
 {
     if (is_null($request)) {
         $request = self::getDefaultRequest();
     }
     if (!isset($request['token_auth'])) {
         // no token is given so we just keep the current loaded user
         return false;
     }
     // a token is specified, we need to reload auth in case it is different than the current one, even if it is empty
     $tokenAuth = Common::getRequestVar('token_auth', '', 'string', $request);
     // not using !== is on purpose as getTokenAuth() might return null whereas $tokenAuth is '' . In this case
     // we do not need to reload.
     return $tokenAuth != Access::getInstance()->getTokenAuth();
 }
 /**
  * Must be called before dispatch()
  * - checks that directories are writable,
  * - loads the configuration file,
  * - loads the plugin,
  * - inits the DB connection,
  * - etc.
  *
  * @throws Exception
  * @return void
  */
 public function init()
 {
     static $initialized = false;
     if ($initialized) {
         return;
     }
     $initialized = true;
     try {
         Registry::set('timer', new Timer());
         $directoriesToCheck = array('/tmp/', '/tmp/assets/', '/tmp/cache/', '/tmp/logs/', '/tmp/tcpdf/', '/tmp/templates_c/');
         Filechecks::dieIfDirectoriesNotWritable($directoriesToCheck);
         self::assignCliParametersToRequest();
         Translate::loadEnglishTranslation();
         $exceptionToThrow = self::createConfigObject();
         if (Session::isFileBasedSessions()) {
             Session::start();
         }
         $this->handleMaintenanceMode();
         $this->handleSSLRedirection();
         $this->handleProfiler();
         $pluginsManager = \Piwik\Plugin\Manager::getInstance();
         $pluginsToLoad = Config::getInstance()->Plugins['Plugins'];
         $pluginsManager->loadPlugins($pluginsToLoad);
         if ($exceptionToThrow) {
             throw $exceptionToThrow;
         }
         try {
             Db::createDatabaseObject();
             Option::get('TestingIfDatabaseConnectionWorked');
         } catch (Exception $exception) {
             if (self::shouldRethrowException()) {
                 throw $exception;
             }
             /**
              * Triggered if the INI config file has the incorrect format or if certain required configuration
              * options are absent.
              * 
              * This event can be used to start the installation process or to display a custom error message.
              * 
              * @param Exception $exception The exception thrown from creating and testing the database
              *                             connection.
              */
             Piwik::postEvent('Config.badConfigurationFile', array($exception), $pending = true);
             throw $exception;
         }
         // Init the Access object, so that eg. core/Updates/* can enforce Super User and use some APIs
         Access::getInstance();
         /**
          * Triggered just after the platform is initialized and plugins are loaded.
          * 
          * This event can be used to do early initialization.
          * 
          * _Note: At this point the user is not authenticated yet._
          */
         Piwik::postEvent('Request.dispatchCoreAndPluginUpdatesScreen');
         \Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
         // ensure the current Piwik URL is known for later use
         if (method_exists('Piwik\\SettingsPiwik', 'getPiwikUrl')) {
             $host = SettingsPiwik::getPiwikUrl();
         }
         /**
          * Triggered before the user is authenticated, when the global authentication object
          * should be created.
          * 
          * Plugins that provide their own authentication implementation should use this event
          * to set the global authentication object (which must derive from {@link Piwik\Auth}).
          * 
          * **Example**
          * 
          *     Piwik::addAction('Request.initAuthenticationObject', function() {
          *         Piwik\Registry::set('auth', new MyAuthImplementation());
          *     });
          */
         Piwik::postEvent('Request.initAuthenticationObject');
         try {
             $authAdapter = Registry::get('auth');
         } catch (Exception $e) {
             throw new Exception("Authentication object cannot be found in the Registry. Maybe the Login plugin is not activated?\n                                <br />You can activate the plugin by adding:<br />\n                                <code>Plugins[] = Login</code><br />\n                                under the <code>[Plugins]</code> section in your config/config.ini.php");
         }
         Access::getInstance()->reloadAccess($authAdapter);
         // Force the auth to use the token_auth if specified, so that embed dashboard
         // and all other non widgetized controller methods works fine
         if (($token_auth = Common::getRequestVar('token_auth', false, 'string')) !== false) {
             Request::reloadAuthUsingTokenAuth();
         }
         SettingsServer::raiseMemoryLimitIfNecessary();
         Translate::reloadLanguage();
         $pluginsManager->postLoadPlugins();
         /**
          * Triggered after the platform is initialized and after the user has been authenticated, but
          * before the platform has handled the request.
          * 
          * Piwik uses this event to check for updates to Piwik.
          */
         Piwik::postEvent('Updater.checkForUpdates');
     } catch (Exception $e) {
         if (self::shouldRethrowException()) {
             throw $e;
         }
         $debugTrace = $e->getTraceAsString();
         Piwik_ExitWithMessage($e->getMessage(), $debugTrace, true);
     }
 }
Exemple #23
0
 /**
  * Add a website.
  * Requires Super User access.
  *
  * The website is defined by a name and an array of URLs.
  * @param string $siteName Site name
  * @param array|string $urls The URLs array must contain at least one URL called the 'main_url' ;
  *                        if several URLs are provided in the array, they will be recorded
  *                        as Alias URLs for this website.
  * @param int $ecommerce Is Ecommerce Reporting enabled for this website?
  * @param null $siteSearch
  * @param string $searchKeywordParameters Comma separated list of search keyword parameter names
  * @param string $searchCategoryParameters Comma separated list of search category parameter names
  * @param string $excludedIps Comma separated list of IPs to exclude from the reports (allows wildcards)
  * @param null $excludedQueryParameters
  * @param string $timezone Timezone string, eg. 'Europe/London'
  * @param string $currency Currency, eg. 'EUR'
  * @param string $group Website group identifier
  * @param string $startDate Date at which the statistics for this website will start. Defaults to today's date in YYYY-MM-DD format
  * @param null|string $excludedUserAgents
  * @param int $keepURLFragments If 1, URL fragments will be kept when tracking. If 2, they
  *                              will be removed. If 0, the default global behavior will be used.
  * @see getKeepURLFragmentsGlobal.
  * @param string $type The website type, defaults to "website" if not set.
  *
  * @return int the website ID created
  */
 public function addSite($siteName, $urls, $ecommerce = null, $siteSearch = null, $searchKeywordParameters = null, $searchCategoryParameters = null, $excludedIps = null, $excludedQueryParameters = null, $timezone = null, $currency = null, $group = null, $startDate = null, $excludedUserAgents = null, $keepURLFragments = null, $type = null)
 {
     Piwik::checkUserHasSuperUserAccess();
     $this->checkName($siteName);
     $urls = $this->cleanParameterUrls($urls);
     $this->checkUrls($urls);
     $this->checkAtLeastOneUrl($urls);
     $siteSearch = $this->checkSiteSearch($siteSearch);
     list($searchKeywordParameters, $searchCategoryParameters) = $this->checkSiteSearchParameters($searchKeywordParameters, $searchCategoryParameters);
     $keepURLFragments = (int) $keepURLFragments;
     self::checkKeepURLFragmentsValue($keepURLFragments);
     $timezone = trim($timezone);
     if (empty($timezone)) {
         $timezone = $this->getDefaultTimezone();
     }
     $this->checkValidTimezone($timezone);
     if (empty($currency)) {
         $currency = $this->getDefaultCurrency();
     }
     $this->checkValidCurrency($currency);
     $db = Db::get();
     $url = $urls[0];
     $urls = array_slice($urls, 1);
     $bind = array('name' => $siteName, 'main_url' => $url);
     $bind['excluded_ips'] = $this->checkAndReturnExcludedIps($excludedIps);
     $bind['excluded_parameters'] = $this->checkAndReturnCommaSeparatedStringList($excludedQueryParameters);
     $bind['excluded_user_agents'] = $this->checkAndReturnCommaSeparatedStringList($excludedUserAgents);
     $bind['keep_url_fragment'] = $keepURLFragments;
     $bind['timezone'] = $timezone;
     $bind['currency'] = $currency;
     $bind['ecommerce'] = (int) $ecommerce;
     $bind['sitesearch'] = $siteSearch;
     $bind['sitesearch_keyword_parameters'] = $searchKeywordParameters;
     $bind['sitesearch_category_parameters'] = $searchCategoryParameters;
     $bind['ts_created'] = !is_null($startDate) ? Date::factory($startDate)->getDatetime() : Date::now()->getDatetime();
     $bind['type'] = $this->checkAndReturnType($type);
     if (!empty($group) && Piwik::hasUserSuperUserAccess()) {
         $bind['group'] = trim($group);
     } else {
         $bind['group'] = "";
     }
     $db->insert(Common::prefixTable("site"), $bind);
     $idSite = $db->lastInsertId();
     $this->insertSiteUrls($idSite, $urls);
     // we reload the access list which doesn't yet take in consideration this new website
     Access::getInstance()->reloadAccess();
     $this->postUpdateWebsite($idSite);
     /**
      * Triggered after a site has been added.
      *
      * @param int $idSite The ID of the site that was added.
      */
     Piwik::postEvent('SitesManager.addSite.end', array($idSite));
     return (int) $idSite;
 }
Exemple #24
0
 /**
  * Assigns a set of generally useful variables to a {@link Piwik\View} instance.
  * 
  * The following variables assigned:
  * 
  * **enableMeasurePiwikForSiteId** - The value of the `[Debug] enable_measure_piwik_usage_in_idsite`
  *                                     INI config option.
  * **isSuperUser** - True if the current user is the Super User, false if otherwise.
  * **hasSomeAdminAccess** - True if the current user has admin access to at least one site,
  *                          false if otherwise.
  * **isCustomLogo** - The value of the `branding_use_custom_logo` option.
  * **logoHeader** - The header logo URL to use.
  * **logoLarge** - The large logo URL to use.
  * **logoSVG** - The SVG logo URL to use.
  * **hasSVGLogo** - True if there is a SVG logo, false if otherwise.
  * **enableFrames** - The value of the `[General] enable_framed_pages` INI config option. If
  *                    true, {@link Piwik\View::setXFrameOptions()} is called on the view.
  * 
  * Also calls {@link setHostValidationVariablesView()}.
  *
  * @param View $view
  * @api
  */
 protected function setBasicVariablesView($view)
 {
     $view->clientSideConfig = PiwikConfig::getInstance()->getClientSideOptions();
     $view->enableMeasurePiwikForSiteId = PiwikConfig::getInstance()->Debug['enable_measure_piwik_usage_in_idsite'];
     $view->isSuperUser = Access::getInstance()->hasSuperUserAccess();
     $view->hasSomeAdminAccess = Piwik::isUserHasSomeAdminAccess();
     $view->hasSomeViewAccess = Piwik::isUserHasSomeViewAccess();
     $view->isUserIsAnonymous = Piwik::isUserIsAnonymous();
     $view->hasSuperUserAccess = Piwik::hasUserSuperUserAccess();
     $this->addCustomLogoInfo($view);
     $view->logoHeader = \Piwik\Plugins\API\API::getInstance()->getHeaderLogoUrl();
     $view->logoLarge = \Piwik\Plugins\API\API::getInstance()->getLogoUrl();
     $view->logoSVG = \Piwik\Plugins\API\API::getInstance()->getSVGLogoUrl();
     $view->hasSVGLogo = \Piwik\Plugins\API\API::getInstance()->hasSVGLogo();
     $view->superUserEmails = implode(',', Piwik::getAllSuperUserAccessEmailAddresses());
     $general = PiwikConfig::getInstance()->General;
     $view->enableFrames = $general['enable_framed_pages'] || isset($general['enable_framed_logins']) && $general['enable_framed_logins'];
     if (!$view->enableFrames) {
         $view->setXFrameOptions('sameorigin');
     }
     self::setHostValidationVariablesView($view);
 }
Exemple #25
0
 /**
  * Checks that the current user has view access to at least one site.
  *
  * @throws Exception if user doesn't have view access to any site.
  * @api
  */
 public static function checkUserHasSomeViewAccess()
 {
     Access::getInstance()->checkUserHasSomeViewAccess();
 }
Exemple #26
0
 public function testReloadAccessWithMockedAuthValid()
 {
     $mock = $this->getMock('\\Piwik\\Auth', array('authenticate', 'getName', 'initSession', 'setTokenAuth', 'setLogin'));
     $mock->expects($this->once())->method('authenticate')->will($this->returnValue(new AuthResult(AuthResult::SUCCESS, 'login', 'token')));
     $mock->expects($this->any())->method('getName')->will($this->returnValue("test name"));
     $access = Access::getInstance();
     $this->assertTrue($access->reloadAccess($mock));
     $this->assertFalse($access->hasSuperUserAccess());
 }
Exemple #27
0
 /**
  * Used to initialize core Piwik components on a piwik.php request
  * Eg. when cache is missed and we will be calling some APIs to generate cache
  */
 public static function initCorePiwikInTrackerMode()
 {
     if (SettingsServer::isTrackerApiRequest() && self::$initTrackerMode === false) {
         self::$initTrackerMode = true;
         require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
         Access::getInstance();
         Config::getInstance();
         try {
             Db::get();
         } catch (Exception $e) {
             Db::createDatabaseObject();
         }
         \Piwik\Plugin\Manager::getInstance()->loadCorePluginsDuringTracker();
     }
 }
Exemple #28
0
 /**
  * @dataProvider getGetPrettyValueTestCases
  */
 public function testGetPrettyValue($columnName, $value, $expected)
 {
     Translate::loadEnglishTranslation();
     $access = Access::getInstance();
     $access->setSuperUserAccess(true);
     $idsite = API::getInstance()->addSite("test", "http://test");
     $this->assertEquals($expected, MetricsFormatter::getPrettyValue($idsite, $columnName, $value, false, false));
     Translate::unloadEnglishTranslation();
 }
Exemple #29
0
 /**
  * @return array|bool
  */
 protected function updateComponents()
 {
     Access::getInstance();
     Piwik::setUserHasSuperUserAccess();
     $updater = new Updater();
     $componentsWithUpdateFile = CoreUpdater::getComponentUpdates($updater);
     if (empty($componentsWithUpdateFile)) {
         return false;
     }
     $result = CoreUpdater::updateComponents($updater, $componentsWithUpdateFile);
     return $result;
 }
Exemple #30
0
 /**
  * If the token_auth is found in the $request parameter,
  * the current session will be authenticated using this token_auth.
  * It will overwrite the previous Auth object.
  *
  * @param array $request If null, uses the default request ($_GET)
  * @return void
  * @ignore
  */
 public static function reloadAuthUsingTokenAuth($request = null)
 {
     // if a token_auth is specified in the API request, we load the right permissions
     $token_auth = Common::getRequestVar('token_auth', '', 'string', $request);
     if ($token_auth) {
         /**
          * Triggered when authenticating an API request, but only if the **token_auth**
          * query parameter is found in the request.
          *
          * Plugins that provide authentication capabilities should subscribe to this event
          * and make sure the global authentication object (the object returned by `Registry::get('auth')`)
          * is setup to use `$token_auth` when its `authenticate()` method is executed.
          *
          * @param string $token_auth The value of the **token_auth** query parameter.
          */
         Piwik::postEvent('API.Request.authenticate', array($token_auth));
         Access::getInstance()->reloadAccess();
         SettingsServer::raiseMemoryLimitIfNecessary();
     }
 }