1 /*
2 * Copyright (c) 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 "edm_command.h"
17
18 #include <getopt.h>
19 #include <iostream>
20 #include <string>
21
22 #include "admin_type.h"
23 #include "element_name.h"
24
25 namespace OHOS {
26 namespace EDM {
27 const std::string SHORT_OPTIONS = "hn:a:t:";
28 const std::string ADMIN_TYPE_ENT_STRING = "super";
29 const std::string ADMIN_TYPE_BYOD_STRING = "byod";
30 constexpr int32_t OPTION_NUM = 4;
31
32 const struct option LONG_OPTIONS[OPTION_NUM] = {
33 {"help", no_argument, nullptr, 'h'},
34 {"bundle-name", required_argument, nullptr, 'n'},
35 {"ability-name", required_argument, nullptr, 'a'},
36 {"admin-type", required_argument, nullptr, 't'}
37 };
38
EdmCommand(int argc,char * argv[])39 EdmCommand::EdmCommand(int argc, char *argv[]) : ShellCommand(argc, argv, TOOL_NAME) {}
40
CreateCommandMap()41 ErrCode EdmCommand::CreateCommandMap()
42 {
43 commandMap_ = {
44 { "help", [this]{return this->RunAsHelpCommand();} },
45 { "enable-admin", [this]{return this->RunAsEnableCommand();} },
46 { "disable-admin", [this]{return this->RunAsDisableAdminCommand();} }
47 };
48 return ERR_OK;
49 }
50
CreateMessageMap()51 ErrCode EdmCommand::CreateMessageMap()
52 {
53 messageMap_ = { // error + message
54 {ERR_EDM_TOOLS_COMMAND_NO_OPTION, "error: command requires option."},
55 {ERR_EDM_TOOLS_COMMAND_N_OPTION_REQUIRES_AN_ARGUMENT, "error: -n, --bundle-name option requires an argument."},
56 {ERR_EDM_TOOLS_COMMAND_A_OPTION_REQUIRES_AN_ARGUMENT, "error: -a, --ability-name option requires an argument."},
57 {ERR_EDM_TOOLS_COMMAND_T_OPTION_REQUIRES_AN_ARGUMENT, "error: -t, --admin-type option requires an argument."},
58 {ERR_EDM_TOOLS_COMMAND_UNKNOWN_OPTION, "error: unknown option."},
59 {ERR_EDM_TOOLS_COMMAND_NO_BUNDLE_NAME_OPTION, "error: -n <bundle-name> is expected."},
60 {ERR_EDM_TOOLS_COMMAND_NO_ABILITY_NAME_OPTION, "error: -a <ability-name> is expected."},
61 {ERR_EDM_TOOLS_COMMAND_NO_ADMIN_TYPE_OPTION, "error: -t <admin-type> is expected."},
62 {ERR_EDM_TOOLS_COMMAND_UNKNOWN_ADMIN_TYPE, "error: argument <admin-type> is unknown value."},
63 {EdmReturnErrCode::COMPONENT_INVALID, "error: the administrator ability component is invalid."},
64 {EdmReturnErrCode::ENABLE_ADMIN_FAILED, "error: failed to enable the administrator application of the device."},
65 {EdmReturnErrCode::DISABLE_ADMIN_FAILED,
66 "error: failed to disable the administrator application of the device."}
67 };
68 return ERR_OK;
69 }
70
Init()71 ErrCode EdmCommand::Init()
72 {
73 if (!enterpriseDeviceMgrProxy_) {
74 enterpriseDeviceMgrProxy_ = EnterpriseDeviceMgrProxy::GetInstance();
75 }
76 return ERR_OK;
77 }
78
RunAsHelpCommand()79 ErrCode EdmCommand::RunAsHelpCommand()
80 {
81 resultReceiver_.append(HELP_MSG);
82 return ERR_OK;
83 }
84
RunAsEnableCommand()85 ErrCode EdmCommand::RunAsEnableCommand()
86 {
87 std::string bundleName;
88 std::string abilityName;
89 AdminType adminType = AdminType::ENT;
90 ErrCode result = ParseEnableAdminCommandOption(bundleName, abilityName, adminType);
91 if (result == ERR_EDM_TOOLS_COMMAND_HELP && bundleName.empty() &&
92 abilityName.empty()) {
93 return ReportMessage(ERR_EDM_TOOLS_COMMAND_HELP, true);
94 }
95 if (result != ERR_EDM_TOOLS_COMMAND_HELP && result != ERR_OK) {
96 return ReportMessage(result, true);
97 }
98 if (bundleName.empty()) {
99 return ReportMessage(ERR_EDM_TOOLS_COMMAND_NO_BUNDLE_NAME_OPTION, true);
100 }
101 if (abilityName.empty()) {
102 return ReportMessage(ERR_EDM_TOOLS_COMMAND_NO_ABILITY_NAME_OPTION, true);
103 }
104 OHOS::AppExecFwk::ElementName elementName;
105 elementName.SetElementBundleName(&elementName, bundleName.c_str());
106 elementName.SetElementAbilityName(&elementName, abilityName.c_str());
107 EntInfo info;
108 result = enterpriseDeviceMgrProxy_->EnableAdmin(elementName, info, adminType, DEFAULT_USER_ID);
109 return ReportMessage(result, true);
110 }
111
RunAsDisableAdminCommand()112 ErrCode EdmCommand::RunAsDisableAdminCommand()
113 {
114 std::string bundleName;
115 std::string abilityName;
116 AdminType adminType = AdminType::UNKNOWN;
117 ErrCode result = ParseEnableAdminCommandOption(bundleName, abilityName, adminType);
118 if (result == ERR_EDM_TOOLS_COMMAND_HELP && bundleName.empty()) {
119 return ReportMessage(ERR_EDM_TOOLS_COMMAND_HELP, false);
120 }
121 if (result != ERR_EDM_TOOLS_COMMAND_HELP && result != ERR_OK) {
122 return ReportMessage(result, false);
123 }
124 if (bundleName.empty()) {
125 return ReportMessage(ERR_EDM_TOOLS_COMMAND_NO_BUNDLE_NAME_OPTION, false);
126 }
127 OHOS::AppExecFwk::ElementName elementName;
128 elementName.SetElementBundleName(&elementName, bundleName.c_str());
129 elementName.SetElementAbilityName(&elementName, abilityName.c_str());
130 result = enterpriseDeviceMgrProxy_->DisableAdmin(elementName, DEFAULT_USER_ID);
131 return ReportMessage(result, false);
132 }
133
ParseEnableAdminCommandOption(std::string & bundleName,std::string & abilityName,AdminType & adminType)134 ErrCode EdmCommand::ParseEnableAdminCommandOption(std::string &bundleName, std::string &abilityName,
135 AdminType &adminType)
136 {
137 int count = 0;
138 ErrCode ret = ERR_INVALID_VALUE;
139 while (count < OPTION_NUM) {
140 count++;
141 int32_t option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
142 if (option == -1) {
143 if (count == 1) {
144 ret = ERR_EDM_TOOLS_COMMAND_NO_OPTION;
145 }
146 break;
147 }
148 if (option == '?') {
149 ret = RunAsEnableCommandMissingOptionArgument();
150 break;
151 }
152 ret = RunAsEnableCommandParseOptionArgument(option, bundleName, abilityName, adminType);
153 }
154 return ret;
155 }
156
RunAsEnableCommandMissingOptionArgument()157 ErrCode EdmCommand::RunAsEnableCommandMissingOptionArgument()
158 {
159 switch (optopt) {
160 case 'n':
161 return ERR_EDM_TOOLS_COMMAND_N_OPTION_REQUIRES_AN_ARGUMENT;
162 case 'a':
163 return ERR_EDM_TOOLS_COMMAND_A_OPTION_REQUIRES_AN_ARGUMENT;
164 case 't':
165 return ERR_EDM_TOOLS_COMMAND_T_OPTION_REQUIRES_AN_ARGUMENT;
166 default:
167 return ERR_EDM_TOOLS_COMMAND_UNKNOWN_OPTION;
168 }
169 }
170
RunAsEnableCommandParseOptionArgument(int option,std::string & bundleName,std::string & abilityName,AdminType & adminType)171 ErrCode EdmCommand::RunAsEnableCommandParseOptionArgument(int option, std::string &bundleName,
172 std::string &abilityName, AdminType &adminType)
173 {
174 ErrCode ret = ERR_OK;
175 switch (option) {
176 case 'h':
177 ret = ERR_EDM_TOOLS_COMMAND_HELP;
178 break;
179 case 'n':
180 bundleName = optarg;
181 break;
182 case 'a':
183 abilityName = optarg;
184 break;
185 case 't':
186 ret = ConvertStringToAdminType(optarg, adminType);
187 break;
188 default:
189 break;
190 }
191 return ret;
192 }
193
ReportMessage(int32_t code,bool isEnable)194 ErrCode EdmCommand::ReportMessage(int32_t code, bool isEnable)
195 {
196 if (code == ERR_OK) {
197 resultReceiver_.append(cmd_ + " success.\n");
198 return ERR_OK;
199 }
200 if (code != ERR_EDM_TOOLS_COMMAND_HELP) {
201 resultReceiver_.append(GetMessageFromCode(code));
202 }
203 if (code == EdmReturnErrCode::COMPONENT_INVALID || code == EdmReturnErrCode::ENABLE_ADMIN_FAILED ||
204 code == EdmReturnErrCode::DISABLE_ADMIN_FAILED) {
205 resultReceiver_.append("errorCode: " + std::to_string(code));
206 return code;
207 }
208 if (isEnable) {
209 resultReceiver_.append(HELP_MSG_ENABLE_ADMIN);
210 } else {
211 resultReceiver_.append(HELP_MSG_DISABLE_ADMIN);
212 }
213 if (code == ERR_EDM_TOOLS_COMMAND_HELP) {
214 return ERR_OK;
215 }
216 return code;
217 }
218
ConvertStringToAdminType(std::string optarg,AdminType & adminType)219 ErrCode EdmCommand::ConvertStringToAdminType(std::string optarg, AdminType &adminType)
220 {
221 ErrCode ret = ERR_OK;
222 if (optarg == ADMIN_TYPE_ENT_STRING) {
223 adminType = AdminType::ENT;
224 } else if (optarg == ADMIN_TYPE_BYOD_STRING) {
225 adminType = AdminType::BYOD;
226 } else {
227 adminType = AdminType::UNKNOWN;
228 ret = ERR_EDM_TOOLS_COMMAND_UNKNOWN_ADMIN_TYPE;
229 }
230 return ret;
231 }
232 } // namespace EDM
233 } // namespace OHOS
234