49 assert(is_array(
$info));
56 foreach (array(
'dsn',
'username',
'password',
'query') as $param) {
57 if (!array_key_exists($param,
$config)) {
58 throw new Exception(
'Missing required attribute \'' . $param .
59 '\' for authentication source
' . $this->authId);
62 if (!is_string($config[$param])) {
63 throw new Exception('Expected parameter \
'' . $param .
64 '\' for authentication source
' . $this->authId .
65 ' to be a
string. Instead it was:
' .
66 var_export($config[$param], true));
70 $this->dsn = $config['dsn
'];
71 $this->username = $config['username
'];
72 $this->password = $config['password
'];
73 $this->query = $config['query
'];
74 if (isset($config['options
'])) {
75 $this->options = $config['options
'];
85 private function connect()
88 $db = new PDO($this->dsn, $this->username, $this->password, $this->options);
89 } catch (PDOException $e) {
90 throw new Exception('sqlauth:
' . $this->authId . ': - Failed to
connect to \
'' .
91 $this->dsn .
'\':
'. $e->getMessage());
94 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
96 $driver = explode(':
', $this->dsn, 2);
97 $driver = strtolower($driver[0]);
99 /* Driver specific initialization. */
103 $db->exec("SET NAMES 'utf8mb4
'");
107 $db->exec("SET NAMES 'UTF8
'");
128 protected function login($username, $password)
130 assert(is_string($username));
131 assert(is_string($password));
133 $db = $this->connect();
136 $sth = $db->prepare($this->query);
137 } catch (PDOException $e) {
138 throw new Exception('sqlauth:
' . $this->authId .
139 ': - Failed to prepare query:
' . $e->getMessage());
143 $sth->execute(array('username
' => $username, 'password
' => $password));
144 } catch (PDOException $e) {
145 throw new Exception('sqlauth:
' . $this->authId .
146 ': - Failed to execute query:
' . $e->getMessage());
150 $data = $sth->fetchAll(PDO::FETCH_ASSOC);
151 } catch (PDOException $e) {
152 throw new Exception('sqlauth:
' . $this->authId .
153 ': - Failed to fetch result
set:
' . $e->getMessage());
156 SimpleSAML\Logger::info('sqlauth:
' . $this->authId . ': Got
' . count($data) .
157 ' rows from database
');
159 if (count($data) === 0) {
160 /* No rows returned - invalid username/password. */
161 SimpleSAML\Logger::error('sqlauth:
' . $this->authId .
162 ': No rows in result
set. Probably wrong username/password.
');
163 throw new SimpleSAML_Error_Error('WRONGUSERPASS
');
166 /* Extract attributes. We allow the resultset to consist of multiple rows. Attributes
167 * which are present in more than one row will become multivalued. null values and
168 * duplicate values will be skipped. All values will be converted to strings.
170 $attributes = array();
171 foreach ($data as $row) {
172 foreach ($row as $name => $value) {
174 if ($value === null) {
178 $value = (string)$value;
180 if (!array_key_exists($name, $attributes)) {
181 $attributes[$name] = array();
184 if (in_array($value, $attributes[$name], true)) {
185 /* Value already exists in attribute. */
189 $attributes[$name][] = $value;
193 SimpleSAML\Logger::info('sqlauth:
' . $this->authId . ': Attributes:
' .
194 implode(',
', array_keys($attributes)));
An exception for terminatinating execution or to throw for unit testing.
$password
The password we should connect to the database with.
$options
The options that we should connect to the database with.
$query
The query we should use to retrieve the attributes for the user.
connect()
Create a database connection.
$username
The username we should connect to the database with.
$dsn
The DSN we should connect to.
__construct($info, $config)
Constructor for this authentication source.