Completed
Push — master ( 8024bc...f8f0d2 )
by Vitor
14s
created

Client::getSessionDirectory()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 21
ccs 0
cts 15
cp 0
rs 9.7666
cc 3
nc 4
nop 0
crap 12
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * SPDX-FileCopyrightText: 2024 Christoph Wurst <[email protected]>
7
 * SPDX-License-Identifier: AGPL-3.0-or-later
8
 */
9
10
namespace OCA\TwoFactorGateway\Provider\Channel\Telegram\Provider\Drivers;
11
12
use OCA\TwoFactorGateway\AppInfo\Application;
13
use OCA\TwoFactorGateway\Exception\MessageTransmissionException;
14
use OCA\TwoFactorGateway\Provider\Channel\Telegram\Provider\AProvider;
15
use OCA\TwoFactorGateway\Provider\FieldDefinition;
16
use OCA\TwoFactorGateway\Provider\Settings;
17
use OCP\Files\IAppData;
18
use OCP\Files\NotFoundException;
19
use OCP\IConfig;
20
use OCP\IL10N;
21
use Psr\Log\LoggerInterface;
22
use Symfony\Component\Console\Helper\QuestionHelper;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Output\OutputInterface;
25
use Symfony\Component\Console\Question\Question;
26
27
/**
28
 * @method string getBotToken()
29
 * @method static setBotToken(string $botToken)
30
 * @method string getApiId()
31
 * @method static setApiId(string $apiId)
32
 * @method string getApiHash()
33
 * @method static setApiHash(string $apiHash)
34
 */
35
class Client extends AProvider {
36 1
	public function __construct(
37
		private LoggerInterface $logger,
38
		private IL10N $l10n,
39
		private IAppData $appData,
40
		private IConfig $config,
41
	) {
42 1
	}
43
44 1
	public function createSettings() {
45 1
		return new Settings(
46 1
			id: 'telegram_client',
47 1
			name: 'Telegram Client API',
48 1
			allowMarkdown: true,
49 1
			instructions: <<<HTML
50
				<p>Enter your full phone number including country code (e.g. +491751234567) as identifier or your Telegram user name preceded by an `@` (e.g. `@myusername`).</p>
51 1
				HTML,
52 1
			fields: [
53 1
				new FieldDefinition(
54 1
					field: 'api_id',
55 1
					prompt: 'Please enter your Telegram api_id (get one at https://my.telegram.org/apps):',
56 1
				),
57 1
				new FieldDefinition(
58 1
					field: 'api_hash',
59 1
					prompt: 'Please enter your Telegram api_hash (get one at https://my.telegram.org/apps):',
60 1
				),
61 1
			]
62 1
		);
63
	}
64
65
	#[\Override]
66
	public function send(string $identifier, string $message, array $extra = []): void {
67
		$this->logger->debug("sending telegram message to $identifier, message: $message");
68
69
		$sessionFile = $this->getSessionDirectory();
70
71
		putenv('TELEGRAM_API_ID=' . $this->getApiId());
72
		putenv('TELEGRAM_API_HASH=' . $this->getApiHash());
73
74
		$path = realpath(__DIR__ . '/ClientCli/Cli.php');
75
		$cmd = 'php ' . escapeshellarg($path) . ' '
76
			. 'telegram:send-message '
77
			. '--session-directory ' . escapeshellarg($sessionFile)
78
			. ' --to ' . escapeshellarg($identifier)
79
			. ' --message ' . escapeshellarg($message);
80
81
		exec($cmd, $output, $returnVar);
82
83
		if ($returnVar !== 0) {
84
			$this->logger->error('Error sending Telegram message', ['output' => $output, 'returnVar' => $returnVar]);
85
			throw new MessageTransmissionException();
86
		}
87
88
		$this->logger->debug("telegram message to chat $identifier sent");
89
	}
90
91
	#[\Override]
92
	public function cliConfigure(InputInterface $input, OutputInterface $output): int {
93
		if (PHP_VERSION_ID < 80200) {
94
			$output->writeln('The Telegram Client API provider requires PHP 8.2 or higher.');
95
			return 1;
96
		}
97
98
		$telegramApiQuestion = new Question('Please enter your api_id (get one at https://my.telegram.org/apps): ');
99
		$helper = new QuestionHelper();
100
		$apiId = $helper->ask($input, $output, $telegramApiQuestion);
101
		$apiHashQuestion = new Question('Please enter your api_hash (get one at https://my.telegram.org/apps): ');
102
		$apiHash = $helper->ask($input, $output, $apiHashQuestion);
103
104
		$this->setApiId($apiId);
105
		$this->setApiHash($apiHash);
106
107
		putenv('TELEGRAM_API_ID=' . $apiId);
108
		putenv('TELEGRAM_API_HASH=' . $apiHash);
109
110
		$sessionFile = $this->getSessionDirectory();
111
112
		$path = realpath(__DIR__ . '/ClientCli/Cli.php');
113
		$cmd = 'php ' . escapeshellarg($path) . ' '
114
			. 'telegram:login '
115
			. '--session-directory ' . escapeshellarg($sessionFile);
116
117
		// This is only to create the client session files.
118
		// The login will be made afterwards.
119
		exec($cmd);
120
121
		$user = posix_getpwuid(posix_getuid());
122
123
		$output->writeln('<info>Run the following command to start the Telegram login process:</info>');
124
		$output->writeln('');
125
		$output->writeln("<comment>$cmd</comment>");
126
		$output->writeln('');
127
		$output->writeln('Make sure that the user to run the command is the same as the web server user: <info>' . $user['name'] . '</info>.');
128
		$output->writeln('');
129
		$output->writeln('Follow the instructions in the command output.');
130
		return 0;
131
	}
132
133
	private function getSessionDirectory(): string {
134
135
		try {
136
			$folder = $this->appData->newFolder('session.madeline');
137
		} catch (NotFoundException) {
138
			$folder = $this->appData->getFolder('session.madeline');
139
		}
140
141
		$instanceId = $this->config->getSystemValueString('instanceid');
142
		$appDataFolder = 'appdata_' . $instanceId;
143
		$dataDirectory = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
144
		$fullPath = $dataDirectory . '/' . $appDataFolder . '/' . Application::APP_ID . '/session.madeline';
145
146
		if (is_dir($fullPath) === false) {
147
			$reflection = new \ReflectionClass($folder);
148
			$reflectionProperty = $reflection->getProperty('folder');
149
			$reflectionProperty->setAccessible(true);
150
			$folder = $reflectionProperty->getValue($folder);
151
			$fullPath = $folder->getInternalPath();
152
		}
153
		return $fullPath;
154
	}
155
}
156