Skip to content

Commit

Permalink
AP inboxあたり
Browse files Browse the repository at this point in the history
  • Loading branch information
mei23 committed Apr 19, 2020
1 parent 653db62 commit 6d52629
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 50 deletions.
14 changes: 8 additions & 6 deletions src/misc/instance-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,28 @@ import { toApHost } from './convert-host';
let blockedHosts: string[];
let closedHosts: string[];

export async function isBlockedHost(host: string) {
export async function isBlockedHost(host: string | null) {
if (host == null) return false;
if (!blockedHosts) await Update();
return blockedHosts?.includes(toApHost(host));
return blockedHosts?.includes(toApHost(host)!);
}

export async function isClosedHost(host: string) {
export async function isClosedHost(host: string | null) {
if (host == null) return false;
if (!closedHosts) await Update();
return closedHosts?.includes(toApHost(host));
return closedHosts?.includes(toApHost(host)!);
}

async function Update() {
const blocked = await Instance.find({
isBlocked: true
});
blockedHosts = blocked.map(x => toApHost(x.host));
blockedHosts = blocked.map(x => toApHost(x.host)!);

const closed = await Instance.find({
isMarkedAsClosed: true
});
closedHosts = closed.map(x => toApHost(x.host));
closedHosts = closed.map(x => toApHost(x.host)!);
}

Update();
Expand Down
53 changes: 25 additions & 28 deletions src/queue/processors/inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { UpdateInstanceinfo } from '../../services/update-instanceinfo';
import { isBlockedHost } from '../../misc/instance-info';
import { InboxJobData } from '..';
import ApResolver from '../../remote/activitypub/ap-resolver';
import { inspect } from 'util';

const logger = new Logger('inbox');

Expand All @@ -28,62 +29,57 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
//#region Log
const info = Object.assign({}, activity);
delete info['@context'];
delete info['signature'];
logger.debug(JSON.stringify(info, null, 2));
logger.debug(inspect(info));
//#endregion

const keyIdLower = signature.keyId.toLowerCase();
let user: IRemoteUser | null;
const host = toUnicode(new URL(signature.keyId).hostname.toLowerCase());

if (keyIdLower.startsWith('acct:')) {
return `skip: acct keyId is no longer supported`;
} else {
// アクティビティ内のホストの検証
const host = toUnicode(new URL(signature.keyId).hostname.toLowerCase());
try {
ValidateActivity(activity, host);
} catch (e) {
return `skip: host validation failed ${e.message}`;
}
// ブロックしてたら中断
if (await isBlockedHost(host)) {
return `skip: Blocked instance: ${host}`;
}

// ブロックしてたら中断
if (await isBlockedHost(host)) {
return `skip: Blocked instance: ${host}`;
}
let user: IRemoteUser | null;

user = await apResolver.getRemoteUserFromKeyId(signature.keyId);
}
// keyIdを元にDBから取得
user = await apResolver.getRemoteUserFromKeyId(signature.keyId);

// アクティビティを送信してきたユーザーがまだMisskeyサーバーに登録されていなかったら登録する
if (user === null) {
// uriを元にDBから取得、なければリモートから取得
if (user == null) {
try {
user = await resolvePerson(getApId(activity.actor)) as IRemoteUser;
} catch (e) {
// 対象が4xxならスキップ
if (e.statusCode >= 400 && e.statusCode < 500) {
return `skip: Ignored actor ${activity.actor} - ${e.statusCode}`;
}
logger.error(`Error in actor ${activity.actor} - ${e.statusCode || e}`);
throw e;
throw `Error in actor ${activity.actor} - ${e.statusCode || e}`;
}
}

if (user === null) {
if (user == null) {
throw new Error('failed to resolve user');
}

// keyId
if (!httpSignature.verifySignature(signature, user.publicKey.publicKeyPem)) {
return `skip: signature verification failed`;
}

//#region Log
// アクティビティ内のホストの検証
try {
ValidateActivity(activity, host);
} catch (e) {
return `skip: host validation failed ${e.message}`;
}

//#region Log/stats
publishApLogStream({
direction: 'in',
activity: activity.type,
host: user.host,
actor: user.username
});
//#endregion

// Update stats
registerOrFetchInstanceDoc(user.host).then(i => {
Expand All @@ -101,6 +97,7 @@ export default async (job: Bull.Job<InboxJobData>): Promise<string> => {

instanceChart.requestReceived(i.host);
});
//#endregion

// アクティビティを処理
return (await perform(user, activity)) || 'ok';
Expand All @@ -117,7 +114,7 @@ function ValidateActivity(activity: any, host: string) {
const uriHost = toUnicode(new URL(activity.id).hostname.toLowerCase());
if (host !== uriHost) {
const diag = activity.signature ? '. Has LD-Signature. Forwarded?' : '';
throw new Error(`activity.id(${activity.id}) has different host(${host})${diag}`);
throw new Error(`activity.id(${activity.id}) has different host(${host})${diag}\n${inspect(activity)}}`);
}
}

Expand Down
20 changes: 4 additions & 16 deletions src/remote/activitypub/models/person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { updateUsertags } from '../../../services/update-hashtag';
import { toArray, toSingle } from '../../../prelude/array';
import { UpdateInstanceinfo } from '../../../services/update-instanceinfo';
import { extractDbHost } from '../../../misc/convert-host';
import ApResolver from '../ap-resolver';
const logger = apLogger;

/**
Expand Down Expand Up @@ -83,24 +84,11 @@ function toPerson(x: IObject, uri: string): IApPerson {
*
* Misskeyに対象のPersonが登録されていればそれを返します。
*/
export async function fetchPerson(uri: string, resolver?: Resolver): Promise<IUser> {
export async function fetchPerson(uri: string): Promise<IUser | null> {
if (typeof uri !== 'string') throw 'uri is not string';

// URIがこのサーバーを指しているならデータベースからフェッチ
if (uri.startsWith(config.url + '/')) {
const id = new mongo.ObjectID(uri.split('/').pop());
return await User.findOne({ _id: id });
}

//#region このサーバーに既に登録されていたらそれを返す
const exist = await User.findOne({ uri });

if (exist) {
return exist;
}
//#endregion

return null;
const apResolver = new ApResolver();
return await apResolver.getUserFromObject(uri);
}

/**
Expand Down

0 comments on commit 6d52629

Please sign in to comment.