Completed
Push — master ( ac8fcc...e4073b )
by Nazar
05:57
created

profile::profile___sign_out()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 8
nc 3
nop 2
1
<?php
2
/**
3
 * @package    CleverStyle CMS
4
 * @subpackage System module
5
 * @category   modules
6
 * @author     Nazar Mokrynskyi <[email protected]>
7
 * @copyright  Copyright (c) 2015-2016, Nazar Mokrynskyi
8
 * @license    MIT License, see license.txt
9
 */
10
namespace cs\modules\System\api\Controller;
11
use
12
	cs\Config,
13
	cs\ExitException,
14
	cs\Language,
15
	cs\Language\Prefix,
16
	cs\Mail,
17
	cs\Page,
18
	cs\Session,
19
	cs\User;
20
21
trait profile {
22
	static function profile___get () {
23
		$User = User::instance();
24
		if ($User->guest()) {
25
			throw new ExitException(403);
26
		}
27
		$fields = [
28
			'id',
29
			'login',
30
			'username',
31
			'language',
32
			'timezone',
33
			'avatar'
34
		];
35
		Page::instance()->json(
36
			$User->get($fields, $User->id)
37
		);
38
	}
39
	/**
40
	 * @param \cs\Request $Request
41
	 *
42
	 * @throws ExitException
43
	 */
44
	static function profile___patch ($Request) {
45
		$user_data = $Request->data('login', 'username', 'language', 'timezone', 'avatar');
46
		if (
47
			!$user_data ||
48
			!$user_data['login']
49
		) {
50
			throw new ExitException(400);
51
		}
52
		$Config = Config::instance();
53
		$User   = User::instance();
54
		if ($User->guest()) {
55
			throw new ExitException(403);
56
		}
57
		$user_data = xap($user_data, false);
58
		if (
59
			(
60
				$user_data['language'] &&
61
				!in_array($user_data['language'], $Config->core['active_languages'])
62
			) ||
63
			(
64
				$user_data['timezone'] &&
65
				!in_array($user_data['timezone'], get_timezones_list())
66
			)
67
		) {
68
			throw new ExitException(400);
69
		}
70
		$user_data['login'] = mb_strtolower($user_data['login']);
71
		/**
72
		 * Check for changing login to new one and whether it is available
73
		 */
74
		if (
75
			$user_data['login'] != $User->login &&
76
			$user_data['login'] != $User->email &&
77
			(
78
				filter_var($user_data['login'], FILTER_VALIDATE_EMAIL) ||
79
				$User->get_id(hash('sha224', $user_data['login'])) !== false
80
			)
81
		) {
82
			throw new ExitException(Language::instance()->system_admin_users_login_occupied, 400);
83
		}
84
		if (!$User->set($user_data)) {
85
			throw new ExitException(500);
86
		}
87
	}
88
	/**
89
	 * @param \cs\Request $Request
90
	 *
91
	 * @throws ExitException
92
	 */
93
	static function profile___change_password ($Request) {
94
		$L    = new Prefix('system_profile_');
95
		$User = User::instance();
96
		$data = $Request->data('current_password', 'new_password');
97
		if (!$data) {
98
			throw new ExitException(400);
99
		}
100
		if (!$User->user()) {
101
			throw new ExitException(403);
102
		}
103
		if (!$data['new_password']) {
104
			throw new ExitException($L->please_type_new_password, 400);
105
		}
106
		if (!$User->validate_password($data['current_password'], $User->id, true)) {
107
			throw new ExitException($L->wrong_current_password, 400);
108
		}
109
		$id = $User->id;
110
		if ($User->set_password($data['new_password'], $id, true)) {
111
			Session::instance()->add($id);
112
		} else {
113
			throw new ExitException($L->change_password_server_error, 400);
114
		}
115
	}
116
	/**
117
	 * @param \cs\Request  $Request
118
	 * @param \cs\Response $Response
119
	 *
120
	 * @throws ExitException
121
	 */
122
	static function profile___registration ($Request, $Response) {
123
		$Config = Config::instance();
124
		$L      = new Prefix('system_profile_registration_');
125
		$User   = User::instance();
126
		if (!$User->guest()) {
127
			throw new ExitException(403);
128
		}
129
		if (!$Config->core['allow_user_registration']) {
130
			throw new ExitException($L->prohibited, 403);
131
		}
132
		$email = $Request->data('email');
133
		if (!$email) {
134
			throw new ExitException($L->please_type_your_email, 400);
135
		}
136
		$email  = mb_strtolower($email);
137
		$result = $User->registration($email);
138
		if ($result === false) {
139
			throw new ExitException($L->please_type_correct_email, 400);
140
		}
141
		if ($result == 'error') {
142
			throw new ExitException($L->server_error, 500);
143
		}
144
		if ($result == 'exists') {
145
			throw new ExitException($L->error_exists, 400);
146
		}
147
		$confirm = $result['reg_key'] !== true;
148
		if ($Request->data('username')) {
149
			$User->set('username', $Request->data['username'], $result['id']);
150
		}
151
		// Actually `sha512(sha512(password) + public_key)` instead of plain password
152
		if ($Request->data('password')) {
153
			$User->set_password($Request->data['password'], $result['id'], true);
154
		}
155
		if ($Request->data('language')) {
156
			$User->set('language', $Request->data['language'], $result['id']);
157
		}
158
		if ($Request->data('timezone')) {
159
			$User->set('timezone', $Request->data['timezone'], $result['id']);
160
		}
161
		if ($Request->data('avatar')) {
162
			$User->set('avatar', $Request->data['avatar'], $result['id']);
163
		}
164
		if ($confirm) {
165
			$body = $L->need_confirmation_mail_body(
166
				$User->username($result['id']),
167
				get_core_ml_text('name'),
168
				$Config->core_url()."/profile/registration_confirmation/$result[reg_key]",
169
				$L->time($Config->core['registration_confirmation_time'], 'd')
170
			);
171
		} elseif ($result['password']) {
172
			$body = $L->success_mail_with_password_body(
173
				$User->username($result['id']),
174
				get_core_ml_text('name'),
175
				$Config->core_url().'/profile/settings',
176
				$User->get('login', $result['id']),
177
				$result['password']
178
			);
179
		} else {
180
			$body = $L->success_mail(
181
				$User->username($result['id']),
182
				get_core_ml_text('name'),
183
				$Config->core_url().'/profile/settings',
184
				$User->get('login', $result['id'])
185
			);
186
		}
187
		if (!Mail::instance()->send_to(
188
			$email,
189
			$L->{$confirm ? 'need_confirmation_mail' : 'success_mail'}(get_core_ml_text('name')),
190
			$body
191
		)
192
		) {
193
			$User->registration_cancel();
194
			throw new ExitException($L->mail_sending_error, 500);
195
		}
196
		$Response->code = $confirm ? 202 : 201;
197
	}
198
	/**
199
	 * @param \cs\Request $Request
200
	 *
201
	 * @throws ExitException
202
	 */
203
	static function profile___restore_password ($Request) {
204
		$Config = Config::instance();
205
		$L      = new Prefix('system_profile_restore_password_');
206
		$User   = User::instance();
207
		$email  = $Request->data('email');
208
		if (!$User->guest()) {
209
			throw new ExitException(403);
210
		}
211
		if (!$email) {
212
			throw new ExitException($L->please_type_your_email, 400);
213
		}
214
		$id = $User->get_id(mb_strtolower($email));
215
		if (!$id) {
216
			throw new ExitException($L->user_with_such_login_email_not_found, 400);
217
		}
218
		$key = $User->restore_password($id);
219
		if (
220
			!$key ||
221
			!Mail::instance()->send_to(
222
				$User->get('email', $id),
223
				$L->confirmation_mail(get_core_ml_text('name')),
224
				$L->confirmation_mail_body(
225
					$User->username($id),
226
					get_core_ml_text('name'),
227
					$Config->core_url()."/profile/restore_password_confirmation/$key",
228
					$L->time($Config->core['registration_confirmation_time'], 'd')
229
				)
230
			)
231
		) {
232
			throw new ExitException($L->server_error, 500);
233
		}
234
	}
235
	/**
236
	 * @param \cs\Request $Request
237
	 *
238
	 * @throws ExitException
239
	 */
240
	static function profile___sign_in ($Request) {
241
		$Config = Config::instance();
242
		$L      = new Prefix('system_profile_sign_in_');
243
		$User   = User::instance();
244
		$data   = $Request->data('login', 'password');
245
		if (!$data) {
246
			throw new ExitException(400);
247
		}
248
		if (!$User->guest()) {
249
			return;
250
		}
251
		if (
252
			$Config->core['sign_in_attempts_block_count'] &&
253
			$User->get_sign_in_attempts_count($data['login']) >= $Config->core['sign_in_attempts_block_count']
254
		) {
255
			$User->sign_in_result(false, $data['login']);
256
			throw new ExitException($L->attempts_are_over_try_again_in(format_time($Config->core['sign_in_attempts_block_time'])), 403);
257
		}
258
		$id = $User->get_id($data['login']);
259
		if ($id && $User->validate_password($data['password'], $id, true)) {
260
			$status      = $User->get('status', $id);
261
			$block_until = $User->get('block_until', $id);
262
			if ($status == User::STATUS_NOT_ACTIVATED) {
263
				throw new ExitException($L->your_account_is_not_active, 403);
264
			}
265
			if ($status == User::STATUS_INACTIVE) {
266
				throw new ExitException($L->your_account_disabled, 403);
267
			}
268
			if ($block_until > time()) {
269
				throw new ExitException($L->your_account_blocked_until(date($L->_datetime, $block_until)), 403);
270
			}
271
			Session::instance()->add($id);
272
			$User->sign_in_result(true, $data['login']);
273
		} else {
274
			$User->sign_in_result(false, $data['login']);
275
			$content = $L->authentication_error;
276
			if (
277
				$Config->core['sign_in_attempts_block_count'] &&
278
				$User->get_sign_in_attempts_count($data['login']) >= $Config->core['sign_in_attempts_block_count'] * 2 / 3
279
			) {
280
				$content .= ' '.$L->attempts_left($Config->core['sign_in_attempts_block_count'] - $User->get_sign_in_attempts_count($data['login']));
281
			}
282
			throw new ExitException($content, 400);
283
		}
284
	}
285
	/**
286
	 * @param \cs\Request  $Request
287
	 * @param \cs\Response $Response
288
	 *
289
	 * @throws ExitException
290
	 */
291
	static function profile___sign_out (
292
		/** @noinspection PhpUnusedParameterInspection */
293
		$Request,
1 ignored issue
show
Unused Code introduced by
The parameter $Request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
294
		$Response
295
	) {
296
		if (User::instance()->guest()) {
297
			return;
298
		}
299
		if (!Session::instance()->del()) {
300
			throw new ExitException(500);
301
		}
302
		/**
303
		 * Hack for 403 after sign out in administration
304
		 */
305
		$Response->cookie('sign_out', 1, TIME + 5, true);
306
	}
307
	static function profile_contacts_get () {
308
		$User = User::instance();
309
		Page::instance()->json($User->get_contacts());
310
	}
311
}
312