diff --git a/lam/lib/config.inc b/lam/lib/config.inc index d0e87366..4fe7bdb9 100644 --- a/lam/lib/config.inc +++ b/lam/lib/config.inc @@ -688,7 +688,8 @@ class LAMConfig { * @throws LAMException import error */ public function importData($data) { - $settingsToIgnore = array('modules', 'types', 'tools', 'jobs'); + $settingsToIgnore = array('modules', 'types', 'tools', 'jobs', 'typeSettings', + 'moduleSettings', 'toolSettings', 'jobSettings', 'jobSQLite'); foreach ($data as $dataKey => $dataValue) { if (in_array($dataKey, $settingsToIgnore)) { continue; @@ -1850,7 +1851,7 @@ class LAMConfig { /** * Returns a list of active account types. * - * @return array list of types + * @return string[] list of types */ public function get_ActiveTypes() { if (($this->activeTypes == '') || !isset($this->activeTypes)) { @@ -1864,7 +1865,7 @@ class LAMConfig { /** * Sets the list of active types. * - * @param array list of types + * @param string[] list of types */ public function set_ActiveTypes($types) { $this->activeTypes = implode(",", $types); diff --git a/lam/lib/persistence.inc b/lam/lib/persistence.inc index 9acd66ab..e1a0f933 100644 --- a/lam/lib/persistence.inc +++ b/lam/lib/persistence.inc @@ -3,6 +3,9 @@ namespace LAM\PERSISTENCE; use LAMCfgMain; use LAMConfig; use LAMException; +use function LAM\PROFILES\getAccountProfiles; +use function LAM\PROFILES\loadAccountProfile; +use function LAM\PROFILES\saveAccountProfile; /* @@ -33,6 +36,7 @@ use LAMException; */ include_once __DIR__ . '/config.inc'; +include_once __DIR__ . '/profiles.inc'; /** * Exporter for LAM's configuration data. @@ -47,12 +51,16 @@ class ConfigDataExporter { $jsonData = array(); $jsonData['mainConfig'] = $this->_getMainConfigData($mainCfg); $jsonData['certificates'] = $this->_getCertificates($mainCfg); - $jsonData['serverProfiles'] = $this->_getServerProfiles(); + $serverProfileNames = getConfigProfiles(); + $serverProfiles = array(); + foreach ($serverProfileNames as $serverProfileName) { + $serverProfiles[$serverProfileName] = new \LAMConfig($serverProfileName); + } + $jsonData['serverProfiles'] = $this->_getServerProfiles($serverProfiles); + $jsonData['accountProfiles'] = $this->_getAccountProfiles($serverProfiles); /** * TODO * - * server profiles - * server profile job database * account profiles * PDF profiles * self service profiles @@ -93,18 +101,37 @@ class ConfigDataExporter { /** * Returns the content of the server profiles. * + * @param array $serverProfiles list of server profiles (name => object) * @return array $data */ - public function _getServerProfiles() { + public function _getServerProfiles($serverProfiles) { $data = array(); - $profileNames = getConfigProfiles(); - foreach ($profileNames as $profileName) { - $serverProfile = new LAMConfig($profileName); + foreach ($serverProfiles as $profileName => $serverProfile) { $data[$profileName] = $serverProfile->exportData(); } return $data; } + /** + * Returns the content of the account profiles. + * + * @param array $serverProfiles list of server profiles (name => object) + * @return array $data + */ + public function _getAccountProfiles($serverProfiles) { + $data = array(); + foreach ($serverProfiles as $profileName => $serverProfile) { + foreach ($serverProfile->get_ActiveTypes() as $typeId) { + $accountProfileNames = getAccountProfiles($typeId, $profileName); + foreach ($accountProfileNames as $accountProfileName) { + $accountProfile = loadAccountProfile($accountProfileName, $typeId, $profileName); + $data[$profileName][$typeId][$accountProfileName] = $accountProfile; + } + } + } + return $data; + } + } /** @@ -140,6 +167,13 @@ class ConfigDataImporter { } $steps[] = $mainStep; break; + case 'accountProfiles': + $mainStep = new ImporterStep(_('Account profiles'), 'accountProfiles', $value); + foreach ($value as $profileName => $profileData) { + $mainStep->addSubStep(new ImporterStep($profileName, 'accountProfile_' . $profileName, $profileData)); + } + $steps[] = $mainStep; + break; default: logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key); } @@ -172,6 +206,9 @@ class ConfigDataImporter { case 'serverProfiles': $this->importServerProfiles($step); break; + case 'accountProfiles': + $this->importAccountProfiles($step); + break; default: logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key); } @@ -227,6 +264,35 @@ class ConfigDataImporter { } } + /** + * Imports the account profiles. + * + * @param ImporterStep $step step + * @throws LAMException error during import + */ + private function importAccountProfiles($step) { + $failedProfiles = array(); + foreach ($step->getSubSteps() as $profileStep) { + if (!$profileStep->isActive()) { + continue; + } + $data = $profileStep->getValue(); + $serverProfileName = str_replace('accountProfile_', '', $profileStep->getKey()); + $serverProfile = new LAMConfig($serverProfileName); + foreach ($data as $typeId => $accountProfiles) { + foreach ($accountProfiles as $accountProfileName => $accountProfileData) { + $result = saveAccountProfile($accountProfileData, $accountProfileName, $typeId, $serverProfile); + if (!$result) { + $failedProfiles[] = $serverProfileName . ':' . $typeId . ':' . $accountProfileName; + } + } + } + } + if (!empty($failedProfiles)) { + throw new LAMException(_('Unable to save account profile.'), implode(', ', $failedProfiles)); + } + } + } /** diff --git a/lam/lib/profiles.inc b/lam/lib/profiles.inc index c6818793..6825843f 100644 --- a/lam/lib/profiles.inc +++ b/lam/lib/profiles.inc @@ -88,9 +88,8 @@ function profileExists($name, $typeId) { * @return array hash array (attribute => value) */ function loadAccountProfile($profile, $typeId, $serverProfileName) { - $typeManager = new \LAM\TYPES\TypeManager(); - $type = $typeManager->getConfiguredType($typeId); - if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId) || ($type == null)) { + if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId)) { + logNewMessage(LOG_NOTICE, "Invalid account profile name: $serverProfileName:$profile:$typeId"); return false; } $settings = array(); @@ -134,21 +133,22 @@ function loadAccountProfile($profile, $typeId, $serverProfileName) { * @param array $attributes hash array (attribute => value) * @param string $profile name of the account profile (without . extension) * @param string $typeId account type - * @param string $serverProfileName server profile name + * @param \LAMConfig $serverProfile server profile * @return boolean true, if saving succeeded */ -function saveAccountProfile($attributes, $profile, $typeId, $serverProfileName) { - if (!isLoggedIn()) return false; +function saveAccountProfile($attributes, $profile, $typeId, $serverProfile) { // check profile name and type id - $typeManager = new \LAM\TYPES\TypeManager(); + $typeManager = new \LAM\TYPES\TypeManager($serverProfile); $type = $typeManager->getConfiguredType($typeId); if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId) || ($type == null)) { + logNewMessage(LOG_NOTICE, 'Invalid account profile name', $profile . ':' . $typeId); return false; } if (!is_array($attributes)) { + logNewMessage(LOG_NOTICE, 'Invalid account profile data'); return false; } - $path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $serverProfileName . '/' . $profile . "." . $typeId; + $path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $serverProfile->getName() . '/' . $profile . "." . $typeId; $file = @fopen($path, "w"); if ($file) { // write attributes @@ -166,6 +166,7 @@ function saveAccountProfile($attributes, $profile, $typeId, $serverProfileName) fclose($file); } else { + logNewMessage(LOG_NOTICE, 'Unable to open account profile file: ' . $path); return false; } return true; diff --git a/lam/templates/config/confImportExport.php b/lam/templates/config/confImportExport.php index 7a6f214b..7e434559 100644 --- a/lam/templates/config/confImportExport.php +++ b/lam/templates/config/confImportExport.php @@ -211,7 +211,7 @@ printHeaderContents(_("Import and export configuration"), '../..'); $validUpload = true; } catch (LAMException $e) { - $content->add(new htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage()), 12); + $content->add(new htmlStatusMessage('ERROR', htmlspecialchars($e->getTitle()), htmlspecialchars($e->getMessage())), 12); } } if (!isset($_POST['importConfigConfirm']) && !$validUpload) { @@ -260,7 +260,7 @@ printHeaderContents(_("Import and export configuration"), '../..'); $content->add(new htmlStatusMessage('INFO', _('Configuration import ended successful.')), 12); } catch (LAMException $e) { - $content->add(new htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage()), 12); + $content->add(new htmlStatusMessage('ERROR', htmlspecialchars($e->getTitle()), htmlspecialchars($e->getMessage())), 12); $content->add(new htmlButton('importCancel', _('Back')), 12); } } diff --git a/lam/templates/profedit/profilepage.php b/lam/templates/profedit/profilepage.php index aac4f8a2..7de209c6 100644 --- a/lam/templates/profedit/profilepage.php +++ b/lam/templates/profedit/profilepage.php @@ -127,7 +127,7 @@ if (isset($_POST['save'])) { $errors = checkProfileOptions($_POST['accounttype'], $options); if (sizeof($errors) == 0) { // input data is valid, save profile // save profile - if (\LAM\PROFILES\saveAccountProfile($options, $_POST['profname'], $_POST['accounttype'], $_SESSION['config']->getName())) { + if (\LAM\PROFILES\saveAccountProfile($options, $_POST['profname'], $_POST['accounttype'], $_SESSION['config'])) { metaRefresh('profilemain.php?savedSuccessfully=' . $_POST['profname']); exit(); } diff --git a/lam/tests/lib/persistenceTest.php b/lam/tests/lib/persistenceTest.php index a39b81ba..27a5d37a 100644 --- a/lam/tests/lib/persistenceTest.php +++ b/lam/tests/lib/persistenceTest.php @@ -41,18 +41,28 @@ class ConfigDataExporterTest extends TestCase { 'profile1' => array('ServerURL' => 'myserver'), 'profile2' => array('ServerURL' => 'myserver2'), ); + $accountProfileData = array( + 'profile1' => array('user' => array('default' => array('key' => 'value'))), + 'profile1' => array( + 'user' => array('default' => array('key' => 'value')), + 'group' => array('default' => array('key' => 'value')), + ), + ); $expectedJson = json_encode(array( 'mainConfig' => $mainData, 'certificates' => 'certs', 'serverProfiles' => $profileData, + 'accountProfiles' => $accountProfileData, )); $exporter = $this->getMockBuilder('\LAM\PERSISTENCE\ConfigDataExporter') - ->setMethods(array('_getMainConfigData', '_getCertificates', '_getServerProfiles')) + ->setMethods(array('_getMainConfigData', '_getCertificates', '_getServerProfiles', + '_getAccountProfiles')) ->getMock(); $exporter->method('_getMainConfigData')->willReturn($mainData); $exporter->method('_getCertificates')->willReturn('certs'); $exporter->method('_getServerProfiles')->willReturn($profileData); + $exporter->method('_getAccountProfiles')->willReturn($accountProfileData); $json = $exporter->exportAsJson();