@lcap/nasl
Version:
NetEase Application Specific Language
127 lines • 4.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isViewLogic = exports.cachePermission = void 0;
const types_1 = require("../types");
const utils_1 = require("../utils");
const utils_2 = require("../../../utils");
const nasl_concepts_1 = require("@lcap/nasl-concepts");
const permission_1 = require("../../../generator/permission");
const storage_1 = require("../storage");
const lodash_1 = require("lodash");
const permissionKey = '__permission';
const { setter, getter } = (0, storage_1.getStorageController)(permissionKey);
function cachePermission(data) {
if (!utils_2.isBrowser) {
return;
}
return setter(data);
}
exports.cachePermission = cachePermission;
/** 获取所有调用逻辑和权限节点 */
function getCallLogicAndAuthNode(action) {
function isGlobalCallLogic(data) {
if (data && 'calleeName' in data && 'calleeNamespace' in data) {
const name = data.calleeNamespace;
return name?.startsWith('app') || name?.startsWith('extensions');
}
return false;
}
function getAuthNode(node, path, context) {
if (!node || !('concept' in node) || !(node.concept !== 'View' && node.concept !== 'BindDirective')) {
return;
}
if (node.concept === 'View' && 'auth' in node && node.auth) {
return path;
}
if (node.concept === 'BindDirective' && 'name' in node && node.name !== 'auth') {
return context.parentPath;
}
}
function getCallLogicAndAuthNode(object, path) {
if (!object || typeof object !== 'object') {
return {
callLogicNodes: [],
authNodes: [],
};
}
const callLogicNodes = [];
const authNodes = [];
const collect = (object, root) => {
if (!object || !object.concept) {
return;
}
(0, nasl_concepts_1.fastTraverseNaslObject)(object, root, (node, path, context) => {
if (isGlobalCallLogic(node)) {
callLogicNodes.push(path);
}
else {
const authNode = getAuthNode(node, path, context);
if (authNode) {
authNodes.push(authNode);
}
}
});
};
// 不是节点,但是可以做逻辑校验
if (!object.concept) {
if (isGlobalCallLogic(object)) {
callLogicNodes.push(path);
}
// 迭代子节点
for (const key of Object.keys(object)) {
const item = object[key];
if (Array.isArray(item)) {
item.forEach((v, i) => v && collect(v, `${path}.${key}[${v.name ? `name=${v.name}` : i}]`));
}
else {
collect(item, `${path}.${key}`);
}
}
}
else {
collect(object, path);
}
return {
callLogicNodes,
authNodes,
};
}
const obj1 = getCallLogicAndAuthNode(action.object, action.path);
const obj2 = getCallLogicAndAuthNode(action.oldObject, action.path);
return {
authNodes: obj1.authNodes.concat(obj2.authNodes),
callLogicNodes: obj1.callLogicNodes.concat(obj2.callLogicNodes),
};
}
exports.isViewLogic = {
name: 'is-view-logic',
afterInstruct(action, { app: { preferenceMap } }) {
// 排除非前端元素
if (!(0, utils_1.isFrontendPath)(action.path)) {
return types_1.RuleResult.UnMatch;
}
// 调用逻辑和权限节点
const { callLogicNodes } = getCallLogicAndAuthNode(action);
// 未修改全局调用,则为前端更改
if (callLogicNodes.length === 0) {
return types_1.RuleResult.Frontend;
}
else {
return preferenceMap.onDemandInterfaceGeneration === 'false' && preferenceMap.serverValidationRules === 'disabled'
? types_1.RuleResult.Frontend
: types_1.RuleResult.Backend;
}
},
async beforeDeploy(context) {
const oldPermission = await getter();
const newPermission = (0, permission_1.genPermissionData)(context.app);
if ((0, lodash_1.isEqual)(oldPermission, newPermission)) {
return types_1.RuleResult.Frontend;
}
else {
await setter(newPermission);
return types_1.RuleResult.Backend;
}
},
};
//# sourceMappingURL=is-view-logic.js.map