diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-11-09 17:51:58 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-11-27 19:40:51 +0100 |
commit | e4f97babf701481b55cc10fb3448feab5f97c867 (patch) | |
tree | af37402a594dc5ff09f71ecb0687e8cfe4cdb471 /server/middlewares | |
parent | 343ad675f2a26c15b86150a9a3552e619d5d44f4 (diff) | |
download | PeerTube-e4f97babf701481b55cc10fb3448feab5f97c867.tar.gz PeerTube-e4f97babf701481b55cc10fb3448feab5f97c867.tar.zst PeerTube-e4f97babf701481b55cc10fb3448feab5f97c867.zip |
Begin activitypub
Diffstat (limited to 'server/middlewares')
-rw-r--r-- | server/middlewares/activitypub.ts | 57 | ||||
-rw-r--r-- | server/middlewares/index.ts | 2 | ||||
-rw-r--r-- | server/middlewares/secure.ts | 55 | ||||
-rw-r--r-- | server/middlewares/validators/account.ts | 53 | ||||
-rw-r--r-- | server/middlewares/validators/activitypub/index.ts (renamed from server/middlewares/validators/remote/index.ts) | 0 | ||||
-rw-r--r-- | server/middlewares/validators/activitypub/pods.ts (renamed from server/middlewares/validators/remote/pods.ts) | 0 | ||||
-rw-r--r-- | server/middlewares/validators/activitypub/signature.ts | 30 | ||||
-rw-r--r-- | server/middlewares/validators/activitypub/videos.ts (renamed from server/middlewares/validators/remote/videos.ts) | 0 | ||||
-rw-r--r-- | server/middlewares/validators/index.ts | 3 | ||||
-rw-r--r-- | server/middlewares/validators/remote/signature.ts | 22 |
10 files changed, 143 insertions, 79 deletions
diff --git a/server/middlewares/activitypub.ts b/server/middlewares/activitypub.ts new file mode 100644 index 000000000..6cf8eea6f --- /dev/null +++ b/server/middlewares/activitypub.ts | |||
@@ -0,0 +1,57 @@ | |||
1 | import { Request, Response, NextFunction } from 'express' | ||
2 | |||
3 | import { database as db } from '../initializers' | ||
4 | import { | ||
5 | logger, | ||
6 | getAccountFromWebfinger, | ||
7 | isSignatureVerified | ||
8 | } from '../helpers' | ||
9 | import { ActivityPubSignature } from '../../shared' | ||
10 | |||
11 | async function checkSignature (req: Request, res: Response, next: NextFunction) { | ||
12 | const signatureObject: ActivityPubSignature = req.body.signature | ||
13 | |||
14 | logger.debug('Checking signature of account %s...', signatureObject.creator) | ||
15 | |||
16 | let account = await db.Account.loadByUrl(signatureObject.creator) | ||
17 | |||
18 | // We don't have this account in our database, fetch it on remote | ||
19 | if (!account) { | ||
20 | account = await getAccountFromWebfinger(signatureObject.creator) | ||
21 | |||
22 | if (!account) { | ||
23 | return res.sendStatus(403) | ||
24 | } | ||
25 | |||
26 | // Save our new account in database | ||
27 | await account.save() | ||
28 | } | ||
29 | |||
30 | const verified = await isSignatureVerified(account, req.body) | ||
31 | if (verified === false) return res.sendStatus(403) | ||
32 | |||
33 | res.locals.signature.account = account | ||
34 | |||
35 | return next() | ||
36 | } | ||
37 | |||
38 | function executeIfActivityPub (fun: any | any[]) { | ||
39 | return (req: Request, res: Response, next: NextFunction) => { | ||
40 | if (req.header('Accept') !== 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"') { | ||
41 | return next() | ||
42 | } | ||
43 | |||
44 | if (Array.isArray(fun) === true) { | ||
45 | fun[0](req, res, next) // FIXME: doesn't work | ||
46 | } | ||
47 | |||
48 | return fun(req, res, next) | ||
49 | } | ||
50 | } | ||
51 | |||
52 | // --------------------------------------------------------------------------- | ||
53 | |||
54 | export { | ||
55 | checkSignature, | ||
56 | executeIfActivityPub | ||
57 | } | ||
diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts index cec3e0b2a..40480450b 100644 --- a/server/middlewares/index.ts +++ b/server/middlewares/index.ts | |||
@@ -1,9 +1,9 @@ | |||
1 | export * from './validators' | 1 | export * from './validators' |
2 | export * from './activitypub' | ||
2 | export * from './async' | 3 | export * from './async' |
3 | export * from './oauth' | 4 | export * from './oauth' |
4 | export * from './pagination' | 5 | export * from './pagination' |
5 | export * from './pods' | 6 | export * from './pods' |
6 | export * from './search' | 7 | export * from './search' |
7 | export * from './secure' | ||
8 | export * from './sort' | 8 | export * from './sort' |
9 | export * from './user-right' | 9 | export * from './user-right' |
diff --git a/server/middlewares/secure.ts b/server/middlewares/secure.ts deleted file mode 100644 index 5dd809f15..000000000 --- a/server/middlewares/secure.ts +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | import 'express-validator' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | import { database as db } from '../initializers' | ||
5 | import { | ||
6 | logger, | ||
7 | checkSignature as peertubeCryptoCheckSignature | ||
8 | } from '../helpers' | ||
9 | import { PodSignature } from '../../shared' | ||
10 | |||
11 | async function checkSignature (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
12 | const signatureObject: PodSignature = req.body.signature | ||
13 | const host = signatureObject.host | ||
14 | |||
15 | try { | ||
16 | const pod = await db.Pod.loadByHost(host) | ||
17 | if (pod === null) { | ||
18 | logger.error('Unknown pod %s.', host) | ||
19 | return res.sendStatus(403) | ||
20 | } | ||
21 | |||
22 | logger.debug('Checking signature from %s.', host) | ||
23 | |||
24 | let signatureShouldBe | ||
25 | // If there is data in the body the sender used it for its signature | ||
26 | // If there is no data we just use its host as signature | ||
27 | if (req.body.data) { | ||
28 | signatureShouldBe = req.body.data | ||
29 | } else { | ||
30 | signatureShouldBe = host | ||
31 | } | ||
32 | |||
33 | const signatureOk = peertubeCryptoCheckSignature(pod.publicKey, signatureShouldBe, signatureObject.signature) | ||
34 | |||
35 | if (signatureOk === true) { | ||
36 | res.locals.secure = { | ||
37 | pod | ||
38 | } | ||
39 | |||
40 | return next() | ||
41 | } | ||
42 | |||
43 | logger.error('Signature is not okay in body for %s.', signatureObject.host) | ||
44 | return res.sendStatus(403) | ||
45 | } catch (err) { | ||
46 | logger.error('Cannot get signed host in body.', { error: err.stack, signature: signatureObject.signature }) | ||
47 | return res.sendStatus(500) | ||
48 | } | ||
49 | } | ||
50 | |||
51 | // --------------------------------------------------------------------------- | ||
52 | |||
53 | export { | ||
54 | checkSignature | ||
55 | } | ||
diff --git a/server/middlewares/validators/account.ts b/server/middlewares/validators/account.ts new file mode 100644 index 000000000..5abe942d6 --- /dev/null +++ b/server/middlewares/validators/account.ts | |||
@@ -0,0 +1,53 @@ | |||
1 | import { param } from 'express-validator/check' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | import { database as db } from '../../initializers/database' | ||
5 | import { checkErrors } from './utils' | ||
6 | import { | ||
7 | logger, | ||
8 | isUserUsernameValid, | ||
9 | isUserPasswordValid, | ||
10 | isUserVideoQuotaValid, | ||
11 | isUserDisplayNSFWValid, | ||
12 | isUserRoleValid, | ||
13 | isAccountNameValid | ||
14 | } from '../../helpers' | ||
15 | import { AccountInstance } from '../../models' | ||
16 | |||
17 | const localAccountValidator = [ | ||
18 | param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'), | ||
19 | |||
20 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
21 | logger.debug('Checking localAccountValidator parameters', { parameters: req.params }) | ||
22 | |||
23 | checkErrors(req, res, () => { | ||
24 | checkLocalAccountExists(req.params.name, res, next) | ||
25 | }) | ||
26 | } | ||
27 | ] | ||
28 | |||
29 | // --------------------------------------------------------------------------- | ||
30 | |||
31 | export { | ||
32 | localAccountValidator | ||
33 | } | ||
34 | |||
35 | // --------------------------------------------------------------------------- | ||
36 | |||
37 | function checkLocalAccountExists (name: string, res: express.Response, callback: (err: Error, account: AccountInstance) => void) { | ||
38 | db.Account.loadLocalAccountByName(name) | ||
39 | .then(account => { | ||
40 | if (!account) { | ||
41 | return res.status(404) | ||
42 | .send({ error: 'Account not found' }) | ||
43 | .end() | ||
44 | } | ||
45 | |||
46 | res.locals.account = account | ||
47 | return callback(null, account) | ||
48 | }) | ||
49 | .catch(err => { | ||
50 | logger.error('Error in account request validator.', err) | ||
51 | return res.sendStatus(500) | ||
52 | }) | ||
53 | } | ||
diff --git a/server/middlewares/validators/remote/index.ts b/server/middlewares/validators/activitypub/index.ts index f1f26043e..f1f26043e 100644 --- a/server/middlewares/validators/remote/index.ts +++ b/server/middlewares/validators/activitypub/index.ts | |||
diff --git a/server/middlewares/validators/remote/pods.ts b/server/middlewares/validators/activitypub/pods.ts index f917b61ee..f917b61ee 100644 --- a/server/middlewares/validators/remote/pods.ts +++ b/server/middlewares/validators/activitypub/pods.ts | |||
diff --git a/server/middlewares/validators/activitypub/signature.ts b/server/middlewares/validators/activitypub/signature.ts new file mode 100644 index 000000000..0ce15c1f6 --- /dev/null +++ b/server/middlewares/validators/activitypub/signature.ts | |||
@@ -0,0 +1,30 @@ | |||
1 | import { body } from 'express-validator/check' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | import { | ||
5 | logger, | ||
6 | isDateValid, | ||
7 | isSignatureTypeValid, | ||
8 | isSignatureCreatorValid, | ||
9 | isSignatureValueValid | ||
10 | } from '../../../helpers' | ||
11 | import { checkErrors } from '../utils' | ||
12 | |||
13 | const signatureValidator = [ | ||
14 | body('signature.type').custom(isSignatureTypeValid).withMessage('Should have a valid signature type'), | ||
15 | body('signature.created').custom(isDateValid).withMessage('Should have a valid signature created date'), | ||
16 | body('signature.creator').custom(isSignatureCreatorValid).withMessage('Should have a valid signature creator'), | ||
17 | body('signature.signatureValue').custom(isSignatureValueValid).withMessage('Should have a valid signature value'), | ||
18 | |||
19 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
20 | logger.debug('Checking activitypub signature parameter', { parameters: { signature: req.body.signature } }) | ||
21 | |||
22 | checkErrors(req, res, next) | ||
23 | } | ||
24 | ] | ||
25 | |||
26 | // --------------------------------------------------------------------------- | ||
27 | |||
28 | export { | ||
29 | signatureValidator | ||
30 | } | ||
diff --git a/server/middlewares/validators/remote/videos.ts b/server/middlewares/validators/activitypub/videos.ts index 497320cc1..497320cc1 100644 --- a/server/middlewares/validators/remote/videos.ts +++ b/server/middlewares/validators/activitypub/videos.ts | |||
diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts index 247f6039e..46c00d679 100644 --- a/server/middlewares/validators/index.ts +++ b/server/middlewares/validators/index.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | export * from './account' | ||
1 | export * from './oembed' | 2 | export * from './oembed' |
2 | export * from './remote' | 3 | export * from './activitypub' |
3 | export * from './pagination' | 4 | export * from './pagination' |
4 | export * from './pods' | 5 | export * from './pods' |
5 | export * from './sort' | 6 | export * from './sort' |
diff --git a/server/middlewares/validators/remote/signature.ts b/server/middlewares/validators/remote/signature.ts deleted file mode 100644 index d3937b515..000000000 --- a/server/middlewares/validators/remote/signature.ts +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | import { body } from 'express-validator/check' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | import { logger, isHostValid } from '../../../helpers' | ||
5 | import { checkErrors } from '../utils' | ||
6 | |||
7 | const signatureValidator = [ | ||
8 | body('signature.host').custom(isHostValid).withMessage('Should have a signature host'), | ||
9 | body('signature.signature').not().isEmpty().withMessage('Should have a signature'), | ||
10 | |||
11 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
12 | logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } }) | ||
13 | |||
14 | checkErrors(req, res, next) | ||
15 | } | ||
16 | ] | ||
17 | |||
18 | // --------------------------------------------------------------------------- | ||
19 | |||
20 | export { | ||
21 | signatureValidator | ||
22 | } | ||