From ce548a10db3822c415b30ea0edb59e02a460734a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 13 Nov 2017 18:48:28 +0100 Subject: Send follow/accept --- server/lib/activitypub/process-accept.ts | 6 ++--- server/lib/activitypub/process-add.ts | 2 +- server/lib/activitypub/process-follow.ts | 39 ++++++++++++++++++++------- server/lib/activitypub/send-request.ts | 46 +++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 14 deletions(-) (limited to 'server/lib') diff --git a/server/lib/activitypub/process-accept.ts b/server/lib/activitypub/process-accept.ts index 37e42bd3a..9e0cd4032 100644 --- a/server/lib/activitypub/process-accept.ts +++ b/server/lib/activitypub/process-accept.ts @@ -7,7 +7,7 @@ async function processAcceptActivity (activity: ActivityAccept, inboxAccount?: A const targetAccount = await db.Account.loadByUrl(activity.actor) - return processFollow(inboxAccount, targetAccount) + return processAccept(inboxAccount, targetAccount) } // --------------------------------------------------------------------------- @@ -18,10 +18,10 @@ export { // --------------------------------------------------------------------------- -async function processFollow (account: AccountInstance, targetAccount: AccountInstance) { +async function processAccept (account: AccountInstance, targetAccount: AccountInstance) { const follow = await db.AccountFollow.loadByAccountAndTarget(account.id, targetAccount.id) if (!follow) throw new Error('Cannot find associated follow.') follow.set('state', 'accepted') - return follow.save() + await follow.save() } diff --git a/server/lib/activitypub/process-add.ts b/server/lib/activitypub/process-add.ts index 40541aca3..024dee559 100644 --- a/server/lib/activitypub/process-add.ts +++ b/server/lib/activitypub/process-add.ts @@ -29,7 +29,7 @@ export { function processAddVideo (account: AccountInstance, videoChannelUrl: string, video: VideoTorrentObject) { const options = { - arguments: [ account, videoChannelUrl ,video ], + arguments: [ account, videoChannelUrl, video ], errorMessage: 'Cannot insert the remote video with many retries.' } diff --git a/server/lib/activitypub/process-follow.ts b/server/lib/activitypub/process-follow.ts index a04fc7994..ee5d97a0b 100644 --- a/server/lib/activitypub/process-follow.ts +++ b/server/lib/activitypub/process-follow.ts @@ -1,7 +1,9 @@ import { ActivityFollow } from '../../../shared/models/activitypub/activity' -import { getOrCreateAccount } from '../../helpers' +import { getOrCreateAccount, retryTransactionWrapper } from '../../helpers' import { database as db } from '../../initializers' import { AccountInstance } from '../../models/account/account-interface' +import { sendAccept } from './send-request' +import { logger } from '../../helpers/logger' async function processFollowActivity (activity: ActivityFollow) { const activityObject = activity.object @@ -18,15 +20,34 @@ export { // --------------------------------------------------------------------------- -async function processFollow (account: AccountInstance, targetAccountURL: string) { - const targetAccount = await db.Account.loadByUrl(targetAccountURL) +function processFollow (account: AccountInstance, targetAccountURL: string) { + const options = { + arguments: [ account, targetAccountURL ], + errorMessage: 'Cannot follow with many retries.' + } - if (targetAccount === undefined) throw new Error('Unknown account') - if (targetAccount.isOwned() === false) throw new Error('This is not a local account.') + return retryTransactionWrapper(follow, options) +} + +async function follow (account: AccountInstance, targetAccountURL: string) { + await db.sequelize.transaction(async t => { + const targetAccount = await db.Account.loadByUrl(targetAccountURL, t) + + if (targetAccount === undefined) throw new Error('Unknown account') + if (targetAccount.isOwned() === false) throw new Error('This is not a local account.') - return db.AccountFollow.create({ - accountId: account.id, - targetAccountId: targetAccount.id, - state: 'accepted' + const sequelizeOptions = { + transaction: t + } + await db.AccountFollow.create({ + accountId: account.id, + targetAccountId: targetAccount.id, + state: 'accepted' + }, sequelizeOptions) + + // Target sends to account he accepted the follow request + return sendAccept(targetAccount, account, t) }) + + logger.info('Account uuid %s is followed by account %s.', account.url, targetAccountURL) } diff --git a/server/lib/activitypub/send-request.ts b/server/lib/activitypub/send-request.ts index ce9a96f14..e6ef5f37a 100644 --- a/server/lib/activitypub/send-request.ts +++ b/server/lib/activitypub/send-request.ts @@ -56,6 +56,18 @@ function sendDeleteAccount (account: AccountInstance, t: Sequelize.Transaction) return broadcastToFollowers(data, account, t) } +function sendAccept (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { + const data = acceptActivityData(fromAccount) + + return unicastTo(data, toAccount, t) +} + +function sendFollow (fromAccount: AccountInstance, toAccount: AccountInstance, t: Sequelize.Transaction) { + const data = followActivityData(toAccount.url, fromAccount) + + return unicastTo(data, toAccount, t) +} + // --------------------------------------------------------------------------- export { @@ -65,7 +77,9 @@ export { sendAddVideo, sendUpdateVideo, sendDeleteVideo, - sendDeleteAccount + sendDeleteAccount, + sendAccept, + sendFollow } // --------------------------------------------------------------------------- @@ -81,6 +95,15 @@ async function broadcastToFollowers (data: any, fromAccount: AccountInstance, t: return httpRequestJobScheduler.createJob(t, 'httpRequestBroadcastHandler', jobPayload) } +async function unicastTo (data: any, toAccount: AccountInstance, t: Sequelize.Transaction) { + const jobPayload = { + uris: [ toAccount.url ], + body: data + } + + return httpRequestJobScheduler.createJob(t, 'httpRequestUnicastHandler', jobPayload) +} + function buildSignedActivity (byAccount: AccountInstance, data: Object) { const activity = activityPubContextify(data) @@ -142,3 +165,24 @@ async function addActivityData (url: string, byAccount: AccountInstance, target: return buildSignedActivity(byAccount, base) } + +async function followActivityData (url: string, byAccount: AccountInstance) { + const base = { + type: 'Follow', + id: byAccount.url, + actor: byAccount.url, + object: url + } + + return buildSignedActivity(byAccount, base) +} + +async function acceptActivityData (byAccount: AccountInstance) { + const base = { + type: 'Accept', + id: byAccount.url, + actor: byAccount.url + } + + return buildSignedActivity(byAccount, base) +} -- cgit v1.2.3