import Context from "../../context" import { IImportConfig, ImportResponse, ReturnMessage, ImportResult, ImportMode, IRelationImportRequest, IAttributeImportRequest, IRoleImportRequest, IGroupsAccessRequest } from "../../models/import" import { sequelize } from "../../models" import { ModelsManager, ModelManager, AttrGroupWrapper } from "../../models/manager" import { Item } from "../../models/items" import { Role, User } from "../../models/users" import { Op, literal } from 'sequelize' import logger from '../../logger' /* mutation { import( config: { mode: CREATE_UPDATE errors: PROCESS_WARN }, roles: [ { delete: false, name: "Администратор2", itemAccess: {access:0, valid:[], groups:[], fromItems:[]}, configAccess: {lovs:2,roles:2,types:2,users:2,languages:2,relations:2,attributes:2}, identifier: "admin2", relAccess: {access:0,relations:[],groups:[]}, } ] ) { roles { identifier result id errors { code message } warnings { code message } }}} */ export async function importRole(context: Context, config: IImportConfig, role: IRoleImportRequest): Promise<ImportResponse> { const result = new ImportResponse(role.identifier) if (!role.identifier || !/^[A-Za-z0-9_-]*$/.test(role.identifier)) { result.addError(ReturnMessage.WrongIdentifier) result.result = ImportResult.REJECTED return result } try { if (role.identifier === 'admin') { result.addError(ReturnMessage.RoleAdminCanNotBeUpdated) result.result = ImportResult.REJECTED return result } const mng = ModelsManager.getInstance().getModelManager(context.getCurrentUser()!.tenantId) const idx = mng.getRoles().findIndex(elem => elem.identifier === role.identifier) if (role.delete) { if (idx === -1) { result.addError(ReturnMessage.RoleNotFound) result.result = ImportResult.REJECTED } else { const data = mng.getRoles()[idx] if (data.identifier === 'admin') { result.addError(ReturnMessage.RoleAdminCanNotBeUpdated) result.result = ImportResult.REJECTED return result } // check Users // const tst1 = await User.applyScope(context).findOne({where: {roles: { [Op.contains]: data.id}}}) const tst1 = await User.applyScope(context).findOne({where: literal("roles @> '"+data.id+"'")}) if (tst1) { result.addError(ReturnMessage.RoleDeleteFailed) result.result = ImportResult.REJECTED return result } data.updatedBy = context.getCurrentUser()!.login data.identifier = role.identifier + '_d_' + Date.now() await sequelize.transaction(async (t) => { await data.save({transaction: t}) await data.destroy({transaction: t}) }) mng.getRoles().splice(idx, 1) mng.getUsers().forEach(wrapper => { const idx = wrapper.getRoles().findIndex(r => r.id === data.id) if (idx !== -1) wrapper.getRoles().splice(idx, 1) }) result.result = ImportResult.DELETED } return result } if (config.mode === ImportMode.CREATE_ONLY) { if (idx !== -1) { result.addError(ReturnMessage.RoleExist) result.result = ImportResult.REJECTED return result } } else if (config.mode === ImportMode.UPDATE_ONLY) { if (idx === -1) { result.addError(ReturnMessage.RoleNotFound) result.result = ImportResult.REJECTED return result } } if (idx === -1) { // create let relationIds = checkRelations(role.relAccess.relations, mng, result) if (result.result) return result let groups = checkGroups(role.relAccess.groups, mng, result) if (result.result) return result const relAccess = {access: role.relAccess.access || 0, relations: relationIds, groups: groups} let valid = checkValid(role.itemAccess.valid, mng, result) if (result.result) return result let groups2 = checkGroups(role.itemAccess.groups, mng, result) if (result.result) return result let fromItems = await checkFromItems(role.itemAccess.fromItems, context, result) if (result.result) return result const itemAccess = { valid: valid, fromItems: fromItems, access: role.itemAccess.access || 0, groups: groups2 } const data = await sequelize.transaction(async (t) => { return await Role.create ({ identifier: role.identifier, tenantId: context.getCurrentUser()!.tenantId, createdBy: context.getCurrentUser()!.login, updatedBy: context.getCurrentUser()!.login, name: role.name || '', configAccess: role.configAccess || { types: 0, attributes: 0, relations: 0, users: 0, roles: 0, languages: 0 }, relAccess: relAccess, itemAccess: itemAccess, otherAccess: role.otherAccess || { audit: false, search: false, exportXLS: false, exportCSV: false, importXLS: false, searchRelations: false, exportRelationsXLS: false, importRelationsXLS: false }, options: role.options ? role.options : [] }, {transaction: t}) }) mng.getRoles().push(data); result.id = ""+data.id result.result = ImportResult.CREATED } else { // update const data = mng.getRoles()[idx] if (role.name) data.name = role.name if (role.configAccess) data.configAccess = role.configAccess if (role.relAccess) { let relationIds = checkRelations(role.relAccess.relations, mng, result) if (result.result) return result let groups = checkGroups(role.relAccess.groups, mng, result) if (result.result) return result const relAccess = {access: role.relAccess.access || 0, relations: relationIds, groups: groups} data.relAccess = relAccess } if (role.itemAccess) { let valid = checkValid(role.itemAccess.valid, mng, result) if (result.result) return result let groups2 = checkGroups(role.itemAccess.groups, mng, result) if (result.result) return result let fromItems = await checkFromItems(role.itemAccess.fromItems, context, result) if (result.result) return result const itemAccess = { valid: valid, fromItems: fromItems, access: role.itemAccess.access || 0, groups: groups2 } data.itemAccess = itemAccess } if (role.otherAccess) data.otherAccess = role.otherAccess if (role.options != null) data.options = role.options data.updatedBy = context.getCurrentUser()!.login await sequelize.transaction(async (t) => { await data.save({transaction: t}) }) result.id = ""+data.id result.result = ImportResult.UPDATED } } catch (error) { result.addError(new ReturnMessage(0, ""+error)) result.result = ImportResult.REJECTED logger.error(error) } return result } function checkRelations(relations: [string], mng: ModelManager, result: ImportResponse) { let rels: number[] = [] if (relations) { for (let index = 0; index < relations.length; index++) { const relIdentifier = relations[index]; const tst = mng.getRelationByIdentifier(relIdentifier) if (!tst) { result.addError(ReturnMessage.RelationNotFound) result.result = ImportResult.REJECTED return <number[]>[] } rels.push(tst.id) } } return rels } function checkGroups(groups: [IGroupsAccessRequest], mng: ModelManager, result: ImportResponse) { const arr: any[] = [] if (groups) { for (let index = 0; index < groups.length; index++) { const data = groups[index] const grpIdentifier = data.groupIdentifier; const tst = mng.getAttrGroups().find(grp => grp.getGroup().identifier === grpIdentifier) if (!tst) { result.addError(ReturnMessage.AttrGroupNotFound) result.result = ImportResult.REJECTED return <AttrGroupWrapper[]>[] } arr.push({access: data.access, groupId: tst.getGroup().id}) } } return arr } function checkValid(valid: [string], mng: ModelManager, result: ImportResponse) { let arr: number[] = [] if (valid) { for (let index = 0; index < valid.length; index++) { const typeIdentifier = valid[index]; const tst = mng.getTypeByIdentifier(typeIdentifier) if (!tst) { result.addError(ReturnMessage.TypeNotFound) result.result = ImportResult.REJECTED return <number[]>[] } arr.push(tst.getValue().id) } } return arr } async function checkFromItems(identifiers: [string], context: Context, result: ImportResponse) { if (identifiers) { const items = await Item.applyScope(context).findAll({ where: { identifier: identifiers} }) return items.map(item => item.id) } else { return [] } }