First implementation of ActivityPub C2S
This commit is contained in:
		
					parent
					
						
							
								df021b07e3
							
						
					
				
			
			
				commit
				
					
						101b3c9703
					
				
			
		
					 7 changed files with 295 additions and 55 deletions
				
			
		|  | @ -21,11 +21,12 @@ | |||
| 
 | ||||
| namespace Friendica\Module\ActivityPub; | ||||
| 
 | ||||
| use Friendica\BaseModule; | ||||
| use Friendica\Core\Logger; | ||||
| use Friendica\Core\System; | ||||
| use Friendica\Database\DBA; | ||||
| use Friendica\DI; | ||||
| use Friendica\Model\User; | ||||
| use Friendica\Module\BaseApi; | ||||
| use Friendica\Protocol\ActivityPub; | ||||
| use Friendica\Util\HTTPSignature; | ||||
| use Friendica\Util\Network; | ||||
|  | @ -33,9 +34,35 @@ use Friendica\Util\Network; | |||
| /** | ||||
|  * ActivityPub Inbox | ||||
|  */ | ||||
| class Inbox extends BaseModule | ||||
| class Inbox extends BaseApi | ||||
| { | ||||
| 	protected function rawContent(array $request = []) | ||||
| 	{ | ||||
| 		self::checkAllowedScope(self::SCOPE_READ); | ||||
| 		$uid  = self::getCurrentUserID(); | ||||
| 		$page = $request['page'] ?? null; | ||||
| 
 | ||||
| 		if (empty($page) && empty($request['max_id'])) { | ||||
| 			$page = 1; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!empty($this->parameters['nickname'])) { | ||||
| 			$owner = User::getOwnerDataByNick($this->parameters['nickname']); | ||||
| 			if (empty($owner)) { | ||||
| 				throw new \Friendica\Network\HTTPException\NotFoundException(); | ||||
| 			} | ||||
| 			if ($owner['uid'] != $uid) { | ||||
| 				throw new \Friendica\Network\HTTPException\ForbiddenException(); | ||||
| 			} | ||||
| 			$outbox = ActivityPub\Transmitter::getInbox($uid, $page, $request['max_id'] ?? null); | ||||
| 		} else { | ||||
| 			$outbox = ActivityPub\Transmitter::getPublicInbox($uid, $page, $request['max_id'] ?? null); | ||||
| 		} | ||||
| 
 | ||||
| 		System::jsonExit($outbox, 'application/activity+json'); | ||||
| 	} | ||||
| 
 | ||||
| 	protected function post(array $request = []) | ||||
| 	{ | ||||
| 		$postdata = Network::postdata(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,16 +21,16 @@ | |||
| 
 | ||||
| namespace Friendica\Module\ActivityPub; | ||||
| 
 | ||||
| use Friendica\BaseModule; | ||||
| use Friendica\Core\System; | ||||
| use Friendica\Model\User; | ||||
| use Friendica\Module\BaseApi; | ||||
| use Friendica\Protocol\ActivityPub; | ||||
| use Friendica\Util\HTTPSignature; | ||||
| 
 | ||||
| /** | ||||
|  * ActivityPub Outbox | ||||
|  */ | ||||
| class Outbox extends BaseModule | ||||
| class Outbox extends BaseApi | ||||
| { | ||||
| 	protected function rawContent(array $request = []) | ||||
| 	{ | ||||
|  | @ -43,10 +43,15 @@ class Outbox extends BaseModule | |||
| 			throw new \Friendica\Network\HTTPException\NotFoundException(); | ||||
| 		} | ||||
| 
 | ||||
| 		$page = !empty($request['page']) ? (int)$request['page'] : null; | ||||
| 		$uid  = self::getCurrentUserID(); | ||||
| 		$page = $request['page'] ?? null; | ||||
| 
 | ||||
| 		if (empty($page) && empty($request['max_id']) && !empty($uid)) { | ||||
| 			$page = 1; | ||||
| 		} | ||||
| 
 | ||||
| 		$requester = HTTPSignature::getSigner('', $_SERVER); | ||||
| 		$outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $requester); | ||||
| 		$outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $request['max_id'] ?? null, $requester); | ||||
| 
 | ||||
| 		System::jsonExit($outbox, 'application/activity+json'); | ||||
| 	} | ||||
|  |  | |||
							
								
								
									
										105
									
								
								src/Module/ActivityPub/Whoami.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/Module/ActivityPub/Whoami.php
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | |||
| <?php | ||||
| /** | ||||
|  * @copyright Copyright (C) 2010-2023, the Friendica project | ||||
|  * | ||||
|  * @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 <https://www.gnu.org/licenses/>. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| namespace Friendica\Module\ActivityPub; | ||||
| 
 | ||||
| use Friendica\Content\Text\BBCode; | ||||
| use Friendica\Core\System; | ||||
| use Friendica\DI; | ||||
| use Friendica\Model\User; | ||||
| use Friendica\Module\BaseApi; | ||||
| use Friendica\Protocol\ActivityPub; | ||||
| 
 | ||||
| /** | ||||
|  * Dummy class for all currently unimplemented endpoints | ||||
|  */ | ||||
| class Whoami extends BaseApi | ||||
| { | ||||
| 	/** | ||||
| 	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException | ||||
| 	 */ | ||||
| 	protected function rawContent(array $request = []) | ||||
| 	{ | ||||
| 		self::checkAllowedScope(self::SCOPE_READ); | ||||
| 		$uid = self::getCurrentUserID(); | ||||
| 
 | ||||
| 		$owner = User::getOwnerDataById($uid); | ||||
| 
 | ||||
| 		$data = ['@context' => ActivityPub::CONTEXT]; | ||||
| 
 | ||||
| 		$data['id']                        = $owner['url']; | ||||
| 		$data['url']                       = $owner['url']; | ||||
| 		$data['type']                      = ActivityPub::ACCOUNT_TYPES[$owner['account-type']]; | ||||
| 		$data['name']                      = $owner['name']; | ||||
| 		$data['preferredUsername']         = $owner['nick']; | ||||
| 		$data['alsoKnownAs']               = []; | ||||
| 		$data['manuallyApprovesFollowers'] = in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]); | ||||
| 		$data['discoverable']              = (bool)$owner['net-publish']; | ||||
| 		$data['tag']                       = []; | ||||
| 
 | ||||
| 		$data['icon'] = [ | ||||
| 			'type' => 'Image', | ||||
| 			'url'  => User::getAvatarUrl($owner) | ||||
| 		]; | ||||
| 
 | ||||
| 		if (!empty($owner['about'])) { | ||||
| 			$data['summary'] = BBCode::convertForUriId($owner['uri-id'] ?? 0, $owner['about'], BBCode::EXTERNAL); | ||||
| 		} | ||||
| 
 | ||||
| 		$custom_fields = []; | ||||
| 
 | ||||
| 		foreach (DI::profileField()->selectByContactId(0, $uid) as $profile_field) { | ||||
| 			$custom_fields[] = [ | ||||
| 				'type'  => 'PropertyValue', | ||||
| 				'name'  => $profile_field->label, | ||||
| 				'value' => BBCode::convertForUriId($owner['uri-id'], $profile_field->value) | ||||
| 			]; | ||||
| 		}; | ||||
| 
 | ||||
| 		if (!empty($custom_fields)) { | ||||
| 			$data['attachment'] = $custom_fields; | ||||
| 		} | ||||
| 
 | ||||
| 		$data['publicKey'] = [ | ||||
| 			'id'           => $owner['url'] . '#main-key', | ||||
| 			'owner'        => $owner['url'], | ||||
| 			'publicKeyPem' => $owner['pubkey'] | ||||
| 		]; | ||||
| 
 | ||||
| 		$data['capabilities'] = []; | ||||
| 		$data['inbox']        = DI::baseUrl() . '/inbox/' . $owner['nick']; | ||||
| 		$data['outbox']       = DI::baseUrl() . '/outbox/' . $owner['nick']; | ||||
| 		$data['featured']     = DI::baseUrl() . '/featured/' . $owner['nick']; | ||||
| 		$data['followers']    = DI::baseUrl() . '/followers/' . $owner['nick']; | ||||
| 		$data['following']    = DI::baseUrl() . '/following/' . $owner['nick']; | ||||
| 
 | ||||
| 		$data['endpoints'] = [ | ||||
| 			'oauthAuthorizationEndpoint' => DI::baseUrl() . '/oauth/authorize', | ||||
| 			'oauthRegistrationEndpoint'  => DI::baseUrl() . '/api/v1/apps', | ||||
| 			'oauthTokenEndpoint'         => DI::baseUrl() . '/oauth/token', | ||||
| 			'sharedInbox'                => DI::baseUrl() . '/inbox', | ||||
| 			'uploadMedia'                => DI::baseUrl() . '/api/upload_media' // @todo Endpoint does not exist at the moment
 | ||||
| 		]; | ||||
| 
 | ||||
| 		$data['generator'] = ActivityPub\Transmitter::getService(); | ||||
| 		System::jsonExit($data, 'application/activity+json'); | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue