161847f8eSopenharmony_ci/*
261847f8eSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
361847f8eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
461847f8eSopenharmony_ci * you may not use this file except in compliance with the License.
561847f8eSopenharmony_ci * You may obtain a copy of the License at
661847f8eSopenharmony_ci *
761847f8eSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
861847f8eSopenharmony_ci *
961847f8eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1061847f8eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1161847f8eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1261847f8eSopenharmony_ci * See the License for the specific language governing permissions and
1361847f8eSopenharmony_ci * limitations under the License.
1461847f8eSopenharmony_ci */
1561847f8eSopenharmony_ci
1661847f8eSopenharmony_ciconst fs = require('fs');
1761847f8eSopenharmony_ciconst path = require('path');
1861847f8eSopenharmony_ciconst { getAPINote, ErrorType, ErrorLevel, FileType, systemPermissionFile, checkOption } = require('./utils');
1961847f8eSopenharmony_ciconst { addAPICheckErrorLogs } = require('./compile_info');
2061847f8eSopenharmony_ci
2161847f8eSopenharmony_ciconst permissionCheckWhitelist = new Set(['@ohos.wifi.d.ts', '@ohos.wifiManager.d.ts']);
2261847f8eSopenharmony_ci
2361847f8eSopenharmony_ci/**
2461847f8eSopenharmony_ci * 门禁环境优先使用systemPermissionFile
2561847f8eSopenharmony_ci * 本地环境从指定分支上下载
2661847f8eSopenharmony_ci * 下载失败则使用默认配置
2761847f8eSopenharmony_ci *
2861847f8eSopenharmony_ci * @returns Set<string>
2961847f8eSopenharmony_ci */
3061847f8eSopenharmony_cifunction getPermissionBank() {
3161847f8eSopenharmony_ci  const permissionTags = ['ohos.permission.HEALTH_DATA', 'ohos.permission.HEART_RATE', 'ohos.permission.ACCELERATION'];
3261847f8eSopenharmony_ci  let permissionFileContent;
3361847f8eSopenharmony_ci  if (fs.existsSync(systemPermissionFile)) {
3461847f8eSopenharmony_ci    permissionFileContent = require(systemPermissionFile);
3561847f8eSopenharmony_ci  } else if (checkOption.permissionContent) {
3661847f8eSopenharmony_ci    permissionFileContent = JSON.parse(checkOption.permissionContent);
3761847f8eSopenharmony_ci  } else {
3861847f8eSopenharmony_ci    permissionFileContent = require('../config/config.json');
3961847f8eSopenharmony_ci  }
4061847f8eSopenharmony_ci  const permissionTagsObj = permissionFileContent.module.definePermissions;
4161847f8eSopenharmony_ci  permissionTagsObj.forEach((item) => {
4261847f8eSopenharmony_ci    permissionTags.push(item.name);
4361847f8eSopenharmony_ci  });
4461847f8eSopenharmony_ci  const permissionRuleSets = new Set(permissionTags);
4561847f8eSopenharmony_ci  return permissionRuleSets;
4661847f8eSopenharmony_ci}
4761847f8eSopenharmony_ciexports.getPermissionBank = getPermissionBank;
4861847f8eSopenharmony_ci
4961847f8eSopenharmony_cifunction checkPermission(node, sourcefile, fileName) {
5061847f8eSopenharmony_ci  const permissionRuleSet = getPermissionBank();
5161847f8eSopenharmony_ci  const apiNote = getAPINote(node);
5261847f8eSopenharmony_ci  let hasPermissionError = false;
5361847f8eSopenharmony_ci  let errorInfo = '';
5461847f8eSopenharmony_ci  let apiNoteArr = [];
5561847f8eSopenharmony_ci  if (apiNote.match(new RegExp('@permission'))) {
5661847f8eSopenharmony_ci    apiNoteArr = apiNote.split(/ *\* *\@/g);
5761847f8eSopenharmony_ci  }
5861847f8eSopenharmony_ci  apiNoteArr.forEach(note => {
5961847f8eSopenharmony_ci    // 找到jsdoc中的permission标签关键字并拿到待校验的permission字段
6061847f8eSopenharmony_ci    if (note.match(new RegExp(/^permission\b/))) {
6161847f8eSopenharmony_ci      const permissionNote = note.replace(/(^permission\b|[(\r\n)\r\n ]|(\*\/|\*))/g, '').trim();
6261847f8eSopenharmony_ci      if (/(or|and)/g.test(permissionNote)) {
6361847f8eSopenharmony_ci        const permissionArr = permissionNote.replace(/( |or|and|\(|\))/g, '$').split('$');
6461847f8eSopenharmony_ci        permissionArr.forEach(permissionStr => {
6561847f8eSopenharmony_ci          if (permissionStr !== '') {
6661847f8eSopenharmony_ci            if (!permissionRuleSet.has(permissionStr)) {
6761847f8eSopenharmony_ci              hasPermissionError = true;
6861847f8eSopenharmony_ci              if (errorInfo !== '') {
6961847f8eSopenharmony_ci                errorInfo += `,${permissionStr}`;
7061847f8eSopenharmony_ci              } else {
7161847f8eSopenharmony_ci                errorInfo += permissionStr;
7261847f8eSopenharmony_ci              }
7361847f8eSopenharmony_ci            }
7461847f8eSopenharmony_ci          }
7561847f8eSopenharmony_ci        });
7661847f8eSopenharmony_ci      } else {
7761847f8eSopenharmony_ci        if (!permissionRuleSet.has(permissionNote)) {
7861847f8eSopenharmony_ci          hasPermissionError = true;
7961847f8eSopenharmony_ci          if (errorInfo !== '') {
8061847f8eSopenharmony_ci            errorInfo += `,${permissionNote}`;
8161847f8eSopenharmony_ci          } else {
8261847f8eSopenharmony_ci            errorInfo += permissionNote;
8361847f8eSopenharmony_ci          }
8461847f8eSopenharmony_ci        }
8561847f8eSopenharmony_ci      }
8661847f8eSopenharmony_ci    }
8761847f8eSopenharmony_ci  });
8861847f8eSopenharmony_ci
8961847f8eSopenharmony_ci  if (hasPermissionError && !permissionCheckWhitelist.has(path.basename(fileName))) {
9061847f8eSopenharmony_ci    addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.UNKNOW_PERMISSION, errorInfo, FileType.API,
9161847f8eSopenharmony_ci      ErrorLevel.MIDDLE);
9261847f8eSopenharmony_ci  } else if (hasPermissionError && permissionCheckWhitelist.has(path.basename(fileName))) {
9361847f8eSopenharmony_ci    addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.UNKNOW_PERMISSION, errorInfo, FileType.API,
9461847f8eSopenharmony_ci      ErrorLevel.LOW);
9561847f8eSopenharmony_ci  }
9661847f8eSopenharmony_ci}
9761847f8eSopenharmony_ciexports.checkPermission = checkPermission;
98