Skip to content

Commit

Permalink
AP inbox log
Browse files Browse the repository at this point in the history
  • Loading branch information
mei23 committed Dec 9, 2019
1 parent ed37773 commit 9efd8ab
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 53 deletions.
25 changes: 9 additions & 16 deletions src/queue/processors/inbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { UpdateInstanceinfo } from '../../services/update-instanceinfo';
const logger = new Logger('inbox');

// ユーザーのinboxにアクティビティが届いた時の処理
export default async (job: Bull.Job): Promise<void> => {
export default async (job: Bull.Job): Promise<string> => {
const signature = job.data.signature as httpSignature.IParsedSignature;
const activity = job.data.activity as IActivity;

Expand All @@ -35,24 +35,21 @@ export default async (job: Bull.Job): Promise<void> => {
if (keyIdLower.startsWith('acct:')) {
const { username, host } = parseAcct(keyIdLower.slice('acct:'.length));
if (host === null) {
logger.warn(`request was made by local user: @${username}`);
return;
return `skip: request was made by local user: @${username}`;
}

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

// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const instance = await Instance.findOne({ host: toDbHost(host) });
if (instance && instance.isBlocked) {
logger.info(`Blocked request: ${host}`);
return;
return `skip: Blocked instance: ${host}`;
}

user = await User.findOne({ usernameLower: username, host: host.toLowerCase() }) as IRemoteUser;
Expand All @@ -62,16 +59,14 @@ export default async (job: Bull.Job): Promise<void> => {
try {
ValidateActivity(activity, host);
} catch (e) {
logger.warn(e.message);
return;
return `skip: host validation failed ${e.message}`;
}

// ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
const instance = await Instance.findOne({ host: toDbHost(host) });
if (instance && instance.isBlocked) {
logger.warn(`Blocked request: ${host}`);
return;
return `skip: Blocked instance: ${host}`;
}

user = await User.findOne({
Expand All @@ -87,8 +82,7 @@ export default async (job: Bull.Job): Promise<void> => {
} catch (e) {
// 対象が4xxならスキップ
if (e.statusCode >= 400 && e.statusCode < 500) {
logger.warn(`Ignored actor ${activity.actor} - ${e.statusCode}`);
return;
return `skip: Ignored actor ${activity.actor} - ${e.statusCode}`;
}
logger.error(`Error in actor ${activity.actor} - ${e.statusCode || e}`);
throw e;
Expand All @@ -100,8 +94,7 @@ export default async (job: Bull.Job): Promise<void> => {
}

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

//#region Log
Expand Down Expand Up @@ -131,7 +124,7 @@ export default async (job: Bull.Job): Promise<void> => {
});

// アクティビティを処理
await perform(user, activity);
return (await perform(user, activity)) || 'ok';
};

/**
Expand Down
6 changes: 3 additions & 3 deletions src/remote/activitypub/kernel/create/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { apLogger } from '../../logger';

const logger = apLogger;

export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
export default async (actor: IRemoteUser, activity: ICreate): Promise<string> => {
const uri = getApId(activity);

logger.info(`Create: ${uri}`);
Expand All @@ -23,8 +23,8 @@ export default async (actor: IRemoteUser, activity: ICreate): Promise<void> => {
}

if (isNote(object)) {
createNote(resolver, actor, object);
return await createNote(resolver, actor, object);
} else {
logger.warn(`Unknown type: ${object.type}`);
return `Unknown type: ${object.type}`;
}
};
9 changes: 5 additions & 4 deletions src/remote/activitypub/kernel/create/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import { IObject, getApId } from '../../type';
/**
* 投稿作成アクティビティを捌きます
*/
export default async function(resolver: Resolver, actor: IRemoteUser, note: IObject, silent = false): Promise<void> {
export default async function(resolver: Resolver, actor: IRemoteUser, note: IObject, silent = false): Promise<string> {
const uri = getApId(note);

const unlock = await getApLock(uri);

try {
const exist = await fetchNote(note);
if (exist == null) {
await createNote(note);
}
if (exist) return 'skip: note exists';

await createNote(note);
return 'ok';
} finally {
unlock();
}
Expand Down
13 changes: 6 additions & 7 deletions src/remote/activitypub/kernel/delete/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import deleteNote from './note';
import { IRemoteUser } from '../../../../models/user';
import { IDelete, getApId, isTombstone } from '../../type';
import { apLogger } from '../../logger';

/**
* 削除アクティビティを捌きます
*/
export default async (actor: IRemoteUser, activity: IDelete): Promise<void> => {
export default async (actor: IRemoteUser, activity: IDelete): Promise<string> => {
if ('actor' in activity && actor.uri !== activity.actor) {
throw new Error('invalid actor');
}
Expand All @@ -26,17 +25,17 @@ export default async (actor: IRemoteUser, activity: IDelete): Promise<void> => {
const uri = getApId(activity.object);

if (['Note', 'Question', 'Article', 'Audio', 'Document', 'Image', 'Page', 'Video'].includes(formarType)) {
await deleteNote(actor, uri);
return await deleteNote(actor, uri);
} else if (['Person', 'Service'].includes(formarType)) {
apLogger.warn(`Delete Actor is not implanted 1`);
return `Delete Actor is not implanted 1`;
} else if (formarType == null && uri === actor.uri) {
// formarTypeが不明でも対象がactorと同じならばそれはActorに違いない
apLogger.warn(`Delete Actor is not implanted 2`);
return `Delete Actor is not implanted 2`;
} else if (formarType == null) {
// それでもformarTypeが不明だったらおそらくNote
await deleteNote(actor, uri);
return await deleteNote(actor, uri);
} else {
// 明示的に見知らぬformarTypeだった場合
apLogger.warn(`Unsupported target object type in Delete activity: ${formarType}`);
return `Unsupported target object type in Delete activity: ${formarType}`;
}
};
9 changes: 4 additions & 5 deletions src/remote/activitypub/kernel/delete/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import { apLogger } from '../../logger';

const logger = apLogger;

export default async function(actor: IRemoteUser, uri: string): Promise<void> {
export default async function(actor: IRemoteUser, uri: string): Promise<string> {
logger.info(`Deleting the Note: ${uri}`);

const note = await Note.findOne({ uri });

if (note == null) {
logger.warn(`note not found: ${uri}`);
return;
return 'note not found';
}

if (!note.userId.equals(actor._id)) {
logger.warn(`投稿を削除しようとしているユーザーは投稿の作成者ではありません: ${uri}`);
return;
return '投稿を削除しようとしているユーザーは投稿の作成者ではありません';
}

await deleteNode(actor, note);
return 'ok: deleted';
}
32 changes: 16 additions & 16 deletions src/remote/activitypub/kernel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,38 @@ export async function performActivity(actor: IRemoteUser, activity: IObject) {
await performOneActivity(actor, act);
}
} else {
await performOneActivity(actor, activity);
return await performOneActivity(actor, activity);
}
}

export async function performOneActivity(actor: IRemoteUser, activity: IObject): Promise<void> {
if (actor.isSuspended) return;
export async function performOneActivity(actor: IRemoteUser, activity: IObject) {
if (actor.isSuspended) return 'skip: actor is suspended';

if (isCreate(activity)) {
await create(actor, activity);
return await create(actor, activity);
} else if (isDelete(activity)) {
await performDeleteActivity(actor, activity);
return await performDeleteActivity(actor, activity);
} else if (isUpdate(activity)) {
await performUpdateActivity(actor, activity);
return await performUpdateActivity(actor, activity);
} else if (isFollow(activity)) {
await follow(actor, activity);
return await follow(actor, activity);
} else if (isAccept(activity)) {
await accept(actor, activity);
return await accept(actor, activity);
} else if (isReject(activity)) {
await reject(actor, activity);
return await reject(actor, activity);
} else if (isAdd(activity)) {
await add(actor, activity).catch(err => apLogger.error(err));
return await add(actor, activity).catch(err => apLogger.error(err));
} else if (isRemove(activity)) {
await remove(actor, activity).catch(err => apLogger.error(err));
return await remove(actor, activity).catch(err => apLogger.error(err));
} else if (isAnnounce(activity)) {
await announce(actor, activity);
return await announce(actor, activity);
} else if (isLike(activity)) {
await like(actor, activity);
return await like(actor, activity);
} else if (isUndo(activity)) {
await undo(actor, activity);
return await undo(actor, activity);
} else if (isBlock(activity)) {
await block(actor, activity);
return await block(actor, activity);
} else {
apLogger.warn(`unknown activity type: ${(activity as any).type}`);
return `skip: unknown activity type: ${(activity as any).type}`;
}
}
4 changes: 2 additions & 2 deletions src/remote/activitypub/perform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { IActivity } from './type';
import { IRemoteUser } from '../../models/user';
import { performActivity } from './kernel';

export default async (actor: IRemoteUser, activity: IActivity): Promise<void> => {
await performActivity(actor, activity);
export default async (actor: IRemoteUser, activity: IActivity) => {
return await performActivity(actor, activity);
};

0 comments on commit 9efd8ab

Please sign in to comment.