From c5cc772706d49488511128a6256a5503cda1b278 Mon Sep 17 00:00:00 2001 From: lihehe Date: Tue, 6 May 2025 11:10:01 +0800 Subject: [PATCH] add permission check when generating Signed-off-by: lihehe Change-Id: I570d3251490423c5319c2e62b7e40a7c7008e15c --- frameworks/common/BUILD.gn | 20 +++- frameworks/common/permission_check.py | 112 ++++++++++++++++++ .../common/permission_definition_parser.py | 2 +- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100755 frameworks/common/permission_check.py diff --git a/frameworks/common/BUILD.gn b/frameworks/common/BUILD.gn index 65c5ded7c..30c9f2b95 100644 --- a/frameworks/common/BUILD.gn +++ b/frameworks/common/BUILD.gn @@ -19,6 +19,20 @@ config("accesstoken_common_cxx_public_config") { include_dirs = [ "include" ] } +action("permission_definition_check") { + script = "permission_check.py" + args = [ + "--source-root-dir", + rebase_path("//", root_build_dir), + "--input-full-permissions", + rebase_path("${access_token_path}") + + "/services/accesstokenmanager/permission_definitions.json", + ] + inputs = [ rebase_path("${access_token_path}") + + "/services/accesstokenmanager/permission_definitions.json" ] + outputs = [ "$target_out_dir" ] +} + action("permission_definition_parse") { script = "permission_definition_parser.py" inputs = [ rebase_path("${access_token_path}") + @@ -32,7 +46,10 @@ action("permission_definition_parse") { "--target-platform", target_platform, ] - outputs = [ "$target_out_dir" ] + outputs = [ "$target_out_dir" + "/permission_map_constant.h" ] + if (!ohos_indep_compiler_enable) { + deps = [ ":permission_definition_check" ] + } } ohos_static_library("accesstoken_static_log") { @@ -98,6 +115,7 @@ ohos_shared_library("accesstoken_common_cxx") { ":accesstoken_static_log", ":permission_definition_parse", ] + external_deps = [ "c_utils:utils", "hilog:libhilog", diff --git a/frameworks/common/permission_check.py b/frameworks/common/permission_check.py new file mode 100755 index 000000000..85f8a3ed4 --- /dev/null +++ b/frameworks/common/permission_check.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" +Copyright (c) 2025 Huawei Device Co., Ltd. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" + +import json +import argparse +import os + + +REQUIRED_ATTRS = [ + "name", + "grantMode", + "availableLevel", + "since", + "provisionEnable", + "distributedSceneEnable" +] + + +ATTRS_ONLY_IN_RESOURCE = [ + "label", + "description" +] + + +def parse_definition_json(path): + permission_maps = {} + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + for perm in data["definePermissions"]: + permission_maps[perm["name"]] = perm + return permission_maps + + +def parse_module_json(path): + permission_maps = {} + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + for perm in data["module"]["definePermissions"]: + permission_maps[perm["name"]] = perm + return permission_maps + + +def check_required_param(defs, filename): + for attr in REQUIRED_ATTRS: + if not attr in defs: + raise Exception("Not found {} of {} in {}".format( + attr, defs["name"], filename)) + + +def check_consistency(def_in_module, full_def): + for attr, value in full_def.items(): + if not attr in def_in_module: + continue + if not value == def_in_module[attr]: + raise Exception("{} of {} is inconsistent in module.json and permission_definition.json".format( + attr, def_in_module["name"])) + + for attr in def_in_module.keys(): + if attr in ATTRS_ONLY_IN_RESOURCE: + continue + elif not attr in full_def: + raise Exception("{} of {} should be define in permission_definition.json".format(attr, + def_in_module["name"])) + + +def check_maps(module_map, definition_map): + for name, perm_def in definition_map.items(): + if not "availableType" in perm_def: + raise Exception("Cannot define permission {} without availableType " \ + "in permission_definition.json".format(name)) + if perm_def["availableType"] == "SERVICE": + if name in module_map: + raise Exception("Cannot define permission {} for SERVICE in module.json".format(name)) + continue + if not name in module_map: + raise Exception("To add permission definition of {} in system_global_resource.".format(name)) + check_required_param(module_map[name], "module.json") + check_required_param(definition_map[name], "permission_definition.json") + check_consistency(module_map[name], definition_map[name]) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--source-root-dir', help='build root dir', required=True) + parser.add_argument('--input-full-permissions', help='json file for permission definition', required=True) + return parser.parse_args() + + +if __name__ == "__main__": + input_args = parse_args() + module_json_path = os.path.join("base/global/system_resources/systemres/main", "module.json") + module_json_path = os.path.join(input_args.source_root_dir, module_json_path) + module_map = parse_module_json(module_json_path) + definition_map = parse_definition_json(input_args.input_full_permissions) + check_maps(module_map, definition_map) + print("Check permission consistency pass!") \ No newline at end of file diff --git a/frameworks/common/permission_definition_parser.py b/frameworks/common/permission_definition_parser.py index 88af60ed4..014e65fea 100755 --- a/frameworks/common/permission_definition_parser.py +++ b/frameworks/common/permission_definition_parser.py @@ -127,7 +127,7 @@ class PermissionDef(object): raise Exception("No deviceTypes in permission difinition of {}".format(self.name)) if "deviceTypes" in permission_def_dict: - if type(permission_def_dict["deviceTypes"]) == list and len(permission_def_dict["deviceTypes"]) > 0: + if isinstance(permission_def_dict["deviceTypes"], list) and len(permission_def_dict["deviceTypes"]) > 0: self.device_types = permission_def_dict["deviceTypes"] else: raise Exception("Must be filled with available device type list, name = {}".format(self.name)) -- Gitee