forked from extern/egroupware
sharing ACL: need explicit new ACL or edit rights, to share into an addressbook
This commit is contained in:
parent
71d185a019
commit
9d776189b0
@ -484,6 +484,7 @@ class addressbook_hooks
|
|||||||
Acl::EDIT => 'edit',
|
Acl::EDIT => 'edit',
|
||||||
Acl::ADD => 'add',
|
Acl::ADD => 'add',
|
||||||
Acl::DELETE => 'delete',
|
Acl::DELETE => 'delete',
|
||||||
|
Acl::CUSTOM1 => 'shared with', // allows to share into given AB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2093,6 +2093,8 @@ class addressbook_ui extends addressbook_bo
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
unset($content['shared_values']);
|
unset($content['shared_values']);
|
||||||
|
// remove invalid shared-with entries (should not happen, as we validate already on client-side)
|
||||||
|
$this->check_shared_with($content['shared']);
|
||||||
|
|
||||||
$button = @key($content['button']);
|
$button = @key($content['button']);
|
||||||
unset($content['button']);
|
unset($content['button']);
|
||||||
@ -2440,6 +2442,8 @@ class addressbook_ui extends addressbook_bo
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
$content['shared_values'] = array_keys($content['shared_options']);
|
$content['shared_values'] = array_keys($content['shared_options']);
|
||||||
|
// disable shared with UI for non-SQL backends
|
||||||
|
$content['shared_disabled'] = !is_a($this->get_backend($content['id'], $content['owner']), Api\Contacts\Sql::class);
|
||||||
|
|
||||||
if ($content['id'])
|
if ($content['id'])
|
||||||
{
|
{
|
||||||
@ -2643,6 +2647,46 @@ class addressbook_ui extends addressbook_bo
|
|||||||
return $this->tmpl->exec('addressbook.addressbook_ui.edit', $content, $sel_options, $readonlys, $preserve, 2);
|
return $this->tmpl->exec('addressbook.addressbook_ui.edit', $content, $sel_options, $readonlys, $preserve, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user has right to share with / into given AB
|
||||||
|
*
|
||||||
|
* @param array $_data values for keys "shared_writable" and "shared_values"
|
||||||
|
* @return array of entries removed from $shared_with because current user is not allowed to share into
|
||||||
|
*/
|
||||||
|
public function ajax_check_shared(array $_data)
|
||||||
|
{
|
||||||
|
$response = Api\Json\Response::get();
|
||||||
|
try {
|
||||||
|
$shared = [];
|
||||||
|
foreach($_data['shared_values'] as $value)
|
||||||
|
{
|
||||||
|
if (is_numeric($value))
|
||||||
|
{
|
||||||
|
$shared[$value] = [
|
||||||
|
'shared_with' => $value,
|
||||||
|
'shared_by' => $this->user,
|
||||||
|
'shared_writable' => (int)$_data['shared_writable'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$shared[$value] = array_combine(['shared_id', 'shared_with', 'shared_by', 'shared_writable'], explode(':', $value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (($failed = $this->check_shared_with($shared)))
|
||||||
|
{
|
||||||
|
$response->data(array_keys($failed));
|
||||||
|
$response->message(lang('You are not allowed to share into the addressbook of %1',
|
||||||
|
implode(', ', array_map(function ($data) {
|
||||||
|
return Api\Accounts::username($data['shared_with']);
|
||||||
|
}, $failed))), 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
$response->message($e->getMessage(), 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the readonlys for non-admins editing their own account
|
* Set the readonlys for non-admins editing their own account
|
||||||
*
|
*
|
||||||
|
@ -1224,6 +1224,27 @@ var AddressbookApp = /** @class */ (function (_super) {
|
|||||||
app.status.makeCall(data);
|
app.status.makeCall(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* Check if new shared_with value is allowed / user has rights to share into that AB
|
||||||
|
*
|
||||||
|
* Remove the entry again, if user is not allowed
|
||||||
|
*/
|
||||||
|
AddressbookApp.prototype.shared_changed = function () {
|
||||||
|
var _a;
|
||||||
|
var shared = this.et2.getInputWidgetById('shared_values');
|
||||||
|
var value = (_a = shared) === null || _a === void 0 ? void 0 : _a.get_value();
|
||||||
|
if (value) {
|
||||||
|
this.egw.json('addressbook.addressbook_ui.ajax_check_shared', [{
|
||||||
|
shared_values: value,
|
||||||
|
shared_writable: this.et2.getInputWidgetById('shared_writable').get_value()
|
||||||
|
}], function (_data) {
|
||||||
|
if (Array.isArray(_data) && _data.length) {
|
||||||
|
// remove not allowed entries
|
||||||
|
shared.set_value(value.filter(function (val) { return _data.indexOf(val) === -1; }));
|
||||||
|
}
|
||||||
|
}).sendRequest();
|
||||||
|
}
|
||||||
|
};
|
||||||
return AddressbookApp;
|
return AddressbookApp;
|
||||||
}(egw_app_1.EgwApp));
|
}(egw_app_1.EgwApp));
|
||||||
app.classes.addressbook = AddressbookApp;
|
app.classes.addressbook = AddressbookApp;
|
||||||
|
@ -1479,6 +1479,30 @@ class AddressbookApp extends EgwApp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if new shared_with value is allowed / user has rights to share into that AB
|
||||||
|
*
|
||||||
|
* Remove the entry again, if user is not allowed
|
||||||
|
*/
|
||||||
|
public shared_changed()
|
||||||
|
{
|
||||||
|
let shared = this.et2.getInputWidgetById('shared_values');
|
||||||
|
let value = <Array<string>>shared?.get_value();
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
this.egw.json('addressbook.addressbook_ui.ajax_check_shared', [{
|
||||||
|
shared_values: value,
|
||||||
|
shared_writable: this.et2.getInputWidgetById('shared_writable').get_value()
|
||||||
|
}], _data => {
|
||||||
|
if (Array.isArray(_data) && _data.length)
|
||||||
|
{
|
||||||
|
// remove not allowed entries
|
||||||
|
shared.set_value(value.filter(val => _data.indexOf(val) === -1));
|
||||||
|
}
|
||||||
|
}).sendRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.classes.addressbook = AddressbookApp;
|
app.classes.addressbook = AddressbookApp;
|
||||||
|
@ -143,9 +143,10 @@
|
|||||||
</hbox>
|
</hbox>
|
||||||
<description/>
|
<description/>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row disabled="@shared_disabled">
|
||||||
<description for="shared" value="Shared with"/>
|
<description for="shared" value="Shared with"/>
|
||||||
<taglist-account id="shared_values" multiple="true" select_options="@shared_options" span="4"/>
|
<taglist-account account_type="both" id="shared_values" multiple="true"
|
||||||
|
onchange="app.addressbook.shared_changed" select_options="@shared_options" span="4"/>
|
||||||
<checkbox id="shared_writable" label="writable" statustext="Create new shares writable"/>
|
<checkbox id="shared_writable" label="writable" statustext="Create new shares writable"/>
|
||||||
</row>
|
</row>
|
||||||
</rows>
|
</rows>
|
||||||
|
@ -30,6 +30,17 @@ class Contacts extends Contacts\Storage
|
|||||||
*/
|
*/
|
||||||
const BIRTHDAY_CACHE_TIME = 864000; /* 10 days*/
|
const BIRTHDAY_CACHE_TIME = 864000; /* 10 days*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom ACL allowing to share into the AB / setting shared_with
|
||||||
|
*/
|
||||||
|
const ACL_SHARED = Acl::CUSTOM1;
|
||||||
|
/**
|
||||||
|
* Mask to allow to share into the AB, at least one of the following need to be set:
|
||||||
|
* - custom ACL_SHARED
|
||||||
|
* - ACL::EDIT
|
||||||
|
*/
|
||||||
|
const CHECK_ACL_SHARED = Acl::EDIT|self::ACL_SHARED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int $now_su actual user (!) time
|
* @var int $now_su actual user (!) time
|
||||||
*/
|
*/
|
||||||
@ -1250,6 +1261,34 @@ class Contacts extends Contacts\Storage
|
|||||||
return $access;
|
return $access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user has right to share with / into given AB
|
||||||
|
*
|
||||||
|
* @param array[]& $shared_with array of arrays with values for keys "shared_with", "shared_by", ...
|
||||||
|
* @return array of entries removed from $shared_with because current user is not allowed to share into (key is preserved)
|
||||||
|
*/
|
||||||
|
function check_shared_with(array &$shared_with)
|
||||||
|
{
|
||||||
|
$removed = [];
|
||||||
|
foreach($shared_with as $key => $shared)
|
||||||
|
{
|
||||||
|
if (!empty($shared['shared_by']) && $shared['shared_by'] != $this->user)
|
||||||
|
{
|
||||||
|
$grants = $this->get_grants($user);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$grants = $this->grants;
|
||||||
|
}
|
||||||
|
if (!($grants[$shared['shared_with']] & self::CHECK_ACL_SHARED))
|
||||||
|
{
|
||||||
|
$removed[$key] = $shared;
|
||||||
|
unset($shared_with[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $removed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check access to the file store
|
* Check access to the file store
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user