· 8 years ago · Jan 19, 2018, 01:32 PM
1<?php
2namespace App\Model\Table;
3
4use Cake\Auth\DefaultPasswordHasher;
5use Cake\ORM\Query;
6use Cake\ORM\RulesChecker;
7use Cake\ORM\Table;
8use Cake\Validation\Validator;
9
10/**
11 * Users Model
12 *
13 * @property \App\Model\Table\LinksTable|\Cake\ORM\Association\HasMany $Links
14 *
15 * @method \App\Model\Entity\User get($primaryKey, $options = [])
16 * @method \App\Model\Entity\User newEntity($data = null, array $options = [])
17 * @method \App\Model\Entity\User[] newEntities(array $data, array $options = [])
18 * @method \App\Model\Entity\User|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
19 * @method \App\Model\Entity\User patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
20 * @method \App\Model\Entity\User[] patchEntities($entities, array $data, array $options = [])
21 * @method \App\Model\Entity\User findOrCreate($search, callable $callback = null, $options = [])
22 *
23 * @mixin \Cake\ORM\Behavior\TimestampBehavior
24 */
25class UsersTable extends Table
26{
27
28 /**
29 * Available system roles
30 */
31 public $systemRoles = [
32 'Administrator' => 'Administrator',
33 'Standard' => 'Standard',
34 ];
35
36 /**
37 * Initialize method
38 *
39 * @param array $config The configuration for the Table.
40 * @return void
41 */
42 public function initialize(array $config)
43 {
44 parent::initialize($config);
45
46 $this->setTable('users');
47 $this->setDisplayField('username');
48 $this->setPrimaryKey('id');
49
50 $this->addBehavior('Timestamp');
51
52 $this->hasMany('Links', [
53 'foreignKey' => 'user_id',
54 'dependent' => true
55 ]);
56 $this->hasMany('Statistics', [
57 'foreignKey' => 'foreign_id',
58 'conditions' => ['foreign_table' => $this->table()],
59 'dependent' => true
60 ]);
61 }
62
63 /**
64 * Default validation rules.
65 *
66 * @param \Cake\Validation\Validator $validator Validator instance.
67 * @return \Cake\Validation\Validator
68 */
69 public function validationDefault(Validator $validator)
70 {
71 $validator
72 ->scalar('username')
73 ->maxLength('username', 255)
74 ->requirePresence('username', 'create')
75 ->notEmpty('username')
76 ->add('username', 'unique', ['rule' => 'validateUnique', 'provider' => 'table', 'message' => __('This email address is already in the system.')])
77 ->add('username', 'custom', [
78 'rule' => 'email',
79 'message' => __('Please enter a valid email address.')
80 ]);
81
82 $validator
83 ->scalar('username-challenge')
84 ->maxLength('username-challenge', 255)
85 ->requirePresence('username-challenge')
86 ->notEmpty('username-challenge')
87 ->add('username-challenge', 'custom', [
88 'rule' => [$this, 'compareUsernames'],
89 'message' => __('The email that you entered does not match.')
90 ]);
91
92 $validator
93 ->scalar('password')
94 ->maxLength('password', 255)
95 ->requirePresence('password', 'create')
96 ->notEmpty('password');
97
98 $validator
99 ->notEmpty('password-challenge')
100 ->requirePresence('password-challenge')
101 ->add('password-challenge', 'custom', [
102 'rule' => [$this, 'comparePasswords'],
103 'message' => __('The passwords that you entered do not match.')
104 ]);
105
106 $validator
107 ->scalar('password-verify')
108 ->requirePresence('password-verify')
109 ->notEmpty('password-verify')
110 ->add('password-verify', 'custom', [
111 'rule' => [$this, 'verifyPassword'],
112 'message' => __('The password that you entered doesn\'t match our records.')
113 ]);
114
115 $validator
116 ->scalar('role')
117 ->maxLength('role', 255)
118 ->requirePresence('role', 'create')
119 ->notEmpty('role');
120
121 $validator
122 ->requirePresence('g-recaptcha-response')
123 ->notEmpty('g-recaptcha-response', __('Please complete the Captcha verification before continuing.'))
124 ->add('g-recaptcha-response', 'custom', [
125 'rule' => [$this, 'verifyCaptcha'],
126 'message' => __('Captcha verification failed.')
127 ]);
128
129 return $validator;
130 }
131
132 /**
133 * Change Username validation rules.
134 *
135 * @param \Cake\Validation\Validator $validator Validator instance.
136 * @return \Cake\Validation\Validator
137 */
138 public function validationChangeUsername(Validator $validator)
139 {
140 $validator
141 ->integer('id')
142 ->allowEmpty('id');
143
144 $validator
145 ->scalar('username')
146 ->maxLength('username', 255)
147 ->requirePresence('username')
148 ->notEmpty('username')
149 ->add('username', 'custom', [
150 'rule' => 'email',
151 'message' => __('Please enter a valid email address.')
152 ]);
153
154 $validator
155 ->scalar('username-challenge')
156 ->maxLength('username-challenge', 255)
157 ->requirePresence('username-challenge')
158 ->notEmpty('username-challenge')
159 ->add('username-challenge', 'custom', [
160 'rule' => [$this, 'compareUsernames'],
161 'message' => __('The email that you entered does not match.')
162 ]);
163
164 $validator
165 ->scalar('password-verify')
166 ->requirePresence('password-verify')
167 ->notEmpty('password-verify')
168 ->add('password-verify', 'custom', [
169 'rule' => [$this, 'verifyPassword'],
170 'message' => __('The password that you entered doesn\'t match our records.')
171 ]);
172
173 return $validator;
174 }
175
176 /**
177 * Change Password validation rules.
178 *
179 * @param \Cake\Validation\Validator $validator Validator instance.
180 * @return \Cake\Validation\Validator
181 */
182 public function validationChangePassword(Validator $validator)
183 {
184 $validator
185 ->integer('id')
186 ->allowEmpty('id', 'create');
187
188 $validator
189 ->scalar('password')
190 ->maxLength('password', 255)
191 ->requirePresence('password')
192 ->notEmpty('password');
193
194 $validator
195 ->notEmpty('password-challenge')
196 ->requirePresence('password-challenge')
197 ->add('password-challenge', 'custom', [
198 'rule' => [$this, 'comparePasswords'],
199 'message' => __('The passwords that you entered do not match.')
200 ]);
201
202 $validator
203 ->notEmpty('password-verify')
204 ->requirePresence('password-verify')
205 ->add('password-verify', 'custom', [
206 'rule' => [$this, 'verifyPassword'],
207 'message' => __('The password that you entered does not match our records.')
208 ]);
209
210 return $validator;
211 }
212
213 /**
214 * Forgot Password validation rules.
215 *
216 * @param \Cake\Validation\Validator $validator Validator instance.
217 * @return \Cake\Validation\Validator
218 */
219 public function validationForgotPassword(Validator $validator)
220 {
221 $validator
222 ->scalar('username')
223 ->maxLength('username', 255)
224 ->requirePresence('username')
225 ->notEmpty('username');
226
227 $validator
228 ->requirePresence('g-recaptcha-response')
229 ->notEmpty('g-recaptcha-response', __('Please complete the Captcha verification before continuing.'))
230 ->add('g-recaptcha-response', 'custom', [
231 'rule' => [$this, 'verifyCaptcha'],
232 'message' => __('Captcha verification failed.')
233 ]);
234
235 return $validator;
236 }
237
238 /**
239 * Login validation rules.
240 *
241 * @param \Cake\Validation\Validator $validator Validator instance.
242 * @return \Cake\Validation\Validator
243 */
244 public function validationLogin(Validator $validator)
245 {
246 $validator
247 ->scalar('username')
248 ->maxLength('username', 255)
249 ->requirePresence('username')
250 ->notEmpty('username');
251
252 $validator
253 ->scalar('password')
254 ->maxLength('password', 255)
255 ->requirePresence('password')
256 ->notEmpty('password');
257
258 $validator
259 ->requirePresence('g-recaptcha-response')
260 ->notEmpty('g-recaptcha-response', __('Please complete the Captcha verification before continuing.'))
261 ->add('g-recaptcha-response', 'custom', [
262 'rule' => [$this, 'verifyCaptcha'],
263 'message' => __('Captcha verification failed.')
264 ]);
265
266 return $validator;
267 }
268
269 /**
270 * Register validation rules.
271 *
272 * @param \Cake\Validation\Validator $validator Validator instance.
273 * @return \Cake\Validation\Validator
274 */
275 public function validationRegister(Validator $validator)
276 {
277 $validator
278 ->scalar('username')
279 ->maxLength('username', 255)
280 ->requirePresence('username')
281 ->notEmpty('username')
282 ->add('username', 'custom', [
283 'rule' => 'email',
284 'message' => __('Please enter a valid email address.')
285 ]);
286
287 $validator
288 ->scalar('password')
289 ->maxLength('password', 255)
290 ->requirePresence('password')
291 ->notEmpty('password');
292
293 $validator
294 ->notEmpty('password-challenge')
295 ->add('password-challenge', 'custom', [
296 'rule' => [$this, 'comparePasswords'],
297 'message' => __('The password that you entered does not match.')
298 ]);
299
300 $validator
301 ->requirePresence('g-recaptcha-response')
302 ->notEmpty('g-recaptcha-response', __('Please complete the Captcha verification before continuing.'))
303 ->add('g-recaptcha-response', 'custom', [
304 'rule' => [$this, 'verifyCaptcha'],
305 'message' => __('Captcha verification failed.')
306 ]);
307
308 return $validator; }
309
310 /**
311 * Returns a rules checker object that will be used for validating
312 * application integrity.
313 *
314 * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
315 * @return \Cake\ORM\RulesChecker
316 */
317 public function buildRules(RulesChecker $rules)
318 {
319 $rules->add($rules->isUnique(['username'], __('This email address already exists in the system.')));
320
321 return $rules;
322 }
323
324 /**
325 * Confirms that the entered password matches the password stored in the db
326 */
327 public function verifyPassword($check, array $context)
328 {
329 $user = $this->get($context['data']['id']);
330 if ((new DefaultPasswordHasher)->check($check, $user->password)) {
331 return true;
332 }
333 return false;
334 }
335
336 /**
337 * Compares password to password-challenge
338 */
339 public function comparePasswords($check, array $context)
340 {
341 if ($check == $context['data']['password']) {
342 return true;
343 }
344 return false;
345 }
346
347 /**
348 * Compares username to username-challenge
349 */
350 public function compareUsernames($check, array $context)
351 {
352 if ($check == $context['data']['username']) {
353 return true;
354 }
355 return false;
356 }
357
358 /**
359 * Validates captcha input
360 */
361 public function verifyCaptcha($check, array $context)
362 {
363 $verifyUrl = 'https://www.google.com/recaptcha/api/siteverify?';
364 $query['secret'] = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
365 $query['response'] = $check;
366 $query['remoteip'] = env('REMOTE_ADDR');
367 $queryString = http_build_query($query);
368
369 $response = file_get_contents($verifyUrl . $queryString);
370 $responseObject = json_decode($response);
371
372 if ($responseObject) {
373 if ($responseObject->success) {
374 return true;
375 }
376 }
377 return false;
378 }
379}