Merge branch 'master' into develop

This commit is contained in:
Lucas Bartholemy 2023-02-21 11:20:46 +01:00
commit 1a50acf391
11 changed files with 127 additions and 96 deletions

View File

@ -4,7 +4,11 @@ HumHub Changelog
1.13.2 (Unreleased)
-------------------------
- Fix #5965: Suppress log warning 'Invalid session auth key attempted for user'
- Fix #6084: Automatic LDAP user registration broken when not all req. attributes provided
- Fix #6104: Fix update user with not existing group
- Fix #6103: Fix null passing to parse_str()
- Fix #6108: Fix log time in the `date()` function
- Fix #6122: Fix deleting a content with empty reason
1.13.1 (January 25, 2023)
-------------------------

View File

@ -314,7 +314,7 @@ class SettingController extends Controller
// I wish..
if ($dating) {
$dating = date('Y-m-d H:i:s', $dating->log_time);
$dating = date('Y-m-d H:i:s', (int) $dating->log_time);
} else {
$dating = "the begining of time";
}

View File

@ -149,7 +149,8 @@ class UserController extends Controller
'items' => UserEditForm::getGroupItems(),
'options' => [
'data-placeholder' => Yii::t('AdminModule.user', 'Select Groups'),
'data-placeholder-more' => Yii::t('AdminModule.user', 'Add Groups...')
'data-placeholder-more' => Yii::t('AdminModule.user', 'Add Groups...'),
'data-tags' => 'false'
],
'maxSelection' => 250,
'isVisible' => Yii::$app->user->can(new ManageGroups())

View File

@ -2,12 +2,11 @@
namespace humhub\modules\admin\models\forms;
use humhub\libs\Html;
use humhub\modules\user\models\GroupUser;
use Yii;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Group;
use humhub\modules\admin\permissions\ManageGroups;
use humhub\modules\user\models\Group;
use humhub\modules\user\models\GroupUser;
use humhub\modules\user\models\User;
use Yii;
/**
* Description of UserEditForm
@ -18,14 +17,13 @@ class UserEditForm extends User
{
/**
* GroupId selection array of the form.
* @var type
* @var array
*/
public $groupSelection;
/**
* Current member groups (models) of the given $user
* @var type
*
* @var Group[]
*/
public $currentGroups;
@ -103,19 +101,19 @@ class UserEditForm extends User
if (!$this->isCurrentlyMemberOf($groupId)) {
/* @var $group Group */
$group = Group::findOne(['id' => $groupId]);
if(!$group->is_admin_group || Yii::$app->user->isAdmin()) {
if ($group && (!$group->is_admin_group || Yii::$app->user->isAdmin())) {
$group->addUser($this);
}
}
}
}
return parent::afterSave($insert, $changedAttributes);
parent::afterSave($insert, $changedAttributes);
}
/**
* Checks if the given group (id or model object) is contained in the form selection
* @param integer $groupId groupId or Group model object
* @param int|Group $groupId groupId or Group model object
* @return boolean true if contained in selection else false
*/
private function isInGroupSelection($groupId)

View File

