X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=include%2Fapi.php;h=bcfd5af2464e570eba213853a6f6d57ebcaefd0b;hb=d89f90e80ee4a7101bcef7369b64ab5fb42f7b1a;hp=f43ee2d1bae693903319081120d9e0aeee31f3f8;hpb=0840938dff3a2bdc8db836662fea2bbccff05e03;p=friendica.git diff --git a/include/api.php b/include/api.php index f43ee2d1ba..bcfd5af246 100644 --- a/include/api.php +++ b/include/api.php @@ -1,5 +1,22 @@ . + * * Friendica implementation of statusnet/twitter API * * @file include/api.php @@ -8,7 +25,6 @@ use Friendica\App; use Friendica\Content\ContactSelector; -use Friendica\Content\Feature; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; @@ -25,7 +41,6 @@ use Friendica\Model\Item; use Friendica\Model\Mail; use Friendica\Model\Notify; use Friendica\Model\Photo; -use Friendica\Model\Profile; use Friendica\Model\User; use Friendica\Model\UserItem; use Friendica\Network\FKOAuth1; @@ -171,23 +186,6 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY */ function api_login(App $a) { - $oauth1 = new FKOAuth1(); - // login with oauth - try { - $request = OAuthRequest::from_request(); - list($consumer, $token) = $oauth1->verify_request($request); - if (!is_null($token)) { - $oauth1->loginUser($token->uid); - Session::set('allow_api', true); - return; - } - echo __FILE__.__LINE__.__FUNCTION__ . "
"; - var_dump($consumer, $token); - die(); - } catch (Exception $e) { - Logger::warning(API_LOG_PREFIX . 'error', ['module' => 'api', 'action' => 'login', 'exception' => $e->getMessage()]); - } - // workaround for HTTP-auth in CGI mode if (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)); @@ -199,6 +197,24 @@ function api_login(App $a) } if (empty($_SERVER['PHP_AUTH_USER'])) { + // Try OAuth when no user is provided + $oauth1 = new FKOAuth1(); + // login with oauth + try { + $request = OAuthRequest::from_request(); + list($consumer, $token) = $oauth1->verify_request($request); + if (!is_null($token)) { + $oauth1->loginUser($token->uid); + Session::set('allow_api', true); + return; + } + echo __FILE__.__LINE__.__FUNCTION__ . ""; + var_dump($consumer, $token); + die(); + } catch (Exception $e) { + Logger::warning(API_LOG_PREFIX . 'OAuth error', ['module' => 'api', 'action' => 'login', 'exception' => $e->getMessage()]); + } + Logger::debug(API_LOG_PREFIX . 'failed', ['module' => 'api', 'action' => 'login', 'parameters' => $_SERVER]); header('WWW-Authenticate: Basic realm="Friendica"'); throw new UnauthorizedException("This API requires login"); @@ -312,9 +328,7 @@ function api_call(App $a, App\Arguments $args = null) } $called_api = explode("/", $p); - //unset($_SERVER['PHP_AUTH_USER']); - /// @TODO should be "true ==[=] $info['auth']", if you miss only one = character, you assign a variable (only with ==). Let's make all this even. if (!empty($info['auth']) && api_user() === false) { api_login($a); } @@ -770,7 +784,7 @@ function api_item_get_user(App $a, $item) $author_user = $status_user; - $status_user["protected"] = $item['private'] ?? 0; + $status_user["protected"] = isset($item['private']) && ($item['private'] == Item::PRIVATE); if (($item['thr-parent'] ?? '') == ($item['uri'] ?? '')) { $owner_user = api_get_user($a, $item['owner-id'] ?? null); @@ -1329,7 +1343,7 @@ function api_get_last_status($ownerId, $uid) 'author-id'=> $ownerId, 'uid' => $uid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], - 'private' => false + 'private' => [Item::PUBLIC, Item::UNLISTED] ]; $item = api_get_item($condition); @@ -1719,8 +1733,8 @@ function api_statuses_public_timeline($type) $start = max(0, ($page - 1) * $count); if ($exclude_replies && !$conversation_id) { - $condition = ["`gravity` IN (?, ?) AND `iid` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND NOT `author`.`hidden`", - GRAVITY_PARENT, GRAVITY_COMMENT, $since_id]; + $condition = ["`gravity` IN (?, ?) AND `iid` > ? AND `private` = ? AND `wall` AND NOT `author`.`hidden`", + GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC]; if ($max_id > 0) { $condition[0] .= " AND `thread`.`iid` <= ?"; @@ -1732,8 +1746,8 @@ function api_statuses_public_timeline($type) $r = Item::inArray($statuses); } else { - $condition = ["`gravity` IN (?, ?) AND `id` > ? AND NOT `private` AND `wall` AND NOT `user`.`hidewall` AND `item`.`origin` AND NOT `author`.`hidden`", - GRAVITY_PARENT, GRAVITY_COMMENT, $since_id]; + $condition = ["`gravity` IN (?, ?) AND `id` > ? AND `private` = ? AND `wall` AND `item`.`origin` AND NOT `author`.`hidden`", + GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC]; if ($max_id > 0) { $condition[0] .= " AND `item`.`id` <= ?"; @@ -1798,8 +1812,8 @@ function api_statuses_networkpublic_timeline($type) $start = max(0, ($page - 1) * $count); - $condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND NOT `private`", - GRAVITY_PARENT, GRAVITY_COMMENT, $since_id]; + $condition = ["`uid` = 0 AND `gravity` IN (?, ?) AND `thread`.`iid` > ? AND `private` = ?", + GRAVITY_PARENT, GRAVITY_COMMENT, $since_id, Item::PUBLIC]; if ($max_id > 0) { $condition[0] .= " AND `thread`.`iid` <= ?"; @@ -2027,7 +2041,7 @@ function api_statuses_repeat($type) Logger::log('API: api_statuses_repeat: '.$id); $fields = ['body', 'title', 'attach', 'tag', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; - $item = Item::selectFirst($fields, ['id' => $id, 'private' => false]); + $item = Item::selectFirst($fields, ['id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED]]); if (DBA::isResult($item) && $item['body'] != "") { if (strpos($item['body'], "[/share]") !== false) { @@ -2908,60 +2922,6 @@ function api_format_items_activities($item, $type = "json") return $activities; } - -/** - * return data from profiles - * - * @param array $profile_row array containing data from db table 'profile' - * @return array - * @throws InternalServerErrorException - */ -function api_format_items_profiles($profile_row) -{ - $profile = [ - 'profile_id' => $profile_row['id'], - 'profile_name' => $profile_row['profile-name'], - 'is_default' => $profile_row['is-default'] ? true : false, - 'hide_friends' => $profile_row['hide-friends'] ? true : false, - 'profile_photo' => $profile_row['photo'], - 'profile_thumb' => $profile_row['thumb'], - 'publish' => $profile_row['publish'] ? true : false, - 'net_publish' => $profile_row['net-publish'] ? true : false, - 'description' => $profile_row['pdesc'], - 'date_of_birth' => $profile_row['dob'], - 'address' => $profile_row['address'], - 'city' => $profile_row['locality'], - 'region' => $profile_row['region'], - 'postal_code' => $profile_row['postal-code'], - 'country' => $profile_row['country-name'], - 'hometown' => $profile_row['hometown'], - 'gender' => $profile_row['gender'], - 'marital' => $profile_row['marital'], - 'marital_with' => $profile_row['with'], - 'marital_since' => $profile_row['howlong'], - 'sexual' => $profile_row['sexual'], - 'politic' => $profile_row['politic'], - 'religion' => $profile_row['religion'], - 'public_keywords' => $profile_row['pub_keywords'], - 'private_keywords' => $profile_row['prv_keywords'], - 'likes' => BBCode::convert(api_clean_plain_items($profile_row['likes']) , false, 2), - 'dislikes' => BBCode::convert(api_clean_plain_items($profile_row['dislikes']) , false, 2), - 'about' => BBCode::convert(api_clean_plain_items($profile_row['about']) , false, 2), - 'music' => BBCode::convert(api_clean_plain_items($profile_row['music']) , false, 2), - 'book' => BBCode::convert(api_clean_plain_items($profile_row['book']) , false, 2), - 'tv' => BBCode::convert(api_clean_plain_items($profile_row['tv']) , false, 2), - 'film' => BBCode::convert(api_clean_plain_items($profile_row['film']) , false, 2), - 'interest' => BBCode::convert(api_clean_plain_items($profile_row['interest']) , false, 2), - 'romance' => BBCode::convert(api_clean_plain_items($profile_row['romance']) , false, 2), - 'work' => BBCode::convert(api_clean_plain_items($profile_row['work']) , false, 2), - 'education' => BBCode::convert(api_clean_plain_items($profile_row['education']), false, 2), - 'social_networks' => BBCode::convert(api_clean_plain_items($profile_row['contact']) , false, 2), - 'homepage' => $profile_row['homepage'], - 'users' => null - ]; - return $profile; -} - /** * format items to be returned by api * @@ -3046,7 +3006,7 @@ function api_format_item($item, $type = "json", $status_user = null, $author_use 'user' => $status_user, 'friendica_author' => $author_user, 'friendica_owner' => $owner_user, - 'friendica_private' => $item['private'] == 1, + 'friendica_private' => $item['private'] == Item::PRIVATE, //'entities' => NULL, 'statusnet_html' => $converted["html"], 'statusnet_conversation_id' => $item['parent'], @@ -5028,6 +4988,9 @@ function prepare_photo_data($type, $scale, $photo_id) // retrieve item element for getting activities (like, dislike etc.) related to photo $condition = ['uid' => local_user(), 'resource-id' => $photo_id, 'type' => 'photo']; $item = Item::selectFirstForUser(local_user(), ['id'], $condition); + if (!DBA::isResult($item)) { + throw new NotFoundException('Photo-related item not found.'); + } $data['photo']['friendica_activities'] = api_format_items_activities($item, $type); @@ -5861,7 +5824,7 @@ function api_friendica_activity($type) $id = $_REQUEST['id'] ?? 0; - $res = Item::performLike($id, $verb); + $res = Item::performActivity($id, $verb); if ($res) { if ($type == "xml") { @@ -5891,10 +5854,11 @@ api_register_func('api/friendica/activity/unattendmaybe', 'api_friendica_activit * Returns notifications * * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * * @return string|array - * @throws BadRequestException * @throws ForbiddenException - * @throws InternalServerErrorException + * @throws BadRequestException + * @throws Exception */ function api_friendica_notification($type) { @@ -5907,7 +5871,7 @@ function api_friendica_notification($type) throw new BadRequestException("Invalid argument count"); } - $notifications = DI::notify()->select(['uid' => api_user()], ['order' => ['seen' => 'ASC', 'date' => 'DESC'], 'limit' => 50]); + $notifications = DI::notification()->getApiList(local_user()); if ($type == "xml") { $xmlnotes = false; @@ -5955,11 +5919,11 @@ function api_friendica_notification_seen($type) $id = (!empty($_REQUEST['id']) ? intval($_REQUEST['id']) : 0); try { - $notification = DI::notify()->getByID($id); - $notification->setSeen(); + $notify = DI::notify()->getByID($id, api_user()); + DI::notify()->setSeen(true, $notify); - if ($notification->otype === Notify::OTYPE_ITEM) { - $item = Item::selectFirstForUser(api_user(), [], ['id' => $notification->iid, 'uid' => api_user()]); + if ($notify->otype === Notify\ObjectType::ITEM) { + $item = Item::selectFirstForUser(api_user(), [], ['id' => $notify->iid, 'uid' => api_user()]); if (DBA::isResult($item)) { // we found the item, return it to the user $ret = api_format_items([$item], $user_info, false, $type); @@ -5970,7 +5934,9 @@ function api_friendica_notification_seen($type) } return api_format_data('result', $type, ['result' => "success"]); } catch (NotFoundException $e) { - throw new BadRequestException('Invalid argument'); + throw new BadRequestException('Invalid argument', $e); + } catch (Exception $e) { + throw new InternalServerErrorException('Internal Server exception', $e); } } @@ -6100,78 +6066,6 @@ function api_friendica_direct_messages_search($type, $box = "") /// @TODO move to top of file or somewhere better api_register_func('api/friendica/direct_messages_search', 'api_friendica_direct_messages_search', true); -/** - * return data of all the profiles a user has to the client - * - * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string|array - * @throws BadRequestException - * @throws ForbiddenException - * @throws ImagickException - * @throws InternalServerErrorException - * @throws UnauthorizedException - */ -function api_friendica_profile_show($type) -{ - $a = DI::app(); - - if (api_user() === false) { - throw new ForbiddenException(); - } - - // input params - $profile_id = $_REQUEST['profile_id'] ?? 0; - - // retrieve general information about profiles for user - $multi_profiles = Feature::isEnabled(api_user(), 'multi_profiles'); - $directory = DI::config()->get('system', 'directory'); - - // get data of the specified profile id or all profiles of the user if not specified - if ($profile_id != 0) { - $r = Profile::getById(api_user(), $profile_id); - // error message if specified gid is not in database - if (!DBA::isResult($r)) { - throw new BadRequestException("profile_id not available"); - } - } else { - $r = Profile::getListByUser(api_user()); - } - // loop through all returned profiles and retrieve data and users - $k = 0; - $profiles = []; - if (DBA::isResult($r)) { - foreach ($r as $rr) { - $profile = api_format_items_profiles($rr); - - // select all users from contact table, loop and prepare standard return for user data - $users = []; - $nurls = Contact::selectToArray(['id', 'nurl'], ['uid' => api_user(), 'profile-id' => $rr['id']]); - foreach ($nurls as $nurl) { - $user = api_get_user($a, $nurl['nurl']); - ($type == "xml") ? $users[$k++ . ":user"] = $user : $users[] = $user; - } - $profile['users'] = $users; - - // add prepared profile data to array for final return - if ($type == "xml") { - $profiles[$k++ . ":profile"] = $profile; - } else { - $profiles[] = $profile; - } - } - } - - // return settings, authenticated user and profiles data - $self = DBA::selectFirst('contact', ['nurl'], ['uid' => api_user(), 'self' => true]); - - $result = ['multi_profiles' => $multi_profiles ? true : false, - 'global_dir' => $directory, - 'friendica_owner' => api_get_user($a, $self['nurl']), - 'profiles' => $profiles]; - return api_format_data("friendica_profiles", $type, ['$result' => $result]); -} -api_register_func('api/friendica/profile/show', 'api_friendica_profile_show', true, API_METHOD_GET); - /** * Returns a list of saved searches. *