Add reserved name check

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-04-27 20:39:34 +02:00 committed by Alexandre BODIN
parent 431715138a
commit 42c149e8bc
8 changed files with 97 additions and 24 deletions

View File

@ -0,0 +1,11 @@
'use strict';
// contentTypes and components reserved names
const RESERVED_MODEL_NAMES = ['admin'];
// attribute reserved names
const RESERVED_ATTRIBUTE_NAMES = ['_id', 'id', 'length', 'attributes', 'relations', 'changed'];
module.exports = {
RESERVED_MODEL_NAMES,
RESERVED_ATTRIBUTE_NAMES,
};

View File

@ -4,7 +4,8 @@ const _ = require('lodash');
const requireConnector = require('./require-connector');
const { createQuery } = require('./queries');
const { checkDuplicatedTableNames } = require('./validation/before-mounting-models');
const constants = require('./constants');
const { validateModelSchemas } = require('./validation');
class DatabaseManager {
constructor(strapi) {
@ -32,7 +33,7 @@ class DatabaseManager {
}
}
checkDuplicatedTableNames(this.strapi);
validateModelSchemas(this.strapi);
for (const connectorToInitialize of connectorsToInitialize) {
const connector = requireConnector(connectorToInitialize)(strapi);
@ -135,6 +136,16 @@ class DatabaseManager {
return model.globalId === globalId;
});
}
getRestrictedNames() {
return {
model: constants.RESERVED_MODEL_NAMES,
attributes: [
...constants.RESERVED_ATTRIBUTE_NAMES,
...(strapi.db.getDefaultConnector().defaultTimestamps || []),
],
};
}
}
function createDatabaseManager(strapi) {

View File

@ -1,5 +0,0 @@
const checkDuplicatedTableNames = require('./check-duplicated-table-names');
module.exports = {
checkDuplicatedTableNames,
};

View File

@ -0,0 +1,54 @@
'use strict';
const _ = require('lodash');
const constants = require('../constants');
const checkReservedAttributeNames = model => {
const usedReservedAttributeNames = _.intersection(
Object.keys(model.attributes),
constants.RESERVED_ATTRIBUTE_NAMES
);
if (usedReservedAttributeNames.length > 0) {
throw new Error(
`Model "${
model.modelName
}" is using reserved attribute names "${usedReservedAttributeNames.join(', ')}".`
);
}
};
const checkReservedModelName = model => {
if (constants.RESERVED_MODEL_NAMES.includes(model.modelName)) {
throw new Error(
`"${model.modelName}" is a reserved model name. You need to rename your model and the files associated with it`
);
}
};
/**
* Checks that there are no model using reserved names (content type, component, attributes)
*/
module.exports = strapi => {
Object.keys(strapi.api).forEach(apiName => {
const api = strapi.api[apiName];
const models = api.models ? Object.values(api.models) : [];
models.forEach(model => {
checkReservedModelName(model);
checkReservedAttributeNames(model);
});
});
Object.keys(strapi.plugins).forEach(pluginName => {
const plugin = strapi.plugins[pluginName];
const models = plugin.models ? Object.values(plugin.models) : [];
models.forEach(model => {
checkReservedModelName(model);
checkReservedAttributeNames(model);
});
});
//TODO: check reserved timestamps per connector when model as timestamps enabled
};

View File

@ -0,0 +1,13 @@
'use strict';
const checkDuplicatedTableNames = require('./check-duplicated-table-names');
const checkReservedNames = require('./check-reserved-names');
const validateModelSchemas = strapi => {
checkDuplicatedTableNames(strapi);
checkReservedNames(strapi);
};
module.exports = {
validateModelSchemas,
};

View File

@ -2,8 +2,8 @@
"routes": [
{
"method": "GET",
"path": "/restricted-names",
"handler": "Builder.getRestrictedNames",
"path": "/reserved-names",
"handler": "Builder.getReservedNames",
"config": {
"policies": []
}

View File

@ -1,20 +1,7 @@
'use strict';
module.exports = {
getRestrictedNames(ctx) {
const defaultConnectionTimestamps = strapi.db.getDefaultConnector().defaultTimestamps || [];
ctx.body = {
models: ['admin'], // contentTypes and components
attributes: [
'_id',
'id',
'length',
'attributes',
'relations',
'changed',
...defaultConnectionTimestamps,
],
};
getReservedNames(ctx) {
ctx.body = strapi.db.getRestrictedNames();
},
};