Merge branch 'master' into develop

This commit is contained in:
Lucas Bartholemy 2023-10-29 09:48:52 +01:00
commit c3e0d27c28
43 changed files with 183 additions and 94 deletions

View File

@ -57,7 +57,7 @@ jobs:
steps:
- name: Start Selenium
run: |
docker run --detach --net=host --shm-size="2g" selenium/standalone-chrome
docker run --detach --net=host --shm-size="2g" selenium/standalone-chrome:117.0-20230926
- uses: actions/checkout@v2
- uses: actions/setup-node@v1

View File

@ -8,6 +8,8 @@ HumHub Changelog
- Fix #6614: Fix undefined error on live event of follow action
- Fix #6615: Improve scrolling to anchor with fixed header
- Fix #6629: Fix visibility of new message counter on space chooser
- Fix #6630: Fix visibility of top sorted stream entries on dashboard from external filters
- Fix #6635: Fix visibility of the method `Controller::getAccessRules()`
1.14.4 (September 20, 2023)
---------------------------

View File

@ -24,7 +24,7 @@ use yii\web\HttpException;
* Disable guest access for all controller actions:
*
* ```php
* public function getAccessRules()
* protected function getAccessRules()
* {
* return [
* ['login']
@ -35,7 +35,7 @@ use yii\web\HttpException;
* Disable guest access for specific controller actions:
*
* ```php
* public function getAccessRules()
* protected function getAccessRules()
* {
* return [
* ['login' => ['action1', 'action2']]
@ -46,7 +46,7 @@ use yii\web\HttpException;
* All users have to be logged in + additional permission check for 'action1' and 'action2':
*
* ```php
* public function getAccessRules()
* protected function getAccessRules()
* {
* return [
* ['login'],
@ -58,7 +58,7 @@ use yii\web\HttpException;
* Custom inline validator for action 'action1':
*
* ```php
* public function getAccessRules()
* protected function getAccessRules()
* {
* return [
* ['validateMyCustomRule', 'someParameter' => 'someValue', 'actions' => ['action1']]

View File

@ -22,7 +22,7 @@ class OembedController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [['login']];
}

View File

@ -25,7 +25,7 @@ class AdminController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageSettings::class],

View File

@ -62,12 +62,9 @@ class Controller extends \humhub\components\Controller
}
/**
* Returns access rules for the standard access control behavior
*
* @return array the access permissions
* @see AccessControl
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
// Use by default ManageSettings permission if method is not overwritten by custom module
if ($this->module->id !== 'admin') {

View File

@ -39,13 +39,13 @@ class ApprovalController extends Controller
{
$this->subLayout = '@admin/views/layouts/user';
$this->appendPageTitle(Yii::t('AdminModule.base', 'Approval'));
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY],

View File

@ -38,13 +38,13 @@ class AuthenticationController extends Controller
$this->subLayout = '@admin/views/layouts/user';
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageSettings::class]

View File

@ -42,13 +42,13 @@ class GroupController extends Controller
$this->subLayout = '@admin/views/layouts/user';
$this->appendPageTitle(Yii::t('AdminModule.base', 'Groups'));
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageGroups::class],

View File

@ -37,16 +37,19 @@ class InformationController extends Controller
*/
public $defaultAction = 'about';
/**
* @inheritdoc
*/
public function init()
{
$this->subLayout = '@admin/views/layouts/information';
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => \humhub\modules\admin\permissions\SeeAdminInformation::class],

View File

@ -32,13 +32,13 @@ class LoggingController extends Controller
$this->appendPageTitle(Yii::t('AdminModule.base', 'Logging'));
$this->subLayout = '@admin/views/layouts/information';
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => SeeAdminInformation::class]

View File

