From aab8a34f78f4929f1807a22921eac9abae72ee82 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Sat, 14 Dec 2019 15:30:56 +0100 Subject: [PATCH 01/29] Allow sharing websites with groups without sharing source files Signed-off-by: Daniel Rudolf --- css/pico.scss | 6 +++ js/personal.js | 70 +++++++++++++++++++-------- lib/Controller/WebsitesController.php | 14 ++++++ lib/Model/Website.php | 17 +++++-- lib/Settings/Personal.php | 2 + templates/settings.personal.php | 69 ++++++++++++++++++++++++-- 6 files changed, 150 insertions(+), 28 deletions(-) diff --git a/css/pico.scss b/css/pico.scss index 3f879c5b..b7d4e87d 100644 --- a/css/pico.scss +++ b/css/pico.scss @@ -139,6 +139,12 @@ } } + .dialog-hint { + margin-top: -2px; + margin-bottom: calc(var(--margin)); + opacity: 0.7; + } + table.table { width: 100%; border: 1px solid var(--color-border); diff --git a/js/personal.js b/js/personal.js index 27802d4d..e8fa77c2 100644 --- a/js/personal.js +++ b/js/personal.js @@ -42,6 +42,7 @@ * @param {string} [options.route] * @param {jQuery|string} [options.template] * @param {jQuery|string} [options.itemTemplate] + * @param {jQuery|string} [options.privateSettingsTemplate] * @param {jQuery|string} [options.loadingTemplate] * @param {jQuery|string} [options.errorTemplate] * @param {string} [options.websiteBaseUrl] @@ -60,6 +61,9 @@ /** @member {jQuery} */ $itemTemplate: $(), + /** @member {jQuery} */ + $privateSettingsTemplate: $(), + /** @member {string} */ websiteBaseUrl: '', @@ -71,6 +75,7 @@ * @param {string} [options.route] * @param {jQuery|string} [options.template] * @param {jQuery|string} [options.itemTemplate] + * @param {jQuery|string} [options.privateSettingsTemplate] * @param {jQuery|string} [options.loadingTemplate] * @param {jQuery|string} [options.errorTemplate] * @param {string} [options.websiteBaseUrl] @@ -80,14 +85,17 @@ options = $.extend({ itemTemplate: $element.data('itemTemplate'), + privateSettingsTemplate: $element.data('privateSettingsTemplate'), websiteBaseUrl: $element.data('websiteBaseUrl') }, options); this.$itemTemplate = $(options.itemTemplate); + this.$privateSettingsTemplate = $(options.privateSettingsTemplate); this.websiteBaseUrl = options.websiteBaseUrl + ((options.websiteBaseUrl.substr(-1) !== '/') ? '/' : ''); var signature = 'OCA.CMSPico.WebsiteList.initialize()'; if (!this.$itemTemplate.length) throw signature + ': No valid item template given'; + if (!this.$privateSettingsTemplate.length) throw signature + ': No valid private settings template given'; if (this.websiteBaseUrl === '/') throw signature + ': No valid website base URL given'; this._init(); @@ -164,17 +172,18 @@ /** * @protected * - * @param {jQuery} $website - * @param {Object} websiteData - * @param {int} websiteData.id - * @param {string} websiteData.user_id - * @param {string} websiteData.name - * @param {string} websiteData.site - * @param {string} websiteData.theme - * @param {int} websiteData.type - * @param {Object} websiteData.options - * @param {string} websiteData.path - * @param {int} websiteData.creation + * @param {jQuery} $website + * @param {Object} websiteData + * @param {int} websiteData.id + * @param {string} websiteData.user_id + * @param {string} websiteData.name + * @param {string} websiteData.site + * @param {string} websiteData.theme + * @param {int} websiteData.type + * @param {Object} websiteData.options + * @param {string[]} [websiteData.options.group_access] + * @param {string} websiteData.path + * @param {int} websiteData.creation */ _setupItem: function ($website, websiteData) { var that = this; @@ -187,23 +196,42 @@ var filesUrl = OC.generateUrl('/apps/files/') + '?dir=' + OC.encodePath(websiteData.path); this._clickRedirect($website.find('.action-files'), filesUrl); - // toggle private website + // edit private websites settings + var websitePrivate = (websiteData.type === WEBSITE_TYPE_PRIVATE), + websiteGroupAccess = (websiteData.options || {}).group_access || []; $website.find('.action-private').each(function () { var $this = $(this), - $icon = $this.find('[class^="icon-"], [class*=" icon-"]'), - value = (websiteData.type === WEBSITE_TYPE_PRIVATE); + $icon = $this.find('[class^="icon-"], [class*=" icon-"]'); $icon - .addClass(value ? 'icon-lock' : 'icon-lock-open') - .removeClass(value ? 'icon-lock-open' : 'icon-lock'); + .addClass(websitePrivate ? 'icon-lock' : 'icon-lock-open') + .removeClass(websitePrivate ? 'icon-lock-open' : 'icon-lock'); + + var dialog = new OCA.CMSPico.Dialog(that.$privateSettingsTemplate, { + title: $this.data('originalTitle') || $this.prop('title') || $this.text(), + buttons: [ + { type: OCA.CMSPico.Dialog.BUTTON_ABORT }, + { type: OCA.CMSPico.Dialog.BUTTON_SUBMIT } + ] + }); - $this.data('value', value); + dialog.on('open.CMSPicoAdminList', function () { + var $inputType = this.$element.find('.input-private-' + (!websitePrivate ? 'public' : 'private')), + $inputGroups = this.$element.find('.input-private-groups'); - $this.on('click.CMSPicoWebsiteList', function (event) { - event.preventDefault(); + $inputType.prop('checked', true); + $inputGroups.val(websiteGroupAccess.join('|')); + OC.Settings.setupGroupsSelect($inputGroups); + }); + + dialog.on('submit.CMSPicoAdminList', function () { + var data = OCA.CMSPico.Util.serialize(this.$element); + that._updateItem(websiteData.id, data); + }); - var websiteType = $(this).data('value') ? WEBSITE_TYPE_PUBLIC : WEBSITE_TYPE_PRIVATE; - that._updateItem(websiteData.id, { type: websiteType }); + $this.on('click.CMSPicoAdminList', function (event) { + event.preventDefault(); + dialog.open(); }); }); diff --git a/lib/Controller/WebsitesController.php b/lib/Controller/WebsitesController.php index c16318ca..663bd81e 100644 --- a/lib/Controller/WebsitesController.php +++ b/lib/Controller/WebsitesController.php @@ -159,6 +159,20 @@ public function updatePersonalWebsite(int $siteId, array $data): DataResponse $website->setTheme($value); break; + case 'options': + foreach ($value as $optionKey => $optionValue) { + switch ($optionKey) { + case 'group_access': + $groupAccess = $optionValue ? explode('|', $optionValue) : []; + $website->setOption($optionKey, $groupAccess ?: null); + break; + + default: + throw new WebsiteInvalidDataException(); + } + } + break; + default: throw new WebsiteInvalidDataException(); } diff --git a/lib/Model/Website.php b/lib/Model/Website.php index 5acf9103..f5e6343c 100644 --- a/lib/Model/Website.php +++ b/lib/Model/Website.php @@ -145,12 +145,12 @@ public function assertViewerAccess(string $path, array $meta = []) return; } - $groupAccess = $meta['access']; - if (!is_array($groupAccess)) { - $groupAccess = explode(',', $groupAccess); + $groupPageAccess = $meta['access']; + if (!is_array($groupPageAccess)) { + $groupPageAccess = explode(',', $groupPageAccess); } - foreach ($groupAccess as $group) { + foreach ($groupPageAccess as $group) { $group = trim($group); if ($group === 'public') { @@ -174,6 +174,15 @@ public function assertViewerAccess(string $path, array $meta = []) return; } + $groupAccess = $this->getOption('group_access') ?? []; + foreach ($groupAccess as $group) { + if ($this->groupManager->groupExists($group)) { + if ($this->groupManager->isInGroup($this->getViewer(), $group)) { + return; + } + } + } + /** @var OCFolder $viewerOCFolder */ $viewerOCFolder = \OC::$server->getUserFolder($this->getViewer()); $viewerAccessClosure = function (OCNode $node) use ($viewerOCFolder) { diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index 85e9d537..815d32e3 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -89,6 +89,8 @@ public function getForm(): TemplateResponse $data = [ 'exampleSite' => $exampleSite, 'baseUrl' => $baseUrl, + 'typePublic' => Website::TYPE_PUBLIC, + 'typePrivate' => Website::TYPE_PRIVATE, 'nameLengthMin' => Website::NAME_LENGTH_MIN, 'nameLengthMax' => Website::NAME_LENGTH_MAX, 'siteLengthMin' => Website::SITE_LENGTH_MIN, diff --git a/templates/settings.personal.php b/templates/settings.personal.php index 95dd8a95..3d6896e2 100644 --- a/templates/settings.personal.php +++ b/templates/settings.personal.php @@ -99,6 +99,7 @@ data-route="/apps/cms_pico/personal/websites" data-template="#picocms-websites-template" data-item-template="#picocms-websites-template-item" + data-private-settings-template="#picocms-websites-template-private-settings" data-loading-template="#picocms-websites-template-loading" data-error-template="#picocms-websites-template-error" data-website-base-url=""> @@ -144,9 +145,9 @@ t('Go to website directory')); ?> + title="t('Edit private website settings')); ?>"> - t('Toggle private website')); ?> + t('Edit private website settings')); ?> @@ -175,7 +176,7 @@
  • - t('Toggle private website')); ?> + t('Edit private website settings')); ?>
  • @@ -225,6 +226,68 @@ + + + + + +