perf(federation): Use hint for getAuthUserFromApId (#13470)
* Hint for getAuthUserFromApId * とどのつまりこれでいいのか?
This commit is contained in:
parent
59ae735169
commit
aaacfabc1b
|
@ -35,7 +35,6 @@ export type UriParseResult = {
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApDbResolverService implements OnApplicationShutdown {
|
export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
private publicKeyCache: MemoryKVCache<MiUserPublickey | null>;
|
|
||||||
private publicKeyByUserIdCache: MemoryKVCache<MiUserPublickey[] | null>;
|
private publicKeyByUserIdCache: MemoryKVCache<MiUserPublickey[] | null>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -54,7 +53,6 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
private cacheService: CacheService,
|
private cacheService: CacheService,
|
||||||
private apPersonService: ApPersonService,
|
private apPersonService: ApPersonService,
|
||||||
) {
|
) {
|
||||||
this.publicKeyCache = new MemoryKVCache<MiUserPublickey | null>(1e3 * 60 * 20); // 20分
|
|
||||||
this.publicKeyByUserIdCache = new MemoryKVCache<MiUserPublickey[] | null>(1e3 * 60 * 20); // 20分
|
this.publicKeyByUserIdCache = new MemoryKVCache<MiUserPublickey[] | null>(1e3 * 60 * 20); // 20分
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,41 +114,11 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* AP KeyId => Misskey User and Key
|
|
||||||
*/
|
|
||||||
@bindThis
|
|
||||||
public async getAuthUserFromKeyId(keyId: string): Promise<{
|
|
||||||
user: MiRemoteUser;
|
|
||||||
key: MiUserPublickey;
|
|
||||||
} | null> {
|
|
||||||
const key = await this.publicKeyCache.fetch(keyId, async () => {
|
|
||||||
const key = await this.userPublickeysRepository.findOneBy({
|
|
||||||
keyId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (key == null) return null;
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}, key => key != null);
|
|
||||||
|
|
||||||
if (key == null) return null;
|
|
||||||
|
|
||||||
const user = await this.cacheService.findUserById(key.userId).catch(() => null) as MiRemoteUser | null;
|
|
||||||
if (user == null) return null;
|
|
||||||
if (user.isDeleted) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
key,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AP Actor id => Misskey User and Key
|
* AP Actor id => Misskey User and Key
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async getAuthUserFromApId(uri: string): Promise<{
|
public async getAuthUserFromApId(uri: string, keyId?: string): Promise<{
|
||||||
user: MiRemoteUser;
|
user: MiRemoteUser;
|
||||||
key: MiUserPublickey | null;
|
key: MiUserPublickey | null;
|
||||||
} | null> {
|
} | null> {
|
||||||
|
@ -170,6 +138,7 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
keys[0] :
|
keys[0] :
|
||||||
keys.find(x => {
|
keys.find(x => {
|
||||||
try {
|
try {
|
||||||
|
if (x.keyId === keyId) return true;
|
||||||
const url = new URL(x.keyId);
|
const url = new URL(x.keyId);
|
||||||
const path = url.pathname.split('/').pop()?.toLowerCase();
|
const path = url.pathname.split('/').pop()?.toLowerCase();
|
||||||
if (url.hash) {
|
if (url.hash) {
|
||||||
|
@ -193,16 +162,10 @@ export class ApDbResolverService implements OnApplicationShutdown {
|
||||||
@bindThis
|
@bindThis
|
||||||
public refreshCacheByUserId(userId: MiUser['id']): void {
|
public refreshCacheByUserId(userId: MiUser['id']): void {
|
||||||
this.publicKeyByUserIdCache.delete(userId);
|
this.publicKeyByUserIdCache.delete(userId);
|
||||||
for (const [k, v] of this.publicKeyCache.cache.entries()) {
|
|
||||||
if (v.value?.userId === userId) {
|
|
||||||
this.publicKeyCache.delete(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
this.publicKeyCache.dispose();
|
|
||||||
this.publicKeyByUserIdCache.dispose();
|
this.publicKeyByUserIdCache.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,20 +77,18 @@ export class InboxProcessorService {
|
||||||
let authUser: {
|
let authUser: {
|
||||||
user: MiRemoteUser;
|
user: MiRemoteUser;
|
||||||
key: MiUserPublickey | null;
|
key: MiUserPublickey | null;
|
||||||
} | null = await this.apDbResolverService.getAuthUserFromKeyId(signature.keyId);
|
} | null = null;
|
||||||
|
|
||||||
// keyIdでわからなければ、activity.actorを元にDBから取得 || activity.actorを元にリモートから取得
|
// keyIdでわからなければ、activity.actorを元にDBから取得 || activity.actorを元にリモートから取得
|
||||||
if (authUser == null) {
|
try {
|
||||||
try {
|
authUser = await this.apDbResolverService.getAuthUserFromApId(getApId(activity.actor), signature.keyId);
|
||||||
authUser = await this.apDbResolverService.getAuthUserFromApId(getApId(activity.actor));
|
} catch (err) {
|
||||||
} catch (err) {
|
// 対象が4xxならスキップ
|
||||||
// 対象が4xxならスキップ
|
if (err instanceof StatusError) {
|
||||||
if (err instanceof StatusError) {
|
if (!err.isRetryable) {
|
||||||
if (!err.isRetryable) {
|
throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`);
|
||||||
throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`);
|
|
||||||
}
|
|
||||||
throw new Error(`Error in actor ${activity.actor} - ${err.statusCode}`);
|
|
||||||
}
|
}
|
||||||
|
throw new Error(`Error in actor ${activity.actor} - ${err.statusCode}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,21 +108,13 @@ export class InboxProcessorService {
|
||||||
// また、signatureのsignerは、activity.actorと一致する必要がある
|
// また、signatureのsignerは、activity.actorと一致する必要がある
|
||||||
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
|
if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
|
||||||
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
||||||
if (activity.signature) {
|
if (activity.signature?.creator) {
|
||||||
if (activity.signature.type !== 'RsaSignature2017') {
|
if (activity.signature.type !== 'RsaSignature2017') {
|
||||||
throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`);
|
throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// activity.signature.creator: https://example.oom/users/user#main-key
|
authUser = await this.apDbResolverService.getAuthUserFromApId(activity.signature.creator.replace(/#.*/, ''));
|
||||||
// みたいになっててUserを引っ張れば公開キーも入ることを期待する
|
|
||||||
if (activity.signature.creator) {
|
|
||||||
const candicate = activity.signature.creator.replace(/#.*/, '');
|
|
||||||
const user = await this.apPersonService.resolvePerson(candicate).catch(() => null);
|
|
||||||
if (user) this.apDbResolverService.refreshCacheByUserId(user.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// keyIdからLD-Signatureのユーザーを取得
|
|
||||||
authUser = await this.apDbResolverService.getAuthUserFromKeyId(activity.signature.creator);
|
|
||||||
if (authUser == null) {
|
if (authUser == null) {
|
||||||
throw new Bull.UnrecoverableError('skip: LD-Signatureのユーザーが取得できませんでした');
|
throw new Bull.UnrecoverableError('skip: LD-Signatureのユーザーが取得できませんでした');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue