Functionality to upload binary files and display them in the form it's a JPEG. Added a new page to download existing binary content.

This commit is contained in:
Brian Lycett 2022-04-11 15:40:15 +01:00
parent e46e590c79
commit 529303f22c
7 changed files with 200 additions and 84 deletions

View File

@ -344,11 +344,13 @@ LDAP_ACCOUNT_ADDITIONAL_ATTRIBUTES=mailAlias+:Email aliases"
### Binary attributes
If you have an attribute that stores the contents of a binary file (for example, a JPEG) then you can add a `^` to the end of the attribute name. This will modify the form so that this attribute has an upload button. If a file has already been uploaded then a link to view or download the file will be shown. For example, to allow you to set a user's photo:
If you have an attribute that stores the contents of a binary file (for example, a JPEG) then you can add a `^` to the end of the attribute name. This will modify the form so that this attribute has an upload button. If a JPEG has already been uploaded then it will display the image. Otherwise the mime-type is displayed and there's a link for downloading the file. For example, to allow you to set a user's photo:
```
LDAP_ACCOUNT_ADDITIONAL_ATTRIBUTES=jpegPhoto^:Photograph"
```
The maximum filesize you can upload is 2MB.
### Caveat

View File

@ -0,0 +1,41 @@
<?php
set_include_path( ".:" . __DIR__ . "/../includes/");
include_once "web_functions.inc.php";
include_once "ldap_functions.inc.php";
include_once "module_functions.inc.php";
set_page_access("admin");
if (!isset($_GET['resource_identifier']) or !isset($_GET['attribute'])) {
exit(0);
}
else {
$this_resource=ldap_escape($_GET['resource_identifier'], "", LDAP_ESCAPE_FILTER);
$this_attribute=ldap_escape($_GET['attribute'], "", LDAP_ESCAPE_FILTER);
}
$exploded = ldap_explode_dn($this_resource,0);
$filter = $exploded[0];
$ldap_connection = open_ldap_connection();
$ldap_search_query="($filter)";
$ldap_search = ldap_search($ldap_connection, $this_resource, $ldap_search_query,array($this_attribute));
if ($ldap_search) {
$records = ldap_get_entries($ldap_connection, $ldap_search);
if ($records['count'] == 1) {
$this_record = $records[0];
if (isset($this_record[$this_attribute][0])) {
header("Content-Type: application/octet-stream");
header("Cache-Control: no-cache private");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename='${this_resource}.${this_attribute}'");
header("Content-Length: ". strlen($this_record[$this_attribute][0]));
print $this_record[$this_attribute][0];
}
}
}
?>

View File

