ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
MetaDataStorageHandlerPdo.php
Go to the documentation of this file.
1 <?php
2 
3 
14 {
15 
19  private $db;
20 
24  private $tablePrefix;
25 
29  private $cachedMetadata = array();
30 
34  public $supportedSets = array(
35  'adfs-idp-hosted',
36  'adfs-sp-remote',
37  'saml20-idp-hosted',
38  'saml20-idp-remote',
39  'saml20-sp-remote',
40  'shib13-idp-hosted',
41  'shib13-idp-remote',
42  'shib13-sp-hosted',
43  'shib13-sp-remote',
44  'wsfed-idp-remote',
45  'wsfed-sp-hosted'
46  );
47 
48 
60  public function __construct($config)
61  {
62  assert(is_array($config));
63 
65  }
66 
67 
80  private function load($set)
81  {
82  assert(is_string($set));
83 
84  $tableName = $this->getTableName($set);
85 
86  if (!in_array($set, $this->supportedSets, true)) {
87  return null;
88  }
89 
90  $stmt = $this->db->read("SELECT entity_id, entity_data FROM $tableName");
91  if ($stmt->execute()) {
92  $metadata = array();
93 
94  while ($d = $stmt->fetch()) {
95  $data = json_decode($d['entity_data'], true);
96  if ($data === null) {
97  throw new SimpleSAML_Error_Exception("Cannot decode metadata for entity '${d['entity_id']}'");
98  }
99  if (!array_key_exists('entityid', $data)) {
100  $data['entityid'] = $d['entity_id'];
101  }
102  $metadata[$d['entity_id']] = $data;
103  }
104 
105  return $metadata;
106  } else {
107  throw new Exception('PDO metadata handler: Database error: '.var_export($this->db->getLastError(), true));
108  }
109  }
110 
111 
119  public function getMetadataSet($set)
120  {
121  assert(is_string($set));
122 
123  if (array_key_exists($set, $this->cachedMetadata)) {
124  return $this->cachedMetadata[$set];
125  }
126 
127  $metadataSet = $this->load($set);
128  if ($metadataSet === null) {
129  $metadataSet = array();
130  }
131 
132  foreach ($metadataSet as $entityId => &$entry) {
133  if (preg_match('/__DYNAMIC(:[0-9]+)?__/', $entityId)) {
134  $entry['entityid'] = $this->generateDynamicHostedEntityID($set);
135  } else {
136  $entry['entityid'] = $entityId;
137  }
138  }
139 
140  $this->cachedMetadata[$set] = $metadataSet;
141  return $metadataSet;
142  }
143 
153  public function getMetaData($entityId, $set)
154  {
155  assert(is_string($entityId));
156  assert(is_string($set));
157 
158  $tableName = $this->getTableName($set);
159 
160  if (!in_array($set, $this->supportedSets, true)) {
161  return null;
162  }
163 
164  $stmt = $this->db->read("SELECT entity_id, entity_data FROM $tableName WHERE entity_id=:entityId", array('entityId' => $entityId));
165  if ($stmt->execute()) {
166  $rowCount = 0;
167  $data = null;
168 
169  while ($d = $stmt->fetch()) {
170  if (++$rowCount > 1) {
171  SimpleSAML\Logger::warning("Duplicate match for $entityId in set $set");
172  break;
173  }
174  $data = json_decode($d['entity_data'], true);
175  if ($data === null) {
176  throw new SimpleSAML_Error_Exception("Cannot decode metadata for entity '${d['entity_id']}'");
177  }
178  if (!array_key_exists('entityid', $data)) {
179  $data['entityid'] = $d['entity_id'];
180  }
181  }
182  return $data;
183  } else {
184  throw new Exception('PDO metadata handler: Database error: '.var_export($this->db->getLastError(), true));
185  }
186  }
187 
188  private function generateDynamicHostedEntityID($set)
189  {
190  assert(is_string($set));
191 
192  // get the configuration
194 
195  if ($set === 'saml20-idp-hosted') {
196  return $baseurl.'saml2/idp/metadata.php';
197  } elseif ($set === 'saml20-sp-hosted') {
198  return $baseurl.'saml2/sp/metadata.php';
199  } elseif ($set === 'shib13-idp-hosted') {
200  return $baseurl.'shib13/idp/metadata.php';
201  } elseif ($set === 'shib13-sp-hosted') {
202  return $baseurl.'shib13/sp/metadata.php';
203  } elseif ($set === 'wsfed-sp-hosted') {
204  return 'urn:federation:'.\SimpleSAML\Utils\HTTP::getSelfHost();
205  } elseif ($set === 'adfs-idp-hosted') {
206  return 'urn:federation:'.\SimpleSAML\Utils\HTTP::getSelfHost().':idp';
207  } else {
208  throw new Exception('Can not generate dynamic EntityID for metadata of this type: ['.$set.']');
209  }
210  }
211 
212 
222  public function addEntry($index, $set, $entityData)
223  {
224  assert(is_string($index));
225  assert(is_string($set));
226  assert(is_array($entityData));
227 
228  if (!in_array($set, $this->supportedSets, true)) {
229  return false;
230  }
231 
232  $tableName = $this->getTableName($set);
233 
234  $metadata = $this->db->read(
235  "SELECT entity_id, entity_data FROM $tableName WHERE entity_id = :entity_id",
236  array(
237  'entity_id' => $index,
238  )
239  );
240 
241  $retrivedEntityIDs = $metadata->fetch();
242 
243  $params = array(
244  'entity_id' => $index,
245  'entity_data' => json_encode($entityData),
246  );
247 
248  if ($retrivedEntityIDs !== false && count($retrivedEntityIDs) > 0) {
249  $rows = $this->db->write(
250  "UPDATE $tableName SET entity_data = :entity_data WHERE entity_id = :entity_id",
251  $params
252  );
253  } else {
254  $rows = $this->db->write(
255  "INSERT INTO $tableName (entity_id, entity_data) VALUES (:entity_id, :entity_data)",
256  $params
257  );
258  }
259 
260  return $rows === 1;
261  }
262 
263 
272  private function getTableName($table)
273  {
274  assert(is_string($table));
275 
276  return $this->db->applyPrefix(str_replace("-", "_", $this->tablePrefix.$table));
277  }
278 
279 
285  public function initDatabase()
286  {
287  $stmt = 0;
288  $fine = true;
289  foreach ($this->supportedSets as $set) {
290  $tableName = $this->getTableName($set);
291  $rows = $this->db->write(
292  "CREATE TABLE IF NOT EXISTS $tableName (entity_id VARCHAR(255) PRIMARY KEY NOT NULL, entity_data ".
293  "TEXT NOT NULL)"
294  );
295  if ($rows === 0) {
296  $fine = false;
297  } else {
298  $stmt += $rows;
299  }
300  }
301  if (!$fine) {
302  return false;
303  }
304  return $stmt;
305  }
306 }
getTableName($table)
Replace the -&#39;s to an _ in table names for Metadata sets since SQL does not allow a - in a table name...
static getInstance($altConfig=null)
Retrieves the current database instance.
Definition: Database.php:55
$config
Definition: bootstrap.php:15
$stmt
addEntry($index, $set, $entityData)
Add metadata to the configured database.
$index
Definition: metadata.php:60
__construct($config)
This constructor initializes the PDO metadata storage handler with the specified configuration.
$metadata['__DYNAMIC:1__']
getMetadataSet($set)
Retrieve a list of all available metadata for a given set.
$supportedSets
All the metadata sets supported by this MetaDataStorageHandler.
static warning($string)
Definition: Logger.php:177
initDatabase()
Initialize the configured database.
$tablePrefix
Prefix to apply to the metadata table.
load($set)
This function loads the given set of metadata from a file to a configured database.
if($source===null) if(!($source instanceof sspmod_saml_Auth_Source_SP)) $entityId
Definition: metadata.php:22
$rows
Definition: xhr_table.php:10
if(empty($password)) $table
Definition: pwgen.php:24
getMetaData($entityId, $set)
Retrieve a metadata entry.
static getBaseURL()
Retrieve the base URL of the SimpleSAMLphp installation.
Definition: HTTP.php:597
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$cachedMetadata
This is an associative array which stores the different metadata sets we have loaded.
$data
Definition: bench.php:6