mirror of https://github.com/nocodb/nocodb
Pranav C
2 years ago
5 changed files with 208 additions and 0 deletions
@ -0,0 +1,20 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'; |
||||
import { ModelVisibilitiesController } from './model-visibilities.controller'; |
||||
import { ModelVisibilitiesService } from './model-visibilities.service'; |
||||
|
||||
describe('ModelVisibilitiesController', () => { |
||||
let controller: ModelVisibilitiesController; |
||||
|
||||
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
||||
controllers: [ModelVisibilitiesController], |
||||
providers: [ModelVisibilitiesService], |
||||
}).compile(); |
||||
|
||||
controller = module.get<ModelVisibilitiesController>(ModelVisibilitiesController); |
||||
}); |
||||
|
||||
it('should be defined', () => { |
||||
expect(controller).toBeDefined(); |
||||
}); |
||||
}); |
@ -0,0 +1,49 @@
|
||||
import { |
||||
Body, |
||||
Controller, |
||||
Get, |
||||
Param, |
||||
Post, |
||||
Query, |
||||
UseGuards, |
||||
} from '@nestjs/common'; |
||||
import { |
||||
Acl, |
||||
ExtractProjectIdMiddleware, |
||||
} from '../../middlewares/extract-project-id/extract-project-id.middleware'; |
||||
import { ModelVisibilitiesService } from './model-visibilities.service'; |
||||
import { AuthGuard } from '@nestjs/passport'; |
||||
|
||||
@Controller('model-visibilities') |
||||
@UseGuards(ExtractProjectIdMiddleware, AuthGuard('jwt')) |
||||
export class ModelVisibilitiesController { |
||||
constructor( |
||||
private readonly modelVisibilitiesService: ModelVisibilitiesService, |
||||
) {} |
||||
|
||||
@Post('/api/v1/db/meta/projects/:projectId/visibility-rules') |
||||
@Acl('modelVisibilitySet') |
||||
async xcVisibilityMetaSetAll( |
||||
@Param('projectId') projectId: string, |
||||
@Body() body: any, |
||||
) { |
||||
await this.modelVisibilitiesService.xcVisibilityMetaSetAll({ |
||||
visibilityRule: body, |
||||
projectId, |
||||
}); |
||||
|
||||
return { msg: 'UI ACL has been created successfully' }; |
||||
} |
||||
|
||||
@Get('/api/v1/db/meta/projects/:projectId/visibility-rules') |
||||
@Acl('modelVisibilityList') |
||||
async modelVisibilityList( |
||||
@Param('projectId') projectId: string, |
||||
@Query('includeM2M') includeM2M: boolean | string, |
||||
) { |
||||
return await this.modelVisibilitiesService.xcVisibilityMetaGet({ |
||||
projectId, |
||||
includeM2M: includeM2M === true || includeM2M === 'true', |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common'; |
||||
import { ModelVisibilitiesService } from './model-visibilities.service'; |
||||
import { ModelVisibilitiesController } from './model-visibilities.controller'; |
||||
|
||||
@Module({ |
||||
controllers: [ModelVisibilitiesController], |
||||
providers: [ModelVisibilitiesService] |
||||
}) |
||||
export class ModelVisibilitiesModule {} |
@ -0,0 +1,18 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'; |
||||
import { ModelVisibilitiesService } from './model-visibilities.service'; |
||||
|
||||
describe('ModelVisibilitiesService', () => { |
||||
let service: ModelVisibilitiesService; |
||||
|
||||
beforeEach(async () => { |
||||
const module: TestingModule = await Test.createTestingModule({ |
||||
providers: [ModelVisibilitiesService], |
||||
}).compile(); |
||||
|
||||
service = module.get<ModelVisibilitiesService>(ModelVisibilitiesService); |
||||
}); |
||||
|
||||
it('should be defined', () => { |
||||
expect(service).toBeDefined(); |
||||
}); |
||||
}); |
@ -0,0 +1,112 @@
|
||||
import { Injectable } from '@nestjs/common'; |
||||
import { VisibilityRuleReqType } from 'nocodb-sdk'; |
||||
import { validatePayload } from '../../helpers'; |
||||
import { NcError } from '../../helpers/catchError'; |
||||
import { Model, ModelRoleVisibility, View } from '../../models'; |
||||
import { T } from 'nc-help'; |
||||
|
||||
@Injectable() |
||||
export class ModelVisibilitiesService { |
||||
async xcVisibilityMetaSetAll(param: { |
||||
visibilityRule: VisibilityRuleReqType; |
||||
projectId: string; |
||||
}) { |
||||
validatePayload( |
||||
'swagger.json#/components/schemas/VisibilityRuleReq', |
||||
param.visibilityRule, |
||||
); |
||||
T.emit('evt', { evt_type: 'uiAcl:updated' }); |
||||
for (const d of param.visibilityRule) { |
||||
for (const role of Object.keys(d.disabled)) { |
||||
const view = await View.get(d.id); |
||||
|
||||
if (view.project_id !== param.projectId) { |
||||
NcError.badRequest('View does not belong to the project'); |
||||
} |
||||
|
||||
const dataInDb = await ModelRoleVisibility.get({ |
||||
role, |
||||
fk_view_id: d.id, |
||||
}); |
||||
if (dataInDb) { |
||||
if (d.disabled[role]) { |
||||
if (!dataInDb.disabled) { |
||||
await ModelRoleVisibility.update(d.id, role, { |
||||
disabled: d.disabled[role], |
||||
}); |
||||
} |
||||
} else { |
||||
await dataInDb.delete(); |
||||
} |
||||
} else if (d.disabled[role]) { |
||||
await ModelRoleVisibility.insert({ |
||||
fk_view_id: d.id, |
||||
disabled: d.disabled[role], |
||||
role, |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
T.emit('evt', { evt_type: 'uiAcl:updated' }); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
async xcVisibilityMetaGet(param: { |
||||
projectId: string; |
||||
includeM2M?: boolean; |
||||
models?: Model[]; |
||||
}) { |
||||
const { includeM2M = true, projectId, models: _models } = param ?? {}; |
||||
|
||||
// todo: move to
|
||||
const roles = [ |
||||
'owner', |
||||
'creator', |
||||
'viewer', |
||||
'editor', |
||||
'commenter', |
||||
'guest', |
||||
]; |
||||
|
||||
const defaultDisabled = roles.reduce((o, r) => ({ ...o, [r]: false }), {}); |
||||
|
||||
let models = |
||||
_models || |
||||
(await Model.list({ |
||||
project_id: projectId, |
||||
base_id: undefined, |
||||
})); |
||||
|
||||
models = includeM2M ? models : (models.filter((t) => !t.mm) as Model[]); |
||||
|
||||
const result = await models.reduce(async (_obj, model) => { |
||||
const obj = await _obj; |
||||
|
||||
const views = await model.getViews(); |
||||
for (const view of views) { |
||||
obj[view.id] = { |
||||
ptn: model.table_name, |
||||
_ptn: model.title, |
||||
ptype: model.type, |
||||
tn: view.title, |
||||
_tn: view.title, |
||||
table_meta: model.meta, |
||||
...view, |
||||
disabled: { ...defaultDisabled }, |
||||
}; |
||||
} |
||||
|
||||
return obj; |
||||
}, Promise.resolve({})); |
||||
|
||||
const disabledList = await ModelRoleVisibility.list(projectId); |
||||
|
||||
for (const d of disabledList) { |
||||
if (result[d.fk_view_id]) |
||||
result[d.fk_view_id].disabled[d.role] = !!d.disabled; |
||||
} |
||||
|
||||
return Object.values(result); |
||||
} |
||||
} |
Loading…
Reference in new issue