1
0
Fork 1
mirror of https://github.com/pixelfed/pixelfed.git synced 2024-12-24 08:44:02 +00:00

Update ActivityPub helper/inbox

This commit is contained in:
Daniel Supernault 2019-04-17 23:29:22 -06:00
parent a538d1d09a
commit e2ebaa40a8
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
2 changed files with 26 additions and 56 deletions

View file

@ -36,11 +36,11 @@ class Helpers {
Rule::in($verbs) Rule::in($verbs)
], ],
'id' => 'required|string', 'id' => 'required|string',
'actor' => 'required|string', 'actor' => 'required|string|url',
'object' => 'required', 'object' => 'required',
'object.type' => 'required_if:type,Create', 'object.type' => 'required_if:type,Create',
'object.attachment' => 'required_if:type,Create', 'object.attachment' => 'required_if:type,Create',
'object.attributedTo' => 'required_if:type,Create', 'object.attributedTo' => 'required_if:type,Create|url',
'published' => 'required_if:type,Create|date' 'published' => 'required_if:type,Create|date'
])->passes(); ])->passes();
@ -63,13 +63,16 @@ class Helpers {
} }
$attachment = $activity['attachment']; $attachment = $activity['attachment'];
if(self::validateUrl($attachment['url']) == false) {
return false;
}
$valid = Validator::make($attachment, [ $valid = Validator::make($attachment, [
'*.type' => [ '*.type' => [
'required', 'required',
'string', 'string',
Rule::in($mediaTypes) Rule::in($mediaTypes)
], ],
'*.url' => 'required|max:255', '*.url' => 'required|url|max:255',
'*.mediaType' => [ '*.mediaType' => [
'required', 'required',
'string', 'string',
@ -331,6 +334,8 @@ class Helpers {
public static function importNoteAttachment($data, Status $status) public static function importNoteAttachment($data, Status $status)
{ {
return;
if(self::verifyAttachments($data) == false) { if(self::verifyAttachments($data) == false) {
return; return;
} }
@ -394,6 +399,10 @@ class Helpers {
$username = Purify::clean($res['preferredUsername']); $username = Purify::clean($res['preferredUsername']);
$remoteUsername = "@{$username}@{$domain}"; $remoteUsername = "@{$username}@{$domain}";
abort_if(!self::validateUrl($res['inbox']), 400);
abort_if(!self::validateUrl($res['outbox']), 400);
abort_if(!self::validateUrl($res['id']), 400);
$profile = Profile::whereRemoteUrl($res['id'])->first(); $profile = Profile::whereRemoteUrl($res['id'])->first();
if(!$profile) { if(!$profile) {
$profile = new Profile; $profile = new Profile;
@ -418,10 +427,7 @@ class Helpers {
public static function sendSignedObject($senderProfile, $url, $body) public static function sendSignedObject($senderProfile, $url, $body)
{ {
$url = self::validateUrl($url); abort_if(!self::validateUrl($url), 400);
if($url == false) {
abort(400, 'Invalid url');
}
$payload = json_encode($body); $payload = json_encode($body);
$headers = HttpSignature::sign($senderProfile, $url, $body); $headers = HttpSignature::sign($senderProfile, $url, $body);
@ -434,42 +440,4 @@ class Helpers {
$response = curl_exec($ch); $response = curl_exec($ch);
return; return;
} }
private static function _headersToSigningString($headers) {
}
public static function validateSignature($request, $payload = null)
{
}
public static function fetchPublicKey()
{
$profile = $this->profile;
$is_url = $this->is_url;
$valid = $this->validateUrl();
if (!$valid) {
throw new \Exception('Invalid URL provided');
}
if ($is_url && isset($profile->public_key) && $profile->public_key) {
return $profile->public_key;
}
try {
$url = $this->profile;
$res = Zttp::timeout(30)->withHeaders([
'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
])->get($url);
$actor = json_decode($res->getBody(), true);
} catch (Exception $e) {
throw new Exception('Unable to fetch public key');
}
if($actor['publicKey']['owner'] != $profile) {
throw new Exception('Invalid key match');
}
$this->public_key = $actor['publicKey']['publicKeyPem'];
$this->key_id = $actor['publicKey']['id'];
return $this;
}
} }

View file

@ -36,6 +36,7 @@ class Inbox
public function handle() public function handle()
{ {
abort_if(!Helpers::validateObject($this->payload), 400);
$this->handleVerb(); $this->handleVerb();
} }
@ -261,24 +262,24 @@ class Inbox
{ {
$actor = $this->payload['actor']; $actor = $this->payload['actor'];
$obj = $this->payload['object']; $obj = $this->payload['object'];
abort_if(!Helpers::validateUrl($obj), 400);
if(is_string($obj) && Helpers::validateUrl($obj)) { if(is_string($obj) && Helpers::validateUrl($obj)) {
// actor object detected // actor object detected
// todo delete actor // todo delete actor
} else if (Helpers::validateUrl($obj['id']) && is_array($obj) && isset($obj['type']) && $obj['type'] == 'Tombstone') { } else if (Helpers::validateUrl($obj['id']) && Helpers::validateObject($obj) && $obj['type'] == 'Tombstone') {
// tombstone detected // todo delete status or object
$status = Status::whereLocal(false)->whereUri($obj['id'])->firstOrFail();
$status->forceDelete();
} }
} }
public function handleLikeActivity() public function handleLikeActivity()
{ {
$actor = $this->payload['actor']; $actor = $this->payload['actor'];
abort_if(!Helpers::validateUrl($actor), 400);
$profile = self::actorFirstOrCreate($actor); $profile = self::actorFirstOrCreate($actor);
$obj = $this->payload['object']; $obj = $this->payload['object'];
if(Helpers::validateLocalUrl($obj) == false) { abort_if(!Helpers::validateLocalUrl($obj), 400);
return;
}
$status = Helpers::statusFirstOrFetch($obj); $status = Helpers::statusFirstOrFetch($obj);
if(!$status || !$profile) { if(!$status || !$profile) {
return; return;
@ -288,12 +289,13 @@ class Inbox
'status_id' => $status->id 'status_id' => $status->id
]); ]);
if($like->wasRecentlyCreated == false) { if($like->wasRecentlyCreated == true) {
return;
}
LikePipeline::dispatch($like); LikePipeline::dispatch($like);
} }
return;
}
public function handleRejectActivity() public function handleRejectActivity()
{ {