refactoring and let settings have an affect

Signed-off-by: dartcafe <github@dartcafe.de>
This commit is contained in:
dartcafe 2021-09-05 18:43:15 +02:00
Родитель a1415ea131
Коммит 45b6e61557
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: CCE73CEF3035D3C8
19 изменённых файлов: 377 добавлений и 55 удалений

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

@ -31,6 +31,7 @@ use OCA\Polls\Db\Poll;
use OCA\Polls\Service\PollService;
use OCA\Polls\Service\OptionService;
use OCA\Polls\Model\Acl;
use OCA\Polls\Model\AppSettings;
class PollController extends Controller {
@ -70,7 +71,12 @@ class PollController extends Controller {
public function list(): DataResponse {
return $this->response(function () {
return $this->pollService->list();
// return $this->pollService->list();
$appSettings = new AppSettings;
return [
'list' => $this->pollService->list(),
'pollCreationAllowed' => $appSettings->getCreationAllowed(),
];
});
}

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

@ -23,64 +23,66 @@
namespace OCA\Polls\Controller;
use OCP\IConfig;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCA\Polls\Model\Group;
use OCA\Polls\Service\SettingsService;
class SettingsController extends Controller {
/** @var IConfig */
private $config;
/** @var SettingsService */
private $settingsService;
use ResponseHandle;
public function __construct(
string $appName,
IRequest $request,
IConfig $config
SettingsService $settingsService
) {
parent::__construct($appName, $request);
$this->config = $config;
$this->settingsService = $settingsService;
}
/**
* Read globals
* Read app settings
* @NoAdminRequired
* @NoCSRFRequired
*/
public function getAppSettings(): DataResponse {
return $this->response(function (): array {
$appSettings = json_decode($this->config->getAppValue('polls', 'globals'));
// convert group ids to group objects
foreach ($appSettings->allowPublicSharesGroups as &$group) {
$group = new Group($group);
}
foreach ($appSettings->allowAllAccessGroups as &$group) {
$group = new Group($group);
}
foreach ($appSettings->allowPollCreationGroups as &$group) {
$group = new Group($group);
}
return ['appSettings' => $appSettings];
return ['appSettings' => $this->settingsService->getAppSettings()];
});
}
/**
* Write globals
* @NoCSRFRequired
* Write app settings
*/
public function writeAppSettings(array $appSettings): DataResponse {
// reduce groups to their ids
$appSettings['allowAllAccessGroups'] = array_column($appSettings['allowAllAccessGroups'], 'id');
$appSettings['allowPublicSharesGroups'] = array_column($appSettings['allowPublicSharesGroups'], 'id');
$appSettings['allowPollCreationGroups'] = array_column($appSettings['allowPollCreationGroups'], 'id');
$this->settingsService->writeAppSettings($appSettings);
return $this->response(function (): array {
return ['appSettings' => $this->settingsService->getAppSettings()];
});
}
/**
* Read user preferences
* @NoAdminRequired
*/
public function getUserSettings(): DataResponse {
return $this->response(function (): array {
return ['appSettings' => $this->settingsService->getUserSettings()];
});
}
return $this->response(function () use ($appSettings) {
$this->config->setAppValue('polls', 'globals', json_encode($appSettings));
return ['appSettings' => $this->getAppSettings()];
/**
* Write user preferences
* @NoAdminRequired
*/
public function writeUserSettings(array $appSettings): DataResponse {
$this->settingsService->writeUserSettings($appSettings);
return $this->response(function (): array {
return ['appSettings' => $this->settingsService->getAppSettings()];
});
}
}

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

@ -56,7 +56,6 @@ class SystemController extends Controller {
* Get a combined list of NC groups
*/
public function groupAll(): DataResponse {
\OC::$server->getLogger()->error('query=\'\'');
return new DataResponse(['groups' => $this->systemService->getGroups(
$query)], Http::STATUS_OK);
}
@ -65,7 +64,6 @@ class SystemController extends Controller {
* Get a combined list of NC groups
*/
public function groupSearch(string $query = ''): DataResponse {
\OC::$server->getLogger()->error('query= \''. $query . '\'');
return new DataResponse(['groups' => $this->systemService->getGroups(
$query)], Http::STATUS_OK);
}

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

@ -54,10 +54,15 @@ class Acl implements JsonSerializable {
public const PERMISSION_COMMENT_ADD = 'comment';
public const PERMISSION_OPTIONS_ADD = 'add_options';
public const PERMISSION_VOTE_EDIT = 'vote';
public const PERMISSION_PUBLIC_SHARES = 'publicShares';
public const PERMISSION_ALL_ACCESS = 'allAccess';
/** @var IUserManager */
private $userManager;
/** @var AppSettings */
private $appSettings;
/** @var IGroupManager */
private $groupManager;
@ -90,6 +95,7 @@ class Acl implements JsonSerializable {
$this->shareMapper = $shareMapper;
$this->poll = new Poll;
$this->share = new Share;
$this->appSettings = new AppSettings;
}
@ -220,6 +226,11 @@ class Acl implements JsonSerializable {
case self::PERMISSION_VOTE_EDIT:
return !$this->poll->getExpired() && $this->share->getType() !== Share::TYPE_PUBLIC;
case self::PERMISSION_ALL_ACCESS:
return $this->appSettings->getAllAccessAllowed();
case self::PERMISSION_PUBLIC_SHARES:
return $this->appSettings->getPublicSharesAllowed();
}
return false;
@ -234,10 +245,12 @@ class Acl implements JsonSerializable {
public function jsonSerialize(): array {
return [
'allowAddOptions' => $this->getIsAllowed(self::PERMISSION_OPTIONS_ADD),
'allowAllAccess' => $this->getIsAllowed(self::PERMISSION_ALL_ACCESS),
'allowArchive' => $this->getIsAllowed(self::PERMISSION_POLL_ARCHIVE),
'allowComment' => $this->getIsAllowed(self::PERMISSION_COMMENT_ADD),
'allowDelete' => $this->getIsAllowed(self::PERMISSION_POLL_DELETE),
'allowEdit' => $this->getIsAllowed(self::PERMISSION_POLL_EDIT),
'allowPublicShares' => $this->getIsAllowed(self::PERMISSION_PUBLIC_SHARES),
'allowSeeResults' => $this->getIsAllowed(self::PERMISSION_POLL_RESULTS_VIEW),
'allowSeeUsernames' => $this->getIsAllowed(self::PERMISSION_POLL_USERNAMES_VIEW),
'allowSubscribe' => $this->getIsAllowed(self::PERMISSION_POLL_SUBSCRIBE),

173
lib/Model/AppSettings.php Normal file
Просмотреть файл

@ -0,0 +1,173 @@
<?php
/**
* @copyright Copyright (c) 2017 Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
*
* @author René Gieling <github@dartcafe.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Polls\Model;
use JsonSerializable;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserSession;
use OCP\App\IAppManager;
use OCA\Circles\Api\v1\Circles;
use OCA\Circles\Model\Circle as CirclesCircle;
use OCA\Polls\Exceptions\CirclesNotEnabledException;
use OCA\Polls\AppInfo\Application;
class AppSettings implements JsonSerializable {
private const APP_NAME = 'polls';
/** @var IConfig */
private $config;
/** @var string */
private $userId = true;
/** @var bool */
private $allowPublicShares = true;
/** @var bool */
private $allowAllAccess = true;
/** @var bool */
private $allowPollCreation = true;
/** @var array */
private $publicSharesGroups = [];
/** @var array */
private $allAccessGroups = [];
/** @var array */
private $pollCreationGroups = [];
public function __construct() {
$this->config = self::getContainer()->query(IConfig::class);
$this->userId = self::getContainer()->query(IUserSession::class)->getUser()->getUID();
$this->groupManager = self::getContainer()->query(IGroupManager::class);
}
// Getters
public function getAllowPublicShares(): bool {
return !!$this->config->getAppValue(self::APP_NAME, 'allowPublicShares');
}
public function getAllowAllAccess(): bool {
return !!$this->config->getAppValue(self::APP_NAME, 'allowAllAccess');
}
public function getAllowPollCreation(): bool {
return !!$this->config->getAppValue(self::APP_NAME, 'allowPollCreation');
}
public function getPublicSharesGroups(): array {
return json_decode($this->config->getAppValue(self::APP_NAME, 'publicSharesGroups'));
}
public function getAllAccessGroups(): array {
return json_decode($this->config->getAppValue(self::APP_NAME, 'allAccessGroups'));
}
public function getPollCreationGroups(): array {
return json_decode($this->config->getAppValue(self::APP_NAME, 'pollCreationGroups'));
}
// Checks
public function getCreationAllowed() {
return $this->getAllowPollCreation() || $this->isMember($this->getPollCreationGroups());
}
public function getAllAccessAllowed() {
return $this->getAllowAllAccess() || $this->isMember($this->getAllAccessGroups());
}
public function getPublicSharesAllowed() {
return $this->getAllowPublicShares() || $this->isMember($this->getPublicSharesGroups());
}
// Setters
public function setAllowPublicShares(bool $value) {
$this->config->setAppValue(self::APP_NAME, 'allowPublicShares', $value);
}
public function setAllowAllAccess(bool $value) {
$this->config->setAppValue(self::APP_NAME, 'allowAllAccess', $value);
}
public function setAllowPollCreation(bool $value) {
$this->config->setAppValue(self::APP_NAME, 'allowPollCreation', $value);
}
public function setPublicSharesGroups(array $value) {
$this->config->setAppValue(self::APP_NAME, 'publicSharesGroups', json_encode($value));
}
public function setAllAccessGroups(array $value) {
$this->config->setAppValue(self::APP_NAME, 'allAccessGroups', json_encode($value));
}
public function setPollCreationGroups(array $value) {
$this->config->setAppValue(self::APP_NAME, 'pollCreationGroups', json_encode($value));
}
public function jsonSerialize() {
// convert group ids to group objects
$publicSharesGroups = [];
$allAccessGroups = [];
$pollCreationGroups = [];
foreach ($this->getPublicSharesGroups() as $group) {
$publicSharesGroups[] = new Group($group);
}
foreach ($this->getAllAccessGroups() as $group) {
$allAccessGroups[] = new Group($group);
}
foreach ($this->getPollCreationGroups() as $group) {
$pollCreationGroups[] = new Group($group);
}
return [
'allowPublicShares' => $this->getAllowPublicShares(),
'allowAllAccess' => $this->getAllowAllAccess(),
'allowPollCreation' => $this->getAllowPollCreation(),
'allAccessGroups' => $allAccessGroups,
'pollCreationGroups' => $pollCreationGroups,
'publicSharesGroups' => $publicSharesGroups,
// 'creationIsAllowed' => $this->getCreationAllowed(),
// 'allAccessIsAllowed' => $this->getAllAccessAllowed(),
// 'publicSharesIsAllowed' => $this->getPublicSharesAllowed(),
];
}
private function isMember(array $groups) {
foreach ($groups as $GID) {
if ($this->groupManager->isInGroup($this->userId, $GID)) {
return true;
}
}
return false;
}
protected static function getContainer() {
$app = \OC::$server->query(Application::class);
return $app->getContainer();
}
}

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

@ -217,6 +217,10 @@ class PollService {
throw new EmptyTitleException('Title must not be empty');
}
if (isset($poll['access']) && $poll['access'] === (Poll::ACCESS_PUBLIC)) {
$this->acl->request(Acl::PERMISSION_ALL_ACCESS);
}
// Set the expiry time to the actual servertime to avoid an
// expiry misinterpration when using acl
if (isset($poll['expire']) && $poll['expire'] < 0) {

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

@ -0,0 +1,91 @@
<?php
/**
* @copyright Copyright (c) 2017 Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
*
* @author René Gieling <github@dartcafe.de>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Polls\Service;
use OCP\IConfig;
use OCA\Polls\Model\AppSettings;
use OCA\Polls\Model\Group;
use OCA\Polls\AppInfo\Application;
class SettingsService {
/** @var IConfig */
private $config;
/** @var AppSettings */
private $appSettings;
/** @var String */
private $userId;
public function __construct(
?string $UserId,
IConfig $config
) {
$this->userId = $UserId;
$this->config = $config;
$this->appSettings = new AppSettings;
}
/**
* Get app settings with extended group information
*/
public function getAppSettings() {
return $this->appSettings;
}
/**
* Write app settings
*/
public function writeAppSettings(array $settingsArray): void {
$this->appSettings->setAllowPublicShares($settingsArray['allowPublicShares']);
$this->appSettings->setAllowAllAccess($settingsArray['allowAllAccess']);
$this->appSettings->setAllowPollCreation($settingsArray['allowPollCreation']);
$this->appSettings->setAllAccessGroups(array_column($settingsArray['allAccessGroups'], 'id'));
$this->appSettings->setPublicSharesGroups(array_column($settingsArray['publicSharesGroups'], 'id'));
$this->appSettings->setPollCreationGroups(array_column($settingsArray['pollCreationGroups'], 'id'));
}
/**
* Read user preferences
*/
public function getUserSettings(): object {
$userSettings = json_decode($this->config->getUserValue($this->userId, 'polls', 'preferences'));
return $userSettings;
}
/**
* Write user preferences
*/
public function writeUserSettings($preferences): void {
$this->config->setUserValue($this->user, 'polls', 'globals', json_encode($preferences));
}
protected static function getContainer() {
$app = \OC::$server->query(Application::class);
return $app->getContainer();
}
}

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

@ -244,7 +244,9 @@ class ShareService {
public function add(int $pollId, string $type, string $userId = ''): Share {
$this->acl->setPollId($pollId, Acl::PERMISSION_POLL_EDIT);
if ($type !== UserGroupClass::TYPE_PUBLIC) {
if ($type === UserGroupClass::TYPE_PUBLIC) {
$this->acl->request(ACL::PERMISSION_PUBLIC_SHARES);
} else {
try {
$this->shareMapper->findByPollAndUser($pollId, $userId);
throw new ShareAlreadyExistsException;

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

@ -98,9 +98,7 @@ class SystemService {
* @return Group[]
*/
public function getGroups(string $query = ''): array {
\OC::$server->getLogger()->error('hallo');
$groups = Group::search($query);
\OC::$server->getLogger()->error(json_encode($groups));
return $groups;
if ($query === '') {
return [];

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

@ -26,7 +26,7 @@
:to="{name: 'vote', params: {id: poll.id}}"
:class="{ closed: closed }">
<template #actions>
<ActionButton icon="icon-polls-clone" @click="$emit('clone-poll')">
<ActionButton v-if="isPollCreationAllowed" icon="icon-polls-clone" @click="$emit('clone-poll')">
{{ t('polls', 'Clone poll') }}
</ActionButton>
@ -54,7 +54,7 @@
<script>
import { mapGetters } from 'vuex'
import { mapState, mapGetters } from 'vuex'
import { ActionButton, AppNavigationItem } from '@nextcloud/vue'
export default {
@ -73,6 +73,10 @@ export default {
},
computed: {
...mapState({
isPollCreationAllowed: (state) => state.polls.isPollCreationAllowed,
}),
...mapGetters({
closed: 'poll/isClosed',
}),

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

@ -84,10 +84,10 @@ export default {
},
createPollGroups: {
get() {
return this.appSettings.allowPollCreationGroups
return this.appSettings.pollCreationGroups
},
set(value) {
this.writeValue({ allowPollCreationGroups: value })
this.writeValue({ pollCreationGroups: value })
},
},
},

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

@ -104,10 +104,10 @@ export default {
},
publicSharesGroups: {
get() {
return this.appSettings.allowPublicSharesGroups
return this.appSettings.publicSharesGroups
},
set(value) {
this.writeValue({ allowPublicSharesGroups: value })
this.writeValue({ publicSharesGroups: value })
},
},
allAccessLimited: {
@ -120,10 +120,10 @@ export default {
},
allAccessGroups: {
get() {
return this.appSettings.allowAllAccessGroups
return this.appSettings.allAccessGroups
},
set(value) {
this.writeValue({ allowAllAccessGroups: value })
this.writeValue({ allAccessGroups: value })
},
},
},

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

@ -50,9 +50,9 @@
<ConfigClosing @change="writePoll" />
</ConfigBox>
<ConfigBox :title="t('polls', 'Access')" icon-class="icon-category-auth">
<ConfigBox v-if="acl.isOwner || acl.allowAllAccess" :title="t('polls', 'Access')" icon-class="icon-category-auth">
<ConfigAdminAccess v-if="acl.isOwner" @change="writePoll" />
<ConfigAccess @change="writePoll" />
<ConfigAccess v-if="acl.allowAllAccess" @change="writePoll" />
</ConfigBox>
<ConfigBox :title="t('polls', 'Result display')" icon-class="icon-screen">

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

@ -27,7 +27,7 @@
<ConfigBox :title="t('polls', 'Add Shares')" icon-class="icon-add">
<UserSearch />
</ConfigBox>
<SharesPublic />
<SharesPublic v-if="allowPublicShares"/>
<SharesUnsent />
</div>
</template>
@ -54,6 +54,7 @@ export default {
computed: {
...mapState({
isOwner: (state) => state.poll.acl.isOwner,
allowPublicShares: (state) => state.poll.acl.allowPublicShares,
}),
},

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

@ -26,11 +26,11 @@ import { generateUrl } from '@nextcloud/router'
const defaultAppSettings = () => ({
appSettings: {
allowPublicShares: true,
allowPublicSharesGroups: [],
allowAllAccess: true,
allowAllAccessGroups: [],
allowPollCreation: true,
allowPollCreationGroups: [],
allAccessGroups: [],
publicSharesGroups: [],
pollCreationGroups: [],
},
})

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

@ -28,6 +28,7 @@ import { generateUrl } from '@nextcloud/router'
const state = {
list: [],
isPollCreationAllowed: false,
categories: [
{
id: 'relevant',
@ -36,6 +37,7 @@ const state = {
description: t('polls', 'All polls which are relevant or important to you, because you are a participant or the owner or you are invited to. Without polls closed more than five days ago.'),
icon: 'icon-details',
pinned: false,
createDependent: false,
},
{
id: 'my',
@ -44,6 +46,7 @@ const state = {
description: t('polls', 'Your polls (in which you are the owner).'),
icon: 'icon-user',
pinned: false,
createDependent: true,
},
{
id: 'hidden',
@ -52,6 +55,7 @@ const state = {
description: t('polls', 'All hidden polls, to which you have access.'),
icon: 'icon-polls-hidden-poll',
pinned: false,
createDependent: true,
},
{
id: 'participated',
@ -60,6 +64,7 @@ const state = {
description: t('polls', 'All polls, where you placed a vote.'),
icon: 'icon-polls-confirmed',
pinned: false,
createDependent: false,
},
{
id: 'public',
@ -68,6 +73,7 @@ const state = {
description: t('polls', 'A complete list with all public polls on this site, regardless who is the owner.'),
icon: 'icon-link',
pinned: false,
createDependent: true,
},
{
id: 'all',
@ -76,6 +82,7 @@ const state = {
description: t('polls', 'All polls, where you have access to.'),
icon: 'icon-polls',
pinned: false,
createDependent: false,
},
{
id: 'closed',
@ -84,6 +91,7 @@ const state = {
description: t('polls', 'All closed polls, where voting is disabled.'),
icon: 'icon-polls-closed',
pinned: false,
createDependent: false,
},
{
id: 'archived',
@ -92,6 +100,7 @@ const state = {
description: t('polls', 'Your archived polls are only accessible to you.'),
icon: 'icon-category-app-bundles',
pinned: true,
createDependent: true,
},
],
}
@ -102,9 +111,19 @@ const mutations = {
set(state, payload) {
Object.assign(state, payload)
},
setPollCreationAllowed(state, payload) {
state.isPollCreationAllowed = payload.pollCreationAllowed
},
}
const getters = {
categories(state) {
if (state.isPollCreationAllowed) {
return state.categories
}
return state.categories.filter((category) => (!category.createDependent))
},
filtered: (state) => (filterId) => {
if (filterId === 'all') {
return state.list.filter((poll) => (!poll.deleted))
@ -142,7 +161,8 @@ const actions = {
try {
const response = await axios.get(generateUrl(endPoint), { params: { time: +new Date() } })
context.commit('set', { list: response.data })
context.commit('set', { list: response.data.list })
context.commit('setPollCreationAllowed', { pollCreationAllowed: response.data.pollCreationAllowed })
} catch (e) {
console.error('Error loading polls', { error: e.response })
}

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

@ -22,9 +22,13 @@
*/
const defaultAcl = () => ({
allowComment: false,
allowEdit: false,
allowAddOptions: false,
allowAllAccess: false,
allowArchive: false,
allowComment: false,
allowDelete: false,
allowEdit: false,
allowPublicShares: false,
allowSeeResults: false,
allowSeeUsernames: false,
allowSubscribe: false,

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

@ -22,7 +22,10 @@
<template lang="html">
<AppNavigation>
<AppNavigationNew button-class="icon-add" :text="t('polls', 'Add new Poll')" @click="toggleCreateDlg" />
<AppNavigationNew v-if="isPollCreationAllowed"
button-class="icon-add"
:text="t('polls', 'Add new Poll')"
@click="toggleCreateDlg" />
<CreateDlg v-show="createDlg" ref="createDlg" @close-create="closeCreate()" />
<template #list>
<AppNavigationItem v-for="(pollCategory) in pollCategories"
@ -82,10 +85,11 @@ export default {
computed: {
...mapState({
pollCategories: (state) => state.polls.categories,
isPollCreationAllowed: (state) => state.polls.isPollCreationAllowed,
}),
...mapGetters({
pollCategories: 'polls/categories',
filteredPolls: 'polls/filtered',
}),

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

@ -56,7 +56,8 @@
@load-poll="loadPoll(poll.id)">
<template #actions>
<Actions :force-menu="true">
<ActionButton icon="icon-add"
<ActionButton v-if="isPollCreationAllowed"
icon="icon-add"
:close-after-click="true"
@click="clonePoll(poll.id)">
{{ t('polls', 'Clone poll') }}
@ -122,6 +123,7 @@ export default {
computed: {
...mapState({
pollCategories: (state) => state.polls.categories,
isPollCreationAllowed: (state) => state.polls.isPollCreationAllowed,
}),
...mapGetters({