kopia lustrzana https://github.com/nextcloud/social
renaming services
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>pull/226/head
rodzic
d028ab206c
commit
a1f0ff0198
|
@ -33,10 +33,10 @@ namespace OCA\Social\Command;
|
|||
|
||||
use Exception;
|
||||
use OC\Core\Command\Base;
|
||||
use OCA\Social\Service\ActivityPub\Object\DocumentService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\DocumentService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -45,11 +45,11 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
class CacheRefresh extends Base {
|
||||
|
||||
|
||||
/** @var ActorService */
|
||||
/** @var AccountService */
|
||||
private $actorService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var DocumentService */
|
||||
private $documentService;
|
||||
|
@ -64,20 +64,20 @@ class CacheRefresh extends Base {
|
|||
/**
|
||||
* CacheUpdate constructor.
|
||||
*
|
||||
* @param ActorService $actorService
|
||||
* @param PersonService $personService
|
||||
* @param AccountService $actorService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param DocumentService $documentService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
ActorService $actorService, PersonService $personService, DocumentService $documentService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
AccountService $actorService, CacheActorService $cacheActorService,
|
||||
DocumentService $documentService, ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->actorService = $actorService;
|
||||
$this->personService = $personService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->documentService = $documentService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
|
@ -105,10 +105,10 @@ class CacheRefresh extends Base {
|
|||
$result = $this->actorService->manageCacheLocalActors();
|
||||
$output->writeLn($result . ' local accounts regenerated');
|
||||
|
||||
$result = $this->personService->missingCacheRemoteActors();
|
||||
$result = $this->cacheActorService->missingCacheRemoteActors();
|
||||
$output->writeLn($result . ' remote accounts created');
|
||||
|
||||
$result = $this->personService->manageCacheRemoteActors();
|
||||
$result = $this->cacheActorService->manageCacheRemoteActors();
|
||||
$output->writeLn($result . ' remote accounts updated');
|
||||
|
||||
$result = $this->documentService->manageCacheDocuments();
|
||||
|
|
|
@ -33,9 +33,8 @@ namespace OCA\Social\Command;
|
|||
use Exception;
|
||||
use OC\Core\Command\Base;
|
||||
use OCA\Social\Model\Post;
|
||||
use OCA\Social\Service\ActivityPub\Object\NoteService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\ActivityService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\CurlService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
|
@ -54,10 +53,10 @@ class NoteCreate extends Base {
|
|||
/** @var ActivityService */
|
||||
private $activityService;
|
||||
|
||||
/** @var ActorService */
|
||||
/** @var AccountService */
|
||||
private $actorService;
|
||||
|
||||
/** @var NoteService */
|
||||
/** @var PostService */
|
||||
private $postService;
|
||||
|
||||
/** @var CurlService */
|
||||
|
@ -71,14 +70,14 @@ class NoteCreate extends Base {
|
|||
* NoteCreate constructor.
|
||||
*
|
||||
* @param ActivityService $activityService
|
||||
* @param ActorService $actorService
|
||||
* @param AccountService $actorService
|
||||
* @param PostService $postService
|
||||
* @param CurlService $curlService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
ActivityService $activityService, ActorService $actorService,
|
||||
ActivityService $activityService, AccountService $actorService,
|
||||
PostService $postService, CurlService $curlService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace OCA\Social\Controller;
|
|||
use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
|
||||
use Exception;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
|
@ -61,7 +61,7 @@ class AccountController extends Controller {
|
|||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var ActorService */
|
||||
/** @var AccountService */
|
||||
private $actorService;
|
||||
|
||||
/** @var MiscService */
|
||||
|
@ -77,14 +77,14 @@ class AccountController extends Controller {
|
|||
* @param IRequest $request
|
||||
* @param IUserManager $userManager
|
||||
* @param ConfigService $configService
|
||||
* @param ActorService $actorService
|
||||
* @param AccountService $actorService
|
||||
* @param MiscService $miscService
|
||||
* @param IAccountManager $accountManager
|
||||
* @param string $userId
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, $userId, IUserManager $userManager, ConfigService $configService,
|
||||
ActorService $actorService, MiscService $miscService,
|
||||
AccountService $actorService, MiscService $miscService,
|
||||
IAccountManager $accountManager
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
@ -121,6 +121,9 @@ class AccountController extends Controller {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* // TODO - is it still used ? maybe using info from LocalController !?
|
||||
*
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
* @NoAdminRequired
|
||||
|
|
|
@ -34,15 +34,13 @@ use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
|
|||
use Exception;
|
||||
use OC\AppFramework\Http;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Db\NotesRequest;
|
||||
use OCA\Social\Exceptions\SignatureIsGoneException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Service\ActivityPub\Activity\FollowService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActivityService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\ImportService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCA\Social\Service\SignatureService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IRequest;
|
||||
|
@ -57,8 +55,11 @@ class ActivityPubController extends Controller {
|
|||
/** @var SocialPubController */
|
||||
private $socialPubController;
|
||||
|
||||
/** @var ActivityService */
|
||||
private $activityService;
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var SignatureService */
|
||||
private $signatureService;
|
||||
|
||||
/** @var ImportService */
|
||||
private $importService;
|
||||
|
@ -66,15 +67,6 @@ class ActivityPubController extends Controller {
|
|||
/** @var FollowService */
|
||||
private $followService;
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
|
||||
/** @var NotesRequest */
|
||||
private $notesRequest;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
@ -84,30 +76,24 @@ class ActivityPubController extends Controller {
|
|||
*
|
||||
* @param IRequest $request
|
||||
* @param SocialPubController $socialPubController
|
||||
* @param ActivityService $activityService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param SignatureService $signatureService
|
||||
* @param ImportService $importService
|
||||
* @param FollowService $followService
|
||||
* @param ActorService $actorService
|
||||
* @param PersonService $personService
|
||||
* @param NotesRequest $notesRequest
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, SocialPubController $socialPubController,
|
||||
ActivityService $activityService, ImportService $importService,
|
||||
FollowService $followService, ActorService $actorService, PersonService $personService,
|
||||
NotesRequest $notesRequest, MiscService $miscService
|
||||
CacheActorService $cacheActorService, SignatureService $signatureService,
|
||||
ImportService $importService, FollowService $followService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->socialPubController = $socialPubController;
|
||||
|
||||
$this->activityService = $activityService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->signatureService = $signatureService;
|
||||
$this->importService = $importService;
|
||||
$this->followService = $followService;
|
||||
$this->actorService = $actorService;
|
||||
$this->personService = $personService;
|
||||
$this->notesRequest = $notesRequest;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
@ -133,7 +119,7 @@ class ActivityPubController extends Controller {
|
|||
}
|
||||
|
||||
try {
|
||||
$actor = $this->personService->getFromLocalAccount($username);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
|
||||
// $actor->setTopLevel(true);
|
||||
|
||||
|
@ -177,10 +163,11 @@ class ActivityPubController extends Controller {
|
|||
$body = file_get_contents('php://input');
|
||||
$this->miscService->log('[<<] shared-inbox: ' . $body, 1);
|
||||
|
||||
$origin = $this->activityService->checkRequest($this->request);
|
||||
$origin = $this->signatureService->checkRequest($this->request);
|
||||
|
||||
$activity = $this->importService->importFromJson($body);
|
||||
$activity->setOrigin($origin);
|
||||
|
||||
try {
|
||||
$this->importService->parseIncomingRequest($activity);
|
||||
} catch (UnknownItemException $e) {
|
||||
|
@ -212,7 +199,7 @@ class ActivityPubController extends Controller {
|
|||
$body = file_get_contents('php://input');
|
||||
$this->miscService->log('[<<] inbox: ' . $body, 1);
|
||||
|
||||
$origin = $this->activityService->checkRequest($this->request);
|
||||
$origin = $this->signatureService->checkRequest($this->request);
|
||||
|
||||
// TODO - check the recipient <-> username
|
||||
// $actor = $this->actorService->getActor($username);
|
||||
|
@ -265,7 +252,7 @@ class ActivityPubController extends Controller {
|
|||
}
|
||||
|
||||
try {
|
||||
$actor = $this->actorService->getActor($username);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
$followers = $this->followService->getFollowersCollection($actor);
|
||||
|
||||
// $followers->setTopLevel(true);
|
||||
|
|
|
@ -38,13 +38,14 @@ use OCA\Social\Exceptions\AccountDoesNotExistException;
|
|||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||
use OCA\Social\Model\Post;
|
||||
use OCA\Social\Service\ActivityPub\Object\DocumentService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\FollowService;
|
||||
use OCA\Social\Service\ActivityPub\Object\NoteService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\DocumentService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCA\Social\Service\NoteService;
|
||||
use OCA\Social\Service\PostService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
|
@ -69,21 +70,21 @@ class LocalController extends Controller {
|
|||
/** @var string */
|
||||
private $userId;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var FollowService */
|
||||
private $followService;
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
|
||||
/** @var PostService */
|
||||
private $postService;
|
||||
|
||||
/** @var NoteService */
|
||||
private $noteService;
|
||||
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
/** @var DocumentService */
|
||||
private $documentService;
|
||||
|
||||
|
@ -100,30 +101,28 @@ class LocalController extends Controller {
|
|||
*
|
||||
* @param IRequest $request
|
||||
* @param string $userId
|
||||
* @param PersonService $personService
|
||||
* @param AccountService $accountService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param FollowService $followService
|
||||
* @param ActorService $actorService
|
||||
* @param PostService $postService
|
||||
* @param NoteService $noteService
|
||||
* @param DocumentService $documentService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, $userId, PersonService $personService,
|
||||
FollowService $followService, ActorService $actorService,
|
||||
PostService $postService, NoteService $noteService,
|
||||
DocumentService $documentService,
|
||||
IRequest $request, $userId, AccountService $accountService,
|
||||
CacheActorService $cacheActorService, FollowService $followService,
|
||||
PostService $postService, NoteService $noteService, DocumentService $documentService,
|
||||
MiscService $miscService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->userId = $userId;
|
||||
|
||||
$this->actorService = $actorService;
|
||||
$this->personService = $personService;
|
||||
$this->followService = $followService;
|
||||
$this->postService = $postService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->accountService = $accountService;
|
||||
$this->noteService = $noteService;
|
||||
$this->postService = $postService;
|
||||
$this->followService = $followService;
|
||||
$this->documentService = $documentService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
@ -146,7 +145,7 @@ class LocalController extends Controller {
|
|||
$post->setReplyTo($this->get('replyTo', $data, ''));
|
||||
$post->setTo($this->getArray('to', $data, []));
|
||||
$post->addTo($this->get('to', $data, ''));
|
||||
$post->setType($this->get('type', $data, NoteService::TYPE_PUBLIC));
|
||||
$post->setType($this->get('type', $data, Note::TYPE_PUBLIC));
|
||||
|
||||
/** @var ACore $activity */
|
||||
$token = $this->postService->createPost($post, $activity);
|
||||
|
@ -179,7 +178,7 @@ class LocalController extends Controller {
|
|||
public function postDelete(string $id): DataResponse {
|
||||
try {
|
||||
$note = $this->noteService->getNoteById($id);
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->accountService->getActorFromUserId($this->userId);
|
||||
if ($note->getAttributedTo() !== $actor->getId()) {
|
||||
throw new InvalidResourceException('user have no rights');
|
||||
}
|
||||
|
@ -234,7 +233,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$account = $this->actorService->getActor($username);
|
||||
$account = $this->cacheActorService->getFromLocalAccount($username);
|
||||
$posts = $this->noteService->getStreamAccount($account->getId(), $since, $limit);
|
||||
|
||||
return $this->success($posts);
|
||||
|
@ -331,7 +330,7 @@ class LocalController extends Controller {
|
|||
*/
|
||||
public function actionFollow(string $account): DataResponse {
|
||||
try {
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->accountService->getActorFromUserId($this->userId);
|
||||
$this->followService->followAccount($actor, $account);
|
||||
|
||||
return $this->success([]);
|
||||
|
@ -355,7 +354,7 @@ class LocalController extends Controller {
|
|||
*/
|
||||
public function actionUnfollow(string $account): DataResponse {
|
||||
try {
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->accountService->getActorFromUserId($this->userId);
|
||||
$this->followService->unfollowAccount($actor, $account);
|
||||
|
||||
return $this->success([]);
|
||||
|
@ -377,8 +376,8 @@ class LocalController extends Controller {
|
|||
*/
|
||||
public function currentInfo(): DataResponse {
|
||||
try {
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->personService->getFromLocalAccount($actor->getPreferredUsername());
|
||||
$local = $this->accountService->getActorFromUserId($this->userId);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($local->getPreferredUsername());
|
||||
|
||||
return $this->success(['account' => $actor]);
|
||||
} catch (Exception $e) {
|
||||
|
@ -398,7 +397,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->accountService->getActorFromUserId($this->userId);
|
||||
$followers = $this->followService->getFollowers($actor);
|
||||
|
||||
return $this->success($followers);
|
||||
|
@ -419,7 +418,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->actorService->getActorFromUserId($this->userId);
|
||||
$actor = $this->accountService->getActorFromUserId($this->userId);
|
||||
$followers = $this->followService->getFollowing($actor);
|
||||
|
||||
return $this->success($followers);
|
||||
|
@ -445,8 +444,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->actorService->getActor($username);
|
||||
$actor = $this->personService->getFromLocalAccount($actor->getPreferredUsername());
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
|
||||
return $this->success(['account' => $actor]);
|
||||
} catch (Exception $e) {
|
||||
|
@ -468,7 +466,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->actorService->getActor($username);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
$followers = $this->followService->getFollowers($actor);
|
||||
|
||||
return $this->success($followers);
|
||||
|
@ -492,7 +490,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->actorService->getActor($username);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
$following = $this->followService->getFollowing($actor);
|
||||
|
||||
return $this->success($following);
|
||||
|
@ -518,7 +516,7 @@ class LocalController extends Controller {
|
|||
try {
|
||||
$this->initViewer();
|
||||
|
||||
$actor = $this->personService->getFromAccount($account);
|
||||
$actor = $this->cacheActorService->getFromAccount($account);
|
||||
|
||||
return $this->success(['account' => $actor]);
|
||||
} catch (Exception $e) {
|
||||
|
@ -542,7 +540,7 @@ class LocalController extends Controller {
|
|||
public function globalActorInfo(string $id): DataResponse {
|
||||
try {
|
||||
$this->initViewer();
|
||||
$actor = $this->personService->getFromId($id);
|
||||
$actor = $this->cacheActorService->getFromId($id);
|
||||
|
||||
return $this->success(['actor' => $actor]);
|
||||
} catch (Exception $e) {
|
||||
|
@ -561,7 +559,7 @@ class LocalController extends Controller {
|
|||
*/
|
||||
public function globalActorAvatar(string $id): Response {
|
||||
try {
|
||||
$actor = $this->personService->getFromId($id);
|
||||
$actor = $this->cacheActorService->getFromId($id);
|
||||
if ($actor->gotIcon()) {
|
||||
$avatar = $actor->getIcon();
|
||||
$document = $this->documentService->getFromCache($avatar->getId());
|
||||
|
@ -606,13 +604,13 @@ class LocalController extends Controller {
|
|||
/* Look for an exactly matching account */
|
||||
$match = null;
|
||||
try {
|
||||
$match = $this->personService->getFromAccount($search, false);
|
||||
$match = $this->cacheActorService->getFromAccount($search, false);
|
||||
$match->setCompleteDetails(true);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$accounts = $this->personService->searchCachedAccounts($search);
|
||||
$accounts = $this->cacheActorService->searchCachedAccounts($search);
|
||||
|
||||
return $this->success(['accounts' => $accounts, 'exact' => $match]);
|
||||
} catch (Exception $e) {
|
||||
|
@ -658,11 +656,10 @@ class LocalController extends Controller {
|
|||
*/
|
||||
private function initViewer(bool $exception = false) {
|
||||
try {
|
||||
$this->viewer = $this->actorService->getActorFromUserId($this->userId, true);
|
||||
$this->viewer = $this->accountService->getActorFromUserId($this->userId, true);
|
||||
|
||||
$this->followService->setViewerId($this->viewer->getId());
|
||||
$this->personService->setViewerId($this->viewer->getId());
|
||||
$this->noteService->setViewerId($this->viewer->getId());
|
||||
$this->cacheActorService->setViewerId($this->viewer->getId());
|
||||
} catch (Exception $e) {
|
||||
if ($exception) {
|
||||
throw new AccountDoesNotExistException();
|
||||
|
|
|
@ -37,11 +37,11 @@ use OC\User\NoUserException;
|
|||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\AccountAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Service\ActivityPub\Object\DocumentService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CheckService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\DocumentService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
|
@ -69,8 +69,8 @@ class NavigationController extends Controller {
|
|||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
private $documentService;
|
||||
|
||||
|
@ -83,46 +83,40 @@ class NavigationController extends Controller {
|
|||
/** @var IL10N */
|
||||
private $l10n;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
|
||||
/** @var CheckService */
|
||||
private $checkService;
|
||||
|
||||
/**
|
||||
* NavigationController constructor.
|
||||
*
|
||||
* @param IL10N $l10n
|
||||
* @param IRequest $request
|
||||
* @param string $userId
|
||||
* @param IConfig $config
|
||||
* @param IURLGenerator $urlGenerator
|
||||
* @param ActorService $actorService
|
||||
* @param AccountService $accountService
|
||||
* @param DocumentService $documentService
|
||||
* @param ConfigService $configService
|
||||
* @param PersonService $personService
|
||||
* @param CheckService $checkService
|
||||
* @param MiscService $miscService
|
||||
* @param IL10N $l10n
|
||||
*/
|
||||
public function __construct(
|
||||
IRequest $request, $userId, IConfig $config, IURLGenerator $urlGenerator,
|
||||
ActorService $actorService, DocumentService $documentService, ConfigService $configService,
|
||||
PersonService $personService, CheckService $checkService,
|
||||
MiscService $miscService, IL10N $l10n
|
||||
IL10N $l10n, IRequest $request, $userId, IConfig $config, IURLGenerator $urlGenerator,
|
||||
AccountService $accountService, DocumentService $documentService,
|
||||
ConfigService $configService, CheckService $checkService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->userId = $userId;
|
||||
$this->l10n = $l10n;
|
||||
$this->config = $config;
|
||||
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->checkService = $checkService;
|
||||
|
||||
$this->actorService = $actorService;
|
||||
$this->accountService = $accountService;
|
||||
$this->documentService = $documentService;
|
||||
$this->configService = $configService;
|
||||
$this->personService = $personService;
|
||||
$this->miscService = $miscService;
|
||||
$this->l10n = $l10n;
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,6 +130,7 @@ class NavigationController extends Controller {
|
|||
* @param string $path
|
||||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
*/
|
||||
public function navigate(string $path = ''): TemplateResponse {
|
||||
$data = [
|
||||
|
@ -143,7 +138,8 @@ class NavigationController extends Controller {
|
|||
'public' => false,
|
||||
'firstrun' => false,
|
||||
'setup' => false,
|
||||
'isAdmin' => \OC::$server->getGroupManager()->isAdmin($this->userId),
|
||||
'isAdmin' => \OC::$server->getGroupManager()
|
||||
->isAdmin($this->userId),
|
||||
'cliUrl' => $this->getCliUrl()
|
||||
]
|
||||
];
|
||||
|
@ -152,7 +148,7 @@ class NavigationController extends Controller {
|
|||
$data['serverData']['cloudAddress'] = $this->configService->getCloudAddress();
|
||||
} catch (SocialAppConfigException $e) {
|
||||
$cloudAddress = $this->setupCloudAddress();
|
||||
if ($cloudAddress !== ''){
|
||||
if ($cloudAddress !== '') {
|
||||
$data['serverData']['cloudAddress'] = $cloudAddress;
|
||||
} else {
|
||||
$data['serverData']['setup'] = true;
|
||||
|
@ -177,7 +173,7 @@ class NavigationController extends Controller {
|
|||
* Create social user account if it doesn't exist yet
|
||||
*/
|
||||
try {
|
||||
$this->actorService->createActor($this->userId, $this->userId);
|
||||
$this->accountService->createActor($this->userId, $this->userId);
|
||||
$data['serverData']['firstrun'] = true;
|
||||
} catch (AccountAlreadyExistsException $e) {
|
||||
// we do nothing
|
||||
|
@ -191,7 +187,9 @@ class NavigationController extends Controller {
|
|||
}
|
||||
|
||||
private function setupCloudAddress(): string {
|
||||
$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
|
||||
$frontControllerActive =
|
||||
($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true
|
||||
|| getenv('front_controller_active') === 'true');
|
||||
|
||||
$cloudAddress = rtrim($this->config->getSystemValue('overwrite.cli.url', ''), '/');
|
||||
if ($cloudAddress !== '') {
|
||||
|
@ -199,17 +197,22 @@ class NavigationController extends Controller {
|
|||
$cloudAddress .= '/index.php';
|
||||
}
|
||||
$this->configService->setCloudAddress($cloudAddress);
|
||||
|
||||
return $cloudAddress;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private function getCliUrl() {
|
||||
$url = rtrim($this->urlGenerator->getBaseUrl(), '/');
|
||||
$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
|
||||
$frontControllerActive =
|
||||
($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true
|
||||
|| getenv('front_controller_active') === 'true');
|
||||
if (!$frontControllerActive) {
|
||||
$url .= '/index.php';
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
@ -251,6 +254,7 @@ class NavigationController extends Controller {
|
|||
* @param string $path
|
||||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
*/
|
||||
public function timeline(string $path = ''): TemplateResponse {
|
||||
return $this->navigate();
|
||||
|
@ -266,6 +270,7 @@ class NavigationController extends Controller {
|
|||
* @param string $path
|
||||
*
|
||||
* @return TemplateResponse
|
||||
* @throws UrlCloudException
|
||||
*/
|
||||
public function account(string $path = ''): TemplateResponse {
|
||||
return $this->navigate();
|
||||
|
|
|
@ -30,10 +30,13 @@ declare(strict_types=1);
|
|||
namespace OCA\Social\Controller;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Traits\TAsync;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Model\RequestQueue;
|
||||
use OCA\Social\Service\ActivityService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
|
@ -105,6 +108,9 @@ class QueueController extends Controller {
|
|||
$this->activityService->manageRequest($request);
|
||||
} catch (RequestException $e) {
|
||||
} catch (SocialAppConfigException $e) {
|
||||
} catch (RedundancyLimitException $e) {
|
||||
} catch (UnknownItemException $e) {
|
||||
} catch (MalformedArrayException $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,9 @@ use Exception;
|
|||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\FollowService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
|
@ -57,11 +58,14 @@ class SocialPubController extends Controller {
|
|||
/** @var IL10N */
|
||||
private $l10n;
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var FollowService */
|
||||
private $followService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
@ -73,20 +77,22 @@ class SocialPubController extends Controller {
|
|||
* @param $userId
|
||||
* @param IRequest $request
|
||||
* @param IL10N $l10n
|
||||
* @param ActorService $actorService
|
||||
* @param PersonService $personService
|
||||
* @param AccountService $accountService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param FollowService $followService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
$userId, IRequest $request, IL10N $l10n, ActorService $actorService,
|
||||
PersonService $personService, MiscService $miscService
|
||||
$userId, IRequest $request, IL10N $l10n, AccountService $accountService,
|
||||
CacheActorService $cacheActorService, FollowService $followService, MiscService $miscService
|
||||
) {
|
||||
parent::__construct(Application::APP_NAME, $request);
|
||||
|
||||
$this->userId = $userId;
|
||||
$this->l10n = $l10n;
|
||||
$this->actorService = $actorService;
|
||||
$this->personService = $personService;
|
||||
$this->accountService = $accountService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->followService = $followService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
@ -105,14 +111,14 @@ class SocialPubController extends Controller {
|
|||
public function actor(string $username): Response {
|
||||
|
||||
try {
|
||||
$actor = $this->personService->getFromLocalAccount($username);
|
||||
$actor = $this->cacheActorService->getFromLocalAccount($username);
|
||||
$actor->setCompleteDetails(true);
|
||||
|
||||
$logged = false;
|
||||
$ownAccount = false;
|
||||
if ($this->userId !== null) {
|
||||
$logged = true;
|
||||
$local = $this->actorService->getActorFromUserId($this->userId, true);
|
||||
$local = $this->accountService->getActorFromUserId($this->userId, true);
|
||||
if ($local->getId() === $actor->getId()) {
|
||||
$ownAccount = true;
|
||||
} else {
|
||||
|
@ -195,7 +201,7 @@ class SocialPubController extends Controller {
|
|||
* @param Person $local
|
||||
*/
|
||||
private function fillActorWithLinks(Person $actor, Person $local) {
|
||||
$links = $this->actorService->getLinksBetweenPersons($local, $actor);
|
||||
$links = $this->followService->getLinksBetweenPersons($local, $actor);
|
||||
$actor->addDetailArray('link', $links);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ namespace OCA\Social\Cron;
|
|||
use Exception;
|
||||
use OC\BackgroundJob\TimedJob;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Service\ActivityPub\Object\DocumentService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCA\Social\Service\ActorService;
|
||||
use OCA\Social\Service\AccountService;
|
||||
use OCA\Social\Service\CacheActorService;
|
||||
use OCA\Social\Service\ConfigService;
|
||||
use OCA\Social\Service\DocumentService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCP\AppFramework\QueryException;
|
||||
|
||||
|
@ -50,11 +50,11 @@ use OCP\AppFramework\QueryException;
|
|||
class Cache extends TimedJob {
|
||||
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var DocumentService */
|
||||
private $documentService;
|
||||
|
@ -83,8 +83,8 @@ class Cache extends TimedJob {
|
|||
$app = new Application();
|
||||
$c = $app->getContainer();
|
||||
|
||||
$this->actorService = $c->query(ActorService::class);
|
||||
$this->personService = $c->query(PersonService::class);
|
||||
$this->accountService = $c->query(AccountService::class);
|
||||
$this->cacheActorService = $c->query(CacheActorService::class);
|
||||
$this->documentService = $c->query(DocumentService::class);
|
||||
$this->configService = $c->query(ConfigService::class);
|
||||
$this->miscService = $c->query(MiscService::class);
|
||||
|
@ -95,12 +95,12 @@ class Cache extends TimedJob {
|
|||
|
||||
private function manageCache() {
|
||||
try {
|
||||
$this->actorService->manageCacheLocalActors();
|
||||
$this->accountService->manageCacheLocalActors();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->personService->manageCacheRemoteActors();
|
||||
$this->cacheActorService->manageCacheRemoteActors();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,13 @@ declare(strict_types=1);
|
|||
namespace OCA\Social\Cron;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use OC\BackgroundJob\TimedJob;
|
||||
use OCA\Social\AppInfo\Application;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Service\ActivityService;
|
||||
use OCA\Social\Service\MiscService;
|
||||
use OCA\Social\Service\QueueService;
|
||||
|
@ -70,7 +73,10 @@ class Queue extends TimedJob {
|
|||
/**
|
||||
* @param mixed $argument
|
||||
*
|
||||
* @throws MalformedArrayException
|
||||
* @throws QueryException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
protected function run($argument) {
|
||||
$app = new Application();
|
||||
|
@ -84,6 +90,11 @@ class Queue extends TimedJob {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws RedundancyLimitException
|
||||
* @throws UnknownItemException
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
private function manageQueue() {
|
||||
$requests = $this->queueService->getRequestStandby();
|
||||
$this->activityService->manageInit();
|
||||
|
|
|
@ -38,10 +38,9 @@ use OCA\Social\Exceptions\InvalidOriginException;
|
|||
use OCA\Social\Exceptions\InvalidResourceEntryException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Interfaces\IActivityPubInterface;
|
||||
|
||||
|
||||
abstract class ACore extends Item implements JsonSerializable {
|
||||
class ACore extends Item implements JsonSerializable {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
@ -72,8 +71,6 @@ abstract class ACore extends Item implements JsonSerializable {
|
|||
/** @var Document */
|
||||
private $icon = null;
|
||||
|
||||
/** @var IActivityPubInterface */
|
||||
private $saveAs;
|
||||
|
||||
/**
|
||||
* Core constructor.
|
||||
|
@ -168,21 +165,6 @@ abstract class ACore extends Item implements JsonSerializable {
|
|||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * @param ICoreService $class
|
||||
// */
|
||||
// public function saveAs(ICoreService $class) {
|
||||
// $this->saveAs = $class;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return ICoreService
|
||||
// */
|
||||
// public function savingAs() {
|
||||
// return $this->saveAs;
|
||||
// }
|
||||
//
|
||||
|
||||
/**
|
||||
* @param string $base
|
||||
*
|
||||
|
|
|
@ -38,12 +38,9 @@ use OCA\Social\Db\FollowsRequest;
|
|||
use OCA\Social\Db\NotesRequest;
|
||||
use OCA\Social\Exceptions\AccountAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\FollowDoesNotExistException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Interfaces\Object\DocumentInterface;
|
||||
use OCA\Social\Interfaces\Actor\PersonInterface;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\IUserManager;
|
||||
|
||||
|
@ -53,7 +50,7 @@ use OCP\IUserManager;
|
|||
*
|
||||
* @package OCA\Social\Service
|
||||
*/
|
||||
class ActorService {
|
||||
class AccountService {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
@ -74,13 +71,13 @@ class ActorService {
|
|||
/** @var NotesRequest */
|
||||
private $notesRequest;
|
||||
|
||||
/** @var PersonInterface */
|
||||
private $personService;
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
|
||||
/** @var SignatureService */
|
||||
private $signatureService;
|
||||
|
||||
/** @var DocumentInterface */
|
||||
/** @var DocumentService */
|
||||
private $documentService;
|
||||
|
||||
/** @var ConfigService */
|
||||
|
@ -98,15 +95,16 @@ class ActorService {
|
|||
* @param ActorsRequest $actorsRequest
|
||||
* @param FollowsRequest $followsRequest
|
||||
* @param NotesRequest $notesRequest
|
||||
* @param PersonInterface $personService
|
||||
* @param DocumentInterface $documentService
|
||||
* @param ActorService $actorService
|
||||
* @param DocumentService $documentService
|
||||
* @param SignatureService $signatureService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IUserManager $userManager, IAccountManager $accountManager, ActorsRequest $actorsRequest,
|
||||
FollowsRequest $followsRequest, NotesRequest $notesRequest, PersonInterface $personService,
|
||||
DocumentInterface $documentService, SignatureService $signatureService,
|
||||
FollowsRequest $followsRequest, NotesRequest $notesRequest, ActorService $actorService,
|
||||
DocumentService $documentService, SignatureService $signatureService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->userManager = $userManager;
|
||||
|
@ -114,7 +112,7 @@ class ActorService {
|
|||
$this->actorsRequest = $actorsRequest;
|
||||
$this->followsRequest = $followsRequest;
|
||||
$this->notesRequest = $notesRequest;
|
||||
$this->personService = $personService;
|
||||
$this->actorService = $actorService;
|
||||
$this->documentService = $documentService;
|
||||
$this->signatureService = $signatureService;
|
||||
$this->configService = $configService;
|
||||
|
@ -129,7 +127,6 @@ class ActorService {
|
|||
* @throws ActorDoesNotExistException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
|
||||
public function getActor(string $username): Person {
|
||||
$actor = $this->actorsRequest->getFromUsername($username);
|
||||
|
||||
|
@ -143,7 +140,7 @@ class ActorService {
|
|||
* @throws ActorDoesNotExistException
|
||||
* @throws SocialAppConfigException
|
||||
*/
|
||||
public function getActorById(string $id): Person {
|
||||
public function getFromId(string $id): Person {
|
||||
$actor = $this->actorsRequest->getFromId($id);
|
||||
|
||||
return $actor;
|
||||
|
@ -228,35 +225,6 @@ class ActorService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $local
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLinksBetweenPersons(Person $local, Person $actor): array {
|
||||
|
||||
$links = [
|
||||
'follower' => false,
|
||||
'following' => false
|
||||
];
|
||||
|
||||
try {
|
||||
$this->followsRequest->getByPersons($local->getId(), $actor->getId());
|
||||
$links['following'] = true;
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->followsRequest->getByPersons($actor->getId(), $local->getId());
|
||||
$links['follower'] = true;
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param bool $refresh
|
||||
|
@ -284,8 +252,7 @@ class ActorService {
|
|||
];
|
||||
$actor->addDetailArray('count', $count);
|
||||
|
||||
|
||||
$this->personService->cacheLocalActor($actor, $refresh);
|
||||
$this->actorService->cacheLocalActor($actor, $refresh);
|
||||
} catch (ActorDoesNotExistException $e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,23 +33,20 @@ namespace OCA\Social\Service;
|
|||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Model\Request;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use OCA\Social\Db\ActorsRequest;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Db\FollowsRequest;
|
||||
use OCA\Social\Db\NotesRequest;
|
||||
use OCA\Social\Exceptions\ActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\EmptyQueueException;
|
||||
use OCA\Social\Exceptions\InvalidOriginException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\NoHighPriorityRequestException;
|
||||
use OCA\Social\Exceptions\QueueStatusException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SignatureException;
|
||||
use OCA\Social\Exceptions\SignatureIsGoneException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Create;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Delete;
|
||||
|
@ -57,8 +54,6 @@ use OCA\Social\Model\ActivityPub\Actor\Person;
|
|||
use OCA\Social\Model\ActivityPub\Object\Tombstone;
|
||||
use OCA\Social\Model\InstancePath;
|
||||
use OCA\Social\Model\RequestQueue;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
use OCP\IRequest;
|
||||
|
||||
class ActivityService {
|
||||
|
||||
|
@ -81,9 +76,6 @@ class ActivityService {
|
|||
const DATE_DELAY = 30;
|
||||
|
||||
|
||||
/** @var ActorsRequest */
|
||||
private $actorsRequest;
|
||||
|
||||
/** @var NotesRequest */
|
||||
private $notesRequest;
|
||||
|
||||
|
@ -93,14 +85,8 @@ class ActivityService {
|
|||
/** @var QueueService */
|
||||
private $queueService;
|
||||
|
||||
/** @var ActorService */
|
||||
private $actorService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
|
||||
/** @var InstanceService */
|
||||
private $instanceService;
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
@ -119,31 +105,24 @@ class ActivityService {
|
|||
/**
|
||||
* ActivityService constructor.
|
||||
*
|
||||
* @param QueueService $queueService
|
||||
* @param ActorsRequest $actorsRequest
|
||||
* @param NotesRequest $notesRequest
|
||||
* @param FollowsRequest $followsRequest
|
||||
* @param QueueService $queueService
|
||||
* @param AccountService $accountService
|
||||
* @param CurlService $curlService
|
||||
* @param ActorService $actorService
|
||||
* @param PersonService $personService
|
||||
* @param InstanceService $instanceService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
ActorsRequest $actorsRequest, NotesRequest $notesRequest, FollowsRequest $followsRequest,
|
||||
QueueService $queueService, CurlService $curlService, ActorService $actorService,
|
||||
PersonService $personService, InstanceService $instanceService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
NotesRequest $notesRequest, FollowsRequest $followsRequest, QueueService $queueService,
|
||||
AccountService $accountService,
|
||||
CurlService $curlService, ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->actorsRequest = $actorsRequest;
|
||||
$this->notesRequest = $notesRequest;
|
||||
$this->followsRequest = $followsRequest;
|
||||
$this->queueService = $queueService;
|
||||
$this->accountService = $accountService;
|
||||
$this->curlService = $curlService;
|
||||
$this->actorService = $actorService;
|
||||
$this->personService = $personService;
|
||||
$this->instanceService = $instanceService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
@ -212,14 +191,14 @@ class ActivityService {
|
|||
}
|
||||
|
||||
$requests = [
|
||||
$this->notesRequest
|
||||
'Note'
|
||||
];
|
||||
|
||||
foreach ($requests as $request) {
|
||||
try {
|
||||
$toDelete = $request->getNoteById($id);
|
||||
$interface = AP::$activityPub->getInterfaceFromType($request);
|
||||
|
||||
return $toDelete;
|
||||
return $interface->getItemById($id);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +286,8 @@ class ActivityService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/** // ====> instanceService
|
||||
*
|
||||
* @param ACore $activity
|
||||
*
|
||||
* @return InstancePath[]
|
||||
|
@ -382,11 +362,11 @@ class ActivityService {
|
|||
$date = gmdate(self::DATE_FORMAT);
|
||||
$localActor = $this->getActorFromAuthor($queue->getAuthor());
|
||||
|
||||
// TODO: move this to SignatureService ?
|
||||
$localActorLink =
|
||||
$this->configService->getUrlSocial() . '@' . $localActor->getPreferredUsername();
|
||||
$signature = "(request-target): post " . $path->getPath() . "\nhost: " . $path->getAddress()
|
||||
. "\ndate: " . $date;
|
||||
|
||||
openssl_sign($signature, $signed, $localActor->getPrivateKey(), OPENSSL_ALGO_SHA256);
|
||||
|
||||
$signed = base64_encode($signed);
|
||||
|
@ -414,44 +394,6 @@ class ActivityService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RequestException
|
||||
* @throws SignatureException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws SignatureIsGoneException
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
public function checkRequest(IRequest $request): string {
|
||||
// TODO : check host is our current host.
|
||||
|
||||
// $host = $request->getHeader('host');
|
||||
// if ($host === '') {
|
||||
// throw new SignatureException('host is not set');
|
||||
// }
|
||||
|
||||
$dTime = new DateTime($request->getHeader('date'));
|
||||
$dTime->format(self::DATE_FORMAT);
|
||||
|
||||
if ($dTime->getTimestamp() < (time() - self::DATE_DELAY)) {
|
||||
throw new SignatureException('object is too old');
|
||||
}
|
||||
|
||||
try {
|
||||
$origin = $this->checkSignature($request);
|
||||
} catch (Request410Exception $e) {
|
||||
throw new SignatureIsGoneException();
|
||||
}
|
||||
|
||||
return $origin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ACore $activity
|
||||
*
|
||||
|
@ -471,144 +413,157 @@ class ActivityService {
|
|||
* @param string $author
|
||||
*
|
||||
* @return Person
|
||||
* @throws ActorDoesNotExistException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws ActorDoesNotExistException
|
||||
*/
|
||||
private function getActorFromAuthor(string $author): Person {
|
||||
return $this->actorService->getActorById($author);
|
||||
return $this->accountService->getFromId($author);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SignatureException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
private function checkSignature(IRequest $request): string {
|
||||
$signatureHeader = $request->getHeader('Signature');
|
||||
// /**
|
||||
// * @param IRequest $request
|
||||
// *
|
||||
// * @return string
|
||||
// * @throws InvalidResourceException
|
||||
// * @throws MalformedArrayException
|
||||
// * @throws Request410Exception
|
||||
// * @throws RequestException
|
||||
// * @throws SignatureException
|
||||
// * @throws SocialAppConfigException
|
||||
// * @throws UrlCloudException
|
||||
// * @throws InvalidOriginException
|
||||
// */
|
||||
// private function checkSignature(IRequest $request): string {
|
||||
// $signatureHeader = $request->getHeader('Signature');
|
||||
//
|
||||
// $sign = $this->parseSignatureHeader($signatureHeader);
|
||||
// $this->mustContains(['keyId', 'headers', 'signature'], $sign);
|
||||
//
|
||||
// $keyId = $sign['keyId'];
|
||||
// $origin = $this->getKeyOrigin($keyId);
|
||||
//
|
||||
// $headers = $sign['headers'];
|
||||
// $signed = base64_decode($sign['signature']);
|
||||
// $estimated = $this->generateEstimatedSignature($headers, $request);
|
||||
//
|
||||
// $publicKey = $this->retrieveKey($keyId);
|
||||
//
|
||||
// if ($publicKey === '' || openssl_verify($estimated, $signed, $publicKey, 'sha256') !== 1) {
|
||||
// throw new SignatureException('signature cannot be checked');
|
||||
// }
|
||||
//
|
||||
// return $origin;
|
||||
// }
|
||||
//
|
||||
|
||||
$sign = $this->parseSignatureHeader($signatureHeader);
|
||||
$this->mustContains(['keyId', 'headers', 'signature'], $sign);
|
||||
|
||||
$keyId = $sign['keyId'];
|
||||
$origin = $this->getKeyOrigin($keyId);
|
||||
|
||||
$headers = $sign['headers'];
|
||||
$signed = base64_decode($sign['signature']);
|
||||
$estimated = $this->generateEstimatedSignature($headers, $request);
|
||||
|
||||
$publicKey = $this->retrieveKey($keyId);
|
||||
|
||||
if ($publicKey === '' || openssl_verify($estimated, $signed, $publicKey, 'sha256') !== 1) {
|
||||
throw new SignatureException('signature cannot be checked');
|
||||
}
|
||||
|
||||
return $origin;
|
||||
}
|
||||
// /**
|
||||
// * @param $id
|
||||
// *
|
||||
// * @return string
|
||||
// * @throws InvalidOriginException
|
||||
// */
|
||||
// private function getKeyOrigin($id) {
|
||||
// $host = parse_url($id, PHP_URL_HOST);
|
||||
// if (is_string($host) && ($host !== '')) {
|
||||
// return $host;
|
||||
// }
|
||||
//
|
||||
// throw new InvalidOriginException();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @param string $headers
|
||||
// * @param IRequest $request
|
||||
// *
|
||||
// * @return string
|
||||
// */
|
||||
// private function generateEstimatedSignature(string $headers, IRequest $request): string {
|
||||
// $keys = explode(' ', $headers);
|
||||
//
|
||||
// $target = '';
|
||||
// try {
|
||||
// $target = strtolower($request->getMethod()) . " " . $request->getRequestUri();
|
||||
// } catch (Exception $e) {
|
||||
// }
|
||||
//
|
||||
// $estimated = "(request-target): " . $target;
|
||||
//
|
||||
// foreach ($keys as $key) {
|
||||
// if ($key === '(request-target)') {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// $estimated .= "\n" . $key . ': ' . $request->getHeader($key);
|
||||
// }
|
||||
//
|
||||
// return $estimated;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * @param $signatureHeader
|
||||
// *
|
||||
// * @return array
|
||||
// */
|
||||
// private function parseSignatureHeader($signatureHeader) {
|
||||
// $sign = [];
|
||||
//
|
||||
// $entries = explode(',', $signatureHeader);
|
||||
// foreach ($entries as $entry) {
|
||||
// list($k, $v) = explode('=', $entry, 2);
|
||||
// preg_match('/"([^"]+)"/', $v, $varr);
|
||||
// $v = trim($varr[0], '"');
|
||||
//
|
||||
// $sign[$k] = $v;
|
||||
// }
|
||||
//
|
||||
// return $sign;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
private function getKeyOrigin($id) {
|
||||
$host = parse_url($id, PHP_URL_HOST);
|
||||
if (is_string($host) && ($host !== '')) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
throw new InvalidOriginException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $headers
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateEstimatedSignature(string $headers, IRequest $request): string {
|
||||
$keys = explode(' ', $headers);
|
||||
|
||||
$target = '';
|
||||
try {
|
||||
$target = strtolower($request->getMethod()) . " " . $request->getRequestUri();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$estimated = "(request-target): " . $target;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($key === '(request-target)') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$estimated .= "\n" . $key . ': ' . $request->getHeader($key);
|
||||
}
|
||||
|
||||
return $estimated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $signatureHeader
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseSignatureHeader($signatureHeader) {
|
||||
$sign = [];
|
||||
|
||||
$entries = explode(',', $signatureHeader);
|
||||
foreach ($entries as $entry) {
|
||||
list($k, $v) = explode('=', $entry, 2);
|
||||
preg_match('/"([^"]+)"/', $v, $varr);
|
||||
$v = trim($varr[0], '"');
|
||||
|
||||
$sign[$k] = $v;
|
||||
}
|
||||
|
||||
return $sign;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $keyId
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidResourceException
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws Request410Exception
|
||||
*/
|
||||
private function retrieveKey($keyId): string {
|
||||
$actor = $this->personService->getFromId($keyId);
|
||||
|
||||
return $actor->getPublicKey();
|
||||
}
|
||||
// /**
|
||||
// * @param $keyId
|
||||
// *
|
||||
// * @return string
|
||||
// * @throws InvalidResourceException
|
||||
// * @throws RequestException
|
||||
// * @throws SocialAppConfigException
|
||||
// * @throws UrlCloudException
|
||||
// * @throws Request410Exception
|
||||
// */
|
||||
// private function retrieveKey($keyId): string {
|
||||
// $actor = $this->cacheActorService->getFromId($keyId);
|
||||
//
|
||||
// return $actor->getPublicKey();
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param ACore $activity
|
||||
*/
|
||||
private function saveActivity(ACore $activity) {
|
||||
$coreService = $activity->savingAs();
|
||||
if ($coreService !== null) {
|
||||
$coreService->save($activity);
|
||||
}
|
||||
// TODO: save activity in DB ?
|
||||
|
||||
if ($activity->gotObject()) {
|
||||
$this->saveActivity($activity->getObject());
|
||||
$this->saveObject($activity->getObject());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ACore $activity
|
||||
*/
|
||||
private function saveObject(ACore $activity) {
|
||||
try {
|
||||
if ($activity->gotObject()) {
|
||||
$this->saveObject($activity->getObject());
|
||||
}
|
||||
|
||||
$service = AP::$activityPub->getInterfaceForItem($activity);
|
||||
$service->save($activity);
|
||||
} catch (UnknownItemException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Db\CacheActorsRequest;
|
||||
use OCA\Social\Db\CacheDocumentsRequest;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\CacheDocumentDoesNotExistException;
|
||||
use OCA\Social\Exceptions\InvalidResourceEntryException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
|
||||
|
||||
/**
|
||||
* Class ActorService
|
||||
*
|
||||
* @package OCA\Social\Service
|
||||
*/
|
||||
class ActorService {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var CacheActorsRequest */
|
||||
private $cacheActorsRequest;
|
||||
|
||||
/** @var CacheDocumentsRequest */
|
||||
private $cacheDocumentsRequest;
|
||||
|
||||
/** @var CurlService */
|
||||
private $curlService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $viewerId = '';
|
||||
|
||||
|
||||
/**
|
||||
* ActorService constructor.
|
||||
*
|
||||
* @param CacheActorsRequest $cacheActorsRequest
|
||||
* @param CacheDocumentsRequest $cacheDocumentsRequest
|
||||
* @param CurlService $curlService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
CacheActorsRequest $cacheActorsRequest, CacheDocumentsRequest $cacheDocumentsRequest,
|
||||
CurlService $curlService,
|
||||
ConfigService $configService,
|
||||
MiscService $miscService
|
||||
) {
|
||||
$this->cacheActorsRequest = $cacheActorsRequest;
|
||||
$this->cacheDocumentsRequest = $cacheDocumentsRequest;
|
||||
$this->curlService = $curlService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $viewerId
|
||||
*/
|
||||
public function setViewerId(string $viewerId) {
|
||||
$this->viewerId = $viewerId;
|
||||
$this->cacheActorsRequest->setViewerId($viewerId);
|
||||
}
|
||||
|
||||
public function getViewerId(): string {
|
||||
return $this->viewerId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param bool $refresh
|
||||
*/
|
||||
public function cacheLocalActor(Person $actor, bool $refresh = false) {
|
||||
if ($refresh) {
|
||||
$this->cacheActorsRequest->deleteFromId($actor->getId());
|
||||
}
|
||||
|
||||
$actor->setLocal(true);
|
||||
$actor->setSource(json_encode($actor, JSON_UNESCAPED_SLASHES));
|
||||
|
||||
$this->save($actor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @param bool $refresh
|
||||
*
|
||||
* @return Person
|
||||
* @throws InvalidResourceException
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws Request410Exception
|
||||
* @throws MalformedArrayException
|
||||
* @throws InvalidResourceEntryException
|
||||
*/
|
||||
public function getFromId(string $id, bool $refresh = false): Person {
|
||||
|
||||
$posAnchor = strpos($id, '#');
|
||||
if ($posAnchor !== false) {
|
||||
$id = substr($id, 0, $posAnchor);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($refresh) {
|
||||
$this->cacheActorsRequest->deleteFromId($id);
|
||||
throw new CacheActorDoesNotExistException();
|
||||
}
|
||||
|
||||
$actor = $this->cacheActorsRequest->getFromId($id);
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
$object = $this->curlService->retrieveObject($id);
|
||||
$actor = $this->generateActorFromObject($object);
|
||||
$actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object));
|
||||
try {
|
||||
$this->save($actor);
|
||||
} catch (Exception $e) {
|
||||
throw new InvalidResourceException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $actor;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * @param string $account
|
||||
// *
|
||||
// * @param bool $retrieve
|
||||
// *
|
||||
// * @return Person
|
||||
// * @throws InvalidResourceException
|
||||
// * @throws RequestException
|
||||
// * @throws CacheActorDoesNotExistException
|
||||
// * @throws SocialAppConfigException
|
||||
// * @throws UrlCloudException
|
||||
// * @throws Request410Exception
|
||||
// * @throws MalformedArrayException
|
||||
// * @throws InvalidResourceEntryException
|
||||
// */
|
||||
// public function getFromAccount(string $account, bool $retrieve = true): Person {
|
||||
//
|
||||
// try {
|
||||
// $actor = $this->cacheActorsRequest->getFromAccount($account);
|
||||
// } catch (CacheActorDoesNotExistException $e) {
|
||||
// if (!$retrieve) {
|
||||
// throw new CacheActorDoesNotExistException();
|
||||
// }
|
||||
//
|
||||
// $object = $this->curlService->retrieveAccount($account);
|
||||
// $actor = $this->generateActorFromObject($object);
|
||||
// $actor->setAccount($account);
|
||||
// try {
|
||||
// $this->save($actor);
|
||||
// } catch (Exception $e) {
|
||||
// throw new InvalidResourceException($e->getMessage());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return $actor;
|
||||
// }
|
||||
|
||||
//
|
||||
// /**
|
||||
// * @param string $account
|
||||
// *
|
||||
// * @return Person
|
||||
// * @throws CacheActorDoesNotExistException
|
||||
// */
|
||||
// public function getFromLocalAccount(string $account): Person {
|
||||
// return $this->cacheActorsRequest->getFromLocalAccount($account);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param array $object
|
||||
*
|
||||
* @return Person
|
||||
* @throws InvalidResourceException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws InvalidResourceEntryException
|
||||
*/
|
||||
private function generateActorFromObject(array $object) {
|
||||
|
||||
$actor = new Person();
|
||||
$actor->setUrlCloud($this->configService->getCloudAddress());
|
||||
$actor->import($object);
|
||||
|
||||
if ($actor->getType() !== Person::TYPE) {
|
||||
throw new InvalidResourceException();
|
||||
}
|
||||
|
||||
$actor->setSource(json_encode($object, JSON_UNESCAPED_SLASHES));
|
||||
|
||||
return $actor;
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * @param string $search
|
||||
// *
|
||||
// * @return Person[]
|
||||
// */
|
||||
// public function searchCachedAccounts(string $search): array {
|
||||
// return $this->cacheActorsRequest->searchAccounts($search);
|
||||
// }
|
||||
|
||||
//
|
||||
// /**
|
||||
// * @throws Exception
|
||||
// * @return int
|
||||
// */
|
||||
// public function missingCacheRemoteActors(): int {
|
||||
// // TODO - looking for missing cache remote actors...
|
||||
// $missing = [];
|
||||
//
|
||||
// foreach ($missing as $item) {
|
||||
// try {
|
||||
// $this->getFromId($item->getId());
|
||||
// } catch (Exception $e) {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return sizeof($missing);
|
||||
// }
|
||||
|
||||
//
|
||||
// /**
|
||||
// * @throws Exception
|
||||
// * @return int
|
||||
// */
|
||||
// public function manageCacheRemoteActors(): int {
|
||||
// $update = $this->cacheActorsRequest->getRemoteActorsToUpdate();
|
||||
//
|
||||
// foreach ($update as $item) {
|
||||
// try {
|
||||
// $this->getFromId($item->getId(), true);
|
||||
// } catch (Exception $e) {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return sizeof($update);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*/
|
||||
public function save(Person $actor) {
|
||||
if ($actor->gotIcon()) {
|
||||
try {
|
||||
$icon = $this->cacheDocumentsRequest->getBySource(
|
||||
$actor->getIcon()
|
||||
->getUrl()
|
||||
);
|
||||
$actor->setIcon($icon);
|
||||
} catch (CacheDocumentDoesNotExistException $e) {
|
||||
$this->cacheDocumentsRequest->save($actor->getIcon());
|
||||
}
|
||||
}
|
||||
|
||||
$this->cacheActorsRequest->save($actor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Db\CacheActorsRequest;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
|
||||
|
||||
class CacheActorService {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var CacheActorsRequest */
|
||||
private $cacheActorsRequest;
|
||||
|
||||
/** @var CurlService */
|
||||
private $curlService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $viewerId;
|
||||
|
||||
|
||||
/**
|
||||
* CacheService constructor.
|
||||
*
|
||||
* @param CacheActorsRequest $cacheActorsRequest
|
||||
* @param CurlService $curlService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
CacheActorsRequest $cacheActorsRequest, CurlService $curlService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->cacheActorsRequest = $cacheActorsRequest;
|
||||
$this->curlService = $curlService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $viewerId
|
||||
*/
|
||||
public function setViewerId(string $viewerId) {
|
||||
$this->viewerId = $viewerId;
|
||||
$this->cacheActorsRequest->setViewerId($viewerId);
|
||||
}
|
||||
|
||||
public function getViewerId(): string {
|
||||
return $this->viewerId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @param bool $refresh
|
||||
*
|
||||
* @return Person
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function getFromId(string $id, bool $refresh = false): Person {
|
||||
|
||||
$posAnchor = strpos($id, '#');
|
||||
if ($posAnchor !== false) {
|
||||
$id = substr($id, 0, $posAnchor);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($refresh) {
|
||||
$this->cacheActorsRequest->deleteFromId($id);
|
||||
throw new CacheActorDoesNotExistException();
|
||||
}
|
||||
|
||||
$actor = $this->cacheActorsRequest->getFromId($id);
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
$object = $this->curlService->retrieveObject($id);
|
||||
|
||||
/** @var Person $actor */
|
||||
$actor = AP::$activityPub->getItemFromData($object);
|
||||
$actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object));
|
||||
try {
|
||||
$this->save($actor);
|
||||
} catch (Exception $e) {
|
||||
throw new InvalidResourceException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $actor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $account
|
||||
*
|
||||
* @return Person
|
||||
* @throws CacheActorDoesNotExistException
|
||||
*/
|
||||
public function getFromLocalAccount(string $account): Person {
|
||||
return $this->cacheActorsRequest->getFromLocalAccount($account);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $account
|
||||
*
|
||||
* @param bool $retrieve
|
||||
*
|
||||
* @return Person
|
||||
* @throws CacheActorDoesNotExistException
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function getFromAccount(string $account, bool $retrieve = true): Person {
|
||||
|
||||
try {
|
||||
$actor = $this->cacheActorsRequest->getFromAccount($account);
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
if (!$retrieve) {
|
||||
throw new CacheActorDoesNotExistException();
|
||||
}
|
||||
|
||||
$object = $this->curlService->retrieveAccount($account);
|
||||
/** @var Person $actor */
|
||||
$actor = AP::$activityPub->getItemFromData($object);
|
||||
$actor->setAccount($account);
|
||||
try {
|
||||
$this->save($actor);
|
||||
} catch (Exception $e) {
|
||||
throw new InvalidResourceException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return $actor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
*
|
||||
* @return Person[]
|
||||
*/
|
||||
public function searchCachedAccounts(string $search): array {
|
||||
return $this->cacheActorsRequest->searchAccounts($search);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return int
|
||||
*/
|
||||
public function missingCacheRemoteActors(): int {
|
||||
// TODO - looking for missing cache remote actors...
|
||||
$missing = [];
|
||||
|
||||
foreach ($missing as $item) {
|
||||
try {
|
||||
$this->getFromId($item->getId());
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof($missing);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return int
|
||||
*/
|
||||
public function manageCacheRemoteActors(): int {
|
||||
$update = $this->cacheActorsRequest->getRemoteActorsToUpdate();
|
||||
|
||||
foreach ($update as $item) {
|
||||
try {
|
||||
$this->getFromId($item->getId(), true);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
return sizeof($update);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*/
|
||||
private function save(Person $actor) {
|
||||
try {
|
||||
$interface = AP::$activityPub->getInterfaceFromType(Person::TYPE);
|
||||
$interface->save($actor);
|
||||
} catch (UnknownItemException $e) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ use OCP\Files\NotPermittedException;
|
|||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
|
||||
|
||||
class CacheService {
|
||||
class CacheDocumentService {
|
||||
|
||||
|
||||
const ERROR_MAX_SIZE = 1;
|
||||
|
|
|
@ -30,10 +30,13 @@ declare(strict_types=1);
|
|||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\ArrayNotFoundException;
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Model\Request;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use daita\MySmallPhpTools\Traits\TPathTools;
|
||||
use Exception;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
|
@ -68,6 +71,65 @@ class CurlService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $account
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RequestException
|
||||
* @throws InvalidResourceException
|
||||
* @throws Request410Exception
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
public function retrieveAccount(string $account) {
|
||||
$account = $this->withoutBeginAt($account);
|
||||
|
||||
if (strstr(substr($account, 0, -3), '@') === false) {
|
||||
throw new InvalidResourceException();
|
||||
}
|
||||
list($username, $host) = explode('@', $account);
|
||||
|
||||
// if ($username === null || $host === null) {
|
||||
// throw new InvalidResourceException();
|
||||
// }
|
||||
|
||||
$request = new Request('/.well-known/webfinger');
|
||||
$request->addData('resource', 'acct:' . $account);
|
||||
$request->setAddress($host);
|
||||
$result = $this->request($request);
|
||||
|
||||
try {
|
||||
$link = $this->extractArray('rel', 'self', $this->getArray('links', $result));
|
||||
} catch (ArrayNotFoundException $e) {
|
||||
throw new RequestException();
|
||||
}
|
||||
|
||||
return $this->retrieveObject($this->get('href', $link, ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RequestException
|
||||
* @throws Request410Exception
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
public function retrieveObject($id) {
|
||||
$url = parse_url($id);
|
||||
$this->mustContains(['path', 'host'], $url);
|
||||
$request = new Request($url['path'], Request::TYPE_GET);
|
||||
$request->setAddress($url['host']);
|
||||
|
||||
$result = $this->request($request);
|
||||
if (is_array($result)) {
|
||||
$result['_host'] = $url['host'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use Exception;
|
||||
use OCA\Social\Db\ActorsRequest;
|
||||
use OCA\Social\Db\CacheDocumentsRequest;
|
||||
use OCA\Social\Exceptions\CacheContentException;
|
||||
use OCA\Social\Exceptions\CacheContentMimeTypeException;
|
||||
use OCA\Social\Exceptions\CacheContentSizeException;
|
||||
use OCA\Social\Exceptions\CacheDocumentDoesNotExistException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Object\Image;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
|
||||
class DocumentService {
|
||||
|
||||
|
||||
const ERROR_SIZE = 1;
|
||||
const ERROR_MIMETYPE = 2;
|
||||
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
/** @var CacheDocumentsRequest */
|
||||
private $cacheDocumentsRequest;
|
||||
|
||||
/** @var ActorsRequest */
|
||||
private $actorRequest;
|
||||
|
||||
|
||||
/** @var CacheDocumentService */
|
||||
private $cacheService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/**
|
||||
* DocumentInterface constructor.
|
||||
*
|
||||
* @param IUrlGenerator $urlGenerator
|
||||
* @param CacheDocumentsRequest $cacheDocumentsRequest
|
||||
* @param ActorsRequest $actorRequest
|
||||
* @param CacheDocumentService $cacheService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
IUrlGenerator $urlGenerator, CacheDocumentsRequest $cacheDocumentsRequest,
|
||||
ActorsRequest $actorRequest,
|
||||
CacheDocumentService $cacheService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->cacheDocumentsRequest = $cacheDocumentsRequest;
|
||||
$this->actorRequest = $actorRequest;
|
||||
$this->configService = $configService;
|
||||
$this->cacheService = $cacheService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param bool $public
|
||||
*
|
||||
* @return Document
|
||||
* @throws CacheDocumentDoesNotExistException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public function cacheRemoteDocument(string $id, bool $public = false) {
|
||||
$document = $this->cacheDocumentsRequest->getById($id, $public);
|
||||
if ($document->getError() > 0) {
|
||||
throw new CacheDocumentDoesNotExistException();
|
||||
}
|
||||
|
||||
if ($document->getLocalCopy() !== '') {
|
||||
return $document;
|
||||
}
|
||||
|
||||
if ($document->getCaching() > (time() - (CacheDocumentsRequest::CACHING_TIMEOUT * 60))) {
|
||||
return $document;
|
||||
}
|
||||
|
||||
$mime = '';
|
||||
$this->cacheDocumentsRequest->initCaching($document);
|
||||
|
||||
try {
|
||||
$localCopy = $this->cacheService->saveRemoteFileToCache($document->getUrl(), $mime);
|
||||
$document->setMimeType($mime);
|
||||
$document->setLocalCopy($localCopy);
|
||||
$this->cacheDocumentsRequest->endCaching($document);
|
||||
|
||||
return $document;
|
||||
} catch (CacheContentMimeTypeException $e) {
|
||||
$document->setMimeType($mime);
|
||||
$document->setError(self::ERROR_MIMETYPE);
|
||||
$this->cacheDocumentsRequest->endCaching($document);
|
||||
} catch (CacheContentSizeException $e) {
|
||||
$document->setError(self::ERROR_SIZE);
|
||||
$this->cacheDocumentsRequest->endCaching($document);
|
||||
} catch (CacheContentException $e) {
|
||||
}
|
||||
|
||||
throw new CacheDocumentDoesNotExistException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @param bool $public
|
||||
*
|
||||
* @return ISimpleFile
|
||||
* @throws CacheContentException
|
||||
* @throws CacheDocumentDoesNotExistException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public function getFromCache(string $id, bool $public = false) {
|
||||
$document = $this->cacheRemoteDocument($id, $public);
|
||||
|
||||
return $this->cacheService->getContentFromCache($document->getLocalCopy());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public function manageCacheDocuments(): int {
|
||||
$update = $this->cacheDocumentsRequest->getNotCachedDocuments();
|
||||
|
||||
$count = 0;
|
||||
foreach ($update as $item) {
|
||||
if ($item->getLocalCopy() === 'avatar') {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->cacheRemoteDocument($item->getId());
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return string
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
*/
|
||||
public function cacheLocalAvatarByUsername(Person $actor): string {
|
||||
$url = $this->urlGenerator->linkToRouteAbsolute(
|
||||
'core.avatar.getAvatar', ['userId' => $actor->getUserId(), 'size' => 128]
|
||||
);
|
||||
|
||||
$versionCurrent =
|
||||
(int)$this->configService->getUserValue('version', $actor->getUserId(), 'avatar');
|
||||
$versionCached = $actor->getAvatarVersion();
|
||||
if ($versionCurrent > $versionCached) {
|
||||
$icon = new Image();
|
||||
$icon->setUrl($url);
|
||||
$icon->setUrlcloud($this->configService->getCloudAddress());
|
||||
$icon->generateUniqueId('/documents/avatar');
|
||||
$icon->setMediaType('');
|
||||
$icon->setLocalCopy('avatar');
|
||||
|
||||
$this->cacheDocumentsRequest->deleteByUrl($icon->getUrl());
|
||||
$this->cacheDocumentsRequest->save($icon);
|
||||
|
||||
$actor->setAvatarVersion($versionCurrent);
|
||||
$this->actorRequest->update($actor);
|
||||
} else {
|
||||
try {
|
||||
$icon = $this->cacheDocumentsRequest->getBySource($url);
|
||||
} catch (CacheDocumentDoesNotExistException $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return $icon->getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use OCA\Social\Db\FollowsRequest;
|
||||
use OCA\Social\Exceptions\CacheActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\FollowDoesNotExistException;
|
||||
use OCA\Social\Exceptions\FollowSameAccountException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Follow;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\OrderedCollection;
|
||||
use OCA\Social\Model\InstancePath;
|
||||
|
||||
class FollowService {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
const REQUEST_INBOX = 1;
|
||||
|
||||
const TIMEOUT_LIVE = 2;
|
||||
const TIMEOUT_ASYNC = 5;
|
||||
const TIMEOUT_SERVICE = 10;
|
||||
|
||||
const CONTEXT_ACTIVITYSTREAMS = 'https://www.w3.org/ns/activitystreams';
|
||||
const CONTEXT_SECURITY = 'https://w3id.org/security/v1';
|
||||
|
||||
const TO_PUBLIC = 'https://www.w3.org/ns/activitystreams#Public';
|
||||
|
||||
const DATE_FORMAT = 'D, d M Y H:i:s T';
|
||||
const DATE_DELAY = 30;
|
||||
|
||||
/** @var FollowsRequest */
|
||||
private $followsRequest;
|
||||
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $viewerId = '';
|
||||
|
||||
|
||||
/**
|
||||
* FollowService constructor.
|
||||
*
|
||||
* @param FollowsRequest $followsRequest
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
FollowsRequest $followsRequest, CacheActorService $cacheActorService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->followsRequest = $followsRequest;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
/**
|
||||
* @param string $viewerId
|
||||
*/
|
||||
public function setViewerId(string $viewerId) {
|
||||
$this->viewerId = $viewerId;
|
||||
$this->followsRequest->setViewerId($viewerId);
|
||||
}
|
||||
|
||||
public function getViewerId(): string {
|
||||
return $this->viewerId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param string $account
|
||||
*
|
||||
* @throws CacheActorDoesNotExistException
|
||||
* @throws FollowSameAccountException
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UrlCloudException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function followAccount(Person $actor, string $account) {
|
||||
$remoteActor = $this->cacheActorService->getFromAccount($account);
|
||||
if ($remoteActor->getId() === $actor->getId()) {
|
||||
throw new FollowSameAccountException("Don't follow yourself, be your own lead");
|
||||
}
|
||||
|
||||
$follow = new Follow();
|
||||
$follow->setUrlCloud($this->configService->getCloudAddress());
|
||||
$follow->generateUniqueId();
|
||||
$follow->setActorId($actor->getId());
|
||||
$follow->setObjectId($remoteActor->getId());
|
||||
$follow->setFollowId($remoteActor->getFollowers());
|
||||
|
||||
try {
|
||||
$this->followsRequest->getByPersons($actor->getId(), $remoteActor->getId());
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
$this->followsRequest->save($follow);
|
||||
// TODO - Remove this auto-accepted.
|
||||
$this->followsRequest->accepted($follow);
|
||||
|
||||
$follow->addInstancePath(
|
||||
new InstancePath(
|
||||
$remoteActor->getInbox(), InstancePath::TYPE_INBOX, InstancePath::PRIORITY_TOP
|
||||
)
|
||||
);
|
||||
// $this->activityService->request($follow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param string $account
|
||||
*
|
||||
* @throws CacheActorDoesNotExistException
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function unfollowAccount(Person $actor, string $account) {
|
||||
$remoteActor = $this->cacheActorService->getFromAccount($account);
|
||||
|
||||
try {
|
||||
$follow = $this->followsRequest->getByPersons($actor->getId(), $remoteActor->getId());
|
||||
$this->followsRequest->delete($follow);
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $local
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLinksBetweenPersons(Person $local, Person $actor): array {
|
||||
|
||||
$links = [
|
||||
'follower' => false,
|
||||
'following' => false
|
||||
];
|
||||
|
||||
try {
|
||||
$this->followsRequest->getByPersons($local->getId(), $actor->getId());
|
||||
$links['following'] = true;
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->followsRequest->getByPersons($actor->getId(), $local->getId());
|
||||
$links['follower'] = true;
|
||||
} catch (FollowDoesNotExistException $e) {
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return Person[]
|
||||
*/
|
||||
public function getFollowers(Person $actor): array {
|
||||
return $this->followsRequest->getFollowersByActorId($actor->getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return OrderedCollection
|
||||
*/
|
||||
public function getFollowersCollection(Person $actor): OrderedCollection {
|
||||
$collection = new OrderedCollection();
|
||||
$collection->setId($actor->getFollowers());
|
||||
$collection->setTotalItems(20);
|
||||
$collection->setFirst('...');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return Person[]
|
||||
*/
|
||||
public function getFollowing(Person $actor): array {
|
||||
return $this->followsRequest->getFollowingByActorId($actor->getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return OrderedCollection
|
||||
*/
|
||||
public function getFollowingCollection(Person $actor): OrderedCollection {
|
||||
$collection = new OrderedCollection();
|
||||
// $collection->setId($actor->getFollowers());
|
||||
// $collection->setTotalItems(20);
|
||||
// $collection->setFirst('...');
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -33,42 +33,12 @@ namespace OCA\Social\Service;
|
|||
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use Exception;
|
||||
use OCA\Social\AP;
|
||||
use OCA\Social\Exceptions\ActivityPubFormatException;
|
||||
use OCA\Social\Exceptions\InvalidResourceEntryException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Accept;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Add;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Block;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Create;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Delete;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Follow;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Like;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Reject;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Remove;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Undo;
|
||||
use OCA\Social\Model\ActivityPub\Activity\Update;
|
||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||
use OCA\Social\Model\ActivityPub\Object\Image;
|
||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Tombstone;
|
||||
use OCA\Social\Service\ActivityPub\Activity\AcceptService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\AddService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\BlockService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\CreateService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\DeleteService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\FollowService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\LikeService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\RejectService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\RemoveService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\UndoService;
|
||||
use OCA\Social\Service\ActivityPub\Activity\UpdateService;
|
||||
use OCA\Social\Service\ActivityPub\ICoreService;
|
||||
use OCA\Social\Service\ActivityPub\Object\NoteService;
|
||||
use OCA\Social\Service\ActivityPub\Actor\PersonService;
|
||||
|
||||
|
||||
class ImportService {
|
||||
|
@ -76,44 +46,6 @@ class ImportService {
|
|||
|
||||
use TArrayTools;
|
||||
|
||||
/** @var AcceptService */
|
||||
private $acceptService;
|
||||
|
||||
/** @var AddService */
|
||||
private $addService;
|
||||
|
||||
/** @var BlockService */
|
||||
private $blockService;
|
||||
|
||||
/** @var CreateService */
|
||||
private $createService;
|
||||
|
||||
/** @var DeleteService */
|
||||
private $deleteService;
|
||||
|
||||
/** @var FollowService */
|
||||
private $followService;
|
||||
|
||||
/** @var LikeService */
|
||||
private $likeService;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
|
||||
/** @var NoteService */
|
||||
private $noteService;
|
||||
|
||||
/** @var RejectService */
|
||||
private $rejectService;
|
||||
|
||||
/** @var RemoveService */
|
||||
private $removeService;
|
||||
|
||||
/** @var UndoService */
|
||||
private $undoService;
|
||||
|
||||
/** @var UpdateService */
|
||||
private $updateService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
@ -125,43 +57,10 @@ class ImportService {
|
|||
/**
|
||||
* ImportService constructor.
|
||||
*
|
||||
* @param AcceptService $acceptService
|
||||
* @param AddService $addService
|
||||
* @param BlockService $blockService
|
||||
* @param CreateService $createService
|
||||
* @param DeleteService $deleteService
|
||||
* @param FollowService $followService
|
||||
* @param NoteService $noteService
|
||||
* @param LikeService $likeService
|
||||
* @param PersonService $personService
|
||||
* @param RejectService $rejectService
|
||||
* @param RemoveService $removeService
|
||||
* @param UndoService $undoService
|
||||
* @param UpdateService $updateService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
AcceptService $acceptService, AddService $addService, BlockService $blockService,
|
||||
CreateService $createService, DeleteService $deleteService, FollowService $followService,
|
||||
NoteService $noteService, LikeService $likeService, PersonService $personService,
|
||||
RejectService $rejectService, RemoveService $removeService,
|
||||
UndoService $undoService, UpdateService $updateService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->acceptService = $acceptService;
|
||||
$this->addService = $addService;
|
||||
$this->blockService = $blockService;
|
||||
$this->createService = $createService;
|
||||
$this->deleteService = $deleteService;
|
||||
$this->followService = $followService;
|
||||
$this->likeService = $likeService;
|
||||
$this->rejectService = $rejectService;
|
||||
$this->removeService = $removeService;
|
||||
$this->personService = $personService;
|
||||
$this->noteService = $noteService;
|
||||
$this->undoService = $undoService;
|
||||
$this->updateService = $updateService;
|
||||
public function __construct(ConfigService $configService, MiscService $miscService) {
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
@ -172,118 +71,54 @@ class ImportService {
|
|||
*
|
||||
* @return ACore
|
||||
* @throws UnknownItemException
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws ActivityPubFormatException
|
||||
* @throws RedundancyLimitException
|
||||
*/
|
||||
public function importFromJson(string $json) {
|
||||
public function importFromJson(string $json): ACore {
|
||||
$data = json_decode($json, true);
|
||||
if (!is_array($data)) {
|
||||
throw new ActivityPubFormatException();
|
||||
}
|
||||
$activity = $this->importFromData($data, null);
|
||||
|
||||
return $activity;
|
||||
return AP::$activityPub->getItemFromData($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param ACore $root
|
||||
*
|
||||
* @return ACore
|
||||
* @throws UnknownItemException
|
||||
* @throws UrlCloudException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws InvalidResourceEntryException
|
||||
*/
|
||||
private function importFromData(array $data, $root = null): ACore {
|
||||
|
||||
// TODO - missing : Person (why not ?), OrderCollection (not yet), Document (should ?)
|
||||
switch ($this->get('type', $data, '')) {
|
||||
case Accept::TYPE:
|
||||
$item = new Accept($root);
|
||||
break;
|
||||
|
||||
case Add::TYPE:
|
||||
$item = new Add($root);
|
||||
break;
|
||||
|
||||
case Block::TYPE:
|
||||
$item = new Block($root);
|
||||
break;
|
||||
|
||||
case Create::TYPE:
|
||||
$item = new Create($root);
|
||||
break;
|
||||
|
||||
case Delete::TYPE:
|
||||
$item = new Delete($root);
|
||||
break;
|
||||
|
||||
case Follow::TYPE:
|
||||
$item = new Follow($root);
|
||||
break;
|
||||
|
||||
case Image::TYPE:
|
||||
$item = new Image($root);
|
||||
break;
|
||||
|
||||
case Like::TYPE:
|
||||
$item = new Like($root);
|
||||
break;
|
||||
|
||||
case Note::TYPE:
|
||||
$item = new Note($root);
|
||||
break;
|
||||
|
||||
case Person::TYPE:
|
||||
$item = new Note($root);
|
||||
break;
|
||||
|
||||
case Reject::TYPE:
|
||||
$item = new Reject($root);
|
||||
break;
|
||||
|
||||
case Remove::TYPE:
|
||||
$item = new Remove($root);
|
||||
break;
|
||||
|
||||
case Tombstone::TYPE:
|
||||
$item = new Tombstone($root);
|
||||
break;
|
||||
|
||||
case Undo::TYPE:
|
||||
$item = new Undo($root);
|
||||
break;
|
||||
|
||||
case Update::TYPE:
|
||||
$item = new Update($root);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnknownItemException();
|
||||
}
|
||||
|
||||
$item->setUrlCloud($this->configService->getCloudAddress());
|
||||
$item->import($data);
|
||||
$item->setSource(json_encode($data, JSON_UNESCAPED_SLASHES));
|
||||
|
||||
try {
|
||||
$object = $this->importFromData($this->getArray('object', $data, []), $item);
|
||||
$item->setObject($object);
|
||||
} catch (UnknownItemException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var Document $icon */
|
||||
$icon = $this->importFromData($this->getArray('icon', $data, []), $item);
|
||||
$item->setIcon($icon);
|
||||
} catch (UnknownItemException $e) {
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * @param array $data
|
||||
// * @param ACore $root
|
||||
// *
|
||||
// * @return ACore
|
||||
// * @throws UnknownItemException
|
||||
// * @throws UrlCloudException
|
||||
// * @throws SocialAppConfigException
|
||||
// * @throws InvalidResourceEntryException
|
||||
// */
|
||||
// private function importFromData(array $data, $root = null): ACore {
|
||||
//
|
||||
// $item = AP::$activityPub->getItemFromData($data);
|
||||
// $item->setParent($root);
|
||||
//
|
||||
// $item->setUrlCloud($this->configService->getCloudAddress());
|
||||
// $item->setSource(json_encode($data, JSON_UNESCAPED_SLASHES));
|
||||
//
|
||||
// try {
|
||||
// $object = $this->importFromData($this->getArray('object', $data, []), $item);
|
||||
// $item->setObject($object);
|
||||
// } catch (UnknownItemException $e) {
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// /** @var Document $icon */
|
||||
// $icon = $this->importFromData($this->getArray('icon', $data, []), $item);
|
||||
// $item->setIcon($icon);
|
||||
// } catch (UnknownItemException $e) {
|
||||
// }
|
||||
//
|
||||
// return $item;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -292,19 +127,10 @@ class ImportService {
|
|||
* @throws UnknownItemException
|
||||
*/
|
||||
public function parseIncomingRequest(ACore $activity) {
|
||||
|
||||
// not sure we need to recursive on activity/parsing.
|
||||
// if ($activity->gotObject()) {
|
||||
// try {
|
||||
// $this->parseIncomingRequest($activity->getObject());
|
||||
// } catch (UnknownItemException $e) {
|
||||
// }
|
||||
// }
|
||||
|
||||
$service = $this->getServiceForItem($activity);
|
||||
$interface = AP::$activityPub->getInterfaceForItem($activity);
|
||||
|
||||
try {
|
||||
$service->processIncomingRequest($activity, $this);
|
||||
$interface->processIncomingRequest($activity);
|
||||
} catch (Exception $e) {
|
||||
$this->miscService->log(
|
||||
'Cannot parse ' . $activity->getType() . ': ' . $e->getMessage()
|
||||
|
@ -313,74 +139,5 @@ class ImportService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ACore $activity
|
||||
*
|
||||
* @return ICoreService
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function getServiceForItem(Acore $activity): ICoreService {
|
||||
switch ($activity->getType()) {
|
||||
|
||||
case Accept::TYPE:
|
||||
$service = $this->acceptService;
|
||||
break;
|
||||
|
||||
case Add::TYPE:
|
||||
$service = $this->addService;
|
||||
break;
|
||||
|
||||
case Block::TYPE:
|
||||
$service = $this->blockService;
|
||||
break;
|
||||
|
||||
case Create::TYPE:
|
||||
$service = $this->createService;
|
||||
break;
|
||||
|
||||
case Delete::TYPE:
|
||||
$service = $this->deleteService;
|
||||
break;
|
||||
|
||||
case Follow::TYPE:
|
||||
$service = $this->followService;
|
||||
break;
|
||||
|
||||
case Like::TYPE:
|
||||
$service = $this->likeService;
|
||||
break;
|
||||
|
||||
case Note::TYPE:
|
||||
$service = $this->noteService;
|
||||
break;
|
||||
|
||||
case Person::TYPE:
|
||||
$service = $this->personService;
|
||||
break;
|
||||
|
||||
case Reject::TYPE:
|
||||
$service = $this->rejectService;
|
||||
break;
|
||||
|
||||
case Remove::TYPE:
|
||||
$service = $this->removeService;
|
||||
break;
|
||||
|
||||
case Undo::TYPE:
|
||||
$service = $this->undoService;
|
||||
break;
|
||||
|
||||
case Update::TYPE:
|
||||
$service = $this->updateService;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnknownItemException();
|
||||
}
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\ArrayNotFoundException;
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Model\Request;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use daita\MySmallPhpTools\Traits\TPathTools;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\Instance;
|
||||
use OCA\Social\Model\InstancePath;
|
||||
|
||||
class InstanceService {
|
||||
|
||||
|
||||
use TPathTools;
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
|
||||
private $curlService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/**
|
||||
* UriIdService constructor.
|
||||
*
|
||||
* @param ConfigService $configService
|
||||
* @param CurlService $curlService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
ConfigService $configService, CurlService $curlService, MiscService $miscService
|
||||
) {
|
||||
$this->configService = $configService;
|
||||
$this->curlService = $curlService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $account
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RequestException
|
||||
* @throws InvalidResourceException
|
||||
* @throws Request410Exception
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
public function retrieveAccount(string $account) {
|
||||
$account = $this->withoutBeginAt($account);
|
||||
|
||||
if (strstr(substr($account, 0, -3), '@') === false) {
|
||||
throw new InvalidResourceException();
|
||||
}
|
||||
list($username, $host) = explode('@', $account);
|
||||
|
||||
// if ($username === null || $host === null) {
|
||||
// throw new InvalidResourceException();
|
||||
// }
|
||||
|
||||
$request = new Request('/.well-known/webfinger');
|
||||
$request->addData('resource', 'acct:' . $account);
|
||||
$request->setAddress($host);
|
||||
$result = $this->curlService->request($request);
|
||||
|
||||
try {
|
||||
$link = $this->extractArray('rel', 'self', $this->getArray('links', $result));
|
||||
} catch (ArrayNotFoundException $e) {
|
||||
throw new RequestException();
|
||||
}
|
||||
|
||||
return $this->retrieveObject($this->get('href', $link, ''));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return mixed
|
||||
* @throws RequestException
|
||||
* @throws Request410Exception
|
||||
* @throws MalformedArrayException
|
||||
*/
|
||||
public function retrieveObject($id) {
|
||||
$url = parse_url($id);
|
||||
$this->mustContains(['path', 'host'], $url);
|
||||
$request = new Request($url['path'], Request::TYPE_GET);
|
||||
$request->setAddress($url['host']);
|
||||
|
||||
$result = $this->curlService->request($request);
|
||||
if (is_array($result)) {
|
||||
$result['_host'] = $url['host'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ACore $activity
|
||||
*
|
||||
* @return Instance[]
|
||||
*/
|
||||
public function getInstancesFromActivity(ACore $activity): array {
|
||||
$instances = [];
|
||||
|
||||
foreach ($activity->getInstancePaths() as $instancePath) {
|
||||
$this->addInstances($instancePath, $instances);
|
||||
}
|
||||
|
||||
return $instances;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param InstancePath $instancePath
|
||||
* @param Instance[] $instances
|
||||
*/
|
||||
private function addInstances(InstancePath $instancePath, array &$instances) {
|
||||
$address = $this->getHostFromUriId($instancePath->getUri());
|
||||
|
||||
if ($address === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($instances as $instance) {
|
||||
if ($instance->getAddress() === $address) {
|
||||
$instance->addPath($instancePath);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$instance = new Instance($address);
|
||||
$instance->addPath($instancePath);
|
||||
$instances[] = $instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $uriId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getHostFromUriId(string $uriId) {
|
||||
$ignoreThose = [
|
||||
'',
|
||||
'https://www.w3.org/ns/activitystreams#Public'
|
||||
];
|
||||
|
||||
if (in_array($uriId, $ignoreThose)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = parse_url($uriId);
|
||||
if (!is_array($url) || !array_key_exists('host', $url)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $url['host'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use Exception;
|
||||
use OC\User\NoUserException;
|
||||
use OCA\Social\Db\NotesRequest;
|
||||
use OCA\Social\Exceptions\AccountAlreadyExistsException;
|
||||
use OCA\Social\Exceptions\ActorDoesNotExistException;
|
||||
use OCA\Social\Exceptions\NoteNotFoundException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UrlCloudException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||
use OCA\Social\Model\InstancePath;
|
||||
|
||||
class NoteService {
|
||||
|
||||
|
||||
/** @var NotesRequest */
|
||||
private $notesRequest;
|
||||
|
||||
/** @var ActivityService */
|
||||
private $activityService;
|
||||
|
||||
/** @var AccountService */
|
||||
private $accountService;
|
||||
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/** @var string */
|
||||
private $viewerId = '';
|
||||
|
||||
|
||||
/**
|
||||
* NoteService constructor.
|
||||
*
|
||||
* @param NotesRequest $notesRequest
|
||||
* @param ActivityService $activityService
|
||||
* @param AccountService $accountService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
NotesRequest $notesRequest,
|
||||
ActivityService $activityService,
|
||||
AccountService $accountService,
|
||||
CacheActorService $cacheActorService,
|
||||
ConfigService $configService,
|
||||
MiscService $miscService
|
||||
) {
|
||||
$this->notesRequest = $notesRequest;
|
||||
$this->activityService = $activityService;
|
||||
$this->accountService = $accountService;
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $viewerId
|
||||
*/
|
||||
public function setViewerId(string $viewerId) {
|
||||
$this->viewerId = $viewerId;
|
||||
$this->notesRequest->setViewerId($viewerId);
|
||||
}
|
||||
|
||||
public function getViewerId(): string {
|
||||
return $this->viewerId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* @param string $content
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return Note
|
||||
* @throws ActorDoesNotExistException
|
||||
* @throws NoUserException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws AccountAlreadyExistsException
|
||||
* @throws UrlCloudException
|
||||
*/
|
||||
public function generateNote(string $userId, string $content, string $type) {
|
||||
$note = new Note();
|
||||
$actor = $this->accountService->getActorFromUserId($userId);
|
||||
|
||||
$note->setId($this->configService->generateId('@' . $actor->getPreferredUsername()));
|
||||
$note->setPublished(date("c"));
|
||||
$note->setAttributedTo(
|
||||
$this->configService->getUrlSocial() . '@' . $actor->getPreferredUsername()
|
||||
);
|
||||
|
||||
$this->setRecipient($note, $actor, $type);
|
||||
$note->setContent($content);
|
||||
$note->convertPublished();
|
||||
$note->setLocal(true);
|
||||
|
||||
return $note;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
* @param Person $actor
|
||||
* @param string $type
|
||||
*/
|
||||
private function setRecipient(Note $note, Person $actor, string $type) {
|
||||
switch ($type) {
|
||||
case Note::TYPE_UNLISTED:
|
||||
$note->setTo($actor->getFollowers());
|
||||
$note->addInstancePath(
|
||||
new InstancePath(
|
||||
$actor->getFollowers(), InstancePath::TYPE_FOLLOWERS,
|
||||
InstancePath::PRIORITY_LOW
|
||||
)
|
||||
);
|
||||
$note->addCc(ActivityService::TO_PUBLIC);
|
||||
break;
|
||||
|
||||
case Note::TYPE_FOLLOWERS:
|
||||
$note->setTo($actor->getFollowers());
|
||||
$note->addInstancePath(
|
||||
new InstancePath(
|
||||
$actor->getFollowers(), InstancePath::TYPE_FOLLOWERS,
|
||||
InstancePath::PRIORITY_LOW
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case Note::TYPE_DIRECT:
|
||||
break;
|
||||
|
||||
default:
|
||||
$note->setTo(ActivityService::TO_PUBLIC);
|
||||
$note->addCc($actor->getFollowers());
|
||||
$note->addInstancePath(
|
||||
new InstancePath(
|
||||
$actor->getFollowers(), InstancePath::TYPE_FOLLOWERS,
|
||||
InstancePath::PRIORITY_LOW
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
* @param string $type
|
||||
* @param string $account
|
||||
*/
|
||||
public function addRecipient(Note $note, string $type, string $account) {
|
||||
if ($account === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$actor = $this->cacheActorService->getFromAccount($account);
|
||||
} catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$instancePath = new InstancePath(
|
||||
$actor->getInbox(), InstancePath::TYPE_INBOX, InstancePath::PRIORITY_MEDIUM
|
||||
);
|
||||
if ($type === Note::TYPE_DIRECT) {
|
||||
$instancePath->setPriority(InstancePath::PRIORITY_HIGH);
|
||||
$note->addToArray($actor->getId());
|
||||
} else {
|
||||
$note->addCc($actor->getId());
|
||||
}
|
||||
|
||||
$note->addTag(
|
||||
[
|
||||
'type' => 'Mention',
|
||||
'href' => $actor->getId()
|
||||
]
|
||||
);
|
||||
|
||||
$note->addInstancePath($instancePath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
* @param string $type
|
||||
* @param array $accounts
|
||||
*/
|
||||
public function addRecipients(Note $note, string $type, array $accounts) {
|
||||
if ($accounts === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$this->addRecipient($note, $type, $account);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
* @param string $replyTo
|
||||
*/
|
||||
public function replyTo(Note $note, string $replyTo) {
|
||||
if ($replyTo === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$note->setInReplyTo($replyTo);
|
||||
// TODO - type can be NOT public !
|
||||
$note->addInstancePath(
|
||||
new InstancePath($replyTo, InstancePath::TYPE_PUBLIC, InstancePath::PRIORITY_HIGH)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Note $note
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function deleteLocalNote(Note $note) {
|
||||
if (!$note->isLocal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$note->setActorId($note->getAttributedTo());
|
||||
$this->activityService->deleteActivity($note);
|
||||
$this->notesRequest->deleteNoteById($note->getId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*
|
||||
* @return Note
|
||||
* @throws NoteNotFoundException
|
||||
*/
|
||||
public function getNoteById(string $id): Note {
|
||||
return $this->notesRequest->getNoteById($id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamHome(Person $actor, int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getStreamHome($actor, $since, $limit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $actorId
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getStreamAccount($actorId, $since, $limit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getStreamDirect($actor, $since, $limit);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamLocalTimeline(int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getStreamTimeline($since, $limit, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamInternalTimeline(int $since = 0, int $limit = 5): array {
|
||||
// TODO - admin should be able to provide a list of 'friendly/internal' instance of ActivityPub
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $since
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Note[]
|
||||
*/
|
||||
public function getStreamGlobalTimeline(int $since = 0, int $limit = 5): array {
|
||||
return $this->notesRequest->getStreamTimeline($since, $limit, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -36,7 +36,6 @@ use OCA\Social\Exceptions\ActorDoesNotExistException;
|
|||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Model\ActivityPub\ACore;
|
||||
use OCA\Social\Model\Post;
|
||||
use OCA\Social\Service\ActivityPub\Object\NoteService;
|
||||
|
||||
class PostService {
|
||||
|
||||
|
@ -44,7 +43,7 @@ class PostService {
|
|||
/** @var NoteService */
|
||||
private $noteService;
|
||||
|
||||
/** @var ActorService */
|
||||
/** @var AccountService */
|
||||
private $actorService;
|
||||
|
||||
/** @var ActivityService */
|
||||
|
@ -58,12 +57,12 @@ class PostService {
|
|||
* PostService constructor.
|
||||
*
|
||||
* @param NoteService $noteService
|
||||
* @param ActorService $actorService
|
||||
* @param AccountService $actorService
|
||||
* @param ActivityService $activityService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
NoteService $noteService, ActorService $actorService, ActivityService $activityService,
|
||||
NoteService $noteService, AccountService $actorService, ActivityService $activityService,
|
||||
MiscService $miscService
|
||||
) {
|
||||
$this->noteService = $noteService;
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
/**
|
||||
* Nextcloud - Social Support
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Social\Service;
|
||||
|
||||
|
||||
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use OCA\Social\Exceptions\InvalidOriginException;
|
||||
use OCA\Social\Exceptions\InvalidResourceException;
|
||||
use OCA\Social\Exceptions\RedundancyLimitException;
|
||||
use OCA\Social\Exceptions\Request410Exception;
|
||||
use OCA\Social\Exceptions\RequestException;
|
||||
use OCA\Social\Exceptions\SignatureException;
|
||||
use OCA\Social\Exceptions\SignatureIsGoneException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Exceptions\UnknownItemException;
|
||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||
use OCP\IRequest;
|
||||
|
||||
class SignatureService {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
||||
|
||||
const DATE_FORMAT = 'D, d M Y H:i:s T';
|
||||
const DATE_DELAY = 30;
|
||||
|
||||
|
||||
/** @var CacheActorService */
|
||||
private $cacheActorService;
|
||||
|
||||
/** @var CurlService */
|
||||
private $curlService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var MiscService */
|
||||
private $miscService;
|
||||
|
||||
|
||||
/**
|
||||
* ActivityService constructor.
|
||||
*
|
||||
* @param AccountService $accountService
|
||||
* @param CacheActorService $cacheActorService
|
||||
* @param CurlService $curlService
|
||||
* @param ConfigService $configService
|
||||
* @param MiscService $miscService
|
||||
*/
|
||||
public function __construct(
|
||||
CacheActorService $cacheActorService, CurlService $curlService,
|
||||
ConfigService $configService, MiscService $miscService
|
||||
) {
|
||||
$this->cacheActorService = $cacheActorService;
|
||||
$this->curlService = $curlService;
|
||||
$this->configService = $configService;
|
||||
$this->miscService = $miscService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $actor
|
||||
*/
|
||||
public function generateKeys(Person &$actor) {
|
||||
$res = openssl_pkey_new(
|
||||
[
|
||||
"digest_alg" => "rsa",
|
||||
"private_key_bits" => 2048,
|
||||
"private_key_type" => OPENSSL_KEYTYPE_RSA,
|
||||
]
|
||||
);
|
||||
|
||||
openssl_pkey_export($res, $privateKey);
|
||||
$publicKey = openssl_pkey_get_details($res)['key'];
|
||||
|
||||
$actor->setPublicKey($publicKey);
|
||||
$actor->setPrivateKey($privateKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws RequestException
|
||||
* @throws SignatureException
|
||||
* @throws SignatureIsGoneException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
public function checkRequest(IRequest $request): string {
|
||||
$dTime = new DateTime($request->getHeader('date'));
|
||||
$dTime->format(self::DATE_FORMAT);
|
||||
|
||||
if ($dTime->getTimestamp() < (time() - self::DATE_DELAY)) {
|
||||
throw new SignatureException('object is too old');
|
||||
}
|
||||
|
||||
try {
|
||||
$origin = $this->checkRequestSignature($request);
|
||||
} catch (Request410Exception $e) {
|
||||
throw new SignatureIsGoneException();
|
||||
}
|
||||
|
||||
return $origin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws RedundancyLimitException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SignatureException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UnknownItemException
|
||||
*/
|
||||
private function checkRequestSignature(IRequest $request): string {
|
||||
$signatureHeader = $request->getHeader('Signature');
|
||||
|
||||
$sign = $this->parseSignatureHeader($signatureHeader);
|
||||
$this->mustContains(['keyId', 'headers', 'signature'], $sign);
|
||||
|
||||
$keyId = $sign['keyId'];
|
||||
$origin = $this->getKeyOrigin($keyId);
|
||||
|
||||
$headers = $sign['headers'];
|
||||
$signed = base64_decode($sign['signature']);
|
||||
$estimated = $this->generateEstimatedSignature($headers, $request);
|
||||
|
||||
$publicKey = $this->retrieveKey($keyId);
|
||||
|
||||
if ($publicKey === '' || openssl_verify($estimated, $signed, $publicKey, 'sha256') !== 1) {
|
||||
throw new SignatureException('signature cannot be checked');
|
||||
}
|
||||
|
||||
return $origin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $headers
|
||||
* @param IRequest $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateEstimatedSignature(string $headers, IRequest $request): string {
|
||||
$keys = explode(' ', $headers);
|
||||
|
||||
$target = '';
|
||||
try {
|
||||
$target = strtolower($request->getMethod()) . " " . $request->getRequestUri();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$estimated = "(request-target): " . $target;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($key === '(request-target)') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$estimated .= "\n" . $key . ': ' . $request->getHeader($key);
|
||||
}
|
||||
|
||||
return $estimated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $signatureHeader
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseSignatureHeader($signatureHeader) {
|
||||
$sign = [];
|
||||
|
||||
$entries = explode(',', $signatureHeader);
|
||||
foreach ($entries as $entry) {
|
||||
list($k, $v) = explode('=', $entry, 2);
|
||||
preg_match('/"([^"]+)"/', $v, $varr);
|
||||
$v = trim($varr[0], '"');
|
||||
|
||||
$sign[$k] = $v;
|
||||
}
|
||||
|
||||
return $sign;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $keyId
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidResourceException
|
||||
* @throws MalformedArrayException
|
||||
* @throws Request410Exception
|
||||
* @throws RequestException
|
||||
* @throws SocialAppConfigException
|
||||
* @throws UnknownItemException
|
||||
* @throws RedundancyLimitException
|
||||
*/
|
||||
private function retrieveKey($keyId): string {
|
||||
$actor = $this->cacheActorService->getFromId($keyId);
|
||||
|
||||
return $actor->getPublicKey();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidOriginException
|
||||
*/
|
||||
private function getKeyOrigin($id) {
|
||||
$host = parse_url($id, PHP_URL_HOST);
|
||||
if (is_string($host) && ($host !== '')) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
throw new InvalidOriginException();
|
||||
}
|
||||
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue