diff --git a/CHANGELOG b/CHANGELOG index 03e78611e..91da876b4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -290,6 +290,12 @@ - documents can be updated by dragging a file on a document list item - dragging a folder on a folder list item oder the drag and drop area will recursively upload the folder hierarchy including all files +- fix checking if user is owner when sending notifications +- do not show fast upload area if access on folder is insufficient +- do not send notification mail 'submitted review/approval' to owner of + document, still send it to uploader of version +- set default language in login form if language selector is turned off +- do not show full list of notifiers to none admins -------------------------------------------------------------------------------- Changes in version 5.1.33 diff --git a/inc/inc.ClassDbAuthentication.php b/inc/inc.ClassDbAuthentication.php index 2d65e8516..0c7eaad4f 100644 --- a/inc/inc.ClassDbAuthentication.php +++ b/inc/inc.ClassDbAuthentication.php @@ -47,6 +47,11 @@ class SeedDMS_DbAuthentication extends SeedDMS_Authentication { if($user = $dms->getUserByLogin($username)) { $userid = $user->getID(); + // Check if password matches + if (!seed_pass_verify($password, $user->getPwd())) { + $user = null; + } + } elseif(!empty($this->settings->_enableLoginByEmail) && ($user = $dms->getUserByEmail($username))) { // Check if password matches if (!seed_pass_verify($password, $user->getPwd())) { $user = null; diff --git a/inc/inc.ClassLdapAuthentication.php b/inc/inc.ClassLdapAuthentication.php index ff4eb17b9..db9ae1449 100644 --- a/inc/inc.ClassLdapAuthentication.php +++ b/inc/inc.ClassLdapAuthentication.php @@ -126,14 +126,16 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { * look like if searching for that user didn't return a dn. */ if (isset($settings->_ldapBaseDN)) { - $ldapSearchAttribut = "uid="; + $ldapSearchAttribut = "uid"; + /* $tmpDN will only be used as a last resort if searching for the user failed */ $tmpDN = "uid=".$username.",".$settings->_ldapBaseDN; } /* Active directory has a different base dn */ if (isset($settings->_ldapType)) { if ($settings->_ldapType==1) { - $ldapSearchAttribut = "sAMAccountName="; + $ldapSearchAttribut = "sAMAccountName"; + /* $tmpDN will only be used as a last resort if searching for the user failed */ $tmpDN = $username.'@'.$settings->_ldapAccountDomainName; // Add the following if authentication with an Active Dir doesn't work // See https://sourceforge.net/p/seeddms/discussion/general/thread/19c70d8d/ @@ -155,7 +157,21 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { } else { $bind = @ldap_bind($ds); } + $dn = false; + + /* The simplest search is just the username */ + $ldapsearchterm = $ldapSearchAttribut.'='.$username; + /* If login by email is allowed, the search for user name is ored with + * the search for the email. + */ + if($settings->_enableLoginByEmail) { + $ldapsearchterm = "|(".$ldapsearchterm.")(mail=".$username.")"; + } + /* If a ldap filter is set, it will be anded */ + if($settings->_ldapFilter) { + $ldapsearchterm = "&(".$ldapsearchterm.")".$settings->_ldapFilter; + } /* If bind succeed, then get the dn of the user. If a filter * is set, it will be used to allow only those users to log in * matching the filter criteria. Depending on the type of server, @@ -163,19 +179,32 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { * 'sAMAccountName=' or 'uid='. All other filters are ANDed. * A common filter is '(mail=*)' to ensure a user has an email * address. + * If the previous bind failed, we could try later to bind with + * the user's credentials (this was until 6.0.26 and 5.1.33 the case), + * but if login by email is allowed, it makes no sense to try it. The + * only way to bind is by using a correct dn and that cannot be + * formed with an email. */ if ($bind) { + /* if (!empty($settings->_ldapFilter)) { - $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.$username.")".$settings->_ldapFilter.")"); + $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.'='.$username.")".$settings->_ldapFilter.")"); } else { - $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.$username); + $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.'='.$username); } + */ + $search = ldap_search($ds, $settings->_ldapBaseDN, "(".$ldapsearchterm.")"); if (!is_bool($search)) { $info = ldap_get_entries($ds, $search); if (!is_bool($info) && $info["count"]>0) { $dn = $info[0]['dn']; + /* Set username to login name in case the email was used for authentication */ + $username = $info[0][$ldapSearchAttribut][0]; } } + } elseif(!empty($settings->_enableLoginByEmail)) { + ldap_close($ds); + return null; } /* If the previous bind failed, try it with the users creditionals @@ -188,8 +217,10 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { * If that user was filtered out, because filter was set to '(mail=*)' * and the user doesn't have a mail address, then $dn will not be * set and $tmpDN will be used instead, allowing a successfull bind. + * Also do not take the $tmpDN if login by email is allowed, because + * the username could be the email and that doesn't form a valid dn. */ - if (is_bool($dn) && empty($settings->_ldapFilter)) { + if (is_bool($dn) && empty($settings->_ldapFilter) && empty($settings->_enableLoginByEmail)) { $dn = $tmpDN; } @@ -201,6 +232,9 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { /* Check if user already exists in the database. Return with an error * only if the sql statements fails, but not if no user was found. + * The username may not be the one passed to this function anymore. It + * could have been overwritten by uid (or sAMAccountName) derived from + * the above ldap search. */ $user = $dms->getUserByLogin($username); if($user === false) { @@ -217,13 +251,15 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication { // Successfully authenticated. Now check to see if the user exists within // the database. If not, add them in if _restricted is not set, - // but do not add their password. + // but do not set the password of the user. if (!$settings->_restricted) { - // Retrieve the user's LDAP information. + /* Retrieve the user's LDAP information. At this time the username is + * the uid or sAMAccountName, even if the email was used for login. + */ if (isset($settings->_ldapFilter) && strlen($settings->_ldapFilter) > 0) { - $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.$username.")".$settings->_ldapFilter.")"); + $search = ldap_search($ds, $settings->_ldapBaseDN, "(&(".$ldapSearchAttribut.'='.$username.")".$settings->_ldapFilter.")"); } else { - $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.$username); + $search = ldap_search($ds, $settings->_ldapBaseDN, $ldapSearchAttribut.'='.$username); } if (!is_bool($search)) { diff --git a/inc/inc.ClassNotificationService.php b/inc/inc.ClassNotificationService.php index a02946950..d6050a9a7 100644 --- a/inc/inc.ClassNotificationService.php +++ b/inc/inc.ClassNotificationService.php @@ -439,7 +439,7 @@ class SeedDMS_NotificationService { * the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ - if($user->getID() != $version->getUser()->getID() && $version->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($version->getUser(), $nl['users'])) + if($user->getID() != $version->getUser()->getID() && $version->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($version->getUser(), $nl['users'])) $this->toIndividual($user, $version->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } /* }}} */ @@ -573,12 +573,12 @@ class SeedDMS_NotificationService { * the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ - if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) + if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } /* }}} */ /** - * This notification is sent when a new attachment is created. + * This notification is sent when an attachment is deleted. */ public function sendDeleteFileMail($file, $user) { /* {{{ */ $document = $file->getDocument(); @@ -816,10 +816,10 @@ class SeedDMS_NotificationService { $params['sitename'] = $this->settings->_siteName; $params['http_root'] = $this->settings->_httpRoot; - // if user is not owner send notification to owner - if ($user->getID() != $document->getOwner()->getID() && - false === SeedDMS_Core_DMS::inList($document->getOwner(), $notifyList['users'])) { - $this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER); + // if user is not uploader of the version send notification to uploader + if ($user->getID() != $content->getUser()->getID() && + false === SeedDMS_Core_DMS::inList($content->getUser(), $notifyList['users'])) { + $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } $this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION); foreach ($notifyList["groups"] as $grp) { @@ -1013,7 +1013,7 @@ class SeedDMS_NotificationService { * the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ - if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) + if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } /* }}} */ @@ -1125,14 +1125,16 @@ class SeedDMS_NotificationService { /* Send mail to owner only if the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ + /* if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users'])) $this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER); + */ /* Send mail to uploader of version only if the uploader is not the owner and * the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ - if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) + if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } /* }}} */ @@ -1161,14 +1163,16 @@ class SeedDMS_NotificationService { /* Send mail to owner only if the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ + /* if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users'])) $this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER); + */ /* Send mail to uploader of version only if the uploader is not the owner and * the currently logged in user is not the * owner and the owner is not already in the list of notifiers. */ - if($user->getID() != $content->getUser()->getID() && $content->getUser()->getID() != $document->getOwner() && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) + if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users'])) $this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER); } /* }}} */ diff --git a/inc/inc.ClassSettings.php b/inc/inc.ClassSettings.php index 7202f8a6d..cfaca62a9 100644 --- a/inc/inc.ClassSettings.php +++ b/inc/inc.ClassSettings.php @@ -47,6 +47,8 @@ class Settings { /* {{{ */ var $_enableGuestAutoLogin = false; // Set to true for 2-factor Authentication var $_enable2FactorAuthentication = false; + // If you want to allow login by email, set the following to true + var $_enableLoginByEmail = false; // Allow users to reset their password var $_enablePasswordForgotten = false; // Do not allow users to change password @@ -680,6 +682,7 @@ class Settings { /* {{{ */ $this->_enableGuestLogin = Settings::boolVal($tab["enableGuestLogin"]); $this->_enableGuestAutoLogin = Settings::boolVal($tab["enableGuestAutoLogin"]); $this->_enable2FactorAuthentication = Settings::boolVal($tab["enable2FactorAuthentication"]); + $this->_enableLoginByEmail = Settings::boolVal($tab["enableLoginByEmail"]); $this->_enablePasswordForgotten = Settings::boolVal($tab["enablePasswordForgotten"]); $this->_passwordStrength = intval($tab["passwordStrength"]); $this->_passwordStrengthAlgorithm = strval($tab["passwordStrengthAlgorithm"]); @@ -1084,6 +1087,7 @@ class Settings { /* {{{ */ $this->setXMLAttributValue($node, "enableGuestLogin", $this->_enableGuestLogin); $this->setXMLAttributValue($node, "enableGuestAutoLogin", $this->_enableGuestAutoLogin); $this->setXMLAttributValue($node, "enable2FactorAuthentication", $this->_enable2FactorAuthentication); + $this->setXMLAttributValue($node, "enableLoginByEmail", $this->_enableLoginByEmail); $this->setXMLAttributValue($node, "enablePasswordForgotten", $this->_enablePasswordForgotten); $this->setXMLAttributValue($node, "passwordStrength", $this->_passwordStrength); $this->setXMLAttributValue($node, "passwordStrengthAlgorithm", $this->_passwordStrengthAlgorithm); diff --git a/inc/inc.Language.php b/inc/inc.Language.php index 8a31c22c1..3cbdf965f 100644 --- a/inc/inc.Language.php +++ b/inc/inc.Language.php @@ -404,10 +404,24 @@ function getAttributeValidationText($error, $attrname='', $attrvalue='', $regex= } /* }}} */ function getAttributeValidationError($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */ + if(is_object($attrvalue)) + $attrvalue = $attrvalue->getId(); switch($error) { - case 10: + case 14: return array("attr_not_in_valueset", array('attrname'=>$attrname, 'value'=>$attrvalue)); break; + case 13: + return array("attr_not_a_group", array('attrname'=>$attrname, 'value'=>$attrvalue)); + break; + case 12: + return array("attr_not_a_user", array('attrname'=>$attrname, 'value'=>$attrvalue)); + break; + case 11: + return array("attr_not_a_folder", array('attrname'=>$attrname, 'value'=>$attrvalue)); + break; + case 10: + return array("attr_not_a_document", array('attrname'=>$attrname, 'value'=>$attrvalue)); + break; case 9: return array("attr_malformed_date", array('attrname'=>$attrname, 'value'=>$attrvalue)); break; diff --git a/op/op.Ajax.php b/op/op.Ajax.php index 14dd3b617..3e66aba9e 100644 --- a/op/op.Ajax.php +++ b/op/op.Ajax.php @@ -122,7 +122,8 @@ switch($command) { foreach($hits['docs'] as $hit) { if($hit->getAccessMode($user, 'search') >= M_READ) { if($hit->getLatestContent()) { - $result[] = $hit->getID().'#'.$hit->getName(); + //$result[] = $hit->getID().'#'.$hit->getName(); + $result[] = array('type'=>'D', 'id'=>$hit->getId(), 'name'=>htmlspecialchars($hit->getName()), 'path'=>htmlspecialchars($hit->getParent()->getFolderPathPlain(true, '/'))); } } } diff --git a/op/op.AttributeMgr.php b/op/op.AttributeMgr.php index 24b94a0eb..8eccffc1d 100644 --- a/op/op.AttributeMgr.php +++ b/op/op.AttributeMgr.php @@ -73,8 +73,13 @@ if ($action == "addattrdef") { if($minvalues > $maxvalues) { UI::exitError(getMLText("admin_tools"),getMLText("attrdef_min_greater_max")); } - if($multiple && $valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) { - UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset")); + if($multiple) { + if(in_array($type, array(SeedDMS_Core_AttributeDefinition::type_document, SeedDMS_Core_AttributeDefinition::type_folder))) { + UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_but_doc_or_folder")); + } + if($valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) { + UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset")); + } } $controller->setParam('name', $name); @@ -150,8 +155,13 @@ else if ($action == "editattrdef") { if($minvalues > $maxvalues) { UI::exitError(getMLText("admin_tools"),getMLText("attrdef_min_greater_max")); } - if($multiple && $valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) { - UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset")); + if($multiple) { + if(in_array($type, array(SeedDMS_Core_AttributeDefinition::type_document, SeedDMS_Core_AttributeDefinition::type_folder))) { + UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_but_doc_or_folder")); + } + if($valueset == '' && !in_array($type, array(SeedDMS_Core_AttributeDefinition::type_user, SeedDMS_Core_AttributeDefinition::type_group))) { + UI::exitError(getMLText("admin_tools"),getMLText("attrdef_multiple_needs_valueset")); + } } $controller->setParam('name', $name); diff --git a/op/op.DocumentNotify.php b/op/op.DocumentNotify.php index e0ba58116..2ba2a5d64 100644 --- a/op/op.DocumentNotify.php +++ b/op/op.DocumentNotify.php @@ -52,37 +52,39 @@ $action = $_POST["action"]; if (isset($_POST["userid"]) && (!is_numeric($_POST["userid"]) || $_POST["userid"]<-1)) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("unknown_user")); } +$userid = isset($_POST["userid"]) ? $_POST["userid"] : -1; -$userid = 0; -if(isset($_POST["userid"])) - $userid = $_POST["userid"]; +if ($userid > 0){ + $u=$dms->getUser($userid); + if (($u->getId() != $user->getId()) && !$user->isAdmin()) + UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied")); +} if (isset($_POST["groupid"]) && (!is_numeric($_POST["groupid"]) || $_POST["groupid"]<-1)) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("unknown_group")); } -if(isset($_POST["groupid"])) - $groupid = $_POST["groupid"]; +$groupid = isset($_POST["groupid"]) ? $_POST["groupid"] : -1; -if (isset($_POST["groupid"])&&$_POST["groupid"]!=-1){ +if ($groupid > 0){ $group=$dms->getGroup($groupid); if (!$group->isMember($user,true) && !$user->isAdmin()) UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied")); } $folder = $document->getFolder(); -$docPathHTML = getFolderPathHTML($folder, true). " / ".$document->getName().""; if ($document->getAccessMode($user) < M_READ) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied")); } // delete notification -if ($action == "delnotify"){ - if ($userid) { +if ($action == "delnotify") { + + if ($userid > 0) { $obj = $dms->getUser($userid); $res = $document->removeNotify($userid, true); - } elseif (isset($groupid)) { + } elseif ($groupid > 0) { $obj = $dms->getGroup($groupid); $res = $document->removeNotify($groupid, false); } @@ -137,7 +139,7 @@ else if ($action == "addnotify") { break; } } - if ($groupid != -1) { + if ($groupid > 0) { $res = $document->addNotify($groupid, false); switch ($res) { case -1: diff --git a/op/op.FolderNotify.php b/op/op.FolderNotify.php index 903b9dc03..4156e00f1 100644 --- a/op/op.FolderNotify.php +++ b/op/op.FolderNotify.php @@ -53,19 +53,24 @@ if (isset($_POST["userid"]) && (!is_numeric($_POST["userid"]) || $_POST["userid" } $userid = isset($_POST["userid"]) ? $_POST["userid"] : -1; +if ($userid > 0){ + $u=$dms->getUser($userid); + if (($u->getId() != $user->getId()) && !$user->isAdmin()) + UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied")); +} + if (isset($_POST["groupid"]) && (!is_numeric($_POST["groupid"]) || $_POST["groupid"]<-1)) { UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("unknown_group")); } + $groupid = isset($_POST["groupid"]) ? $_POST["groupid"] : -1; -if (isset($_POST["groupid"])&&$_POST["groupid"]!=-1){ +if ($groupid > 0){ $group=$dms->getGroup($groupid); if (!$group->isMember($user,true) && !$user->isAdmin()) UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied")); } -$folderPathHTML = getFolderPathHTML($folder, true); - if ($folder->getAccessMode($user) < M_READ) { UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("access_denied")); } @@ -74,12 +79,11 @@ if ($folder->getAccessMode($user) < M_READ) { if ($action == "delnotify") { if ($userid > 0) { - $res = $folder->removeNotify($userid, true); $obj = $dms->getUser($userid); - } - elseif ($groupid > 0) { - $res = $folder->removeNotify($groupid, false); + $res = $folder->removeNotify($userid, true); + } elseif ($groupid > 0) { $obj = $dms->getGroup($groupid); + $res = $folder->removeNotify($groupid, false); } switch ($res) { case -1: @@ -106,7 +110,7 @@ if ($action == "delnotify") { // Add notification ---------------------------------------------------------- else if ($action == "addnotify") { - if ($userid != -1) { + if ($userid > 0) { $res = $folder->addNotify($userid, true); switch ($res) { case -1: @@ -132,7 +136,7 @@ else if ($action == "addnotify") { break; } } - if ($groupid != -1) { + if ($groupid > 0) { $res = $folder->addNotify($groupid, false); switch ($res) { case -1: diff --git a/op/op.Settings.php b/op/op.Settings.php index 6ab984b32..8e9b46bf2 100644 --- a/op/op.Settings.php +++ b/op/op.Settings.php @@ -198,6 +198,7 @@ if ($action == "saveSettings") setBoolValue("enableGuestLogin"); setBoolValue("enableGuestAutoLogin"); setBoolValue("enable2FactorAuthentication"); + setBoolValue("enableLoginByEmail"); setBoolValue("restricted"); setBoolValue("enableUserImage"); setBoolValue("disableSelfEdit"); diff --git a/out/out.DocumentNotify.php b/out/out.DocumentNotify.php index 0dbf70976..d40d97c18 100644 --- a/out/out.DocumentNotify.php +++ b/out/out.DocumentNotify.php @@ -55,6 +55,7 @@ if($view) { $view->setParam('folder', $folder); $view->setParam('document', $document); $view->setParam('sortusersinlist', $settings->_sortUsersInList); + $view->setParam('enableusersview', $settings->_enableUsersView); $view->setParam('accessobject', $accessop); $view($_GET); exit; diff --git a/out/out.FolderNotify.php b/out/out.FolderNotify.php index 7117d6fc4..03c472df2 100644 --- a/out/out.FolderNotify.php +++ b/out/out.FolderNotify.php @@ -27,6 +27,7 @@ require_once("inc/inc.Init.php"); require_once("inc/inc.Extension.php"); require_once("inc/inc.DBInit.php"); require_once("inc/inc.ClassUI.php"); +require_once("inc/inc.ClassAccessOperation.php"); require_once("inc/inc.Authentication.php"); $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); @@ -36,6 +37,7 @@ $accessop = new SeedDMS_AccessOperation($dms, $user, $settings); if (!isset($_GET["folderid"]) || !is_numeric($_GET["folderid"]) || intval($_GET["folderid"])<1) { UI::exitError(getMLText("folder_title", array("foldername" => getMLText("invalid_folder_id"))),getMLText("invalid_folder_id")); } + $folder = $dms->getFolder($_GET["folderid"]); if (!is_object($folder)) { @@ -46,16 +48,15 @@ if ($folder->getAccessMode($user) < M_READ) { UI::exitError(getMLText("folder_title", array("foldername" => htmlspecialchars($folder->getName()))),getMLText("access_denied")); } -$allUsers = $dms->getAllUsers($settings->_sortUsersInList); -$allGroups = $dms->getAllGroups(); +/* Create object for checking access to certain operations */ +$accessop = new SeedDMS_AccessOperation($dms, null, $user, $settings); if($view) { $view->setParam('showtree', showtree()); $view->setParam('folder', $folder); - $view->setParam('allusers', $allUsers); - $view->setParam('allgroups', $allGroups); - $view->setParam('accessobject', $accessop); + $view->setParam('enableusersview', $settings->_enableUsersView); $view->setParam('sortusersinlist', $settings->_sortUsersInList); + $view->setParam('accessobject', $accessop); $view($_GET); exit; } diff --git a/out/out.Login.php b/out/out.Login.php index d929c81b7..ce2f4c281 100644 --- a/out/out.Login.php +++ b/out/out.Login.php @@ -60,6 +60,7 @@ if($view) { $view->setParam('enablelanguageselector', $settings->_enableLanguageSelector); $view->setParam('enablethemeselector', $settings->_enableThemeSelector); $view->setParam('enable2factauth', $settings->_enable2FactorAuthentication); + $view->setParam('defaultlanguage', $settings->_language); $view($_GET); exit; } diff --git a/restapi/index.php b/restapi/index.php index d99ce0f1e..f9971ad41 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -728,13 +728,13 @@ class RestapiController { /* {{{ */ if($settings->_workflowMode == 'traditional' || $settings->_workflowMode == 'traditional_only_approval') { // add mandatory reviewers/approvers if($settings->_workflowMode == 'traditional') { - $mreviewers = getMandatoryReviewers($mfolder, $userobj); + $mreviewers = getMandatoryReviewers($mfolder, null, $userobj); if($mreviewers['i']) $reviewers['i'] = array_merge($reviewers['i'], $mreviewers['i']); if($mreviewers['g']) $reviewers['g'] = array_merge($reviewers['g'], $mreviewers['g']); } - $mapprovers = getMandatoryApprovers($mfolder, $userobj); + $mapprovers = getMandatoryApprovers($mfolder, null, $userobj); if($mapprovers['i']) $approvers['i'] = array_merge($approvers['i'], $mapprovers['i']); if($mapprovers['g']) diff --git a/views/bootstrap/class.AttributeMgr.php b/views/bootstrap/class.AttributeMgr.php index 0a9455911..9e9b78582 100644 --- a/views/bootstrap/class.AttributeMgr.php +++ b/views/bootstrap/class.AttributeMgr.php @@ -142,10 +142,14 @@ $(document).ready( function() { print $this->folderListHeader(); print "\n"; foreach($res['folders'] as $subFolder) { - echo $this->folderListRow($subFolder); + $extracontent = array(); + $extracontent['below_title'] = $this->getListRowPath($subFolder); + echo $this->folderListRow($subFolder, false, $extracontent); } foreach($res['docs'] as $document) { - echo $this->documentListRow($document, $previewer); + $extracontent = array(); + $extracontent['below_title'] = $this->getListRowPath($document); + echo $this->documentListRow($document, $previewer, false, 0, $extracontent); } echo "\n\n"; @@ -161,7 +165,9 @@ $(document).ready( function() { print "\n\n\n"; foreach($res['contents'] as $content) { $doc = $content->getDocument(); - echo $this->documentListRow($doc, $previewer); + $extracontent = array(); + $extracontent['below_title'] = $this->getListRowPath($doc); + echo $this->documentListRow($doc, $previewer, false, 0, $extracontent); } print ""; } diff --git a/views/bootstrap/class.Bootstrap.php b/views/bootstrap/class.Bootstrap.php index b5caed06d..6763c879f 100644 --- a/views/bootstrap/class.Bootstrap.php +++ b/views/bootstrap/class.Bootstrap.php @@ -796,8 +796,8 @@ background-image: linear-gradient(to bottom, #882222, #111111);; if ($accessobject->check_view_access('FolderAccess')) $menuitems['edit_folder_access'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderAccess.php?folderid=".$folderID."&showtree=".showtree(), 'label'=>getMLText('edit_folder_access')); } - if ($accessobject->check_controller_access('FolderNotify')) - $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_existing_notify')); + if ($accessobject->check_view_access('FolderNotify')) + $menuitems['edit_folder_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_folder_notify')); } if($enableClipboard) { $menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'F'.$folder->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard")); @@ -877,7 +877,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if ($accessMode >= M_READ && !$this->params['user']->isGuest()) { if ($accessobject->check_view_access('DocumentNotify')) - $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_existing_notify')); + $menuitems['edit_document_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_document_notify')); } if($enableClipboard) { $menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'D'.$document->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard")); diff --git a/views/bootstrap/class.DocumentNotify.php b/views/bootstrap/class.DocumentNotify.php index a6463abcf..207b5efa2 100644 --- a/views/bootstrap/class.DocumentNotify.php +++ b/views/bootstrap/class.DocumentNotify.php @@ -70,6 +70,7 @@ $(document).ready( function() { $folder = $this->params['folder']; $document = $this->params['document']; $sortusersinlist = $this->params['sortusersinlist']; + $enableusersview = $this->params['enableusersview']; $notifyList = $document->getNotifyList(0, true); @@ -151,10 +152,10 @@ $(document).ready( function() { } else { print "\n"; foreach ($notifyList["users"] as $userNotify) { - print ""; - print ""; - print ""; - if ($user->isAdmin() || $user->getID() == $userNotify->getID()) { + if ($user->isAdmin() || /*$enableusersview || */$user->getID() == $userNotify->getID()) { + print ""; + print ""; + print ""; print "\n"; echo createHiddenFieldWithKey('documentnotify')."\n"; print "getID()."\">\n"; @@ -164,14 +165,15 @@ $(document).ready( function() { print ""; print ""; print "\n"; - }else print ""; - print ""; + print ""; + } } foreach ($notifyList["groups"] as $groupNotify) { - print ""; - print ""; - print ""; - if ($user->isAdmin() || $groupNotify->isMember($user,true)) { + /* admins and members of a group may see exiting notifications */ + if ($user->isAdmin() || /*$enableusersview || */$groupNotify->isMember($user,false)) { + print ""; + print ""; + print ""; print "\n"; echo createHiddenFieldWithKey('documentnotify')."\n"; print "getID()."\">\n"; @@ -181,8 +183,8 @@ $(document).ready( function() { print ""; print ""; print "\n"; - }else print ""; - print ""; + print ""; + } } print "
" . htmlspecialchars($userNotify->getLogin() . " - " . $userNotify->getFullName()) . "
" . htmlspecialchars($userNotify->getLogin() . " - " . $userNotify->getFullName()) . "
" . htmlspecialchars($groupNotify->getName()) . "
" . htmlspecialchars($groupNotify->getName()) . "
\n"; } diff --git a/views/bootstrap/class.FolderNotify.php b/views/bootstrap/class.FolderNotify.php index 56a7a5961..d9f5cbeb2 100644 --- a/views/bootstrap/class.FolderNotify.php +++ b/views/bootstrap/class.FolderNotify.php @@ -67,9 +67,8 @@ $(document).ready(function() { $dms = $this->params['dms']; $user = $this->params['user']; $folder = $this->params['folder']; - $allUsers = $this->params['allusers']; - $allGroups = $this->params['allgroups']; $sortusersinlist = $this->params['sortusersinlist']; + $enableusersview = $this->params['enableusersview']; $notifyList = $folder->getNotifyList(0, true); @@ -151,10 +150,10 @@ $(document).ready(function() { } else { print "\n"; foreach ($notifyList["users"] as $userNotify) { - print ""; - print ""; - print ""; - if ($user->isAdmin() || $user->getID() == $userNotify->getID()) { + if ($user->isAdmin() || /*$enableusersview || */$user->getID() == $userNotify->getID()) { + print ""; + print ""; + print ""; print "\n"; echo createHiddenFieldWithKey('foldernotify')."\n"; print "getID()."\">\n"; @@ -164,14 +163,15 @@ $(document).ready(function() { print ""; print ""; print "\n"; - }else print ""; - print ""; + print ""; + } } foreach ($notifyList["groups"] as $groupNotify) { - print ""; - print ""; - print ""; - if ($user->isAdmin() || $groupNotify->isMember($user,true)) { + /* admins and members of a group may see exiting notifications */ + if ($user->isAdmin() || /*$enableusersview || */$groupNotify->isMember($user,false)) { + print ""; + print ""; + print ""; print "\n"; echo createHiddenFieldWithKey('foldernotify')."\n"; print "getID()."\">\n"; @@ -181,8 +181,8 @@ $(document).ready(function() { print ""; print ""; print "\n"; - }else print ""; - print ""; + print ""; + } } print "
" . htmlspecialchars($userNotify->getLogin() . " - " . $userNotify->getFullName()) . "
" . htmlspecialchars($userNotify->getLogin() . " - " . $userNotify->getFullName()) . "
" . htmlspecialchars($groupNotify->getName()) . "
" . htmlspecialchars($groupNotify->getName()) . "
\n"; } diff --git a/views/bootstrap/class.GroupMgr.php b/views/bootstrap/class.GroupMgr.php index 851ce24e4..667e7b9c4 100644 --- a/views/bootstrap/class.GroupMgr.php +++ b/views/bootstrap/class.GroupMgr.php @@ -208,7 +208,7 @@ $(document).ready( function() { print ""; print ""; - print "" . htmlspecialchars($member->getFullName()) . ""; + print "" . htmlspecialchars($member->getFullName()." (".$member->getLogin().")") ."
".htmlspecialchars($member->getEmail()). ""; print "" . ($group->isMember($member,true)?getMLText("manager"):" ") . ""; print ""; print "
getID()."\" />getID()."\" />".createHiddenFieldWithKey('rmmember')."
"; diff --git a/views/bootstrap/class.GroupView.php b/views/bootstrap/class.GroupView.php index 8e7745a3c..d4070eea4 100644 --- a/views/bootstrap/class.GroupView.php +++ b/views/bootstrap/class.GroupView.php @@ -79,14 +79,14 @@ $(document).ready( function() { foreach ($members as $member) { $memberids[] = $member->getId(); - echo "
  • ".htmlspecialchars($member->getFullName()); + echo "
  • ".htmlspecialchars($member->getFullName().", ".$member->getLogin()); if ($member->getEmail()!="") echo " (getEmail())."\">".htmlspecialchars($member->getEmail()).")"; foreach($managers as $manager) if($manager->getId() == $member->getId()) echo ", ".getMLText("manager"); if($ismanager && $member->getId() != $user->getId()) { - echo ' '.getMLText("rm_user").''; + echo ' '.getMLText("rm_user").''; } echo "
  • "; } diff --git a/views/bootstrap/class.Login.php b/views/bootstrap/class.Login.php index 52f87d95e..2914de462 100644 --- a/views/bootstrap/class.Login.php +++ b/views/bootstrap/class.Login.php @@ -88,6 +88,7 @@ $(document).ready( function() { $themes = $this->params['themes']; $msg = $this->params['msg']; $languages = $this->params['languages']; + $defaultlanguage = $this->params['defaultlanguage']; $enableLanguageSelector = $this->params['enablelanguageselector']; $enableThemeSelector = $this->params['enablethemeselector']; $enable2factauth = $this->params['enable2factauth']; @@ -162,6 +163,8 @@ $(document).ready( function() { 'options'=>$options ) ); + } elseif($defaultlanguage) { + echo ""; } if($enableThemeSelector) { $options = array(); diff --git a/views/bootstrap/class.Settings.php b/views/bootstrap/class.Settings.php index 989f2a425..64d0c581e 100644 --- a/views/bootstrap/class.Settings.php +++ b/views/bootstrap/class.Settings.php @@ -499,6 +499,7 @@ if(($kkk = $this->callHook('getFullSearchEngine')) && is_array($kkk)) showConfigCheckbox('settings_enableGuestLogin', 'enableGuestLogin'); ?> showConfigCheckbox('settings_enableGuestAutoLogin', 'enableGuestAutoLogin'); ?> showConfigCheckbox('settings_enable2FactorAuthentication', 'enable2FactorAuthentication'); ?> +showConfigCheckbox('settings_enableLoginByEmail', 'enableLoginByEmail'); ?> showConfigCheckbox('settings_restricted', 'restricted'); ?> showConfigCheckbox('settings_enableUserImage', 'enableUserImage'); ?> showConfigCheckbox('settings_disableSelfEdit', 'disableSelfEdit'); ?> diff --git a/views/bootstrap/class.ViewDocument.php b/views/bootstrap/class.ViewDocument.php index 816103d72..121b5910a 100644 --- a/views/bootstrap/class.ViewDocument.php +++ b/views/bootstrap/class.ViewDocument.php @@ -1944,7 +1944,9 @@ $(document).ready( function() { if(is_string($txt)) echo $txt; else { - echo $this->documentListRow($targetDoc, $previewer, true); + $extracontent = array(); + $extracontent['below_title'] = $this->getListRowPath($targetDoc); + echo $this->documentListRow($targetDoc, $previewer, true, 0, $extracontent); } print ""; print getMLText("document_link_by")." ".htmlspecialchars($responsibleUser->getFullName()); @@ -2010,7 +2012,9 @@ $(document).ready( function() { if(is_string($txt)) echo $txt; else { - echo $this->documentListRow($sourceDoc, $previewer, true); + $extracontent = array(); + $extracontent['below_title'] = $this->getListRowPath($sourceDoc); + echo $this->documentListRow($sourceDoc, $previewer, true, 0, $extracontent); } print ""; if (($user->getID() == $responsibleUser->getID()) || ($document->getAccessMode($user) == M_ALL )) diff --git a/views/bootstrap/class.ViewFolder.php b/views/bootstrap/class.ViewFolder.php index 30ad20424..37b39bed8 100644 --- a/views/bootstrap/class.ViewFolder.php +++ b/views/bootstrap/class.ViewFolder.php @@ -474,13 +474,13 @@ $('body').on('click', '.order-btn', function(ev) { $folder = $this->params['folder']; $maxuploadsize = $this->params['maxuploadsize']; - $this->contentHeading(getMLText("dropupload"), true); if ($folder->getAccessMode($user) >= M_READWRITE) { + $this->contentHeading(getMLText("dropupload"), true); ?>
    SeedDMS_Core_File::format_filesize($maxuploadsize)]); ?>
    errorMsg(getMLText('access_denied')); + //$this->errorMsg(getMLText('access_denied')); } } /* }}} */ diff --git a/views/bootstrap/styles/application.js b/views/bootstrap/styles/application.js index c03ec5225..a5d2133f1 100644 --- a/views/bootstrap/styles/application.js +++ b/views/bootstrap/styles/application.js @@ -186,21 +186,42 @@ function initMost() { }); }, /* updater is called when the item in the list is clicked. It is - * actually provided to update the input field where you type, but here - * we use it to update a second input field with the doc id. */ + * provided to update the input field where you type. */ updater: function (item) { - strarr = item.value.split("#"); target = this.$element.data('target'); - $('#'+target).attr('value', strarr[0]); - return strarr[1]; + $('#'+target).attr('value', item.id); + return item.value; + }, + sorter: function(items) { + return items; }, /* Set a matcher that allows any returned value */ matcher : function (item) { return true; }, highlighter : function (item) { - strarr = item.split("#"); - return ' ' + strarr[1].replace(/ ' + item.name.replace(/' + item.path + '' : ''); + }, + /* This only works with a modified version of bootstrap typeahead located + * in boostrap-typeahead.js Search for 'render' + * The line + * this.render = this.options.render || this.render + * was added to bootstrap-typeahead.js + * The following function is a copy of the original render function but + * access item.name instead of item + */ + render : function (items) { + var that = this + + items = $(items).map(function (i, item) { + i = $(that.options.item).attr('data-value', item.name).attr('data-id', item.id).attr('data-type', item.type); + i.find('a').html(that.highlighter(item)) + return i[0] + }) + + items.first().addClass('active') + this.$menu.html(items) + return this } }); /* }}} */ diff --git a/views/bootstrap4/class.Bootstrap4.php b/views/bootstrap4/class.Bootstrap4.php index 8003e2adc..7a2fe40b1 100644 --- a/views/bootstrap4/class.Bootstrap4.php +++ b/views/bootstrap4/class.Bootstrap4.php @@ -727,8 +727,8 @@ background-image: linear-gradient(to bottom, #882222, #111111);; if ($accessobject->check_view_access('FolderAccess')) $menuitems['edit_folder_access'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderAccess.php?folderid=".$folderID."&showtree=".showtree(), 'label'=>getMLText('edit_folder_access')); } - if ($accessobject->check_controller_access('FolderNotify')) - $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_existing_notify')); + if ($accessobject->check_view_access('FolderNotify')) + $menuitems['edit_folder_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.FolderNotify.php?folderid=". $folderID ."&showtree=". showtree(), 'label'=>getMLText('edit_folder_notify')); } if($enableClipboard) { $menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'F'.$folder->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard")); @@ -804,7 +804,7 @@ background-image: linear-gradient(to bottom, #882222, #111111);; } if ($accessMode >= M_READ && !$this->params['user']->isGuest()) { if ($accessobject->check_view_access('DocumentNotify')) - $menuitems['edit_existing_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_existing_notify')); + $menuitems['edit_document_notify'] = array('link'=>$this->params['settings']->_httpRoot."out/out.DocumentNotify". $docid, 'label'=>getMLText('edit_document_notify')); } if($enableClipboard) { $menuitems['add_to_clipboard'] = array('class'=>'addtoclipboard', 'attributes'=>array(['rel', 'D'.$document->getId()], ['msg', getMLText('splash_added_to_clipboard')], ['title', getMLText("add_to_clipboard")]), 'label'=>getMLText("add_to_clipboard")); diff --git a/views/bootstrap4/styles/application.js b/views/bootstrap4/styles/application.js index ae87f474a..d2375d10a 100644 --- a/views/bootstrap4/styles/application.js +++ b/views/bootstrap4/styles/application.js @@ -193,21 +193,42 @@ function initMost() { }); }, /* updater is called when the item in the list is clicked. It is - * actually provided to update the input field where you type, but here - * we use it to update a second input field with the doc id. */ + * provided to update the input field where you type. */ updater: function (item) { - strarr = item.value.split("#"); target = this.$element.data('target'); - $('#'+target).attr('value', strarr[0]); - return strarr[1]; + $('#'+target).attr('value', item.id); + return item.value; + }, + sorter: function(items) { + return items; }, /* Set a matcher that allows any returned value */ matcher : function (item) { return true; }, highlighter : function (item) { - strarr = item.split("#"); - return ' ' + strarr[1].replace(/ ' + item.name.replace(/' + item.path + '' : ''); + }, + /* This only works with a modified version of bootstrap typeahead located + * in boostrap-typeahead.js Search for 'render' + * The line + * this.render = this.options.render || this.render + * was added to bootstrap-typeahead.js + * The following function is a copy of the original render function but + * access item.name instead of item + */ + render : function (items) { + var that = this + + items = $(items).map(function (i, item) { + i = $(that.options.item).attr('data-value', item.name).attr('data-id', item.id).attr('data-type', item.type); + i.find('a').html(that.highlighter(item)) + return i[0] + }) + + items.first().addClass('active') + this.$menu.html(items) + return this } }); /* }}} */