Permalink
Browse files

Extended ExistingUserException to carry a user if passed, making sure…

… there can only be one user with given email
  • Loading branch information...
sergeychernyshev committed May 23, 2016
1 parent 712db6a commit b4904920a747dad30166fad844a062c3c8a4e339
Showing with 80 additions and 30 deletions.
  1. +19 −0 classes/AuthenticationModule.php
  2. +37 −18 classes/User.php
  3. +1 −1 edit.php
  4. +6 −4 modules/email/index.php
  5. +8 −2 modules/facebook/index.php
  6. +9 −5 modules/usernamepass/index.php
@@ -304,7 +304,26 @@ class InputValidationException extends AuthenticationException {
* @subpackage Authentication
*/
class ExistingUserException extends AuthenticationException {
+ /**
+ * User that was found to already exist.
+ * Can be null if we just know that user exists, but did not get object specifically.
+ *
+ * @var User|null Existing user or null if we just know that user exists, but did not get object specifically.
+ */
+ private $existing_user;
+
+ public function __construct(User $user = null, $string, $code, $errors) {
+ parent::__construct($user, $string, $code, $errors);
+ $this->existing_user = $user;
+ }
+ /**
+ * Returns existing user or null
+ * @return User|null Existing user or null if we just know that user exists, but did not get object specifically.
+ */
+ public function getExistingUser() {
+ return $this->existing_user;
+ }
}
/**
View
@@ -627,6 +627,29 @@ public static function verifyEmailLinkCode($code, User $user = null) {
return $verified;
}
+ public function getEmailVerificationCode() {
+ $code = substr(base64_encode(mcrypt_create_iv(50, MCRYPT_DEV_URANDOM)), 0, 10);
+
+ if ($stmt = $db->prepare('UPDATE u_users SET
+ email_verification_code = ?,
+ email_verification_code_time = now()
+ WHERE id = ?')
+ ) {
+ if (!$stmt->bind_param('si', $code, $this->userid)) {
+ throw new DBBindParamException($db, $stmt);
+ }
+ if (!$stmt->execute()) {
+ throw new DBExecuteStmtException($db, $stmt);
+ }
+
+ $stmt->close();
+ } else {
+ throw new DBPrepareStmtException($db);
+ }
+
+ return $code;
+ }
+
/**
* Sends email verification emai to user's email address
*
@@ -645,23 +668,7 @@ public function sendEmailVerificationCode() {
$db = UserConfig::getDB();
- $code = substr(base64_encode(mcrypt_create_iv(50, MCRYPT_DEV_URANDOM)), 0, 10);
-
- if ($stmt = $db->prepare('UPDATE u_users SET
- email_verification_code = ?,
- email_verification_code_time = now()
- WHERE id = ?')) {
- if (!$stmt->bind_param('si', $code, $this->userid)) {
- throw new DBBindParamException($db, $stmt);
- }
- if (!$stmt->execute()) {
- throw new DBExecuteStmtException($db, $stmt);
- }
-
- $stmt->close();
- } else {
- throw new DBPrepareStmtException($db);
- }
+ $code = $this->getEmailVerificationCode();
$verification_link = UserConfig::$USERSROOTFULLURL . '/verify_email.php?code=' . urlencode($code);
@@ -733,6 +740,11 @@ public static function createNewFacebookUser($name, $fb_id, $me = null) {
$email = $me['email'];
}
+ $existing_users = User::getUsersByEmailOrUsername($email);
+ if (count($existing_users) > 0) {
+ throw new ExistingUserException($existing_users[0]);
+ }
+
$user = null;
if ($stmt = $db->prepare("INSERT INTO u_users (name, regmodule, tos_version, email, fb_id) VALUES (?, 'facebook', ?, ?, ?)")) {
@@ -1657,7 +1669,8 @@ public static function getUsersByActivity($activityid, $pagenumber = 0, $perpage
/**
* Return a list of users who match a username or email
*
- * Used to retrieve user based on a login form, can return multiple objects
+ * Used to retrieve user based on a login form.
+ * @TODO CONFIRM that this call can return multiple objects, including users with unverified emails.
*
* @param string $nameoremail String with username or email address
*
@@ -2373,6 +2386,12 @@ public function getEmail() {
*/
public function setEmail($email) {
if ($this->email != $email) {
+ // Checking if there are other users with this email
+ $existing_users = User::getUsersByEmailOrUsername($email);
+ if (count($existing_users) > 0) {
+ throw new ExistingUserException($existing_users[0]);
+ }
+
$this->setEmailVerified(false);
}
View
@@ -75,7 +75,7 @@
if ((!array_key_exists('profile-info', $errors) || !array_key_exists('email', $errors['profile-info'])) &&
(count($existing_users) > 0 && !$existing_users[0]->isTheSameAs($user))
) {
- $errors['profile-info']['email'][] = "This email is already used by another user, please enter another email address.";
+ $errors['profile-info']['email'][] = "This email is already used by another user, please enter a different email address.";
}
if (!array_key_exists('profile-info', $errors) || count($errors['profile-info']) == 0) {
View
@@ -230,12 +230,14 @@ public function processRegistration($data, &$remember) {
throw new InputValidationException('Validation failed', 0, $errors);
}
- if (count(User::getUsersByEmailOrUsername($email)) > 0) {
- $errors['email'][] = "This email is already used by another user, please enter another email address.";
+ $existing_users = User::getUsersByEmailOrUsername($email);
+
+ if (count($existing_users) > 0) {
+ $errors['email'][] = "This email is already used by another user, please enter a different email address.";
}
if (count($errors) > 0) {
- throw new ExistingUserException('User already exists', 0, $errors);
+ throw new ExistingUserException($existing_users[0], 'User already exists', 0, $errors);
}
// ok, let's create a user
@@ -290,7 +292,7 @@ public function processEditUser($user, $data) {
if (!array_key_exists('email', $errors) &&
(count($existing_users) > 0 && !$existing_users[0]->isTheSameAs($user))
) {
- $errors['email'][] = "This email is already used by another user, please enter another email address.";
+ $errors['email'][] = "This email is already used by another user, please enter a different email address.";
}
if (count($errors) > 0) {
View
@@ -377,6 +377,7 @@ public function processRegistration($post_data, &$remember) {
if (array_key_exists('name', $me)) {
$name = $me['name'];
} else {
+ // @TODO Revise this check to show appropriate message when FB user doesn't have a name
$errors['username'][] = "User doesn't have a name";
}
@@ -388,7 +389,8 @@ public function processRegistration($post_data, &$remember) {
}
if (count($errors) > 0) {
- throw new ExistingUserException('User already exists', 0, $errors);
+ // @TODO figure out what to throw here and send appropriate exception
+ throw new ExistingUserException(null, 'User already exists', 0, $errors);
}
$user->recordActivity(USERBASE_ACTIVITY_REGISTER_FB);
@@ -440,7 +442,11 @@ public function processEditUser($user, $data) {
}
if (array_key_exists('email', $me)) {
- $user->setEmail($me['email']);
+ try {
+ $user->setEmail($me['email']);
+ } catch (ExistingUserException $ex) {
+ // @TODO find existing users with such emai address and merge accounts???
+ }
}
}
@@ -258,16 +258,20 @@ public function processRegistration($data, &$remember)
throw new InputValidationException('Validation failed', 0, $errors);
}
- if (count(User::getUsersByEmailOrUsername($username)) > 0 ) {
+ $existing_usernames = User::getUsersByEmailOrUsername($username);
+ if (count($existing_usernames) > 0 ) {
$errors['username'][] = "This username is already used, please pick another one";
}
- if (count(User::getUsersByEmailOrUsername($email)) > 0 ) {
- $errors['email'][] = "This email is already used by another user, please enter another email address.";
+
+ $existing_emails = User::getUsersByEmailOrUsername($email);
+ if (count($existing_emails) > 0 ) {
+ $errors['email'][] = "This email is already used by another user, please enter a different email address.";
}
- if (count($errors) > 0)
+ $existing_users = array_merge($existing_usernames, $existing_emails);
+ if (count($existing_users) > 0)
{
- throw new ExistingUserException('User already exists', 0, $errors);
+ throw new ExistingUserException($existing_users[0], 'User already exists', 0, $errors);
}
// ok, let's create a user

0 comments on commit b490492

Please sign in to comment.