Skip to content

Commit 357d7cc

Browse files
authored
Merge pull request #1680 from rocket-admin/backend_ceadr_refactoring
Backend ceadr refactoring
2 parents b4ef990 + 0d43b88 commit 357d7cc

42 files changed

Lines changed: 119 additions & 4448 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/src/common/application/global-database-context.interface.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import { ICustomFieldsRepository } from '../../entities/custom-field/repository/
2323
import { IEmailVerificationRepository } from '../../entities/email/repository/email-verification.repository.interface.js';
2424
import { IGroupRepository } from '../../entities/group/repository/group.repository.interface.js';
2525
import { ILogOutRepository } from '../../entities/log-out/repository/log-out-repository.interface.js';
26-
import { IPermissionRepository } from '../../entities/permission/repository/permission.repository.interface.js';
2726
import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js';
2827
import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js';
2928
import { ActionEventsEntity } from '../../entities/table-actions/table-action-events-module/action-event.entity.js';
@@ -70,7 +69,6 @@ export interface IGlobalDatabaseContext extends IDatabaseContext {
7069
userRepository: Repository<UserEntity> & IUserRepository;
7170
connectionRepository: Repository<ConnectionEntity> & IConnectionRepository;
7271
groupRepository: IGroupRepository;
73-
permissionRepository: IPermissionRepository;
7472
tableSettingsRepository: Repository<TableSettingsEntity> & ITableSettingsRepository;
7573
agentRepository: IAgentRepository;
7674
emailVerificationRepository: IEmailVerificationRepository;

backend/src/common/application/global-database-context.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ import { groupCustomRepositoryExtension } from '../../entities/group/repository/
4242
import { LogOutEntity } from '../../entities/log-out/log-out.entity.js';
4343
import { logOutCustomRepositoryExtension } from '../../entities/log-out/repository/log-out-custom-repository-extension.js';
4444
import { ILogOutRepository } from '../../entities/log-out/repository/log-out-repository.interface.js';
45-
import { PermissionEntity } from '../../entities/permission/permission.entity.js';
46-
import { IPermissionRepository } from '../../entities/permission/repository/permission.repository.interface.js';
47-
import { permissionCustomRepositoryExtension } from '../../entities/permission/repository/permission-custom-repository-extension.js';
4845
import { secretAccessLogRepositoryExtension } from '../../entities/secret-access-log/repository/secret-access-log-repository.extension.js';
4946
import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js';
5047
import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js';
@@ -123,7 +120,6 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext {
123120
private _userRepository: Repository<UserEntity> & IUserRepository;
124121
private _connectionRepository: Repository<ConnectionEntity> & IConnectionRepository;
125122
private _groupRepository: IGroupRepository;
126-
private _permissionRepository: IPermissionRepository;
127123
private _tableSettingsRepository: Repository<TableSettingsEntity> & ITableSettingsRepository;
128124
private _agentRepository: IAgentRepository;
129125
private _emailVerificationRepository: IEmailVerificationRepository;
@@ -175,9 +171,6 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext {
175171
.getRepository(ConnectionEntity)
176172
.extend(customConnectionRepositoryExtension);
177173
this._groupRepository = this.appDataSource.getRepository(GroupEntity).extend(groupCustomRepositoryExtension);
178-
this._permissionRepository = this.appDataSource
179-
.getRepository(PermissionEntity)
180-
.extend(permissionCustomRepositoryExtension);
181174
this._tableSettingsRepository = this.appDataSource
182175
.getRepository(TableSettingsEntity)
183176
.extend(tableSettingsCustomRepositoryExtension);
@@ -285,10 +278,6 @@ export class GlobalDatabaseContext implements IGlobalDatabaseContext {
285278
return this._groupRepository;
286279
}
287280

288-
public get permissionRepository(): IPermissionRepository {
289-
return this._permissionRepository;
290-
}
291-
292281
public get tableSettingsRepository(): Repository<TableSettingsEntity> & ITableSettingsRepository {
293282
return this._tableSettingsRepository;
294283
}

backend/src/entities/cedar-authorization/cedar-authorization.service.ts

Lines changed: 5 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import { HttpException, HttpStatus, Inject, Injectable, Logger, OnModuleInit } from '@nestjs/common';
2-
import { AccessLevelEnum, PermissionTypeEnum } from '../../enums/index.js';
32
import { Messages } from '../../exceptions/text/messages.js';
43
import { Cacher } from '../../helpers/cache/cacher.js';
54
import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js';
65
import { BaseType } from '../../common/data-injection.tokens.js';
76
import { GroupEntity } from '../group/group.entity.js';
87
import { IComplexPermission } from '../permission/permission.interface.js';
9-
import { PermissionEntity } from '../permission/permission.entity.js';
108
import {
119
CedarAction,
1210
CedarResourceType,
@@ -87,14 +85,12 @@ export class CedarAuthorizationService implements ICedarAuthorizationService, On
8785
): Promise<{ cedarPolicy: string; classicalPermissions: IComplexPermission }> {
8886
this.validateCedarPolicyText(cedarPolicy);
8987

90-
const group = await this.globalDbContext.groupRepository.findGroupWithPermissionsById(groupId);
88+
const group = await this.globalDbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId);
9189
if (!group) {
9290
throw new HttpException({ message: Messages.GROUP_NOT_FOUND }, HttpStatus.BAD_REQUEST);
9391
}
9492

95-
const groupWithConnection = await this.globalDbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId);
96-
97-
if (groupWithConnection?.connection?.id !== connectionId) {
93+
if (group.connection?.id !== connectionId) {
9894
throw new HttpException({ message: Messages.GROUP_NOT_FROM_THIS_CONNECTION }, HttpStatus.BAD_REQUEST);
9995
}
10096

@@ -106,8 +102,6 @@ export class CedarAuthorizationService implements ICedarAuthorizationService, On
106102

107103
const classicalPermissions = parseCedarPolicyToClassicalPermissions(cedarPolicy, connectionId, groupId);
108104

109-
await this.syncClassicalPermissions(group, classicalPermissions);
110-
111105
group.cedarPolicy = cedarPolicy;
112106
await this.globalDbContext.groupRepository.saveNewOrUpdatedGroup(group);
113107
Cacher.invalidateCedarPolicyCache(connectionId);
@@ -181,7 +175,7 @@ export class CedarAuthorizationService implements ICedarAuthorizationService, On
181175
const userGroups = await this.globalDbContext.groupRepository.findAllUserGroupsInConnection(connectionId, userId);
182176
if (userGroups.length === 0) return false;
183177

184-
const groupPolicies = await this.loadPoliciesPerGroup(connectionId, userGroups);
178+
const groupPolicies = this.loadPoliciesPerGroup(userGroups);
185179
if (groupPolicies.length === 0) return false;
186180

187181
const entities = buildCedarEntities(userId, userGroups, connectionId, tableName, dashboardId);
@@ -210,13 +204,8 @@ export class CedarAuthorizationService implements ICedarAuthorizationService, On
210204
return false;
211205
}
212206

213-
private async loadPoliciesPerGroup(connectionId: string, userGroups: Array<GroupEntity>): Promise<string[]> {
214-
const groups = await this.globalDbContext.groupRepository.findAllGroupsInConnection(connectionId);
215-
const userGroupIdSet = new Set(userGroups.map((g) => g.id));
216-
return groups
217-
.filter((g) => userGroupIdSet.has(g.id))
218-
.map((g) => g.cedarPolicy)
219-
.filter(Boolean);
207+
private loadPoliciesPerGroup(userGroups: Array<GroupEntity>): string[] {
208+
return userGroups.map((g) => g.cedarPolicy).filter(Boolean);
220209
}
221210

222211
private async assertUserNotSuspended(userId: string): Promise<void> {
@@ -316,74 +305,4 @@ export class CedarAuthorizationService implements ICedarAuthorizationService, On
316305
}
317306
}
318307

319-
private async syncClassicalPermissions(group: GroupEntity, permissions: IComplexPermission): Promise<void> {
320-
if (group.permissions && group.permissions.length > 0) {
321-
for (const perm of group.permissions) {
322-
await this.globalDbContext.permissionRepository.removePermissionEntity(perm);
323-
}
324-
}
325-
group.permissions = [];
326-
327-
if (permissions.connection.accessLevel !== AccessLevelEnum.none) {
328-
const connPerm = new PermissionEntity();
329-
connPerm.type = PermissionTypeEnum.Connection;
330-
connPerm.accessLevel = permissions.connection.accessLevel;
331-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(connPerm);
332-
group.permissions.push(saved);
333-
}
334-
335-
if (permissions.group.accessLevel !== AccessLevelEnum.none) {
336-
const groupPerm = new PermissionEntity();
337-
groupPerm.type = PermissionTypeEnum.Group;
338-
groupPerm.accessLevel = permissions.group.accessLevel;
339-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(groupPerm);
340-
group.permissions.push(saved);
341-
}
342-
343-
for (const table of permissions.tables) {
344-
const access = table.accessLevel;
345-
if (access.visibility) {
346-
const perm = new PermissionEntity();
347-
perm.type = PermissionTypeEnum.Table;
348-
perm.accessLevel = AccessLevelEnum.visibility;
349-
perm.tableName = table.tableName;
350-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(perm);
351-
group.permissions.push(saved);
352-
}
353-
if (access.readonly) {
354-
const perm = new PermissionEntity();
355-
perm.type = PermissionTypeEnum.Table;
356-
perm.accessLevel = AccessLevelEnum.readonly;
357-
perm.tableName = table.tableName;
358-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(perm);
359-
group.permissions.push(saved);
360-
}
361-
if (access.add) {
362-
const perm = new PermissionEntity();
363-
perm.type = PermissionTypeEnum.Table;
364-
perm.accessLevel = AccessLevelEnum.add;
365-
perm.tableName = table.tableName;
366-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(perm);
367-
group.permissions.push(saved);
368-
}
369-
if (access.edit) {
370-
const perm = new PermissionEntity();
371-
perm.type = PermissionTypeEnum.Table;
372-
perm.accessLevel = AccessLevelEnum.edit;
373-
perm.tableName = table.tableName;
374-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(perm);
375-
group.permissions.push(saved);
376-
}
377-
if (access.delete) {
378-
const perm = new PermissionEntity();
379-
perm.type = PermissionTypeEnum.Table;
380-
perm.accessLevel = AccessLevelEnum.delete;
381-
perm.tableName = table.tableName;
382-
const saved = await this.globalDbContext.permissionRepository.saveNewOrUpdatedPermission(perm);
383-
group.permissions.push(saved);
384-
}
385-
}
386-
387-
await this.globalDbContext.groupRepository.saveNewOrUpdatedGroup(group);
388-
}
389308
}

backend/src/entities/cedar-authorization/cedar-policy-parser.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ export function parseCedarPolicyToClassicalPermissions(
7979
}
8080

8181
result.tables = Array.from(tableMap.values());
82+
for (const table of result.tables) {
83+
const a = table.accessLevel;
84+
a.readonly = a.visibility && !a.add && !a.edit && !a.delete;
85+
}
8286
result.dashboards = Array.from(dashboardMap.values());
8387

8488
return result;
@@ -215,7 +219,6 @@ function applyTableAction(entry: ITablePermissionData, action: string): void {
215219
switch (action) {
216220
case 'table:read':
217221
entry.accessLevel.visibility = true;
218-
entry.accessLevel.readonly = true;
219222
break;
220223
case 'table:add':
221224
entry.accessLevel.add = true;

backend/src/entities/cedar-authorization/scripts/migrate-permissions-to-cedar.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.

backend/src/entities/company-info/company-info.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { ConnectionPropertiesEntity } from '../connection-properties/connection-
99
import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js';
1010
import { GroupEntity } from '../group/group.entity.js';
1111
import { LogOutEntity } from '../log-out/log-out.entity.js';
12-
import { PermissionEntity } from '../permission/permission.entity.js';
1312
import { TableLogsEntity } from '../table-logs/table-logs.entity.js';
1413
import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js';
1514
import { UserEntity } from '../user/user.entity.js';
@@ -50,7 +49,6 @@ import { VerifyInviteUserInCompanyAndConnectionGroupUseCase } from './use-cases/
5049
ConnectionEntity,
5150
UserEntity,
5251
GroupEntity,
53-
PermissionEntity,
5452
TableSettingsEntity,
5553
TableLogsEntity,
5654
CustomFieldsEntity,

backend/src/entities/connection/connection.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { ConnectionPropertiesEntity } from '../connection-properties/connection-
1010
import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js';
1111
import { GroupEntity } from '../group/group.entity.js';
1212
import { LogOutEntity } from '../log-out/log-out.entity.js';
13-
import { PermissionEntity } from '../permission/permission.entity.js';
1413
import { TableLogsEntity } from '../table-logs/table-logs.entity.js';
1514
import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js';
1615
import { UserEntity } from '../user/user.entity.js';
@@ -43,7 +42,6 @@ import { ValidateConnectionTokenUseCase } from './use-cases/validate-connection-
4342
ConnectionEntity,
4443
UserEntity,
4544
GroupEntity,
46-
PermissionEntity,
4745
TableSettingsEntity,
4846
TableLogsEntity,
4947
CustomFieldsEntity,

backend/src/entities/connection/use-cases/create-connection.use.case.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ export class CreateConnectionUseCase
9999
savedConnection,
100100
connectionAuthor,
101101
);
102-
await this._dbContext.permissionRepository.createdDefaultAdminPermissionsInGroup(createdAdminGroup);
103102
createdAdminGroup.cedarPolicy = generateCedarPolicyForGroup(
104103
savedConnection.id,
105104
true,

backend/src/entities/connection/use-cases/find-all-connections.use.case.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ import { isSaaS } from '../../../helpers/app/is-saas.js';
88
import { Constants } from '../../../helpers/constants/constants.js';
99
import { AmplitudeService } from '../../amplitude/amplitude.service.js';
1010
import { CedarPermissionsService } from '../../cedar-authorization/cedar-permissions.service.js';
11+
import { generateCedarPolicyForGroup } from '../../cedar-authorization/cedar-policy-generator.js';
1112
import { GroupEntity } from '../../group/group.entity.js';
12-
import { PermissionEntity } from '../../permission/permission.entity.js';
1313
import { CreateUserDs } from '../../user/application/data-structures/create-user.ds.js';
1414
import { FindUserDs } from '../../user/application/data-structures/find-user.ds.js';
1515
import { UserRoleEnum } from '../../user/enums/user-role.enum.js';
1616
import { buildConnectionEntitiesFromTestDtos } from '../../user/utils/build-connection-entities-from-test-dtos.js';
1717
import { buildDefaultAdminGroups } from '../../user/utils/build-default-admin-groups.js';
18-
import { buildDefaultAdminPermissions } from '../../user/utils/build-default-admin-permissions.js';
1918
import { FoundConnectionsDs } from '../application/data-structures/found-connections.ds.js';
2019
import { ConnectionEntity } from '../connection.entity.js';
2120
import { buildFoundConnectionDs } from '../utils/build-found-connection.ds.js';
@@ -76,10 +75,16 @@ export class FindAllConnectionsUseCase
7675
return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group);
7776
}),
7877
);
79-
const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups);
8078
await Promise.all(
81-
testPermissionsEntities.map(async (permission: PermissionEntity) => {
82-
await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission);
79+
createdTestGroups.map(async (group: GroupEntity) => {
80+
const connectionId = group.connection?.id;
81+
if (!connectionId) return;
82+
group.cedarPolicy = generateCedarPolicyForGroup(connectionId, group.isMain, {
83+
connection: { connectionId, accessLevel: AccessLevelEnum.edit },
84+
group: { groupId: group.id, accessLevel: AccessLevelEnum.edit },
85+
tables: [],
86+
});
87+
await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group);
8388
}),
8489
);
8590
allFoundUserTestConnections.push(...createdTestConnections);

0 commit comments

Comments
 (0)