зеркало из https://github.com/nextcloud/guests.git
add configuration UI
This commit is contained in:
Родитель
a964afc6d4
Коммит
f317df3c12
|
@ -4,7 +4,7 @@ Allow classifying users or contacts as guests
|
|||
|
||||
Jails a user into a readonly home storage
|
||||
|
||||
* TODO If his quota is 0
|
||||
* TODO If his quota is 0 TODO below x
|
||||
* TODO If he is member of a configurable group
|
||||
* If he is a contact of another user and has been shared a file
|
||||
|
||||
|
|
|
@ -10,8 +10,12 @@
|
|||
*/
|
||||
|
||||
$guestBackend = \OCA\Guests\Backend::createForStaticLegacyCode();
|
||||
\OC_User::useBackend($guestBackend);
|
||||
\OC::$server->getUserManager()->registerBackend($guestBackend);
|
||||
|
||||
|
||||
\OCP\App::registerAdmin('guests', 'settings/admin');
|
||||
|
||||
\OCP\Util::connectHook('OC_Filesystem', 'preSetup', '\OCA\Guests\Hooks', 'preSetup');
|
||||
\OCP\Util::connectHook('OCP\Share', 'pre_shared', '\OCA\Guests\Hooks', 'preShareHook');
|
||||
\OCP\Util::connectHook('OCP\Share', 'post_shared', '\OCA\Guests\Hooks', 'postShareHook');
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING-AGPL file.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @copyright Jörn Friedrich Dreyer 2015
|
||||
*/
|
||||
|
||||
return [
|
||||
'routes' => [
|
||||
[
|
||||
'name' => 'settings#getConfig',
|
||||
'url' => '/config',
|
||||
'verb' => 'GET',
|
||||
],
|
||||
[
|
||||
'name' => 'settings#setConfig',
|
||||
'url' => '/config',
|
||||
'verb' => 'PUT',
|
||||
],
|
||||
],
|
||||
];
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING-AGPL file.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @copyright Jörn Friedrich Dreyer 2015
|
||||
*/
|
||||
|
||||
namespace OCA\Guests\Controller;
|
||||
|
||||
use OCA\Guests\Backend;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
|
||||
/**
|
||||
* Class SettingsController is used to handle configuration changes on the
|
||||
* settings page
|
||||
*
|
||||
* @package OCA\Guests\Controller
|
||||
*/
|
||||
class SettingsController extends Controller {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @var IConfig
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function __construct($AppName, IRequest $request, $UserId, IConfig $config) {
|
||||
parent::__construct($AppName, $request);
|
||||
$this->userId = $UserId;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX handler for getting the config
|
||||
*
|
||||
* @return DataResponse with the current config
|
||||
*/
|
||||
public function getConfig() {
|
||||
$conditions = $this->config->getUserValue($this->userId, 'guests', 'conditions', 'quota');
|
||||
$conditions = explode(',', $conditions);
|
||||
$apps = $this->config->getUserValue($this->userId, 'guests', 'apps', Backend::DEFAULT_GUEST_GROUPS);
|
||||
$apps = explode(',', $apps);
|
||||
return new DataResponse([
|
||||
'conditions' => $conditions,
|
||||
'group' => $this->config->getUserValue($this->userId, 'guests', 'group', 'guests'),
|
||||
'apps' => $apps,
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* AJAX handler for setting the config
|
||||
*
|
||||
* @param $conditions string[]
|
||||
* @param $group string
|
||||
* @param $apps string[]
|
||||
* @return DataResponse
|
||||
*/
|
||||
public function setConfig($conditions, $group, $apps) {
|
||||
$conditions = join(',', $conditions);
|
||||
$newApps = [];
|
||||
foreach ($apps as $app) {
|
||||
$newApps[] = trim($app);
|
||||
}
|
||||
$newApps = join(',', $newApps);
|
||||
$this->config->setUserValue($this->userId, 'guests', 'conditions', $conditions);
|
||||
$this->config->setUserValue($this->userId, 'guests', 'group', $group);
|
||||
$this->config->setUserValue($this->userId, 'guests', 'apps', $newApps);
|
||||
return new DataResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING-AGPL file.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @copyright Jörn Friedrich Dreyer 2015
|
||||
*/
|
||||
(function() {
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// variables
|
||||
var $section = $('#guests');
|
||||
var $guestsByQuota = $section.find('#guestsByQuota');
|
||||
var $guestsByGroup = $section.find('#guestsByGroup');
|
||||
var $guestGroup = $section.find('#guestGroup');
|
||||
var $guestsByContact = $section.find('#guestsByContact');
|
||||
var $guestApps = $section.find('#guestApps');
|
||||
var $msg = $section.find('.msg');
|
||||
|
||||
var config = { conditions: ['quota'], group: 'guests',
|
||||
apps:[
|
||||
'','core','settings','avatar','files','files_trashbin','files_sharing'
|
||||
]};
|
||||
|
||||
// functions
|
||||
|
||||
var loadConfig = function () {
|
||||
OC.msg.startAction($msg, t('guests', 'Loading…'));
|
||||
$.get(
|
||||
OC.generateUrl('apps/guests/config'),
|
||||
'',
|
||||
function (data) {
|
||||
// update model
|
||||
config = data;
|
||||
// update ui
|
||||
if($.inArray('quota', config.conditions) > -1) {
|
||||
$guestsByQuota.prop('checked', true);
|
||||
} else {
|
||||
$guestsByQuota.prop('checked', false);
|
||||
}
|
||||
if($.inArray('group', config.conditions) > -1) {
|
||||
$guestsByGroup.prop('checked', true);
|
||||
} else {
|
||||
$guestsByGroup.prop('checked', false);
|
||||
}
|
||||
if($.inArray('contact', config.conditions) > -1) {
|
||||
$guestsByContact.prop('checked', true);
|
||||
} else {
|
||||
$guestsByContact.prop('checked', false);
|
||||
}
|
||||
if (config.group) {
|
||||
$guestGroup.val(config.group);
|
||||
} else {
|
||||
$guestGroup.val('');
|
||||
}
|
||||
if ($.isArray(config.apps)) {
|
||||
$guestApps.val(config.apps.join());
|
||||
} else {
|
||||
$guestApps.val('');
|
||||
}
|
||||
},
|
||||
'json'
|
||||
).then(function() {
|
||||
var data = { status: 'success', data: {message: t('guests', 'Loaded')} };
|
||||
OC.msg.finishedAction($msg, data);
|
||||
}, function(result) {
|
||||
var data = { status: 'error', data:{message:result.responseJSON.message} };
|
||||
OC.msg.finishedAction($msg, data);
|
||||
});
|
||||
};
|
||||
|
||||
var saveConfig = function () {
|
||||
OC.msg.startSaving($msg);
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
url: OC.generateUrl('apps/guests/config'),
|
||||
data: config,
|
||||
dataType: 'json'
|
||||
}).success(function() {
|
||||
var data = { status:'success', data:{message:t('guests', 'Saved')} };
|
||||
OC.msg.finishedSaving($msg, data);
|
||||
}).fail(function(result) {
|
||||
var data = { status: 'error', data:{message:result.responseJSON.message} };
|
||||
OC.msg.finishedSaving($msg, data);
|
||||
});
|
||||
};
|
||||
|
||||
// load initial config
|
||||
loadConfig();
|
||||
|
||||
var updateConditions = function () {
|
||||
var conditions = [];
|
||||
if ($guestsByQuota.prop('checked')) {
|
||||
conditions.push('quota');
|
||||
}
|
||||
if ($guestsByGroup.prop('checked')) {
|
||||
conditions.push('group');
|
||||
}
|
||||
if ($guestsByContact.prop('checked')) {
|
||||
conditions.push('contact');
|
||||
}
|
||||
config.conditions = conditions;
|
||||
};
|
||||
|
||||
// listen to ui changes
|
||||
$guestsByQuota.on('change', function () {
|
||||
updateConditions();
|
||||
saveConfig();
|
||||
});
|
||||
$guestsByGroup.on('change', function () {
|
||||
updateConditions();
|
||||
saveConfig();
|
||||
});
|
||||
$guestsByContact.on('change', function () {
|
||||
updateConditions();
|
||||
saveConfig();
|
||||
});
|
||||
$guestGroup.on('change', function () {
|
||||
config.group = $guestGroup.val();
|
||||
saveConfig();
|
||||
});
|
||||
$guestApps.on('change', function () {
|
||||
var apps = $guestApps.val().split(',');
|
||||
config.apps = [];
|
||||
$.each(apps, function( index, value ) {
|
||||
config.apps.push(value.trim());
|
||||
});
|
||||
saveConfig();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
|
@ -43,12 +43,16 @@ class Backend implements UserInterface, IUserBackend {
|
|||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IGroupManager */
|
||||
private $groupManager;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
ILogger $logger,
|
||||
GuestMapper $mapper,
|
||||
IHasher $hasher,
|
||||
IManager $contactsManager,
|
||||
IUserManager $userManager,
|
||||
IGroupManager $groupManager
|
||||
) {
|
||||
$this->config = $config;
|
||||
|
@ -56,6 +60,7 @@ class Backend implements UserInterface, IUserBackend {
|
|||
$this->mapper = $mapper;
|
||||
$this->hasher = $hasher;
|
||||
$this->contactsManager = $contactsManager;
|
||||
$this->userManager = $userManager;
|
||||
$this->groupManager = $groupManager;
|
||||
}
|
||||
|
||||
|
@ -78,6 +83,7 @@ class Backend implements UserInterface, IUserBackend {
|
|||
new GuestMapper(\OC::$server->getDatabaseConnection(), $logger),
|
||||
\OC::$server->getHasher(),
|
||||
\OC::$server->getContactsManager(),
|
||||
\OC::$server->getUserManager(),
|
||||
\OC::$server->getGroupManager()
|
||||
);
|
||||
}
|
||||
|
@ -259,12 +265,13 @@ class Backend implements UserInterface, IUserBackend {
|
|||
}
|
||||
|
||||
public function isGuest($uid) {
|
||||
$conditions = $this->config->getAppValue('guests', 'conditions', 'quota');
|
||||
$conditions = explode(',',$conditions);
|
||||
return
|
||||
$uid !== '' && $this->userManager->userExists($uid) && (
|
||||
// TODO only check if enabled
|
||||
$this->isGuestByQuota($uid) ||
|
||||
$this->isGuestByGroup($uid) ||
|
||||
$this->isGuestByContact($uid)
|
||||
( in_array('quota', $conditions) && $this->isGuestByQuota($uid) ) ||
|
||||
( in_array('group', $conditions) && $this->isGuestByGroup($uid) ) ||
|
||||
( in_array('contact', $conditions) && $this->isGuestByContact($uid) )
|
||||
);
|
||||
|
||||
}
|
||||
|
@ -291,11 +298,37 @@ class Backend implements UserInterface, IUserBackend {
|
|||
return false;
|
||||
}
|
||||
public function isGuestByGroup($uid) {
|
||||
$this->groupManager->isInGroup($uid, 'guests');
|
||||
$group = $this->config->getAppValue('guests', 'group', 'guests');
|
||||
$this->groupManager->isInGroup($uid, $group);
|
||||
return false;
|
||||
}
|
||||
|
||||
const DEFAULT_GUEST_GROUPS = ',core,settings,avatar,files,files_trashbin,files_versions,files_sharing,files_texteditor,activity';
|
||||
public function getGuestApps () {
|
||||
return ['files'];
|
||||
$apps = $this->config->getAppValue('guests', 'apps', self::DEFAULT_GUEST_GROUPS);
|
||||
return explode(',', $apps);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Core has \OC::$REQUESTEDAPP but it isn't set until the routes are matched
|
||||
* taken from \OC\Route\Router::match()
|
||||
*/
|
||||
public function getRequestedApp($url) {
|
||||
if (substr($url, 0, 6) === '/apps/') {
|
||||
// empty string / 'apps' / $app / rest of the route
|
||||
list(, , $app,) = explode('/', $url, 4);
|
||||
|
||||
return \OC_App::cleanAppId($app);
|
||||
} else if (substr($url, 0, 6) === '/core/') {
|
||||
return 'core';
|
||||
} else if (substr($url, 0, 10) === '/settings/') {
|
||||
return 'settings';
|
||||
} else if (substr($url, 0, 8) === '/avatar/') {
|
||||
return 'avatar';
|
||||
} else if (substr($url, 0, 10) === '/heartbeat') {
|
||||
return 'heartbeat';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function createJail($uid) {
|
||||
|
|
|
@ -27,8 +27,16 @@ class Hooks {
|
|||
|
||||
foreach(\OC::$server->getUserManager()->getBackends() as $backend) {
|
||||
if ($backend instanceof Backend && $backend->isGuest($uid)) {
|
||||
$backend->createJail($uid);
|
||||
$app = $backend->getRequestedApp(\OC::$server->getRequest()->getRawPathInfo());
|
||||
if ( ! in_array($app, $backend->getGuestApps()) ) {
|
||||
// send forbidden and exit
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
|
||||
$l = \OC::$server->getL10NFactory()->get('guests');
|
||||
\OCP\Template::printErrorPage($l->t('Access to this resource is forbidden for guests.'));
|
||||
exit;
|
||||
}
|
||||
$backend->createJail($uid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING-AGPL file.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @copyright Jörn Friedrich Dreyer 2015
|
||||
*/
|
||||
|
||||
\OCP\Util::addScript('guests', 'guests');
|
||||
|
||||
$template = new \OCP\Template('guests', 'settings/admin');
|
||||
return $template->fetchPage();
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING-AGPL file.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @copyright Jörn Friedrich Dreyer 2015
|
||||
*/
|
||||
|
||||
/** @var $l OC_L10N */
|
||||
/** @var $_ array */
|
||||
?>
|
||||
<div class="section" id="guests">
|
||||
<h2>Guests</h2>
|
||||
<div>
|
||||
<span class="inlineblock user-info-label"><?php p($l->t('Treat users as Guests when:'));?></span><br/><br/>
|
||||
<input type="checkbox" id="guestsByQuota" value="quota"/><label for="guestsByQuota"><?php p($l->t('their quota is 0'));?></label><br/>
|
||||
<input type="checkbox" id="guestsByGroup" value="group"/><label for="guestsByGroup"><?php p($l->t('they are a member of group'));?></label>
|
||||
<input type="text" id="guestGroup" value="" /><br/>
|
||||
<input type="checkbox" id="guestsByContact" value="contact"/><label for="guestsByContact"><?php p($l->t('they are a contact of a regular user'));?></label><br/>
|
||||
<br/>
|
||||
<span class="inlineblock user-info-label"><?php p($l->t('Allow access to these apps:'));?></span><br/>
|
||||
<input type="text" id="guestApps" value="" style="width:99%;"/><br/>
|
||||
<span class="msg"></span>
|
||||
</div>
|
||||
</div>
|
Загрузка…
Ссылка в новой задаче