Skip to content

Commit

Permalink
Users with "uploader" role can now be limited to certain clients only
Browse files Browse the repository at this point in the history
  • Loading branch information
ignacionelson committed Sep 16, 2022
1 parent a7f82ea commit 51e0d74
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 17 deletions.
12 changes: 12 additions & 0 deletions assets/src/js/pages/user_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
admin.pages.userForm = function () {

$(document).ready(function(){
// Display or not the limit accounts selector
$('#level').on('change', function(e) {
var el = document.getElementById('limit_upload_to_container');
if (typeof(el) != 'undefined' && el != null) {
if ($(this).val() == '7') {
$('#limit_upload_to_container').slideDown();
} else {
$('#limit_upload_to_container').slideUp();
}
}
});

var form_type = $("#user_form").data('form-type');

var validator = $("#user_form").validate({
Expand Down
2 changes: 1 addition & 1 deletion files-edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
$files = explode(',', $_GET['ids']);
foreach ($files as $file_id) {
if (is_numeric($file_id)) {
if (userCanEditFile(CURRENT_USER_ID, $file_id))
if (user_can_edit_file(CURRENT_USER_ID, $file_id))
{
$editable[] = (int)$file_id;
}
Expand Down
3 changes: 1 addition & 2 deletions header.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@
<div class="container-fluid">
<?php
render_custom_assets('body_top');
?>
<?php

// Gets the mark up and values for the System Updated and errors messages.
include_once INCLUDES_DIR . DS . 'updates.messages.php';

Expand Down
23 changes: 22 additions & 1 deletion includes/Classes/Files.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public function getId()

public function currentUserCanEdit()
{
return userCanEditFile(CURRENT_USER_ID, $this->id);
return user_can_edit_file(CURRENT_USER_ID, $this->id);
}

/**
Expand Down Expand Up @@ -915,6 +915,27 @@ public function saveAssignments($new_values, $hidden = 0)
if (empty($new_values['clients'])) { $new_values['clients'] = []; }
if (empty($new_values['groups'])) { $new_values['groups'] = []; }

// Clean new ids based on user permissions
if (CURRENT_USER_LEVEL == 7) {
$get_user = new \ProjectSend\Classes\Users();
$get_user->get(CURRENT_USER_ID);
if (!empty($get_user->limit_upload_to)) {
// If client ID is not allowed, remove from array
foreach ($new_values['clients'] as $key => $client_id) {
if (!in_array($client_id, $get_user->limit_upload_to)) {
unset($new_values['clients'][$key]);
}
}
// Do the same for groups. First get allowed groups
$allowed_groups = array_keys(file_editor_get_groups_by_members($get_user->limit_upload_to));
foreach ($new_values['groups'] as $key => $group_id) {
if (!in_array($group_id, $allowed_groups)) {
unset($new_values['groups'][$key]);
}
}
}
}

// Get current assignments from database to compare with new values
$current = [
'clients' => $this->assignments_clients,
Expand Down
95 changes: 95 additions & 0 deletions includes/Classes/Users.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Users
public $created_date;
public $metadata;
public $require_password_change;
public $limit_upload_to;

// Uploaded files
public $files;
Expand Down Expand Up @@ -151,6 +152,7 @@ public function set($arguments = [])
$this->max_file_size = (!empty($arguments['max_file_size'])) ? (int)$arguments['max_file_size'] : 0;
$this->can_upload_public = (!empty($arguments['can_upload_public'])) ? (int)$arguments['can_upload_public'] : 0;
$this->require_password_change = (!empty($arguments['require_password_change'])) ? $arguments['require_password_change'] : false;
$this->limit_upload_to = (!empty($arguments['limit_upload_to'])) ? $arguments['limit_upload_to'] : null;

// Specific for clients
$this->address = (!empty($arguments['address'])) ? encode_html($arguments['address']) : null;
Expand Down Expand Up @@ -201,6 +203,8 @@ public function get($id)
$this->require_password_change = ($meta['value'] == 'true') ? true : false;
}

$this->limit_upload_to = $this->limitUploadToGet();

// Specific for clients
$this->address = html_output($this->row['address']);
$this->phone = html_output($this->row['phone']);
Expand Down Expand Up @@ -267,6 +271,7 @@ public function getProperties()
'files' => $this->files,
'groups' => $this->groups,
'meta' => $this->meta,
'limit_upload_to' => $this->limit_upload_to,
];

return $return;
Expand Down Expand Up @@ -456,6 +461,9 @@ public function create()
save_user_meta($this->id, 'require_password_change', 'true');
}

// Uploader role: limit who user can upload to
$this->limitUploadToSave($this->limit_upload_to);

switch ($this->role) {
case 0:
$email_type = "new_client";
Expand Down Expand Up @@ -617,6 +625,8 @@ public function edit()
}
}

$this->limitUploadToSave($this->limit_upload_to);

$state['query'] = 1;

switch ($this->role) {
Expand Down Expand Up @@ -813,4 +823,89 @@ public function accountDeny()

return false;
}

// Methods to handle who this user is limited to upload to. Only Uploader role
/**
* Get from database. Returns array of client ids
*
* @return array
*/
private function limitUploadToGet()
{
$clients_ids = [];
if ( !tableExists( TABLE_USER_LIMIT_UPLOAD_TO ) ) {
return $clients_ids;
}

$statement = $this->dbh->prepare("SELECT * FROM " . TABLE_USER_LIMIT_UPLOAD_TO . " WHERE user_id = :user_id");
$statement->bindParam(':user_id', $this->id, PDO::PARAM_INT);
$statement->execute();
if ( $statement->rowCount() > 0) {
$statement->setFetchMode(PDO::FETCH_ASSOC);
while( $row = $statement->fetch() ) {
$clients_ids[] = $row['client_id'];
}
}

$this->limit_upload_to = $clients_ids;

return $clients_ids;
}

private function limitUploadToSave($clients_ids = [])
{
if (CURRENT_USER_LEVEL == 7) {
return;
}

if (CURRENT_USER_ID == $this->id)
{
return;
}

$current_client_ids = $this->limitUploadToGet();

// Remove clients that are not in the new array
$delete = [];
foreach ($current_client_ids as $client_id) {
if (empty($clients_ids) || !in_array($client_id, $clients_ids)) {
$delete[] = $client_id;
}
}

if (!empty($delete)) {
$delete = implode(',', $delete);
$statement = $this->dbh->prepare("DELETE FROM " . TABLE_USER_LIMIT_UPLOAD_TO . " WHERE user_id = :user_id AND FIND_IN_SET(client_id, :delete)");
$statement->bindParam(':user_id', $this->id);
$statement->bindParam(':delete', $delete);
$statement->execute();

$this->limit_upload_to = [];
}

// Add those that are new and do not exist in the database
$add = [];
foreach ($clients_ids as $client_id) {
if (!in_array($client_id, $current_client_ids)) {
$add[] = $client_id;
}
}

foreach ($add as $client_id) {
$statement = $this->dbh->prepare("INSERT INTO " . TABLE_USER_LIMIT_UPLOAD_TO . " (user_id, client_id) VALUES (:user_id, :client_id)");
$statement->bindParam(':user_id', $this->id);
$statement->bindParam(':client_id', $client_id, PDO::PARAM_INT);
$statement->execute();
}

// Get again to refresh the properties
$this->limitUploadToGet();
}

public function shouldLimitUploadTo()
{
if (!$this->isClient() && $this->role == '7') {
return true;
}
}
}
2 changes: 2 additions & 0 deletions includes/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
define('TABLE_LOGINS_FAILED', TABLES_PREFIX . 'logins_failed');
define('TABLE_CRON_LOG', TABLES_PREFIX . 'cron_log');
define('TABLE_CUSTOM_ASSETS', TABLES_PREFIX . 'custom_assets');
define('TABLE_USER_LIMIT_UPLOAD_TO', TABLES_PREFIX . 'user_limit_upload_to');

$original_basic_tables = array(
TABLE_FILES,
Expand All @@ -176,6 +177,7 @@
'logins_failed',
'cron_log',
'custom_assets',
'user_limit_upload_to',
);

/**
Expand Down
13 changes: 11 additions & 2 deletions includes/forms/file_editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@
<div class="container-fluid">
<?php
$i = 1;
$clients = fileEditorGetAllClients();
$groups = fileEditorGetAllGroups();

$me = new \ProjectSend\Classes\Users();
$me->get(CURRENT_USER_ID);
if ($me->shouldLimitUploadTo() && !empty($me->limit_upload_to)) {
$clients = file_editor_get_clients_by_ids($me->limit_upload_to);
$groups = file_editor_get_groups_by_members($me->limit_upload_to);
} else {
$clients = file_editor_get_all_clients();
$groups = file_editor_get_all_groups();
}


foreach ($editable as $file_id) {
clearstatcache();
Expand Down
48 changes: 41 additions & 7 deletions includes/forms/users.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,30 @@
* @subpackage Users
*
*/
$disable_user = true;
$require_pass = true;
$form_action = 'users-add.php';
$extra_fields = false;
$limit_field_class = 'none';

switch ($user_form_type) {
case 'new_user':
$submit_value = __('Add user','cftp_admin');
$disable_user = false;
$require_pass = true;
$form_action = 'users-add.php';
$disable_user = false;
$extra_fields = true;
break;
case 'edit_user':
$submit_value = __('Save user','cftp_admin');
$disable_user = true;
$require_pass = false;
$form_action = 'users-edit.php?id='.$user_id;
$require_pass = false;
$extra_fields = true;
if ($user_arguments['role'] == '7') $limit_field_class = '';
break;
case 'edit_user_self':
$submit_value = __('Update account','cftp_admin');
$disable_user = true;
$require_pass = false;
$form_action = 'users-edit.php?id='.$user_id;
$extra_fields = false;
$require_pass = false;
break;
}
?>
Expand Down Expand Up @@ -102,6 +105,37 @@
</div>
</div>

<div class="form-group <?php echo $limit_field_class; ?>" id="limit_upload_to_container">
<label for="limit_upload_to" class="col-sm-4 control-label"><?php _e('Limit account to this clients only','cftp_admin'); ?></label>
<div class="col-sm-8">
<select multiple="multiple" id="limit_upload_to" class="form-control chosen-select none" name="limit_upload_to[]" data-placeholder="<?php _e('Select one or more options. Type to search.', 'cftp_admin');?>">
<?php
$sql = $dbh->prepare("SELECT * FROM " . TABLE_USERS . " WHERE level = '0' ORDER BY name ASC");
$sql->execute();
$sql->setFetchMode(PDO::FETCH_ASSOC);
while ( $row = $sql->fetch() ) {
?>
<option value="<?php echo $row["id"]; ?>"
<?php
if ($user_form_type == 'edit_user') {
if (!empty($user_arguments['limit_upload_to'])) {
if (in_array($row["id"], $user_arguments['limit_upload_to'])) {
echo ' selected="selected"';
}
}
}
?>
><?php echo sprintf('%d - %s - %s', html_output($row["id"]), html_output($row["name"]), html_output($row["email"])); ?>
</option>
<?php
}
?>
</select>
<p class="field_note"><?php _e('Leave empty to allow access to all clients','cftp_admin'); ?></p>
<p class="field_note"><?php _e('Important: at the moment limiting to specific users also limits uploading to groups that these clients are members of.','cftp_admin'); ?></p>
</div>
</div>

<div class="form-group">
<div class="col-sm-8 col-sm-offset-4">
<label for="active">
Expand Down

0 comments on commit 51e0d74

Please sign in to comment.