1 /*
2 * Copyright (c) 2021-2023 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 #include "account_command.h"
16 #include <fstream>
17 #include <getopt.h>
18 #include <sys/stat.h>
19 #include "account_log_wrapper.h"
20 #include "singleton.h"
21 #include "string_ex.h"
22
23 using namespace OHOS::AAFwk;
24
25 namespace OHOS {
26 namespace AccountSA {
27 namespace {
28 const std::string SHORT_OPTIONS = "hn:t:i:s:l:c:ea";
29 const struct option LONG_OPTIONS[] = {
30 {"help", no_argument, nullptr, 'h'},
31 {"name", required_argument, nullptr, 'n'},
32 {"type", required_argument, nullptr, 't'},
33 {"id", required_argument, nullptr, 'i'},
34 {"shortName", optional_argument, nullptr, 's'},
35 {"disallowedlist", optional_argument, nullptr, 'l'},
36 {"constraint", required_argument, nullptr, 'c'},
37 {"enable", no_argument, nullptr, 'e'},
38 {"all", no_argument, nullptr, 'a'},
39 {nullptr, no_argument, nullptr, no_argument}
40 };
41
42 static const std::string DEACTIVATE_COMMAND = "deactivate";
43 static const std::string DELETE_COMMAND = "delete";
44 static const std::string SWITCH_COMMAND = "switch";
45 static const std::string DUMP_COMMAND = "dump";
46 static const std::string SET_COMMAND = "set";
47 static const std::string CREATE_COMMAND = "create";
48 static constexpr int MIN_ARGUMENT_NUMBER = 2;
49 static constexpr int MAX_ARGUMENT_NUMBER = 4096;
50 } // namespace
51
AccountCommand(int argc,char * argv[])52 AccountCommand::AccountCommand(int argc, char *argv[])
53 {
54 ACCOUNT_LOGD("enter");
55 opterr = 0;
56 argc_ = argc;
57 argv_ = argv;
58 name_ = TOOL_NAME;
59
60 if (argc < MIN_ARGUMENT_NUMBER || argc > MAX_ARGUMENT_NUMBER) {
61 cmd_ = "help";
62 return;
63 }
64 cmd_ = argv[1];
65 for (int i = MIN_ARGUMENT_NUMBER; i < argc; i++) {
66 argList_.push_back(argv[i]);
67 }
68 for (int i = 0; i < argc_; i++) {
69 ACCOUNT_LOGD("argv_[%{public}d]: %{public}s", i, argv_[i]);
70 }
71 }
72
CreateCommandMap()73 void AccountCommand::CreateCommandMap()
74 {
75 commandMap_ = {
76 {"help", [this] { return this->RunAsHelpCommand(); }},
77 {"create", [this] { return this->RunAsCreateCommand(); }},
78 {"delete", [this] { return this->RunAsDeleteCommand(); }},
79 {"dump", [this] { return this->RunAsDumpCommand(); }},
80 {"set", [this] { return this->RunAsSetCommand(); }},
81 {"switch", [this] { return this->RunAsSwitchCommand(); }},
82 {"deactivate", [this] { return this->RunAsDeactivateCommand(); }},
83 };
84 }
85
GetCommandErrorMsg() const86 std::string AccountCommand::GetCommandErrorMsg() const
87 {
88 std::string commandErrorMsg =
89 name_ + ": '" + cmd_ + "' is not a valid " + name_ + " command. See '" + name_ + " help'.\n";
90
91 return commandErrorMsg;
92 }
93
GetUnknownOptionMsg(std::string & unknownOption) const94 std::string AccountCommand::GetUnknownOptionMsg(std::string& unknownOption) const
95 {
96 std::string result = "";
97
98 if (optind < 0 || optind > argc_) {
99 return result;
100 }
101
102 result.append("fail: unknown option");
103 result.append(".\n");
104
105 return result;
106 }
107
OnCommand()108 void AccountCommand::OnCommand()
109 {
110 auto respond = commandMap_[cmd_];
111 if (respond == nullptr) {
112 resultReceiver_.append(GetCommandErrorMsg());
113 respond = commandMap_["help"];
114 }
115
116 respond();
117 }
118
ExecCommand()119 std::string AccountCommand::ExecCommand()
120 {
121 CreateCommandMap();
122 OnCommand();
123 return resultReceiver_;
124 }
125
RunAsHelpCommand(void)126 ErrCode AccountCommand::RunAsHelpCommand(void)
127 {
128 ACCOUNT_LOGD("enter");
129 resultReceiver_.append(HELP_MSG);
130 return ERR_OK;
131 }
132
ParseCreateCommandOpt(std::string & name,std::string & shortName,OsAccountType & osAccountType,std::vector<std::string> & disallowedList)133 ErrCode AccountCommand::ParseCreateCommandOpt(std::string &name,
134 std::string &shortName, OsAccountType &osAccountType, std::vector<std::string> &disallowedList)
135 {
136 int counter = 0;
137 ErrCode result = ERR_OK;
138 while (true) {
139 counter++;
140
141 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
142 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
143
144 if (option == -1) {
145 if (counter == 1) {
146 result = RunCommandError(CREATE_COMMAND);
147 }
148 break;
149 }
150
151 if (option == '?') {
152 result = RunAsCreateCommandMissingOptionArgument();
153 break;
154 }
155
156 result = RunAsCreateCommandExistentOptionArgument(option, name, shortName, osAccountType, disallowedList);
157 }
158 return result;
159 }
160
RunAsCreateCommand(void)161 ErrCode AccountCommand::RunAsCreateCommand(void)
162 {
163 ACCOUNT_LOGD("enter");
164 ErrCode result = ERR_OK;
165 std::string name = "";
166 std::string shortName = "";
167 OsAccountType osAccountType = END;
168 CreateOsAccountOptions options;
169 result = ParseCreateCommandOpt(name, shortName, osAccountType, options.disallowedHapList);
170 if (result == ERR_OK) {
171 if (name.size() == 0 || osAccountType == END) {
172 ACCOUNT_LOGD("'acm create' without enough options");
173
174 if (name.size() == 0) {
175 resultReceiver_.append(HELP_MSG_NO_NAME_OPTION + "\n");
176 }
177
178 if (osAccountType == END) {
179 resultReceiver_.append(HELP_MSG_NO_TYPE_OPTION + "\n");
180 }
181
182 result = ERR_INVALID_VALUE;
183 }
184 }
185
186 if (result != ERR_OK && result != ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED) {
187 resultReceiver_.append(HELP_MSG_CREATE);
188 } else {
189 /* create */
190
191 // make os account info
192 OsAccountInfo osAccountInfo;
193 if (shortName.empty()) {
194 shortName = name;
195 }
196 // create an os account
197 result = OsAccount::GetInstance().CreateOsAccount(name, shortName, osAccountType, osAccountInfo, options);
198 switch (result) {
199 case ERR_OK:
200 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_OK + "\n";
201 break;
202 case ERR_OSACCOUNT_SERVICE_MANAGER_NOT_ENABLE_MULTI_ERROR:
203 resultReceiver_ = "create failed, reason: multiple-os-account feature not enabled\n";
204 break;
205 default:
206 resultReceiver_ = STRING_CREATE_OS_ACCOUNT_NG + "\n";
207 }
208 }
209
210 ACCOUNT_LOGD("result = %{public}d, name = %{public}s, type = %{public}d", result, name.c_str(), osAccountType);
211 return result;
212 }
213
RunAsDeleteCommand(void)214 ErrCode AccountCommand::RunAsDeleteCommand(void)
215 {
216 ErrCode result = ERR_OK;
217 int id = -1;
218
219 ParseCommandOpt(DELETE_COMMAND, result, id);
220
221 if (result != ERR_OK) {
222 resultReceiver_.append(HELP_MSG_DELETE);
223 } else {
224 /* delete */
225
226 // delete an os account
227 result = OsAccount::GetInstance().RemoveOsAccount(id);
228 if (result == ERR_OK) {
229 resultReceiver_ = STRING_DELETE_OS_ACCOUNT_OK + "\n";
230 } else {
231 resultReceiver_ = STRING_DELETE_OS_ACCOUNT_NG + "\n";
232 }
233 }
234
235 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
236 return result;
237 }
238
RunAsDumpCommand(void)239 ErrCode AccountCommand::RunAsDumpCommand(void)
240 {
241 ErrCode result = ERR_OK;
242 int id = -1;
243
244 ParseCommandOpt(DUMP_COMMAND, result, id);
245
246 if (result != ERR_OK) {
247 resultReceiver_.append(HELP_MSG_DUMP);
248 } else {
249 /* dump */
250
251 // dump state
252 std::vector<std::string> state;
253 result = OsAccount::GetInstance().DumpState(id, state);
254 if (result == ERR_OK) {
255 for (auto info : state) {
256 resultReceiver_ += info + "\n";
257 }
258 } else {
259 resultReceiver_ = STRING_DUMP_OS_ACCOUNT_NG + "\n";
260 }
261 }
262
263 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
264 return result;
265 }
266
RunCommand(int & counter,ErrCode & result,bool & enable,int & id,std::vector<std::string> & constraints)267 void AccountCommand::RunCommand(
268 int &counter, ErrCode &result, bool &enable, int &id, std::vector<std::string> &constraints)
269 {
270 while (true) {
271 counter++;
272
273 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
274 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
275
276 if (option == -1) {
277 if (counter == 1) {
278 result = RunCommandError(SET_COMMAND);
279 }
280 break;
281 }
282
283 if (option == '?') {
284 result = RunAsSetCommandMissingOptionArgument();
285 break;
286 }
287
288 result = RunAsSetCommandExistentOptionArgument(option, id, constraints, enable);
289 }
290 }
291
RunAsSetCommand(void)292 ErrCode AccountCommand::RunAsSetCommand(void)
293 {
294 ErrCode result = ERR_OK;
295 int counter = 0;
296 int id = -1;
297 std::vector<std::string> constraints;
298 bool enable = false;
299
300 RunCommand(counter, result, enable, id, constraints);
301
302 if (result == ERR_OK) {
303 if (id == -1 || constraints.size() == 0) {
304 ACCOUNT_LOGD("'acm set' without enough options");
305
306 if (id == -1) {
307 resultReceiver_.append(HELP_MSG_NO_ID_OPTION + "\n");
308 }
309
310 if (constraints.size() == 0) {
311 resultReceiver_.append(HELP_MSG_NO_CONSTRAINTS_OPTION + "\n");
312 }
313
314 result = ERR_INVALID_VALUE;
315 }
316 }
317
318 if (result != ERR_OK) {
319 resultReceiver_.append(HELP_MSG_SET);
320 } else {
321 /* set */
322
323 // set os account constraints
324 result = OsAccount::GetInstance().SetOsAccountConstraints(id, constraints, enable);
325 if (result == ERR_OK) {
326 resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_OK + "\n";
327 } else {
328 resultReceiver_ = STRING_SET_OS_ACCOUNT_CONSTRAINTS_NG + "\n";
329 }
330 }
331
332 ACCOUNT_LOGD("result = %{public}d, id = %{public}d, enable = %{public}d", result, id, enable);
333 for (auto constraint : constraints) {
334 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
335 }
336
337 return result;
338 }
339
ParseCommandOpt(const std::string & command,ErrCode & result,int & id)340 void AccountCommand::ParseCommandOpt(const std::string &command, ErrCode &result, int &id)
341 {
342 int counter = 0;
343 while (true) {
344 counter++;
345
346 int option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr);
347 ACCOUNT_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind);
348
349 if (option == -1) {
350 if (counter == 1) {
351 result = RunCommandError(command);
352 }
353 break;
354 }
355
356 if (option == '?') {
357 result = RunAsCommonCommandMissingOptionArgument(command);
358 break;
359 }
360
361 result = RunAsCommonCommandExistentOptionArgument(option, id);
362 }
363 }
364
RunAsSwitchCommand(void)365 ErrCode AccountCommand::RunAsSwitchCommand(void)
366 {
367 ErrCode result = ERR_OK;
368 int id = -1;
369 ParseCommandOpt(SWITCH_COMMAND, result, id);
370
371 if (result != ERR_OK) {
372 resultReceiver_.append(HELP_MSG_SWITCH);
373 } else {
374 /* switch */
375
376 // switch an os account
377 result = OsAccount::GetInstance().ActivateOsAccount(id);
378 if (result == ERR_OK) {
379 resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_OK + "\n";
380 } else {
381 resultReceiver_ = STRING_SWITCH_OS_ACCOUNT_NG + "\n";
382 }
383 }
384
385 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
386 return result;
387 }
388
RunAsDeactivateCommand(void)389 ErrCode AccountCommand::RunAsDeactivateCommand(void)
390 {
391 ErrCode result = ERR_OK;
392 int id = -1;
393
394 ParseCommandOpt(DEACTIVATE_COMMAND, result, id);
395
396 if (result != ERR_OK) {
397 resultReceiver_.append(HELP_MSG_DEACTIVATE);
398 } else if (id != -1) {
399 /* deactivate */
400
401 // deactivate an os account
402 result = OsAccount::GetInstance().DeactivateOsAccount(id);
403 if (result == ERR_OK) {
404 resultReceiver_ = STRING_DEACTIVATE_OS_ACCOUNT_OK + "\n";
405 } else {
406 resultReceiver_ = STRING_DEACTIVATE_OS_ACCOUNT_NG + "\n";
407 }
408 } else {
409 result = OsAccount::GetInstance().DeactivateAllOsAccounts();
410 if (result == ERR_OK) {
411 resultReceiver_ = STRING_DEACTIVATE_ALL_OS_ACCOUNTS_OK + "\n";
412 } else {
413 resultReceiver_ = STRING_DEACTIVATE_ALL_OS_ACCOUNTS_NG + "\n";
414 }
415 }
416
417 ACCOUNT_LOGD("result = %{public}d, id = %{public}d", result, id);
418
419 return result;
420 }
421
RunAsCreateCommandMissingOptionArgument(void)422 ErrCode AccountCommand::RunAsCreateCommandMissingOptionArgument(void)
423 {
424 ErrCode result = ERR_OK;
425
426 switch (optopt) {
427 case 'n': {
428 // 'acm create -n <name>' with no argument: acm create -n
429 // 'acm create --name <name>' with no argument: acm create --name
430 ACCOUNT_LOGD("'acm create -n' with no argument.");
431
432 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
433 result = ERR_INVALID_VALUE;
434 break;
435 }
436 case 't': {
437 // 'acm create -t <type>' with no argument: acm create -t
438 // 'acm create --type <type>' with no argument: acm create --type
439 ACCOUNT_LOGD("'acm create -t' with no argument.");
440
441 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
442
443 result = ERR_INVALID_VALUE;
444 break;
445 }
446 default: {
447 // 'acm create' with an unknown option: acm create -x
448 // 'acm create' with an unknown option: acm create -xxx
449 std::string unknownOption = "";
450 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
451
452 ACCOUNT_LOGD("'acm create' with an unknown option.");
453
454 resultReceiver_.append(unknownOptionMsg);
455 result = ERR_INVALID_VALUE;
456 break;
457 }
458 }
459
460 ACCOUNT_LOGD("end, result = %{public}d", result);
461 return result;
462 }
463
RunAsCreateCommandExistentOptionArgument(const int & option,std::string & name,std::string & shortName,OsAccountType & type,std::vector<std::string> & disallowedList)464 ErrCode AccountCommand::RunAsCreateCommandExistentOptionArgument(const int &option, std::string &name,
465 std::string &shortName, OsAccountType &type, std::vector<std::string> &disallowedList)
466 {
467 ErrCode result = ERR_OK;
468
469 switch (option) {
470 case 'h': {
471 // 'acm create -h'
472 // 'acm create --help'
473 result = ERR_INVALID_VALUE;
474 break;
475 }
476 case 'n': {
477 // 'acm create -n <name>'
478 // 'acm create --name <name>'
479 name = optarg;
480 break;
481 }
482 case 't': {
483 // 'acm create -t <type>'
484 // 'acm create --type <type>'
485 result = AnalyzeTypeArgument(type);
486 break;
487 }
488 case 's': {
489 // 'acm create -s <shortName>'
490 // 'acm create --shortName <shortName>'
491 shortName = optarg;
492 break;
493 }
494 case 'l': {
495 // 'acm create -l <disallowedlist>'
496 // 'acm create --disallowedlist <disallowedlist>'
497 result = AnalyzeDisallowedListArgument(disallowedList);
498 break;
499 }
500 default: {
501 break;
502 }
503 }
504
505 ACCOUNT_LOGD("end, result = %{public}d", result);
506 return result;
507 }
508
RunAsCommonCommandMissingOptionArgument(const std::string & command)509 ErrCode AccountCommand::RunAsCommonCommandMissingOptionArgument(const std::string &command)
510 {
511 ErrCode result = ERR_OK;
512
513 switch (optopt) {
514 case 'i': {
515 // 'acm command -i <id>' with no argument: acm command -i
516 // 'acm command --id <id>' with no argument: acm command --id
517 ACCOUNT_LOGD("'acm %{public}s -i' with no argument.", command.c_str());
518
519 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
520 result = ERR_INVALID_VALUE;
521 break;
522 }
523 default: {
524 // 'acm delete' with an unknown option: acm delete -x
525 // 'acm delete' with an unknown option: acm delete -xxx
526 std::string unknownOption = "";
527 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
528
529 ACCOUNT_LOGD("'acm %{public}s' with an unknown option.", command.c_str());
530
531 resultReceiver_.append(unknownOptionMsg);
532 result = ERR_INVALID_VALUE;
533 break;
534 }
535 }
536 ACCOUNT_LOGD("end, result = %{public}d", result);
537 return result;
538 }
539
RunCommandError(const std::string & command)540 ErrCode AccountCommand::RunCommandError(const std::string &command)
541 {
542 ErrCode result = ERR_OK;
543
544 if (optind < 0 || optind >= argc_) {
545 ACCOUNT_LOGD("optind %{public}d invalid", optind);
546 return ERR_INVALID_VALUE;
547 }
548
549 // When scanning the first argument
550 if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
551 // 'acm command' with no option: acm command
552 // 'acm command' with a wrong argument: acm command xxx
553 ACCOUNT_LOGD("'acm %{public}s' with no option.", command.c_str());
554
555 resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
556 result = ERR_INVALID_VALUE;
557 }
558
559 ACCOUNT_LOGD("end, result = %{public}d", result);
560
561 return result;
562 }
563
RunAsSetCommandMissingOptionArgument(void)564 ErrCode AccountCommand::RunAsSetCommandMissingOptionArgument(void)
565 {
566 ErrCode result = ERR_OK;
567
568 switch (optopt) {
569 case 'i': {
570 // 'acm set -i <id>' with no argument: acm set -i
571 // 'acm set --id <id>' with no argument: acm set --id
572 ACCOUNT_LOGD("'acm set -i' with no argument.");
573
574 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
575 result = ERR_INVALID_VALUE;
576 break;
577 }
578 case 'c': {
579 // 'acm set -c <constraints>' with no argument: acm set -c
580 // 'acm set --constraint <constraints>' with no argument: acm set --constraint
581 ACCOUNT_LOGD("'acm set -c' with no argument.");
582
583 resultReceiver_.append(HELP_MSG_OPTION_REQUIRES_AN_ARGUMENT + "\n");
584 result = ERR_INVALID_VALUE;
585 break;
586 }
587 default: {
588 // 'acm set' with an unknown option: acm set -x
589 // 'acm set' with an unknown option: acm set -xxx
590 std::string unknownOption = "";
591 std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption);
592
593 ACCOUNT_LOGD("'set dump' with an unknown option.");
594
595 resultReceiver_.append(unknownOptionMsg);
596 result = ERR_INVALID_VALUE;
597 break;
598 }
599 }
600 ACCOUNT_LOGD("end, result = %{public}d", result);
601 return result;
602 }
603
RunAsSetCommandExistentOptionArgument(const int & option,int & id,std::vector<std::string> & constraints,bool & enable)604 ErrCode AccountCommand::RunAsSetCommandExistentOptionArgument(
605 const int &option, int &id, std::vector<std::string> &constraints, bool &enable)
606 {
607 ErrCode result = ERR_OK;
608
609 switch (option) {
610 case 'h': {
611 // 'acm set -h'
612 // 'acm set --help'
613 result = ERR_INVALID_VALUE;
614 break;
615 }
616 case 'i': {
617 // 'acm set -i <id>'
618 // 'acm set --id <id>'
619 result = AnalyzeLocalIdArgument(id);
620 break;
621 }
622 case 'c': {
623 // 'acm set -c <constraints>'
624 // 'acm set --constraint <constraints>'
625 result = AnalyzeConstraintArgument(constraints);
626 break;
627 }
628 case 'e': {
629 // 'acm set -e'
630 // 'acm set --enable'
631 enable = true;
632 break;
633 }
634 default: {
635 break;
636 }
637 }
638
639 ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
640 return result;
641 }
642
RunAsCommonCommandExistentOptionArgument(const int & option,int & id)643 ErrCode AccountCommand::RunAsCommonCommandExistentOptionArgument(const int &option, int &id)
644 {
645 ErrCode result = ERR_OK;
646
647 switch (option) {
648 case 'h': {
649 // 'acm command -h'
650 // 'acm command --help'
651 // command includes stop, switch, deactivate, dump, delete
652 result = ERR_INVALID_VALUE;
653 break;
654 }
655 case 'i': {
656 // 'acm command -i <id>'
657 // 'acm command --id <id>
658 // command includes stop, switch, deactivate, dump, delete
659 result = AnalyzeLocalIdArgument(id);
660 break;
661 }
662 default: {
663 break;
664 }
665 }
666 ACCOUNT_LOGD("end, result = %{public}d, id = %{public}d", result, id);
667 return result;
668 }
669
AnalyzeTypeArgument(OsAccountType & type)670 ErrCode AccountCommand::AnalyzeTypeArgument(OsAccountType &type)
671 {
672 ErrCode result = ERR_OK;
673 std::string typeByUser = optarg;
674
675 if (typeByUser == "admin") {
676 type = OsAccountType::ADMIN;
677 } else if (typeByUser == "normal") {
678 type = OsAccountType::NORMAL;
679 } else if (typeByUser == "guest") {
680 type = OsAccountType::GUEST;
681 } else if (typeByUser == "private") {
682 type = OsAccountType::PRIVATE;
683 } else {
684 resultReceiver_.append(HELP_MSG_INVALID_TYPE_ARGUMENT + "\n");
685 result = ERR_INVALID_VALUE;
686 }
687
688 return result;
689 }
690
IsExistFile(const std::string & path)691 static bool IsExistFile(const std::string &path)
692 {
693 if (path.empty()) {
694 return false;
695 }
696
697 struct stat buf = {};
698 if (stat(path.c_str(), &buf) != 0) {
699 return false;
700 }
701
702 return S_ISREG(buf.st_mode);
703 }
704
GetDisallowedListByPath(const std::string & path,std::vector<std::string> & disallowedList)705 static ErrCode GetDisallowedListByPath(const std::string &path, std::vector<std::string> &disallowedList)
706 {
707 if (!IsExistFile(path)) {
708 ACCOUNT_LOGE("cannot find file, path = %{public}s", path.c_str());
709 return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
710 }
711 std::ifstream readFile;
712 readFile.open(path.c_str(), std::ios::in);
713 if (!readFile.is_open()) {
714 ACCOUNT_LOGE("cannot open file, path = %{public}s", path.c_str());
715 return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
716 }
717 std::string str;
718 while (getline(readFile, str)) {
719 ACCOUNT_LOGI("read file, str = %{public}s", str.c_str());
720 disallowedList.emplace_back(str);
721 }
722 readFile.close();
723 return ERR_OK;
724 }
725
AnalyzeDisallowedListArgument(std::vector<std::string> & disallowedList)726 ErrCode AccountCommand::AnalyzeDisallowedListArgument(std::vector<std::string> &disallowedList)
727 {
728 std::string listPath = optarg;
729 return GetDisallowedListByPath(listPath, disallowedList);
730 }
731
AnalyzeLocalIdArgument(int & id)732 ErrCode AccountCommand::AnalyzeLocalIdArgument(int &id)
733 {
734 std::string idByUser = optarg;
735 if (!StrToInt(idByUser, id)) {
736 resultReceiver_.append(HELP_MSG_INVALID_ID_ARGUMENT + "\n");
737 return ERR_INVALID_VALUE;
738 }
739
740 return ERR_OK;
741 }
742
AnalyzeConstraintArgument(std::vector<std::string> & constraints)743 ErrCode AccountCommand::AnalyzeConstraintArgument(std::vector<std::string> &constraints)
744 {
745 std::string constraintsByUser = optarg;
746 ACCOUNT_LOGD("constraintsByUser = %{public}s", constraintsByUser.c_str());
747
748 constraints.clear();
749 std::string constraint = "";
750 std::string delimiter = ",";
751 size_t last = 0;
752 size_t next = 0;
753
754 while ((next = constraintsByUser.find(delimiter, last)) != std::string::npos) {
755 constraint = constraintsByUser.substr(last, next - last);
756 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
757
758 constraints.emplace_back(constraint);
759 last = next + 1;
760 }
761 constraint = constraintsByUser.substr(last);
762 ACCOUNT_LOGD("constraint = %{public}s", constraint.c_str());
763 constraints.emplace_back(constraint);
764
765 return ERR_OK;
766 }
767 } // namespace AccountSA
768 } // namespace OHOS