Ajax file upload

This commit is contained in:
Roland Gruber 2016-12-07 21:18:06 +01:00
parent c9008b3c7c
commit eddfb11cf0
9 changed files with 605 additions and 363 deletions

View File

@ -584,7 +584,7 @@ class lamList {
}
// file upload
elseif (isset($_POST['fileUpload']) && checkIfNewEntriesAreAllowed($this->type)){
metaRefresh("../masscreate.php?type=" . $this->type);
metaRefresh("../upload/masscreate.php?type=" . $this->type);
exit;
}
}
@ -1091,7 +1091,7 @@ class lamList {
elseif (isset($_GET['uploadAllOk'])) {
StatusMessage('INFO', _("Upload has finished"));
if (isset($_SESSION['mass_pdf']['file'])) {
StatusMessage('INFO', sprintf(_('You can download your PDF files {link=%s}{color=#d2131a}here{endcolor}{endlink}.'), '../' . $_SESSION['mass_pdf']['file']));
StatusMessage('INFO', sprintf(_('You can download your PDF files {link=%s}{color=#d2131a}here{endcolor}{endlink}.'), $_SESSION['mass_pdf']['file']));
}
}
elseif (isset($_GET['accountEditInvalidID'])) {

View File

@ -9,12 +9,12 @@ $Id$
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
@ -30,56 +30,56 @@ $Id$
/**
* File upload
*
*
* @package tools
*/
*/
class toolFileUpload implements LAMTool {
/**
* Returns the name of the tool.
*
*
* @return string name
*/
function getName() {
return _("File upload");
}
/**
* returns a description text for the tool.
*
*
* @return string description
*/
function getDescription() {
return _("Creates accounts by uploading a CSV formated file.");
}
/**
* Returns a link to the tool page (relative to templates/).
*
*
* @return string link
*/
function getLink() {
return "masscreate.php";
return "upload/masscreate.php";
}
/**
/**
* Returns if the tool requires write access to LDAP.
*
*
* @return boolean true if write access is needed
*/
function getRequiresWriteAccess() {
return true;
}
/**
* Returns if the tool requires password change rights.
*
*
* @return boolean true if password change rights are needed
*/
function getRequiresPasswordChangeRights() {
return true;
}
/**
* Returns the link to the tool image (relative to graphics/)
*
@ -88,7 +88,7 @@ class toolFileUpload implements LAMTool {
function getImageLink() {
return 'up.gif';
}
/**
* Returns the prefered position of this tool on the tools page.
* The position may be between 0 and 1000. 0 is the top position.
@ -98,16 +98,16 @@ class toolFileUpload implements LAMTool {
function getPosition() {
return 300;
}
/**
* Returns a list of sub tools or an empty array.
*
*
* @return array list of subtools (LAMTool)
*/
function getSubTools() {
return array();
}
/**
* Returns if the tool is visible in the menu.
*
@ -116,16 +116,16 @@ class toolFileUpload implements LAMTool {
function isVisible() {
return (sizeof($_SESSION['config']->get_ActiveTypes()) > 0);
}
/**
* Returns if a tool may be hidden by configuration in the LAM server profile.
*
*
* @return boolean hideable
*/
function isHideable() {
return true;
}
}
?>

307
lam/lib/upload.inc Normal file
View File

@ -0,0 +1,307 @@
<?php
namespace LAM\UPLOAD;
use ZipArchive;
use accountContainer;
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2016 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
*/
/**
* Creates LDAP accounts for file upload.
*
* @author Roland Gruber
* @package tools
*/
/** LDAP handle */
include_once('ldap.inc');
/** PDF */
include_once('pdf.inc');
/**
* Creates LDAP accounts for file upload.
*
* @author Roland Gruber
* @package tools
*/
class Uploader {
private $accounts = null;
private $data = null;
private $scope = null;
private $endTime;
const TIME_LIMIT = 10;
public static function cleanSession() {
foreach ($_SESSION as $key => &$value) {
if (strpos($key, 'mass_') === 0) {
unset($_SESSION[$key]);
}
}
}
/**
* Constructor
*/
public function __construct($scope) {
$this->accounts = unserialize(lamDecrypt($_SESSION['mass_accounts']));
$this->data = unserialize(lamDecrypt($_SESSION['mass_data']));
$this->scope = $scope;
$startTime = time();
$maxTime = get_cfg_var('max_execution_time') - 5;
if ($maxTime > Uploader::TIME_LIMIT) $maxTime = Uploader::TIME_LIMIT;
if ($maxTime <= 0) $maxTime = Uploader::TIME_LIMIT;
$this->endTime = $startTime + $maxTime;
}
/**
* Start or continues the file upload.
*
* @return String JSON of upload status
*/
public function doUpload() {
$this->securityCheck();
if (!isset($_SESSION['mass_counter'])) {
return $this->startUpload();
}
elseif ($_SESSION['mass_counter'] < sizeof($this->accounts)) {
return $this->continueUpload();
}
elseif (!isset($_SESSION['mass_postActions']['finished'])) {
return $this->runPostActions();
}
elseif (($_SESSION['mass_pdf']['structure'] != null) && !isset($_SESSION['mass_pdf']['finished'])) {
return $this->createPDF();
}
return $this->buildUploadStatus(100, true, '', 100, true, 100);
}
/**
* Continues to upload accounts.
*
* @return String JSON of upload status
*/
private function continueUpload() {
while (($_SESSION['mass_counter'] < sizeof($this->accounts)) && ($this->endTime > time())) {
$this->uploadEntry($_SESSION['mass_counter']);
$_SESSION['mass_counter']++;
}
$accountsProgress = round(($_SESSION['mass_counter'] * 100) / sizeof($this->accounts), 2);
$accountsFinished = ($_SESSION['mass_counter'] == sizeof($this->accounts));
return $this->buildUploadStatus($accountsProgress, $accountsFinished);
}
/**
* Performs the upload of a single LDAP entry.
*
* @param int $position position in $this->accounts.
*/
private function uploadEntry($position) {
$attrs = $this->accounts[$position];
$dn = $attrs['dn'];
unset($attrs['dn']);
// remove informational attributes
foreach ($attrs as $key => $value) {
if (strpos($key, 'INFO.') === 0) {
unset($attrs[$key]);
}
}
// run preactions
$preAttributes = array();
foreach ($attrs as $key => $value) {
$preAttributes[$key] = &$attrs[$key];
}
$preAttributes['dn'] = &$dn;
$preMessages = doUploadPreActions($this->scope, $_SESSION['mass_selectedModules'], $preAttributes);
$preActionOk = true;
for ($i = 0; $i < sizeof($preMessages); $i++) {
if (($preMessages[$i][0] == 'ERROR') || ($preMessages[$i][0] == 'WARN')) {
$preActionOk = false;
$_SESSION['mass_errors'][] = $preMessages[$i];
}
}
if ($preActionOk) {
// add LDAP entry
$success = @ldap_add($_SESSION['ldap']->server(), $dn, $attrs);
if (!$success) {
$errorMessage = array(
"ERROR",
_("LAM was unable to create account %s! An LDAP error occured."),
getDefaultLDAPErrorString($_SESSION['ldap']->server()),
array($position));
$_SESSION['mass_errors'][] = $errorMessage;
$_SESSION['mass_failed'][] = $position;
}
}
}
/**
* Starts the file upload.
*
* @return String JSON of upload status
*/
private function startUpload() {
$_SESSION['mass_counter'] = 0;
return $this->buildUploadStatus();
}
/**
* Returns the upload status as JSON.
*
* @param number $accountsProgress progress for LDAP entries
* @param string $accountsFinished all entries in LDAP
* @param string $postActionsTitle title for current post action
* @param number $postActionsProgress progress for post actions
* @param string $postActionsFinished post actions finished
* @param number $pdfProgress PDF creation progress
* @return String JSON status
*/
private function buildUploadStatus($accountsProgress = 0, $accountsFinished = false,
$postActionsTitle = '', $postActionsProgress = 0, $postActionsFinished = false,
$pdfProgress = 0) {
$pdfFinished = ($_SESSION['mass_pdf']['structure'] == null) || isset($_SESSION['mass_pdf']['finished']);
$allDone = $accountsFinished && $postActionsFinished && $pdfFinished;
$errorHtml = '';
if ($allDone && !empty($_SESSION['mass_errors'])) {
foreach ($_SESSION['mass_errors'] as $error) {
$text = isset($error[2]) ? $error[2] : '';
$vars = isset($error[3]) ? $error[3] : array();
$errorHtml .= StatusMessage($error[0], $error[1], $text, $vars, true);
}
}
$status = array(
'title' => _("LDAP upload in progress. Please wait."),
'titleFinished' => _("Upload has finished"),
'titleErrors' => _("There were errors while uploading:"),
'titlePDF' => _('Create PDF files'),
'accountsProgress' => $accountsProgress,
'accountsFinished' => $accountsFinished,
'postActionsTitle' => $postActionsTitle,
'postActionsProgress' => $postActionsProgress,
'postActionsFinished' => $postActionsFinished,
'pdfProgress' => $pdfProgress,
'pdfFinished' => $pdfFinished,
'allDone' => $allDone,
'errorHtml' => $errorHtml,
'scope' => $this->scope
);
return json_encode($status);
}
/**
* Checks for security violations and stops processing if needed.
*/
private function securityCheck() {
if (!isLoggedIn() || empty($this->scope)
|| isAccountTypeHidden($this->scope)
|| !checkIfNewEntriesAreAllowed($this->scope)
|| !checkIfWriteAccessIsAllowed($this->scope)) {
die;
}
}
/**
* Performs any post create actions by modules.
*
* @return String JSON of upload status
*/
private function runPostActions() {
$return = $this->runModulePostActions();
while (!isset($_SESSION['mass_postActions']['finished']) && ($this->endTime > time())) {
$return = $this->runModulePostActions();
}
$title = _("Additional tasks for module:") . ' ' . getModuleAlias($return['module'], $this->scope);
$progress = round($return['progress'], 2);
$finished = isset($_SESSION['mass_postActions']['finished']);
return $this->buildUploadStatus(100, true, $title, $progress, $finished);
}
/**
* Runs a single post create action by modules.
*
* @return array status array
*/
private function runModulePostActions() {
$return = doUploadPostActions($this->scope, $this->data, $_SESSION['mass_ids'], $_SESSION['mass_failed'], $_SESSION['mass_selectedModules'], $this->accounts);
if ($return['status'] == 'finished') {
$_SESSION['mass_postActions']['finished'] = true;
}
if (isset($return['errors'])) {
for ($i = 0; $i < sizeof($return['errors']); $i++) {
$_SESSION['mass_errors'][] = $return['errors'][$i];
}
}
return $return;
}
/**
* Creates the PDF files.
*
* @return String JSON of upload status
*/
private function createPDF() {
$file = $_SESSION['mass_pdf']['file'];
$pdfStructure = $_SESSION['mass_pdf']['structure'];
$pdfZip = new ZipArchive();
if ($_SESSION['mass_pdf']['counter'] == 0) {
$pdfZipResult = @$pdfZip->open($_SESSION['mass_pdf']['file'], ZipArchive::CREATE);
if (!$pdfZipResult === true) {
$_SESSION['mass_errors'][] = array('ERROR', _('Unable to create ZIP file for PDF export.'), $file);
$_SESSION['mass_pdf']['finished'] = true;
}
}
else {
@$pdfZip->open($_SESSION['mass_pdf']['file']);
}
while (!isset($_SESSION['mass_pdf']['finished']) && ($this->endTime > time())) {
$attrs = $this->accounts[$_SESSION['mass_pdf']['counter']];
$dn = $attrs['dn'];
// get informational attributes
$infoAttributes = array();
foreach ($attrs as $key => $value) {
if (strpos($key, 'INFO.') === 0) {
$infoAttributes[$key] = $value;
}
}
// load account
$_SESSION['mass_pdfAccount'] = new accountContainer($this->scope, 'mass_pdfAccount');
$pdfErrors = $_SESSION['mass_pdfAccount']->load_account($dn, $infoAttributes);
if (sizeof($pdfErrors) > 0) {
$_SESSION['mass_errors'] = array_merge($_SESSION['mass_errors'], $pdfErrors);
$_SESSION['mass_pdf']['finished'] = true;
break;
}
// create and save PDF
$pdfContent = createModulePDF(array($_SESSION['mass_pdfAccount']), $pdfStructure, true);
$fileName = $dn . '.pdf';
$pdfZip->addFromString($fileName, $pdfContent);
$_SESSION['mass_pdf']['counter'] ++;
if ($_SESSION['mass_pdf']['counter'] >= sizeof($this->accounts)) {
$_SESSION['mass_pdf']['finished'] = true;
}
}
@$pdfZip->close();
$progress = ($_SESSION['mass_pdf']['counter'] * 100) / sizeof($this->accounts);
return $this->buildUploadStatus(100, true, '', 100, true, $progress);
}
}

View File

@ -3,7 +3,7 @@
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2003 - 2014 Roland Gruber
Copyright (C) 2003 - 2016 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
@ -23,7 +23,7 @@ $Id$
/**
* Called when user clicks on a table row. This toggles the checkbox in the row.
*
*
* @param box checkbox name
*/
function list_click(box) {
@ -38,7 +38,7 @@ function list_click(box) {
/**
* The user changed the value in the OU selection box. This will reload the list view with the new suffix.
*
*
* @param type account type
* @param element dropdown box
*/
@ -48,7 +48,7 @@ function listOUchanged(type, element) {
/**
* The user pressed a key in the page number box. On enter this will reload the list view with the new page.
*
*
* @param url target URL
* @param e event
*/
@ -83,7 +83,7 @@ function listResizeITabContentDiv() {
/**
* Shows the dialog to change the list settings.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -104,7 +104,7 @@ function listShowSettingsDialog(title, okText, cancelText) {
/**
* Submits the form by clicking on the given button if enter was pressed.
* Example: SubmitForm('apply_filter', event);
*
*
* @param id button ID
* @param e event
* @returns Boolean result
@ -147,7 +147,7 @@ function addResizeHandler(item, min, max) {
}
jQuery(item).toggleClass('imgExpanded');
}
);
);
}
/**
@ -168,7 +168,7 @@ function list_switchAccountSelection() {
/**
* The user changed the value in the profile selection box. This will reload the login page with the new profile.
*
*
* @param element dropdown box
*/
function loginProfileChanged(element) {
@ -177,7 +177,7 @@ function loginProfileChanged(element) {
/**
* Shows the dialog to delete a profile.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -206,7 +206,7 @@ function profileShowDeleteDialog(title, okText, cancelText, scope, selectFieldNa
/**
* Shows a simple dialog.
*
*
* @param title dialog title
* @param okText text for Ok button (optional, submits form)
* @param cancelText text for Cancel button
@ -230,7 +230,7 @@ function showSimpleDialog(title, okText, cancelText, formID, dialogDivID) {
/**
* Shows the dialog to change the password.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -259,7 +259,7 @@ function passwordShowChangeDialog(title, okText, cancelText, randomText, ajaxURL
/**
* Manages the password change when a button is pressed.
*
*
* @param random "true" if random password should be generated
* @param ajaxURL URL used for AJAX request
*/
@ -292,7 +292,7 @@ function passwordHandleInput(random, ajaxURL) {
/**
* Manages the server reply to a password change request.
*
*
* @param data JSON reply
*/
function passwordHandleReply(data) {
@ -306,12 +306,12 @@ function passwordHandleReply(data) {
}
else {
jQuery('#passwordDialogMessageArea').html(data.messages);
}
}
}
/**
* Shows a general confirmation dialog and submits a form if the user accepted.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -345,7 +345,7 @@ function showConfirmationDialog(title, okText, cancelText, dialogDiv, formName,
/**
* Appends the input fields of a dialog back to the form and submits it.
*
*
* @param dialogDiv ID of dialog div
* @param formName name of form
*/
@ -361,7 +361,7 @@ function appendDialogInputsToFormAndSubmit(dialogDiv, formName) {
/**
* Shows a simple confirmation dialog.
* If the user presses Cancel then the current action is stopped (event.preventDefault()).
*
*
* @param text dialog text
* @param e event
*/
@ -380,7 +380,7 @@ function confirmOrStopProcessing(text, e) {
/**
* Alines the elements with the given IDs to the same width.
*
*
* @param elementIDs IDs
*/
function equalWidth(elementIDs) {
@ -401,7 +401,7 @@ function equalWidth(elementIDs) {
/**
* Alines the elements with the given IDs to the same height.
*
*
* @param elementIDs IDs
*/
function equalHeight(elementIDs) {
@ -418,7 +418,7 @@ function equalHeight(elementIDs) {
/**
* Shows the dialog to change the list settings.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -430,7 +430,7 @@ function showDistributionDialog(title, okText, cancelText, scope, type, selectFi
// show dialog
var buttonList = {};
var dialogId = '';
if (type == 'export') {
// show structure name to export
jQuery('#exportName').text(jQuery('[name=' + selectFieldName + ']').val());
@ -451,7 +451,7 @@ function showDistributionDialog(title, okText, cancelText, scope, type, selectFi
buttonList[okText] = function() { document.forms["importDialogForm_" + scope].submit(); };
}
buttonList[cancelText] = function() { jQuery(this).dialog("close"); };
jQuery('#' + dialogId).dialog({
modal: true,
title: title,
@ -468,7 +468,7 @@ function showDistributionDialog(title, okText, cancelText, scope, type, selectFi
/**
* Stores the current scroll position in the form.
*
*
* @param formName ID of form
*/
function saveScrollPosition(formName) {
@ -484,11 +484,11 @@ function saveScrollPosition(formName) {
name: 'scrollPositionLeft',
value: left
}).appendTo(jQuery('#' + formName));
}
}
/**
* Shows the dialog to create a DNS zone.
*
*
* @param title dialog title
* @param okText text for Ok button
* @param cancelText text for Cancel button
@ -528,14 +528,14 @@ jQuery(document).ready(
/**
* Checks if the given field has the same value as the reference field.
* Field is marked red if different and green if equal.
*
*
* @param fieldID ID of field to check
* @param fieldIDReference ID of reference field
*/
function checkFieldsHaveSameValues(fieldID, fieldIDReference) {
var field = jQuery('#' + fieldID);
var fieldRef = jQuery('#' + fieldIDReference);
var check =
var check =
function() {
var value = field.val();
var valueRef = fieldRef.val();
@ -546,7 +546,7 @@ function checkFieldsHaveSameValues(fieldID, fieldIDReference) {
else {
if (value == valueRef) {
field.removeClass('markFail');
field.addClass('markOk');
field.addClass('markOk');
}
else {
field.addClass('markFail');
@ -561,12 +561,12 @@ function checkFieldsHaveSameValues(fieldID, fieldIDReference) {
/**
* Checks if the value of the given password field matches LAM's password policy.
* Field is marked red if fail and green if ok.
*
*
* @param fieldID ID of field to check
*/
function checkPasswordStrength(fieldID, ajaxURL) {
var field = jQuery('#' + fieldID);
var check =
var check =
function() {
var value = field.val();
var pwdJSON = {
@ -580,7 +580,7 @@ function checkPasswordStrength(fieldID, ajaxURL) {
/**
* Manages the server reply to a password strength check request.
*
*
* @param data JSON reply
* @param fieldID input field ID
*/
@ -593,19 +593,19 @@ function checkPasswordStrengthHandleReply(data, fieldID) {
}
else if (field.val() == '') {
field.removeClass('markFail');
field.removeClass('markOk');
field.removeClass('markOk');
}
else {
field.addClass('markFail');
field.removeClass('markOk');
field.prop('title', data.result);
}
}
}
/**
* Updates the positions of a htmlSortable list in a hidden input field.
* The positions must be separated by comma (e.g. "0,1,2,3").
*
*
* @param id HTML ID of hidden input field
* @param oldPos old position
* @param newPos new position
@ -631,7 +631,7 @@ function updateModulePositions(id, oldPos, newPos) {
/**
* Filters a select box by the value of the filter input field.
*
*
* @param filterInput ID of input field for filter
* @param select ID of select box to filter
* @param event key event
@ -658,3 +658,117 @@ function filterSelect(filterInput, select, event) {
}
});
}
window.lam = window.lam || {};
window.lam.upload = window.lam.upload || {};
/**
* Continues a CSV file upload.
*
* @param url URL where to get status JSON
*/
window.lam.upload.continueUpload = function(url) {
jQuery.ajax({
url: url,
method: 'POST',
data: 'jsonInput='
})
.done(function(jsonData){
if (!jsonData.accountsFinished) {
window.lam.upload.printBasicStatus(jsonData);
}
else if (!jsonData.postActionsFinished) {
window.lam.upload.printPostActionStatus(jsonData);
}
else if (!jsonData.pdfFinished) {
window.lam.upload.printPDFStatus(jsonData);
}
// next call if not finished
if (!jsonData.allDone) {
window.lam.upload.continueUpload(url);
}
else {
window.lam.upload.uploadDone(jsonData);
}
});
};
/**
* Prints the upload status when accounts are still being created.
*
* @param jsonData status JSON
*/
window.lam.upload.printBasicStatus = function(jsonData) {
var htmlOut = '<div class="title">';
htmlOut += '<h2 class="titleText">' + jsonData.title + '</h2>';
htmlOut += '</div>';
htmlOut += '<div id="progressbarGeneral"></div>';
jQuery('#uploadContent').html(htmlOut);
jQuery('#progressbarGeneral').progressbar({
value: jsonData.accountsProgress
});
};
/**
* Prints the upload status when post actions run.
*
* @param jsonData status JSON
*/
window.lam.upload.printPostActionStatus = function(jsonData) {
var htmlOut = '<div class="title">';
htmlOut += '<h2 class="titleText">' + jsonData.title + '</h2>';
htmlOut += '</div>';
htmlOut += '<div id="progressbarGeneral"></div>';
if (jsonData.postActionsTitle) {
htmlOut += '<h2>' + jsonData.postActionsTitle + '</h2>';
htmlOut += '<div id="progressbarPostActions"></div>';
}
jQuery('#uploadContent').html(htmlOut);
jQuery('#progressbarGeneral').progressbar({
value: 100
});
if (jsonData.postActionsTitle) {
jQuery('#progressbarPostActions').progressbar({
value: jsonData.postActionsProgress
});
}
};
/**
* Prints the upload status when PDFs are generated.
*
* @param jsonData status JSON
*/
window.lam.upload.printPDFStatus = function(jsonData) {
var htmlOut = '<div class="title">';
htmlOut += '<h2 class="titleText">' + jsonData.title + '</h2>';
htmlOut += '</div>';
htmlOut += '<div id="progressbarGeneral"></div>';
htmlOut += '<h2>' + jsonData.titlePDF + '</h2>';
htmlOut += '<div id="progressbarPDF"></div>';
jQuery('#uploadContent').html(htmlOut);
jQuery('#progressbarGeneral').progressbar({
value: 100
});
jQuery('#progressbarPDF').progressbar({
value: jsonData.pdfProgress
});
};
/**
* Upload finished, check for errors.
*
* @param jsonData status JSON
*/
window.lam.upload.uploadDone = function(jsonData) {
if (jsonData.errorHtml) {
var htmlOut = '<div class="subTitle">';
htmlOut += '<h4 class="subTitleText">' + jsonData.titleErrors + '</h4>';
htmlOut += '</div>';
htmlOut += jsonData.errorHtml;
jQuery('#uploadContent').html(htmlOut);
}
else {
top.location.href = '../lists/list.php?type=' + jsonData.scope + '&uploadAllOk';
}
}

View File

@ -1,277 +0,0 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2004 - 2013 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
*/
/**
* Creates LDAP accounts for file upload.
*
* @author Roland Gruber
* @package tools
*/
/** security functions */
include_once("../lib/security.inc");
/** access to configuration */
include_once('../lib/config.inc');
/** LDAP handle */
include_once('../lib/ldap.inc');
/** status messages */
include_once('../lib/status.inc');
/** account modules */
include_once('../lib/modules.inc');
/** PDF */
include_once('../lib/pdf.inc');
// Start session
startSecureSession();
// check if this tool may be run
checkIfToolIsActive('toolFileUpload');
// die if no write access
if (!checkIfWriteAccessIsAllowed()) die();
// Redirect to startpage if user is not loged in
if (!isLoggedIn()) {
metaRefresh("login.php");
exit;
}
// Set correct language, codepages, ....
setlanguage();
include 'main_header.php';
$scope = htmlspecialchars($_SESSION['mass_scope']);
// check if account type is ok
if (isAccountTypeHidden($scope)) {
logNewMessage(LOG_ERR, 'User tried to access hidden upload: ' . $scope);
die();
}
if (!checkIfNewEntriesAreAllowed($scope) || !checkIfWriteAccessIsAllowed($scope)) {
logNewMessage(LOG_ERR, 'User tried to access forbidden upload: ' . $scope);
die();
}
echo '<div class="' . $scope . '-bright smallPaddingContent">';
// create accounts
$accounts = unserialize(lamDecrypt($_SESSION['mass_accounts']));
if (($_SESSION['mass_counter'] < sizeof($accounts)) || !isset($_SESSION['mass_postActions']['finished']) || !isset($_SESSION['mass_pdf']['finished'])) {
$startTime = time();
$maxTime = get_cfg_var('max_execution_time') - 5;
if ($maxTime > 60) $maxTime = 60;
if ($maxTime <= 0) $maxTime = 60;
echo "<div class=\"title\">\n";
echo "<h2 class=\"titleText\">" . _("LDAP upload in progress. Please wait.") . "</h2>\n";
echo "</div>";
$progress = ($_SESSION['mass_counter'] * 100) / sizeof($accounts);
?>
<div id="progressbarGeneral"></div>
<script type="text/javascript">
$(function() {
$( "#progressbarGeneral" ).progressbar({
value: <?php echo $progress; ?>
});
});
</script>
<?php
flush(); // send HTML to browser
// add accounts to LDAP
while (($_SESSION['mass_counter'] < sizeof($accounts)) && (($startTime + $maxTime) > time())) {
// create accounts as long as max_execution_time is not near
$attrs = $accounts[$_SESSION['mass_counter']];
$dn = $attrs['dn'];
unset($attrs['dn']);
// remove informational attributes
foreach ($attrs as $key => $value) {
if (strpos($key, 'INFO.') === 0) {
unset($attrs[$key]);
}
}
// run preactions
$preAttributes = array();
foreach ($attrs as $key => $value) {
$preAttributes[$key] = &$attrs[$key];
}
$preAttributes['dn'] = &$dn;
$preMessages = doUploadPreActions($scope, $_SESSION['mass_selectedModules'], $preAttributes);
$preActionOk = true;
for ($i = 0; $i < sizeof($preMessages); $i++) {
if (($preMessages[$i][0] == 'ERROR') || ($preMessages[$i][0] == 'WARN')) {
$preActionOk = false;
$_SESSION['mass_errors'][] = $preMessages[$i];
}
}
if ($preActionOk) {
// add LDAP entry
$success = @ldap_add($_SESSION['ldap']->server(), $dn, $attrs);
if (!$success) {
$errorMessage = array(
"ERROR",
_("LAM was unable to create account %s! An LDAP error occured."),
getDefaultLDAPErrorString($_SESSION['ldap']->server()),
array($_SESSION['mass_counter']));
$_SESSION['mass_errors'][] = $errorMessage;
$_SESSION['mass_failed'][] = $_SESSION['mass_counter'];
}
}
$_SESSION['mass_counter']++;
}
$progress = ($_SESSION['mass_counter'] * 100) / sizeof($accounts);
?>
<script type="text/javascript">
jQuery(function() {
jQuery( "#progressbarGeneral" ).progressbar({
value: <?php echo $progress; ?>
});
});
</script>
<?php
flush(); // send HTML to browser
// do post upload actions after all accounts are created
if (($_SESSION['mass_counter'] >= sizeof($accounts)) && !isset($_SESSION['mass_postActions']['finished'])) {
$data = unserialize(lamDecrypt($_SESSION['mass_data']));
$return = doUploadPostActions($scope, $data, $_SESSION['mass_ids'], $_SESSION['mass_failed'], $_SESSION['mass_selectedModules'], $accounts);
if ($return['status'] == 'finished') {
$_SESSION['mass_postActions']['finished'] = true;
}
for ($i = 0; $i < sizeof($return['errors']); $i++) $_SESSION['mass_errors'][] = $return['errors'][$i];
echo "<h1>" . _("Additional tasks for module:") . ' ' . getModuleAlias($return['module'], $scope) . "</h1>\n";
?>
<div id="progressbar<?php echo $return['module']; ?>"></div>
<script type="text/javascript">
jQuery(function() {
jQuery( "#progressbar<?php echo $return['module']; ?>" ).progressbar({
value: <?php echo $return['progress']; ?>
});
});
</script>
<?php
flush();
while (!isset($_SESSION['mass_postActions']['finished']) && (($startTime + $maxTime) > time())) {
$return = doUploadPostActions($scope, $data, $_SESSION['mass_ids'], $_SESSION['mass_failed'], $_SESSION['mass_selectedModules'], $accounts);
if ($return['status'] == 'finished') {
$_SESSION['mass_postActions']['finished'] = true;
}
if (isset($return['errors'])) {
for ($i = 0; $i < sizeof($return['errors']); $i++) {
$_SESSION['mass_errors'][] = $return['errors'][$i];
}
}
}
}
// create PDF when upload post actions are done
if (isset($_SESSION['mass_postActions']['finished'])) {
if (($_SESSION['mass_pdf']['structure'] != null) && !isset($_SESSION['mass_pdf']['finished'])) {
$file = $_SESSION['mass_pdf']['file'];
$pdfStructure = $_SESSION['mass_pdf']['structure'];
$pdfZip = new ZipArchive();
if ($_SESSION['mass_pdf']['counter'] == 0) {
$pdfZipResult = @$pdfZip->open($_SESSION['mass_pdf']['file'], ZipArchive::CREATE);
if (!$pdfZipResult === true) {
$_SESSION['mass_errors'][] = array('ERROR', _('Unable to create ZIP file for PDF export.'), $file);
$_SESSION['mass_pdf']['finished'] = true;
}
}
else {
@$pdfZip->open($_SESSION['mass_pdf']['file']);
}
// show progress bar
$progress = ($_SESSION['mass_pdf']['counter'] * 100) / sizeof($accounts);
echo "<h1>" . _('Create PDF files') . "</h1>\n";
?>
<div id="progressbarPDF"></div>
<script type="text/javascript">
jQuery(function() {
jQuery( "#progressbarPDF" ).progressbar({
value: <?php echo $progress; ?>
});
});
</script>
<?php
flush();
while (!isset($_SESSION['mass_pdf']['finished']) && (($startTime + $maxTime) > time())) {
$attrs = $accounts[$_SESSION['mass_pdf']['counter']];
$dn = $attrs['dn'];
// get informational attributes
$infoAttributes = array();
foreach ($attrs as $key => $value) {
if (strpos($key, 'INFO.') === 0) {
$infoAttributes[$key] = $value;
}
}
// load account
$_SESSION['pdfAccount'] = new accountContainer($scope, 'pdfAccount');
$pdfErrors = $_SESSION['pdfAccount']->load_account($dn, $infoAttributes);
if (sizeof($pdfErrors) > 0) {
$_SESSION['mass_errors'] = array_merge($_SESSION['mass_errors'], $pdfErrors);
$_SESSION['mass_pdf']['finished'] = true;
break;
}
// create and save PDF
$pdfContent = createModulePDF(array($_SESSION['pdfAccount']), $pdfStructure, true);
$fileName = $dn . '.pdf';
$pdfZip->addFromString($fileName, $pdfContent);
$_SESSION['mass_pdf']['counter'] ++;
if ($_SESSION['mass_pdf']['counter'] >= sizeof($accounts)) {
$_SESSION['mass_pdf']['finished'] = true;
}
}
@$pdfZip->close();
}
else {
$_SESSION['mass_pdf']['finished'] = true;
}
}
// refresh with JavaScript
echo "<script type=\"text/javascript\">\n";
echo "top.location.href = \"massDoUpload.php\";\n";
echo "</script>\n";
}
// all accounts have been created
else {
echo "<div class=\"title\">\n";
echo "<h2 class=\"titleText\">" . _("Upload has finished") . "</h2>\n";
echo "</div>";
if (sizeof($_SESSION['mass_errors']) > 0) {
echo "<div class=\"subTitle\">\n";
echo "<h4 class=\"subTitleText\">" . _("There were errors while uploading:") . "</h4>\n";
echo "</div>";
for ($i = 0; $i < sizeof($_SESSION['mass_errors']); $i++) {
call_user_func_array('StatusMessage', $_SESSION['mass_errors'][$i]);
echo "<br>";
}
}
else {
// redirect to list if no errors occured
echo "<script type=\"text/javascript\">\n";
echo "top.location.href = \"lists/list.php?type=" . $scope . "&uploadAllOk\";\n";
echo "</script>\n";
}
}
echo '</div>';
include 'main_footer.php';
?>

View File

@ -88,6 +88,14 @@ class lamAjax {
elseif ($function == 'passwordStrengthCheck') {
lamAjax::checkPasswordStrength($jsonInput);
}
elseif ($function == 'upload') {
include_once('../../lib/upload.inc');
$uploader = new LAM\UPLOAD\Uploader($_GET['scope']);
ob_start();
$jsonOut = $uploader->doUpload();
ob_end_clean();
echo $jsonOut;
}
}
/**

View File

@ -29,13 +29,13 @@ $Id$
*/
/** security functions */
include_once("../lib/security.inc");
include_once("../../lib/security.inc");
/** access to configuration */
include_once('../lib/config.inc');
include_once('../../lib/config.inc');
/** status messages */
include_once('../lib/status.inc');
include_once('../../lib/status.inc');
/** account modules */
include_once('../lib/modules.inc');
include_once('../../lib/modules.inc');
// Start session
@ -49,7 +49,7 @@ if (!checkIfWriteAccessIsAllowed()) die();
// Redirect to startpage if user is not loged in
if (!isLoggedIn()) {
metaRefresh("login.php");
metaRefresh("../login.php");
exit;
}
@ -88,7 +88,7 @@ if (isset($_GET['showldif'])) {
exit;
}
include 'main_header.php';
include '../main_header.php';
$scope = htmlspecialchars($_POST['scope']);
// check if account type is ok
@ -215,7 +215,6 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
else {
// store accounts in session
$_SESSION['mass_accounts'] = lamEncrypt(serialize($accounts));
$_SESSION['mass_counter'] = 0;
$_SESSION['mass_errors'] = array();
$_SESSION['mass_failed'] = array();
$_SESSION['mass_postActions'] = array();
@ -229,7 +228,7 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
if (isset($_POST['createPDF']) && ($_POST['createPDF'] == 'on')) {
$_SESSION['mass_pdf']['structure'] = $_POST['pdfStructure'];
$_SESSION['mass_pdf']['counter'] = 0;
$_SESSION['mass_pdf']['file'] = '../tmp/lam_pdf' . getRandomNumber() . '.zip';
$_SESSION['mass_pdf']['file'] = '../../tmp/lam_pdf' . getRandomNumber() . '.zip';
}
else {
$_SESSION['mass_pdf']['structure'] = null;
@ -238,8 +237,8 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
$container->addElement(new htmlTitle(_("LAM has checked your input and is now ready to create the accounts.")), true);
$container->addElement(new htmlSpacer(null, '10px'), true);
$buttonContainer = new htmlTable();
$buttonContainer->addElement(new htmlLink(_("Upload accounts to LDAP"), 'massDoUpload.php', '../graphics/up.gif', true));
$buttonContainer->addElement(new htmlLink(_("Show LDIF file"), 'massBuildAccounts.php?showldif=true', '../graphics/edit.png', true));
$buttonContainer->addElement(new htmlLink(_("Upload accounts to LDAP"), 'massDoUpload.php', '../../graphics/up.gif', true));
$buttonContainer->addElement(new htmlLink(_("Show LDIF file"), 'massBuildAccounts.php?showldif=true', '../../graphics/edit.png', true));
$buttonContainer->addElement(new htmlSpacer('10px', null));
massPrintBackButton($scope, $selectedModules, $buttonContainer);
$container->addElement($buttonContainer, true);
@ -263,7 +262,7 @@ parseHtml(null, $container, array(), false, $tabindex, $scope);
echo '</div>';
echo '</form>';
include 'main_footer.php';
include '../main_footer.php';
/**
* Prints a back button to the page where the user enters a file to upload.

View File

@ -0,0 +1,88 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
Copyright (C) 2004 - 2013 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
*/
/**
* Creates LDAP accounts for file upload.
*
* @author Roland Gruber
* @package tools
*/
/** security functions */
include_once("../../lib/security.inc");
/** access to configuration */
include_once('../../lib/config.inc');
/** LDAP handle */
include_once('../../lib/ldap.inc');
/** status messages */
include_once('../../lib/status.inc');
/** account modules */
include_once('../../lib/modules.inc');
/** PDF */
include_once('../../lib/pdf.inc');
// Start session
startSecureSession();
// check if this tool may be run
checkIfToolIsActive('toolFileUpload');
// die if no write access
if (!checkIfWriteAccessIsAllowed()) die();
// Redirect to startpage if user is not loged in
if (!isLoggedIn()) {
metaRefresh("../login.php");
exit;
}
// Set correct language, codepages, ....
setlanguage();
include '../main_header.php';
$scope = htmlspecialchars($_SESSION['mass_scope']);
// check if account type is ok
if (isAccountTypeHidden($scope)) {
logNewMessage(LOG_ERR, 'User tried to access hidden upload: ' . $scope);
die();
}
if (!checkIfNewEntriesAreAllowed($scope) || !checkIfWriteAccessIsAllowed($scope)) {
logNewMessage(LOG_ERR, 'User tried to access forbidden upload: ' . $scope);
die();
}
echo '<div id="uploadContent" class="' . $scope . '-bright smallPaddingContent">';
$tokenPrefix = '?' . getSecurityTokenName() . '=' . getSecurityTokenValue();
?>
<script type="text/javascript">
jQuery(document).ready(function(){
window.lam.upload.continueUpload('../misc/ajax.php' + '<?php echo $tokenPrefix; ?>' + '&function=upload&scope=' + '<?php echo $scope ?>');
});
</script>
<?php
echo '</div>';
include '../main_footer.php';
?>

View File

@ -29,16 +29,17 @@ $Id$
*/
/** security functions */
include_once("../lib/security.inc");
include_once("../../lib/security.inc");
/** access to configuration */
include_once('../lib/config.inc');
include_once('../../lib/config.inc');
/** status messages */
include_once('../lib/status.inc');
include_once('../../lib/status.inc');
/** account modules */
include_once('../lib/modules.inc');
include_once('../../lib/modules.inc');
/** Used to get PDF information. */
include_once('../lib/pdfstruct.inc');
include_once('../../lib/pdfstruct.inc');
/** upload functions */
include_once('../../lib/upload.inc');
// Start session
startSecureSession();
@ -53,7 +54,7 @@ checkIfToolIsActive('toolFileUpload');
// Redirect to startpage if user is not loged in
if (!isLoggedIn()) {
metaRefresh("login.php");
metaRefresh("../login.php");
exit;
}
@ -73,7 +74,9 @@ if (isset($_GET['getCSV'])) {
exit;
}
include 'main_header.php';
LAM\UPLOAD\Uploader::cleanSession();
include '../main_header.php';
// get possible types and remove those which do not support file upload
$types = $_SESSION['config']->get_ActiveTypes();
@ -173,7 +176,7 @@ for ($i = 0; $i < sizeof($types); $i++) {
$module = moduleCache::getModule($modules[$m], $types[$i]);
$iconImage = $module->getIcon();
if (!is_null($iconImage) && !(strpos($iconImage, 'http') === 0) && !(strpos($iconImage, '/') === 0)) {
$iconImage = '../graphics/' . $iconImage;
$iconImage = '../../graphics/' . $iconImage;
}
$innerTable->addElement(new htmlImage($iconImage));
$enabled = true;
@ -223,7 +226,7 @@ function changeVisibleModules(element) {
echo "</form>\n";
echo '</div>';
include 'main_footer.php';
include '../main_footer.php';
/**
* Displays the acount type specific main page of the upload.
@ -253,7 +256,7 @@ function showMainPage($scope, $selectedModules) {
$inputContainer->addElement(new htmlOutputText(_("CSV file")));
$inputContainer->addElement(new htmlInputFileUpload('inputfile'));
$inputContainer->addElement(new htmlSpacer('10px', null));
$inputContainer->addElement(new htmlLink(_("Download sample CSV file"), 'masscreate.php?getCSV=1', '../graphics/save.png', true));
$inputContainer->addElement(new htmlLink(_("Download sample CSV file"), 'masscreate.php?getCSV=1', '../../graphics/save.png', true));
$inputContainer->addElement(new htmlHiddenInput('scope', $scope));
$inputContainer->addElement(new htmlHiddenInput('selectedModules', implode(',', $selectedModules)), true);
// PDF
@ -285,7 +288,7 @@ function showMainPage($scope, $selectedModules) {
$columnContainer = new htmlTable();
$columnContainer->setCSSClasses(array($scope . 'list', 'collapse'));
// DN options
$dnTitle = new htmlSubTitle(_("DN settings"), '../graphics/logo32.png');
$dnTitle = new htmlSubTitle(_("DN settings"), '../../graphics/logo32.png');
$dnTitle->colspan = 20;
$columnContainer->addElement($dnTitle, true);
$columnContainer->addElement($columnSpacer);
@ -357,7 +360,7 @@ function showMainPage($scope, $selectedModules) {
$module = moduleCache::getModule($modules[$m], $scope);
$icon = $module->getIcon();
if (($icon != null) && !(strpos($icon, 'http') === 0) && !(strpos($icon, '/') === 0)) {
$icon = '../graphics/' . $icon;
$icon = '../../graphics/' . $icon;
}
$moduleTitle = new htmlSubTitle(getModuleAlias($modules[$m], $scope), $icon);
$moduleTitle->colspan = 20;
@ -473,7 +476,7 @@ function showMainPage($scope, $selectedModules) {
$_SESSION['mass_csv'] = $sampleCSV;
echo '</div>';
include 'main_footer.php';
include '../main_footer.php';
die;
}