new config file structuring

This commit is contained in:
Roland Gruber 2012-10-28 14:37:54 +00:00
parent 943ba02334
commit c680ecceed
49 changed files with 897 additions and 51 deletions

View File

@ -1,4 +1,5 @@
December 2012
- account profiles and PDF structures are now bound to server profile
- IMAP: support "/" as path separator (RFE 3575692)

View File

@ -0,0 +1,6 @@
<pdf type="alias" filename="printLogo.jpg" headline="Alias information">
<section name="_uidObject_uid">
<entry name="aliasEntry_entry" />
<entry name="main_dn" />
</section>
</pdf>

View File

@ -0,0 +1,6 @@
<pdf type="automountType" filename="printLogo.jpg" headline="Automount information">
<section name="_automount_cn">
<entry name="automount_description" />
<entry name="automount_automountInformation" />
</section>
</pdf>

View File

@ -0,0 +1,8 @@
<pdf type="gon" headline="Group information">
<section name="_groupOfNames_name">
<entry name="main_dn" />
<entry name="groupOfNames_description" />
<entry name="groupOfNames_owner" />
<entry name="groupOfNames_members" />
</section>
</pdf>

View File

@ -0,0 +1,7 @@
<pdf type="nisObjectType" filename="printLogo.jpg" headline="LDAP Account Manager">
<section name="_nisObject_cn">
<entry name="nisObject_nisMapName" />
<entry name="nisObject_nisMapEntry" />
<entry name="nisObject_description" />
</section>
</pdf>

View File

@ -0,0 +1,18 @@
<pdf type="ppolicyType" filename="printLogo.jpg" headline="LDAP Account Manager">
<section name="_ppolicy_cn">
<entry name="ppolicy_pwdMinAge" />
<entry name="ppolicy_pwdMaxAge" />
<entry name="ppolicy_pwdExpireWarning" />
<entry name="ppolicy_pwdGraceAuthnLimit" />
<entry name="ppolicy_pwdInHistory" />
<entry name="ppolicy_pwdCheckQuality" />
<entry name="ppolicy_pwdMinLength" />
<entry name="ppolicy_pwdLockout" />
<entry name="ppolicy_pwdLockoutDuration" />
<entry name="ppolicy_pwdMaxFailure" />
<entry name="ppolicy_pwdFailureCountInterval" />
<entry name="ppolicy_pwdMustChange" />
<entry name="ppolicy_pwdAllowUserChange" />
<entry name="ppolicy_pwdSafeModify" />
</section>
</pdf>

View File

@ -0,0 +1,11 @@
<pdf type="sudo" filename="printLogo.jpg" headline="Sudo role">
<section name="_sudoRole_cn">
<entry name="sudoRole_sudoUser" />
<entry name="sudoRole_sudoHost" />
<entry name="sudoRole_sudoCommand" />
<entry name="sudoRole_sudoRunAsUser" />
<entry name="sudoRole_sudoRunAsGroup" />
<entry name="sudoRole_sudoOption" />
<entry name="sudoRole_description" />
</section>
</pdf>

View File

@ -0,0 +1,8 @@
<pdf type="zarafaAddressListType" filename="printLogo.jpg" headline="LDAP Account Manager">
<section name="_zarafaAddressList_cn">
<entry name="zarafaAddressList_zarafaBase" />
<entry name="zarafaAddressList_zarafaFilter" />
<entry name="zarafaAddressList_zarafaAccount" />
<entry name="zarafaAddressList_zarafaHidden" />
</section>
</pdf>

View File

