/Authentication/src/filters/openid/openid_file_store.php

https://github.com/F5/zetacomponents · PHP · 301 lines · 120 code · 33 blank · 148 comment · 12 complexity · 400a892ceb01db399e3034c0fe305ac6 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcAuthenticationOpenidFileStore class.
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  23. * @filesource
  24. * @package Authentication
  25. * @version //autogen//
  26. */
  27. /**
  28. * Class providing file storage for OpenID authentication.
  29. *
  30. * Example of use:
  31. * <code>
  32. * // create an OpenID options object
  33. * $options = new ezcAuthenticationOpenidOptions();
  34. * $options->mode = ezcAuthenticationOpenidFilter::MODE_SMART;
  35. *
  36. * // define a file store
  37. * $options->store = new ezcAuthenticationOpenidFileStore( '/tmp/store' );
  38. *
  39. * // create an OpenID filter based on the options object
  40. * $filter = new ezcAuthenticationOpenidFilter( $options );
  41. * </code>
  42. *
  43. * @property string $path
  44. * The path where the files will be kept. It must exist and it must
  45. * be writable.
  46. *
  47. * @package Authentication
  48. * @version //autogen//
  49. */
  50. class ezcAuthenticationOpenidFileStore extends ezcAuthenticationOpenidStore
  51. {
  52. /**
  53. * Holds the properties of this class.
  54. *
  55. * @var array(string=>mixed)
  56. */
  57. private $properties = array();
  58. /**
  59. * Creates a new object of this class.
  60. *
  61. * @throws ezcBaseFileNotFoundException
  62. * if $path does not exist
  63. * @throws ezcBaseFilePermissionException
  64. * if $path cannot be opened for reading and writing
  65. * @param string $path The path where to save the nonces
  66. * @param ezcAuthenticationOpenidFileStoreOptions $options Options for this class
  67. */
  68. public function __construct( $path, ezcAuthenticationOpenidFileStoreOptions $options = null )
  69. {
  70. $this->path = $path;
  71. $this->options = ( $options === null ) ? new ezcAuthenticationOpenidFileStoreOptions() : $options;
  72. }
  73. /**
  74. * Sets the property $name to $value.
  75. *
  76. * @throws ezcBasePropertyNotFoundException
  77. * if the property $name does not exist
  78. * @throws ezcBaseValueException
  79. * if $value is not correct for the property $name
  80. * @throws ezcBaseFileNotFoundException
  81. * if the $value file does not exist
  82. * @throws ezcBaseFilePermissionException
  83. * if the $value file cannot be opened for reading and writing
  84. * @param string $name The name of the property to set
  85. * @param mixed $value The new value of the property
  86. * @ignore
  87. */
  88. public function __set( $name, $value )
  89. {
  90. switch ( $name )
  91. {
  92. case 'path':
  93. if ( !is_string( $value ) )
  94. {
  95. throw new ezcBaseValueException( $name, $value, 'string' );
  96. }
  97. if ( !is_dir( $value ) )
  98. {
  99. throw new ezcBaseFileNotFoundException( $value );
  100. }
  101. if ( !is_readable( $value ) )
  102. {
  103. throw new ezcBaseFilePermissionException( $value, ezcBaseFileException::READ );
  104. }
  105. if ( !is_writable( $value ) )
  106. {
  107. throw new ezcBaseFilePermissionException( $value, ezcBaseFileException::WRITE );
  108. }
  109. $this->properties[$name] = $value;
  110. break;
  111. default:
  112. throw new ezcBasePropertyNotFoundException( $name );
  113. }
  114. }
  115. /**
  116. * Returns the value of the property $name.
  117. *
  118. * @throws ezcBasePropertyNotFoundException
  119. * if the property $name does not exist
  120. * @param string $name The name of the property for which to return the value
  121. * @return mixed
  122. * @ignore
  123. */
  124. public function __get( $name )
  125. {
  126. switch ( $name )
  127. {
  128. case 'path':
  129. return $this->properties[$name];
  130. default:
  131. throw new ezcBasePropertyNotFoundException( $name );
  132. }
  133. }
  134. /**
  135. * Returns true if the property $name is set, otherwise false.
  136. *
  137. * @param string $name The name of the property to test if it is set
  138. * @return bool
  139. * @ignore
  140. */
  141. public function __isset( $name )
  142. {
  143. switch ( $name )
  144. {
  145. case 'path':
  146. return isset( $this->properties[$name] );
  147. default:
  148. return false;
  149. }
  150. }
  151. /**
  152. * Stores the nonce in the store.
  153. *
  154. * Returns true if the nonce was stored successfully, and false otherwise.
  155. *
  156. * @throws ezcBaseFilePermissionException
  157. * if the nonce cannot be written in the store
  158. * @param string $nonce The nonce value to store
  159. * @return bool
  160. */
  161. public function storeNonce( $nonce )
  162. {
  163. $file = $this->path . DIRECTORY_SEPARATOR . $nonce;
  164. // suppress warnings caused by fopen() if $file could not be opened
  165. $fh = @fopen( $file, 'w' );
  166. if ( $fh === false )
  167. {
  168. throw new ezcBaseFilePermissionException( $file, ezcBaseFileException::WRITE );
  169. }
  170. fclose( $fh );
  171. return true;
  172. }
  173. /**
  174. * Checks if the nonce exists and afterwards deletes it.
  175. *
  176. * Returns the timestamp of the nonce if it exists, and false otherwise.
  177. *
  178. * @param string $nonce The nonce value to check and delete
  179. * @return bool|int
  180. */
  181. public function useNonce( $nonce )
  182. {
  183. $file = $this->path . DIRECTORY_SEPARATOR . $nonce;
  184. if ( !file_exists( $file ) )
  185. {
  186. return false;
  187. }
  188. $lastModified = filemtime( $file );
  189. unlink( $file );
  190. return $lastModified;
  191. }
  192. /**
  193. * Stores an association in the store linked to the OpenID provider URL.
  194. *
  195. * Returns true if the association was stored successfully, and false
  196. * otherwise.
  197. *
  198. * @throws ezcBaseFilePermissionException
  199. * if the nonce cannot be written in the store
  200. * @param string $url The URL of the OpenID provider
  201. * @param ezcAuthenticationOpenidAssociation $association The association value to store
  202. * @return bool
  203. */
  204. public function storeAssociation( $url, $association )
  205. {
  206. $file = $this->path . DIRECTORY_SEPARATOR . $this->convertToFilename( $url );
  207. // suppress warnings caused by fopen() if $file could not be opened
  208. $fh = @fopen( $file, 'w' );
  209. if ( $fh === false )
  210. {
  211. throw new ezcBaseFilePermissionException( $file, ezcBaseFileException::WRITE );
  212. }
  213. $data = serialize( $association );
  214. fwrite( $fh, $data );
  215. fclose( $fh );
  216. return true;
  217. }
  218. /**
  219. * Returns the unserialized association linked to the OpenID provider URL.
  220. *
  221. * Returns false if the association could not be retrieved or if it expired.
  222. *
  223. * @param string $url The URL of the OpenID provider
  224. * @return ezcAuthenticationOpenidAssociation
  225. */
  226. public function getAssociation( $url )
  227. {
  228. $file = $this->path . DIRECTORY_SEPARATOR . $this->convertToFilename( $url );
  229. if ( !file_exists( $file ) )
  230. {
  231. return false;
  232. }
  233. $data = unserialize( file_get_contents( $file ) );
  234. return $data;
  235. }
  236. /**
  237. * Removes the association linked to the OpenID provider URL.
  238. *
  239. * Returns true if the association could be removed, and false otherwise.
  240. *
  241. * @param string $url The URL of the OpenID provider
  242. * @return bool
  243. */
  244. public function removeAssociation( $url )
  245. {
  246. $file = $this->path . DIRECTORY_SEPARATOR . $this->convertToFilename( $url );
  247. if ( !file_exists( $file ) )
  248. {
  249. return false;
  250. }
  251. unlink( $file );
  252. return true;
  253. }
  254. /**
  255. * Creates a valid filename from the provided string.
  256. *
  257. * @param string $value A string which needs to be used as a valid filename
  258. * @return string
  259. */
  260. protected function convertToFilename( $value )
  261. {
  262. $result = base64_encode( $value );
  263. $result = str_replace( '/', '_', $result );
  264. $result = str_replace( '+', '-', $result );
  265. return $result;
  266. }
  267. }
  268. ?>