@ -39,13 +39,13 @@ class ModuleController extends Controller
{
$this->appendPageTitle(Yii::t('AdminModule.base', 'Modules'));
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [

View File

@ -34,7 +34,7 @@ class PendingRegistrationsController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[

View File

@ -28,7 +28,6 @@ use humhub\models\UrlOembed;
use humhub\modules\admin\components\Controller;
use humhub\modules\admin\models\Log;
use humhub\modules\notification\models\forms\NotificationSettings;
use yii\base\BaseObject;
/**
* SettingController
@ -65,13 +64,13 @@ class SettingController extends Controller
]);
$this->subLayout = '@admin/views/layouts/setting';
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageSettings::class]

View File

@ -41,13 +41,13 @@ class SpaceController extends Controller
$this->subLayout = '@admin/views/layouts/space';
$this->appendPageTitle(Yii::t('AdminModule.base', 'Spaces'));
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => [ManageSpaces::class, ManageSettings::class]],

View File

@ -55,7 +55,7 @@ class UserController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => [ManageUsers::class, ManageGroups::class]],

View File

@ -40,7 +40,7 @@ class UserPeopleController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => [ManageSettings::class]]

View File

@ -11,13 +11,10 @@ use humhub\modules\admin\components\Controller;
use humhub\modules\admin\permissions\ManageSettings;
use humhub\modules\admin\permissions\ManageUsers;
use humhub\modules\content\components\ContentContainerDefaultPermissionManager;
use humhub\modules\content\models\ContentContainerDefaultPermission;
use humhub\modules\content\models\ContentContainerPermission;
use humhub\modules\content\models\ContentContainerSetting;
use humhub\modules\user\models\User;
use humhub\modules\user\Module;
use Yii;
use yii\db\Expression;
use yii\web\HttpException;
/**
@ -47,7 +44,7 @@ class UserPermissionsController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => [ManageUsers::class]],

View File

@ -39,13 +39,13 @@ class UserProfileController extends Controller
$this->appendPageTitle(Yii::t('AdminModule.base', 'Userprofiles'));
$this->subLayout = '@admin/views/layouts/user';
return parent::init();
parent::init();
}
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageUsers::class]

View File

@ -39,9 +39,9 @@ use yii\web\NotFoundHttpException;
class CommentController extends Controller
{
/**
* @return array
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY => ['post', 'edit', 'delete']],

View File

@ -4,8 +4,6 @@ namespace humhub\modules\dashboard\stream;
use humhub\modules\activity\stream\ActivityStreamQuery;
use humhub\modules\dashboard\Module;
use humhub\modules\dashboard\stream\filters\DashboardGuestStreamFilter;
use humhub\modules\dashboard\stream\filters\DashboardMemberStreamFilter;
use Yii;
/**
@ -25,8 +23,6 @@ class DashboardStreamQuery extends ActivityStreamQuery
*/
public function beforeApplyFilters()
{
parent::beforeApplyFilters();
if (empty($this->user)) {
$this->addFilterHandler(Module::getModuleInstance()->guestFilterClass);
} else {
@ -34,6 +30,8 @@ class DashboardStreamQuery extends ActivityStreamQuery
'class' => Module::getModuleInstance()->memberFilterClass,
'user' => $this->user]));
}
parent::beforeApplyFilters();
}
}

View File

@ -31,7 +31,7 @@ class FileController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY => ['upload', 'delete']]

View File

@ -26,7 +26,7 @@ class BrowseController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageModules::class]

View File

@ -32,7 +32,7 @@ class PurchaseController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageModules::class]

View File

@ -23,7 +23,7 @@ class UpdateController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageModules::class]

View File

@ -25,7 +25,7 @@ class AdminController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['permissions' => ManageSettings::class],

View File

@ -30,7 +30,7 @@ class EntryController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY]

View File

