kopia lustrzana https://github.com/nextcloud/social
840 wiersze
19 KiB
PHP
840 wiersze
19 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Social\Controller;
|
|
|
|
use Exception;
|
|
use OCA\Social\AP;
|
|
use OCA\Social\AppInfo\Application;
|
|
use OCA\Social\Exceptions\AccountDoesNotExistException;
|
|
use OCA\Social\Exceptions\ClientNotFoundException;
|
|
use OCA\Social\Exceptions\InstanceDoesNotExistException;
|
|
use OCA\Social\Exceptions\StreamNotFoundException;
|
|
use OCA\Social\Exceptions\UnknownProbeException;
|
|
use OCA\Social\Model\ActivityPub\ACore;
|
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
|
use OCA\Social\Model\ActivityPub\Object\Document;
|
|
use OCA\Social\Model\ActivityPub\Stream;
|
|
use OCA\Social\Model\Client\MediaAttachment;
|
|
use OCA\Social\Model\Client\Options\ProbeOptions;
|
|
use OCA\Social\Model\Client\SocialClient;
|
|
use OCA\Social\Model\Client\Status;
|
|
use OCA\Social\Model\Post;
|
|
use OCA\Social\Service\AccountService;
|
|
use OCA\Social\Service\ActionService;
|
|
use OCA\Social\Service\CacheActorService;
|
|
use OCA\Social\Service\CacheDocumentService;
|
|
use OCA\Social\Service\ClientService;
|
|
use OCA\Social\Service\ConfigService;
|
|
use OCA\Social\Service\DocumentService;
|
|
use OCA\Social\Service\FollowService;
|
|
use OCA\Social\Service\InstanceService;
|
|
use OCA\Social\Service\PostService;
|
|
use OCA\Social\Service\StreamService;
|
|
use OCA\Social\Tools\Traits\TNCDataResponse;
|
|
use OCP\AppFramework\Controller;
|
|
use OCP\AppFramework\Http;
|
|
use OCP\AppFramework\Http\DataResponse;
|
|
use OCP\AppFramework\Http\FileDisplayResponse;
|
|
use OCP\AppFramework\Http\Response;
|
|
use OCP\IRequest;
|
|
use OCP\IURLGenerator;
|
|
use OCP\IUserSession;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* Class ApiController
|
|
*
|
|
* @package OCA\Social\Controller
|
|
*/
|
|
class ApiController extends Controller {
|
|
use TNCDataResponse;
|
|
|
|
private IURLGenerator $urlGenerator;
|
|
private IUserSession $userSession;
|
|
private LoggerInterface $logger;
|
|
private InstanceService $instanceService;
|
|
private ClientService $clientService;
|
|
private AccountService $accountService;
|
|
private CacheActorService $cacheActorService;
|
|
private CacheDocumentService $cacheDocumentService;
|
|
private DocumentService $documentService;
|
|
private FollowService $followService;
|
|
private StreamService $streamService;
|
|
private ActionService $actionService;
|
|
private PostService $postService;
|
|
private ConfigService $configService;
|
|
|
|
private string $bearer = '';
|
|
private ?SocialClient $client = null;
|
|
private ?Person $viewer = null;
|
|
|
|
public function __construct(
|
|
IRequest $request,
|
|
IURLGenerator $urlGenerator,
|
|
IUserSession $userSession,
|
|
LoggerInterface $logger,
|
|
InstanceService $instanceService,
|
|
ClientService $clientService,
|
|
AccountService $accountService,
|
|
CacheActorService $cacheActorService,
|
|
CacheDocumentService $cacheDocumentService,
|
|
DocumentService $documentService,
|
|
FollowService $followService,
|
|
StreamService $streamService,
|
|
ActionService $actionService,
|
|
PostService $postService,
|
|
ConfigService $configService,
|
|
) {
|
|
parent::__construct(Application::APP_ID, $request);
|
|
|
|
$this->urlGenerator = $urlGenerator;
|
|
$this->userSession = $userSession;
|
|
$this->logger = $logger;
|
|
$this->instanceService = $instanceService;
|
|
$this->clientService = $clientService;
|
|
$this->accountService = $accountService;
|
|
$this->cacheActorService = $cacheActorService;
|
|
$this->cacheDocumentService = $cacheDocumentService;
|
|
$this->documentService = $documentService;
|
|
$this->followService = $followService;
|
|
$this->streamService = $streamService;
|
|
$this->actionService = $actionService;
|
|
$this->postService = $postService;
|
|
$this->configService = $configService;
|
|
|
|
$authHeader = trim($this->request->getHeader('Authorization'));
|
|
if (strpos($authHeader, ' ')) {
|
|
[$authType, $authToken] = explode(' ', $authHeader);
|
|
if (strtolower($authType) === 'bearer') {
|
|
$this->bearer = $authToken;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function appsCredentials() {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
if ($this->client === null) {
|
|
return new DataResponse(
|
|
[
|
|
'name' => 'Nextcloud Social',
|
|
'website' => 'https://github.com/nextcloud/social/'
|
|
], Http::STATUS_OK
|
|
);
|
|
} else {
|
|
return new DataResponse(
|
|
[
|
|
'name' => $this->client->getAppName(),
|
|
'website' => $this->client->getAppWebsite()
|
|
], Http::STATUS_OK
|
|
);
|
|
}
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function verifyCredentials() {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
return new DataResponse($this->viewer, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function customEmojis(): DataResponse {
|
|
return new DataResponse([], Http::STATUS_OK);
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function savedSearches(): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
return new DataResponse([], Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
* @throws InstanceDoesNotExistException
|
|
*/
|
|
public function instance(): DataResponse {
|
|
$local = $this->instanceService->getLocal(Stream::FORMAT_LOCAL);
|
|
|
|
return new DataResponse($local, Http::STATUS_OK);
|
|
}
|
|
|
|
|
|
/**
|
|
* @PublicPage
|
|
* @NoCSRFRequired
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function statusNew(): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$input = file_get_contents('php://input');
|
|
$this->logger->debug('[ApiController] statusNew: ' . $input);
|
|
|
|
$status = new Status();
|
|
$status->import($this->convertInput($input));
|
|
|
|
$post = new Post($this->accountService->getActorFromUserId($this->currentSession()));
|
|
$post->setContent(nl2br($status->getStatus()));
|
|
$post->setType($status->getVisibility());
|
|
|
|
if (!empty($status->getMediaIds())) {
|
|
$post->setMedias(
|
|
array_map(function (Document $document): MediaAttachment {
|
|
return $document->convertToMediaAttachment(
|
|
$this->urlGenerator,
|
|
ACore::FORMAT_ACTIVITYPUB
|
|
);
|
|
}, $this->documentService->getMediaFromArray(
|
|
$status->getMediaIds(),
|
|
$this->viewer->getPreferredUsername()
|
|
))
|
|
);
|
|
}
|
|
|
|
if ($status->getInReplyToId() > 0) {
|
|
try {
|
|
$replyTo = $this->streamService->getStreamByNid($status->getInReplyToId());
|
|
$post->setReplyTo($replyTo->getId());
|
|
} catch (StreamNotFoundException $e) {
|
|
$this->logger->debug('reply to post not found');
|
|
}
|
|
}
|
|
|
|
$activity = $this->postService->createPost($post);
|
|
|
|
$item = $this->streamService->getStreamById(
|
|
$activity->getObjectId(),
|
|
true,
|
|
ACore::FORMAT_LOCAL
|
|
);
|
|
|
|
return new DataResponse($item, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
$this->logger->warning('issues while statusNew', ['exception' => $e]);
|
|
|
|
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @PublicPage
|
|
* @NoCSRFRequired
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function mediaNew(): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$file = $_FILES['file'] ?? [];
|
|
if (empty($file)) {
|
|
throw new Exception('no media found');
|
|
}
|
|
|
|
if ($file['error'] !== UPLOAD_ERR_OK) {
|
|
throw new Exception('error during upload');
|
|
}
|
|
|
|
$name = $file['tmp_name'] ?? '';
|
|
$size = $file['size'] ?? -1;
|
|
$type = $file['type'] ?? '';
|
|
|
|
if ($name === '' || $size === -1 || $type === '') {
|
|
throw new Exception('missing details');
|
|
}
|
|
|
|
$this->logger->debug('[ApiController] mediaNew: ' . json_encode($file));
|
|
|
|
$document = new Document();
|
|
$document->setLocal(true);
|
|
$document->setAccount($this->viewer->getPreferredUsername());
|
|
$document->setUrlCloud($this->configService->getCloudUrl());
|
|
$document->generateUniqueId('/documents/local');
|
|
$document->setPublic(true);
|
|
|
|
$this->cacheDocumentService->saveFromTempToCache($document, $name);
|
|
$service = AP::$activityPub->getInterfaceForItem($document);
|
|
$service->save($document);
|
|
|
|
$mediaAttachment = $document->convertToMediaAttachment($this->urlGenerator);
|
|
|
|
$this->logger->debug('generated attachment: ' . json_encode($mediaAttachment));
|
|
|
|
return new DataResponse($mediaAttachment, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
$this->logger->warning('issues while mediaNew', ['exception' => $e]);
|
|
|
|
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @PublicPage
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $id
|
|
*
|
|
* @return Response
|
|
*/
|
|
public function mediaGet(string $nid, string $preview = ''): Response {
|
|
try {
|
|
return new DataResponse([], Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
$this->logger->warning('issues while mediaNew', ['exception' => $e]);
|
|
|
|
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @PublicPage
|
|
* @NoCSRFRequired
|
|
*
|
|
* @param string $id
|
|
*
|
|
* @return Response
|
|
*/
|
|
public function mediaOpen(string $uuid): Response {
|
|
$ext = '';
|
|
if (strpos($uuid, '.') > 0) {
|
|
[$uuid, $ext] = explode('.', $uuid, 2);
|
|
}
|
|
|
|
try {
|
|
$mime = '';
|
|
$file = $this->documentService->getFromUuid($uuid);
|
|
|
|
return new FileDisplayResponse(
|
|
$file, Http::STATUS_OK, ['Content-Type' => $this->mimeFromExt($ext)]
|
|
);
|
|
} catch (Exception $e) {
|
|
$this->logger->warning('issues while mediaOpen', ['exception' => $e]);
|
|
|
|
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $ext
|
|
* only support image actually
|
|
*
|
|
* @return string
|
|
*/
|
|
private function mimeFromExt(string $ext): string {
|
|
if ($ext === '') {
|
|
return '';
|
|
}
|
|
|
|
return 'image/' . $ext;
|
|
}
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param string $timeline
|
|
* @param bool $local
|
|
* @param int $limit
|
|
* @param int $max_id
|
|
* @param int $min_id
|
|
* @param int $since_id
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function timelines(
|
|
string $timeline,
|
|
bool $local = false,
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since_id = 0,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
if (!in_array(
|
|
strtolower($timeline),
|
|
[
|
|
ProbeOptions::HOME,
|
|
ProbeOptions::ACCOUNT,
|
|
ProbeOptions::PUBLIC,
|
|
ProbeOptions::DIRECT,
|
|
ProbeOptions::FAVOURITES
|
|
]
|
|
)) {
|
|
throw new UnknownProbeException('unknown timeline');
|
|
}
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe($timeline)
|
|
->setLocal($local)
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since_id);
|
|
|
|
$posts = $this->streamService->getTimeline($options);
|
|
|
|
return new DataResponse($posts, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param int $nid
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function statusGet(int $nid): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$item = $this->streamService->getStreamByNid($nid);
|
|
|
|
return new DataResponse($item, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param int $nid
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function statusContext(int $nid): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
$context = $this->streamService->getContextByNid($nid);
|
|
|
|
return new DataResponse($context, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param int $nid
|
|
* @param string $action
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function statusAction(int $nid, string $act): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
$actor = $this->accountService->getActor($this->viewer->getPreferredUsername());
|
|
$item = $this->actionService->action($actor, $nid, $act);
|
|
|
|
if ($item === null) {
|
|
$item = $this->streamService->getStreamByNid($nid);
|
|
}
|
|
|
|
return new DataResponse($item, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param array $id
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function relationships(array $id): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
return new DataResponse($this->followService->getRelationships($id), Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param string $account
|
|
* @param int $limit
|
|
* @param int $max_id
|
|
* @param int $min_id
|
|
* @param int $since
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function accountStatuses(
|
|
string $account,
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since_id = 0,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$local = $this->cacheActorService->getFromLocalAccount($account);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe(ProbeOptions::ACCOUNT)
|
|
->setAccountId($local->getId())
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since_id);
|
|
|
|
$posts = $this->streamService->getTimeline($options);
|
|
|
|
return new DataResponse($posts, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param string $account
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function accountFollowing(
|
|
string $account,
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since = 0,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
$local = $this->cacheActorService->getFromLocalAccount($account);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe(ProbeOptions::FOLLOWING)
|
|
->setAccountId($local->getId())
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since);
|
|
|
|
return new DataResponse($this->cacheActorService->probeActors($options), Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param string $account
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function accountFollowers(
|
|
string $account,
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since = 0,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$local = $this->cacheActorService->getFromLocalAccount($account);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe(ProbeOptions::FOLLOWERS)
|
|
->setAccountId($local->getId())
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since);
|
|
|
|
return new DataResponse($this->cacheActorService->probeActors($options), Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @param int $limit
|
|
* @param int $max_id
|
|
* @param int $min_id
|
|
* @param int $since_id
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function favourites(
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since_id = 0,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe(ProbeOptions::FAVOURITES)
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since_id);
|
|
|
|
$posts = $this->streamService->getTimeline($options);
|
|
|
|
return new DataResponse($posts, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function notifications(
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since_id = 0,
|
|
array $types = [],
|
|
array $exclude_types = [],
|
|
string $accountId = '',
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe(ProbeOptions::NOTIFICATIONS)
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since_id)
|
|
->setTypes($types)
|
|
->setExcludeTypes($exclude_types)
|
|
->setAccountId($accountId);
|
|
|
|
$posts = $this->streamService->getTimeline($options);
|
|
|
|
return new DataResponse($posts, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @NoCSRFRequired
|
|
* @PublicPage
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
public function tag(
|
|
string $hashtag,
|
|
int $limit = 20,
|
|
int $max_id = 0,
|
|
int $min_id = 0,
|
|
int $since_id = 0,
|
|
bool $local = false,
|
|
bool $only_media = false,
|
|
): DataResponse {
|
|
try {
|
|
$this->initViewer(true);
|
|
|
|
$options = new ProbeOptions($this->request);
|
|
$options->setFormat(ACore::FORMAT_LOCAL);
|
|
$options->setProbe('hashtag')
|
|
->setLimit($limit)
|
|
->setMaxId($max_id)
|
|
->setMinId($min_id)
|
|
->setSince($since_id)
|
|
->setLocal($local)
|
|
->setOnlyMedia($only_media)
|
|
->setArgument($hashtag);
|
|
|
|
$posts = $this->streamService->getTimeline($options);
|
|
|
|
return new DataResponse($posts, Http::STATUS_OK);
|
|
} catch (Exception $e) {
|
|
return $this->error($e->getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param bool $exception
|
|
*
|
|
* @return bool
|
|
* @throws ClientNotFoundException
|
|
*/
|
|
private function initViewer(bool $exception = false): bool {
|
|
try {
|
|
$userId = $this->currentSession();
|
|
|
|
$this->logger->debug(
|
|
'[ApiController] initViewer: ' . $userId . ' (bearer=' . $this->bearer . ')'
|
|
);
|
|
|
|
$account = $this->accountService->getActorFromUserId($userId);
|
|
$this->viewer = $this->cacheActorService->getFromLocalAccount($account->getPreferredUsername());
|
|
$this->viewer->setExportFormat(ACore::FORMAT_LOCAL);
|
|
|
|
$this->streamService->setViewer($this->viewer);
|
|
$this->followService->setViewer($this->viewer);
|
|
$this->cacheActorService->setViewer($this->viewer);
|
|
|
|
return true;
|
|
} catch (Exception $e) {
|
|
if ($exception) {
|
|
throw new ClientNotFoundException('the access_token was revoked');
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
private function convertInput(string $input): array {
|
|
$contentType = $this->request->getHeader('Content-Type');
|
|
|
|
$pos = strpos($contentType, ';');
|
|
if ($pos > 0) {
|
|
$contentType = substr($contentType, 0, $pos);
|
|
}
|
|
|
|
switch ($contentType) {
|
|
case 'application/json':
|
|
return json_decode($input, true);
|
|
|
|
case 'application/x-www-form-urlencoded':
|
|
return $this->request->getParams();
|
|
|
|
default: // in case of no header ...
|
|
$result = json_decode($input, true);
|
|
if (is_array($result)) {
|
|
return $result;
|
|
}
|
|
|
|
return $this->request->getParams();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @return string
|
|
* @throws AccountDoesNotExistException
|
|
* @throws ClientNotFoundException
|
|
*/
|
|
private function currentSession(): string {
|
|
$user = $this->userSession->getUser();
|
|
if ($user !== null) {
|
|
return $user->getUID();
|
|
}
|
|
|
|
if ($this->bearer !== '') {
|
|
$this->client = $this->clientService->getFromToken($this->bearer);
|
|
|
|
return $this->client->getAuthUserId();
|
|
}
|
|
|
|
throw new AccountDoesNotExistException('userId not defined');
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $error
|
|
*
|
|
* @return DataResponse
|
|
*/
|
|
private function error(string $error): DataResponse {
|
|
return new DataResponse(['error' => $error], Http::STATUS_UNAUTHORIZED);
|
|
}
|
|
}
|