1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "shell_command_config_loader.h"
17 #include <fstream>
18 #include <sstream>
19 #include <nlohmann/json.hpp>
20 #include <unistd.h>
21 #include "hilog_tag_wrapper.h"
22 
23 using json = nlohmann::json;
24 namespace OHOS {
25 namespace AAFwk {
26 namespace {
27     constexpr const char* AA_TOOL_COMMAND_LIST = "command_list";
28     constexpr static int  COMMANDS_MAX_SIZE = 100;
29 }
30 
31 bool ShellCommandConfigLoader::configState_ = false;
32 std::set<std::string> ShellCommandConfigLoader::commands_ = {};
33 
ReadConfig(const std::string & filePath)34 bool ShellCommandConfigLoader::ReadConfig(const std::string &filePath)
35 {
36     TAG_LOGD(AAFwkTag::AA_TOOL, "called");
37     if (configState_) {
38         TAG_LOGI(AAFwkTag::AA_TOOL, "config read");
39         return true;
40     }
41 
42     if (filePath.empty()) {
43         TAG_LOGE(AAFwkTag::AA_TOOL, "empty file path");
44         return false;
45     }
46 
47     if (access(filePath.c_str(), F_OK) != 0) {
48         TAG_LOGE(AAFwkTag::AA_TOOL, "access file: %{private}s failed", filePath.c_str());
49         return false;
50     }
51 
52     std::ifstream inFile;
53     inFile.open(filePath, std::ios::in);
54     if (!inFile.is_open()) {
55         TAG_LOGI(AAFwkTag::AA_TOOL, "read aa config error");
56         return false;
57     }
58 
59     json aaJson;
60     inFile >> aaJson;
61     inFile.close();
62     if (aaJson.is_discarded()) {
63         TAG_LOGI(AAFwkTag::AA_TOOL, "json discarded error");
64         return false;
65     }
66 
67     if (aaJson.is_null() || aaJson.empty()) {
68         TAG_LOGI(AAFwkTag::AA_TOOL, "invalid jsonObj");
69         return false;
70     }
71 
72     if (!aaJson.contains(AA_TOOL_COMMAND_LIST)) {
73         TAG_LOGI(AAFwkTag::AA_TOOL, "config not contains the key");
74         return false;
75     }
76 
77     if (aaJson[AA_TOOL_COMMAND_LIST].is_null() || !aaJson[AA_TOOL_COMMAND_LIST].is_array() ||
78         aaJson[AA_TOOL_COMMAND_LIST].empty()) {
79         TAG_LOGI(AAFwkTag::AA_TOOL, "invalid command obj size");
80         return false;
81     }
82 
83     if (aaJson[AA_TOOL_COMMAND_LIST].size() > COMMANDS_MAX_SIZE) {
84         TAG_LOGI(AAFwkTag::AA_TOOL, "command obj size overflow");
85         return false;
86     }
87 
88     std::lock_guard<std::mutex> lock(mtxRead_);
89     for (size_t i = 0; i < aaJson[AA_TOOL_COMMAND_LIST].size(); i++) {
90         if (aaJson[AA_TOOL_COMMAND_LIST][i].is_null() || !aaJson[AA_TOOL_COMMAND_LIST][i].is_string()) {
91             continue;
92         }
93         std::string cmd = aaJson[AA_TOOL_COMMAND_LIST][i].get<std::string>();
94         TAG_LOGD(AAFwkTag::AA_TOOL, "add cmd: %{public}s", cmd.c_str());
95         commands_.emplace(cmd);
96     }
97 
98     aaJson.clear();
99     TAG_LOGI(AAFwkTag::AA_TOOL, "read config success");
100     configState_ = true;
101     return true;
102 }
103 
104 }  // namespace AAFwk
105 }  // namespace OHOS