Passed
Push — master ( c233ac...ceefe0 )
by Joas
14:23 queued 13s
created

ResetPassword   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 63
dl 0
loc 107
rs 10
c 0
b 0
f 0
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A configure() 0 14 1
B execute() 0 67 11
A completeArgumentValues() 0 5 2
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Andreas Fischer <[email protected]>
6
 * @author Christopher Schäpers <[email protected]>
7
 * @author Clark Tomlinson <[email protected]>
8
 * @author Joas Schilling <[email protected]>
9
 * @author Laurens Post <[email protected]>
10
 * @author Roeland Jago Douma <[email protected]>
11
 * @author Sujith H <[email protected]>
12
 *
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
namespace OC\Core\Command\User;
29
30
use OC\Core\Command\Base;
31
use OCP\IUser;
32
use OCP\IUserManager;
33
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
34
use Symfony\Component\Console\Helper\QuestionHelper;
35
use Symfony\Component\Console\Input\InputArgument;
36
use Symfony\Component\Console\Input\InputInterface;
37
use Symfony\Component\Console\Input\InputOption;
38
use Symfony\Component\Console\Output\OutputInterface;
39
use Symfony\Component\Console\Question\ConfirmationQuestion;
40
use Symfony\Component\Console\Question\Question;
41
42
class ResetPassword extends Base {
43
44
	/** @var IUserManager */
45
	protected $userManager;
46
47
	public function __construct(IUserManager $userManager) {
48
		$this->userManager = $userManager;
49
		parent::__construct();
50
	}
51
52
	protected function configure() {
53
		$this
54
			->setName('user:resetpassword')
55
			->setDescription('Resets the password of the named user')
56
			->addArgument(
57
				'user',
58
				InputArgument::REQUIRED,
59
				'Username to reset password'
60
			)
61
			->addOption(
62
				'password-from-env',
63
				null,
64
				InputOption::VALUE_NONE,
65
				'read password from environment variable OC_PASS'
66
			)
67
		;
68
	}
69
70
	protected function execute(InputInterface $input, OutputInterface $output): int {
71
		$username = $input->getArgument('user');
72
73
		$user = $this->userManager->get($username);
74
		if (is_null($user)) {
75
			$output->writeln('<error>User does not exist</error>');
76
			return 1;
77
		}
78
79
		if ($input->getOption('password-from-env')) {
80
			$password = getenv('OC_PASS');
81
			if (!$password) {
82
				$output->writeln('<error>--password-from-env given, but OC_PASS is empty!</error>');
83
				return 1;
84
			}
85
		} elseif ($input->isInteractive()) {
86
			/** @var QuestionHelper $helper */
87
			$helper = $this->getHelper('question');
88
89
			if (\OCP\App::isEnabled('encryption')) {
90
				$output->writeln(
91
					'<error>Warning: Resetting the password when using encryption will result in data loss!</error>'
92
				);
93
94
				$question = new ConfirmationQuestion('Do you want to continue?');
95
				if (!$helper->ask($input, $output, $question)) {
96
					return 1;
97
				}
98
			}
99
100
			$question = new Question('Enter a new password: ');
101
			$question->setHidden(true);
102
			$password = $helper->ask($input, $output, $question);
103
104
			if ($password === null) {
105
				$output->writeln("<error>Password cannot be empty!</error>");
106
				return 1;
107
			}
108
109
			$question = new Question('Confirm the new password: ');
110
			$question->setHidden(true);
111
			$confirm = $helper->ask($input, $output, $question);
112
113
			if ($password !== $confirm) {
114
				$output->writeln("<error>Passwords did not match!</error>");
115
				return 1;
116
			}
117
		} else {
118
			$output->writeln("<error>Interactive input or --password-from-env is needed for entering a new password!</error>");
119
			return 1;
120
		}
121
122
123
		try {
124
			$success = $user->setPassword($password);
125
		} catch (\Exception $e) {
126
			$output->writeln('<error>' . $e->getMessage() . '</error>');
127
			return 1;
128
		}
129
130
		if ($success) {
131
			$output->writeln("<info>Successfully reset password for " . $username . "</info>");
132
		} else {
133
			$output->writeln("<error>Error while resetting password!</error>");
134
			return 1;
135
		}
136
		return 0;
137
	}
138
139
	/**
140
	 * @param string $argumentName
141
	 * @param CompletionContext $context
142
	 * @return string[]
143
	 */
144
	public function completeArgumentValues($argumentName, CompletionContext $context) {
145
		if ($argumentName === 'user') {
146
			return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->search($context->getCurrentWord()));
147
		}
148
		return [];
149
	}
150
}
151