Bläddra i källkod

Merge pull request #29968 from overleaf/acf-migration3-express-routes

(3) Create Express routes (replaces swagger-router)

GitOrigin-RevId: e27973b630509312b198be899148310e69b94777
Anna Claire Fields 8 månader sedan
förälder
incheckning
56c98ac99c

+ 50 - 44
services/history-v1/api/middleware/security.js

@@ -11,8 +11,6 @@ const schemas = require('../schema')
 function hasValidBasicAuthCredentials(req) {
 function hasValidBasicAuthCredentials(req) {
   const credentials = basicAuth(req)
   const credentials = basicAuth(req)
   if (!credentials) return false
   if (!credentials) return false
-
-  // No security in the name, so just use straight comparison.
   if (credentials.name !== 'staging') return false
   if (credentials.name !== 'staging') return false
 
 
   const password = config.get('basicHttpAuth.password')
   const password = config.get('basicHttpAuth.password')
@@ -50,53 +48,58 @@ function setupSSL(app) {
 
 
 exports.setupSSL = setupSSL
 exports.setupSSL = setupSSL
 
 
-function handleJWTAuth(req, res, next) {
-  if (hasValidBasicAuthCredentials(req)) {
-    return next()
-  }
-
-  let token
-  if (req.query.token) {
-    token = req.query.token
-  } else if (
-    req.headers.authorization &&
-    req.headers.authorization.split(' ')[0] === 'Bearer'
-  ) {
-    token = req.headers.authorization.split(' ')[1]
-  }
-
-  if (!token) {
-    const err = new Error('jwt missing')
-    err.statusCode = HTTPStatus.UNAUTHORIZED
-    err.headers = { 'WWW-Authenticate': 'Bearer' }
-    return next(err)
-  }
+function configureJWTAuth(mode = 'jwt') {
+  return function handleJWTAuth(req, res, next) {
+    if (hasValidBasicAuthCredentials(req)) {
+      return next()
+    }
 
 
-  let decoded
-  try {
-    decoded = decodeJWT(token)
-  } catch (error) {
-    if (
-      error instanceof jwt.JsonWebTokenError ||
-      error instanceof jwt.TokenExpiredError
+    let token
+    if ((mode === 'either' || mode === 'token') && req.query.token) {
+      token = req.query.token
+    } else if (
+      (mode === 'either' || mode === 'jwt') &&
+      req.headers.authorization &&
+      req.headers.authorization.split(' ')[0] === 'Bearer'
     ) {
     ) {
-      const err = new Error(error.message)
+      token = req.headers.authorization.split(' ')[1]
+    }
+
+    if (!token) {
+      const err = new Error('jwt missing')
       err.statusCode = HTTPStatus.UNAUTHORIZED
       err.statusCode = HTTPStatus.UNAUTHORIZED
-      err.headers = { 'WWW-Authenticate': 'Bearer error="invalid_token"' }
+      err.headers = { 'WWW-Authenticate': 'Bearer' }
       return next(err)
       return next(err)
     }
     }
-    throw error
-  }
 
 
-  const { params } = validateReq(req, schemas.projectId)
-  if (decoded.project_id.toString() !== params.project_id.toString()) {
-    const err = new Error('Wrong project_id')
-    err.statusCode = HTTPStatus.FORBIDDEN
-    return next(err)
-  }
+    let decoded
+    try {
+      decoded = decodeJWT(token)
+    } catch (error) {
+      if (
+        error instanceof jwt.JsonWebTokenError ||
+        error instanceof jwt.TokenExpiredError
+      ) {
+        const err = new Error(error.message)
+        err.statusCode = HTTPStatus.UNAUTHORIZED
+        err.headers = {
+          'WWW-Authenticate': 'Bearer error="invalid_token"',
+        }
+        return next(err)
+      }
+      throw error
+    }
 
 
-  req.jwt = decoded
-  next()
+    const { params } = validateReq(req, schemas.projectId)
+    if (decoded.project_id.toString() !== params.project_id.toString()) {
+      const err = new Error('Wrong project_id')
+      err.statusCode = HTTPStatus.FORBIDDEN
+      return next(err)
+    }
+
+    req.jwt = decoded
+    next()
+  }
 }
 }
 
 
 /**
 /**
@@ -134,11 +137,14 @@ function getAuthHandlers() {
   }
   }
 
 
   const handlers = {}
   const handlers = {}
-  handlers.jwt = handleJWTAuth
+  handlers.jwt = configureJWTAuth('jwt')
+  handlers.token = configureJWTAuth('token')
+  handlers.either = configureJWTAuth('either')
   handlers.basic = handleBasicAuth
   handlers.basic = handleBasicAuth
-  handlers.token = handleJWTAuth
   return handlers
   return handlers
 }
 }
 
 
 exports.hasValidBasicAuthCredentials = hasValidBasicAuthCredentials
 exports.hasValidBasicAuthCredentials = hasValidBasicAuthCredentials
+exports.configureJWTAuth = configureJWTAuth
+exports.handleBasicAuth = handleBasicAuth
 exports.getAuthHandlers = getAuthHandlers
 exports.getAuthHandlers = getAuthHandlers

+ 46 - 0
services/history-v1/api/routes/project_import.js

@@ -0,0 +1,46 @@
+'use strict'
+
+const express = require('express')
+const router = express.Router()
+const { getAuthHandlers } = require('../middleware/security')
+const projectImportController = require('../controllers/project_import')
+
+const { basic: handleBasicAuth } = getAuthHandlers()
+
+router.post(
+  '/projects/:project_id/import',
+  handleBasicAuth,
+  projectImportController.importSnapshot
+)
+
+router.post(
+  '/projects/:project_id/legacy_import',
+  handleBasicAuth,
+  projectImportController.importSnapshot
+)
+
+router.post(
+  '/projects/:project_id/changes',
+  handleBasicAuth,
+  projectImportController.importChanges
+)
+
+router.post(
+  '/projects/:project_id/legacy_changes',
+  handleBasicAuth,
+  projectImportController.importChanges
+)
+
+router.post(
+  '/projects/:project_id/flush',
+  handleBasicAuth,
+  projectImportController.flushChanges
+)
+
+router.post(
+  '/projects/:project_id/expire',
+  handleBasicAuth,
+  projectImportController.expireProject
+)
+
+module.exports = router

+ 119 - 0
services/history-v1/api/routes/projects.js

@@ -0,0 +1,119 @@
+'use strict'
+
+const express = require('express')
+const router = express.Router()
+const { getAuthHandlers } = require('../middleware/security')
+const projectsController = require('../controllers/projects')
+
+const {
+  basic: handleBasicAuth,
+  jwt: handleJWTAuth,
+  token: handleTokenAuth,
+  either: handleJWTOrTokenAuth,
+} = getAuthHandlers()
+
+router.post('/projects', handleBasicAuth, projectsController.initializeProject)
+
+router.post(
+  '/projects/blob-stats',
+  handleBasicAuth,
+  projectsController.getProjectBlobsStats
+)
+
+router.post(
+  '/projects/:project_id/blob-stats',
+  handleBasicAuth,
+  projectsController.getBlobStats
+)
+
+router.delete(
+  '/projects/:project_id',
+  handleBasicAuth,
+  projectsController.deleteProject
+)
+
+router.get(
+  '/projects/:project_id/blobs/:hash',
+  handleJWTOrTokenAuth,
+  projectsController.getProjectBlob
+)
+
+router.put(
+  '/projects/:project_id/blobs/:hash',
+  handleJWTAuth,
+  projectsController.createProjectBlob
+)
+
+router.post(
+  '/projects/:project_id/blobs/:hash',
+  handleJWTAuth,
+  projectsController.copyProjectBlob
+)
+
+router.get(
+  '/projects/:project_id/latest/content',
+  handleJWTAuth,
+  projectsController.getLatestContent
+)
+
+router.get(
+  '/projects/:project_id/latest/hashed_content',
+  handleBasicAuth,
+  projectsController.getLatestHashedContent
+)
+
+router.get(
+  '/projects/:project_id/latest/history',
+  handleJWTAuth,
+  projectsController.getLatestHistory
+)
+
+router.get(
+  '/projects/:project_id/latest/history/raw',
+  handleJWTAuth,
+  projectsController.getLatestHistoryRaw
+)
+
+router.get(
+  '/projects/:project_id/latest/persistedHistory',
+  handleJWTAuth,
+  projectsController.getLatestPersistedHistory
+)
+
+router.get(
+  '/projects/:project_id/versions/:version/history',
+  handleJWTAuth,
+  projectsController.getHistory
+)
+
+router.get(
+  '/projects/:project_id/versions/:version/content',
+  handleJWTAuth,
+  projectsController.getContentAtVersion
+)
+
+router.get(
+  '/projects/:project_id/timestamp/:timestamp/history',
+  handleJWTAuth,
+  projectsController.getHistoryBefore
+)
+
+router.get(
+  '/projects/:project_id/version/:version/zip',
+  handleTokenAuth,
+  projectsController.getZip
+)
+
+router.post(
+  '/projects/:project_id/version/:version/zip',
+  handleBasicAuth,
+  projectsController.createZip
+)
+
+router.get(
+  '/projects/:project_id/changes',
+  handleBasicAuth,
+  projectsController.getChanges
+)
+
+module.exports = router