@ -13,26 +13,27 @@ if (! array_key_exists($LDAP['account_attribute'], $attribute_map)) {
}
if ( isset($_POST['setup_admin_account']) ) {
$admin_setup = TRUE;
validate_setup_cookie();
set_page_access("setup");
$admin_setup = TRUE;
$completed_action="${SERVER_PATH}log_in";
$page_title="New administrator account";
validate_setup_cookie();
set_page_access("setup");
render_header("$ORGANISATION_NAME account manager - setup administrator account", FALSE);
$completed_action="${SERVER_PATH}log_in";
$page_title="New administrator account";
render_header("$ORGANISATION_NAME account manager - setup administrator account", FALSE);
}
else {
set_page_access("admin");
set_page_access("admin");
$completed_action="${THIS_MODULE_PATH}/";
$page_title="New account";
$admin_setup = FALSE;
$completed_action="${THIS_MODULE_PATH}/";
$page_title="New account";
$admin_setup = FALSE;
render_header("$ORGANISATION_NAME account manager");
render_submenu();
render_header("$ORGANISATION_NAME account manager");
render_submenu();
}
$invalid_password = FALSE;
@ -49,6 +50,17 @@ $new_account_r = array();
foreach ($attribute_map as $attribute => $attr_r) {
if (isset($_FILES[$attribute]['size']) and $_FILES[$attribute]['size'] > 0) {
$this_attribute = array();
$this_attribute['count'] = 1;
$this_attribute[0] = file_get_contents($_FILES[$attribute]['tmp_name']);
$$attribute = $this_attribute;
$new_account_r[$attribute] = $this_attribute;
unset($new_account_r[$attribute]['count']);
}
if (isset($_POST[$attribute])) {
$this_attribute = array();
@ -323,7 +335,7 @@ $tabindex=1;
<div class="panel-heading text-center"><?php print $page_title; ?></div>
<div class="panel-body text-center">
<form class="form-horizontal" action="" method="post">
<form class="form-horizontal" action="" enctype="multipart/form-data" method="post">
<?php if ($admin_setup == TRUE) { ?><input type="hidden" name="setup_admin_account" value="true"><?php } ?>
<input type="hidden" name="create_account">
@ -335,8 +347,8 @@ $tabindex=1;
if (isset($attr_r['onkeyup'])) { $onkeyup = $attr_r['onkeyup']; } else { $onkeyup = ""; }
if ($attribute == $LDAP['account_attribute']) { $label = "<strong>$label</strong><sup>&ast;</sup>"; }
if (isset($$attribute)) { $these_values=$$attribute; } else { $these_values = array(); }
if (isset($attr_r['multiple'])) { $multiple = $attr_r['multiple']; } else { $multiple = FALSE; }
render_attribute_fields($attribute,$label,$these_values,$onkeyup,$multiple,$tabindex);
if (isset($attr_r['inputtype'])) { $inputtype = $attr_r['inputtype']; } else { $inputtype = ""; }
render_attribute_fields($attribute,$label,$these_values,"",$onkeyup,$inputtype,$tabindex);
$tabindex++;
}
?>

View File

@ -40,6 +40,8 @@ if ($ENFORCE_SAFE_SYSTEM_NAMES == TRUE and !preg_match("/$USERNAME_REGEX/",$grou
######################################################################################
$initialise_group = FALSE;
$create_group_message = "Add members to create the new group";
$attribute_map = $LDAP['default_group_attribute_map'];
if (isset($LDAP['group_additional_attributes'])) {
$attribute_map = ldap_complete_attribute_array($attribute_map,$LDAP['group_additional_attributes']);
@ -51,7 +53,7 @@ $this_group = array();
if (isset($_POST['new_group'])) {
$new_group = TRUE;
$current_members = array();
$full_dn = "Add members to create the new group";
$full_dn = $create_group_message;
$has_been = "";
}
elseif (isset($_POST['initialise_group'])) {
@ -78,6 +80,17 @@ foreach ($attribute_map as $attribute => $attr_r) {
$$attribute = array();
}
if (isset($_FILES[$attribute]['size']) and $_FILES[$attribute]['size'] > 0) {
$this_attribute = array();
$this_attribute['count'] = 1;
$this_attribute[0] = file_get_contents($_FILES[$attribute]['tmp_name']);
$$attribute = $this_attribute;
$to_update[$attribute] = $this_attribute;
unset($to_update[$attribute]['count']);
}
if (isset($_POST[$attribute])) {
$this_attribute = array();
@ -305,7 +318,7 @@ ldap_close($ldap_connection);
<div class="panel-heading clearfix">
<h3 class="panel-title pull-left" style="padding-top: 7.5px;"><?php print $group_cn; ?><?php if ($group_cn == $LDAP["admins_group"]) { print " <sup>(admin group)</sup>" ; } ?></h3>
<button class="btn btn-warning pull-right" onclick="show_delete_group_button();" <?php if ($group_cn == $LDAP["admins_group"]) { print "disabled"; } ?>>Delete group</button>
<form action="<?php print "${THIS_MODULE_PATH}"; ?>/groups.php" method="post"><input type="hidden" name="delete_group" value="<?php print $group_cn; ?>"><button class="btn btn-danger pull-right invisible" id="delete_group">Confirm deletion</button></form>
<form action="<?php print "${THIS_MODULE_PATH}"; ?>/groups.php" method="post" enctype="multipart/form-data"><input type="hidden" name="delete_group" value="<?php print $group_cn; ?>"><button class="btn btn-danger pull-right invisible" id="delete_group">Confirm deletion</button></form>
</div>
<ul class="list-group">
@ -404,9 +417,9 @@ if (count($attribute_map) > 0) { ?>
foreach ($attribute_map as $attribute => $attr_r) {
$label = $attr_r['label'];
if (isset($$attribute)) { $these_values=$$attribute; } else { $these_values = array(); }
if (isset($attr_r['multiple'])) { $multiple = $attr_r['multiple']; } else { $multiple = FALSE; }
print "<div class='row'>";
render_attribute_fields($attribute,$label,$these_values,"",$multiple,$tabindex);
$dl_identifider = ($full_dn != $create_group_message) ? $full_dn : "";
render_attribute_fields($attribute,$label,$these_values,$dl_identifider,"",$attr_r['inputtype'],$tabindex);
print "</div>";
$tabindex++;
}

View File

@ -50,6 +50,7 @@ $ldap_search = ldap_search( $ldap_connection, $LDAP['user_dn'], $ldap_search_que
#########################
if ($ldap_search) {
$user = ldap_get_entries($ldap_connection, $ldap_search);
@ -65,6 +66,17 @@ if ($ldap_search) {
$$attribute = array();
}
if (isset($_FILES[$attribute]['size']) and $_FILES[$attribute]['size'] > 0) {
$this_attribute = array();
$this_attribute['count'] = 1;
$this_attribute[0] = file_get_contents($_FILES[$attribute]['tmp_name']);
$$attribute = $this_attribute;
$to_update[$attribute] = $this_attribute;
unset($to_update[$attribute]['count']);
}
if (isset($_POST['update_account']) and isset($_POST[$attribute])) {
$this_attribute = array();
@ -441,7 +453,7 @@ if ($ldap_search) {
<li class="list-group-item"><?php print $dn; ?></li>
</li>
<div class="panel-body">
<form class="form-horizontal" action="" method="post">
<form class="form-horizontal" action="" enctype="multipart/form-data" method="post">
<input type="hidden" name="update_account">
<input type="hidden" id="pass_score" value="0" name="pass_score">
@ -451,10 +463,10 @@ if ($ldap_search) {
foreach ($attribute_map as $attribute => $attr_r) {
$label = $attr_r['label'];
if (isset($attr_r['onkeyup'])) { $onkeyup = $attr_r['onkeyup']; } else { $onkeyup = ""; }
if (isset($attr_r['inputtype'])) { $inputtype = $attr_r['inputtype']; } else { $inputtype = ""; }
if ($attribute == $LDAP['account_attribute']) { $label = "<strong>$label</strong><sup>&ast;</sup>"; }
if (isset($$attribute)) { $these_values=$$attribute; } else { $these_values = array(); }
if (isset($attr_r['multiple'])) { $multiple = $attr_r['multiple']; } else { $multiple = FALSE; }
render_attribute_fields($attribute,$label,$these_values,$onkeyup,$multiple);
render_attribute_fields($attribute,$label,$these_values,$dn,$onkeyup,$inputtype);
}
?>

View File

@ -733,22 +733,17 @@ function ldap_complete_attribute_array($default_attributes,$additional_attribute
$this_r = array();
$kv = explode(":", $this_attr);
$attr_name = strtolower(filter_var($kv[0], FILTER_SANITIZE_FULL_SPECIAL_CHARS));
$this_r['inputtype'] = "singleinput";
if (substr($attr_name, -1) == '+') {
$this_r['multiple'] = TRUE;
$this_r['inputtype'] = "multipleinput";
$attr_name = rtrim($attr_name, '+');
}
else {
$this_r['multiple'] = FALSE;
}
if (substr($attr_name, -1) == '^') {
$this_r['binary'] = TRUE;
$this_r['inputtype'] = "binary";
$attr_name = rtrim($attr_name, '^');
}
else {
$this_r['binary'] = FALSE;
}
if (preg_match('/^[a-zA-Z0-9\-]+$/', $attr_name) == 1) {

View File

@ -42,8 +42,6 @@ $DEFAULT_COOKIE_OPTIONS = array( 'expires' => time()+(60 * $SESSION_TIMEOUT),
'samesite' => 'strict'
);
validate_passkey_cookie();
if ($REMOTE_HTTP_HEADERS_LOGIN) {
login_via_headers();
} else {
@ -111,52 +109,53 @@ function login_via_headers() {
function validate_passkey_cookie() {
global $SESSION_TIMEOUT, $IS_ADMIN, $USER_ID, $VALIDATED, $log_prefix, $SESSION_TIMED_OUT, $SESSION_DEBUG;
global $SESSION_TIMEOUT, $IS_ADMIN, $USER_ID, $VALIDATED, $log_prefix, $SESSION_TIMED_OUT, $SESSION_DEBUG;
$this_time=time();
$this_time=time();
$VALIDATED = FALSE;
unset($USER_ID);
$IS_ADMIN = FALSE;
if (isset($_COOKIE['orf_cookie'])) {
if (isset($_COOKIE['orf_cookie'])) {
list($user_id,$c_passkey) = explode(":",$_COOKIE['orf_cookie']);
$filename = preg_replace('/[^a-zA-Z0-9]/','_', $user_id);
$session_file = @ file_get_contents("/tmp/$filename");
if (!$session_file) {
if ($SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: orf_cookie was sent by the client but the session file wasn't found at /tmp/$filename",0); }
}
else {
list($f_passkey,$f_is_admin,$f_time) = explode(":",$session_file);
if (!empty($c_passkey) and $f_passkey == $c_passkey and $this_time < $f_time+(60 * $SESSION_TIMEOUT)) {
if ($f_is_admin == 1) { $IS_ADMIN = TRUE; }
$VALIDATED = TRUE;
$USER_ID=$user_id;
if ($SESSION_DEBUG == TRUE) { error_log("$log_prefix Setup session: Cookie and session file values match for user ${user_id} - VALIDATED (ADMIN = ${IS_ADMIN})",0); }
set_passkey_cookie($USER_ID,$IS_ADMIN);
}
else {
if ($SESSION_DEBUG == TRUE) {
$this_error="$log_prefix Session: orf_cookie was sent by the client and the session file was found at /tmp/$filename, but";
if (empty($c_passkey)) { $this_error .= " the cookie passkey wasn't set;"; }
if ($c_passkey != $f_passkey) { $this_error .= " the session file passkey didn't match the cookie passkey;"; }
$this_error.=" Cookie: ${_COOKIE['orf_cookie']} - Session file contents: $session_file";
error_log($this_error,0);
}
}
}
list($user_id,$c_passkey) = explode(":",$_COOKIE['orf_cookie']);
$filename = preg_replace('/[^a-zA-Z0-9]/','_', $user_id);
$session_file = @ file_get_contents("/tmp/$filename");
if (!$session_file) {
$VALIDATED = FALSE;
unset($USER_ID);
$IS_ADMIN = FALSE;
if ( $SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: orf_cookie was sent by the client but the session file wasn't found at /tmp/$filename",0); }
}
else {
list($f_passkey,$f_is_admin,$f_time) = explode(":",$session_file);
if (!empty($c_passkey) and $f_passkey == $c_passkey and $this_time < $f_time+(60 * $SESSION_TIMEOUT)) {
if ($f_is_admin == 1) { $IS_ADMIN = TRUE; }
$VALIDATED = TRUE;
$USER_ID=$user_id;
if ( $SESSION_DEBUG == TRUE) { error_log("$log_prefix Setup session: Cookie and session file values match for user ${user_id} - VALIDATED (ADMIN = ${IS_ADMIN})",0); }
set_passkey_cookie($USER_ID,$IS_ADMIN);
}
else {
if ( $SESSION_DEBUG == TRUE ) {
$this_error="$log_prefix Session: orf_cookie was sent by the client and the session file was found at /tmp/$filename, but";
if (empty($c_passkey)) { $this_error .= " the cookie passkey wasn't set;"; }
if ($c_passkey != $f_passkey) { $this_error .= " the session file passkey didn't match the cookie passkey;"; }
$this_error.=" Cookie: ${_COOKIE['orf_cookie']} - Session file contents: $session_file";
error_log($this_error,0);
if ($SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: orf_cookie wasn't sent by the client.",0); }
if (isset($_COOKIE['sessto_cookie'])) {
$this_session_timeout = $_COOKIE['sessto_cookie'];
if ($this_time >= $this_session_timeout) {
$SESSION_TIMED_OUT = TRUE;
if ($SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: The session had timed-out (over $SESSION_TIMEOUT mins idle).",0); }
}
}
}
}
}
else {
if ( $SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: orf_cookie wasn't sent by the client.",0); }
if (isset($_COOKIE['sessto_cookie'])) {
$this_session_timeout = $_COOKIE['sessto_cookie'];
if ($this_time >= $this_session_timeout) {
$SESSION_TIMED_OUT = TRUE;
if ( $SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: The session had timed-out (over $SESSION_TIMEOUT mins idle).",0); }
}
}
}
}
@ -621,36 +620,78 @@ function render_dynamic_field_js() {
######################################################
function render_attribute_fields($attribute,$label,$values_r,$onkeyup="",$multiple=FALSE,$tabindex=null) {
function render_attribute_fields($attribute,$label,$values_r,$resource_identifier,$onkeyup="",$inputtype="",$tabindex=null) {
?>
global $THIS_MODULE_PATH;
?>
<div class="form-group" id="<?php print $attribute; ?>_div">
<label for="<?php print $attribute; ?>" class="col-sm-3 control-label"><?php print $label; ?></label>
<div class="col-sm-6" id="<?php print $attribute; ?>_input_div">
<?php if ($multiple != TRUE) { ?>
<input <?php if (isset($tabindex)) { ?>tabindex="<?php print $tabindex; ?>" <?php } ?>type="text" class="form-control" id="<?php print $attribute; ?>" name="<?php print $attribute; ?>" value="<?php if (isset($values_r[0])) { print $values_r[0]; } ?>" <?php if ($onkeyup != "") { print "onkeyup=\"$onkeyup\""; } ?>>
<?php }
else {
<?php if($inputtype == "multipleinput") {
?><div class="input-group">
<input type="text" class="form-control" id="<?php print $attribute; ?>" name="<?php print $attribute; ?>[]" value="<?php if (isset($values_r[0])) { print $values_r[0]; } ?>">
<div class="input-group-btn"><button type="button" class="btn btn-default" onclick="add_field_to('<?php print $attribute; ?>')">+</i></button></div>
</div>
<?php
if (isset($values_r['count']) and $values_r['count'] > 0) {
$remaining_values = array_slice($values_r, 2);
print "<script>";
foreach($remaining_values as $this_value) { print "add_field_to('$attribute','$this_value');"; }
print "</script>";
}
if (isset($values_r['count']) and $values_r['count'] > 0) {
$remaining_values = array_slice($values_r, 2);
print "<script>";
foreach($remaining_values as $this_value) { print "add_field_to('$attribute','$this_value');"; }
print "</script>";
}
}
elseif ($inputtype == "binary") {
$button_text="Browse";
$file_button_action="disabled";
$description="Select a file to upload";
$mimetype="";
if (isset($values_r[0])) {
$this_file_info = new finfo(FILEINFO_MIME_TYPE);
$mimetype = $this_file_info->buffer($values_r[0]);
if (strlen($mimetype) > 23) { $mimetype = substr($mimetype,0,19) . "..."; }
$description="Download $mimetype file (" . human_readable_filesize(strlen($values_r[0])) . ")";
$button_text="Replace file";
if ($resource_identifier != "") {
$this_url="//${_SERVER['HTTP_HOST']}${THIS_MODULE_PATH}/download.php?resource_identifier=${resource_identifier}&attribute=${attribute}";
$file_button_action="onclick=\"window.open('$this_url','_blank');\"";
}
}
if ($mimetype == "image/jpeg") {
$this_image = base64_encode($values_r[0]);
print "<img class='img-thumbnail' src='data:image/jpeg;base64,$this_image'>";
$description="";
}
else {
?>
<button type="button" <?php print $file_button_action; ?> class="btn btn-default" id="<?php print $attribute; ?>-file-info"><?php print $description; ?></button>
<?php } ?>
<label class="btn btn-default">
<?php print $button_text; ?><input <?php if (isset($tabindex)) { ?>tabindex="<?php print $tabindex; ?>" <?php } ?>type="file" style="display:none" onchange="$('#<?php print $attribute; ?>-file-info').text(this.files[0].name)" id="<?php print $attribute; ?>" name="<?php print $attribute; ?>">
</label>
<?php
}
else { ?>
<input <?php if (isset($tabindex)) { ?>tabindex="<?php print $tabindex; ?>" <?php } ?>type="text" class="form-control" id="<?php print $attribute; ?>" name="<?php print $attribute; ?>" value="<?php if (isset($values_r[0])) { print $values_r[0]; } ?>" <?php if ($onkeyup != "") { print "onkeyup=\"$onkeyup\""; } ?>>
<?php
}
?>
</div>
</div>
<?php
<?php
}
######################################################
function human_readable_filesize($bytes) {
for($i = 0; ($bytes / 1024) > 0.9; $i++, $bytes /= 1024) {}
return round($bytes, [0,0,1,2,2,3,3,4,4][$i]).['B','kB','MB','GB','TB','PB','EB','ZB','YB'][$i];
}