2323use YesWiki \Security \Controller \SecurityController ;
2424use YesWiki \Wiki ;
2525
26+ if (!function_exists ('send_mail ' )) {
27+ require_once 'includes/email.inc.php ' ;
28+ }
29+
2630class UserManager implements UserProviderInterface, PasswordUpgraderInterface
2731{
2832 protected $ wiki ;
@@ -33,6 +37,7 @@ class UserManager implements UserProviderInterface, PasswordUpgraderInterface
3337
3438 private $ getOneByNameCacheResults ;
3539
40+ public const KEY_VOCABULARY = 'http://outils-reseaux.org/_vocabulary/key ' ;
3641
3742 public function __construct (
3843 Wiki $ wiki ,
@@ -47,6 +52,7 @@ public function __construct(
4752 $ this ->securityController = $ securityController ;
4853 $ this ->params = $ params ;
4954 $ this ->getOneByNameCacheResults = [];
55+ $ this ->userlink = '' ;
5056 }
5157
5258 private function arrayToUser (?array $ userAsArray = null , bool $ fillEmpty = false ): ?User
@@ -176,6 +182,94 @@ public function create($wikiNameOrUser, string $email = "", string $plainPasswor
176182 );
177183 }
178184
185+ /*
186+ * Password recovery process (AKA reset password)
187+ * 1. A key is generated using name, email alongside with other stuff.
188+ * 2. The triple (user's name, specific key "vocabulary",key) is stored in triples table.
189+ * 3. In order to update h·er·is password, the user must provided that key.
190+ * 4. The new password is accepted only if the key matches with the value in triples table.
191+ * 5. The corresponding row is removed from triples table.
192+ */
193+
194+ protected function generateUserLink ($ user )
195+ {
196+ // Generate the password recovery key
197+ $ passwordHasher = $ this ->passwordHasherFactory ->getPasswordHasher ($ user );
198+ $ plainKey = $ user ['name ' ] . '_ ' . $ user ['email ' ] . random_int (0 , 10000 ) . date ('Y-m-d H:i:s ' );
199+ $ hashedKey = $ passwordHasher ->hash ($ plainKey );
200+ $ tripleStore = $ this ->wiki ->services ->get (TripleStore::class);
201+ // Erase the previous triples in the trible table
202+ $ tripleStore ->delete ($ user ['name ' ], self ::KEY_VOCABULARY , null , '' , '' );
203+ // Store the (name, vocabulary, key) triple in triples table
204+ $ tripleStore ->create ($ user ['name ' ], self ::KEY_VOCABULARY , $ hashedKey , '' , '' );
205+
206+ // Generate the recovery email
207+ $ this ->userlink = $ this ->wiki ->Href ('' , 'MotDePassePerdu ' , [
208+ 'a ' => 'recover ' ,
209+ 'email ' => $ hashedKey ,
210+ 'u ' => base64_encode ($ user ['name ' ]),
211+ ], false );
212+ }
213+
214+ /**
215+ * Part of the Password recovery process: Handles the password recovery email process.
216+ *
217+ * Generates the password recovery key
218+ * Stores the (name, vocabulary, key) triple in triples table
219+ * Generates the recovery email
220+ * Sends it
221+ *
222+ * @return bool True if OK or false if any problems
223+ */
224+ public function sendPasswordRecoveryEmail (User $ user , string $ title ): bool
225+ {
226+ $ this ->generateUserLink ($ user );
227+ $ pieces = parse_url ($ this ->params ->get ('base_url ' ));
228+ $ domain = isset ($ pieces ['host ' ]) ? $ pieces ['host ' ] : '' ;
229+
230+ $ message = _t ('LOGIN_DEAR ' ) . ' ' . $ user ['name ' ] . ", \n" ;
231+ $ message .= _t ('LOGIN_CLICK_FOLLOWING_LINK ' ) . ' : ' . "\n" ;
232+ $ message .= '----------------------- ' . "\n" ;
233+ $ message .= $ this ->userlink . "\n" ;
234+ $ message .= '----------------------- ' . "\n" ;
235+ $ message .= _t ('LOGIN_THE_TEAM ' ) . ' ' . $ domain . "\n" ;
236+
237+ $ subject = $ title . ' ' . $ domain ;
238+ // Send the email
239+ return send_mail ($ this ->params ->get ('BAZ_ADRESSE_MAIL_ADMIN ' ), $ this ->params ->get ('BAZ_ADRESSE_MAIL_ADMIN ' ), $ user ['email ' ], $ subject , $ message );
240+ }
241+
242+ /**
243+ * Assessor for userlink field.
244+ */
245+ public function getUserLink (): string
246+ {
247+ return $ this ->userlink ;
248+ }
249+
250+ /**
251+ * Assessor for userlink field.
252+ */
253+ public function getLastUserLink (User $ user ): string
254+ {
255+ $ passwordHasher = $ this ->passwordHasherFactory ->getPasswordHasher ($ user );
256+ $ plainKey = $ user ['name ' ] . '_ ' . $ user ['email ' ] . random_int (0 , 10000 ) . date ('Y-m-d H:i:s ' );
257+ $ hashedKey = $ passwordHasher ->hash ($ plainKey );
258+ $ tripleStore = $ this ->wiki ->services ->get (TripleStore::class);
259+ $ key = $ tripleStore ->getOne ($ user ['name ' ], self ::KEY_VOCABULARY , '' , '' );
260+ if ($ key != null ) {
261+ $ this ->userlink = $ this ->wiki ->Href ('' , 'MotDePassePerdu ' , [
262+ 'a ' => 'recover ' ,
263+ 'email ' => $ key ,
264+ 'u ' => base64_encode ($ user ['name ' ]),
265+ ], false );
266+ } else {
267+ $ this ->generateUserLink ($ user );
268+ }
269+
270+ return $ this ->userlink ;
271+ }
272+
179273 /**
180274 * update user params
181275 * for e-mail check is existing e-mail
0 commit comments