@ -0,0 +1,10 @@
<pdf type="zarafaDynamicGroupType" filename="printLogo.jpg" headline="LDAP Account Manager">
<section name="_zarafaDynamicGroup_cn">
<entry name="zarafaDynamicGroup_mail" />
<entry name="zarafaDynamicGroup_zarafaAliases" />
<entry name="zarafaDynamicGroup_zarafaBase" />
<entry name="zarafaDynamicGroup_zarafaFilter" />
<entry name="zarafaDynamicGroup_zarafaAccount" />
<entry name="zarafaDynamicGroup_zarafaHidden" />
</section>
</pdf>

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -160,7 +160,7 @@ $helpArray = array (
"362" => array ("Headline" => _("Import profiles"),
"Text" => _("Here you can import account profiles from other server profiles (overwrite existing).")),
"363" => array ("Headline" => _("Export profiles"),
"Text" => _("Here you can export account profiles to other server profiles (overwrite existing).")),
"Text" => _("Here you can export account profiles to other server profiles (overwrite existing). You may also export a profile to the global templates. In this case it will always be copied to all server profiles that do not yet have a profile with this name.")),
// 400 - 499
// account pages
"401" => array ("Headline" => _("Load profile"),
@ -178,7 +178,7 @@ $helpArray = array (
"408" => array ("Headline" => _("Import PDF structures"),
"Text" => _("Here you can import PDF structures from other server profiles (overwrite existing).")),
"409" => array ("Headline" => _("Export PDF structures"),
"Text" => _("Here you can export PDF structures to other server profiles (overwrite existing).")),
"Text" => _("Here you can export PDF structures to other server profiles (overwrite existing). You may also export a structure to the global templates. In this case it will always be copied to all server profiles that do not yet have a structure with this name.")),
// 500 - 599
// LAM Pro
"501" => array ("Headline" => _("LDAP suffix"),

View File

@ -116,6 +116,45 @@ function getConfigProfiles() {
return $ret;
}
/**
* Deletes the given server profile.
*
* @param String $name profile name
* @return String null if success or error message if failed
*/
function deleteConfigProfile($name) {
if (!preg_match("/^[a-z0-9_-]+$/i", $name)) {
return _("Unable to delete profile!");
}
$dir = substr(__FILE__, 0, strlen(__FILE__) - 15) . "/config/";
// delete account profiles and PDF structures
$subDirs = array($dir . 'pdf/' . $name . '/logos', $dir . 'pdf/' . $name, $dir . 'profiles/' . $name);
for ($i = 0; $i < sizeof($subDirs); $i++) {
if (is_dir($subDirs[$i])) {
$dirHandle = @opendir($subDirs[$i]);
while (false !== ($path = readdir($dirHandle))) {
if ($path != '.' && $path != '..') {
if (!@unlink($subDirs[$i] . '/' . $path)) {
logNewMessage(LOG_ERR, 'Unable to delete ' . $subDirs[$i] . '/' . $path);
return _("Unable to delete profile!");
}
}
}
@closedir($dirHandle);
if (!@rmdir($subDirs[$i])) {
logNewMessage(LOG_ERR, 'Unable to delete ' . $subDirs[$i]);
return _("Unable to delete profile!");
}
}
}
// delete config file
$confFile = $dir . $_POST['delfilename'] . ".conf";
if (!@unlink($confFile)) {
logNewMessage(LOG_ERR, 'Unable to delete ' . $confFile);
return _("Unable to delete profile!");
}
}
/**
* Returns the version number of this LAM installation.
* Format: <major version>.<minor version>.<patch level>

View File

@ -947,7 +947,7 @@ class htmlSelect extends htmlElement {
$name = ' name="' . $this->name . '" id="' . $this->name . '"';
if ($this->multiSelect) {
$multi = ' multiple';
$name = ' name="' . $this->name . '[]"';
$name = ' name="' . $this->name . '[]" id="' . $this->name . '"';
}
$size = ' size="' . $this->size . '"';
$class = '';
@ -2514,9 +2514,45 @@ class htmlDiv extends htmlElement {
echo '</div>';
return $return;
}
}
/**
* Creates a JavaScript element.
*
* @package metaHTML
*/
class htmlJavaScript extends htmlElement {
/** htmlElement that generates inner content */
private $content = null;
/**
* Constructor.
*
* @param String $content script
*/
function __construct($content) {
$this->content = $content;
}
/**
* Prints the HTML code for this element.
*
* @param string $module Name of account module
* @param array $input List of meta-HTML elements
* @param array $values List of values which override the defaults in $input (name => value)
* @param boolean $restricted If true then no buttons will be displayed
* @param integer $tabindex Start value of tabulator index for input fields
* @param string $scope Account type
* @return array List of input field names and their type (name => type)
*/
function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) {
$return = array();
echo '<script type="text/javascript">';
echo $this->content;
echo '</script>';
return $return;
}
}

View File

@ -86,13 +86,13 @@ class lamPDF extends UFPDF {
$this->setMargins('10.0','10.0','10.0');
$this->setAutoPageBreak(true,'20.0');
}
/**
* Creates the PDF page header.
*/
function header() {
if($this->page_definitions['filename'] != 'none') {
$imageFile = substr(__FILE__,0,strlen(__FILE__)- 14) . "config/pdf/logos/" . $this->page_definitions['filename'];
$imageFile = substr(__FILE__,0,strlen(__FILE__)- 14) . "config/pdf/" . $_SESSION['config']->getName() . "/logos/" . $this->page_definitions['filename'];
$imgProperties = getimagesize($imageFile);
$this->Image($imageFile,10,15,($imgProperties[0] / $this->k) / 5, ($imgProperties[1] / $this->k) / 5,0,"JPG");
}

View File

@ -37,22 +37,27 @@ include_once("ldap.inc");
/**
* This function will return all available PDF structure definitions for the submitted
* account scope.
*
*
* @param string $scope The account scope the PDF structure definitions should be
* returned.
*
* @param string $profile server profile name
*
* @return array $scope All available PDF structure definitions for the submitted account
* scope. Each entry is a string being the filename that may be passed to the
* scope. Each entry is a string being the filename that may be passed to the
* createModulePDF() function as second argument.
*/
function getPDFStructureDefinitions($scope = "user") {
function getPDFStructureDefinitions($scope = "user", $profile = null) {
$return = array();
$path = dirname(__FILE__) . '/../config/pdf/';
if (!isset($profile)) {
$profile = $_SESSION['config']->getName();
}
$path = dirname(__FILE__) . '/../config/pdf/' . $profile;
if(is_dir($path)) {
$dirHandle = opendir($path);
while($file = readdir($dirHandle)) {
$struct_file = explode('.',$file);
if(!is_dir($path.$file) && ($file != '.') && ($file != '..') && ($struct_file[1] == $scope) && ($struct_file[2] == 'xml')) {
if(!is_dir($path.$file) && ($file != '.') && ($file != '..') && (sizeof($struct_file) == 3) && ($struct_file[1] == $scope) && ($struct_file[2] == 'xml')) {
array_push($return, $struct_file[0]);
}
}
@ -67,12 +72,12 @@ function getPDFStructureDefinitions($scope = "user") {
*
* @param string $scope The account scope for wich the PDF structure should be returned.
* @param string $pdf_structure Structure name of selected scope wich should be returned.
*
*
* @return array PDF structure
*/
function loadPDFStructureDefinitions($scope='user',$pdf_structure='default') {
$parser = new xmlParser();
$file = dirname(__FILE__) . '/../config/pdf/' . $pdf_structure . '.' . $scope . '.xml';
$file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $pdf_structure . '.' . $scope . '.xml';
$xml = $parser->parse($file);
$border = array();
$structure = array();
@ -101,8 +106,8 @@ function loadPDFStructureDefinitions($scope='user',$pdf_structure='default') {
function savePDFStructureDefinitions($scope,$definition) {
if (!preg_match('/[a-zA-Z0-9\-\_]+/',$definition)) return 'no perms';
if (!preg_match('/[a-zA-Z]+/',$scope)) return 'no perms';
$struct_file = dirname(__FILE__) . '/../config/pdf/' . $definition . '.' . $scope . '.xml';
if(!is_writable(dirname(__FILE__) . '/../config/pdf/')) {
$struct_file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $definition . '.' . $scope . '.xml';
if(!is_writable(dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName())) {
return 'no perms';
}
else {
@ -150,33 +155,33 @@ function savePDFStructureDefinitions($scope,$definition) {
/**
* Deletes XML file with PDF structure definitions.
*
*
* @param string $scope account type
* @param string $definition Name of definition to delete
*
*
* @return boolean True if file was deleted or false if a problem occured.
*/
function deletePDFStructureDefinition($scope, $definition) {
if (!preg_match('/[a-zA-Z0-9\-\_]+/',$definition)) return false;
if (!preg_match('/[a-zA-Z]+/',$scope)) return false;
$file = dirname(__FILE__) . '/../config/pdf/' . $definition . '.' . $scope . '.xml';
$file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $definition . '.' . $scope . '.xml';
if(is_file($file) && is_writable($file)) {
return unlink($file);
}
else {
return false;
}
}
/**
* This function returns an array with all aviliable logo images.
*
*
* @return array list of logo files
*/
function getAvailableLogos() {
$return = array();
$dirPath = dirname(__FILE__) . '/../config/pdf/logos/';
$dirPath = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/logos/';
$dirHandle = opendir($dirPath);
while($file = readdir($dirHandle)) {
if(!is_dir($file) && $file != '.' && $file != '..' && preg_match('/\\.(jpg|png)$/',$file)) {
@ -189,4 +194,47 @@ function getAvailableLogos() {
sort($return);
return $return;
}
?>
/**
* Copies PDF profiles to other server profiles.
*
* @param array $pdfProfiles PDF profile names
* @param String $scope account scope
* @param array $dests destinations
*
* @return boolean operation succeeded
*/
function copyPdfProfiles($pdfProfiles, $scope, $dests = array()) {
$state = true;
$profilePath = substr(__FILE__, 0, strlen(__FILE__) - 17) . 'config/pdf/';
foreach ($pdfProfiles as $profile) {
//part 1: server profile
//part 2: account profile
$tmpArr = explode('##', $profile);
$src = $profilePath . $tmpArr[0] . '/' . $tmpArr[1] . '.' . $scope . '.xml';
if (!empty($dests)) {
foreach ($dests as $dest) {
if ($dest == 'templates*') {
$dst = substr(__FILE__, 0, strlen(__FILE__) - 17) . 'config/templates/pdf/' . $tmpArr[1] . '.' . $scope . '.xml';
} else {
$dst = $profilePath . $dest . '/' . $tmpArr[1] . '.' . $scope . '.xml';
}
if (!@copy($src, $dst)) {
StatusMessage('ERROR', _('Failed to export!'), $tmpArr[1] . '.' . $scope . '.xml');
$state = false;
}
}
} else {
$dst = $profilePath . $_SESSION['config']->getName() . '/' . $tmpArr[1] . '.' . $scope . '.xml';
if (!@copy($src, $dst)) {
StatusMessage('ERROR', _('Failed to import!'), $tmpArr[1] . '.' . $scope . '.xml');
$state = false;
}
}
}
return $state;
}
?>

View File

@ -33,10 +33,16 @@ $Id$
* Returns an array of string with all available profiles for the given account type
*
* @param string $scope account type
* @param string $profile server profile name
* @return array profile names
*/
function getAccountProfiles($scope) {
$dir = @dir(substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles");
function getAccountProfiles($scope, $profile = null) {
if (!isset($profile)) {
$profile = $_SESSION['config']->getName();
}
$dir = @dir(substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $profile);
$ret = array();
$pos = 0;
if ($dir) {
@ -56,6 +62,7 @@ function getAccountProfiles($scope) {
return $ret;
}
/**
* Loads an profile of the given account type
*
@ -66,7 +73,7 @@ function getAccountProfiles($scope) {
function loadAccountProfile($profile, $scope) {
if (!preg_match("/^[0-9a-z _-]+$/i", $profile) || !preg_match("/^[a-z]+$/i", $scope)) return false;
$settings = array();
$file = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $profile . "." . $scope;
$file = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $_SESSION['config']->getName() . '/' . $profile . "." . $scope;
if (is_file($file) == True) {
$file = @fopen($file, "r");
if ($file) {
@ -114,7 +121,7 @@ function saveAccountProfile($attributes, $profile, $scope) {
if (!is_array($attributes)) {
return false;
}
$path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $profile . "." . $scope;
$path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $_SESSION['config']->getName() . '/' . $profile . "." . $scope;
$file = @fopen($path, "w");
if ($file) {
// write attributes
@ -147,7 +154,7 @@ function saveAccountProfile($attributes, $profile, $scope) {
function delAccountProfile($file, $scope) {
if (!$_SESSION['loggedIn'] == true) return false;
if (!preg_match("/^[0-9a-z _-]+$/i", $file) || !preg_match("/^[a-z]+$/i", $scope)) return false;
$prof = substr(__FILE__, 0, strlen(__FILE__) - 16) . "config/profiles/" . $file . "." . $scope;
$prof = substr(__FILE__, 0, strlen(__FILE__) - 16) . "config/profiles/". $_SESSION['config']->getName() . '/' . $file . "." . $scope;
if (is_file($prof)) {
return @unlink($prof);
}
@ -155,4 +162,45 @@ function delAccountProfile($file, $scope) {
}
/**
* Copies account profiles to other server profiles.
*
* @param array $accountProfiles account profile names
* @param String $scope account scope
* @param array $dests destinations
*
* @return boolean operation succeeded
*/
function copyAccountProfiles($accountProfiles, $scope, $dests = array()) {
$state = true;
$profilePath = substr(__FILE__, 0, strlen(__FILE__) - 17) . '/config/profiles/';
foreach ($accountProfiles as $profile) {
//part 1: server profile
//part 2: account profile
$tmpArr = explode('##', $profile);
$src = $profilePath . $tmpArr[0] . '/' . $tmpArr[1] . '.' . $scope;
if (!empty($dests)) {
foreach ($dests as $dest) {
if ($dest == 'templates*') {
$dst = substr(__FILE__, 0, strlen(__FILE__) - 17) . '/config/templates/profiles/' . $tmpArr[1] . '.' . $scope;
} else {
$dst = $profilePath . $dest . '/' . $tmpArr[1] . '.' . $scope;
}
if (!@copy($src, $dst)) {
StatusMessage('ERROR', _('Failed to export!'), $tmpArr[1] . '.' . $scope);
$state = false;
}
}
} else {
$dst = $profilePath . $_SESSION['config']->getName() . '/' . $tmpArr[1] . '.' . $scope;
if (!@copy($src, $dst)) {
StatusMessage('ERROR', _('Failed to import!'), $tmpArr[1] . '.' . $scope);
$state = false;
}
}
}
return $state;
}
?>

227
lam/lib/upgrade.inc Normal file
View File

@ -0,0 +1,227 @@
<?php
/*
$Id:
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2012 Christian Kropp
2012 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to upgrade the pdf/profiles configuration files.
*
* @package main
* @author Christian Kropp
* @author Roland Gruber
*/
/**
* check the write/read permission for the upgrade
*
* @return array - permission messages
*/
function testPermissions() {
$result = array();
if (!is_writable('../config')) {
$result[] = htmlspecialchars(realpath('../config'));
}
$result = array_merge($result, testPermissionRecursive('../config/profiles/'));
$result = array_merge($result, testPermissionRecursive('../config/pdf/'));
return $result;
}
/**
* Recursively checks the permissions in a directory.
*
* @param String $dir directory
* @return array list of files/directories with wrong permission
*/
function testPermissionRecursive($dir) {
$result = array();
if (!is_writable($dir)) {
$result[] = htmlspecialchars(realpath($dir));
}
$dirHandle = @opendir($dir);
if ($dirHandle != null) {
$file = @readdir($dirHandle);
while ($file !== false) {
if (($file != '.') && ($file != '..')) {
if (is_dir($dir . '/' . $file)) {
$result = array_merge($result, testPermissionRecursive($dir . '/' . $file));
}
elseif (!is_writable($dir . '/' . $file)) {
$result[] = htmlspecialchars(realpath($dir . '/' . $file));
}
}
$file = @readdir($dirHandle);
}
}
@closedir($dirHandle);
return $result;
}
/**
* Checks if the given directory contains files.
* This is used to check if config files need to be migrated.
*
* @param String $dir directory path
*/
function containsFiles($dir) {
$return = false;
$dirHandle = @opendir($dir);
if ($dirHandle != null) {
$file = @readdir($dirHandle);
while ($file !== false) {
if (is_file($dir . '/' . $file)) {
$return = true;
break;
}
$file = @readdir($dirHandle);
}
}
@closedir($dirHandle);
return $return;
}
/**
* Saves an hash array (attribute => value) to an account profile
*
* @param array $profiles server profiles
*/
function upgradeConfigToServerProfileFolders($profiles) {
if (!is_writable('../config')) {
StatusMessage('ERROR', 'Upgrade failed.', 'The directory \'/config\' has missing write permissions.');
return;
}
// copy default configs
if (!file_exists('../config/templates')) {
@mkdir('../config/templates');
recursiveCopy('../config/pdf/', '../config/templates/pdf/', $profiles, 'default.');
recursiveCopy('../config/profiles/', '../config/templates/profiles/', $profiles, 'default.');
}
foreach ($profiles as $profile) {
// upgrade PDF configs
$dir = '../config/pdf/' . $profile;
if (!file_exists($dir)) {
recursiveCopy('../config/pdf/', $dir, $profiles);
}
// upgrade profiles configs
$dir = '../config/profiles/' . $profile;
if (!file_exists($dir)) {
recursiveCopy('../config/profiles/', $dir, $profiles);
}
}
// delete old files
recursiveDelete('../config/pdf', $profiles);
recursiveDelete('../config/profiles', $profiles);
}
/**
* Saves an hash array (attribute => value) to an account profile
*
* @param array $profiles server profiles
*/
function copyConfigTemplates($profiles) {
foreach ($profiles as $profile) {
// copy templates but do not override existing files
recursiveCopy('../config/templates/pdf/', '../config/pdf/' . $profile, $profiles, null, false);
recursiveCopy('../config/templates/profiles/', '../config/profiles/' . $profile, $profiles, null, false);
}
}
/**
* Copy a file or recursively copy a directory
*
* @param string $src - source path to file or directory
* @param string $dst - destination path to file or directory
* @param array $profiles - server profiles (used to avoid copying of newly created folders)
* @param string $fileFilter copy only files that start with the given filter
* @param boolean $overwrite overwrite existing files
*/
function recursiveCopy($src, $dst, $profiles, $fileFilter = null, $overwrite = true) {
$dir = @opendir($src);
if (!file_exists($dst)) {
$tmpState = @mkdir($dst);
if ($tmpState === false) {
StatusMessage('ERROR', 'Upgrade failed.', 'The directory \'' . $dst . '\' could not be created.');
}
}
while (false !== ($file = readdir($dir))) {
if ($file != '.' && $file != '..' && !in_array($file, $profiles)) {
if (is_dir($src . '/' . $file) && ($file == 'logos')) {
recursiveCopy($src . '/' . $file, $dst . '/' . $file, $profiles, $fileFilter, $overwrite);
}
elseif ((isset($fileFilter) && (strpos($file, $fileFilter) === 0 || $file == '.htaccess'))
|| (!isset($fileFilter)))
{
if ($overwrite || !file_exists($dst . '/' . $file)) {
$tmpState = @copy($src . '/' . $file, $dst . '/' . $file);
if ($tmpState === false) {
StatusMessage('ERROR', 'Upgrade failed.', 'The file ' . $file . ' could not be copied.');
}
}
}
}
}
closedir($dir);
}
/**
* Delete a file or recursively delete a directory
*
* @param string $src - path to file or directory
* @param array $profiles - server profiles (used to avoid copying of newly created folders)
*/
function recursiveDelete($src, $profiles) {
if (is_file($src)) {
$tmpState = @unlink($src);
if ($tmpState === false) {
StatusMessage('ERROR', 'Upgrade failed.', 'The file ' . $src . ' could not be deleted.');
}
return;
} else if (is_dir($src) && is_writable($src)) {
$dir = @opendir($src);
while (false !== ($path = readdir($dir))) {
if ($path != '.' && $path != '..' && !in_array($path, $profiles)) {
recursiveDelete($src . '/' . $path, $profiles);
}
}
@closedir($dir);
if ($src != '../config/pdf' && $src != '../config/profiles') {
$tmpState = @rmdir($src);
if ($tmpState === false) {
StatusMessage('ERROR', 'Upgrade failed.', 'The directory ' . $src . ' could not be deleted.');
}
}
return;
} else {
StatusMessage('ERROR', 'Upgrade failed.', 'The directory ' . $src . ' has missing write permissions.');
return;
}
}
?>

View File

@ -89,6 +89,10 @@ if (isset($_POST['action'])) {
elseif ($_POST['action'] == "rename") {
if (preg_match("/^[a-z0-9_-]+$/i", $_POST['oldfilename']) && preg_match("/^[a-z0-9_-]+$/i", $_POST['renfilename']) && !in_array($_POST['renfilename'], getConfigProfiles())) {
if (rename("../../config/" . $_POST['oldfilename'] . ".conf", "../../config/" . $_POST['renfilename'] . ".conf")) {
// rename pdf and profiles folder
rename("../../config/profiles/" . $_POST['oldfilename'], "../../config/profiles/" . $_POST['renfilename']);
rename("../../config/pdf/" . $_POST['oldfilename'], "../../config/pdf/" . $_POST['renfilename']);
$msg = _("Renamed profile.");
}
else $error = _("Could not rename file!");
@ -102,7 +106,7 @@ if (isset($_POST['action'])) {
}
// delete profile
elseif ($_POST['action'] == "delete") {
if (preg_match("/^[a-z0-9_-]+$/i", $_POST['delfilename']) && @unlink("../../config/" . $_POST['delfilename'] . ".conf")) {
if (deleteConfigProfile($_POST['delfilename']) == null) {
$msg = _("Profile deleted.");
}
else $error = _("Unable to delete profile!");

View File

@ -320,3 +320,70 @@ function showConfirmationDialog(title, okText, cancelText, dialogDiv, formName,
jQuery('#' + dialogDiv).parent().appendTo(document.forms[formName]);
}
/**
* Alines the elements with the given IDs to the same width.
*
* @param elementIDs IDs
*/
function equalWidth(elementIDs) {
var maxWidth = 0;
for (var i = 0; i < elementIDs.length; ++i) {
if (jQuery(elementIDs[i]).width() > maxWidth) {
maxWidth = jQuery(elementIDs[i]).width();
};
}
for (var i = 0; i < elementIDs.length; ++i) {
jQuery(elementIDs[i]).css({'width': maxWidth - (jQuery(elementIDs[i]).outerWidth() - jQuery(elementIDs[i]).width())});
}
}
/**
* Shows the dialog to change the list settings.
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
* @param scope account type
* @param selectFieldName name of select box with profile name
* @param serverProfile profile name
*/
function showDistributionDialog(title, okText, cancelText, scope, type, selectFieldName, serverProfile) {
// show dialog
var buttonList = {};
var dialogId = '';
buttonList[cancelText] = function() { jQuery(this).dialog("close"); };
if (type == 'export') {
// show structure name to export
jQuery('#exportName').text(jQuery('[name=' + selectFieldName + ']').val());
dialogId = 'exportDialog';
buttonList[okText] = function() { document.forms["exportDialogForm"].submit(); };
jQuery('<input>').attr({
type: 'hidden',
name: 'exportProfiles[]',
value: serverProfile + '##' + jQuery('[name=' + selectFieldName + ']').val()
}).appendTo('form');
jQuery('<input>').attr({
type: 'hidden',
name: 'scope',
value: scope
}).appendTo('form');
} else if (type == 'import') {
dialogId = 'importDialog_' + scope;
buttonList[okText] = function() { document.forms["importDialogForm_" + scope].submit(); };
}
jQuery('#' + dialogId).dialog({
modal: true,
title: title,
dialogClass: 'defaultBackground',
buttons: buttonList,
width: 'auto'
});
if (type == 'export') {
equalWidth(new Array('#passwd', '#destServerProfiles'));
} else if (type == 'import') {
equalWidth(new Array('#passwd_' + scope, '#importProfiles_' + scope));
}
}

View File

@ -43,6 +43,9 @@ include_once("../lib/selfService.inc");
/** access to configuration options */
include_once("../lib/config.inc"); // Include config.inc which provides Config class
/** Upgrade functions */
include_once("../lib/upgrade.inc");
// set session save path
if (strtolower(session_module_name()) == 'files') {
session_save_path(dirname(__FILE__) . '/../sess');
@ -176,6 +179,20 @@ function display_LoginPage($config_object) {
echo "<script type=\"text/javascript\" src=\"lib/" . $jsEntry . "\"></script>\n";
}
// upgrade if pdf/profiles contain single files
if (containsFiles('../config/profiles') || containsFiles('../config/pdf')) {
echo 'bla';
$result = testPermissions();
if (sizeof($result) > 0) {
StatusMessage('ERROR', 'Unable to migrate configuration files. Please allow write access to these paths:', implode('<br>', $result));
}
else {
upgradeConfigToServerProfileFolders(getConfigProfiles());
}
}
// copy any missing default profiles
copyConfigTemplates(getConfigProfiles());
// set focus on password field
echo "<script type=\"text/javascript\" language=\"javascript\">\n";
echo "<!--\n";
@ -201,15 +218,7 @@ function display_LoginPage($config_object) {
<script type="text/javascript">
jQuery(document).ready(function() {
var equalWidthElements = new Array('#username', '#passwd', '#language');
var maxWidth = 0;
for (var i = 0; i < equalWidthElements.length; ++i) {
if (jQuery(equalWidthElements[i]).width() > maxWidth) {
maxWidth = jQuery(equalWidthElements[i]).width();
};
}
for (var i = 0; i < equalWidthElements.length; ++i) {
jQuery(equalWidthElements[i]).css({'width': maxWidth - (jQuery(equalWidthElements[i]).outerWidth() - jQuery(equalWidthElements[i]).width())});
}
equalWidth(equalWidthElements);
});
</script>
@ -560,6 +569,6 @@ if(!empty($_POST['checklogin'])) {
}
}
//displays the login window
display_LoginPage($_SESSION["config"]);
?>

View File

@ -94,6 +94,32 @@ if (isset($_POST['deleteProfile']) && ($_POST['deleteProfile'] == 'true')) {
}
}
if (isset($_POST['importexport']) && ($_POST['importexport'] === '1')) {
$cfg = new LAMCfgMain();
$impExpMessage = null;
if (isset($_POST['importProfiles_' . $_POST['scope']])) {
// check master password
if (!$cfg->checkPassword($_POST['passwd_' . $_POST['scope']])) {
$impExpMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!'));
}
elseif (copyPdfProfiles($_POST['importProfiles_' . $_POST['scope']], $_POST['scope'])) {
$impExpMessage = new htmlStatusMessage('INFO', _('Import successful'));
}
} else if (isset($_POST['exportProfiles'])) {
// check master password
if (!$cfg->checkPassword($_POST['passwd'])) {
$impExpMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!'));
}
elseif (copyPdfProfiles($_POST['exportProfiles'], $_POST['scope'], $_POST['destServerProfiles'])) {
$impExpMessage = new htmlStatusMessage('INFO', _('Export successful'));
}
}
if ($impExpMessage != null) {
$impExpMessage->colspan = 10;
$container->addElement($impExpMessage, true);
}
}
// get list of account types
$availableScopes = '';
$templateClasses = array();
@ -120,14 +146,19 @@ for ($i = 0; $i < sizeof($templateClasses); $i++) {
include '../main_header.php';
?>
<div class="userlist-bright smallPaddingContent">
<form action="pdfmain.php" method="post">
<form action="pdfmain.php" method="post" name="pdfmainForm" >
<div id="passwordDialogDiv" class="hidden">
<?php echo _("Master password")?>
<input type="password" name="passwd">
<?php echo printHelpLink(getHelp('', '236'), '236')?>
</div>
<?php
if (isset($_GET['savedSuccessfully'])) {
$message = new htmlStatusMessage("INFO", _("PDF structure was successfully saved."), htmlspecialchars($_GET['savedSuccessfully']));
$message->colspan = 10;
$container->addElement($message, true);
}
// new template
$container->addElement(new htmlSubTitle(_('Create a new PDF structure')), true);
$newPDFContainer = new htmlTable();
@ -139,11 +170,17 @@ include '../main_header.php';
$newPDFContainer->addElement(new htmlButton('createNewTemplate', _('Create')));
$container->addElement($newPDFContainer, true);
$container->addElement(new htmlSpacer(null, '10px'), true);
// existing templates
$configProfiles = getConfigProfiles();
$container->addElement(new htmlSubTitle(_("Manage existing PDF structures")), true);
$existingContainer = new htmlTable();
for ($i = 0; $i < sizeof($templateClasses); $i++) {
if ($i > 0) {
$existingContainer->addElement(new htmlSpacer(null, '10px'), true);
}
$existingContainer->addElement(new htmlImage('../../graphics/' . $templateClasses[$i]['scope'] . '.png'));
$existingContainer->addElement(new htmlSpacer('3px', null));
$existingContainer->addElement(new htmlOutputText($templateClasses[$i]['title']));
@ -158,17 +195,122 @@ include '../main_header.php';
$deleteLink = new htmlLink(null, '#', '../../graphics/delete.png');
$deleteLink->setTitle(_('Delete'));
$deleteLink->setOnClick("profileShowDeleteDialog('" . _('Delete') . "', '" . _('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['scope'] . "', '" . 'template_' . $templateClasses[$i]['scope'] . "');");
$existingContainer->addElement($deleteLink, true);
$existingContainer->addElement(new htmlSpacer(null, '10px'), true);
$existingContainer->addElement($deleteLink);
if (count($configProfiles) > 1) {
$importLink = new htmlLink(null, '#', '../../graphics/import.png');
$importLink->setTitle(_('Import PDF structures'));
$importLink->setOnClick("showDistributionDialog('" . _("Import PDF structures") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['scope'] . "', 'import');");
$existingContainer->addElement($importLink);
$exportLink = new htmlLink(null, '#', '../../graphics/export.png');
$exportLink->setTitle(_('Export PDF structure'));
$exportLink->setOnClick("showDistributionDialog('" . _("Export PDF structure") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $templateClasses[$i]['scope'] . "', 'export', '" . 'template_' . $templateClasses[$i]['scope'] . "', '" . $_SESSION['config']->getName() . "');");
$existingContainer->addElement($exportLink);
}
$existingContainer->addNewLine();
}
$container->addElement($existingContainer, true);
$container->addElement(new htmlSpacer(null, '10px'), true);
// generate content
$tabindex = 1;
parseHtml(null, $container, array(), false, $tabindex, 'user');
?>
</form>
</div>
<?php
echo "</form>\n";
echo "</div>\n";
for ($i = 0; $i < sizeof($templateClasses); $i++) {
$scope = $templateClasses[$i]['scope'];
$tmpArr = array();
foreach ($configProfiles as $profile) {
if ($profile != $_SESSION['config']->getName()) {
$accountProfiles = getPDFStructureDefinitions($scope, $profile);
for ($p = 0; $p < sizeof($accountProfiles); $p++) {
$tmpArr[$profile][$accountProfiles[$p]] = $profile . '##' . $accountProfiles[$p];
}
}
}
//import dialog
echo "<div id=\"importDialog_$scope\" class=\"hidden\">\n";
echo "<form id=\"importDialogForm_$scope\" method=\"post\" action=\"pdfmain.php\">\n";
$container = new htmlTable();
$container->addElement(new htmlOutputText(_('PDF structures')), true);
$select = new htmlSelect('importProfiles_' . $scope, $tmpArr, array(), count($tmpArr, 1) < 15 ? count($tmpArr, 1) : 15);
$select->setMultiSelect(true);
$select->setHasDescriptiveElements(true);
$select->setContainsOptgroups(true);
$select->setWidth('290px');
$container->addElement($select);
$container->addElement(new htmlHelpLink('408'), true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Master password")), true);
$exportPasswd = new htmlInputField('passwd_' . $scope);
$exportPasswd->setIsPassword(true);
$container->addElement($exportPasswd);
$container->addElement(new htmlHelpLink('236'));
$container->addElement(new htmlHiddenInput('importexport', '1'));
$container->addElement(new htmlHiddenInput('scope', $scope), true);
parseHtml(null, $container, array(), false, $tabindex, 'user');
echo '</form>';
echo "</div>\n";
}
//export dialog
echo "<div id=\"exportDialog\" class=\"hidden\">\n";
echo "<form id=\"exportDialogForm\" method=\"post\" action=\"pdfmain.php\">\n";
$container = new htmlTable();
$container->addElement(new htmlOutputText(_('PDF structure')), true);
$expStructGroup = new htmlTable();
$expStructGroup->addElement(new htmlSpacer('10px', null));
$expStructGroup->addElement(new htmlDiv('exportName', ''));
$container->addElement($expStructGroup, true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Target server profile")), true);
foreach ($configProfiles as $key => $value) {
$tmpProfiles[$value] = $value;
}
natcasesort($tmpProfiles);
$tmpProfiles['*' . _('Global templates')] = 'templates*';
$findProfile = array_search($_SESSION['config']->getName(), $tmpProfiles);
if ($findProfile !== false) {
unset($tmpProfiles[$findProfile]);
}
$select = new htmlSelect('destServerProfiles', $tmpProfiles, array(), count($tmpProfiles) < 10 ? count($tmpProfiles) : 10);
$select->setHasDescriptiveElements(true);
$select->setSortElements(false);
$select->setMultiSelect(true);
$container->addElement($select);
$container->addElement(new htmlHelpLink('409'), true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Master password")), true);
$exportPasswd = new htmlInputField('passwd');
$exportPasswd->setIsPassword(true);
$container->addElement($exportPasswd);
$container->addElement(new htmlHelpLink('236'));
$container->addElement(new htmlHiddenInput('importexport', '1'), true);
parseHtml(null, $container, array(), false, $tabindex, 'user');
echo '</form>';
echo "</div>\n";
// form for delete action
echo '<div id="deleteProfileDialog" class="hidden"><form id="deleteProfileForm" action="pdfmain.php" method="post">';
echo _("Do you really want to delete this PDF structure?");

View File

@ -85,8 +85,14 @@ for ($i = 0; $i < sizeof($profileClasses); $i++) {
include '../main_header.php';
echo "<div class=\"userlist-bright smallPaddingContent\">\n";
echo "<form action=\"profilemain.php\" method=\"post\">\n";
echo "<form name=\"profilemainForm\" action=\"profilemain.php\" method=\"post\">\n";
?>
<div id="passwordDialogDiv" class="hidden">
<?php echo _("Master password")?>
<input type="password" name="passwd">
<?php echo printHelpLink(getHelp('', '236'), '236')?>
</div>
<?php
$container = new htmlTable();
$container->addElement(new htmlTitle(_("Profile editor")), true);
@ -104,6 +110,33 @@ if (isset($_POST['deleteProfile']) && ($_POST['deleteProfile'] == 'true')) {
}
}
// check if profiles should be imported or exported
if (isset($_POST['importexport']) && ($_POST['importexport'] === '1')) {
$cfg = new LAMCfgMain();
$impExpMessage = null;
if (isset($_POST['importProfiles_' . $_POST['scope']])) {
// check master password
if (!$cfg->checkPassword($_POST['passwd_' . $_POST['scope']])) {
$impExpMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!'));
}
elseif (copyAccountProfiles($_POST['importProfiles_' . $_POST['scope']], $_POST['scope'])) {
$impExpMessage = new htmlStatusMessage('INFO', _('Import successful'));
}
} else if (isset($_POST['exportProfiles'])) {
// check master password
if (!$cfg->checkPassword($_POST['passwd'])) {
$impExpMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!'));
}
elseif (copyAccountProfiles($_POST['exportProfiles'], $_POST['scope'], $_POST['destServerProfiles'])) {
$impExpMessage = new htmlStatusMessage('INFO', _('Export successful'));
}
}
if ($impExpMessage != null) {
$impExpMessage->colspan = 10;
$container->addElement($impExpMessage, true);
}
}
// get list of profiles for each account type
for ($i = 0; $i < sizeof($profileClasses); $i++) {
$profileList = getAccountProfiles($profileClasses[$i]['scope']);
@ -139,10 +172,14 @@ $container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlSubTitle(_('Manage existing profiles')), true);
$existingContainer = new htmlTable();
$existingContainer->colspan = 5;
$configProfiles = getConfigProfiles();
for ($i = 0; $i < sizeof($profileClasses); $i++) {
if ($i > 0) {
$existingContainer->addElement(new htmlSpacer(null, '10px'), true);
}
$existingContainer->addElement(new htmlImage('../../graphics/' . $profileClasses[$i]['scope'] . '.png'));
$existingContainer->addElement(new htmlSpacer('3px', null));
$existingContainer->addElement(new htmlOutputText($profileClasses[$i]['title']));
@ -158,9 +195,23 @@ for ($i = 0; $i < sizeof($profileClasses); $i++) {
$deleteLink->setTitle(_('Delete'));
$deleteLink->setOnClick("profileShowDeleteDialog('" . _('Delete') . "', '" . _('Ok') . "', '" . _('Cancel') . "', '" . $profileClasses[$i]['scope'] . "', '" . 'profile_' . $profileClasses[$i]['scope'] . "');");
$existingContainer->addElement($deleteLink);
if (count($configProfiles) > 1) {
$importLink = new htmlLink(null, '#', '../../graphics/import.png');
$importLink->setTitle(_('Import profiles'));
$importLink->setOnClick("showDistributionDialog('" . _("Import profiles") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $profileClasses[$i]['scope'] . "', 'import');");
$existingContainer->addElement($importLink);
$exportLink = new htmlLink(null, '#', '../../graphics/export.png');
$exportLink->setTitle(_('Export profile'));
$exportLink->setOnClick("showDistributionDialog('" . _("Export profile") . "', '" .
_('Ok') . "', '" . _('Cancel') . "', '" . $profileClasses[$i]['scope'] . "', 'export', '" . 'profile_' . $profileClasses[$i]['scope'] . "', '" . $_SESSION['config']->getName() . "');");
$existingContainer->addElement($exportLink);
}
$existingContainer->addNewLine();
}
$container->addElement($existingContainer);
$container->addElement(new htmlSpacer(null, '10px'), true);
// generate content
$tabindex = 1;
@ -169,6 +220,98 @@ parseHtml(null, $container, array(), false, $tabindex, 'user');
echo "</form>\n";
echo "</div>\n";
for ($i = 0; $i < sizeof($profileClasses); $i++) {
$scope = $profileClasses[$i]['scope'];
$tmpArr = array();
foreach ($configProfiles as $profile) {
if ($profile != $_SESSION['config']->getName()) {
$accountProfiles = getAccountProfiles($scope, $profile);
if (!empty($accountProfiles)) {
for ($p = 0; $p < sizeof($accountProfiles); $p++) {
$tmpArr[$profile][$accountProfiles[$p]] = $profile . '##' . $accountProfiles[$p];
}
}
}
}
//import dialog
echo "<div id=\"importDialog_$scope\" class=\"hidden\">\n";
echo "<form id=\"importDialogForm_$scope\" method=\"post\" action=\"profilemain.php\">\n";
$container = new htmlTable();
$container->addElement(new htmlOutputText(_('Profiles')), true);
$select = new htmlSelect('importProfiles_' . $scope, $tmpArr, array(), count($tmpArr, 1) < 15 ? count($tmpArr, 1) : 15);
$select->setMultiSelect(true);
$select->setHasDescriptiveElements(true);
$select->setContainsOptgroups(true);
$select->setWidth('290px');
$container->addElement($select);
$container->addElement(new htmlHelpLink('362'), true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Master password")), true);
$exportPasswd = new htmlInputField('passwd_' . $scope);
$exportPasswd->setIsPassword(true);
$container->addElement($exportPasswd);
$container->addElement(new htmlHelpLink('236'));
$container->addElement(new htmlHiddenInput('importexport', '1'));
$container->addElement(new htmlHiddenInput('scope', $scope), true);
parseHtml(null, $container, array(), false, $tabindex, 'user');
echo '</form>';
echo "</div>\n";
}
//export dialog
echo "<div id=\"exportDialog\" class=\"hidden\">\n";
echo "<form id=\"exportDialogForm\" method=\"post\" action=\"profilemain.php\">\n";
$container = new htmlTable();
$container->addElement(new htmlOutputText(_('Profile name')), true);
$expStructGroup = new htmlTable();
$expStructGroup->addElement(new htmlSpacer('10px', null));
$expStructGroup->addElement(new htmlDiv('exportName', ''));
$container->addElement($expStructGroup, true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Target server profile")), true);
foreach ($configProfiles as $key => $value) {
$tmpProfiles[$value] = $value;
}
natcasesort($tmpProfiles);
$tmpProfiles['*' . _('Global templates')] = 'templates*';
$findProfile = array_search($_SESSION['config']->getName(), $tmpProfiles);
if ($findProfile !== false) {
unset($tmpProfiles[$findProfile]);
}
$select = new htmlSelect('destServerProfiles', $tmpProfiles, array(), count($tmpProfiles) < 10 ? count($tmpProfiles) : 10);
$select->setHasDescriptiveElements(true);
$select->setSortElements(false);
$select->setMultiSelect(true);
$container->addElement($select);
$container->addElement(new htmlHelpLink('363'), true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Master password")), true);
$exportPasswd = new htmlInputField('passwd');
$exportPasswd->setIsPassword(true);
$container->addElement($exportPasswd);
$container->addElement(new htmlHelpLink('236'));
$container->addElement(new htmlHiddenInput('importexport', '1'), true);
parseHtml(null, $container, array(), false, $tabindex, 'user');
echo '</form>';
echo "</div>\n";
// form for delete action
echo '<div id="deleteProfileDialog" class="hidden"><form id="deleteProfileForm" action="profilemain.php" method="post">';
echo _("Do you really want to delete this profile?");