X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FUser.php;h=41d26ee19d66f4c27d3b3a885f086564d9e466c0;hb=7d6b1264ec038bc9c3917bc933ba8d02bedadcbc;hp=382ec62cc2780920d2697f88944bb30e1508f364;hpb=986e22d9e17dafeb3ca46daf5abc942c1f1c2510;p=friendica.git diff --git a/src/Model/User.php b/src/Model/User.php index 382ec62cc2..41d26ee19d 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1,14 +1,14 @@ $user_info, - 'blocked' => 0, - 'account_expired' => 0, - 'account_removed' => 0, - 'verified' => 1 - ] - ); - } elseif (is_string($user_info)) { - $user = dba::fetch_first('SELECT `uid`, `password` - FROM `user` - WHERE (`email` = ? OR `username` = ? OR `nickname` = ?) - AND `blocked` = 0 - AND `account_expired` = 0 - AND `account_removed` = 0 - AND `verified` = 1 - LIMIT 1', - $user_info, - $user_info, - $user_info - ); - } else { - $user = $user_info; - } + $user = null; - if (!DBM::is_result($user) || !isset($user['uid']) || !isset($user['password'])) { - return false; - } + if (is_object($user_info) || is_array($user_info)) { + if (is_object($user_info)) { + $user = (array) $user_info; + } else { + $user = $user_info; + } - $password_hashed = self::hashPassword($password); + if (!isset($user['uid']) + || !isset($user['password']) + || !isset($user['legacy_password']) + ) { + throw new Exception(L10n::t('Not enough information to authenticate')); + } + } elseif (is_int($user_info) || is_string($user_info)) { + if (is_int($user_info)) { + $user = dba::selectFirst('user', ['uid', 'password', 'legacy_password'], + [ + 'uid' => $user_info, + 'blocked' => 0, + 'account_expired' => 0, + 'account_removed' => 0, + 'verified' => 1 + ] + ); + } else { + $user = dba::fetch_first('SELECT `uid`, `password`, `legacy_password` + FROM `user` + WHERE (`email` = ? OR `username` = ? OR `nickname` = ?) + AND `blocked` = 0 + AND `account_expired` = 0 + AND `account_removed` = 0 + AND `verified` = 1 + LIMIT 1', + $user_info, + $user_info, + $user_info + ); + } - if ($password_hashed !== $user['password']) { - return false; + if (!DBM::is_result($user)) { + throw new Exception(L10n::t('User not found')); + } } - return $user['uid']; + return $user; } /** @@ -162,16 +229,42 @@ class User } /** - * Global user password hashing function + * Checks if the provided plaintext password has been exposed or not + * + * @param string $password + * @return bool + */ + public static function isPasswordExposed($password) + { + return password_exposed($password) === PasswordStatus::EXPOSED; + } + + /** + * Legacy hashing function, kept for password migration purposes * * @param string $password * @return string */ - private static function hashPassword($password) + private static function hashPasswordLegacy($password) { return hash('whirlpool', $password); } + /** + * Global user password hashing function + * + * @param string $password + * @return string + */ + public static function hashPassword($password) + { + if (!trim($password)) { + throw new Exception(L10n::t('Password can\'t be empty')); + } + + return password_hash($password, PASSWORD_DEFAULT); + } + /** * Updates a user row with a new plaintext password * @@ -197,7 +290,8 @@ class User $fields = [ 'password' => $pasword_hashed, 'pwdreset' => null, - 'pwdreset_time' => null + 'pwdreset_time' => null, + 'legacy_password' => false ]; return dba::update('user', $fields, ['uid' => $uid]); } @@ -242,30 +336,30 @@ class User $netpublish = strlen(Config::get('system', 'directory')) ? $publish : 0; if ($password1 != $confirm) { - throw new Exception(t('Passwords do not match. Password unchanged.')); + throw new Exception(L10n::t('Passwords do not match. Password unchanged.')); } elseif ($password1 != '') { $password = $password1; } if ($using_invites) { if (!$invite_id) { - throw new Exception(t('An invitation is required.')); + throw new Exception(L10n::t('An invitation is required.')); } if (!dba::exists('register', ['hash' => $invite_id])) { - throw new Exception(t('Invitation could not be verified.')); + throw new Exception(L10n::t('Invitation could not be verified.')); } } if (!x($username) || !x($email) || !x($nickname)) { if ($openid_url) { - if (!validate_url($openid_url)) { - throw new Exception(t('Invalid OpenID url')); + if (!Network::isUrlValid($openid_url)) { + throw new Exception(L10n::t('Invalid OpenID url')); } $_SESSION['register'] = 1; $_SESSION['openid'] = $openid_url; - $openid = new \LightOpenID; + $openid = new LightOpenID; $openid->identity = $openid_url; $openid->returnUrl = System::baseUrl() . '/openid'; $openid->required = ['namePerson/friendly', 'contact/email', 'namePerson']; @@ -273,16 +367,16 @@ class User try { $authurl = $openid->authUrl(); } catch (Exception $e) { - throw new Exception(t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . EOL . EOL . t('The error message was:') . $e->getMessage(), 0, $e); + throw new Exception(L10n::t('We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID.') . EOL . EOL . L10n::t('The error message was:') . $e->getMessage(), 0, $e); } goaway($authurl); // NOTREACHED } - throw new Exception(t('Please enter the required information.')); + throw new Exception(L10n::t('Please enter the required information.')); } - if (!validate_url($openid_url)) { + if (!Network::isUrlValid($openid_url)) { $openid_url = ''; } @@ -292,10 +386,10 @@ class User $username = preg_replace('/ +/', ' ', $username); if (mb_strlen($username) > 48) { - throw new Exception(t('Please use a shorter name.')); + throw new Exception(L10n::t('Please use a shorter name.')); } if (mb_strlen($username) < 3) { - throw new Exception(t('Name too short.')); + throw new Exception(L10n::t('Name too short.')); } // So now we are just looking for a space in the full name. @@ -303,20 +397,20 @@ class User if (!$loose_reg) { $username = mb_convert_case($username, MB_CASE_TITLE, 'UTF-8'); if (!strpos($username, ' ')) { - throw new Exception(t("That doesn't appear to be your full \x28First Last\x29 name.")); + throw new Exception(L10n::t("That doesn't appear to be your full \x28First Last\x29 name.")); } } - if (!allowed_email($email)) { - throw new Exception(t('Your email domain is not among those allowed on this site.')); + if (!Network::isEmailDomainAllowed($email)) { + throw new Exception(L10n::t('Your email domain is not among those allowed on this site.')); } - if (!valid_email($email) || !validate_email($email)) { - throw new Exception(t('Not a valid email address.')); + if (!valid_email($email) || !Network::isEmailDomainValid($email)) { + throw new Exception(L10n::t('Not a valid email address.')); } - if (dba::exists('user', ['email' => $email])) { - throw new Exception(t('Cannot use that email.')); + if (Config::get('system', 'block_extended_register', false) && dba::exists('user', ['email' => $email])) { + throw new Exception(L10n::t('Cannot use that email.')); } // Disallow somebody creating an account using openid that uses the admin email address, @@ -324,21 +418,21 @@ class User if (x($a->config, 'admin_email') && strlen($openid_url)) { $adminlist = explode(',', str_replace(' ', '', strtolower($a->config['admin_email']))); if (in_array(strtolower($email), $adminlist)) { - throw new Exception(t('Cannot use that email.')); + throw new Exception(L10n::t('Cannot use that email.')); } } $nickname = $data['nickname'] = strtolower($nickname); if (!preg_match('/^[a-z0-9][a-z0-9\_]*$/', $nickname)) { - throw new Exception(t('Your "nickname" can only contain "a-z", "0-9" and "_".')); + throw new Exception(L10n::t('Your nickname can only contain a-z, 0-9 and _.')); } // Check existing and deleted accounts for this nickname. if (dba::exists('user', ['nickname' => $nickname]) || dba::exists('userd', ['username' => $nickname]) ) { - throw new Exception(t('Nickname is already registered. Please choose another.')); + throw new Exception(L10n::t('Nickname is already registered. Please choose another.')); } $new_password = strlen($password) ? $password : User::generateNewPassword(); @@ -348,7 +442,7 @@ class User $keys = Crypto::newKeypair(4096); if ($keys === false) { - throw new Exception(t('SERIOUS ERROR: Generation of security keys failed.')); + throw new Exception(L10n::t('SERIOUS ERROR: Generation of security keys failed.')); } $prvkey = $keys['prvkey']; @@ -373,7 +467,7 @@ class User 'verified' => $verified, 'blocked' => $blocked, 'timezone' => 'UTC', - 'register_date' => datetime_convert(), + 'register_date' => DateTimeFormat::utcNow(), 'default-location' => '' ]); @@ -381,11 +475,11 @@ class User $uid = dba::lastInsertId(); $user = dba::selectFirst('user', [], ['uid' => $uid]); } else { - throw new Exception(t('An error occurred during registration. Please try again.')); + throw new Exception(L10n::t('An error occurred during registration. Please try again.')); } if (!$uid) { - throw new Exception(t('An error occurred during registration. Please try again.')); + throw new Exception(L10n::t('An error occurred during registration. Please try again.')); } // if somebody clicked submit twice very quickly, they could end up with two accounts @@ -394,7 +488,7 @@ class User if ($user_count > 1) { dba::delete('user', ['uid' => $uid]); - throw new Exception(t('Nickname is already registered. Please choose another.')); + throw new Exception(L10n::t('Nickname is already registered. Please choose another.')); } $insert_result = dba::insert('profile', [ @@ -405,28 +499,28 @@ class User 'publish' => $publish, 'is-default' => 1, 'net-publish' => $netpublish, - 'profile-name' => t('default') + 'profile-name' => L10n::t('default') ]); if (!$insert_result) { dba::delete('user', ['uid' => $uid]); - throw new Exception(t('An error occurred creating your default profile. Please try again.')); + throw new Exception(L10n::t('An error occurred creating your default profile. Please try again.')); } // Create the self contact if (!Contact::createSelfFromUserId($uid)) { dba::delete('user', ['uid' => $uid]); - throw new Exception(t('An error occurred creating your self contact. Please try again.')); + throw new Exception(L10n::t('An error occurred creating your self contact. Please try again.')); } // Create a group with no members. This allows somebody to use it // right away as a default group for new contacts. - $def_gid = Group::create($uid, t('Friends')); + $def_gid = Group::create($uid, L10n::t('Friends')); if (!$def_gid) { dba::delete('user', ['uid' => $uid]); - throw new Exception(t('An error occurred creating your default contact group. Please try again.')); + throw new Exception(L10n::t('An error occurred creating your default contact group. Please try again.')); } $fields = ['def_gid' => $def_gid]; @@ -438,7 +532,7 @@ class User // if we have no OpenID photo try to look up an avatar if (!strlen($photo)) { - $photo = avatar_img($email); + $photo = Network::lookupAvatarByEmail($email); } // unless there is no avatar-addon loaded @@ -446,7 +540,7 @@ class User $photo_failure = false; $filename = basename($photo); - $img_str = fetch_url($photo, true); + $img_str = Network::fetchUrl($photo, true); // guess mimetype from headers or filename $type = Image::guessType($photo, true); @@ -454,9 +548,9 @@ class User if ($Image->isValid()) { $Image->scaleToSquare(175); - $hash = photo_new_resource(); + $hash = Photo::newResource(); - $r = Photo::store($Image, $uid, 0, $hash, $filename, t('Profile Photos'), 4); + $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 4); if ($r === false) { $photo_failure = true; @@ -464,7 +558,7 @@ class User $Image->scaleDown(80); - $r = Photo::store($Image, $uid, 0, $hash, $filename, t('Profile Photos'), 5); + $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 5); if ($r === false) { $photo_failure = true; @@ -472,7 +566,7 @@ class User $Image->scaleDown(48); - $r = Photo::store($Image, $uid, 0, $hash, $filename, t('Profile Photos'), 6); + $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 6); if ($r === false) { $photo_failure = true; @@ -500,7 +594,7 @@ class User */ public static function sendRegisterPendingEmail($email, $sitename, $username) { - $body = deindent(t(' + $body = deindent(L10n::t(' Dear %1$s, Thank you for registering at %2$s. Your account is pending for approval by the administrator. ')); @@ -510,7 +604,7 @@ class User return notification([ 'type' => SYSTEM_EMAIL, 'to_email' => $email, - 'subject'=> sprintf( t('Registration at %s'), $sitename), + 'subject'=> L10n::t('Registration at %s', $sitename), 'body' => $body]); } @@ -528,15 +622,16 @@ class User */ public static function sendRegisterOpenEmail($email, $sitename, $siteurl, $username, $password) { - $preamble = deindent(t(' + $preamble = deindent(L10n::t(' Dear %1$s, Thank you for registering at %2$s. Your account has been created. ')); - $body = deindent(t(' + $body = deindent(L10n::t(' The login details are as follows: - Site Location: %3$s - Login Name: %1$s - Password: %5$s + + Site Location: %3$s + Login Name: %1$s + Password: %5$s You may change your password from your account "Settings" page after logging in. @@ -544,10 +639,10 @@ class User Please take a few moments to review the other account settings on that page. You may also wish to add some basic information to your default profile - (on the "Profiles" page) so that other people can easily find you. + ' . "\x28" . 'on the "Profiles" page' . "\x29" . ' so that other people can easily find you. We recommend setting your full name, adding a profile photo, - adding some profile "keywords" (very useful in making new friends) - and + adding some profile "keywords" ' . "\x28" . 'very useful in making new friends' . "\x29" . ' - and perhaps what country you live in; if you do not wish to be more specific than that. @@ -555,6 +650,7 @@ class User If you are new and do not know anybody here, they may help you to make some new and interesting friends. + If you ever want to delete your account, you can do so at %3$s/removeme Thank you and welcome to %2$s.')); @@ -564,7 +660,7 @@ class User return notification([ 'type' => SYSTEM_EMAIL, 'to_email' => $email, - 'subject'=> sprintf( t('Registration details for %s'), $sitename), + 'subject'=> L10n::t('Registration details for %s', $sitename), 'preamble'=> $preamble, 'body' => $body]); } @@ -590,7 +686,7 @@ class User dba::insert('userd', ['username' => $user['nickname']]); // The user and related data will be deleted in "cron_expire_and_remove_users" (cronjobs.php) - dba::update('user', ['account_removed' => true, 'account_expires_on' => datetime_convert()], ['uid' => $uid]); + dba::update('user', ['account_removed' => true, 'account_expires_on' => DateTimeFormat::utcNow()], ['uid' => $uid]); Worker::add(PRIORITY_HIGH, "Notifier", "removeme", $uid); // Send an update to the directory