PasswordValidator::getCallbacks()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 10
rs 10
1
<?php
2
namespace Ubiquity\security\auth\user;
3
4
use Ubiquity\contents\validation\validators\multiples\LengthValidator;
5
6
/**
7
 * Validates a password
8
 * Usage @validator("password","constraints"=>["min"=>v,"max"=>v,"upperCase"=>v,"numeric"=>v,"specialChar"=>v,"charset"=>v])
9
 * Ubiquity\security\auth\user$PasswordValidator
10
 * This class is part of Ubiquity
11
 *
12
 * @author jc
13
 * @version 1.0.0
14
 *
15
 */
16
class PasswordValidator extends LengthValidator {
17
18
	protected $min;
19
20
	protected $max;
21
22
	protected $upperCase;
23
24
	protected $numeric;
25
26
	protected $specialChar;
27
28
	protected $charset = 'UTF-8';
29
30
	protected const PASSWORD_CONSTRAINTS = [
31
		'upperCase',
32
		'numeric',
33
		'specialChar'
34
	];
35
36
	public function __construct() {
37
		parent::__construct();
38
		$this->message = array_merge($this->message, [
39
			'max' => 'This value cannot be longer than {max} characters.',
40
			'min' => 'This value should have at least {min} characters.',
41
			'charset' => 'This value is not in {charset} charset.',
42
			'upperCase' => 'This value must contain at least {upperCase} uppercase characters.',
43
			'numeric' => 'This value must contain at least {numeric} numeric characters.',
44
			'specialChar' => 'This value must contain at least {specialChar} special characters.'
45
		]);
46
	}
47
48
	protected function getCallbacks() {
49
		return [
50
			'upperCase' => function ($c) {
51
				return \ctype_alpha($c) && \strtoupper($c) === $c;
52
			},
53
			'numeric' => function ($c) {
54
				return \is_numeric($c);
55
			},
56
			'specialChar' => function ($c) {
57
				return \strpos("!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~", $c) !== false;
58
			}
59
		];
60
	}
61
62
	protected function getLengths($string) {
63
		$result = \array_combine(self::PASSWORD_CONSTRAINTS, \array_fill(0, \count(self::PASSWORD_CONSTRAINTS), 0));
64
		$size = \strlen($string);
65
		$callbacks = $this->getCallbacks();
66
		for ($i = 0; $i < $size; $i ++) {
67
			$c = $string[$i];
68
			foreach ($callbacks as $key => $callback) {
69
				if ($callback($c)) {
70
					$result[$key] ++;
71
				}
72
			}
73
		}
74
		return $result;
75
	}
76
77
	protected function validateValue($stringValue) {
78
		$result = parent::validateValue($stringValue);
79
		if (! $result) {
80
			return $result;
81
		}
82
		$lengths = $this->getLengths($stringValue);
83
		foreach (self::PASSWORD_CONSTRAINTS as $constraint) {
84
			if ($this->$constraint && $lengths[$constraint] < $this->$constraint) {
85
				$this->violation = $constraint;
86
				return false;
87
			}
88
		}
89
		return true;
90
	}
91
92
	/**
93
	 *
94
	 * {@inheritdoc}
95
	 * @see \Ubiquity\contents\validation\validators\Validator::getParameters()
96
	 */
97
	public function getParameters(): array {
98
		return \array_merge(parent::getParameters(), self::PASSWORD_CONSTRAINTS);
99
	}
100
}
101
102