]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/activitypub/security.ts
Cleanup tests imports
[github/Chocobozzz/PeerTube.git] / server / tests / api / activitypub / security.ts
CommitLineData
df66d815
C
1/* tslint:disable:no-unused-expression */
2
3import 'mocha'
4
d175a6f7 5import { flushAndRunMultipleServers, flushTests, killallServers, ServerInfo } from '../../utils'
df66d815
C
6import { HTTP_SIGNATURE } from '../../../initializers'
7import { buildDigest, buildGlobalHeaders } from '../../../lib/job-queue/handlers/utils/activitypub-http-utils'
8import * as chai from 'chai'
9import { setActorField } from '../../utils/miscs/sql'
10import { activityPubContextify, buildSignedActivity } from '../../../helpers/activitypub'
d175a6f7 11import { makeFollowRequest, makePOSTAPRequest } from '../../utils/requests/activitypub'
df66d815
C
12
13const expect = chai.expect
14
15function setKeysOfServer2 (serverNumber: number, publicKey: string, privateKey: string) {
16 return Promise.all([
17 setActorField(serverNumber, 'http://localhost:9002/accounts/peertube', 'publicKey', publicKey),
18 setActorField(serverNumber, 'http://localhost:9002/accounts/peertube', 'privateKey', privateKey)
19 ])
20}
21
22function setKeysOfServer3 (serverNumber: number, publicKey: string, privateKey: string) {
23 return Promise.all([
24 setActorField(serverNumber, 'http://localhost:9003/accounts/peertube', 'publicKey', publicKey),
25 setActorField(serverNumber, 'http://localhost:9003/accounts/peertube', 'privateKey', privateKey)
26 ])
27}
28
29describe('Test ActivityPub security', function () {
30 let servers: ServerInfo[]
31 let url: string
32
33 const keys = require('./json/peertube/keys.json')
34 const invalidKeys = require('./json/peertube/invalid-keys.json')
35 const baseHttpSignature = {
36 algorithm: HTTP_SIGNATURE.ALGORITHM,
37 authorizationHeaderName: HTTP_SIGNATURE.HEADER_NAME,
38 keyId: 'acct:peertube@localhost:9002',
39 key: keys.privateKey,
40 headers: HTTP_SIGNATURE.HEADERS_TO_SIGN
41 }
42
43 // ---------------------------------------------------------------
44
45 before(async function () {
46 this.timeout(60000)
47
48 servers = await flushAndRunMultipleServers(3)
49
50 url = servers[0].url + '/inbox'
51
52 await setKeysOfServer2(1, keys.publicKey, keys.privateKey)
53
54 const to = { url: 'http://localhost:9001/accounts/peertube' }
55 const by = { url: 'http://localhost:9002/accounts/peertube', privateKey: keys.privateKey }
56 await makeFollowRequest(to, by)
57 })
58
59 describe('When checking HTTP signature', function () {
60
61 it('Should fail with an invalid digest', async function () {
62 const body = activityPubContextify(require('./json/peertube/announce-without-context.json'))
63 const headers = {
64 Digest: buildDigest({ hello: 'coucou' })
65 }
66
5c6d985f 67 const { response } = await makePOSTAPRequest(url, body, baseHttpSignature, headers)
df66d815
C
68
69 expect(response.statusCode).to.equal(403)
70 })
71
72 it('Should fail with an invalid date', async function () {
73 const body = activityPubContextify(require('./json/peertube/announce-without-context.json'))
74 const headers = buildGlobalHeaders(body)
75 headers['date'] = 'Wed, 21 Oct 2015 07:28:00 GMT'
76
5c6d985f 77 const { response } = await makePOSTAPRequest(url, body, baseHttpSignature, headers)
df66d815
C
78
79 expect(response.statusCode).to.equal(403)
80 })
81
82 it('Should fail with bad keys', async function () {
83 await setKeysOfServer2(1, invalidKeys.publicKey, invalidKeys.privateKey)
84 await setKeysOfServer2(2, invalidKeys.publicKey, invalidKeys.privateKey)
85
86 const body = activityPubContextify(require('./json/peertube/announce-without-context.json'))
87 const headers = buildGlobalHeaders(body)
88
5c6d985f 89 const { response } = await makePOSTAPRequest(url, body, baseHttpSignature, headers)
df66d815
C
90
91 expect(response.statusCode).to.equal(403)
92 })
93
94 it('Should succeed with a valid HTTP signature', async function () {
95 await setKeysOfServer2(1, keys.publicKey, keys.privateKey)
96 await setKeysOfServer2(2, keys.publicKey, keys.privateKey)
97
98 const body = activityPubContextify(require('./json/peertube/announce-without-context.json'))
99 const headers = buildGlobalHeaders(body)
100
5c6d985f 101 const { response } = await makePOSTAPRequest(url, body, baseHttpSignature, headers)
df66d815
C
102
103 expect(response.statusCode).to.equal(204)
104 })
105 })
106
107 describe('When checking Linked Data Signature', function () {
108 before(async () => {
109 await setKeysOfServer3(3, keys.publicKey, keys.privateKey)
110
111 const to = { url: 'http://localhost:9001/accounts/peertube' }
112 const by = { url: 'http://localhost:9003/accounts/peertube', privateKey: keys.privateKey }
113 await makeFollowRequest(to, by)
114 })
115
116 it('Should fail with bad keys', async function () {
117 this.timeout(10000)
118
119 await setKeysOfServer3(1, invalidKeys.publicKey, invalidKeys.privateKey)
120 await setKeysOfServer3(3, invalidKeys.publicKey, invalidKeys.privateKey)
121
122 const body = require('./json/peertube/announce-without-context.json')
123 body.actor = 'http://localhost:9003/accounts/peertube'
124
125 const signer: any = { privateKey: invalidKeys.privateKey, url: 'http://localhost:9003/accounts/peertube' }
126 const signedBody = await buildSignedActivity(signer, body)
127
128 const headers = buildGlobalHeaders(signedBody)
129
5c6d985f 130 const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature, headers)
df66d815
C
131
132 expect(response.statusCode).to.equal(403)
133 })
134
135 it('Should fail with an altered body', async function () {
136 this.timeout(10000)
137
138 await setKeysOfServer3(1, keys.publicKey, keys.privateKey)
139 await setKeysOfServer3(3, keys.publicKey, keys.privateKey)
140
141 const body = require('./json/peertube/announce-without-context.json')
142 body.actor = 'http://localhost:9003/accounts/peertube'
143
144 const signer: any = { privateKey: keys.privateKey, url: 'http://localhost:9003/accounts/peertube' }
145 const signedBody = await buildSignedActivity(signer, body)
146
147 signedBody.actor = 'http://localhost:9003/account/peertube'
148
149 const headers = buildGlobalHeaders(signedBody)
150
5c6d985f 151 const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature, headers)
df66d815
C
152
153 expect(response.statusCode).to.equal(403)
154 })
155
156 it('Should succeed with a valid signature', async function () {
157 this.timeout(10000)
158
159 const body = require('./json/peertube/announce-without-context.json')
160 body.actor = 'http://localhost:9003/accounts/peertube'
161
162 const signer: any = { privateKey: keys.privateKey, url: 'http://localhost:9003/accounts/peertube' }
163 const signedBody = await buildSignedActivity(signer, body)
164
165 const headers = buildGlobalHeaders(signedBody)
166
5c6d985f 167 const { response } = await makePOSTAPRequest(url, signedBody, baseHttpSignature, headers)
df66d815
C
168
169 expect(response.statusCode).to.equal(204)
170 })
171 })
172
173 after(async function () {
174 killallServers(servers)
175
176 // Keep the logs if the test failed
177 if (this['ok']) {
178 await flushTests()
179 }
180 })
181})