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