Issues (2553)

apps/admin_audit/lib/AppInfo/Application.php (7 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2017 Joas Schilling <[email protected]>
7
 *
8
 * @author Arthur Schiwon <[email protected]>
9
 * @author Bjoern Schiessle <[email protected]>
10
 * @author Christoph Wurst <[email protected]>
11
 * @author Daniel Kesselberg <[email protected]>
12
 * @author GrayFix <[email protected]>
13
 * @author Joas Schilling <[email protected]>
14
 * @author Morris Jobke <[email protected]>
15
 * @author Roeland Jago Douma <[email protected]>
16
 * @author Tiago Flores <[email protected]>
17
 *
18
 * @license GNU AGPL version 3 or any later version
19
 *
20
 * This program is free software: you can redistribute it and/or modify
21
 * it under the terms of the GNU Affero General Public License as
22
 * published by the Free Software Foundation, either version 3 of the
23
 * License, or (at your option) any later version.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
 * GNU Affero General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU Affero General Public License
31
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32
 *
33
 */
34
namespace OCA\AdminAudit\AppInfo;
35
36
use Closure;
37
use OC\Files\Filesystem;
38
use OC\Files\Node\File;
39
use OC\Group\Manager as GroupManager;
40
use OC\User\Session as UserSession;
41
use OCA\AdminAudit\Actions\AppManagement;
42
use OCA\AdminAudit\Actions\Auth;
43
use OCA\AdminAudit\Actions\Console;
44
use OCA\AdminAudit\Actions\Files;
45
use OCA\AdminAudit\Actions\GroupManagement;
46
use OCA\AdminAudit\Actions\Security;
47
use OCA\AdminAudit\Actions\Sharing;
48
use OCA\AdminAudit\Actions\Trashbin;
49
use OCA\AdminAudit\Actions\UserManagement;
50
use OCA\AdminAudit\Actions\Versions;
51
use OCA\AdminAudit\AuditLogger;
52
use OCA\AdminAudit\IAuditLogger;
53
use OCA\AdminAudit\Listener\CriticalActionPerformedEventListener;
54
use OCP\App\ManagerEvent;
55
use OCP\AppFramework\App;
56
use OCP\AppFramework\Bootstrap\IBootContext;
57
use OCP\AppFramework\Bootstrap\IBootstrap;
58
use OCP\AppFramework\Bootstrap\IRegistrationContext;
59
use OCP\Authentication\TwoFactorAuth\IProvider;
60
use OCP\Console\ConsoleEvent;
61
use OCP\IConfig;
62
use OCP\IGroupManager;
63
use OCP\IPreview;
64
use OCP\IServerContainer;
65
use OCP\IUserSession;
66
use OCP\Log\Audit\CriticalActionPerformedEvent;
67
use OCP\Log\ILogFactory;
68
use OCP\Share;
69
use OCP\Util;
70
use Psr\Container\ContainerInterface;
71
use Psr\Log\LoggerInterface;
72
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
73
use Symfony\Component\EventDispatcher\GenericEvent;
74
75
class Application extends App implements IBootstrap {
76
77
	/** @var LoggerInterface */
78
	protected $logger;
79
80
	public function __construct() {
81
		parent::__construct('admin_audit');
82
	}
83
84
	public function register(IRegistrationContext $context): void {
85
		$context->registerService(IAuditLogger::class, function (ContainerInterface $c) {
86
			return new AuditLogger($c->get(ILogFactory::class), $c->get(Iconfig::class));
87
		});
88
89
		$context->registerEventListener(CriticalActionPerformedEvent::class, CriticalActionPerformedEventListener::class);
90
	}
91
92
	public function boot(IBootContext $context): void {
93
		/** @var IAuditLogger $logger */
94
		$logger = $context->getAppContainer()->get(IAuditLogger::class);
95
96
		/*
97
		 * TODO: once the hooks are migrated to lazy events, this should be done
98
		 *       in \OCA\AdminAudit\AppInfo\Application::register
99
		 */
100
		$this->registerHooks($logger, $context->getServerContainer());
101
	}
102
103
	/**
104
	 * Register hooks in order to log them
105
	 */
106
	private function registerHooks(IAuditLogger $logger,
107
									 IServerContainer $serverContainer): void {
108
		$this->userManagementHooks($logger, $serverContainer->get(IUserSession::class));
109
		$this->groupHooks($logger, $serverContainer->get(IGroupManager::class));
110
		$this->authHooks($logger);
111
112
		/** @var EventDispatcherInterface $eventDispatcher */
113
		$eventDispatcher = $serverContainer->get(EventDispatcherInterface::class);
114
		$this->consoleHooks($logger, $eventDispatcher);
115
		$this->appHooks($logger, $eventDispatcher);
116
117
		$this->sharingHooks($logger);
118
119
		$this->fileHooks($logger, $eventDispatcher);
120
		$this->trashbinHooks($logger);
121
		$this->versionsHooks($logger);
122
123
		$this->securityHooks($logger, $eventDispatcher);
124
	}
125
126
	private function userManagementHooks(IAuditLogger $logger,
127
										 IUserSession $userSession): void {
128
		$userActions = new UserManagement($logger);
129
130
		Util::connectHook('OC_User', 'post_createUser', $userActions, 'create');
131
		Util::connectHook('OC_User', 'post_deleteUser', $userActions, 'delete');
132
		Util::connectHook('OC_User', 'changeUser', $userActions, 'change');
133
134
		assert($userSession instanceof UserSession);
135
		$userSession->listen('\OC\User', 'postSetPassword', [$userActions, 'setPassword']);
136
		$userSession->listen('\OC\User', 'assignedUserId', [$userActions, 'assign']);
137
		$userSession->listen('\OC\User', 'postUnassignedUserId', [$userActions, 'unassign']);
138
	}
139
140
	private function groupHooks(IAuditLogger $logger,
141
								IGroupManager $groupManager): void {
142
		$groupActions = new GroupManagement($logger);
143
144
		assert($groupManager instanceof GroupManager);
145
		$groupManager->listen('\OC\Group', 'postRemoveUser', [$groupActions, 'removeUser']);
146
		$groupManager->listen('\OC\Group', 'postAddUser', [$groupActions, 'addUser']);
147
		$groupManager->listen('\OC\Group', 'postDelete', [$groupActions, 'deleteGroup']);
148
		$groupManager->listen('\OC\Group', 'postCreate', [$groupActions, 'createGroup']);
149
	}
150
151
	private function sharingHooks(IAuditLogger $logger): void {
152
		$shareActions = new Sharing($logger);
153
154
		Util::connectHook(Share::class, 'post_shared', $shareActions, 'shared');
155
		Util::connectHook(Share::class, 'post_unshare', $shareActions, 'unshare');
156
		Util::connectHook(Share::class, 'post_unshareFromSelf', $shareActions, 'unshare');
157
		Util::connectHook(Share::class, 'post_update_permissions', $shareActions, 'updatePermissions');
158
		Util::connectHook(Share::class, 'post_update_password', $shareActions, 'updatePassword');
159
		Util::connectHook(Share::class, 'post_set_expiration_date', $shareActions, 'updateExpirationDate');
160
		Util::connectHook(Share::class, 'share_link_access', $shareActions, 'shareAccessed');
161
	}
162
163
	private function authHooks(IAuditLogger $logger): void {
164
		$authActions = new Auth($logger);
165
166
		Util::connectHook('OC_User', 'pre_login', $authActions, 'loginAttempt');
167
		Util::connectHook('OC_User', 'post_login', $authActions, 'loginSuccessful');
168
		Util::connectHook('OC_User', 'logout', $authActions, 'logout');
169
	}
170
171
	private function appHooks(IAuditLogger $logger,
172
							  EventDispatcherInterface $eventDispatcher): void {
173
		$eventDispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE, function (ManagerEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\App\ManagerEvent::EVENT_APP_ENABLE has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

173
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ ManagerEvent::EVENT_APP_ENABLE, function (ManagerEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
174
			$appActions = new AppManagement($logger);
175
			$appActions->enableApp($event->getAppID());
176
		});
177
		$eventDispatcher->addListener(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, function (ManagerEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\App\ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

177
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, function (ManagerEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
178
			$appActions = new AppManagement($logger);
179
			$appActions->enableAppForGroups($event->getAppID(), $event->getGroups());
180
		});
181
		$eventDispatcher->addListener(ManagerEvent::EVENT_APP_DISABLE, function (ManagerEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\App\ManagerEvent::EVENT_APP_DISABLE has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

181
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ ManagerEvent::EVENT_APP_DISABLE, function (ManagerEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
182
			$appActions = new AppManagement($logger);
183
			$appActions->disableApp($event->getAppID());
184
		});
185
	}
186
187
	private function consoleHooks(IAuditLogger $logger,
188
								  EventDispatcherInterface $eventDispatcher): void {
189
		$eventDispatcher->addListener(ConsoleEvent::EVENT_RUN, function (ConsoleEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\Console\ConsoleEvent::EVENT_RUN has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

189
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ ConsoleEvent::EVENT_RUN, function (ConsoleEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
190
			$appActions = new Console($logger);
191
			$appActions->runCommand($event->getArguments());
192
		});
193
	}
194
195
	private function fileHooks(IAuditLogger $logger,
196
							   EventDispatcherInterface $eventDispatcher): void {
197
		$fileActions = new Files($logger);
198
		$eventDispatcher->addListener(
199
			IPreview::EVENT,
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\IPreview::EVENT has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

199
			/** @scrutinizer ignore-deprecated */ IPreview::EVENT,

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
200
			function (GenericEvent $event) use ($fileActions) {
201
				/** @var File $file */
202
				$file = $event->getSubject();
203
				$fileActions->preview([
204
					'path' => mb_substr($file->getInternalPath(), 5),
205
					'width' => $event->getArguments()['width'],
206
					'height' => $event->getArguments()['height'],
207
					'crop' => $event->getArguments()['crop'],
208
					'mode' => $event->getArguments()['mode']
209
				]);
210
			}
211
		);
212
213
		Util::connectHook(
214
			Filesystem::CLASSNAME,
215
			Filesystem::signal_post_rename,
216
			$fileActions,
217
			'rename'
218
		);
219
		Util::connectHook(
220
			Filesystem::CLASSNAME,
221
			Filesystem::signal_post_create,
222
			$fileActions,
223
			'create'
224
		);
225
		Util::connectHook(
226
			Filesystem::CLASSNAME,
227
			Filesystem::signal_post_copy,
228
			$fileActions,
229
			'copy'
230
		);
231
		Util::connectHook(
232
			Filesystem::CLASSNAME,
233
			Filesystem::signal_post_write,
234
			$fileActions,
235
			'write'
236
		);
237
		Util::connectHook(
238
			Filesystem::CLASSNAME,
239
			Filesystem::signal_post_update,
240
			$fileActions,
241
			'update'
242
		);
243
		Util::connectHook(
244
			Filesystem::CLASSNAME,
245
			Filesystem::signal_read,
246
			$fileActions,
247
			'read'
248
		);
249
		Util::connectHook(
250
			Filesystem::CLASSNAME,
251
			Filesystem::signal_delete,
252
			$fileActions,
253
			'delete'
254
		);
255
	}
256
257
	private function versionsHooks(IAuditLogger $logger): void {
258
		$versionsActions = new Versions($logger);
259
		Util::connectHook('\OCP\Versions', 'rollback', $versionsActions, 'rollback');
260
		Util::connectHook('\OCP\Versions', 'delete', $versionsActions, 'delete');
261
	}
262
263
	private function trashbinHooks(IAuditLogger $logger): void {
264
		$trashActions = new Trashbin($logger);
265
		Util::connectHook('\OCP\Trashbin', 'preDelete', $trashActions, 'delete');
266
		Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', $trashActions, 'restore');
267
	}
268
269
	private function securityHooks(IAuditLogger $logger,
270
								   EventDispatcherInterface $eventDispatcher): void {
271
		$eventDispatcher->addListener(IProvider::EVENT_SUCCESS, function (GenericEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\Authentication\TwoFa...Provider::EVENT_SUCCESS has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

271
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ IProvider::EVENT_SUCCESS, function (GenericEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
272
			$security = new Security($logger);
273
			$security->twofactorSuccess($event->getSubject(), $event->getArguments());
274
		});
275
		$eventDispatcher->addListener(IProvider::EVENT_FAILED, function (GenericEvent $event) use ($logger) {
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\Authentication\TwoFa...IProvider::EVENT_FAILED has been deprecated: 22.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

275
		$eventDispatcher->addListener(/** @scrutinizer ignore-deprecated */ IProvider::EVENT_FAILED, function (GenericEvent $event) use ($logger) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
276
			$security = new Security($logger);
277
			$security->twofactorFailed($event->getSubject(), $event->getArguments());
278
		});
279
	}
280
}
281