Async signature and various fixes
This commit is contained in:
parent
18c8e94508
commit
709756b8e1
10 changed files with 40 additions and 54 deletions
|
@ -64,8 +64,7 @@ function remoteVideos (req: express.Request, res: express.Response, next: expres
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
// We need to process in the same order to keep consistency
|
// We need to process in the same order to keep consistency
|
||||||
// TODO: optimization
|
Promise.each(requests, (request: any) => {
|
||||||
Promise.mapSeries(requests, (request: any) => {
|
|
||||||
const data = request.data
|
const data = request.data
|
||||||
|
|
||||||
// Get the function we need to call in order to process the request
|
// Get the function we need to call in order to process the request
|
||||||
|
@ -79,7 +78,7 @@ function remoteVideos (req: express.Request, res: express.Response, next: expres
|
||||||
})
|
})
|
||||||
.catch(err => logger.error('Error managing remote videos.', { error: err }))
|
.catch(err => logger.error('Error managing remote videos.', { error: err }))
|
||||||
|
|
||||||
// We don't need to keep the other pod waiting
|
// Don't block the other pod
|
||||||
return res.type('json').status(204).end()
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +86,7 @@ function remoteVideosQadu (req: express.Request, res: express.Response, next: ex
|
||||||
const requests = req.body.data
|
const requests = req.body.data
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
Promise.mapSeries(requests, (request: any) => {
|
Promise.each(requests, (request: any) => {
|
||||||
const videoData = request.data
|
const videoData = request.data
|
||||||
|
|
||||||
return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
|
return quickAndDirtyUpdateVideoRetryWrapper(videoData, fromPod)
|
||||||
|
@ -101,7 +100,7 @@ function remoteVideosEvents (req: express.Request, res: express.Response, next:
|
||||||
const requests = req.body.data
|
const requests = req.body.data
|
||||||
const fromPod = res.locals.secure.pod
|
const fromPod = res.locals.secure.pod
|
||||||
|
|
||||||
Promise.mapSeries(requests, (request: any) => {
|
Promise.each(requests, (request: any) => {
|
||||||
const eventData = request.data
|
const eventData = request.data
|
||||||
|
|
||||||
return processVideosEventsRetryWrapper(eventData, fromPod)
|
return processVideosEventsRetryWrapper(eventData, fromPod)
|
||||||
|
|
|
@ -8,15 +8,14 @@ import {
|
||||||
CONFIG,
|
CONFIG,
|
||||||
REMOTE_SCHEME,
|
REMOTE_SCHEME,
|
||||||
STATIC_PATHS,
|
STATIC_PATHS,
|
||||||
STATIC_MAX_AGE
|
STATIC_MAX_AGE,
|
||||||
|
OPENGRAPH_COMMENT
|
||||||
} from '../initializers'
|
} from '../initializers'
|
||||||
import { root, readFileBufferPromise } from '../helpers'
|
import { root, readFileBufferPromise } from '../helpers'
|
||||||
import { VideoInstance } from '../models'
|
import { VideoInstance } from '../models'
|
||||||
|
|
||||||
const clientsRouter = express.Router()
|
const clientsRouter = express.Router()
|
||||||
|
|
||||||
// TODO: move to constants
|
|
||||||
const opengraphComment = '<!-- opengraph tags -->'
|
|
||||||
const distPath = join(root(), 'client', 'dist')
|
const distPath = join(root(), 'client', 'dist')
|
||||||
const embedPath = join(distPath, 'standalone', 'videos', 'embed.html')
|
const embedPath = join(distPath, 'standalone', 'videos', 'embed.html')
|
||||||
const indexPath = join(distPath, 'index.html')
|
const indexPath = join(distPath, 'index.html')
|
||||||
|
@ -85,7 +84,7 @@ function addOpenGraphTags (htmlStringPage: string, video: VideoInstance) {
|
||||||
tagsString += '<meta property="' + tagName + '" content="' + tagValue + '" />'
|
tagsString += '<meta property="' + tagName + '" content="' + tagValue + '" />'
|
||||||
})
|
})
|
||||||
|
|
||||||
return htmlStringPage.replace(opengraphComment, tagsString)
|
return htmlStringPage.replace(OPENGRAPH_COMMENT, tagsString)
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
|
function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import * as fs from 'fs'
|
import * as Promise from 'bluebird'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -52,18 +52,15 @@ function sign (data: string|Object) {
|
||||||
dataString = JSON.stringify(data)
|
dataString = JSON.stringify(data)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Cannot sign data.', { error: err })
|
logger.error('Cannot sign data.', { error: err })
|
||||||
return ''
|
return Promise.resolve('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sign.update(dataString, 'utf8')
|
sign.update(dataString, 'utf8')
|
||||||
|
|
||||||
// TODO: make async
|
return getMyPrivateCert().then(myKey => {
|
||||||
const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
|
return sign.sign(myKey, SIGNATURE_ENCODING)
|
||||||
const myKey = fs.readFileSync(certPath)
|
})
|
||||||
const signature = sign.sign(myKey.toString(), SIGNATURE_ENCODING)
|
|
||||||
|
|
||||||
return signature
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function comparePassword (plainPassword: string, hashPassword: string) {
|
function comparePassword (plainPassword: string, hashPassword: string) {
|
||||||
|
|
|
@ -33,7 +33,6 @@ type MakeSecureRequestParams = {
|
||||||
method: 'GET'|'POST'
|
method: 'GET'|'POST'
|
||||||
toPod: PodInstance
|
toPod: PodInstance
|
||||||
path: string
|
path: string
|
||||||
sign: boolean
|
|
||||||
data?: Object
|
data?: Object
|
||||||
}
|
}
|
||||||
function makeSecureRequest (params: MakeSecureRequestParams) {
|
function makeSecureRequest (params: MakeSecureRequestParams) {
|
||||||
|
@ -47,31 +46,30 @@ function makeSecureRequest (params: MakeSecureRequestParams) {
|
||||||
return rej(new Error('Cannot make a secure request with a non POST method.'))
|
return rej(new Error('Cannot make a secure request with a non POST method.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add signature if it is specified in the params
|
const host = CONFIG.WEBSERVER.HOST
|
||||||
if (params.sign === true) {
|
|
||||||
const host = CONFIG.WEBSERVER.HOST
|
|
||||||
|
|
||||||
let dataToSign
|
let dataToSign
|
||||||
if (params.data) {
|
if (params.data) {
|
||||||
dataToSign = params.data
|
dataToSign = params.data
|
||||||
} else {
|
} else {
|
||||||
// We do not have data to sign so we just take our host
|
// We do not have data to sign so we just take our host
|
||||||
// It is not ideal but the connection should be in HTTPS
|
// It is not ideal but the connection should be in HTTPS
|
||||||
dataToSign = host
|
dataToSign = host
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sign(dataToSign).then(signature => {
|
||||||
requestParams.json['signature'] = {
|
requestParams.json['signature'] = {
|
||||||
host, // Which host we pretend to be
|
host, // Which host we pretend to be
|
||||||
signature: sign(dataToSign)
|
signature
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If there are data informations
|
// If there are data informations
|
||||||
if (params.data) {
|
if (params.data) {
|
||||||
requestParams.json['data'] = params.data
|
requestParams.json['data'] = params.data
|
||||||
}
|
}
|
||||||
|
|
||||||
request.post(requestParams, (err, response, body) => err ? rej(err) : res({ response, body }))
|
request.post(requestParams, (err, response, body) => err ? rej(err) : res({ response, body }))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,10 @@ const USER_ROLES: { [ id: string ]: UserRole } = {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const OPENGRAPH_COMMENT = '<!-- opengraph tags -->'
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Special constants for a test instance
|
// Special constants for a test instance
|
||||||
if (isTestInstance() === true) {
|
if (isTestInstance() === true) {
|
||||||
CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14
|
CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14
|
||||||
|
@ -306,12 +310,13 @@ export {
|
||||||
CONFIG,
|
CONFIG,
|
||||||
CONSTRAINTS_FIELDS,
|
CONSTRAINTS_FIELDS,
|
||||||
FRIEND_SCORE,
|
FRIEND_SCORE,
|
||||||
JOBS_FETCHING_INTERVAL,
|
|
||||||
JOB_STATES,
|
JOB_STATES,
|
||||||
JOBS_CONCURRENCY,
|
JOBS_CONCURRENCY,
|
||||||
JOBS_FETCH_LIMIT_PER_CYCLE,
|
JOBS_FETCH_LIMIT_PER_CYCLE,
|
||||||
|
JOBS_FETCHING_INTERVAL,
|
||||||
LAST_MIGRATION_VERSION,
|
LAST_MIGRATION_VERSION,
|
||||||
OAUTH_LIFETIME,
|
OAUTH_LIFETIME,
|
||||||
|
OPENGRAPH_COMMENT,
|
||||||
PAGINATION_COUNT_DEFAULT,
|
PAGINATION_COUNT_DEFAULT,
|
||||||
PODS_SCORE,
|
PODS_SCORE,
|
||||||
PREVIEWS_SIZE,
|
PREVIEWS_SIZE,
|
||||||
|
|
|
@ -35,9 +35,7 @@ function migrate () {
|
||||||
return getMigrationScripts().then(migrationScripts => ({ actualVersion, migrationScripts }))
|
return getMigrationScripts().then(migrationScripts => ({ actualVersion, migrationScripts }))
|
||||||
})
|
})
|
||||||
.then(({ actualVersion, migrationScripts }) => {
|
.then(({ actualVersion, migrationScripts }) => {
|
||||||
return Promise.mapSeries(migrationScripts, entity => {
|
return Promise.each(migrationScripts, entity => executeMigration(actualVersion, entity))
|
||||||
return executeMigration(actualVersion, entity)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
|
logger.info('Migrations finished. New migration version schema: %s', LAST_MIGRATION_VERSION)
|
||||||
|
|
|
@ -141,9 +141,7 @@ function makeFriends (hosts: string[]) {
|
||||||
logger.info('Make friends!')
|
logger.info('Make friends!')
|
||||||
return getMyPublicCert()
|
return getMyPublicCert()
|
||||||
.then(cert => {
|
.then(cert => {
|
||||||
return Promise.mapSeries(hosts, host => {
|
return Promise.each(hosts, host => computeForeignPodsList(host, podsScore)).then(() => cert)
|
||||||
return computeForeignPodsList(host, podsScore)
|
|
||||||
}).then(() => cert)
|
|
||||||
})
|
})
|
||||||
.then(cert => {
|
.then(cert => {
|
||||||
logger.debug('Pods scores computed.', { podsScore: podsScore })
|
logger.debug('Pods scores computed.', { podsScore: podsScore })
|
||||||
|
@ -169,7 +167,6 @@ function quitFriends () {
|
||||||
const requestParams = {
|
const requestParams = {
|
||||||
method: 'POST' as 'POST',
|
method: 'POST' as 'POST',
|
||||||
path: '/api/' + API_VERSION + '/remote/pods/remove',
|
path: '/api/' + API_VERSION + '/remote/pods/remove',
|
||||||
sign: true,
|
|
||||||
toPod: null
|
toPod: null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +175,7 @@ function quitFriends () {
|
||||||
// The other pod will exclude us automatically after a while
|
// The other pod will exclude us automatically after a while
|
||||||
return Promise.map(pods, pod => {
|
return Promise.map(pods, pod => {
|
||||||
requestParams.toPod = pod
|
requestParams.toPod = pod
|
||||||
|
|
||||||
return makeSecureRequest(requestParams)
|
return makeSecureRequest(requestParams)
|
||||||
}, { concurrency: REQUESTS_IN_PARALLEL })
|
}, { concurrency: REQUESTS_IN_PARALLEL })
|
||||||
.then(() => pods)
|
.then(() => pods)
|
||||||
|
|
|
@ -70,7 +70,6 @@ abstract class AbstractRequestScheduler <T> {
|
||||||
protected makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: Object) {
|
protected makeRequest (toPod: PodInstance, requestEndpoint: string, requestsToMake: Object) {
|
||||||
const params = {
|
const params = {
|
||||||
toPod: toPod,
|
toPod: toPod,
|
||||||
sign: true, // Prove our identity
|
|
||||||
method: 'POST' as 'POST',
|
method: 'POST' as 'POST',
|
||||||
path: '/api/' + API_VERSION + '/remote/' + requestEndpoint,
|
path: '/api/' + API_VERSION + '/remote/' + requestEndpoint,
|
||||||
data: requestsToMake // Requests we need to make
|
data: requestsToMake // Requests we need to make
|
||||||
|
|
|
@ -61,16 +61,9 @@ class RequestScheduler extends AbstractRequestScheduler<RequestsGrouped> {
|
||||||
}
|
}
|
||||||
|
|
||||||
createRequest ({ type, endpoint, data, toIds, transaction }: RequestSchedulerOptions) {
|
createRequest ({ type, endpoint, data, toIds, transaction }: RequestSchedulerOptions) {
|
||||||
// TODO: check the setPods works
|
|
||||||
const podIds = []
|
|
||||||
|
|
||||||
// If there are no destination pods abort
|
// If there are no destination pods abort
|
||||||
if (toIds.length === 0) return undefined
|
if (toIds.length === 0) return undefined
|
||||||
|
|
||||||
toIds.forEach(toPod => {
|
|
||||||
podIds.push(toPod)
|
|
||||||
})
|
|
||||||
|
|
||||||
const createQuery = {
|
const createQuery = {
|
||||||
endpoint,
|
endpoint,
|
||||||
request: {
|
request: {
|
||||||
|
@ -85,7 +78,7 @@ class RequestScheduler extends AbstractRequestScheduler<RequestsGrouped> {
|
||||||
|
|
||||||
return db.Request.create(createQuery, dbRequestOptions)
|
return db.Request.create(createQuery, dbRequestOptions)
|
||||||
.then(request => {
|
.then(request => {
|
||||||
return request.setPods(podIds, dbRequestOptions)
|
return request.setPods(toIds, dbRequestOptions)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ function checkSignature (req: express.Request, res: express.Response, next: expr
|
||||||
return res.sendStatus(403)
|
return res.sendStatus(403)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error('Cannot get signed host in body.', { error: err })
|
logger.error('Cannot get signed host in body.', { error: err.stack, signature: req.body.signature.signature })
|
||||||
return res.sendStatus(500)
|
return res.sendStatus(500)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue