Merge "Add CollationFa"
[lhc/web/wiklou.git] / includes / password / ParameterizedPassword.php
1 <?php
2 /**
3 * Implements the ParameterizedPassword class for the MediaWiki software.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23 /**
24 * Helper class for password hash types that have a delimited set of parameters
25 * inside of the hash.
26 *
27 * All passwords are in the form of :<TYPE>:... as explained in the main Password
28 * class. This class is for hashes in the form of :<TYPE>:<PARAM1>:<PARAM2>:... where
29 * <PARAM1>, <PARAM2>, etc. are parameters that determine how the password was hashed.
30 * Of course, the internal delimiter (which is : by convention and default), can be
31 * changed by overriding the ParameterizedPassword::getDelimiter() function.
32 *
33 * This class requires overriding an additional function: ParameterizedPassword::getDefaultParams().
34 * See the function description for more details on the implementation.
35 *
36 * @since 1.24
37 */
38 abstract class ParameterizedPassword extends Password {
39 /**
40 * Named parameters that have default values for this password type
41 * @var array
42 */
43 protected $params = [];
44
45 /**
46 * Extra arguments that were found in the hash. This may or may not make
47 * the hash invalid.
48 * @var array
49 */
50 protected $args = [];
51
52 protected function parseHash( $hash ) {
53 parent::parseHash( $hash );
54
55 if ( $hash === null ) {
56 $this->params = $this->getDefaultParams();
57 return;
58 }
59
60 $parts = explode( $this->getDelimiter(), $hash );
61 $paramKeys = array_keys( $this->getDefaultParams() );
62
63 if ( count( $parts ) < count( $paramKeys ) ) {
64 throw new PasswordError( 'Hash is missing required parameters.' );
65 }
66
67 if ( $paramKeys ) {
68 $this->args = array_splice( $parts, count( $paramKeys ) );
69 $this->params = array_combine( $paramKeys, $parts );
70 } else {
71 $this->args = $parts;
72 }
73
74 if ( $this->args ) {
75 $this->hash = array_pop( $this->args );
76 } else {
77 $this->hash = null;
78 }
79 }
80
81 public function needsUpdate() {
82 return parent::needsUpdate() || $this->params !== $this->getDefaultParams();
83 }
84
85 public function toString() {
86 $str = ':' . $this->config['type'] . ':';
87
88 if ( count( $this->params ) || count( $this->args ) ) {
89 $str .= implode( $this->getDelimiter(), array_merge( $this->params, $this->args ) );
90 $str .= $this->getDelimiter();
91 }
92
93 $res = $str . $this->hash;
94 $this->assertIsSafeSize( $res );
95 return $res;
96 }
97
98 /**
99 * Returns the delimiter for the parameters inside the hash
100 *
101 * @return string
102 */
103 abstract protected function getDelimiter();
104
105 /**
106 * Return an ordered array of default parameters for this password hash
107 *
108 * The keys should be the parameter names and the values should be the default
109 * values. Additionally, the order of the array should be the order in which they
110 * appear in the hash.
111 *
112 * When parsing a password hash, the constructor will split the hash based on
113 * the delimiter, and consume as many parts as it can, matching each to a parameter
114 * in this list. Once all the parameters have been filled, all remaining parts will
115 * be considered extra arguments, except, of course, for the very last part, which
116 * is the hash itself.
117 *
118 * @return array
119 */
120 abstract protected function getDefaultParams();
121 }