user calender permission

This commit is contained in:
Yuri Kuznetsov
2025-01-07 14:06:40 +02:00
parent 4430a40d32
commit 6264812d12
21 changed files with 95 additions and 58 deletions
+3
View File
@@ -40,4 +40,7 @@ class Permission
public const DATA_PRIVACY = 'dataPrivacy';
public const MESSAGE = 'message';
public const MENTION = 'mention';
public const USER_CALENDAR = 'userCalendar';
public const FOLLOWER_MANAGEMENT = 'followerManagement';
public const GROUP_EMAIL_ACCOUNT = 'groupEmailAccount';
}
@@ -34,11 +34,14 @@ use Espo\Core\Upgrades\Migration\Script;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\Metadata;
use Espo\Entities\Preferences;
use Espo\Entities\Role;
use Espo\Entities\ScheduledJob;
use Espo\Entities\User;
use Espo\Modules\Crm\Entities\Account;
use Espo\Modules\Crm\Entities\Contact;
use Espo\ORM\EntityManager;
use Espo\ORM\Query\Part\Expression;
use Espo\ORM\Query\UpdateBuilder;
class AfterUpgrade implements Script
{
@@ -51,12 +54,23 @@ class AfterUpgrade implements Script
public function run(): void
{
$this->updateRoles();
$this->setReactionNotifications();
$this->createScheduledJob();
$this->setAclLinks();
$this->fixTimezone();
}
private function updateRoles(): void
{
$query = UpdateBuilder::create()
->in(Role::ENTITY_TYPE)
->set(['userCalendarPermission' => Expression::column('userPermission')])
->build();
$this->entityManager->getQueryExecutor()->execute($query);
}
private function createScheduledJob(): void
{
$found = $this->entityManager
@@ -737,7 +737,7 @@ class Service
protected function accessCheck(Entity $entity): void
{
if ($entity instanceof User) {
if (!$this->acl->checkUserPermission($entity)) {
if (!$this->acl->checkUserPermission($entity, Acl\Permission::USER_CALENDAR)) {
throw new Forbidden();
}
@@ -260,7 +260,7 @@ class UpcomingService
private function accessCheck(Entity $entity): void
{
if ($entity instanceof User) {
if (!$this->acl->checkUserPermission($entity)) {
if (!$this->acl->checkUserPermission($entity, Acl\Permission::USER_CALENDAR)) {
throw new Forbidden();
}
@@ -197,8 +197,7 @@ class Service
private function accessCheck(Entity $entity): void
{
if ($entity instanceof User) {
/** @noinspection PhpRedundantOptionalArgumentInspection */
if (!$this->acl->checkUserPermission($entity, Acl\Permission::USER)) {
if (!$this->acl->checkUserPermission($entity, Acl\Permission::USER_CALENDAR)) {
throw new Forbidden();
}
@@ -621,16 +620,16 @@ class Service
*/
public function fetchForTeams(array $teamIdList, FetchParams $fetchParams): array
{
if ($this->acl->getPermissionLevel(Acl\Permission::USER) === Table::LEVEL_NO) {
throw new Forbidden("User Permission not allowing to view calendars of other users.");
if ($this->acl->getPermissionLevel(Acl\Permission::USER_CALENDAR) === Table::LEVEL_NO) {
throw new Forbidden("User Calendar Permission not allowing to view calendars of other users.");
}
if ($this->acl->getPermissionLevel(Acl\Permission::USER) === Table::LEVEL_TEAM) {
if ($this->acl->getPermissionLevel(Acl\Permission::USER_CALENDAR) === Table::LEVEL_TEAM) {
$userTeamIdList = $this->user->getLinkMultipleIdList(Field::TEAMS);
foreach ($teamIdList as $teamId) {
if (!in_array($teamId, $userTeamIdList)) {
throw new Forbidden("User Permission not allowing to view calendars of other teams.");
throw new Forbidden("User Calendar Permission not allowing to view calendars of other teams.");
}
}
}
@@ -13,6 +13,7 @@
"dataPrivacyPermission": "Data Privacy Permission",
"auditPermission": "Audit Permission",
"mentionPermission": "Mention Permission",
"userCalendarPermission": "User Calendar Permission",
"data": "Data",
"fieldData": "Field Data"
},
@@ -23,7 +24,8 @@
"tooltips": {
"messagePermission": "Allows to send messages to other users.\n\n* all can send to all\n* team can send only to teammates\n* no cannot send",
"assignmentPermission": "Allows to assign records to other users.\n\n* all no restriction\n* team can assign only to teammates\n* no can assign only to self",
"userPermission": "Allows view activities, calendar and stream of other users.\n\n* all can view all\n* team can view activities of teammates only\n* no can't view",
"userPermission": "Allows to view stream of other users. Allows users to view the access levels other users have for specific records.",
"userCalendarPermission": "Allows to view calendars of other users.",
"portalPermission": "Access to portal information, the ability to post messages to portal users.",
"groupEmailAccountPermission": "Access to group email accounts, the ability to send emails from group SMTP.",
"exportPermission": "Allows to export records.",
@@ -12,13 +12,13 @@
"rows": [
[
{"name": "exportPermission"},
{"name": "userPermission"},
{"name": "mentionPermission"},
{"name": "assignmentPermission"}
],
[
{"name": "portalPermission"},
{"name": "groupEmailAccountPermission"},
{"name": "dataPrivacyPermission"}
{"name": "userCalendarPermission"}
],
[
{"name": "massUpdatePermission"},
@@ -27,8 +27,8 @@
],
[
{"name": "auditPermission"},
{"name": "mentionPermission"},
false
{"name": "userPermission"},
{"name": "dataPrivacyPermission"}
]
]
}
@@ -160,16 +160,17 @@
},
"valuePermissionList": [
"assignmentPermission",
"userPermission",
"messagePermission",
"portalPermission",
"groupEmailAccountPermission",
"mentionPermission",
"userCalendarPermission",
"auditPermission",
"exportPermission",
"massUpdatePermission",
"userPermission",
"portalPermission",
"groupEmailAccountPermission",
"followerManagementPermission",
"dataPrivacyPermission",
"auditPermission",
"mentionPermission"
"dataPrivacyPermission"
],
"valuePermissionHighestLevels": {
"assignmentPermission": "all",
@@ -182,7 +183,8 @@
"followerManagementPermission": "all",
"dataPrivacyPermission": "yes",
"auditPermission": "yes",
"mentionPermission": "yes"
"mentionPermission": "yes",
"userCalendarPermission": "all"
},
"permissionsStrictDefaults": {
"assignmentPermission": "no",
@@ -195,6 +197,7 @@
"followerManagementPermission": "no",
"dataPrivacyPermission": "no",
"auditPermission": "no",
"mentionPermission": "no"
"mentionPermission": "no",
"userCalendarPermission": "no"
}
}
@@ -105,6 +105,15 @@
"view": "views/role/fields/permission",
"audited": true
},
"userCalendarPermission": {
"type": "enum",
"options": ["not-set", "all", "team", "no"],
"default": "not-set",
"tooltip": true,
"translation": "Role.options.levelList",
"view": "views/role/fields/permission",
"audited": true
},
"data": {
"type": "jsonObject",
"audited": true
+1 -1
View File
@@ -339,7 +339,7 @@ class AppService
*/
private function getUserGroupEmailAddressList(User $user): array
{
$groupEmailAccountPermission = $this->acl->getPermissionLevel('groupEmailAccount');
$groupEmailAccountPermission = $this->acl->getPermissionLevel(Acl\Permission::GROUP_EMAIL_ACCOUNT);
if (!$groupEmailAccountPermission || $groupEmailAccountPermission === Acl\Table::LEVEL_NO) {
return [];
@@ -221,7 +221,7 @@ class FollowerRecordService
if (
!$user->isPortal() &&
$this->user->getId() !== $user->getId() &&
!$this->acl->checkUserPermission($user, 'followerManagement')
!$this->acl->checkUserPermission($user, Acl\Permission::FOLLOWER_MANAGEMENT)
) {
throw new Forbidden("No 'followerManagement' permission.");
}
@@ -93,7 +93,8 @@ class UserRecordService
throw new NotFound("User not found.");
}
if (!$this->acl->checkUserPermission($user, 'user')) {
/** @noinspection PhpRedundantOptionalArgumentInspection */
if (!$this->acl->checkUserPermission($user, Acl\Permission::USER)) {
throw new Forbidden("No user permission access.");
}
@@ -135,7 +136,8 @@ class UserRecordService
throw new NotFound("User not found.");
}
if (!$this->acl->checkUserPermission($user, 'user')) {
/** @noinspection PhpRedundantOptionalArgumentInspection */
if (!$this->acl->checkUserPermission($user, Acl\Permission::USER)) {
throw new Forbidden("No user permission access.");
}
@@ -102,8 +102,8 @@ class UsersAccessService
}
if (
$this->acl->getPermissionLevel('user') !== Acl\Table::LEVEL_TEAM &&
$this->acl->getPermissionLevel('user') !== Acl\Table::LEVEL_ALL
$this->acl->getPermissionLevel(Acl\Permission::USER) !== Acl\Table::LEVEL_TEAM &&
$this->acl->getPermissionLevel(Acl\Permission::USER) !== Acl\Table::LEVEL_ALL
) {
throw new Forbidden("No user permission.");
}
@@ -129,7 +129,7 @@ class UsersAccessService
]
]);
if ($this->acl->getPermissionLevel('user') === Acl\Table::LEVEL_TEAM) {
if ($this->acl->getPermissionLevel(Acl\Permission::USER) === Acl\Table::LEVEL_TEAM) {
$queryBuilder
->where(
Condition::in(
@@ -192,7 +192,7 @@ class CalendarView extends View {
this.colors = {...this.colors, ...this.getHelper().themeManager.getParam('calendarColors')};
this.isCustomViewAvailable = this.getAcl().getPermissionLevel('userPermission') !== 'no';
this.isCustomViewAvailable = this.getAcl().getPermissionLevel('userCalendar') !== 'no';
if (this.options.userId) {
this.isCustomViewAvailable = false;
@@ -33,7 +33,7 @@ define('crm:views/calendar/fields/teams', ['views/fields/link-multiple'], functi
foreignScope: 'Team',
getSelectBoolFilterList: function () {
if (this.getAcl().get('userPermission') === 'team') {
if (this.getAcl().getPermissionLevel('userCalendar') === 'team') {
return ['onlyMy'];
}
}
@@ -34,7 +34,7 @@ class CalendarUsersFieldView extends LinkMultipleFieldView {
sortable = true
getSelectBoolFilterList() {
if (this.getAcl().getPermissionLevel('userPermission') === 'team') {
if (this.getAcl().getPermissionLevel('userCalendar') === 'team') {
return ['onlyMyTeam'];
}
}
@@ -157,7 +157,7 @@ class TimelineView extends View {
this.colors = {...this.colors, ...this.getHelper().themeManager.getParam('calendarColors')};
this.isCustomViewAvailable = this.getAcl().getPermissionLevel('userPermission') !== 'no';
this.isCustomViewAvailable = this.getAcl().getPermissionLevel('userCalendar') !== 'no';
if (this.options.userId) {
this.isCustomViewAvailable = false;
@@ -201,7 +201,7 @@ class TimelineView extends View {
}
}
if (this.getAcl().getPermissionLevel('userPermission') === 'no') {
if (this.getAcl().getPermissionLevel('userCalendar') === 'no') {
if (this.calendarType === 'shared') {
this.calendarType = 'single';
}
@@ -249,7 +249,7 @@ class TimelineView extends View {
return list;
}
if (this.getAcl().getPermissionLevel('userPermission') !== 'no') {
if (this.getAcl().getPermissionLevel('userCalendar') !== 'no') {
list.push({
type: 'shared',
label: this.getCalendarTypeLabel('shared'),
@@ -997,7 +997,7 @@ class TimelineView extends View {
actionAddUser() {
const boolFilterList = [];
if (this.getAcl().getPermissionLevel('userPermission') === 'team') {
if (this.getAcl().getPermissionLevel('userCalendar') === 'team') {
boolFilterList.push('onlyMyTeam');
}
@@ -52,7 +52,7 @@ define('crm:views/dashlets/options/calendar', ['views/dashlets/options/base'], f
}
if (
this.getAcl().get('userPermission') !== 'no'
this.getAcl().getPermissionLevel('userCalendar') !== 'no'
&&
~['basicWeek', 'month', 'basicDay'].indexOf(this.model.get('mode'))
) {
+3 -3
View File
@@ -83,15 +83,15 @@ export default class extends DetailView {
this.getAcl().checkScope('Calendar') &&
(this.getUserModel().isRegular() || this.getUserModel().isAdmin())
) {
const showActivities = this.getAcl().checkUserPermission(this.getUserModel());
const showActivities = this.getAcl().checkPermission('userCalendar', this.getUserModel());
if (
!showActivities &&
this.getAcl().getPermissionLevel('userPermission') === 'team' &&
this.getAcl().getPermissionLevel('userCalendar') === 'team' &&
!this.model.has('teamsIds')
) {
this.listenToOnce(this.model, 'sync', () => {
if (this.getAcl().checkUserPermission(this.getUserModel())) {
if (this.getAcl().checkPermission('userCalendar', this.getUserModel())) {
this.showHeaderActionItem('calendar');
}
});
@@ -33,15 +33,17 @@ class UserDetailBottomRecordView extends DetailBottomRecordView {
setupPanels() {
super.setupPanels();
let streamAllowed = this.getAcl().checkUserPermission(this.model);
const userModel = /** @type {import('models/user').default} */ this.model;
const streamAllowed = this.getAcl().checkPermission('userCalendar', userModel);
if (
!streamAllowed &&
this.getAcl().getPermissionLevel('userPermission') === 'team' &&
this.getAcl().getPermissionLevel('userCalendar') === 'team' &&
!this.model.has('teamsIds')
) {
this.listenToOnce(this.model, 'sync', () => {
if (this.getAcl().checkUserPermission(this.model)) {
if (this.getAcl().checkPermission('userCalendar', userModel)) {
this.onPanelsReady(() => {
this.showPanel('stream', 'acl');
});
+19 -16
View File
@@ -42,24 +42,27 @@ define('views/user/record/detail-side', ['views/record/detail-side'], function (
return;
}
var showActivities = this.getAcl().checkUserPermission(this.model);
const showActivities = this.getAcl().checkPermission('userCalendar', this.model);
if (!showActivities) {
if (this.getAcl().get('userPermission') === 'team') {
if (!this.model.has('teamsIds')) {
this.listenToOnce(this.model, 'sync', function () {
if (this.getAcl().checkUserPermission(this.model)) {
this.onPanelsReady(function () {
this.showPanel('activities', 'acl');
this.showPanel('history', 'acl');
if (!this.model.isPortal()) {
this.showPanel('tasks', 'acl');
}
});
}
}, this);
if (
!showActivities &&
this.getAcl().getPermissionLevel('userCalendar') === 'team' &&
!this.model.has('teamsIds')
) {
this.listenToOnce(this.model, 'sync', () => {
if (!this.getAcl().checkPermission('userCalendar', this.model)) {
return;
}
}
this.onPanelsReady(() => {
this.showPanel('activities', 'acl');
this.showPanel('history', 'acl');
if (!this.model.isPortal()) {
this.showPanel('tasks', 'acl');
}
});
});
}
if (!showActivities) {