Gateway::cliConfigure()   F
last analyzed

Complexity

Conditions 14
Paths 432

Size

Total Lines 60
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 210

Importance

Changes 0
Metric Value
eloc 49
dl 0
loc 60
ccs 0
cts 48
cp 0
rs 2.8887
c 0
b 0
f 0
cc 14
nc 432
nop 2
crap 210

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