X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FUser.php;h=03ddb4605b8f96d02e38f3b4e9822562dc15c132;hb=bd9f36622e056c83e8bfef2920640285ce9672b0;hp=c12ac31cdc694325327e0f0beecb91e514fd2fee;hpb=8565617ea120b7ff3d8783e90070e286e8b119c0;p=friendica.git diff --git a/src/Model/User.php b/src/Model/User.php index c12ac31cdc..03ddb4605b 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -100,6 +100,150 @@ class User * @} */ + private static $owner; + + /** + * Returns the numeric account type by their string + * + * @param string $accounttype as string constant + * @return int|null Numeric account type - or null when not set + */ + public static function getAccountTypeByString(string $accounttype) + { + switch ($accounttype) { + case 'person': + return User::ACCOUNT_TYPE_PERSON; + case 'organisation': + return User::ACCOUNT_TYPE_ORGANISATION; + case 'news': + return User::ACCOUNT_TYPE_NEWS; + case 'community': + return User::ACCOUNT_TYPE_COMMUNITY; + default: + return null; + break; + } + } + + /** + * Fetch the system account + * + * @return array system account + */ + public static function getSystemAccount() + { + $system = Contact::selectFirst([], ['self' => true, 'uid' => 0]); + if (!DBA::isResult($system)) { + self::createSystemAccount(); + $system = Contact::selectFirst([], ['self' => true, 'uid' => 0]); + if (!DBA::isResult($system)) { + return []; + } + } + + $system['sprvkey'] = $system['uprvkey'] = $system['prvkey']; + $system['spubkey'] = $system['upubkey'] = $system['pubkey']; + $system['nickname'] = $system['nick']; + + // Ensure that the user contains data + $user = DBA::selectFirst('user', ['prvkey'], ['uid' => 0]); + if (empty($user['prvkey'])) { + $fields = [ + 'username' => $system['name'], + 'nickname' => $system['nick'], + 'register_date' => $system['created'], + 'pubkey' => $system['pubkey'], + 'prvkey' => $system['prvkey'], + 'spubkey' => $system['spubkey'], + 'sprvkey' => $system['sprvkey'], + 'verified' => true, + 'page-flags' => User::PAGE_FLAGS_SOAPBOX, + 'account-type' => User::ACCOUNT_TYPE_RELAY, + ]; + + DBA::update('user', $fields, ['uid' => 0]); + } + + return $system; + } + + /** + * Create the system account + * + * @return void + */ + private static function createSystemAccount() + { + $system_actor_name = self::getActorName(); + if (empty($system_actor_name)) { + return; + } + + $keys = Crypto::newKeypair(4096); + if ($keys === false) { + throw new Exception(DI::l10n()->t('SERIOUS ERROR: Generation of security keys failed.')); + } + + $system = []; + $system['uid'] = 0; + $system['created'] = DateTimeFormat::utcNow(); + $system['self'] = true; + $system['network'] = Protocol::ACTIVITYPUB; + $system['name'] = 'System Account'; + $system['addr'] = $system_actor_name . '@' . DI::baseUrl()->getHostname(); + $system['nick'] = $system_actor_name; + $system['avatar'] = DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO; + $system['photo'] = DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO; + $system['thumb'] = DI::baseUrl() . Contact::DEFAULT_AVATAR_THUMB; + $system['micro'] = DI::baseUrl() . Contact::DEFAULT_AVATAR_MICRO; + $system['url'] = DI::baseUrl() . '/friendica'; + $system['nurl'] = Strings::normaliseLink($system['url']); + $system['pubkey'] = $keys['pubkey']; + $system['prvkey'] = $keys['prvkey']; + $system['blocked'] = 0; + $system['pending'] = 0; + $system['contact-type'] = Contact::TYPE_RELAY; // In AP this is translated to 'Application' + $system['name-date'] = DateTimeFormat::utcNow(); + $system['uri-date'] = DateTimeFormat::utcNow(); + $system['avatar-date'] = DateTimeFormat::utcNow(); + $system['closeness'] = 0; + $system['baseurl'] = DI::baseUrl(); + $system['gsid'] = GServer::getID($system['baseurl']); + DBA::insert('contact', $system); + } + + /** + * Detect a usable actor name + * + * @return string actor account name + */ + public static function getActorName() + { + $system_actor_name = DI::config()->get('system', 'actor_name'); + if (!empty($system_actor_name)) { + $self = Contact::selectFirst(['nick'], ['uid' => 0, 'self' => true]); + if (!empty($self['nick'])) { + if ($self['nick'] != $system_actor_name) { + // Reset the actor name to the already used name + DI::config()->set('system', 'actor_name', $self['nick']); + $system_actor_name = $self['nick']; + } + } + return $system_actor_name; + } + + // List of possible actor names + $possible_accounts = ['friendica', 'actor', 'system', 'internal']; + foreach ($possible_accounts as $name) { + if (!DBA::exists('user', ['nickname' => $name, 'account_removed' => false, 'expire' => false]) && + !DBA::exists('userd', ['username' => $name])) { + DI::config()->set('system', 'actor_name', $name); + return $name; + } + } + return ''; + } + /** * Returns true if a user record exists with the provided id * @@ -120,7 +264,7 @@ class User */ public static function getById($uid, array $fields = []) { - return DBA::selectFirst('user', $fields, ['uid' => $uid]); + return !empty($uid) ? DBA::selectFirst('user', $fields, ['uid' => $uid]) : []; } /** @@ -163,14 +307,29 @@ class User * @return integer user id * @throws Exception */ - public static function getIdForURL($url) + public static function getIdForURL(string $url) { - $self = DBA::selectFirst('contact', ['uid'], ['nurl' => Strings::normaliseLink($url), 'self' => true]); - if (!DBA::isResult($self)) { - return false; - } else { + // Avoid any database requests when the hostname isn't even part of the url. + if (!strpos($url, DI::baseUrl()->getHostname())) { + return 0; + } + + $self = Contact::selectFirst(['uid'], ['self' => true, 'nurl' => Strings::normaliseLink($url)]); + if (!empty($self['uid'])) { + return $self['uid']; + } + + $self = Contact::selectFirst(['uid'], ['self' => true, 'addr' => $url]); + if (!empty($self['uid'])) { + return $self['uid']; + } + + $self = Contact::selectFirst(['uid'], ['self' => true, 'alias' => [$url, Strings::normaliseLink($url)]]); + if (!empty($self['uid'])) { return $self['uid']; } + + return 0; } /** @@ -188,6 +347,24 @@ class User return DBA::selectFirst('user', $fields, ['email' => $email]); } + /** + * Fetch the user array of the administrator. The first one if there are several. + * + * @param array $fields + * @return array user + */ + public static function getFirstAdmin(array $fields = []) + { + if (!empty(DI::config()->get('config', 'admin_nickname'))) { + return self::getByNickname(DI::config()->get('config', 'admin_nickname'), $fields); + } elseif (!empty(DI::config()->get('config', 'admin_email'))) { + $adminList = explode(',', str_replace(' ', '', DI::config()->get('config', 'admin_email'))); + return self::getByEmail($adminList[0], $fields); + } else { + return []; + } + } + /** * Get owner data by user id * @@ -196,8 +373,16 @@ class User * @return boolean|array * @throws Exception */ - public static function getOwnerDataById($uid, $check_valid = true) + public static function getOwnerDataById(int $uid, bool $check_valid = true) { + if ($uid == 0) { + return self::getSystemAccount(); + } + + if (!empty(self::$owner[$uid])) { + return self::$owner[$uid]; + } + $owner = DBA::selectFirst('owner-view', [], ['uid' => $uid]); if (!DBA::isResult($owner)) { if (!DBA::exists('user', ['uid' => $uid]) || !$check_valid) { @@ -224,7 +409,7 @@ class User if (!$repair) { // Check if "addr" is present and correct $addr = $owner['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3); - $repair = ($addr != $owner['addr']); + $repair = ($addr != $owner['addr']) || empty($owner['prvkey']) || empty($owner['pubkey']); } if (!$repair) { @@ -241,6 +426,7 @@ class User $owner = self::getOwnerDataById($uid, false); } + self::$owner[$uid] = $owner; return $owner; } @@ -373,7 +559,7 @@ class User * @return array * @throws HTTPException\NotFoundException */ - private static function getAuthenticationInfo($user_info) + public static function getAuthenticationInfo($user_info) { $user = null; @@ -552,15 +738,24 @@ class User public static function isNicknameBlocked($nickname) { $forbidden_nicknames = DI::config()->get('system', 'forbidden_nicknames', ''); + if (!empty($forbidden_nicknames)) { + $forbidden = explode(',', $forbidden_nicknames); + $forbidden = array_map('trim', $forbidden); + } else { + $forbidden = []; + } + + // Add the name of the internal actor to the "forbidden" list + $actor_name = self::getActorName(); + if (!empty($actor_name)) { + $forbidden[] = $actor_name; + } - // if the config variable is empty return false - if (empty($forbidden_nicknames)) { + if (empty($forbidden)) { return false; } // check if the nickname is in the list of blocked nicknames - $forbidden = explode(',', $forbidden_nicknames); - $forbidden = array_map('trim', $forbidden); if (in_array(strtolower($nickname), $forbidden)) { return true; } @@ -827,7 +1022,7 @@ class User $photo_failure = false; $filename = basename($photo); - $curlResult = Network::curl($photo, true); + $curlResult = DI::httpRequest()->get($photo); if ($curlResult->isSuccess()) { $img_str = $curlResult->getBody(); $type = $curlResult->getContentType(); @@ -1166,7 +1361,7 @@ class User // unique), so it cannot be re-registered in the future. DBA::insert('userd', ['username' => $user['nickname']]); - // The user and related data will be deleted in Friendica\Worker\CronJobs::expireAndRemoveUsers() + // The user and related data will be deleted in Friendica\Worker\ExpireAndRemoveUsers DBA::update('user', ['account_removed' => true, 'account_expires_on' => DateTimeFormat::utc('now + 7 day')], ['uid' => $uid]); Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::REMOVAL, $uid); @@ -1336,7 +1531,9 @@ class User $condition['blocked'] = false; break; case 'blocked': + $condition['account_removed'] = false; $condition['blocked'] = true; + $condition['verified'] = true; break; case 'removed': $condition['account_removed'] = true;