diff --git a/application/Espo/Controllers/Stream.php b/application/Espo/Controllers/Stream.php index 775a219581..2b19ef7116 100644 --- a/application/Espo/Controllers/Stream.php +++ b/application/Espo/Controllers/Stream.php @@ -26,7 +26,7 @@ use \Espo\Core\Exceptions\Error; class Stream extends \Espo\Core\Controllers\Base { - const MAX_SIZE_LIMIT = 400; + const MAX_SIZE_LIMIT = 200; public static $defaultAction = 'list'; diff --git a/application/Espo/Core/Acl.php b/application/Espo/Core/Acl.php index acd0d2c515..929861b977 100644 --- a/application/Espo/Core/Acl.php +++ b/application/Espo/Core/Acl.php @@ -22,13 +22,16 @@ namespace Espo\Core; +use \Espo\ORM\Entity; +use \Espo\Entities\User; + class Acl { private $user; private $aclManager; - public function __construct(AclManager $aclManager, \Espo\Entities\User $user) + public function __construct(AclManager $aclManager, User $user) { $this->aclManager = $aclManager; $this->user = $user; @@ -78,5 +81,10 @@ class Acl { return $this->getAclManager()->checkScope($this->getUser(), $scope, $action, $isOwner, $inTeam, $entity) ; } + + public function checkPermission($permission, User $entity) + { + return $this->getAclManager()->checkPermission($this->getUser(), $permission, $entity); + } } diff --git a/application/Espo/Core/AclManager.php b/application/Espo/Core/AclManager.php index f531aaecbc..729351f023 100644 --- a/application/Espo/Core/AclManager.php +++ b/application/Espo/Core/AclManager.php @@ -177,5 +177,34 @@ class AclManager $data = $this->getTable($user)->getScopeData($scope); return $this->getImplementation($scope)->checkScope($user, $data, $scope, $action, $isOwner, $inTeam, $entity); } + + public function checkPermission(User $user, $permission, User $entity) + { + if ($user->isAdmin()) { + return true; + } + if ($this->get($user, $permission) === 'no') { + if ($entity->id !== $user->id) { + return false; + } + } else if ($this->get($user, $permission) === 'team') { + if ($entity->id != $user->id) { + $teamIdList1 = $user->getTeamIdList(); + $teamIdList2 = $entity->getTeamIdList(); + + $inTeam = false; + foreach ($teamIdList1 as $id) { + if (in_array($id, $teamIdList2)) { + $inTeam = true; + break; + } + } + if (!$inTeam) { + return false; + } + } + } + return true; + } } diff --git a/application/Espo/Modules/Crm/Services/Activities.php b/application/Espo/Modules/Crm/Services/Activities.php index c0b98fd6a3..7631800beb 100644 --- a/application/Espo/Modules/Crm/Services/Activities.php +++ b/application/Espo/Modules/Crm/Services/Activities.php @@ -464,36 +464,10 @@ class Activities extends \Espo\Core\Services\Base protected function accessCheck($entity) { if ($entity->getEntityType() == 'User') { - if ($this->getUser()->isAdmin()) { - return; + if (!$this->getAcl()->checkPermission('userPermission', $entity)) { + throw new Forbidden(); } - $e = $this->getAcl()->get('userPermission'); - if ($this->getAcl()->get('userPermission') === 'no') { - if ($entity->id != $this->getUser()->id) { - throw new Forbidden(); - } - } else if ($this->getAcl()->get('userPermission') === 'team') { - if ($entity->id != $this->getUser()->id) { - if (!$this->getUser()->has('teamsIds')) { - $this->getUser()->loadLinkMultipleField('teams'); - } - $entity->loadLinkMultipleField('teams'); - $teamIdList1 = $this->getUser()->get('teamsIds'); - $teamIdList2 = $entity->get('teamsIds'); - - $inTeam = false; - foreach ($teamIdList1 as $id) { - if (in_array($id, $teamIdList2)) { - $inTeam = true; - break; - } - } - if (!$inTeam) { - throw new Forbidden(); - } - } - } } else { if (!$this->getAcl()->check($entity, 'read')) { throw new Forbidden(); diff --git a/application/Espo/Services/Stream.php b/application/Espo/Services/Stream.php index 50b137bd42..aa1a9af94c 100644 --- a/application/Espo/Services/Stream.php +++ b/application/Espo/Services/Stream.php @@ -267,11 +267,23 @@ class Stream extends \Espo\Core\Services\Base $sth = $pdo->prepare($sql)->execute(); } - public function findUserStream($params = array()) + public function findUserStream($userId, $params = array()) { $offset = intval($params['offset']); $maxSize = intval($params['maxSize']); + if ($userId === $this->getUser()->id) { + $user = $this->getUser(); + } else { + $user = $this->getEntityManager()->getEntity('User', $userId); + if (!$user) { + throw new NotFound(); + } + if (!$this->getAcl()->checkPermission('userPermission', $user)) { + throw new Forbidden(); + } + } + $pdo = $this->getEntityManager()->getPDO(); $selectSqlPart = " @@ -303,7 +315,7 @@ class Stream extends \Espo\Core\Services\Base note.parent_id = subscription.entity_id ) ) AND - subscription.user_id = ".$pdo->quote($this->getUser()->id)." + subscription.user_id = ".$pdo->quote($user->id)." LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id WHERE note.deleted = 0 {where} ORDER BY number DESC @@ -321,7 +333,7 @@ class Stream extends \Espo\Core\Services\Base note.super_parent_id = subscription.entity_id ) ) AND - subscription.user_id = ".$pdo->quote($this->getUser()->id)." + subscription.user_id = ".$pdo->quote($user->id)." LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id WHERE note.deleted = 0 AND ( @@ -341,7 +353,7 @@ class Stream extends \Espo\Core\Services\Base LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id WHERE note.deleted = 0 AND ( - note.created_by_id = ".$pdo->quote($this->getUser()->id)." AND + note.created_by_id = ".$pdo->quote($user->id)." AND note.parent_id IS NULL AND note.type = 'Post' AND note.is_global = 0 @@ -359,8 +371,8 @@ class Stream extends \Espo\Core\Services\Base LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id WHERE note.deleted = 0 AND ( - note.created_by_id <> ".$pdo->quote($this->getUser()->id)." AND - usersMiddle.user_id = ".$pdo->quote($this->getUser()->id)." AND + note.created_by_id <> ".$pdo->quote($user->id)." AND + usersMiddle.user_id = ".$pdo->quote($user->id)." AND note.parent_id IS NULL AND note.is_global = 0 ) @@ -384,7 +396,7 @@ class Stream extends \Espo\Core\Services\Base ) "; - $teamIdList = $this->getUser()->getTeamIdList(); + $teamIdList = $user->getTeamIdList(); $teamIdQuotedList = []; foreach ($teamIdList as $teamId) { $teamIdQuotedList[] = $pdo->quote($teamId); @@ -399,7 +411,7 @@ class Stream extends \Espo\Core\Services\Base LEFT JOIN `user` AS `createdBy` ON note.created_by_id = createdBy.id WHERE note.deleted = 0 AND ( - note.created_by_id <> ".$pdo->quote($this->getUser()->id)." AND + note.created_by_id <> ".$pdo->quote($user->id)." AND teamsMiddle.team_id IN (".implode(',', $teamIdQuotedList).") AND note.parent_id IS NULL AND note.is_global = 0 @@ -416,15 +428,22 @@ class Stream extends \Espo\Core\Services\Base "; + $where = ''; if (!empty($params['after'])) { - $where = array(); - $where['createdAt>'] = $params['after']; - $selectParams['whereClause'] = $where; - $sql = str_replace('{where}', "AND note.created_at > ".$pdo->quote($params['after']), $sql); - } else { - $sql = str_replace('{where}', '', $sql); + $where .= " AND note.created_at > ".$pdo->quote($params['after']); + } + if (!empty($params['filter'])) { + switch ($params['filter']) { + case 'posts': + $where .= " AND note.type = 'Post'"; + break; + case 'updates': + $where .= " AND note.type IN ('Update', 'Status')"; + break; + } } + $sql = str_replace('{where}', $where, $sql); $sql = $this->getEntityManager()->getQuery()->limit($sql, $offset, $maxSize + 1); @@ -472,8 +491,11 @@ class Stream extends \Espo\Core\Services\Base public function find($scope, $id, $params = array()) { - if ($scope == 'User') { - return $this->findUserStream($params); + if ($scope === 'User') { + if (empty($id)) { + $id = $this->getUser()->id; + } + return $this->findUserStream($id, $params); } $entity = $this->getEntityManager()->getEntity($scope, $id); diff --git a/frontend/client/modules/crm/src/views/record/panels/activities.js b/frontend/client/modules/crm/src/views/record/panels/activities.js index 7a18fe2fa8..a1b2943642 100644 --- a/frontend/client/modules/crm/src/views/record/panels/activities.js +++ b/frontend/client/modules/crm/src/views/record/panels/activities.js @@ -25,7 +25,7 @@ Espo.define('crm:views/record/panels/activities', ['views/record/panels/relation name: 'activities', - template: 'crm:record.panels.activities', + template: 'crm:record/panels/activities', scopeList: ['Meeting', 'Call'], diff --git a/frontend/client/src/views/stream/panel.js b/frontend/client/src/views/stream/panel.js index e8bf99f645..70fa73be95 100644 --- a/frontend/client/src/views/stream/panel.js +++ b/frontend/client/src/views/stream/panel.js @@ -149,7 +149,9 @@ Espo.define('views/stream/panel', ['views/record/panels/relationship', 'lib!Text }.bind(this), 500); }, this); - collection.fetch(); + if (!this.defs.hidden) { + collection.fetch(); + } this.$textarea.textcomplete([{ match: /(^|\s)@(\w*)$/, diff --git a/frontend/client/src/views/user/record/detail-bottom.js b/frontend/client/src/views/user/record/detail-bottom.js index b367d60026..f850d1c8ca 100644 --- a/frontend/client/src/views/user/record/detail-bottom.js +++ b/frontend/client/src/views/user/record/detail-bottom.js @@ -33,7 +33,7 @@ Espo.define('views/user/record/detail-bottom', 'views/record/detail-bottom', fun this.listenToOnce(this.model, 'sync', function () { if (this.getAcl().checkUserPermission(this.model)) { this.getParentView().showPanel('stream'); - this.getView('stream').actionRefresh(); + this.getView('stream').collection.fetch(); } }, this); }