Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load schemas from database #566

Merged
merged 8 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
workspace/
20 changes: 13 additions & 7 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const convict = require('convict')
const fs = require('fs')

const conf = convict({
app: {
Expand Down Expand Up @@ -474,6 +473,18 @@ const conf = convict({
format: Number,
default: 200
}
},
schemas: {
collection: {
doc: 'The name of the internal collection to store collection schemas',
format: String,
default: 'schemas'
},
loadSeeds: {
doc: 'Whether to scan the workspace directory for collection seed files',
format: Boolean,
default: true
}
}
})

Expand All @@ -487,14 +498,9 @@ conf.updateConfigDataForDomain = function(domain) {
const domainConfig = './config/' + domain + '.json'

try {
const stats = fs.statSync(domainConfig)

// no error, file exists
conf.loadFile(domainConfig)
} catch (err) {
if (err.code === 'ENOENT') {
// console.log('No domain-specific configuration file: ' + domainConfig)
} else {
if (err.code !== 'ENOENT') {
console.log(err)
}
}
Expand Down
3 changes: 3 additions & 0 deletions config/config.test.json.sample
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,8 @@
"workQueue": {
"debounceTime": 0,
"pollingTime": 0
},
"schemas": {
"loadSeeds": false
}
}
54 changes: 37 additions & 17 deletions dadi/lib/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const log = require('@dadi/logger')
const config = require(path.join(__dirname, '/../../../config'))

const Api = function() {
this.paths = {}
this.paths = []
this.all = []
this.errors = []

Expand Down Expand Up @@ -95,12 +95,32 @@ Api.prototype.use = function(path, handler) {
}

const regex = pathToRegexp(path)

this.paths[path] = {
const order = routePriority(path, regex.keys)
const newPath = {
handler,
order: routePriority(path, regex.keys),
order,
path,
regex
}
const existingIndex = this.paths.findIndex(item => item.path === path)

if (existingIndex !== -1) {
this.paths[existingIndex] = newPath
} else {
this.paths.push(newPath)
}

this.paths = this.paths.sort((a, b) => {
if (a.order < b.order) {
return 1
}

if (a.order > b.order) {
return -1
}

return 0
})
}

/**
Expand Down Expand Up @@ -145,7 +165,11 @@ Api.prototype.unuse = function(path) {
return Boolean(~indx) && this.all.splice(indx, 1)
}

delete this.paths[path]
const pathIndex = this.paths.findIndex(item => item.path === path)

if (pathIndex !== -1) {
this.paths.splice(pathIndex, 1)
}
}

/**
Expand Down Expand Up @@ -265,20 +289,19 @@ Api.prototype.redirectListener = function(req, res) {
* @api private
*/
Api.prototype._match = function(path, req) {
const paths = this.paths
const handlers = []

// always add params object to avoid need for checking later
req.params = {}

Object.keys(paths).forEach(key => {
const match = paths[key].regex.exec(path)
this.paths.forEach(registeredPath => {
const match = registeredPath.regex.exec(path)

if (!match) return

const keys = paths[key].regex.keys
const keys = registeredPath.regex.keys

handlers.push(paths[key].handler)
handlers.push(registeredPath.handler)

match.forEach((k, i) => {
const keyOpts = keys[i] || {}
Expand Down Expand Up @@ -327,13 +350,10 @@ function notFound(req, res) {

function routePriority(path, keys) {
const tokens = pathToRegexp.parse(path)

let staticRouteLength = 0

if (typeof tokens[0] === 'string') {
staticRouteLength = tokens[0].split('/').filter(Boolean).length
}

const staticRouteLength =
typeof tokens[0] === 'string'
? tokens[0].split('/').filter(Boolean).length
: 0
const requiredParamLength = keys.filter(key => !key.optional).length
const optionalParamLength = keys.filter(key => key.optional).length

Expand Down
16 changes: 2 additions & 14 deletions dadi/lib/cache/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,9 @@ module.exports = function(server) {
}

Cache.prototype.cachingEnabled = function(req) {
let options = {}
const endpoints = this.server.components
const requestPath = url.parse(req.url, true).pathname

const endpointKey = Object.keys(endpoints).find(key =>
pathToRegexp(key).exec(requestPath)
return Boolean(
this.enabled && req.collectionModel && req.collectionModel.isCacheable()
)

if (!endpointKey) return false

if (endpoints[endpointKey].model && endpoints[endpointKey].model.settings) {
options = endpoints[endpointKey].model.settings
}

return this.enabled && (options.cache || false)
}

Cache.prototype.getEndpointContentType = function(req) {
Expand Down
76 changes: 37 additions & 39 deletions dadi/lib/controller/clients.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ Clients.prototype.post = function(req, res, next) {
.catch(this.handleError(res, next))
}

Clients.prototype.postResource = function(req, res, next) {
Clients.prototype.postResource = async function(req, res, next) {
if (
typeof req.body.name !== 'string' ||
typeof req.body.access !== 'object'
Expand All @@ -295,48 +295,46 @@ Clients.prototype.postResource = function(req, res, next) {
})
}

if (!acl.hasResource(req.body.name)) {
return help.sendBackJSON(400, res, next)(null, {
success: false,
errors: [`Invalid resource: ${req.body.name}`]
})
}
try {
// To add a resource to a client, the requesting client needs to have
// "update" access to the "clients" resource, as well as access to the
// resource in question.
const access = await acl.access.get(req.dadiApiClient, 'clients')

// To add a resource to a client, the requesting client needs to have
// "update" access to the "clients" resource, as well as access to the
// resource in question.
return acl.access
.get(req.dadiApiClient, 'clients')
.then(access => {
if (access.update !== true) {
return Promise.reject(acl.createError(req.dadiApiClient))
}
if (access.update !== true) {
throw acl.createError(req.dadiApiClient)
}

// If the client does not have admin access, we need to ensure that
// they have each of the access types they are trying to assign.
if (!model.isAdmin(req.dadiApiClient)) {
return acl.access.get(req.dadiApiClient, req.body.name).then(access => {
const forbiddenType = Object.keys(req.body.access).find(type => {
return access[type] !== true
})
// If the client does not have admin access, we need to ensure that
// they have each of the access types they are trying to assign.
if (!model.isAdmin(req.dadiApiClient)) {
const access = await acl.access.get(req.dadiApiClient, req.body.name)
const forbiddenType = Object.keys(req.body.access).find(type => {
return access[type] !== true
})

if (forbiddenType) {
return Promise.reject(acl.createError(req.dadiApiClient))
}
})
if (forbiddenType) {
throw acl.createError(req.dadiApiClient)
}
})
.then(() => {
return model.resourceAdd(
req.params.clientId,
req.body.name,
req.body.access
)
})
.then(({results}) => {
help.sendBackJSON(201, res, next)(null, {results})
})
.catch(this.handleError(res, next))
}

if (!acl.hasResource(req.body.name)) {
return help.sendBackJSON(400, res, next)(null, {
success: false,
errors: [`Invalid resource: ${req.body.name}`]
})
}

const {results} = await model.resourceAdd(
req.params.clientId,
req.body.name,
req.body.access
)

help.sendBackJSON(201, res, next)(null, {results})
} catch (error) {
this.handleError(res, next)(error)
}
}

Clients.prototype.postRole = function(req, res, next) {
Expand Down
Loading