看板初始化提交
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Kanboard\Core\Security\AuthenticationManager;
|
||||
use Kanboard\Core\Session\SessionManager;
|
||||
use Kanboard\Event\AuthSuccessEvent;
|
||||
use Kanboard\Event\AuthFailureEvent;
|
||||
|
||||
/**
|
||||
* Authentication Subscriber
|
||||
*
|
||||
* @package subscriber
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AuthSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* Get event listeners
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
AuthenticationManager::EVENT_SUCCESS => 'afterLogin',
|
||||
AuthenticationManager::EVENT_FAILURE => 'onLoginFailure',
|
||||
SessionManager::EVENT_DESTROY => 'afterLogout',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* After Login callback
|
||||
*
|
||||
* @access public
|
||||
* @param AuthSuccessEvent $event
|
||||
*/
|
||||
public function afterLogin(AuthSuccessEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
|
||||
$userAgent = $this->request->getUserAgent();
|
||||
$ipAddress = $this->request->getIpAddress();
|
||||
|
||||
$this->userLockingModel->resetFailedLogin($this->userSession->getUsername());
|
||||
$this->captchaModel->resetFailedLogin($ipAddress);
|
||||
|
||||
$this->lastLoginModel->create(
|
||||
$event->getAuthType(),
|
||||
$this->userSession->getId(),
|
||||
$ipAddress,
|
||||
$userAgent
|
||||
);
|
||||
|
||||
if ($event->getAuthType() === 'RememberMe') {
|
||||
$this->userSession->setPostAuthenticationAsValidated();
|
||||
}
|
||||
|
||||
if (REMEMBER_ME_AUTH && session_is_true('hasRememberMe') && ! $this->userSession->hasPostAuthentication()) {
|
||||
$session = $this->rememberMeSessionModel->create($this->userSession->getId(), $ipAddress, $userAgent);
|
||||
$this->rememberMeCookie->write($session['token'], $session['sequence'], $session['expiration']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy RememberMe session on logout
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function afterLogout()
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$credentials = $this->rememberMeCookie->read();
|
||||
|
||||
if ($credentials !== false) {
|
||||
$session = $this->rememberMeSessionModel->find($credentials['token'], $credentials['sequence']);
|
||||
|
||||
if (! empty($session)) {
|
||||
$this->rememberMeSessionModel->remove($session['id']);
|
||||
}
|
||||
|
||||
$this->rememberMeCookie->remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment failed login counter
|
||||
*
|
||||
* @access public
|
||||
* @param AuthFailureEvent $event
|
||||
*/
|
||||
public function onLoginFailure(AuthFailureEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$username = $event->getUsername();
|
||||
$ipAddress = $this->request->getIpAddress();
|
||||
|
||||
// IP-based captcha
|
||||
$this->captchaModel->incrementFailedLogin($ipAddress);
|
||||
|
||||
if (! empty($username)) {
|
||||
// log login failure in web server log to allow fail2ban usage
|
||||
error_log('Kanboard: user '.$username.' authentication failure with IP address: '.$ipAddress);
|
||||
$this->userLockingModel->incrementFailedLogin($username);
|
||||
|
||||
if ($this->userLockingModel->getFailedLogin($username) > BRUTEFORCE_LOCKDOWN) {
|
||||
$this->userLockingModel->lock($username, BRUTEFORCE_LOCKDOWN_DURATION);
|
||||
}
|
||||
} else {
|
||||
// log login failure in web server log to allow fail2ban usage
|
||||
error_log('Kanboard: user Unknown authentication failure with IP address: '.$ipAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Base class for subscribers
|
||||
*
|
||||
* @package subscriber
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class BaseSubscriber extends Base
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class BootstrapSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
'app.bootstrap' => 'execute',
|
||||
);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$this->languageModel->loadCurrentLanguage();
|
||||
$this->timezoneModel->setCurrentTimezone();
|
||||
$this->actionManager->attachEvents();
|
||||
|
||||
if ($this->userSession->isLogged()) {
|
||||
session_set('hasSubtaskInProgress', $this->subtaskStatusModel->hasSubtaskInProgress($this->userSession->getId()));
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (DEBUG) {
|
||||
foreach ($this->db->getLogMessages() as $message) {
|
||||
$this->logger->debug('SQL: ' . $message);
|
||||
}
|
||||
|
||||
$this->logger->debug('APP: nb_queries={nb}', array('nb' => $this->db->getStatementHandler()->getNbQueries()));
|
||||
$this->logger->debug('APP: rendering_time={time}', array('time' => microtime(true) - $this->request->getStartTime()));
|
||||
$this->logger->debug('APP: memory_usage='.$this->helper->text->bytes(memory_get_usage()));
|
||||
$this->logger->debug('APP: uri='.$this->request->getUri());
|
||||
$this->logger->debug('###############################################');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Core\User\UserProfile;
|
||||
use Kanboard\Event\UserProfileSyncEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Class LdapUserPhotoSubscriber
|
||||
*
|
||||
* @package Kanboard\Subscriber
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LdapUserPhotoSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* Get event listeners
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
UserProfile::EVENT_USER_PROFILE_AFTER_SYNC => 'syncUserPhoto',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the user profile photo from LDAP to the object storage
|
||||
*
|
||||
* @access public
|
||||
* @param UserProfileSyncEvent $event
|
||||
*/
|
||||
public function syncUserPhoto(UserProfileSyncEvent $event)
|
||||
{
|
||||
if (is_a($event->getUser(), 'Kanboard\User\LdapUserProvider')) {
|
||||
$profile = $event->getProfile();
|
||||
$photo = $event->getUser()->getPhoto();
|
||||
|
||||
if (empty($profile['avatar_path']) && ! empty($photo)) {
|
||||
$this->logger->info('Saving user photo from LDAP profile');
|
||||
$this->avatarFileModel->uploadImageContent($profile['id'], $photo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Event\GenericEvent;
|
||||
use Kanboard\Model\TaskLinkModel;
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Kanboard\Model\CommentModel;
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
use Kanboard\Model\TaskFileModel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class NotificationSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_USER_MENTION => 'handleEvent',
|
||||
TaskModel::EVENT_CREATE => 'handleEvent',
|
||||
TaskModel::EVENT_UPDATE => 'handleEvent',
|
||||
TaskModel::EVENT_CLOSE => 'handleEvent',
|
||||
TaskModel::EVENT_OPEN => 'handleEvent',
|
||||
TaskModel::EVENT_MOVE_COLUMN => 'handleEvent',
|
||||
TaskModel::EVENT_MOVE_PROJECT => 'handleEvent',
|
||||
TaskModel::EVENT_MOVE_POSITION => 'handleEvent',
|
||||
TaskModel::EVENT_MOVE_SWIMLANE => 'handleEvent',
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE => 'handleEvent',
|
||||
SubtaskModel::EVENT_CREATE => 'handleEvent',
|
||||
SubtaskModel::EVENT_UPDATE => 'handleEvent',
|
||||
SubtaskModel::EVENT_DELETE => 'handleEvent',
|
||||
CommentModel::EVENT_CREATE => 'handleEvent',
|
||||
CommentModel::EVENT_UPDATE => 'handleEvent',
|
||||
CommentModel::EVENT_DELETE => 'handleEvent',
|
||||
CommentModel::EVENT_USER_MENTION => 'handleEvent',
|
||||
TaskFileModel::EVENT_CREATE => 'handleEvent',
|
||||
TaskFileModel::EVENT_DESTROY => 'handleEvent',
|
||||
TaskLinkModel::EVENT_CREATE_UPDATE => 'handleEvent',
|
||||
TaskLinkModel::EVENT_DELETE => 'handleEvent',
|
||||
);
|
||||
}
|
||||
|
||||
public function handleEvent(GenericEvent $event, $eventName)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: ' . __METHOD__);
|
||||
$this->queueManager->push($this->notificationJob->withParams($event, $eventName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Event\TaskEvent;
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class ProjectDailySummarySubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE => 'execute',
|
||||
TaskModel::EVENT_CLOSE => 'execute',
|
||||
TaskModel::EVENT_OPEN => 'execute',
|
||||
TaskModel::EVENT_MOVE_COLUMN => 'execute',
|
||||
TaskModel::EVENT_MOVE_SWIMLANE => 'execute',
|
||||
);
|
||||
}
|
||||
|
||||
public function execute(TaskEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$this->queueManager->push($this->projectMetricJob->withParams($event['task']['project_id']));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Event\GenericEvent;
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class ProjectModificationDateSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_CREATE_UPDATE => 'execute',
|
||||
TaskModel::EVENT_CLOSE => 'execute',
|
||||
TaskModel::EVENT_OPEN => 'execute',
|
||||
TaskModel::EVENT_MOVE_SWIMLANE => 'execute',
|
||||
TaskModel::EVENT_MOVE_COLUMN => 'execute',
|
||||
TaskModel::EVENT_MOVE_POSITION => 'execute',
|
||||
TaskModel::EVENT_MOVE_PROJECT => 'execute',
|
||||
TaskModel::EVENT_ASSIGNEE_CHANGE => 'execute',
|
||||
SubtaskModel::EVENT_CREATE_UPDATE => 'execute',
|
||||
SubtaskModel::EVENT_DELETE => 'execute',
|
||||
);
|
||||
}
|
||||
|
||||
public function execute(GenericEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$this->projectModel->updateModificationDate($event['task']['project_id']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Event\TaskEvent;
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class RecurringTaskSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN => 'onMove',
|
||||
TaskModel::EVENT_CLOSE => 'onClose',
|
||||
);
|
||||
}
|
||||
|
||||
public function onMove(TaskEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$task = $event['task'];
|
||||
|
||||
if ($task['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING) {
|
||||
if ($task['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_FIRST_COLUMN && $this->columnModel->getFirstColumnId($task['project_id']) == $event['src_column_id']) {
|
||||
$this->taskRecurrenceModel->duplicateRecurringTask($task['id']);
|
||||
} elseif ($task['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_LAST_COLUMN && $this->columnModel->getLastColumnId($task['project_id']) == $event['dst_column_id']) {
|
||||
$this->taskRecurrenceModel->duplicateRecurringTask($task['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onClose(TaskEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
$task = $event['task'];
|
||||
|
||||
if ($task['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING && $task['recurrence_trigger'] == TaskModel::RECURRING_TRIGGER_CLOSE) {
|
||||
$this->taskRecurrenceModel->duplicateRecurringTask($event['task_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Subscriber;
|
||||
|
||||
use Kanboard\Event\TaskEvent;
|
||||
use Kanboard\Model\TaskModel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class TransitionSubscriber extends BaseSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
TaskModel::EVENT_MOVE_COLUMN => 'execute',
|
||||
);
|
||||
}
|
||||
|
||||
public function execute(TaskEvent $event)
|
||||
{
|
||||
$this->logger->debug('Subscriber executed: '.__METHOD__);
|
||||
|
||||
$user_id = $this->userSession->getId();
|
||||
|
||||
if (! empty($user_id)) {
|
||||
$this->transitionModel->save($user_id, $event->getAll());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user