This commit is contained in:
Jörn Friedrich Dreyer 2015-09-23 15:03:47 +02:00
Родитель a964afc6d4
Коммит f317df3c12
9 изменённых файлов: 340 добавлений и 9 удалений

Просмотреть файл

@ -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');

25
appinfo/routes.php Normal file
Просмотреть файл

@ -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();
}
}

136
js/guests.js Normal file
Просмотреть файл

@ -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;
}
}

15
settings/admin.php Normal file
Просмотреть файл

@ -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>