Skip to content

Commit

Permalink
Update activitypub.extend.php
Browse files Browse the repository at this point in the history
  • Loading branch information
gnh1201 authored Aug 8, 2023
1 parent b201e9d commit 6bd734d
Showing 1 changed file with 57 additions and 26 deletions.
83 changes: 57 additions & 26 deletions extend/activitypub.extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// Author: Go Namhyeon (Catswords Research) <[email protected]>
// ActivityPub: @[email protected]
// License: MIT
// Date: 2023-08-06
// Version: 0.1.17-dev
// Date: 2023-08-08
// Version: 0.1.17
// References:
// * https://www.w3.org/TR/activitypub/
// * https://www.w3.org/TR/activitystreams-core/
Expand All @@ -19,6 +19,7 @@
// * https://github.com/autogestion/pubgate-telegram
// * https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/
// * https://chat.openai.com/share/4fda7974-cc0b-439a-b0f2-dc828f8acfef
// * https://codeberg.org/mro/activitypub/src/commit/4b1319d5363f4a836f23c784ef780b81bc674013/like.sh#L101

define("ACTIVITYPUB_INSTANCE_ID", md5_file(G5_DATA_PATH . "/dbconfig.php"));
define("ACTIVITYPUB_INSTANCE_VERSION", "0.1.14-dev");
Expand Down Expand Up @@ -350,7 +351,7 @@ function activitypub_build_http_headers($headers) {

function activitypub_build_datetime($s='now') {
// e.g. 18 Dec 2019 10:08:46 GMT
$format = "d M Y H:i:s e";
$format = "D, d M Y H:i:s e";
$dt = ($s == "now" ? new DateTime('now', new DateTimeZone("GMT")) : DateTime::createFromFormat($format, $s));
return $dt->format($format);
}
Expand All @@ -362,7 +363,7 @@ function activitypub_build_digest($body) {
return $digest;
}

function activitypub_build_signature($url, $date, $digest, $mb, $method="POST") {
function activitypub_build_signature($url, $date, $digest, $mb, $method="post") {
// get a certificate
list($private_key, $public_key) = activitypub_get_stored_keypair($mb);

Expand All @@ -374,13 +375,24 @@ function activitypub_build_signature($url, $date, $digest, $mb, $method="POST")
$keyId = $activitypub_user_id . "#main-key";

// build a target data to get signature
/*
$signature = $method . ' ' . $path . "\n" .
'HOST: ' . $host . "\n" .
'Date: ' . $date . "\n" .
'Digest: ' . $digest;
*/
// Ref: https://codeberg.org/mro/activitypub/src/commit/4b1319d5363f4a836f23c784ef780b81bc674013/like.sh#L101
$signature = sprintf(
"%s: %s\n%s: %s\n%s: %s\n%s: %s",
"(request-target)",
"{$method} {$path}",
"host", $host,
"date", $date,
"digest", $digest
);

// create a signature
openssl_sign($signature, $signature, $privateKey, OPENSSL_ALGO_SHA256);
openssl_sign($signature, $signature, $private_key, OPENSSL_ALGO_SHA256);
$signature = base64_encode($signature);

// create a signature header
Expand All @@ -391,7 +403,7 @@ function activitypub_http_get($url, $access_token = '') {
// build the header
$headers = array(
"Date" => activitypub_build_datetime('now'),
"Accept" => "application/ld+json; profile=\"" . NAMESPACE_ACTIVITYSTREAMS . "\""
"Accept" => "application/activity+json; profile=\"" . NAMESPACE_ACTIVITYSTREAMS . "\""
);

// set access token
Expand Down Expand Up @@ -432,20 +444,20 @@ function activitypub_get_attachments($bo_table, $wr_id) {
return $attachments;
}

function activitypub_http_post($url, $raw_data, $mb, $access_token = '') {
function activitypub_http_post($url, $rawdata, $mb, $access_token = '') {
// get digest
$date = activitypub_build_datetime('now');
$digest = activitypub_build_digest($raw_data);
$digest = activitypub_build_digest($rawdata);

// build the headers
$headers = array(
"Date" => $date,
"Digest" => $digest,
"Content-Type" => "application/ld+json; profile=\"" . NAMESPACE_ACTIVITYSTREAMS . "\"",
"Accept" => "application/activity+json; profile=\"" . NAMESPACE_ACTIVITYSTREAMS . "\"",
);

// build the signature
$signature = activitypub_build_signature($url, $date, $digest, $mb, "POST");
$signature = activitypub_build_signature($url, $date, $digest, $mb);
$headers["Signature"] = $signature;

// set access token
Expand All @@ -461,12 +473,18 @@ function activitypub_http_post($url, $raw_data, $mb, $access_token = '') {
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => $raw_data,
CURLOPT_POSTFIELDS => $rawdata,
CURLOPT_POST => true
));
$response = curl_exec($ch);
$errno = curl_errno($ch);
curl_close($ch);

// 전송 오류가 있었을 시 쪽지로 알림
if ($errno) {
activitypub_add_memo(ACTIVITYPUB_G5_USERNAME, $mb['mb_id'], "[경고] 메시지 전송 중 오류가 발생함. 오류 번호: " . $errno);
}

return activitypub_json_decode($response, true);
}

Expand Down Expand Up @@ -650,6 +668,9 @@ function activitypub_publish_content($content, $object_id, $mb, $_added_object =

// 수신자/내용 생성
$to = array_merge(activitypub_cast_to_array(NAMESPACE_ACTIVITYSTREAMS_PUBLIC), $_added_to);
$cc = array(); // 참조자
$tag = array(); // 태그
$endpoints = array();
$content = "";
foreach($terms as $term_ctx) {
switch ($term_ctx['type']) {
Expand Down Expand Up @@ -681,15 +702,22 @@ function activitypub_publish_content($content, $object_id, $mb, $_added_object =

// WebFinger 정보 수신을 못한 경우, 쪽지로 알리고 아무 작업도 하지 않음
if (empty($webfigner_ctx['subject'])) {
activitypub_add_memo(ACTIVITYPUB_G5_USERNAME, $mb['mb_id'], "[발송실패] 수신자를 찾을 수 없음: " . $account);
activitypub_add_memo(ACTIVITYPUB_G5_USERNAME, $mb['mb_id'], "[발송실패] 수신자를 찾을 수 없음: @" . $account);
break;
}

// 받은 요청으로 처리
$webfigner_links = $webfigner_ctx['links'];
foreach($webfigner_links as $link) {
if ($link['rel'] == "self" && $link['type'] == "application/activity+json") {
array_push($to, $link['href']); // 수신자에 반영
// 태그 목록에 추가
array_push($tag, array(
"type" => "Mention",
"href" => $link['href'],
"name" => '@' . $account
));
array_push($cc, $link['href']); // 참조자 목록에 추가
array_push($endpoints, $link['href']); // 글을 전송할 엔드포인트(URL)에 반영
}
}
}
Expand All @@ -703,11 +731,17 @@ function activitypub_publish_content($content, $object_id, $mb, $_added_object =

// 위치정보가 활성화되어 있으면
if (ACTIVITYPUB_ENABLED_GEOLOCATION) {
$object = array_merge($_added_object, array(
$_added_object = array_merge($_added_object, array(
"location" => $location_ctx
));
}

// 참조자, 태그 추가
$_added_object = array_merge($_added_object, array(
"cc" => $cc,
"tag" => $tag
));

// 전문 생성
$object = activitypub_build_note($content, $object_id, $mb, $_added_object);

Expand All @@ -728,23 +762,20 @@ function activitypub_publish_content($content, $object_id, $mb, $_added_object =
// 보낼 전문을 인코딩
$rawdata = activitypub_json_encode($data);

// 수신자 작업
foreach($to as $_to) {
// 공개 네임스페이스인 경우 건너뛰기
if ($_to == NAMESPACE_ACTIVITYSTREAMS_PUBLIC) continue;

// 수신자 엔드포인트(URL) 작업
foreach($endpoints as $endpoint) {
// 수신자 정보 조회
$remote_user_ctx = activitypub_http_get($_to);
$remote_account_ctx = activitypub_http_get($endpoint);

// inbox 주소 찾기
$remote_inbox_url = $remote_user_ctx['inbox'];
$remote_inbox_url = $remote_account_ctx['inbox'];
if (empty($remote_inbox_url)) {
$remote_inbox_url = $remote_user_ctx['endpoints']['sharedInbox'];
$remote_inbox_url = $remote_account_ctx['endpoints']['sharedInbox'];
}

// inbox 주소가 없으면 건너뛰기
if (empty($remote_inbox_url)) {
activitypub_add_memo(ACTIVITYPUB_G5_USERNAME, $mb['mb_id'], "Could not find the inbox of " . $_to);
activitypub_add_memo(ACTIVITYPUB_G5_USERNAME, $mb['mb_id'], "이 사용자 또는 서버는 메시지를 수신할 수 없는 상태임: " . $_to);
continue;
}

Expand All @@ -759,7 +790,7 @@ function activitypub_publish_content($content, $object_id, $mb, $_added_object =
}

// inbox로 데이터 전송
$response = activitypub_http_post($remote_inbox_url, $rawdata, $mb, $access_token);
activitypub_http_post($remote_inbox_url, $rawdata, $mb, $access_token);
}

// 발행됨(Published)으로 상태 업데이트
Expand Down Expand Up @@ -1674,7 +1705,7 @@ function _activitypub_comment_update_after($board, $wr_id, $w, $qstr, $redirect_
_GNUBOARD_ActivityPub::close();
break;

case "oauth2.authorize": // TODO
case "oauth2.authorize": // To be implement
_GNUBOARD_ActivityPub::open();
echo _GNUBOARD_ActivityPub::authorize();
_GNUBOARD_ActivityPub::close();
Expand Down

0 comments on commit 6bd734d

Please sign in to comment.