Passed
Pull Request — master (#640)
by Vitor
03:36
created

Gateway::cliConfigure()   C

Complexity

Conditions 13
Paths 216

Size

Total Lines 57
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 47
dl 0
loc 57
rs 5.5833
c 0
b 0
f 0
cc 13
nc 216
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * SPDX-FileCopyrightText: 2024 Rainer Dohmen <[email protected]>
7
 * SPDX-License-Identifier: AGPL-3.0-or-later
8
 */
9
10
namespace OCA\TwoFactorGateway\Provider\Channel\XMPP;
11
12
use OCA\TwoFactorGateway\Exception\MessageTransmissionException;
13
use OCA\TwoFactorGateway\Provider\Gateway\AGateway;
14
use OCP\IAppConfig;
15
use OCP\IUser;
16
use Psr\Log\LoggerInterface;
17
use Symfony\Component\Console\Helper\QuestionHelper;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Question\Question;
21
22
/**
23
 * @method string getSender()
24
 * @method static setSender(string $sender)
25
 * @method string getPassword()
26
 * @method static setPassword(string $password)
27
 * @method string getServer()
28
 * @method static setServer(string $server)
29
 * @method string getUsername()
30
 * @method static setUsername(string $username)
31
 * @method string getMethod()
32
 * @method static setMethod(string $method)
33
 */
34
class Gateway extends AGateway {
35
	public const SCHEMA = [
36
		'name' => 'XMPP',
37
		'instructions' => <<<HTML
38
			<p>In order to receive authentication codes via XMPP, your XMPP Server must support http requests (ask your admin).</p>
39
			<p>Enter your JID (XMPP address) to receive your verification code below.</p>
40
			HTML,
41
		'fields' => [
42
			['field' => 'sender',   'prompt' => 'Please enter your sender XMPP-JID:'],
43
			['field' => 'password', 'prompt' => 'Please enter your sender XMPP password:'],
44
			['field' => 'server',   'prompt' => 'Please enter full path to access REST/HTTP API:'],
45
			['field' => 'username'],
46
			['field' => 'method',   'prompt' => 'Please enter 1 or 2 for XMPP sending option:'],
47
		],
48
	];
49
50
	public function __construct(
51
		public IAppConfig $appConfig,
52
		private LoggerInterface $logger,
53
	) {
54
		parent::__construct($appConfig);
55
	}
56
57
	#[\Override]
58
	public function send(IUser $user, string $identifier, string $message, array $extra = []): void {
59
		$this->logger->debug("sending xmpp message to $identifier, message: $message");
60
61
		$sender = $this->getSender();
62
		$password = $this->getPassword();
63
		$server = $this->getServer();
64
		$method = $this->getMethod();
65
		$user = $this->getUsername();
66
		$url = $server . $identifier;
67
68
		if ($method === '1') {
69
			$from = $user;
70
		}
71
		if ($method === '2') {
72
			$from = $sender;
73
		}
74
		$this->logger->debug("URL: $url, sender: $sender, method: $method");
75
76
		try {
77
			$ch = curl_init();
78
			curl_setopt($ch, CURLOPT_URL, $url);
79
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
80
			curl_setopt($ch, CURLOPT_POST, 1);
81
			curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
82
			curl_setopt($ch, CURLOPT_USERPWD, $from . ':' . $password);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $from does not seem to be defined for all execution paths leading up to this point.
Loading history...
83
			curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/plain']);
84
			$result = curl_exec($ch);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
85
			curl_close($ch);
86
			$this->logger->debug("XMPP message to $identifier sent");
87
		} catch (\Exception) {
88
			throw new MessageTransmissionException();
89
		}
90
	}
91
92
	#[\Override]
93
	public function cliConfigure(InputInterface $input, OutputInterface $output): int {
94
		$helper = new QuestionHelper();
95
		$fields = self::SCHEMA['fields'];
96
		$fields = array_combine(array_column($fields, 'field'), $fields);
97
		$sender = '';
98
		while (empty($sender) or substr_count($sender, '@') !== 1) {
99
			$senderQuestion = new Question($fields['sender']['prompt'] . ' ');
100
			$sender = $helper->ask($input, $output, $senderQuestion);
101
			if (empty($sender)) {
102
				$output->writeln('XMPP-JID must not be empty!');
103
			} elseif (substr_count($sender, '@') !== 1) {
104
				$output->writeln('XMPP-JID not valid!');
105
			} else {
106
				$username = explode('@', $sender)[0];
107
			}
108
		}
109
		$output->writeln("Using $sender as XMPP-JID.\nUsing $username as username.");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $username does not seem to be defined for all execution paths leading up to this point.
Loading history...
110
		$password = '';
111
		while (empty($password)) {
112
			$passwordQuestion = new Question($fields['password']['prompt'] . ' ');
113
			$password = $helper->ask($input, $output, $passwordQuestion);
114
			if (empty($password)) {
115
				$output->writeln('Password must not be empty!');
116
			}
117
		}
118
		$output->writeln('Password accepted.');
119
		$server = '';
120
		while (empty($server)) {
121
			$serverQuestion = new Question($fields['server']['prompt'] . ' ');
122
			$server = $helper->ask($input, $output, $serverQuestion);
123
			if (empty($server)) {
124
				$output->writeln('API path must not be empty!');
125
			}
126
		}
127
		$output->writeln("Using $server as full URL to access REST/HTTP API.");
128
		$method = 0;
129
		while (intval($method) < 1 or intval($method) > 2) {
130
			echo $fields['method']['prompt'] . PHP_EOL;
131
			echo "(1) prosody with mod_rest\n";
132
			echo "(2) prosody with mod_post_msg\n";
133
			$methodQuestion = new Question('Your choice: ');
134
			$method = $helper->ask($input, $output, $methodQuestion);
135
		}
136
		if ($method === '1') {
137
			$output->writeln('Using prosody with mod_rest as XMPP sending option.');
138
		} elseif ($method === '2') {
139
			$output->writeln('Using prosody with mod_post_msg as XMPP sending option.');
140
		}
141
		$output->writeln('XMPP Admin Configuration finished.');
142
143
		$this->setSender($sender);
144
		$this->setPassword($password);
145
		$this->setServer($server);
146
		$this->setUsername($username);
147
		$this->setMethod($method);
148
		return 0;
149
	}
150
}
151