item.value === option.value)}
+ checked={valuePresent}
onClick={(e) => {
- onSelect([...selectedValues, option]);
+ if (!valuePresent) {
+ onSelect([...selectedValues, option]);
+ } else {
+ onSelect([...selectedValues.filter((item) => item.value !== option.value)]);
+ }
}}
/>
diff --git a/server/src/controllers/group_permissions.controller.v2.ts b/server/src/controllers/group_permissions.controller.v2.ts
index c54fb6d25c..5606652f67 100644
--- a/server/src/controllers/group_permissions.controller.v2.ts
+++ b/server/src/controllers/group_permissions.controller.v2.ts
@@ -183,8 +183,6 @@ export class GroupPermissionsControllerV2 {
//Check for license validation first here
// What are license validation for this
// const { groupId } = createGranularPermissionsDto;
- console.log('Updating this');
- console.log(granularPermissionsId);
const granularPermissions = await this.granularPermissionsService.get(granularPermissionsId);
@@ -193,6 +191,7 @@ export class GroupPermissionsControllerV2 {
const group = granularPermissions.group;
validateGranularPermissionUpdateOperation(group);
return await this.granularPermissionsService.update(granularPermissionsId, {
+ group: group,
organizationId: group.organizationId,
updateGranularPermissionDto,
});
diff --git a/server/src/modules/seeds/seeds.module.ts b/server/src/modules/seeds/seeds.module.ts
index ce35a59567..541816f02f 100644
--- a/server/src/modules/seeds/seeds.module.ts
+++ b/server/src/modules/seeds/seeds.module.ts
@@ -1,7 +1,9 @@
import { Module } from '@nestjs/common';
import { SeedsService } from '../../services/seeds.service';
+import { UserResourcePermissionsModule } from '@module/user_resource_permissions/user_resource_permissions.module';
@Module({
+ imports: [UserResourcePermissionsModule],
providers: [SeedsService],
exports: [SeedsService],
})
diff --git a/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts b/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts
index 5bcade86e5..87c68b238d 100644
--- a/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts
+++ b/server/src/modules/user_resource_permissions/constants/granular-permissions.constant.ts
@@ -39,4 +39,5 @@ export const ERROR_HANDLER = {
ADMIN_DEFAULT_GROUP_GRANULAR_PERMISSIONS: 'Cannot create granular permissions of admin group',
EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED:
'End-users can only be granted permission to view apps. If you wish to add this permission, kindly change the following users role from end-user to builder',
+ EDITOR_LEVEL_PERMISSION_NOT_ALLOWED_END_USER: 'Cannot assign builder level permission to end users',
};
diff --git a/server/src/modules/user_resource_permissions/interface/granular-permissions.interface.ts b/server/src/modules/user_resource_permissions/interface/granular-permissions.interface.ts
index 5c1e62b4b2..b16cc420e4 100644
--- a/server/src/modules/user_resource_permissions/interface/granular-permissions.interface.ts
+++ b/server/src/modules/user_resource_permissions/interface/granular-permissions.interface.ts
@@ -2,6 +2,7 @@ import { AppsGroupPermissions } from 'src/entities/apps_group_permissions.entity
import { SearchParamItem } from '@helpers/db-utility/db-utility.interface';
import { CreateGranularPermissionDto, UpdateGranularPermissionDto } from '@dto/granular-permissions.dto';
import { GranularPermissions } from 'src/entities/granular_permissions.entity';
+import { GroupPermissions } from 'src/entities/group_permissions.entity';
export interface AppsPermissionDeleteResourceItem {
id: string;
@@ -20,6 +21,7 @@ export interface AppsGroupPermissionsActions {
export type ResourceGroupActions = AppsGroupPermissionsActions;
export interface UpdateGranularPermissionObject {
+ group?: GroupPermissions;
organizationId: string;
updateGranularPermissionDto: UpdateGranularPermissionDto;
}
@@ -28,6 +30,7 @@ export type GranularPermissionAddResourceItems = AppsPermissionAddResourceItem[]
export type GranularPermissionDeleteResourceItems = AppsPermissionDeleteResourceItem[];
export interface UpdateResourceGroupPermissionsObject {
+ group?: GroupPermissions;
granularPermissions: GranularPermissions;
actions: ResourceGroupActions;
resourcesToAdd: GranularPermissionAddResourceItems;
diff --git a/server/src/modules/user_resource_permissions/services/group-permissions.utility.service.ts b/server/src/modules/user_resource_permissions/services/group-permissions.utility.service.ts
index 9ce23b4111..f0ee74a3ed 100644
--- a/server/src/modules/user_resource_permissions/services/group-permissions.utility.service.ts
+++ b/server/src/modules/user_resource_permissions/services/group-permissions.utility.service.ts
@@ -34,8 +34,6 @@ export class GroupPermissionsUtilityService {
}
async getAddableUser(user: User, groupId: string, searchInput?: string, manager?: EntityManager) {
- console.log('find addable users');
-
return await dbTransactionWrap(async (manager: EntityManager) => {
console.log(await addableUsersToGroupQuery(groupId, user.organizationId, manager, searchInput).getMany());
diff --git a/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts b/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts
index fb602cf2e9..86aeafdc57 100644
--- a/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts
+++ b/server/src/modules/user_resource_permissions/utility/granular-permissios.utility.ts
@@ -3,7 +3,7 @@ import { USER_ROLE } from '../constants/group-permissions.constant';
import { BadRequestException } from '@nestjs/common';
import { ERROR_HANDLER } from '../constants/granular-permissions.constant';
import { EntityManager, SelectQueryBuilder } from 'typeorm';
-import { GranularPermissionQuerySearchParam } from '../interface/granular-permissions.interface';
+import { GranularPermissionQuerySearchParam, ResourceGroupActions } from '../interface/granular-permissions.interface';
import { GranularPermissions } from 'src/entities/granular_permissions.entity';
export function validateGranularPermissionCreateOperation(group: GroupPermissions) {
@@ -16,6 +16,11 @@ export function validateGranularPermissionUpdateOperation(group: GroupPermission
throw new BadRequestException(ERROR_HANDLER.ADMIN_DEFAULT_GROUP_GRANULAR_PERMISSIONS);
}
+export function validateAppResourcePermissionUpdateOperation(group: GroupPermissions, actions: ResourceGroupActions) {
+ if (group.name === USER_ROLE.END_USER && actions.canEdit)
+ throw new BadRequestException(ERROR_HANDLER.EDITOR_LEVEL_PERMISSION_NOT_ALLOWED_END_USER);
+}
+
export function getAllGranularPermissionQuery(
searchParam: GranularPermissionQuerySearchParam,
manager: EntityManager
diff --git a/server/src/modules/user_resource_permissions/utility/group-permissions.utility.ts b/server/src/modules/user_resource_permissions/utility/group-permissions.utility.ts
index 458351c85c..3f68527077 100644
--- a/server/src/modules/user_resource_permissions/utility/group-permissions.utility.ts
+++ b/server/src/modules/user_resource_permissions/utility/group-permissions.utility.ts
@@ -83,6 +83,9 @@ export function validateUpdateGroupOperation(
const { name } = group;
const { name: newName } = updateGroupPermissionDto;
+ console.log('Printing group');
+ console.log(group);
+
if (
newName &&
(Object.values(USER_ROLE).includes(newName as USER_ROLE) || group.type == GROUP_PERMISSIONS_TYPE.DEFAULT)
@@ -91,8 +94,6 @@ export function validateUpdateGroupOperation(
}
if ([USER_ROLE.ADMIN, USER_ROLE.END_USER].includes(name as USER_ROLE)) {
- console.log('this is running');
-
throw new MethodNotAllowedException(ERROR_HANDLER.NON_EDITABLE_GROUP_UPDATE);
}
}
@@ -150,13 +151,14 @@ export function addableUsersToGroupQuery(
.select('groupUsers.userId')
.from(GroupUsers, 'groupUsers')
.innerJoin('groupUsers.group', 'group')
- .where('(group.name = :admin OR group.id = :groupId)', { admin: USER_ROLE.ADMIN, groupId })
+ .where('group.id = :groupId', { groupId })
.andWhere('group.organizationId = :organizationId', { organizationId })
.getQuery();
return 'users.id NOT IN ' + subQuery;
})
- .andWhere(addableUserGetOrConditions(searchInput));
+ .andWhere(addableUserGetOrConditions(searchInput))
+ .orderBy('users.createdAt', 'DESC');
return query;
}
diff --git a/server/src/services/granular_permissions.service.ts b/server/src/services/granular_permissions.service.ts
index afd8c96023..7fc0af2f99 100644
--- a/server/src/services/granular_permissions.service.ts
+++ b/server/src/services/granular_permissions.service.ts
@@ -24,9 +24,11 @@ import { ERROR_HANDLER } from '@module/user_resource_permissions/constants/granu
import {
getAllGranularPermissionQuery,
getGranularPermissionQuery,
+ validateAppResourcePermissionUpdateOperation,
} from '@module/user_resource_permissions/utility/granular-permissios.utility';
import { GroupPermissionsUtilityService } from '@module/user_resource_permissions/services/group-permissions.utility.service';
import { GroupApps } from 'src/entities/group_apps.entity';
+import { GroupPermissions } from 'src/entities/group_permissions.entity';
@Injectable()
export class GranularPermissionsService {
@@ -72,13 +74,14 @@ export class GranularPermissionsService {
async update(id: string, updateGranularPermissionsObj: UpdateGranularPermissionObject, manager?: EntityManager) {
return await dbTransactionWrap(async (manager: EntityManager) => {
const granularPermissions = await this.get(id, manager);
- const { organizationId, updateGranularPermissionDto } = updateGranularPermissionsObj;
+ const { organizationId, updateGranularPermissionDto, group } = updateGranularPermissionsObj;
const { isAll, name, resourcesToAdd, resourcesToDelete, actions } = updateGranularPermissionDto;
const updateGranularPermission = {
isAll: isAll == true ? true : false,
...(name && { name }),
};
const updateResource: UpdateResourceGroupPermissionsObject = {
+ group,
granularPermissions,
actions,
resourcesToDelete,
@@ -134,11 +137,13 @@ export class GranularPermissionsService {
granularPermissions.groupId,
manager
);
-
if (groupEditors.length && canEdit)
throw new BadRequestException({
- message: ERROR_HANDLER.EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED,
- data: groupEditors,
+ message: {
+ error: ERROR_HANDLER.EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED,
+ data: groupEditors.map((user) => user.email),
+ title: 'Cannot create permissions',
+ },
});
const appGRoupPermissions = await manager.save(
@@ -181,7 +186,20 @@ export class GranularPermissionsService {
manager?: EntityManager
) {
return await dbTransactionWrap(async (manager: EntityManager) => {
- const { granularPermissions, actions, resourcesToDelete, resourcesToAdd } = UpdateResourceGroupPermissionsObject;
+ const {
+ granularPermissions,
+ actions,
+ resourcesToDelete,
+ resourcesToAdd,
+ group: permissionGroup,
+ } = UpdateResourceGroupPermissionsObject;
+ let group: GroupPermissions;
+ if (permissionGroup) {
+ group = permissionGroup;
+ } else {
+ group = await manager.findOne(GroupPermissions, granularPermissions.groupId);
+ }
+ validateAppResourcePermissionUpdateOperation(group, actions);
const { canEdit } = actions;
const groupEditors = await this.groupPermissionsUtilityService.getRoleUsersList(
USER_ROLE.END_USER,
@@ -197,8 +215,11 @@ export class GranularPermissionsService {
if (groupEditors.length && canEdit)
throw new BadRequestException({
- message: ERROR_HANDLER.EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED,
- data: groupEditors,
+ message: {
+ error: ERROR_HANDLER.EDITOR_LEVEL_PERMISSIONS_NOT_ALLOWED,
+ data: groupEditors.map((user) => user.email),
+ title: 'Cannot update permissions',
+ },
});
const appsGroupPermissions = await manager.findOne(AppsGroupPermissions, {
where: {
@@ -207,6 +228,8 @@ export class GranularPermissionsService {
});
if (actions) {
+ if (actions.canEdit) actions.canView = false;
+ else if (actions.canView) actions.canEdit = false;
await manager.update(AppsGroupPermissions, appsGroupPermissions.id, actions);
}
if (resourcesToDelete?.length) {
diff --git a/server/src/services/group_permissions.service.v2.ts b/server/src/services/group_permissions.service.v2.ts
index 5bd61b5a27..c6a0e109bc 100644
--- a/server/src/services/group_permissions.service.v2.ts
+++ b/server/src/services/group_permissions.service.v2.ts
@@ -24,6 +24,7 @@ import {
validateUpdateGroupOperation,
} from '@module/user_resource_permissions/utility/group-permissions.utility';
import { GroupPermissionsUtilityService } from '@module/user_resource_permissions/services/group-permissions.utility.service';
+import { ResourceType } from '@module/user_resource_permissions/constants/granular-permissions.constant';
@Injectable()
export class GroupPermissionsServiceV2 {
@@ -100,6 +101,7 @@ export class GroupPermissionsServiceV2 {
message: {
error: ERROR_HANDLER.UPDATE_EDITABLE_PERMISSION_END_USER_GROUP,
data: getEndUsersList?.map((user) => user.email),
+ title: 'Cannot add this permissions to the group',
},
});
}
@@ -158,20 +160,23 @@ export class GroupPermissionsServiceV2 {
async addGroupUsers(addGroupUserDto: AddGroupUserDto, organizationId: string, manager?: EntityManager) {
const { userIds, groupId } = addGroupUserDto;
- const group = await this.getGroup(groupId);
- validateAddGroupUserOperation(group);
+ return await dbTransactionWrap(async (manager: EntityManager) => {
+ const group = await this.getGroup(groupId, manager);
+ const granularPermission = await this.granularPermissionsService.getAll({ groupId: group.id }, manager);
+ validateAddGroupUserOperation(group);
- return await Promise.all(
- userIds.map(async (userId) => {
- return await dbTransactionWrap(async (manager: EntityManager) => {
+ return await Promise.all(
+ userIds.map(async (userId) => {
const user = await getUserDetailQuery(userId, organizationId, manager).getOne();
if (!user) throw new BadRequestException(ERROR_HANDLER.ADD_GROUP_USER_NON_EXISTING_USER);
const role = await this.groupPermissionsUtilityService.getUserRole(userId, organizationId, manager);
- const editPermissionsPresent = Object.values(group).some(
- (value) => typeof value === 'boolean' && value === true
- );
- //NEED TO CHECK FOR EDITOR LEVEL PERMISSION IN GRANULAR PERMISSIONS
+ const editPermissionsPresent =
+ Object.values(group).some((value) => typeof value === 'boolean' && value === true) ||
+ granularPermission.some((value) => {
+ return value.type === ResourceType.APP && value.appsGroupPermissions.canEdit;
+ });
+
if (editPermissionsPresent && role.name == USER_ROLE.END_USER) {
throw new MethodNotAllowedException({
message: {
@@ -182,8 +187,8 @@ export class GroupPermissionsServiceV2 {
}
return await this.createGroupUser(user, group, manager);
- }, manager);
- })
- );
+ })
+ );
+ }, manager);
}
}
diff --git a/server/src/services/seeds.service.ts b/server/src/services/seeds.service.ts
index d121ef999e..b2cb47ea49 100644
--- a/server/src/services/seeds.service.ts
+++ b/server/src/services/seeds.service.ts
@@ -3,15 +3,15 @@ import { EntityManager } from 'typeorm/entity-manager/EntityManager';
import { User } from '../entities/user.entity';
import { Organization } from '../entities/organization.entity';
import { OrganizationUser } from '../entities/organization_user.entity';
-import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppEnvironment } from 'src/entities/app_environments.entity';
-import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { USER_STATUS, WORKSPACE_USER_STATUS } from 'src/helpers/user_lifecycle';
import { defaultAppEnvironments } from 'src/helpers/utils.helper';
+import { UserRoleService } from './user-role.service';
+import { USER_ROLE } from '@module/user_resource_permissions/constants/group-permissions.constant';
@Injectable()
export class SeedsService {
- constructor(private readonly entityManager: EntityManager) {}
+ constructor(private readonly entityManager: EntityManager, private userRoleService: UserRoleService) {}
async perform(): Promise {
await this.entityManager.transaction(async (manager) => {
@@ -85,10 +85,10 @@ export class SeedsService {
await manager.save(testUserOrganization);
// Save Test user organization mapping
- await this.createDefaultUserGroups(manager, user);
+ await this.createDefaultUserGroups(manager, user, USER_ROLE.ADMIN);
+ await this.createDefaultUserGroups(manager, testUser, USER_ROLE.BUILDER);
// Adding test user to group
- this.addToGroup(manager, testUser);
console.log(
'Seeding complete. Use default credentials to login.\n' + 'email: dev@tooljet.io\n' + 'password: password'
@@ -96,52 +96,9 @@ export class SeedsService {
});
}
- async createDefaultUserGroups(manager: EntityManager, user: User): Promise {
- const defaultGroups = ['all_users', 'admin'];
- for (const group of defaultGroups) {
- await this.createGroupAndAssociateUser(group, manager, user);
- }
- }
-
- async addToGroup(manager: EntityManager, user: User): Promise {
- const defaultGroups = ['all_users'];
- for (const group of defaultGroups) {
- await this.createGroupAndAssociateUser(group, manager, user);
- }
- }
-
- async createGroupAndAssociateUser(group: string, manager: EntityManager, user: User): Promise {
- //Need to update this for new group permissions
- let groupPermission = await manager.findOne(GroupPermission, {
- where: { organizationId: user.organizationId, group: group },
- });
-
- if (!groupPermission) {
- groupPermission = manager.create(GroupPermission, {
- organizationId: user.organizationId,
- group: group,
- appCreate: group == 'admin',
- appDelete: group == 'admin',
- folderCreate: group == 'admin',
- orgEnvironmentVariableCreate: group == 'admin',
- orgEnvironmentVariableUpdate: group == 'admin',
- orgEnvironmentVariableDelete: group == 'admin',
- orgEnvironmentConstantCreate: group == 'admin',
- orgEnvironmentConstantDelete: group == 'admin',
- folderUpdate: group == 'admin',
- folderDelete: group == 'admin',
- });
- //Need to update this as well
- await manager.save(groupPermission);
- }
-
- const userGroupPermission = manager.create(UserGroupPermission, {
- groupPermissionId: groupPermission.id,
- userId: user.id,
- });
-
- //Need to update this as well
- await manager.save(userGroupPermission);
+ async createDefaultUserGroups(manager: EntityManager, user: User, role: USER_ROLE): Promise {
+ if (role === USER_ROLE.ADMIN) await this.userRoleService.createDefaultGroups(user.organizationId, manager);
+ await this.userRoleService.addUserRole({ role, userId: user.id }, user.organizationId, manager);
}
async createDefaultEnvironments(organizationId: string, manager: EntityManager) {
diff --git a/server/src/services/user-role.service.ts b/server/src/services/user-role.service.ts
index 7e23f245db..0d383c18eb 100644
--- a/server/src/services/user-role.service.ts
+++ b/server/src/services/user-role.service.ts
@@ -95,9 +95,13 @@ export class UserRoleService {
if (userRole.name == USER_ROLE.ADMIN) {
const groupUsers = await this.groupPermissionsService.getAllGroupUsers(userRole.id, null, manager);
- console.log(groupUsers);
-
- if (groupUsers.length < 2) throw new BadRequestException(ERROR_HANDLER.EDITING_LAST_ADMIN_ROLE_NOT_ALLOWED);
+ if (groupUsers.length < 2)
+ throw new BadRequestException({
+ message: {
+ error: ERROR_HANDLER.EDITING_LAST_ADMIN_ROLE_NOT_ALLOWED,
+ title: 'Can not remove last active admin',
+ },
+ });
}
if (newRole == USER_ROLE.END_USER) {
const userCreatedApps = await manager.find(App, {