Removed depreciated code

This commit is contained in:
kriks7iitk 2024-07-09 14:29:54 +05:30
parent fa203bbf2d
commit d8fbf7ce5e
15 changed files with 3 additions and 855 deletions

View file

@ -54,11 +54,12 @@ export class AppsController {
return await dbTransactionWrap(async (manager: EntityManager) => {
const app = await this.appsService.create(name, user, manager);
console.log('okay till here');
const appUpdateDto = new AppUpdateDto();
appUpdateDto.name = name;
appUpdateDto.slug = app.id;
appUpdateDto.icon = icon;
await this.appsService.update(app.id, appUpdateDto, manager);
return decamelizeKeys(app);

View file

@ -1,119 +0,0 @@
import { Controller, Body, Post, Get, Put, Delete, UseGuards, Param, Query } from '@nestjs/common';
import { decamelizeKeys } from 'humps';
import { JwtAuthGuard } from '../../src/modules/auth/jwt-auth.guard';
import { GroupPermissionsService } from '../services/group_permissions.service';
import { PoliciesGuard } from 'src/modules/casl/policies.guard';
import { CheckPolicies } from 'src/modules/casl/check_policies.decorator';
import { AppAbility } from 'src/modules/casl/casl-ability.factory';
import { User } from 'src/decorators/user.decorator';
import { User as UserEntity } from 'src/entities/user.entity';
import { CreateGroupPermissionDto, UpdateGroupPermissionDto, DuplucateGroupDto } from '@dto/group-permission.dto';
import { ORGANIZATION_RESOURCE_ACTIONS } from 'src/constants/global.constant';
@Controller('group_permissions')
export class GroupPermissionsController {
constructor(private groupPermissionsService: GroupPermissionsService) {}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Post()
async create(@User() user, @Body() createGroupPermissionDto: CreateGroupPermissionDto) {
await this.groupPermissionsService.create(user, createGroupPermissionDto.group);
return;
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Post(':id/duplicate')
async duplicate(@User() user, @Param('id') id: string, @Body() body: DuplucateGroupDto) {
const duplicateGroup = await this.groupPermissionsService.duplicateGroup(user, id, body);
return duplicateGroup;
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get(':id')
async show(@User() user, @Param('id') id: string) {
const groupPermission = await this.groupPermissionsService.findOne(user, id);
return decamelizeKeys(groupPermission);
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Put(':id/app_group_permissions/:appGroupPermissionId')
async updateAppGroupPermission(
@Body() updateGroupPermissionDto: UpdateGroupPermissionDto,
@User() user,
@Param('id') id: string,
@Param('appGroupPermissionId') appGroupPermissionId: string
) {
await this.groupPermissionsService.updateAppGroupPermission(
user,
id,
appGroupPermissionId,
updateGroupPermissionDto.actions
);
return;
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Put(':id')
async update(@User() user, @Param('id') id, @Body() body) {
await this.groupPermissionsService.update(user, id, body);
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get()
async index(@User() user) {
const groupPermissions = await this.groupPermissionsService.findAll(user);
return decamelizeKeys({ groupPermissions });
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Delete(':id')
async destroy(@User() user, @Param('id') id) {
await this.groupPermissionsService.destroy(user, id);
return;
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get(':id/apps')
async apps(@User() user, @Param('id') id) {
const apps = await this.groupPermissionsService.findApps(user, id);
return decamelizeKeys({ apps });
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get(':id/addable_apps')
async addableApps(@User() user, @Param('id') id) {
const apps = await this.groupPermissionsService.findAddableApps(user, id);
return decamelizeKeys({ apps });
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get(':id/users')
async users(@User() user, @Param('id') id) {
const users = await this.groupPermissionsService.findUsers(user, id);
return decamelizeKeys({ users });
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(ORGANIZATION_RESOURCE_ACTIONS.ACCESS_PERMISSIONS, UserEntity))
@Get(':id/addable_users')
async addableUsers(@User() user, @Param('id') id, @Query('input') searchInput: string) {
const users = await this.groupPermissionsService.findAddableUsers(user, id, searchInput.trim());
return decamelizeKeys({ users });
}
}

View file

@ -2,52 +2,7 @@ import { UserAppsPermissions } from '@module/permissions/interface/permissions-a
import { AppBase } from 'src/entities/app_base.entity';
import { Folder } from 'src/entities/folder.entity';
import { User } from 'src/entities/user.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { Brackets, createQueryBuilder, EntityManager, SelectQueryBuilder } from 'typeorm';
//Need to change this based on new group permissions
export function viewableAppsQuery(user: User, searchKey?: string, select?: Array<string>): SelectQueryBuilder<AppBase> {
const viewableAppsQb = createQueryBuilder(AppBase, 'viewable_apps');
if (select) {
viewableAppsQb.select(select.map((col) => `viewable_apps.${col}`));
}
viewableAppsQb
.innerJoin('viewable_apps.user', 'user')
.addSelect(['user.firstName', 'user.lastName'])
.innerJoin('viewable_apps.groupPermissions', 'group_permissions')
.innerJoinAndSelect('viewable_apps.appGroupPermissions', 'app_group_permissions')
.innerJoin(
UserGroupPermission,
'user_group_permissions',
'app_group_permissions.group_permission_id = user_group_permissions.group_permission_id'
)
.where(
new Brackets((qb) => {
qb.where('user_group_permissions.user_id = :userId', {
userId: user.id,
})
.andWhere('app_group_permissions.read = :value', { value: true })
.andWhere('app_group_permissions.hide_from_dashboard = :hideFromDashboard', {
hideFromDashboard: false,
})
.orWhere('viewable_apps.is_public = :value OR viewable_apps.user_id = :userId', {
value: true,
organizationId: user.organizationId,
userId: user.id,
});
})
)
.andWhere('viewable_apps.organization_id = :organizationId', { organizationId: user.organizationId });
if (searchKey) {
viewableAppsQb.andWhere('LOWER(viewable_apps.name) like :searchKey', {
searchKey: `%${searchKey && searchKey.toLowerCase()}%`,
});
}
viewableAppsQb.orderBy('viewable_apps.createdAt', 'DESC');
return viewableAppsQb;
}
import { createQueryBuilder, EntityManager, SelectQueryBuilder } from 'typeorm';
export function getFolderQuery(organizationId: string, searchKey?: string): SelectQueryBuilder<Folder> {
const query = createQueryBuilder(Folder, 'folders');

View file

@ -20,9 +20,6 @@ import { FoldersService } from '@services/folders.service';
import { Folder } from 'src/entities/folder.entity';
import { FolderApp } from 'src/entities/folder_app.entity';
import { DataSource } from 'src/entities/data_source.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { AppImportExportService } from '@services/app_import_export.service';
import { DataSourcesService } from '@services/data_sources.service';
import { CredentialsService } from '@services/credentials.service';
@ -59,10 +56,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
User,
Organization,
DataSource,
//Depreciated
GroupPermission,
AppGroupPermission,
UserGroupPermission,
Credential,
File,
Plugin,

View file

@ -15,14 +15,10 @@ import { ConfigService } from '@nestjs/config';
import { EmailService } from '@services/email.service';
import { OauthService, GoogleOAuthService, GitOAuthService } from '@ee/services/oauth';
import { OauthController } from '@ee/controllers/oauth.controller';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { App } from 'src/entities/app.entity';
import { File } from 'src/entities/file.entity';
import { FilesService } from '@services/files.service';
import { SSOConfigs } from 'src/entities/sso_config.entity';
import { GroupPermissionsService } from '@services/group_permissions.service';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { EncryptionService } from '@services/encryption.service';
import { DataSourcesService } from '@services/data_sources.service';
import { CredentialsService } from '@services/credentials.service';
@ -49,14 +45,8 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
File,
Organization,
OrganizationUser,
//Depreciated
GroupPermission,
App,
SSOConfigs,
//Depreciated
AppGroupPermission,
//Depreciated
UserGroupPermission,
DataSource,
Credential,
Plugin,
@ -84,8 +74,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
GoogleOAuthService,
GitOAuthService,
FilesService,
//Need to remove group Permission service since this is not required.
GroupPermissionsService,
EncryptionService,
DataSourcesService,
CredentialsService,

View file

@ -15,8 +15,6 @@ import { App } from 'src/entities/app.entity';
import { AppVersion } from 'src/entities/app_version.entity';
import { AppUser } from 'src/entities/app_user.entity';
import { FolderApp } from 'src/entities/folder_app.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UsersService } from '@services/users.service';
import { User } from 'src/entities/user.entity';
import { OrganizationUser } from 'src/entities/organization_user.entity';
@ -43,9 +41,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
Credential,
DataSource,
FolderApp,
//Depreciated
GroupPermission,
AppGroupPermission,
User,
OrganizationUser,
Organization,

View file

@ -16,8 +16,6 @@ import { CaslModule } from '../casl/casl.module';
import { DataQueriesService } from '@services/data_queries.service';
import { DataQuery } from 'src/entities/data_query.entity';
import { FolderApp } from 'src/entities/folder_app.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UsersService } from '@services/users.service';
import { User } from 'src/entities/user.entity';
import { OrganizationUser } from 'src/entities/organization_user.entity';
@ -46,9 +44,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
AppVersion,
AppUser,
FolderApp,
//Depreciated
GroupPermission,
AppGroupPermission,
User,
OrganizationUser,
Organization,

View file

@ -1,37 +0,0 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { GroupPermission } from '../../../src/entities/group_permission.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { GroupPermissionsController } from '../../controllers/group_permissions.controller';
import { GroupPermissionsService } from '../../services/group_permissions.service';
import { CaslModule } from '../casl/casl.module';
import { UsersService } from '@services/users.service';
import { User } from 'src/entities/user.entity';
import { OrganizationUser } from 'src/entities/organization_user.entity';
import { Organization } from 'src/entities/organization.entity';
import { App } from 'src/entities/app.entity';
import { File } from 'src/entities/file.entity';
import { FilesService } from '@services/files.service';
import { UserResourcePermissionsModule } from '@module/user_resource_permissions/user_resource_permissions.module';
@Module({
//Depreciated
controllers: [GroupPermissionsController],
imports: [
UserResourcePermissionsModule,
TypeOrmModule.forFeature([
GroupPermission,
UserGroupPermission,
AppGroupPermission,
User,
OrganizationUser,
Organization,
App,
File,
]),
CaslModule,
],
providers: [GroupPermissionsService, FilesService, UsersService],
})
export class GroupPermissionsModule {}

View file

@ -19,8 +19,6 @@ import { AppUser } from 'src/entities/app_user.entity';
import { DataSource } from 'src/entities/data_source.entity';
import { DataQuery } from 'src/entities/data_query.entity';
import { FolderApp } from 'src/entities/folder_app.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { AppVersion } from 'src/entities/app_version.entity';
import { AppImportExportService } from '@services/app_import_export.service';
import { DataSourcesService } from '@services/data_sources.service';
@ -48,8 +46,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
DataSource,
DataQuery,
FolderApp,
GroupPermission,
AppGroupPermission,
Credential,
]),
CaslModule,

View file

@ -23,8 +23,6 @@ import { AppUser } from 'src/entities/app_user.entity';
import { DataSource } from 'src/entities/data_source.entity';
import { DataQuery } from 'src/entities/data_query.entity';
import { FolderApp } from 'src/entities/folder_app.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { AppVersion } from 'src/entities/app_version.entity';
import { AppImportExportService } from '@services/app_import_export.service';
import { DataSourcesService } from '@services/data_sources.service';
@ -52,10 +50,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
DataSource,
DataQuery,
FolderApp,
//Depreciated
GroupPermission,
//Depreciated
AppGroupPermission,
Credential,
]),
CaslModule,

View file

@ -11,16 +11,12 @@ import { UsersService } from 'src/services/users.service';
import { CaslModule } from '../casl/casl.module';
import { EmailService } from '@services/email.service';
import { FilesService } from '@services/files.service';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { App } from 'src/entities/app.entity';
import { File } from 'src/entities/file.entity';
import { SSOConfigs } from 'src/entities/sso_config.entity';
import { AuthService } from '@services/auth.service';
import { JwtModule } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { GroupPermissionsService } from '@services/group_permissions.service';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { EncryptionService } from '@services/encryption.service';
import { AppConfigService } from '@services/app_config.service';
import { Plugin } from 'src/entities/plugin.entity';
@ -45,11 +41,8 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
OrganizationUser,
User,
File,
GroupPermission,
App,
SSOConfigs,
AppGroupPermission,
UserGroupPermission,
DataSource,
Credential,
Plugin,
@ -77,8 +70,6 @@ import { UserResourcePermissionsModule } from '@module/user_resource_permissions
EmailService,
FilesService,
AuthService,
//Need to check if group permission is required in organization module
GroupPermissionsService,
EncryptionService,
DataSourcesService,
CredentialsService,

View file

@ -2,12 +2,10 @@ import { BadRequestException, Injectable } from '@nestjs/common';
import { isEmpty } from 'lodash';
import { App } from 'src/entities/app.entity';
import { AppEnvironment } from 'src/entities/app_environments.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { AppVersion } from 'src/entities/app_version.entity';
import { DataQuery } from 'src/entities/data_query.entity';
import { DataSource } from 'src/entities/data_source.entity';
import { DataSourceOptions } from 'src/entities/data_source_options.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { User } from 'src/entities/user.entity';
import { EntityManager, In } from 'typeorm';
import { DataSourcesService } from './data_sources.service';
@ -258,7 +256,6 @@ export class AppImportExportService {
isNormalizedAppDefinitionSchema,
currentTooljetVersion
);
await this.createAdminGroupPermissions(this.entityManager, importedApp);
await this.updateEntityReferencesForImportedApp(this.entityManager, resourceMapping);
// NOTE: App slug updation callback doesn't work while wrapped in transaction
@ -1350,32 +1347,6 @@ export class AppImportExportService {
await manager.update(AppVersion, { id: lastVersionIdToUpdate }, { updatedAt: new Date() });
}
//Need to update this as per new group permissions
async createAdminGroupPermissions(manager: EntityManager, app: App) {
const orgDefaultGroupPermissions = await manager.find(GroupPermission, {
where: {
organizationId: app.organizationId,
group: 'admin',
},
});
const adminPermissions = {
read: true,
update: true,
delete: true,
};
for (const groupPermission of orgDefaultGroupPermissions) {
const appGroupPermission = manager.create(AppGroupPermission, {
groupPermissionId: groupPermission.id,
appId: app.id,
...adminPermissions,
});
return await manager.save(AppGroupPermission, appGroupPermission);
}
}
async createDatasourceOption(
manager: EntityManager,
options: Record<string, unknown>,

View file

@ -7,8 +7,6 @@ import { AppUser } from 'src/entities/app_user.entity';
import { AppVersion } from 'src/entities/app_version.entity';
import { DataSource } from 'src/entities/data_source.entity';
import { DataQuery } from 'src/entities/data_query.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { AppImportExportService } from './app_import_export.service';
import { DataSourcesService } from './data_sources.service';
import { Credential } from 'src/entities/credential.entity';
@ -174,52 +172,11 @@ export class AppsService {
updatedAt: new Date(),
})
);
//Depreciated - Need to change this
await this.createAppGroupPermissionsForAdmin(app, manager);
return app;
}, [{ dbConstraint: DataBaseConstraints.APP_NAME_UNIQUE, message: 'This app name is already taken.' }]);
});
}
//Need to change this as per new group permissions
async createAppGroupPermissionsForAdmin(app: App, manager: EntityManager): Promise<void> {
await dbTransactionWrap(async (manager: EntityManager) => {
const orgDefaultGroupPermissions = await manager.find(GroupPermission, {
where: {
organizationId: app.organizationId,
group: 'admin',
},
});
for (const groupPermission of orgDefaultGroupPermissions) {
const appGroupPermission = manager.create(AppGroupPermission, {
groupPermissionId: groupPermission.id,
appId: app.id,
...this.fetchDefaultAppGroupPermissions(groupPermission.group),
});
await manager.save(appGroupPermission);
}
}, manager);
}
//Change this ..
fetchDefaultAppGroupPermissions(group: string): {
read: boolean;
update: boolean;
delete: boolean;
} {
switch (group) {
case 'all_users':
return { read: true, update: false, delete: false };
case 'admin':
return { read: true, update: true, delete: true };
default:
throw `${group} is not a default group`;
}
}
async clone(existingApp: App, user: User, appName: string): Promise<App> {
const appWithRelations = await this.appImportExportService.export(user, existingApp.id);
const clonedApp = await this.appImportExportService.import(user, appWithRelations, appName);

View file

@ -1,516 +0,0 @@
import { BadRequestException, ConflictException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, createQueryBuilder, In, Not, EntityManager, Brackets } from 'typeorm';
import { User } from 'src/entities/user.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { App } from 'src/entities/app.entity';
import { AppGroupPermission } from 'src/entities/app_group_permission.entity';
import { UserGroupPermission } from 'src/entities/user_group_permission.entity';
import { UsersService } from './users.service';
import { dbTransactionWrap, getMaxCopyNumber } from 'src/helpers/utils.helper';
import { DuplucateGroupDto } from '@dto/group-permission.dto';
@Injectable()
export class GroupPermissionsService {
constructor(
@InjectRepository(GroupPermission)
private groupPermissionsRepository: Repository<GroupPermission>,
@InjectRepository(AppGroupPermission)
private appGroupPermissionsRepository: Repository<AppGroupPermission>,
@InjectRepository(UserGroupPermission)
private userGroupPermissionsRepository: Repository<UserGroupPermission>,
@InjectRepository(User)
private userRepository: Repository<User>,
@InjectRepository(App)
private appRepository: Repository<App>,
private usersService: UsersService
) {}
async create(user: User, group: string, manager?: EntityManager): Promise<void> {
if (!group || group === '') {
throw new BadRequestException('Cannot create group without name');
}
const reservedGroups = ['All Users', 'Admin'];
if (reservedGroups.includes(group)) {
throw new BadRequestException('Group name already exist');
}
const groupToFind = await this.groupPermissionsRepository.findOne({
where: {
organizationId: user.organizationId,
group,
},
});
if (groupToFind) {
throw new ConflictException('Group name already exist');
}
await dbTransactionWrap(async (manager: EntityManager) => {
await manager.save(
manager.create(GroupPermission, {
organizationId: user.organizationId,
group: group,
})
);
}, manager);
}
async destroy(user: User, groupPermissionId: string, manager?: EntityManager): Promise<void> {
const groupPermission = await this.groupPermissionsRepository.findOne({
where: {
id: groupPermissionId,
},
});
if (groupPermission.group == 'admin' || groupPermission.group == 'all_users') {
throw new BadRequestException('Cannot delete default group');
}
await dbTransactionWrap(async (manager: EntityManager) => {
const relationalEntitiesToBeDeleted = [AppGroupPermission, UserGroupPermission];
for (const entityToDelete of relationalEntitiesToBeDeleted) {
const entities = await manager.find(entityToDelete, {
where: { groupPermissionId },
});
for (const entity of entities) {
await manager.delete(entityToDelete, entity.id);
}
}
await manager.delete(GroupPermission, {
organizationId: user.organizationId,
id: groupPermissionId,
});
}, manager);
}
async updateAppGroupPermission(
user: User,
groupPermissionId: string,
appGroupPermissionId: string,
actions: any,
manager?: EntityManager
) {
const appGroupPermission = await this.appGroupPermissionsRepository.findOne({
where: {
id: appGroupPermissionId,
groupPermissionId: groupPermissionId,
},
});
const groupPermission = await this.groupPermissionsRepository.findOne({
where: {
id: appGroupPermission.groupPermissionId,
},
});
if (groupPermission.organizationId !== user.organizationId) {
throw new BadRequestException();
}
if (groupPermission.group == 'admin') {
throw new BadRequestException('Cannot update admin group');
}
await dbTransactionWrap(async (manager: EntityManager) => {
await manager.update(AppGroupPermission, appGroupPermissionId, actions);
}, manager);
}
async update(user: User, groupPermissionId: string, body: any, manager?: EntityManager) {
const groupPermission = await this.groupPermissionsRepository.findOne({
where: {
id: groupPermissionId,
organizationId: user.organizationId,
},
});
const {
name,
app_create,
app_delete,
add_apps,
remove_apps,
add_users,
remove_users,
folder_create,
org_environment_variable_create,
org_environment_variable_update,
org_environment_variable_delete,
folder_delete,
folder_update,
org_environment_constant_create,
org_environment_constant_delete,
} = body;
return await dbTransactionWrap(async (manager: EntityManager) => {
//update user group name
if (name) {
const newName = name.trim();
if (!newName) {
throw new BadRequestException('Group name should not be empty');
}
const reservedGroups = ['admin', 'all_users'];
if (reservedGroups.includes(groupPermission.group)) {
throw new BadRequestException('Cannot update a default group name');
}
if (reservedGroups.includes(newName.replace(/ /g, '_').toLowerCase())) {
throw new BadRequestException('Group name already exists');
}
const groupToFind = await this.groupPermissionsRepository.findOne({
where: {
organizationId: user.organizationId,
group: newName,
},
});
if (groupToFind && groupToFind.id !== groupPermission.id) {
throw new ConflictException('Group name already exists');
} else if (!groupToFind) {
await manager.update(GroupPermission, groupPermissionId, { group: newName });
}
}
// update group permissions
const groupPermissionUpdateParams = {
...(typeof app_create === 'boolean' && { appCreate: app_create }),
...(typeof app_delete === 'boolean' && { appDelete: app_delete }),
...(typeof folder_create === 'boolean' && { folderCreate: folder_create }),
...(typeof org_environment_variable_create === 'boolean' && {
orgEnvironmentVariableCreate: org_environment_variable_create,
}),
...(typeof org_environment_variable_update === 'boolean' && {
orgEnvironmentVariableUpdate: org_environment_variable_update,
}),
...(typeof org_environment_variable_delete === 'boolean' && {
orgEnvironmentVariableDelete: org_environment_variable_delete,
}),
...(typeof folder_delete === 'boolean' && { folderDelete: folder_delete }),
...(typeof folder_update === 'boolean' && { folderUpdate: folder_update }),
...(typeof org_environment_constant_create === 'boolean' && {
orgEnvironmentConstantCreate: org_environment_constant_create,
}),
...(typeof org_environment_constant_delete === 'boolean' && {
orgEnvironmentConstantDelete: org_environment_constant_delete,
}),
};
if (Object.keys(groupPermissionUpdateParams).length !== 0) {
await manager.update(GroupPermission, groupPermissionId, groupPermissionUpdateParams);
}
// update app group permissions
if (remove_apps) {
if (groupPermission.group == 'admin') {
throw new BadRequestException('Cannot update admin group');
}
for (const appId of remove_apps) {
await manager.delete(AppGroupPermission, {
appId: appId,
groupPermissionId: groupPermissionId,
});
}
}
if (add_apps) {
if (groupPermission.group == 'admin') {
throw new BadRequestException('Cannot update admin group');
}
for (const appId of add_apps) {
await manager.save(
AppGroupPermission,
manager.create(AppGroupPermission, {
appId: appId,
groupPermissionId: groupPermissionId,
read: true,
})
);
}
}
// update user group permissions
if (remove_users) {
for (const userId of body.remove_users) {
const params = {
removeGroups: [groupPermission.group],
};
await this.usersService.update(userId, params, manager, user.organizationId);
}
}
if (add_users) {
for (const userId of body.add_users) {
const params = {
addGroups: [groupPermission.group],
};
await this.usersService.update(userId, params, manager, user.organizationId);
}
}
}, manager);
}
async findOne(user: User, groupPermissionId: string): Promise<GroupPermission> {
return this.groupPermissionsRepository.findOne({
where: {
organizationId: user.organizationId,
id: groupPermissionId,
},
});
}
async duplicateGroup(
user: User,
groupPermissionId: string,
body: DuplucateGroupDto,
manager?: EntityManager
): Promise<GroupPermission> {
const groupToDuplicate = await this.findOne(user, groupPermissionId);
let newGroup: GroupPermission;
const { addPermission, addApps, addUsers } = body;
if (!groupToDuplicate) throw new BadRequestException('Wrong group id');
const existNameList = await createQueryBuilder()
.select(['group_permissions.group', 'group_permissions.id'])
.from(GroupPermission, 'group_permissions')
.where('group_permissions.group ~* :pattern', { pattern: `^${groupToDuplicate.group}_copy_[0-9]+$` })
.orWhere('group_permissions.group = :groupToDuplicateGroup', {
groupToDuplicateGroup: `${groupToDuplicate.group}_copy`,
})
.andWhere('group_permissions.id != :groupPermissionId', { groupPermissionId })
.andWhere('group_permissions.organizationId = :organizationId', { organizationId: user.organizationId })
.getMany();
let newName = `${groupToDuplicate.group}_copy`;
const number = getMaxCopyNumber(existNameList.map((group) => group.group));
if (number) newName = `${groupToDuplicate.group}_copy_${number}`;
await dbTransactionWrap(async (manager: EntityManager) => {
newGroup = manager.create(GroupPermission, {
organizationId: user.organizationId,
group: newName,
});
await manager.save(GroupPermission, newGroup);
if (addPermission) {
const {
appCreate,
appDelete,
folderCreate,
orgEnvironmentVariableCreate,
orgEnvironmentVariableUpdate,
orgEnvironmentVariableDelete,
orgEnvironmentConstantCreate,
orgEnvironmentConstantDelete,
folderDelete,
folderUpdate,
} = groupToDuplicate;
const updateParam = {
appCreate,
appDelete,
folderCreate,
orgEnvironmentVariableCreate,
orgEnvironmentVariableUpdate,
orgEnvironmentVariableDelete,
orgEnvironmentConstantCreate,
orgEnvironmentConstantDelete,
folderDelete,
folderUpdate,
};
await manager.update(GroupPermission, { id: newGroup.id }, updateParam);
}
const apps = await groupToDuplicate.apps;
if (addApps) {
for (const app of apps) {
const appGrpPermission = await this.appGroupPermissionsRepository.findOne({
where: {
appId: app.id,
groupPermissionId: groupToDuplicate.id,
},
});
if (appGrpPermission)
await manager.save(
AppGroupPermission,
manager.create(AppGroupPermission, {
appId: app.id,
groupPermissionId: newGroup.id,
read: appGrpPermission.read,
update: appGrpPermission.update,
delete: appGrpPermission.delete,
hideFromDashboard: appGrpPermission.hideFromDashboard,
})
);
}
}
}, manager);
if (addUsers) {
const usersGroup = await groupToDuplicate.users;
for (const userAdd of usersGroup) {
const params = {
addGroups: [newGroup.group],
};
await this.usersService.update(userAdd.id, params, manager, user.organizationId);
}
}
return newGroup;
}
async findAll(user: User): Promise<GroupPermission[]> {
const groupPermissions = await this.groupPermissionsRepository.find({
where: { organizationId: user.organizationId },
order: { createdAt: 'ASC' },
});
const customSortGroupPermission = (a, b) => {
if (a.group === 'all_users') {
return -1; // 'all_users' comes first
} else if (b.group === 'all_users') {
return 1; // 'all_users' comes first
} else if (a.group === 'admin') {
return -1; // 'admin' comes second
} else if (b.group === 'admin') {
return 1; // 'admin' comes second
} else {
return 0; // No specific order for other groups
}
};
return groupPermissions.sort(customSortGroupPermission);
}
async findApps(user: User, groupPermissionId: string): Promise<App[]> {
return createQueryBuilder(App, 'apps')
.innerJoinAndSelect('apps.groupPermissions', 'group_permissions')
.innerJoinAndSelect('apps.appGroupPermissions', 'app_group_permissions')
.where('group_permissions.id = :groupPermissionId', {
groupPermissionId,
})
.andWhere('group_permissions.organization_id = :organizationId', {
organizationId: user.organizationId,
})
.andWhere('app_group_permissions.group_permission_id = :groupPermissionId', { groupPermissionId })
.orderBy('apps.created_at', 'DESC')
.getMany();
}
async findAddableApps(user: User, groupPermissionId: string): Promise<App[]> {
const groupPermission = await this.groupPermissionsRepository.findOne({
where: {
id: groupPermissionId,
organizationId: user.organizationId,
},
});
const appsInGroup = await groupPermission.apps;
const appsInGroupIds = appsInGroup.map((u) => u.id);
return await this.appRepository.find({
where: {
id: Not(In(appsInGroupIds)),
organizationId: user.organizationId,
},
loadEagerRelations: false,
relations: ['groupPermissions', 'appGroupPermissions'],
});
}
async findUsers(user: User, groupPermissionId: string): Promise<User[]> {
return createQueryBuilder(User, 'users')
.select(['users.id', 'users.firstName', 'users.lastName', 'users.email'])
.innerJoin('users.groupPermissions', 'group_permissions')
.innerJoin('users.userGroupPermissions', 'user_group_permissions')
.where('group_permissions.id = :groupPermissionId', {
groupPermissionId,
})
.andWhere('group_permissions.organization_id = :organizationId', {
organizationId: user.organizationId,
})
.andWhere('user_group_permissions.group_permission_id = :groupPermissionId', { groupPermissionId })
.orderBy('users.created_at', 'DESC')
.getMany();
}
async findAddableUsers(user: User, groupPermissionId: string, searchInput: string): Promise<User[]> {
const groupPermission = await this.groupPermissionsRepository.findOne({
where: {
id: groupPermissionId,
organizationId: user.organizationId,
},
});
const userInGroup = await groupPermission.users;
const usersInGroupIds = userInGroup.map((u) => u.id);
const adminUsers = await createQueryBuilder(UserGroupPermission, 'user_group_permissions')
.innerJoin(
GroupPermission,
'group_permissions',
'group_permissions.id = user_group_permissions.group_permission_id'
)
.where('group_permissions.group = :group', { group: 'admin' })
.andWhere('group_permissions.organization_id = :organizationId', {
organizationId: user.organizationId,
})
.getMany();
const adminUserIds = adminUsers.map((u) => u.userId);
const getOrConditions = () => {
return new Brackets((qb) => {
if (searchInput) {
qb.orWhere('lower(user.email) like :email', {
email: `%${searchInput.toLowerCase()}%`,
});
qb.orWhere('lower(user.firstName) like :firstName', {
firstName: `%${searchInput.toLowerCase()}%`,
});
qb.orWhere('lower(user.lastName) like :lastName', {
lastName: `%${searchInput.toLowerCase()}%`,
});
}
});
};
const builtQuery = createQueryBuilder(User, 'user')
.select(['user.id', 'user.firstName', 'user.lastName', 'user.email'])
.innerJoin(
'user.organizationUsers',
'organization_users',
'organization_users.organizationId = :organizationId',
{ organizationId: user.organizationId }
)
.where('user.id NOT IN (:...userList)', { userList: [...usersInGroupIds, ...adminUserIds] })
.andWhere(getOrConditions());
if (!searchInput) {
builtQuery.take(10); // Limiting to 10 users if there's no search input
}
builtQuery.orderBy('user.firstName');
return await builtQuery.getMany();
}
async createUserGroupPermission(userId: string, groupPermissionId: string, manager?: EntityManager) {
await dbTransactionWrap(async (manager: EntityManager) => {
await manager.save(
manager.create(UserGroupPermission, {
userId,
groupPermissionId,
})
);
}, manager);
}
}

View file

@ -1,6 +1,5 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { createQueryBuilder } from 'typeorm';
import { User } from '../entities/user.entity';
import { DeepPartial, EntityManager, getRepository, Repository } from 'typeorm';
import { UsersService } from 'src/services/users.service';
@ -8,7 +7,6 @@ import { OrganizationUser } from 'src/entities/organization_user.entity';
import { BadRequestException } from '@nestjs/common';
import { EmailService } from './email.service';
import { Organization } from 'src/entities/organization.entity';
import { GroupPermission } from 'src/entities/group_permission.entity';
import { dbTransactionWrap } from 'src/helpers/utils.helper';
import { ConfigService } from '@nestjs/config';
import { WORKSPACE_USER_SOURCE, WORKSPACE_USER_STATUS } from 'src/helpers/user_lifecycle';
@ -218,20 +216,6 @@ export class OrganizationUsersService {
return personalWorkspaceArray;
}
async lastActiveAdmin(organizationId: string): Promise<boolean> {
const adminsCount = await this.activeAdminCount(organizationId);
return adminsCount <= 1;
}
async activeAdminCount(organizationId: string) {
return await createQueryBuilder(GroupPermission, 'group_permissions')
.innerJoin('group_permissions.userGroupPermission', 'user_group_permission')
.where('group_permissions.group = :admin', { admin: 'admin' })
.andWhere('group_permissions.organization = :organizationId', { organizationId })
.getCount();
}
async organizationsCount(manager?: EntityManager) {
return dbTransactionWrap(async (manager) => {
return await manager