Filter tracker based on infohash
authorChocobozzz <me@florianbigard.com>
Tue, 14 Aug 2018 09:00:03 +0000 (11:00 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 14 Aug 2018 09:00:03 +0000 (11:00 +0200)
server/controllers/tracker.ts
server/models/video/video-file.ts
server/tests/api/index-fast.ts
server/tests/api/server/tracker.ts [new file with mode: 0644]

index 42f5aea8101b8de40229a8b6acd2ea7c679771de..9bc7586d19a23412e4652cf28228e60f0971fd08 100644 (file)
@@ -5,6 +5,7 @@ import * as bitTorrentTracker from 'bittorrent-tracker'
 import * as proxyAddr from 'proxy-addr'
 import { Server as WebSocketServer } from 'ws'
 import { CONFIG, TRACKER_RATE_LIMITS } from '../initializers/constants'
+import { VideoFileModel } from '../models/video/video-file'
 
 const TrackerServer = bitTorrentTracker.Server
 
@@ -37,7 +38,12 @@ const trackerServer = new TrackerServer({
       return cb(new Error(`Too many requests (${peersIpInfoHash[ key ]} of ip ${ip} for torrent ${infoHash}`))
     }
 
-    return cb()
+    VideoFileModel.isInfohashExists(infoHash)
+      .then(exists => {
+        if (exists === false) return cb(new Error(`Unknown infoHash ${infoHash}`))
+
+        return cb()
+      })
   }
 })
 
index f5a2b6c1f5ef99a4cc3a5381490a6912c37b4b28..3bc4855f38afb2bb5c86cb1adf24a8ed96caf0a6 100644 (file)
@@ -9,6 +9,7 @@ import {
 import { CONSTRAINTS_FIELDS } from '../../initializers'
 import { throwIfNotValid } from '../utils'
 import { VideoModel } from './video'
+import * as Sequelize from 'sequelize'
 
 @Table({
   tableName: 'videoFile',
@@ -68,4 +69,18 @@ export class VideoFileModel extends Model<VideoFileModel> {
     onDelete: 'CASCADE'
   })
   Video: VideoModel
+
+  static isInfohashExists (infoHash: string) {
+    const query = 'SELECT 1 FROM "videoFile" WHERE "infoHash" = $infoHash LIMIT 1'
+    const options = {
+      type: Sequelize.QueryTypes.SELECT,
+      bind: { infoHash },
+      raw: true
+    }
+
+    return VideoModel.sequelize.query(query, options)
+              .then(results => {
+                return results.length === 1
+              })
+  }
 }
index 531a09b82418769d7d320a6da1642dfc90840451..02ffdd4f1bbfe7a36e1e12a91fdfbbe5d86e99ac 100644 (file)
@@ -15,3 +15,4 @@ import './server/email'
 import './server/config'
 import './server/reverse-proxy'
 import './search/search-videos'
+import './server/tracker'
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts
new file mode 100644 (file)
index 0000000..5d61c15
--- /dev/null
@@ -0,0 +1,71 @@
+/* tslint:disable:no-unused-expression */
+
+import * as magnetUtil from 'magnet-uri'
+import * as chai from 'chai'
+import 'mocha'
+import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../utils'
+import { flushTests, setAccessTokensToServers } from '../../utils/index'
+import { VideoDetails } from '../../../../shared/models/videos'
+import * as WebTorrent from 'webtorrent'
+
+describe('Test tracker', function () {
+  let server: ServerInfo
+  let badMagnet: string
+  let goodMagnet: string
+
+  before(async function () {
+    this.timeout(60000)
+
+    await flushTests()
+    server = await runServer(1)
+    await setAccessTokensToServers([ server ])
+
+    {
+      const res = await uploadVideo(server.url, server.accessToken, {})
+      const videoUUID = res.body.video.uuid
+
+      const resGet = await getVideo(server.url, videoUUID)
+      const video: VideoDetails = resGet.body
+      goodMagnet = video.files[0].magnetUri
+
+      const parsed = magnetUtil.decode(goodMagnet)
+      parsed.infoHash = '010597bb88b1968a5693a4fa8267c592ca65f2e9'
+
+      badMagnet = magnetUtil.encode(parsed)
+    }
+  })
+
+  it('Should return an error when adding an incorrect infohash', done => {
+    this.timeout(10000)
+    const webtorrent = new WebTorrent()
+
+    const torrent = webtorrent.add(badMagnet)
+
+    torrent.on('error', done)
+    torrent.on('warning', warn => {
+      const message = typeof warn === 'string' ? warn : warn.message
+      if (message.indexOf('Unknown infoHash ') !== -1) return done()
+    })
+
+    torrent.on('done', () => done(new Error('No error on infohash')))
+  })
+
+  it('Should succeed with the correct infohash', done => {
+    this.timeout(10000)
+    const webtorrent = new WebTorrent()
+
+    const torrent = webtorrent.add(goodMagnet)
+
+    torrent.on('error', done)
+    torrent.on('warning', warn => {
+      const message = typeof warn === 'string' ? warn : warn.message
+      if (message.indexOf('Unknown infoHash ') !== -1) return done(new Error('Error on infohash'))
+    })
+
+    torrent.on('done', done)
+  })
+
+  after(async function () {
+    killallServers([ server ])
+  })
+})