@ -22,9 +22,9 @@ use yii\db\IntegrityException;
class ListController extends Controller
{
/**
* @inheritDoc
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY]

View File

@ -29,7 +29,7 @@ class OverviewController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY]

View File

@ -10,7 +10,7 @@ namespace humhub\modules\search\controllers;
use humhub\components\Controller;
use humhub\libs\ParameterEvent;
use \humhub\modules\comment\Module as CommentModule;
use humhub\modules\comment\Module as CommentModule;
use humhub\modules\content\components\ContentContainerActiveRecord;
use humhub\modules\content\models\Content;
use humhub\modules\post\models\Post;
@ -45,7 +45,7 @@ class MentioningController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['login']

View File

@ -48,7 +48,7 @@ class SearchController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['login']

View File

@ -36,7 +36,10 @@ use yii\web\HttpException;
*/
class MembershipController extends ContentContainerController
{
public function getAccessRules()
/**
* @inheritdoc
*/
protected function getAccessRules()
{
return [
['permission' => [InviteUsers::class], 'actions' => ['invite']],

View File

@ -21,7 +21,10 @@ class ImageController extends ContainerImageController
{
public $validContentContainerClasses = [Space::class];
public function getAccessRules()
/**
* @inheritdoc
*/
protected function getAccessRules()
{
return [
[ContentContainerControllerAccess::RULE_USER_GROUP_ONLY => [Space::USERGROUP_ADMIN]],

View File

@ -1,13 +1,10 @@
<?php
namespace humhub\modules\stream\models;
use humhub\modules\content\components\ContentContainerActiveRecord;
use humhub\modules\stream\models\filters\ContentContainerStreamFilter;
use humhub\modules\stream\models\filters\PinnedContentStreamFilter;
use humhub\modules\stream\models\filters\StreamQueryFilter;
use yii\base\InvalidConfigException;
/**
@ -33,8 +30,6 @@ class ContentContainerStreamQuery extends WallStreamQuery
*/
protected function beforeApplyFilters()
{
parent::beforeApplyFilters();
$this->addFilterHandler(
new ContentContainerStreamFilter(['container' => $this->container]),
true,
@ -45,5 +40,6 @@ class ContentContainerStreamQuery extends WallStreamQuery
$this->addFilterHandler(new PinnedContentStreamFilter(['container' => $this->container]));
}
parent::beforeApplyFilters();
}
}

View File

@ -143,6 +143,13 @@ class StreamQuery extends Model
ScheduledContentStreamFilter::class
];
/**
* @var array Excluded query filter handlers from adding
* @see [[removeFilterHandler(..., $exclude = true)]]
* @since 1.14.5
*/
public $excludedFilterHandlers = [];
/**
* Per default only content with published state are returned.
*
@ -422,7 +429,10 @@ class StreamQuery extends Model
Yii::warning('StreamQuery::postProcessAll - invalid FilterHandler: ' . var_export($filterHandler, true), 'content');
}
}
return $result;
// Remove duplicates, they may exist after fetch top sorted items by different way,
// e.g. when a Content is top sorted as Draft and as Unread News
return array_values(ArrayHelper::index($result, 'id'));
}
/**
@ -583,8 +593,11 @@ class StreamQuery extends Model
* ```php
* protected function beforeApplyFilters()
* {
* parent::beforeApplyFilters();
* $this->removeFilterHandler(SomeStreamFilter::class);
* $this->addFilterHandler(MyStreamFilter::class);
* // NOTE: Put the parent method here in the end of this method in order to have
* // all core applied filters when external event triggers will be called
* parent::beforeApplyFilters();
* }
* ```
*
@ -627,14 +640,18 @@ class StreamQuery extends Model
*
* @param string|StreamQueryFilter $handler
* @param bool $overwrite whether or not to overwrite existing filters of the same class
* @return StreamQueryFilter initialized stream filter
* @return StreamQueryFilter|null initialized stream filter
* @throws InvalidConfigException
* @since 1.6
*/
public function addFilterHandler($handler, $overwrite = true, $prepend = false)
{
if ($this->isExcludedFilterHandler($handler)) {
return null;
}
if ($overwrite) {
$this->removeFilterHandler($handler);
$this->removeFilterHandler($handler, false);
}
$handler = $this->prepareHandler($handler);
@ -665,7 +682,10 @@ class StreamQuery extends Model
{
$result = [];
foreach ($handlers as $handler) {
$result[] = $this->addFilterHandler($handler, $overwrite);
$handler = $this->addFilterHandler($handler, $overwrite);
if ($handler !== null) {
$result[] = $handler;
}
}
return $result;
@ -674,12 +694,11 @@ class StreamQuery extends Model
/**
* Can be used to remove filters by filter class.
*
* @param $handler
* @return StreamQueryFilter
* @throws InvalidConfigException
* @param string|StreamQueryFilter $handlerToRemove
* @param bool $exclude Exclude from further adding
* @since 1.6
*/
public function removeFilterHandler($handlerToRemove)
public function removeFilterHandler($handlerToRemove, bool $exclude = true)
{
$result = [];
$handlerToRemoveClass = is_string($handlerToRemove) ? $handlerToRemove : get_class($handlerToRemove);
@ -690,21 +709,37 @@ class StreamQuery extends Model
}
$this->filterHandlers = $result;
if ($exclude && !$this->isExcludedFilterHandler($handlerToRemoveClass)) {
$this->excludedFilterHandlers[] = $handlerToRemoveClass;
}
}
/**
* Check the filter handler is excluded
*
* @param string|StreamQueryFilter $handler
* @return bool
*/
public function isExcludedFilterHandler($handler): bool
{
$handler = is_string($handler) ? $handler : get_class($handler);
return in_array($handler, $this->excludedFilterHandlers);
}
/**
* Can be used to search for a filter handler by class.
*
* @param $handler
* @return StreamQueryFilter
* @param string|StreamQueryFilter $class
* @return StreamQueryFilter|null
* @throws InvalidConfigException
* @since 1.6
*/
public function getFilterHandler($class): ?StreamQueryFilter
{
$handlerToRemoveClass = is_string($class) ? $class : get_class($class);
$handlerClass = is_string($class) ? $class : get_class($class);
foreach ($this->filterHandlers as $handler) {
if (is_a($handler, $handlerToRemoveClass, true)) {
if (is_a($handler, $handlerClass, true)) {
return $this->prepareHandler($handler);
}
}

View File

@ -6,6 +6,7 @@ use humhub\modules\content\models\Content;
use humhub\modules\post\models\Post;
use humhub\modules\space\models\Space;
use humhub\modules\stream\actions\Stream;
use humhub\modules\stream\models\filters\DefaultStreamFilter;
use humhub\modules\stream\models\StreamQuery;
use tests\codeception\_support\HumHubDbTestCase;
use yii\base\Exception;
@ -47,6 +48,28 @@ class StreamQueryTest extends HumHubDbTestCase
return $post;
}
private function removeArrayValue(array $array, $value): array
{
$i = array_search($value, $array);
if ($i === false) {
return $array;
}
unset($array[$i]);
return array_values($array);
}
private function arrayValuesAsClassName(array $array): array
{
foreach ($array as $i => $item) {
if (is_object($item)) {
$array[$i] = get_class($item);
}
}
return $array;
}
/**
* Tests Stream::SORT_CREATED_AT query order. The result should ignore the stream sort date.
* @throws Exception
@ -199,4 +222,36 @@ class StreamQueryTest extends HumHubDbTestCase
$this->assertEquals($p1->message, $result[0]->getModel()->message);
}
/**
* Test methods to add/remove/exclude filter handlers
*/
public function testFilterHandlers()
{
$streamQuery = new StreamQuery();
$defaultFilterHandlers = $streamQuery->filterHandlers;
$this->assertEquals([], $streamQuery->excludedFilterHandlers);
// Remove a handler but don't exclude(allow to add it later)
$streamQuery->removeFilterHandler(DefaultStreamFilter::class, false);
$customFilterHandlers = $this->removeArrayValue($defaultFilterHandlers, DefaultStreamFilter::class);
$this->assertEquals($customFilterHandlers, $streamQuery->filterHandlers);
$this->assertEquals([], $streamQuery->excludedFilterHandlers);
// Add the same handler removed before
$streamQuery->addFilterHandler(DefaultStreamFilter::class);
$customFilterHandlers[] = DefaultStreamFilter::class;
$this->assertEquals($customFilterHandlers, $this->arrayValuesAsClassName($streamQuery->filterHandlers));
// Remove a handler with excluding completely(deny adding it later)
$streamQuery->removeFilterHandler(DefaultStreamFilter::class, true);
$customFilterHandlers = $this->removeArrayValue($defaultFilterHandlers, DefaultStreamFilter::class);
$this->assertEquals($customFilterHandlers, $streamQuery->filterHandlers);
$this->assertEquals([DefaultStreamFilter::class], $streamQuery->excludedFilterHandlers);
// Try to add the same handler which was excluded completely(without possibility further adding)
$streamQuery->addFilterHandler(DefaultStreamFilter::class);
$this->assertEquals($customFilterHandlers, $this->arrayValuesAsClassName($streamQuery->filterHandlers));
}
}

View File

@ -19,7 +19,10 @@ use yii\web\HttpException;
class ManageController extends ContentContainerController
{
public function getAccessRules()
/**
* @inheritdoc
*/
protected function getAccessRules()
{
return [
['login'],

View File

@ -8,13 +8,8 @@
namespace humhub\modules\topic\controllers;
use humhub\modules\content\components\ContentContainerController;
use humhub\modules\content\models\Content;
use humhub\modules\topic\models\forms\ContentTopicsForm;
use humhub\modules\topic\widgets\TopicPicker;
use Yii;
use yii\web\HttpException;
class TopicController extends ContentContainerController
{
@ -26,7 +21,7 @@ class TopicController extends ContentContainerController
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
['json']

View File

@ -9,10 +9,10 @@
namespace humhub\modules\tour\controllers;
use humhub\modules\space\models\Membership;
use humhub\modules\space\models\Space;
use humhub\modules\tour\Module;
use Yii;
use yii\web\HttpException;
use humhub\modules\space\models\Space;
/**
* TourController
@ -23,7 +23,10 @@ use humhub\modules\space\models\Space;
*/
class TourController extends \humhub\components\Controller
{
public function getAccessRules()
/**
* @inheritdoc
*/
protected function getAccessRules()
{
return [
['login']

View File

@ -28,7 +28,7 @@ class BaseAccountController extends \humhub\components\Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY]
@ -46,7 +46,7 @@ class BaseAccountController extends \humhub\components\Controller
public function init()
{
$this->appendPageTitle(\Yii::t('UserModule.base', 'My Account'));
return parent::init();
parent::init();
}
/**

View File

@ -49,7 +49,10 @@ class ImageController extends ContainerImageController
}
}
public function getAccessRules()
/**
* @inheritdoc
*/
protected function getAccessRules()
{
return [
['validateAccess'],

View File

@ -44,7 +44,7 @@ class PeopleController extends Controller
/**
* @inheritdoc
*/
public function getAccessRules()
protected function getAccessRules()
{
return [
[ControllerAccess::RULE_LOGGED_IN_ONLY],

View File

@ -1,12 +1,8 @@
<?php
namespace humhub\modules\user\stream;
use humhub\modules\stream\actions\ContentContainerStream;
use humhub\modules\stream\models\filters\ContentContainerStreamFilter;
use humhub\modules\stream\models\WallStreamQuery;
use humhub\modules\user\models\User;
use humhub\modules\user\stream\filters\IncludeAllContributionsFilter;
use humhub\modules\stream\models\ContentContainerStreamQuery;
@ -28,7 +24,6 @@ class ProfileStreamQuery extends ContentContainerStreamQuery
*/
public function beforeApplyFilters()
{
parent::beforeApplyFilters();
$this->removeFilterHandler(ContentContainerStreamFilter::class);
// The default scope may be overwritten by first request, the real default is handled in the stream filter navigation
@ -38,5 +33,7 @@ class ProfileStreamQuery extends ContentContainerStreamQuery
? IncludeAllContributionsFilter::SCOPE_ALL
: IncludeAllContributionsFilter::SCOPE_PROFILE
]));
parent::beforeApplyFilters();
}
}