Merge branch 'seeddms-5.1.x' into seeddms-6.0.x

This commit is contained in:
Uwe Steinmann 2020-07-30 11:06:28 +02:00
commit 709d362b02
14 changed files with 151 additions and 49 deletions

View File

@ -1,3 +1,8 @@
--------------------------------------------------------------------------------
Changes in version 6.0.12
--------------------------------------------------------------------------------
- merge changes up to 5.1.19
--------------------------------------------------------------------------------
Changes in version 6.0.11
--------------------------------------------------------------------------------
@ -157,6 +162,12 @@
- add document list which can be exported as an archive
- search results can be exported
--------------------------------------------------------------------------------
Changes in version 5.1.19
--------------------------------------------------------------------------------
- add hooks showDocumentAttribute and showDocumentContentAttribute in Search view
- fix layout problems of select2 menu, add option for adding an icon to each option
--------------------------------------------------------------------------------
Changes in version 5.1.18
--------------------------------------------------------------------------------

View File

@ -472,7 +472,7 @@ class SeedDMS_Core_DMS {
$this->lasterror = '';
$this->version = '@package_version@';
if($this->version[0] == '@')
$this->version = '6.0.11';
$this->version = '6.0.12';
} /* }}} */
/**
@ -824,7 +824,9 @@ class SeedDMS_Core_DMS {
* Returns a document by its name
*
* This function searches a document by its name and restricts the search
* to given folder if passed as the second parameter.
* to the given folder if passed as the second parameter.
* If there are more than one document with that name, then only the first
* one will be returned.
*
* @param string $name
* @param object $folder

View File

@ -15,8 +15,8 @@
<date>2020-06-05</date>
<time>09:43:12</time>
<version>
<release>6.0.11</release>
<api>6.0.11</api>
<release>6.0.12</release>
<api>6.0.12</api>
</version>
<stability>
<release>stable</release>
@ -24,7 +24,7 @@
</stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
SeedDMS_Core_DMS::filterAccess() properly checks for documents
- ???
</notes>
<contents>
<dir baseinstalldir="SeedDMS" name="/">
@ -1802,6 +1802,21 @@ add method SeedDMS_Core_DatabaseAccess::setLogFp()
- fix SeedDMS_Core_DMS::getDocumentByOriginalFilename()
</notes>
</release>
<release>
<date>2020-07-30</date>
<time>09:43:12</time>
<version>
<release>5.1.19</release>
<api>5.1.19</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
</notes>
</release>
<release>
<date>2017-02-28</date>
<time>06:34:50</time>
@ -2036,5 +2051,21 @@ remove a user from all its process can also be used to set a new user
SeedDMS_Core_DocumentContent::delRevisor() returns -4 if user has already made a revision
</notes>
</release>
<release>
<date>2020-06-05</date>
<time>09:43:12</time>
<version>
<release>6.0.11</release>
<api>6.0.11</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/gpl-license">GPL License</license>
<notes>
SeedDMS_Core_DMS::filterAccess() properly checks for documents
</notes>
</release>
</changelog>
</package>

View File

@ -33,12 +33,12 @@ class SeedDMS_Controller_UserListCsv extends SeedDMS_Controller_Common {
$m = max($m, count($u->getGroups()));
}
$fp = fopen("php://temp/maxmemory", 'r+');
$header = array('login', 'name', 'email', 'comment', 'role', 'quota', 'homefolder');
$header = array('login', 'passenc', 'name', 'email', 'comment', 'role', 'quota', 'homefolder');
for($i=1; $i<=$m; $i++)
$header[] = 'group_'.$i;
fputcsv($fp, $header, ';');
foreach($allUsers as $u) {
$data = array($u->getLogin(), $u->getFullName(), $u->getEmail(), $u->getComment(), $u->isAdmin() ? 'admin' : ($u->isGuest() ? 'guest' : 'user'), $u->getQuota(), $u->getHomeFolder() ? $u->getHomeFolder() : '');
$data = array($u->getLogin(), $u->getPwd(), $u->getFullName(), $u->getEmail(), $u->getComment(), $u->isAdmin() ? 'admin' : ($u->isGuest() ? 'guest' : 'user'), $u->getQuota(), $u->getHomeFolder() ? $u->getHomeFolder() : '');
foreach($u->getGroups() as $g)
$data[] = $g->getName();
fputcsv($fp, $data, ';');

View File

@ -58,7 +58,7 @@ class SeedDMS_DbAuthentication extends SeedDMS_Authentication {
// Check if password matches (if not a guest user)
// Assume that the password has been sent via HTTP POST. It would be careless
// (and dangerous) for passwords to be sent via GET.
if (md5($password) != $user->getPwd()) {
if (!seed_pass_verify($password, $user->getPwd())) {
/* if counting of login failures is turned on, then increment its value */
if($settings->_loginFailure) {
$failures = $user->addLoginFailure();

View File

@ -615,7 +615,7 @@ function getBaseUrl() { /* {{{ */
return "http".((isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'],'off')!=0)) ? "s" : "")."://".$_SERVER['HTTP_HOST'];
} /* }}} */
function getToken($length){
function getToken($length){ /* {{{ */
$token = "";
$codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
@ -627,7 +627,27 @@ function getToken($length){
}
return $token;
}
} /* }}} */
/**
* Hash a password
*
* @param string $password
* @return string hashed password
*/
function seed_pass_hash($password) { /* {{{ */
return md5($password);
} /* }}} */
/**
* Verify a password
*
* @param string $password
* @return string hashed password
*/
function seed_pass_verify($password, $hash) { /* {{{ */
return $hash == md5($password);
} /* }}} */
function resolveTask($task) {
global $dms, $user, $settings, $logger;
@ -642,19 +662,19 @@ function resolveTask($task) {
return $task;
}
class SeedDMS_CSRF {
class SeedDMS_CSRF { /* {{{ */
protected $secret;
public function __construct($secret) {
public function __construct($secret) { /* {{{ */
$this->secret = $secret;
}
} /* }}} */
public function create_api_key() {
public function create_api_key() { /* {{{ */
return base64_encode($this->encrypt(time().'|'.$_SERVER['REMOTE_ADDR'])); // !change if you dont want IP check
}
} /* }}} */
public function check_api_key($key, $timeout = 5) {
public function check_api_key($key, $timeout = 5) { /* {{{ */
if (empty($key)) exit('Invalid Key');
$keys = explode('|', $this->decrypt(base64_decode($key)));
@ -664,9 +684,9 @@ class SeedDMS_CSRF {
$keys[0] >= (time() - $timeout) &&
$keys[1] == $_SERVER['REMOTE_ADDR'] // !change if you dont want IP check
);
}
} /* }}} */
public function encrypt($string, $key = 'PrivateKey', $method = 'AES-256-CBC') {
public function encrypt($string, $key = 'PrivateKey', $method = 'AES-256-CBC') { /* {{{ */
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
@ -675,9 +695,9 @@ class SeedDMS_CSRF {
$output = openssl_encrypt($string, $method, $key, 0, $iv);
// encode
return base64_encode($output);
}
} /* }}} */
public function decrypt($string, $key = 'PrivateKey', $method = 'AES-256-CBC') {
public function decrypt($string, $key = 'PrivateKey', $method = 'AES-256-CBC') { /* {{{ */
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
@ -686,8 +706,8 @@ class SeedDMS_CSRF {
$string = base64_decode($string);
// decrypt
return openssl_decrypt($string, $method, $key, 0, $iv);
}
}
} /* }}} */
} /* }}} */
//$CSRF = new SeedDMS_CSRF($settings->_encryptionKey);
//$kkk = $CSRF->create_api_key();

View File

@ -20,7 +20,7 @@
class SeedDMS_Version { /* {{{ */
const _number = "6.0.11";
const _number = "6.0.12";
const _string = "SeedDMS";
function __construct() {

View File

@ -54,7 +54,7 @@ if (empty($newpassword) || empty($newpasswordrepeat) || $newpassword != $newpass
$user = $dms->checkPasswordRequest($hash);
if($user) {
$user->setPwd(md5($newpassword));
$user->setPwd(seed_pass_hash($newpassword));
$dms->deletePasswordRequest($hash);
header('Location: ../out/out.Login.php');
exit;

View File

@ -46,7 +46,7 @@ if(isset($_POST["theme"]))
$mytheme = $_POST["theme"];
$current_pwd = $_POST["currentpwd"];
if($user->getPwd() != md5($current_pwd)) {
if(!seed_pass_verify($current_pwd, $user->getPwd())) {
UI::exitError(getMLText("edit_user_details"),getMLText("password_wrong"));
}
@ -61,14 +61,14 @@ if (isset($_POST["pwd"]) && ($_POST["pwd"] != "")) {
if ($current_pwd == $_POST["pwd"]) // history doesn't have the initial pw stored yet
UI::exitError(getMLText("set_password"),getMLText("password_already_used"));
$phm = new SeedDMS_PasswordHistoryManager($db);
$oldpwd = $phm->search($user, md5($_POST["pwd"]));
$oldpwd = $phm->search($user, seed_pass_hash($_POST["pwd"]));
if($oldpwd) {
UI::exitError(getMLText("set_password"),getMLText("password_already_used"));
} else {
$phm->add($user, md5($_POST["pwd"]));
$phm->add($user, seed_pass_hash($_POST["pwd"]));
}
}
$user->setPwd(md5($_POST["pwd"]));
$user->setPwd(seed_pass_hash($_POST["pwd"]));
$user->setPwdExpiration(date('Y-m-d H:i:s', time()+$settings->_passwordExpiration*86400));
} else {
UI::exitError(getMLText("set_password"),getMLText("password_strength_insuffient"));
@ -76,14 +76,14 @@ if (isset($_POST["pwd"]) && ($_POST["pwd"] != "")) {
} else {
if($settings->_passwordHistory > 0) {
$phm = new SeedDMS_PasswordHistoryManager($db);
$oldpwd = $phm->search($user, md5($_POST["pwd"]));
$oldpwd = $phm->search($user, seed_pass_hash($_POST["pwd"]));
if($oldpwd) {
UI::exitError(getMLText("set_password"),getMLText("password_already_used"));
} else {
$phm->add($user, md5($_POST["pwd"]));
$phm->add($user, seed_pass_hash($_POST["pwd"]));
}
}
$user->setPwd(md5($_POST["pwd"]));
$user->setPwd(seed_pass_hash($_POST["pwd"]));
$user->setPwdExpiration(date('Y-m-d H:i:s', time()+$settings->_passwordExpiration*86400));
}
}

View File

@ -31,6 +31,11 @@ function getBaseData($colname, $coldata, $objdata) { /* {{{ */
return $objdata;
} /* }}} */
function getPasswordPlainData($colname, $coldata, $objdata) { /* {{{ */
$objdata['passenc'] = seed_pass_hash($coldata);
return $objdata;
} /* }}} */
function getQuotaData($colname, $coldata, $objdata) { /* {{{ */
$objdata[$colname] = SeedDMS_Core_File::parse_filesize($coldata);
return $objdata;
@ -98,7 +103,9 @@ if (isset($_FILES['userdata']) && $_FILES['userdata']['error'] == 0) {
$colmap[$i] = array("getFolderData", $colname);
} elseif(in_array($colname, array('quota'))) {
$colmap[$i] = array("getQuotaData", $colname);
} elseif(in_array($colname, array('login', 'name', 'email', 'comment', 'group'))) {
} elseif(in_array($colname, array('password'))) {
$colmap[$i] = array("getPasswordPlainData", $colname);
} elseif(in_array($colname, array('login', 'name', 'passenc', 'email', 'comment', 'group'))) {
$colmap[$i] = array("getBaseData", $colname);
} elseif(substr($colname, 0, 5) == 'attr:') {
$kk = explode(':', $colname, 2);
@ -141,6 +148,11 @@ if (isset($_FILES['userdata']) && $_FILES['userdata']['error'] == 0) {
if($makeupdate)
$eu->setEmail($u['email']);
}
if(isset($u['passenc']) && $u['passenc'] != $eu->getPwd()) {
$log[] = array('id'=>$eu->getLogin(), 'type'=>'success', 'msg'=> "Encrypted password of user updated. '".$u['passenc']."' != '".$eu->getPwd()."'");
if($makeupdate)
$eu->setPwd($u['passenc']);
}
if(isset($u['comment']) && $u['comment'] != $eu->getComment()) {
$log[] = array('id'=>$eu->getLogin(), 'type'=>'success', 'msg'=> "Comment of user updated. '".$u['comment']."' != '".$eu->getComment()."'");
if($makeupdate)

View File

@ -68,7 +68,7 @@ if ($action == "adduser") {
UI::exitError(getMLText("admin_tools"),getMLText("user_exists"));
}
$newUser = $dms->addUser($login, md5($pwd), $name, $email, $settings->_language, $settings->_theme, $comment, $role, $isHidden, $isDisabled, $pwdexpiration, $quota, $homefolder);
$newUser = $dms->addUser($login, seed_pass_hash($pwd), $name, $email, $settings->_language, $settings->_theme, $comment, $role, $isHidden, $isDisabled, $pwdexpiration, $quota, $homefolder);
if ($newUser) {
/* Set user image if uploaded */
@ -388,7 +388,7 @@ else if ($action == "edituser") {
$editedUser->setPwd('');
} else {
if (isset($pwd) && ($pwd != "")) {
$editedUser->setPwd(md5($pwd));
$editedUser->setPwd(seed_pass_hash($pwd));
}
}
if ($editedUser->getFullName() != $name)

View File

@ -11,7 +11,10 @@ chzn_template_func = function (state) {
var warning = '';
if($(state.element).data('warning'))
warning = $(state.element).data('warning')+''; /* make sure it is a string */
var html = '<span>'+state.text.replace(/</g, '&lt;')+'';
var html = '<span>';
if($(state.element).data('icon-before'))
html += '<i class="icon-'+$(state.element).data('icon-before')+'"></i> ';
html += state.text.replace(/</g, '&lt;')+'';
if(subtitle)
html += '<br /><i>'+subtitle.replace(/</g, '&lt;')+'</i>';
if(warning)
@ -58,8 +61,8 @@ $(document).ready( function() {
$(".chzn-select").select2({
width: '100%',
templateResult: chzn_template_func,
templateSelection: chzn_template_func
templateResult: chzn_template_func//,
//templateSelection: chzn_template_func
});
/* change the color and length of the bar graph showing the password
@ -377,8 +380,8 @@ $(document).ready( function() {
element.html(data);
$(".chzn-select").select2({
width: '100%',
templateResult: chzn_template_func,
templateSelection: chzn_template_func
templateResult: chzn_template_func//,
//templateSelection: chzn_template_func
});
$(".pwd").passStrength({ /* {{{ */
url: "../op/op.Ajax.php",
@ -426,8 +429,8 @@ $(document).ready( function() {
element.html(data);
$(".chzn-select").select2({
width: '100%',
templateResult: chzn_template_func,
templateSelection: chzn_template_func
templateResult: chzn_template_func//,
//templateSelection: chzn_template_func
});
$(".pwd").passStrength({ /* {{{ */
url: "../op/op.Ajax.php",

View File

@ -626,18 +626,40 @@ $(document).ready( function() {
$attrstr .= "<table class=\"table table-condensed\">\n";
$attrstr .= "<tr><th>".getMLText('name')."</th><th>".getMLText('attribute_value')."</th></tr>";
foreach($lcattributes as $lcattribute) {
$attrdef = $lcattribute->getAttributeDefinition();
$attrstr .= "<tr><td>".htmlspecialchars($attrdef->getName())."</td><td>".htmlspecialchars(implode(', ', $lcattribute->getValueAsArray()))."</td></tr>\n";
$arr = $this->callHook('showDocumentContentAttribute', $lc, $lcattribute);
if(is_array($arr)) {
$attrstr .= "<tr>";
$attrstr .= "<td>".$arr[0].":</td>";
$attrstr .= "<td>".$arr[1]."</td>";
$attrstr .= "</tr>";
} elseif(is_string($arr)) {
$attrstr .= $arr;
} else {
$attrdef = $lcattribute->getAttributeDefinition();
$attrstr .= "<tr><td>".htmlspecialchars($attrdef->getName())."</td><td>".htmlspecialchars(implode(', ', $lcattribute->getValueAsArray()))."</td></tr>\n";
// TODO: better use printAttribute()
// $this->printAttribute($lcattribute);
}
}
$attrstr .= "</table>\n";
}
$docttributes = $document->getAttributes();
if($docttributes) {
$docattributes = $document->getAttributes();
if($docattributes) {
$attrstr .= "<table class=\"table table-condensed\">\n";
$attrstr .= "<tr><th>".getMLText('name')."</th><th>".getMLText('attribute_value')."</th></tr>";
foreach($docttributes as $docttribute) {
$attrdef = $docttribute->getAttributeDefinition();
$attrstr .= "<tr><td>".htmlspecialchars($attrdef->getName())."</td><td>".htmlspecialchars(implode(', ', $docttribute->getValueAsArray()))."</td></tr>\n";
foreach($docattributes as $docattribute) {
$arr = $this->callHook('showDocumentAttribute', $document, $docattribute);
if(is_array($arr)) {
$attrstr .= "<tr>";
$attrstr .= "<td>".$arr[0].":</td>";
$attrstr .= "<td>".$arr[1]."</td>";
$attrstr .= "</tr>";
} elseif(is_string($arr)) {
$attrstr .= $arr;
} else {
$attrdef = $docattribute->getAttributeDefinition();
$attrstr .= "<tr><td>".htmlspecialchars($attrdef->getName())."</td><td>".htmlspecialchars(implode(', ', $docattribute->getValueAsArray()))."</td></tr>\n";
}
}
$attrstr .= "</table>\n";
}

View File

@ -613,10 +613,11 @@ $('body').on('click', '.order-btn', function(ev) {
echo "</div>";
}
// $this->folderList();
echo $this->callHook('rightContentPre');
?>
<div class="ajax" data-view="ViewFolder" data-action="folderList" <?php echo ($folder ? "data-query=\"folderid=".$folder->getID()."&orderby=".$orderby."\"" : "") ?>></div>
<?php
echo $this->callHook('rightContentPost');
echo "</div>\n"; // End of right column div
echo "</div>\n"; // End of div around left and right column