@ -9,7 +9,7 @@ use yii\web\View;
/* @var $name string */
/** @var OEmbedProviderForm $model */
parse_str($model->endpoint, $query);
parse_str($model->endpoint ?? '', $query);
$this->registerJs(<<<JS
function initEndpointInputs() {

View File

@ -13,18 +13,13 @@ use humhub\components\Controller;
use humhub\modules\content\models\Content;
use humhub\modules\content\models\forms\AdminDeleteContentForm;
use humhub\modules\content\Module;
use humhub\modules\content\notifications\ContentDeleted;
use humhub\modules\content\permissions\CreatePublicContent;
use humhub\modules\content\widgets\AdminDeleteModal;
use humhub\modules\stream\actions\StreamEntryResponse;
use Yii;
use yii\base\BaseObject;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\web\BadRequestHttpException;
use yii\web\ForbiddenHttpException;
use yii\web\HttpException;
use yii\web\NotAcceptableHttpException;
use yii\web\NotFoundHttpException;
use yii\web\Response;
@ -57,17 +52,15 @@ class ContentController extends Controller
*/
public function actionDelete()
{
Yii::$app->response->format = 'json';
$this->forcePostRequest();
$model = Yii::$app->request->get('model');
// Due to backward compatibility we use the old delete mechanism in case a model parameter is provided
$id = (int)($model != null) ? Yii::$app->request->get('id') : Yii::$app->request->post('id');
$id = $model ? Yii::$app->request->get('id') : Yii::$app->request->post('id');
/* @var $contentObjs Content */
$contentObj = ($model != null) ? Content::Get($model, $id) : Content::findOne(['id' => $id]);
/* @var $contentObj Content */
$contentObj = $model ? Content::Get($model, $id) : Content::findOne(['id' => $id]);
if (!$contentObj) {
throw new NotFoundHttpException();
@ -77,37 +70,19 @@ class ContentController extends Controller
throw new ForbiddenHttpException();
}
if ($contentObj !== null) {
$form = new AdminDeleteContentForm();
$form = new AdminDeleteContentForm(['content' => $contentObj]);
$form->load(Yii::$app->request->post());
if ($form->load(Yii::$app->request->post())) {
if (!$form->validate()) {
throw new BadRequestHttpException();
}
if ($form->notify) {
$contentDeleted = ContentDeleted::instance()
->from(Yii::$app->user->getIdentity())
->payload(['contentTitle' => (new ContentDeleted)->getContentPlainTextInfo($contentObj), 'reason' => $form->message]);
$contentDeleted->saveRecord($contentObj->createdBy);
$contentDeleted->record->updateAttributes([
'send_web_notifications' => 1
]);
}
}
$json = [
'success' => $contentObj->softDelete(),
'uniqueId' => $contentObj->getUniqueId(),
'model' => $model,
'pk' => $id
];
} else {
throw new HttpException(500, Yii::t('ContentModule.base', 'Could not delete content!'));
if (!$form->delete()) {
return $this->asJson(['error' => $form->getErrorsAsString()]);
}
return $json;
return $this->asJson([
'success' => true,
'uniqueId' => $contentObj->getUniqueId(),
'model' => $model,
'pk' => $id
]);
}
/**
@ -126,7 +101,7 @@ class ContentController extends Controller
}
if (!$contentObj->canEdit()) {
throw new HttpException(400);
throw new ForbiddenHttpException();
}
return [
@ -192,9 +167,7 @@ class ContentController extends Controller
{
$this->forcePostRequest();
$post = Yii::$app->request->post();
$content = Content::findOne(['id' => $post['id']]);
$content = Content::findOne(['id' => Yii::$app->request->post('id')]);
if (!$content) {
throw new NotFoundHttpException();
@ -204,26 +177,14 @@ class ContentController extends Controller
throw new ForbiddenHttpException();
}
$form = new AdminDeleteContentForm();
$form = new AdminDeleteContentForm(['content' => $content]);
$form->load(Yii::$app->request->post());
if ($form->load($post)) {
if (!$form->validate()) {
throw new BadRequestHttpException();
}
if ($form->notify) {
$contentDeleted = ContentDeleted::instance()
->from(Yii::$app->user->getIdentity())
->payload(['contentTitle' => (new ContentDeleted)->getContentPlainTextInfo($content), 'reason' => $form->message]);
$contentDeleted->saveRecord($content->createdBy);
$contentDeleted->record->updateAttributes([
'send_web_notifications' => 1
]);
}
if (!$form->delete()) {
return $this->asJson(['error' => $form->getErrorsAsString()]);
}
return $this->asJson(['success' => $content->softDelete()]);
return $this->asJson(['success' => true]);
}
public function actionReload($id)
@ -231,11 +192,11 @@ class ContentController extends Controller
$content = Content::findOne(['id' => $id]);
if (!$content) {
throw new HttpException(400, Yii::t('ContentModule.base', 'Invalid content id given!'));
throw new NotFoundHttpException(Yii::t('ContentModule.base', 'Invalid content id given!'));
}
if (!$content->canView()) {
throw new HttpException(403);
throw new ForbiddenHttpException();
}
return StreamEntryResponse::getAsJson($content);
@ -244,10 +205,9 @@ class ContentController extends Controller
/**
* Switches the content visibility for the given content.
*
* @param type $id content id
* @param int $id content id
* @return Response
* @throws Exception
* @throws HttpException
* @throws InvalidConfigException
* @throws \Throwable
* @throws \yii\db\IntegrityException
@ -258,11 +218,11 @@ class ContentController extends Controller
$content = Content::findOne(['id' => $id]);
if (!$content) {
throw new HttpException(400, Yii::t('ContentModule.base', 'Invalid content id given!'));
throw new NotFoundHttpException(Yii::t('ContentModule.base', 'Invalid content id given!'));
} elseif (!$content->canEdit()) {
throw new HttpException(403);
throw new ForbiddenHttpException();
} elseif ($content->isPrivate() && !$content->container->permissionManager->can(new CreatePublicContent())) {
throw new HttpException(403);
throw new ForbiddenHttpException();
}
if ($content->isPrivate()) {
@ -284,7 +244,6 @@ class ContentController extends Controller
* @param bool $lockComments True to lock comments, False to unlock
* @return Response
* @throws Exception
* @throws HttpException
* @throws InvalidConfigException
* @throws \Throwable
* @throws \yii\db\IntegrityException
@ -295,9 +254,9 @@ class ContentController extends Controller
$content = Content::findOne(['id' => $id]);
if (!$content) {
throw new HttpException(400, Yii::t('ContentModule.base', 'Invalid content id given!'));
throw new NotFoundHttpException(Yii::t('ContentModule.base', 'Invalid content id given!'));
} elseif (!$content->canLockComments()) {
throw new HttpException(403);
throw new ForbiddenHttpException();
}
$content->locked_comments = $lockComments;
@ -313,7 +272,6 @@ class ContentController extends Controller
* @param int $id Content id
* @return Response
* @throws Exception
* @throws HttpException
* @throws InvalidConfigException
* @throws \Throwable
* @throws \yii\db\IntegrityException
@ -329,7 +287,6 @@ class ContentController extends Controller
* @param int $id Content id
* @return Response
* @throws Exception
* @throws HttpException
* @throws InvalidConfigException
* @throws \Throwable
* @throws \yii\db\IntegrityException
@ -345,7 +302,6 @@ class ContentController extends Controller
* Returns JSON Output.
* @return Response
* @throws ForbiddenHttpException
* @throws HttpException
* @throws NotFoundHttpException
* @throws Exception
* @throws InvalidConfigException

View File

@ -2,8 +2,8 @@
namespace humhub\modules\content\models\forms;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\content\models\Content;
use humhub\modules\content\notifications\ContentDeleted;
use Yii;
use yii\base\Model;
@ -12,6 +12,11 @@ use yii\base\Model;
*/
class AdminDeleteContentForm extends Model
{
/**
* @var Content
*/
public $content;
/**
* @var string
*/
@ -43,4 +48,46 @@ class AdminDeleteContentForm extends Model
'notify' => Yii::t('CommentModule.base', 'Send a notification to author')
];
}
public function delete(): bool
{
if (!$this->validate()) {
return false;
}
if (!$this->notify()) {
return false;
}
return (bool) $this->content->softDelete();
}
public function notify(): bool
{
if (!$this->notify) {
return true;
}
$contentDeleted = ContentDeleted::instance()
->from(Yii::$app->user->getIdentity())
->payload([
'contentTitle' => (new ContentDeleted)->getContentPlainTextInfo($this->content),
'reason' => $this->message
]);
if (!$contentDeleted->saveRecord($this->content->createdBy)) {
$this->addError('message', Yii::t('ContentModule.base', 'Cannot notify the author.'));
return false;
}
$contentDeleted->record->updateAttributes([
'send_web_notifications' => 1
]);
return true;
}
public function getErrorsAsString(): string
{
return implode(' ', $this->getErrorSummary(true));
}
}

View File

@ -7,12 +7,12 @@
humhub.module('content', function (module, require, $) {
var client = require('client');
var util = require('util');
var object = util.object;
var string = util.string;
var actions = require('action');
var Component = actions.Component;
var event = require('event');
var modal = require('ui.modal');
var status = require('ui.status');
var DATA_CONTENT_KEY = "content-key";
var DATA_CONTENT_DELETE_URL = "content-delete-url";
@ -130,9 +130,13 @@ humhub.module('content', function (module, require, $) {
client.post(deleteUrl, {
data: postData
}).then(function (response) {
that.remove().then(function () {
resolve(true);
});
if (response.response.success) {
that.remove().then(function () {
resolve(true);
});
} else {
status.error(response.response.error);
}
}).catch(function (err) {
reject(err);
}).finally(function () {

View File

@ -579,4 +579,15 @@ class LdapAuth extends BaseFormAuth implements AutoSyncUsers, SyncAttributes, Ap
return $authClient;
}
/**
* @inheridoc
*/
public function beforeSerialize(): void
{
// Make sure we normalized user attributes before put it in session (anonymous functions)
$this->setNormalizeUserAttributeMap([]);
$this->_ldap = null;
}
}

View File

@ -34,7 +34,15 @@ class BaseClient extends \yii\authclient\BaseClient
*/
protected function initUserAttributes()
{
}
/**
* Workaround for serialization into session during the registration process
*
* @return void
*/
public function beforeSerialize(): void
{
}
}

View File

@ -36,7 +36,7 @@ class AuthController extends Controller
* after the response is generated.
*/
const EVENT_AFTER_LOGIN = 'afterLogin';
/**
* @event Triggered after an successful login but before checking user status
*/
@ -192,8 +192,10 @@ class AuthController extends Controller
return $this->login($user, $authClient);
}
// Make sure we normalized user attributes before put it in session (anonymous functions)
$authClient->setNormalizeUserAttributeMap([]);
if ($authClient instanceof \humhub\modules\user\authclient\BaseClient) {
/** @var \humhub\modules\user\authclient\BaseClient $authClient */
$authClient->beforeSerialize();
}
// Store authclient in session - for registration controller
Yii::$app->session->set('authClient', $authClient);