1919use Doctrine \DBAL \Statement ;
2020use OpenConext \EngineBlock \Metadata \Entity \ServiceProvider ;
2121use OpenConext \EngineBlock \Authentication \Value \ConsentType ;
22+ use OpenConext \EngineBlock \Service \Consent \ConsentHashServiceInterface ;
2223
2324class EngineBlock_Corto_Model_Consent
2425{
@@ -37,15 +38,10 @@ class EngineBlock_Corto_Model_Consent
3738 */
3839 private $ _response ;
3940 /**
40- * @var array
41+ * @var array All attributes as an associative array.
4142 */
4243 private $ _responseAttributes ;
4344
44- /**
45- * @var EngineBlock_Database_ConnectionFactory
46- */
47- private $ _databaseConnectionFactory ;
48-
4945 /**
5046 * A reflection of the eb.run_all_manipulations_prior_to_consent feature flag
5147 *
@@ -61,63 +57,59 @@ class EngineBlock_Corto_Model_Consent
6157 private $ _consentEnabled ;
6258
6359 /**
64- * @param string $tableName
65- * @param bool $mustStoreValues
66- * @param EngineBlock_Saml2_ResponseAnnotationDecorator $response
67- * @param array $responseAttributes
68- * @param EngineBlock_Database_ConnectionFactory $databaseConnectionFactory
60+ * @var ConsentHashServiceInterface
61+ */
62+ private $ _hashService ;
63+
64+ /**
6965 * @param bool $amPriorToConsentEnabled Is the run_all_manipulations_prior_to_consent feature enabled or not
70- * @param bool $consentEnabled Is the feature_enable_consent feature enabled or not
7166 */
7267 public function __construct (
73- $ tableName ,
74- $ mustStoreValues ,
68+ string $ tableName ,
69+ bool $ mustStoreValues ,
7570 EngineBlock_Saml2_ResponseAnnotationDecorator $ response ,
7671 array $ responseAttributes ,
77- EngineBlock_Database_ConnectionFactory $ databaseConnectionFactory ,
78- $ amPriorToConsentEnabled ,
79- $ consentEnabled
80- )
81- {
72+ bool $ amPriorToConsentEnabled ,
73+ bool $ consentEnabled ,
74+ ConsentHashServiceInterface $ hashService
75+ ) {
8276 $ this ->_tableName = $ tableName ;
8377 $ this ->_mustStoreValues = $ mustStoreValues ;
8478 $ this ->_response = $ response ;
8579 $ this ->_responseAttributes = $ responseAttributes ;
86- $ this ->_databaseConnectionFactory = $ databaseConnectionFactory ;
8780 $ this ->_amPriorToConsentEnabled = $ amPriorToConsentEnabled ;
81+ $ this ->_hashService = $ hashService ;
8882 $ this ->_consentEnabled = $ consentEnabled ;
8983 }
9084
91- public function explicitConsentWasGivenFor (ServiceProvider $ serviceProvider )
85+ public function explicitConsentWasGivenFor (ServiceProvider $ serviceProvider ): bool
9286 {
9387 return !$ this ->_consentEnabled ||
9488 $ this ->_hasStoredConsent ($ serviceProvider , ConsentType::TYPE_EXPLICIT );
9589 }
9690
97- public function implicitConsentWasGivenFor (ServiceProvider $ serviceProvider )
91+ public function implicitConsentWasGivenFor (ServiceProvider $ serviceProvider ): bool
9892 {
9993 return !$ this ->_consentEnabled ||
10094 $ this ->_hasStoredConsent ($ serviceProvider , ConsentType::TYPE_IMPLICIT );
10195 }
10296
103- public function giveExplicitConsentFor (ServiceProvider $ serviceProvider )
97+ public function giveExplicitConsentFor (ServiceProvider $ serviceProvider ): bool
10498 {
10599 return !$ this ->_consentEnabled ||
106100 $ this ->_storeConsent ($ serviceProvider , ConsentType::TYPE_EXPLICIT );
107101 }
108102
109- public function giveImplicitConsentFor (ServiceProvider $ serviceProvider )
103+ public function giveImplicitConsentFor (ServiceProvider $ serviceProvider ): bool
110104 {
111105 return !$ this ->_consentEnabled ||
112106 $ this ->_storeConsent ($ serviceProvider , ConsentType::TYPE_IMPLICIT );
113107 }
114108
115- /**
116- * @return Doctrine\DBAL\Connection
117- */
118- protected function _getConsentDatabaseConnection ()
109+ public function countTotalConsent (): int
119110 {
120- return $ this ->_databaseConnectionFactory ->create ();
111+ $ consentUid = $ this ->_getConsentUid ();
112+ return $ this ->_hashService ->countTotalConsent ($ consentUid );
121113 }
122114
123115 protected function _getConsentUid ()
@@ -129,116 +121,55 @@ protected function _getConsentUid()
129121 return $ this ->_response ->getNameIdValue ();
130122 }
131123
132- protected function _getAttributesHash ($ attributes )
124+ protected function _getAttributesHash ($ attributes ): string
133125 {
134- $ hashBase = NULL ;
135- if ($ this ->_mustStoreValues ) {
136- ksort ($ attributes );
137- $ hashBase = serialize ($ attributes );
138- } else {
139- $ names = array_keys ($ attributes );
140- sort ($ names );
141- $ hashBase = implode ('| ' , $ names );
142- }
143- return sha1 ($ hashBase );
126+ return $ this ->_hashService ->getUnstableAttributesHash ($ attributes , $ this ->_mustStoreValues );
144127 }
145128
146- private function _storeConsent ( ServiceProvider $ serviceProvider , $ consentType )
129+ protected function _getStableAttributesHash ( $ attributes ): string
147130 {
148- $ dbh = $ this ->_getConsentDatabaseConnection ();
149- if (!$ dbh ) {
150- return false ;
151- }
131+ return $ this ->_hashService ->getStableAttributesHash ($ attributes , $ this ->_mustStoreValues );
132+ }
152133
134+ private function _storeConsent (ServiceProvider $ serviceProvider , $ consentType ): bool
135+ {
153136 $ consentUuid = $ this ->_getConsentUid ();
154- if (! is_string ($ consentUuid )){
137+ if (! is_string ($ consentUuid )) {
155138 return false ;
156139 }
157140
158- $ query = "INSERT INTO consent (hashed_user_id, service_id, attribute, consent_type, consent_date, deleted_at)
159- VALUES (?, ?, ?, ?, NOW(), '0000-00-00 00:00:00')
160- ON DUPLICATE KEY UPDATE attribute=VALUES(attribute), consent_type=VALUES(consent_type), consent_date=NOW() " ;
161141 $ parameters = array (
162142 sha1 ($ consentUuid ),
163143 $ serviceProvider ->entityId ,
164- $ this ->_getAttributesHash ($ this ->_responseAttributes ),
144+ $ this ->_getStableAttributesHash ($ this ->_responseAttributes ),
165145 $ consentType ,
166146 );
167147
168- $ statement = $ dbh ->prepare ($ query );
169- if (!$ statement ) {
170- throw new EngineBlock_Exception (
171- "Unable to create a prepared statement to insert consent?! " ,
172- EngineBlock_Exception::CODE_CRITICAL
173- );
174- }
175-
176- assert ($ statement instanceof Statement);
177- try {
178- foreach ($ parameters as $ index => $ parameter ){
179- $ statement ->bindValue ($ index + 1 , $ parameter );
180- }
181-
182- $ statement ->executeStatement ();
183- }catch (\Doctrine \DBAL \Exception $ e ){
184- throw new EngineBlock_Corto_Module_Services_Exception (
185- sprintf ('Error storing consent: "%s" ' , var_export ($ e ->getMessage (), true )),
186- EngineBlock_Exception::CODE_CRITICAL
187- );
188- }
189- return true ;
148+ return $ this ->_hashService ->storeConsentHash ($ parameters );
190149 }
191150
192- private function _hasStoredConsent (ServiceProvider $ serviceProvider , $ consentType )
151+ private function _hasStoredConsent (ServiceProvider $ serviceProvider , $ consentType ): bool
193152 {
194- try {
195- $ dbh = $ this ->_getConsentDatabaseConnection ();
196- if (!$ dbh ) {
197- return false ;
198- }
199-
200- $ attributesHash = $ this ->_getAttributesHash ($ this ->_responseAttributes );
201-
202- $ consentUuid = $ this ->_getConsentUid ();
203- if (!is_string ($ consentUuid )) {
204- return false ;
205- }
206-
207- $ query = "
208- SELECT *
209- FROM {$ this ->_tableName }
210- WHERE hashed_user_id = ?
211- AND service_id = ?
212- AND attribute = ?
213- AND consent_type = ?
214- AND deleted_at IS NULL
215- " ;
216- $ hashedUserId = sha1 ($ consentUuid );
217- $ parameters = array (
218- $ hashedUserId ,
219- $ serviceProvider ->entityId ,
220- $ attributesHash ,
221- $ consentType ,
222- );
223-
224- $ statement = $ dbh ->prepare ($ query );
225- assert ($ statement instanceof Statement);
226- foreach ($ parameters as $ position => $ parameter ) {
227- $ statement ->bindValue ($ position + 1 , $ parameter );
228- }
229- $ rows = $ statement ->executeQuery ();
230-
231- if ($ rows ->rowCount () < 1 ) {
232- // No stored consent found
233- return false ;
234- }
153+ $ parameters = array (
154+ sha1 ($ this ->_getConsentUid ()),
155+ $ serviceProvider ->entityId ,
156+ $ this ->_getAttributesHash ($ this ->_responseAttributes ),
157+ $ consentType ,
158+ );
159+
160+ $ hasUnstableConsentHash = $ this ->_hashService ->retrieveConsentHash ($ parameters );
235161
162+ if ($ hasUnstableConsentHash ) {
236163 return true ;
237- } catch (PDOException $ e ) {
238- throw new EngineBlock_Corto_ProxyServer_Exception (
239- sprintf ('Consent retrieval failed! Error: "%s" ' , $ e ->getMessage ()),
240- EngineBlock_Exception::CODE_ALERT
241- );
242164 }
165+
166+ $ parameters [2 ] = array (
167+ sha1 ($ this ->_getConsentUid ()),
168+ $ serviceProvider ->entityId ,
169+ $ this ->_getStableAttributesHash ($ this ->_responseAttributes ),
170+ $ consentType ,
171+ );
172+
173+ return $ this ->_hashService ->retrieveConsentHash ($ parameters );
243174 }
244175}
0 commit comments