1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Add-on installer/uninstaller. |
4
|
|
|
* |
5
|
|
|
* @package ThreemaGateway |
6
|
|
|
* @author rugk |
7
|
|
|
* @copyright Copyright (c) 2015-2016 rugk |
8
|
|
|
* @license MIT |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Installation and uninstallation routines for Threema Gateway. |
13
|
|
|
*/ |
14
|
|
|
class ThreemaGateway_Installer |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* At the installation this will check the XenForo version and |
18
|
|
|
* add the 2FA provider to the table. |
19
|
|
|
* |
20
|
|
|
* @param array $installedAddon |
21
|
|
|
*/ |
22
|
|
|
public static function install($installedAddon) |
23
|
|
|
{ |
24
|
|
|
/** @var array $providerInstaller An array with the models of all providers */ |
25
|
|
|
$providerInstaller = self::getProviderInstaller(); |
26
|
|
|
// check requirements of Gateway |
27
|
|
|
if (!self::meetsRequirements($error)) { |
28
|
|
|
throw new XenForo_Exception($error); |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
// Get installed add-on version |
32
|
|
|
/** @var int $oldAddonVersion internal version number of installed addon version */ |
33
|
|
|
$oldAddonVersion = is_array($installedAddon) ? $installedAddon['version_id'] : 0; |
34
|
|
|
|
35
|
|
|
// Not installed |
36
|
|
|
if ($oldAddonVersion == 0) { |
37
|
|
|
// add tfa providers to database |
38
|
|
|
foreach ($providerInstaller as $provider) { |
39
|
|
|
$provider->add(); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
// add permissions |
43
|
|
|
/** @var ThreemaGateway_Installer_Permissions $permissionsInstaller */ |
44
|
|
|
$permissionsInstaller = new ThreemaGateway_Installer_Permissions; |
45
|
|
|
// allow everything for registered users by default |
46
|
|
|
$permissionsInstaller->addForUserGroup(2, 'use', 'allow'); |
47
|
|
|
$permissionsInstaller->addForUserGroup(2, 'send', 'allow'); |
48
|
|
|
$permissionsInstaller->addForUserGroup(2, 'receive', 'allow'); |
49
|
|
|
$permissionsInstaller->addForUserGroup(2, 'fetch', 'allow'); |
50
|
|
|
$permissionsInstaller->addForUserGroup(2, 'lookup', 'allow'); |
51
|
|
|
$permissionsInstaller->addForUserGroup(2, 'tfa', 'allow'); |
52
|
|
|
|
53
|
|
|
// allow registered users some basic (uncritical) block actions |
54
|
|
|
$permissionsInstaller->addForUserGroup(2, 'blockedNotification', 'allow'); |
55
|
|
|
$permissionsInstaller->addForUserGroup(2, 'blockTfaMode', 'allow'); |
56
|
|
|
|
57
|
|
|
// allow all block actions for mods (& thus also admins) |
58
|
|
|
$permissionsInstaller->addForUserGroup(4, 'blockedNotification', 'allow'); |
59
|
|
|
$permissionsInstaller->addForUserGroup(4, 'blockTfaMode', 'allow'); |
60
|
|
|
$permissionsInstaller->addForUserGroup(4, 'blockUser', 'allow'); // not possible as mods/admins cannot be blocked, but we allow it :) |
61
|
|
|
$permissionsInstaller->addForUserGroup(4, 'blockIp', 'allow'); |
62
|
|
|
|
63
|
|
|
// create public key store |
64
|
|
|
/** @var ThreemaGateway_Installer_Keystore $keystoreInstaller */ |
65
|
|
|
$keystoreInstaller = new ThreemaGateway_Installer_Keystore; |
66
|
|
|
$keystoreInstaller->create(); |
67
|
|
|
|
68
|
|
|
// create custom user field |
69
|
|
|
/** @var XenForo_DataWriter $userFieldWriter */ |
70
|
|
|
$userFieldWriter = XenForo_DataWriter::create('XenForo_DataWriter_UserField'); |
71
|
|
|
$userFieldWriter->set('field_id', 'threemaid'); |
72
|
|
|
$userFieldWriter->set('display_group', 'contact'); |
73
|
|
|
$userFieldWriter->set('display_order', 120); |
74
|
|
|
$userFieldWriter->set('field_type', 'textbox'); |
75
|
|
|
$userFieldWriter->set('match_type', 'callback'); |
76
|
|
|
$userFieldWriter->set('match_callback_class', 'ThreemaGateway_Helper_UserField'); |
77
|
|
|
$userFieldWriter->set('match_callback_method', 'verifyThreemaId'); |
78
|
|
|
$userFieldWriter->set('max_length', 8); |
79
|
|
|
$userFieldWriter->save(); |
80
|
|
|
|
81
|
|
|
// create tables for messages |
82
|
|
|
/** @var ThreemaGateway_Installer_MessagesDb $messageDbInstaller */ |
83
|
|
|
$messageDbInstaller = new ThreemaGateway_Installer_MessagesDb; |
84
|
|
|
$messageDbInstaller->create(); |
85
|
|
|
|
86
|
|
|
// create tfa tables |
87
|
|
|
/** @var ThreemaGateway_Installer_TfaPendingConfirmMsgs $pendReqInstaller */ |
88
|
|
|
$pendReqInstaller = new ThreemaGateway_Installer_TfaPendingConfirmMsgs; |
89
|
|
|
$pendReqInstaller->create(); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
// introduced in v1.00.00 70 (stable) |
|
|
|
|
93
|
|
|
if ($oldAddonVersion < 1000070) { |
94
|
|
|
// add throttle table |
95
|
|
|
/** @var ThreemaGateway_Installer_ActionThrottle $throttleInstaller */ |
96
|
|
|
$throttleInstaller = new ThreemaGateway_Installer_ActionThrottle; |
97
|
|
|
$throttleInstaller->create(); |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* When uninstalling this deletes the unnecessary database entries/tables. |
103
|
|
|
*/ |
104
|
|
|
public static function uninstall() |
105
|
|
|
{ |
106
|
|
|
// delete throttle table |
107
|
|
|
/** @var ThreemaGateway_Installer_ActionThrottle $throttleInstaller */ |
108
|
|
|
$throttleInstaller = new ThreemaGateway_Installer_ActionThrottle; |
109
|
|
|
$throttleInstaller->destroy(); |
110
|
|
|
|
111
|
|
|
// delete tfa tables |
112
|
|
|
/** @var ThreemaGateway_Installer_TfaPendingConfirmMsgs $pendReqInstaller */ |
113
|
|
|
$pendReqInstaller = new ThreemaGateway_Installer_TfaPendingConfirmMsgs; |
114
|
|
|
$pendReqInstaller->destroy(); |
115
|
|
|
|
116
|
|
|
// remove message tables |
117
|
|
|
/** @var ThreemaGateway_Installer_MessagesDb $messageDbInstaller */ |
118
|
|
|
$messageDbInstaller = new ThreemaGateway_Installer_MessagesDb; |
119
|
|
|
$messageDbInstaller->destroy(); |
120
|
|
|
|
121
|
|
|
/** @var array $providerInstaller An array with the models of all providers */ |
122
|
|
|
$providerInstaller = self::getProviderInstaller(); |
123
|
|
|
|
124
|
|
|
// delete tfa provider from database |
125
|
|
|
foreach ($providerInstaller as $provider) { |
126
|
|
|
$provider->delete(); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
// delete keystore |
130
|
|
|
/** @var ThreemaGateway_Installer_Keystore $keystoreInstaller */ |
131
|
|
|
$keystoreInstaller = new ThreemaGateway_Installer_Keystore; |
132
|
|
|
$keystoreInstaller->destroy(); |
133
|
|
|
|
134
|
|
|
// delete permissions |
135
|
|
|
/** @var ThreemaGateway_Installer_Permissions $permissionsInstaller */ |
136
|
|
|
$permissionsInstaller = new ThreemaGateway_Installer_Permissions; |
137
|
|
|
$permissionsInstaller->deleteAll(); |
138
|
|
|
|
139
|
|
|
// delete custom user field (if it exists) |
140
|
|
|
/** @var XenForo_Model_UserField $userFieldModel */ |
141
|
|
|
$userFieldModel = XenForo_Model::create('XenForo_Model_UserField'); |
142
|
|
|
/** @var array $userFieldData fetched data from database */ |
143
|
|
|
if ($userFieldData = $userFieldModel->getUserFieldById('threemaid')) { |
144
|
|
|
/** @var XenForo_DataWriter $userFieldWriter */ |
145
|
|
|
$userFieldWriter = XenForo_DataWriter::create('XenForo_DataWriter_UserField'); |
146
|
|
|
$userFieldWriter->setExistingData($userFieldData); |
147
|
|
|
$userFieldWriter->delete(); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** @var XenForo_Options $xenOptions */ |
151
|
|
|
$xenOptions = XenForo_Application::getOptions(); |
152
|
|
|
|
153
|
|
|
try { |
154
|
|
|
//delete debug log file |
155
|
|
|
ThreemaGateway_Option_DebugModeLog::removeLog($xenOptions->threema_gateway_logreceivedmsgs); |
156
|
|
|
|
157
|
|
|
//delete private key file if possible |
158
|
|
|
ThreemaGateway_Option_PrivateKeyPath::removePrivateKey($xenOptions->threema_gateway_privatekeyfile); |
159
|
|
|
} catch (Exception $e) { |
160
|
|
|
// ignore errors as deletion operations are additional security |
161
|
|
|
// features, which may fail in an expected way, e.g. when XenForo |
162
|
|
|
// does not have write access to these files. |
163
|
|
|
} |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Returns the provider installer needed for modifying the database. |
168
|
|
|
* |
169
|
|
|
* @return array |
170
|
|
|
*/ |
171
|
|
|
protected static function getProviderInstaller() |
172
|
|
|
{ |
173
|
|
|
/** @var array $providerInstaller An array with the models of all providers */ |
174
|
|
|
$providerInstaller = []; |
175
|
|
|
|
176
|
|
|
// add provider |
177
|
|
|
$providerInstaller['conventional'] = new ThreemaGateway_Installer_TfaProvider( |
178
|
|
|
ThreemaGateway_Constants::TFA_ID_PREFIX . '_conventional', |
179
|
|
|
'ThreemaGateway_Tfa_Conventional', |
180
|
|
|
ThreemaGateway_Constants::TFA_BASE_PRIORITY - 15); |
181
|
|
|
$providerInstaller['reversed'] = new ThreemaGateway_Installer_TfaProvider( |
182
|
|
|
ThreemaGateway_Constants::TFA_ID_PREFIX . '_reversed', |
183
|
|
|
'ThreemaGateway_Tfa_Reversed', |
184
|
|
|
ThreemaGateway_Constants::TFA_BASE_PRIORITY - 10); |
185
|
|
|
$providerInstaller['fast'] = new ThreemaGateway_Installer_TfaProvider( |
186
|
|
|
ThreemaGateway_Constants::TFA_ID_PREFIX . '_fast', |
187
|
|
|
'ThreemaGateway_Tfa_Fast', |
188
|
|
|
ThreemaGateway_Constants::TFA_BASE_PRIORITY - 5); |
189
|
|
|
|
190
|
|
|
return $providerInstaller; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* At the installation this will check the XenForo version and |
195
|
|
|
* remove the 2FA provider to the table. |
196
|
|
|
* |
197
|
|
|
* @param string $error Will be filled by a human-readable error description |
198
|
|
|
* when an error occurs |
199
|
|
|
* @return bool |
200
|
|
|
*/ |
201
|
|
|
protected static function meetsRequirements(&$error) |
202
|
|
|
{ |
203
|
|
|
/** @var bool $isError whether an error is triggered */ |
204
|
|
|
$isError = false; |
205
|
|
|
|
206
|
|
|
// check XenForo version |
207
|
|
|
if (XenForo_Application::$versionId < 1050770) { |
208
|
|
|
$error .= 'This add-on requires XenForo 1.5.7 or higher.' . PHP_EOL; |
209
|
|
|
$isError = true; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
// check PHP version |
213
|
|
|
if (version_compare(PHP_VERSION, '5.4', '<')) { |
214
|
|
|
$error .= 'Threema Gateway requires PHP version 5.4 or higher. Current version: ' . PHP_VERSION . PHP_EOL; |
215
|
|
|
$isError = true; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
return !$isError; |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.