@@ -26,15 +26,15 @@ class SQL2 extends UserPassBase
2626 * List of one or more databases that are used by auth and attribute queries.
2727 * Each database must have a unique name, and the name is used to refer to
2828 * the database in auth and attribute queries.
29- *
29+ *
3030 * @var array
3131 */
3232 private array $ databases = [];
3333
3434 /**
3535 * List of one or more authentication queries. The first query that returns a result
3636 * is considered to have authenticated the user (and termed "winning").
37- *
37+ *
3838 * @var array
3939 */
4040 private array $ authQueries = [];
@@ -47,6 +47,7 @@ class SQL2 extends UserPassBase
4747 */
4848 private array $ attributesQueries = [];
4949
50+
5051 /**
5152 * Constructor for this authentication source.
5253 *
@@ -73,7 +74,7 @@ public function __construct(array $info, array $config)
7374
7475 foreach ($ config ['databases ' ] as $ dbname => $ dbConfig ) {
7576 if (!is_array ($ dbConfig )) {
76- throw new Exception ('Each entry in the ' .
77+ throw new Exception ('Each entry in the ' .
7778 $ dbname . ' \'databases \' parameter for authentication source ' .
7879 $ this ->authId . ' is expected to be an array. Instead it was: ' .
7980 var_export ($ dbConfig , true ));
@@ -126,7 +127,7 @@ public function __construct(array $info, array $config)
126127
127128 foreach ($ config ['auth_queries ' ] as $ authQueryName => $ authQueryConfig ) {
128129 if (!is_array ($ authQueryConfig )) {
129- throw new Exception ('Each entry in the ' .
130+ throw new Exception ('Each entry in the ' .
130131 $ authQueryName . ' \'auth_queries \' parameter for authentication source ' .
131132 $ this ->authId . ' is expected to be an array. Instead it was: ' .
132133 var_export ($ authQueryConfig , true ));
@@ -146,7 +147,7 @@ public function __construct(array $info, array $config)
146147 var_export ($ authQueryConfig [$ param ], true ));
147148 }
148149 }
149-
150+
150151 if (!array_key_exists ($ authQueryConfig ['database ' ], $ this ->databases )) {
151152 throw new Exception ('Auth query ' .
152153 $ authQueryName . ' references unknown database \'' .
@@ -155,8 +156,13 @@ public function __construct(array $info, array $config)
155156 }
156157
157158 $ this ->authQueries [$ authQueryName ] = [
158- '_winning_auth_query ' => false , // Will be set to true for the query that successfully authenticated the user
159- '_extracted_userid ' => null , // Will hold the value of the attribute named by 'extract_userid_from' if specified and authentication succeeds
159+ // Will be set to true for the query that successfully authenticated the user
160+ '_winning_auth_query ' => false ,
161+
162+ // Will hold the value of the attribute named by 'extract_userid_from'
163+ // if specified and authentication succeeds
164+ '_extracted_userid ' => null ,
165+
160166 'database ' => $ authQueryConfig ['database ' ],
161167 'query ' => $ authQueryConfig ['query ' ],
162168 ];
@@ -181,15 +187,21 @@ public function __construct(array $info, array $config)
181187
182188 if (array_key_exists ('password_verify_hash_column ' , $ authQueryConfig )) {
183189 if (!is_string ($ authQueryConfig ['password_verify_hash_column ' ])) {
184- throw new Exception ('Optional parameter \'password_verify_hash_column \' for authentication source ' .
190+ throw new Exception (
191+ 'Optional parameter \'password_verify_hash_column \' for authentication source ' .
185192 $ this ->authId . ' was provided and is expected to be a string. Instead it was: ' .
186- var_export ($ authQueryConfig ['password_verify_hash_column ' ], true ));
193+ var_export ($ authQueryConfig ['password_verify_hash_column ' ], true ),
194+ );
187195 }
188- $ this ->authQueries [$ authQueryName ]['password_verify_hash_column ' ] = $ authQueryConfig ['password_verify_hash_column ' ];
196+ $ this ->authQueries [$ authQueryName ]['password_verify_hash_column ' ] =
197+ $ authQueryConfig ['password_verify_hash_column ' ];
189198 }
190199 }
191200 } else {
192- throw new Exception ('Missing required attribute \'auth_queries \' for authentication source ' . $ this ->authId );
201+ throw new Exception (
202+ 'Missing required attribute \'auth_queries \' for authentication source ' .
203+ $ this ->authId ,
204+ );
193205 }
194206
195207 // attr_queries is optional, but if specified, we need to check the parameters
@@ -220,7 +232,7 @@ public function __construct(array $info, array $config)
220232 var_export ($ attrQueryConfig [$ param ], true ));
221233 }
222234 }
223-
235+
224236 $ currentAttributeQuery = [
225237 'database ' => $ attrQueryConfig ['database ' ],
226238 'query ' => $ attrQueryConfig ['query ' ],
@@ -258,6 +270,7 @@ public function __construct(array $info, array $config)
258270 }
259271 }
260272
273+
261274 /**
262275 * Create a database connection.
263276 *
@@ -273,17 +286,18 @@ protected function connect(string $dbname): PDO
273286 // Already connected
274287 return $ this ->databases [$ dbname ]['_pdo ' ];
275288 }
276-
289+
277290 try {
278291 $ db = new PDO (
279292 $ this ->databases [$ dbname ]['dsn ' ],
280293 $ this ->databases [$ dbname ]['username ' ],
281294 $ this ->databases [$ dbname ]['password ' ],
282- $ this ->databases [$ dbname ]['options ' ]
295+ $ this ->databases [$ dbname ]['options ' ],
283296 );
284297 } catch (PDOException $ e ) {
285298 // Obfuscate the password if it's part of the dsn
286- $ obfuscated_dsn = preg_replace ('/(user|password)=(.*?([;]|$))/ ' , '${1}=*** ' , $ this ->databases [$ dbname ]['dsn ' ]);
299+ $ obfuscated_dsn =
300+ preg_replace ('/(user|password)=(.*?([;]|$))/ ' , '${1}=*** ' , $ this ->databases [$ dbname ]['dsn ' ]);
287301
288302 throw new Exception ('sqlauth: ' . $ this ->authId . ': - Failed to connect to \'' .
289303 $ obfuscated_dsn . '\': ' . $ e ->getMessage ());
@@ -311,6 +325,7 @@ protected function connect(string $dbname): PDO
311325 return $ db ;
312326 }
313327
328+
314329 /**
315330 * Extract SQL columns into SAML attribute array
316331 *
@@ -347,6 +362,7 @@ protected function extractAttributes(array &$attributes, array $data, array $for
347362 return $ attributes ;
348363 }
349364
365+
350366 /**
351367 * Execute the query with given parameters and return the tuples that result.
352368 *
@@ -379,6 +395,7 @@ protected function executeQuery(PDO $db, string $query, array $params): array
379395 }
380396 }
381397
398+
382399 /**
383400 * Attempt to log in using the given username and password.
384401 *
@@ -404,7 +421,10 @@ protected function login(
404421 // Run authentication queries in order until one succeeds.
405422 foreach ($ this ->authQueries as $ queryname => &$ queryConfig ) {
406423 // Check if the username matches the username_regex for this query
407- if (array_key_exists ('username_regex ' , $ queryConfig ) && !preg_match ($ queryConfig ['username_regex ' ], $ username )) {
424+ if (
425+ array_key_exists ('username_regex ' , $ queryConfig ) &&
426+ !preg_match ($ queryConfig ['username_regex ' ], $ username )
427+ ) {
408428 Logger::debug ('sqlauth: ' . $ this ->authId . ': Skipping auth query ' . $ queryname .
409429 ' because username ' . $ username . ' does not match username_regex ' .
410430 $ queryConfig ['username_regex ' ]);
@@ -416,14 +436,12 @@ protected function login(
416436 $ db = $ this ->connect ($ queryConfig ['database ' ]);
417437
418438 try {
419- if (array_key_exists ('password_verify_hash_column ' , $ queryConfig )) {
420- // We will verify the password using password_verify() later, so we do not
421- // pass the password to the query.
422- $ data = $ this ->executeQuery ($ db , $ queryConfig ['query ' ], ['username ' => $ username ]);
423- } else {
424- // Pass both username and password to the query
425- $ data = $ this ->executeQuery ($ db , $ queryConfig ['query ' ], ['username ' => $ username , 'password ' => $ password ]);
439+ $ sqlParams = ['username ' => $ username ];
440+ if (!array_key_exists ('password_verify_hash_column ' , $ queryConfig )) {
441+ // If we are not using password_verify(), pass the password to the query
442+ $ sqlParams ['password ' ] = $ password ;
426443 }
444+ $ data = $ this ->executeQuery ($ db , $ queryConfig ['query ' ], $ sqlParams );
427445 } catch (PDOException $ e ) {
428446 Logger::error ('sqlauth: ' . $ this ->authId . ': Auth query ' . $ queryname .
429447 ' failed with error: ' . $ e ->getMessage ());
@@ -493,7 +511,6 @@ protected function login(
493511
494512 // The first auth query that succeeds is the winning one, so we can stop here.
495513 break ;
496-
497514 } else {
498515 Logger::debug ('sqlauth: ' . $ this ->authId . ': Auth query ' . $ queryname .
499516 ' returned no rows, trying next auth query if any ' );
@@ -510,17 +527,25 @@ protected function login(
510527 foreach ($ this ->attributesQueries as $ attrQueryConfig ) {
511528 // If the attribute query is limited to certain auth queries, check if the winning auth query
512529 // is one of those.
513- Logger::debug ('sqlauth: ' . $ this ->authId . ': Considering attribute query ' . $ attrQueryConfig ['query ' ] .
514- ' for winning auth query ' . $ winning_auth_query . ' with only_for_auth ' . implode (', ' , $ attrQueryConfig ['only_for_auth ' ] ?? []));
515- if ((!array_key_exists ('only_for_auth ' , $ attrQueryConfig )) || in_array ($ winning_auth_query , $ attrQueryConfig ['only_for_auth ' ], true )) {
530+ Logger::debug (
531+ 'sqlauth: ' . $ this ->authId . ': ' .
532+ 'Considering attribute query ' . $ attrQueryConfig ['query ' ] .
533+ ' for winning auth query ' . $ winning_auth_query .
534+ ' with only_for_auth ' . implode (', ' , $ attrQueryConfig ['only_for_auth ' ] ?? []),
535+ );
536+
537+ if (
538+ (!array_key_exists ('only_for_auth ' , $ attrQueryConfig )) ||
539+ in_array ($ winning_auth_query , $ attrQueryConfig ['only_for_auth ' ], true )
540+ ) {
516541 Logger::debug ('sqlauth: ' . $ this ->authId . ': Running attribute query ' . $ attrQueryConfig ['query ' ] .
517542 ' for winning auth query ' . $ winning_auth_query );
518543
519544 $ db = $ this ->connect ($ attrQueryConfig ['database ' ]);
520545
521546 try {
522- $ params = ($ this ->authQueries [$ winning_auth_query ]['_extracted_userid ' ] !== null ) ?
523- ['userid ' => $ this ->authQueries [$ winning_auth_query ]['_extracted_userid ' ]] :
547+ $ params = ($ this ->authQueries [$ winning_auth_query ]['_extracted_userid ' ] !== null ) ?
548+ ['userid ' => $ this ->authQueries [$ winning_auth_query ]['_extracted_userid ' ]] :
524549 ['username ' => $ username ];
525550 $ data = $ this ->executeQuery ($ db , $ attrQueryConfig ['query ' ], $ params );
526551 } catch (PDOException $ e ) {
0 commit comments