OTPHelper::generateKeyURI()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 10
cts 10
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
nc 1
nop 8
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * OTPHelper
5
 * @package OTPAuthenticate
6
 * @copyright (c) Marc Alexander <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace OTPAuthenticate;
13
14
class OTPHelper
15
{
16
	/** @var array Allowed types of OTP */
17
	protected $allowedType = array(
18
		'hotp',
19
		'totp',
20
	);
21
22
	/** @var array Allowed algorithms */
23
	protected $allowedAlgorithm = array(
24
		'sha1',
25
		'sha256',
26
		'sha512',
27
	);
28
29
	/** @var string Label string for URI */
30
	protected $label;
31
32
	/** @var string Issuer string for URI */
33
	protected $issuer;
34
35
	/** @var string Additional parameters for URI */
36
	protected $parameters = '';
37
38
	/**
39
	 * Generate OTP key URI
40
	 *
41
	 * @param string $type OTP type
42
	 * @param string $secret Base32 encoded secret
43
	 * @param string $account Account name
44
	 * @param string $issuer Issuer name (optional)
45
	 * @param int $counter Counter for HOTP (optional)
46
	 * @param string $algorithm Algorithm name (optional)
47
	 * @param string $digits Number of digits for code (optional)
48
	 * @param string $period Period for TOTP codes (optional)
49
	 *
50
	 * @return string OTP key URI
51
	 */
52 12
	public function generateKeyURI($type, $secret, $account, $issuer = '', $counter = 0, $algorithm = '', $digits = '', $period = '')
53
	{
54
		// Check if type is supported
55 12
		$this->validateType($type);
56 11
		$this->validateAlgorithm($algorithm);
57
58
		// Format label string
59 10
		$this->formatLabel($issuer, 'issuer');
60 10
		$this->formatLabel($account, 'account');
61
62
		// Set additional parameters
63 8
		$this->setCounter($type, $counter);
64 7
		$this->setParameter($algorithm, 'algorithm');
65 7
		$this->setParameter($digits, 'digits');
66 7
		$this->setParameter($period, 'period');
67
68 7
		return 'otpauth://' . $type . '/' . $this->label . '?secret=' . $secret . $this->issuer . $this->parameters;
69
	}
70
71
	/**
72
	 * Check if OTP type is supported
73
	 *
74
	 * @param string $type OTP type
75
	 *
76
	 * @throws \InvalidArgumentException When type is not supported
77
	 */
78 12
	protected function validateType($type)
79
	{
80 12
		if (empty($type) || !in_array($type, $this->allowedType))
81
		{
82 1
			throw new \InvalidArgumentException("The OTP type $type is not supported");
83
		}
84 11
	}
85
86
	/**
87
	 * Check if algorithm is supported
88
	 *
89
	 * @param string $algorithm Algorithm to use
90
	 *
91
	 * @throws \InvalidArgumentException When algorithm is not supported
92
	 */
93 11
	protected function validateAlgorithm($algorithm)
94
	{
95 11
		if (!empty($algorithm) && !in_array($algorithm, $this->allowedAlgorithm))
96
		{
97 1
			throw new \InvalidArgumentException("The algorithm $algorithm is not supported");
98
		}
99 10
	}
100
101
	/**
102
	 * Format label string according to expected urlencoded standards.
103
	 *
104
	 * @param string $string The label string
105
	 * @param string $part Part of label
106
	 */
107 10
	protected function formatLabel($string, $part)
108
	{
109 10
		$string = trim($string);
110
111 10
		if ($part === 'account')
112
		{
113 10
			$this->setAccount($string);
114
		}
115 10
		else if ($part === 'issuer')
116
		{
117 10
			$this->setIssuer($string);
118
		}
119 10
	}
120
121
	/**
122
	 * Format and and set account name
123
	 *
124
	 * @param string $account Account name
125
	 *
126
	 * @throws \InvalidArgumentException When given account name is an empty string
127
	 */
128 10
	protected function setAccount($account)
129
	{
130 10
		if (empty($account))
131
		{
132 2
			throw new \InvalidArgumentException("Label can't contain empty strings");
133
		}
134
135 8
		$this->label .= str_replace('%40', '@', rawurlencode($account));
136 8
	}
137
138
	/**
139
	 * Format and set issuer
140
	 *
141
	 * @param string $issuer Issuer name
142
	 */
143 10
	protected function setIssuer($issuer)
144
	{
145 10
		if (!empty($issuer))
146
		{
147 2
			$this->label = rawurlencode($issuer) . ':';
148 2
			$this->issuer = '&issuer=' . rawurlencode($issuer);
149
		}
150 10
	}
151
152
	/**
153
	 * Set parameter if it is defined
154
	 *
155
	 * @param string $data Data to set
156
	 * @param string $name Name of data
157
	 */
158 7
	protected function setParameter($data, $name)
159
	{
160 7
		if (!empty($data))
161
		{
162 2
			$this->parameters .= "&$name=" . rawurlencode($data);
163
		}
164 7
	}
165
166
	/**
167
	 * Set counter value if hotp is being used
168
	 *
169
	 * @param string $type Type of OTP auth, either HOTP or TOTP
170
	 * @param int $counter Counter value
171
	 *
172
	 * @throws \InvalidArgumentException If counter is empty while using HOTP
173
	 */
174 8
	protected function setCounter($type, $counter)
175
	{
176 8
		if ($type === 'hotp')
177
		{
178 5
			if ($counter !== 0 && empty($counter))
179
			{
180 1
				throw new \InvalidArgumentException("Counter can't be empty if HOTP is being used");
181
			}
182
183 4
			$this->parameters .= "&counter=$counter";
184
		}
185 7
	}
186
}
187