mirror of
https://github.com/strapi/strapi.git
synced 2025-07-23 17:10:08 +00:00
Hotfix mongo aggregate policy verifications
This commit is contained in:
parent
f36a5cf096
commit
7a3b64016c
@ -7,6 +7,8 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const pluralize = require('pluralize');
|
const pluralize = require('pluralize');
|
||||||
const { convertRestQueryParams, buildQuery } = require('strapi-utils');
|
const { convertRestQueryParams, buildQuery } = require('strapi-utils');
|
||||||
|
const policyUtils = require('strapi-utils').policy;
|
||||||
|
const compose = require('koa-compose');
|
||||||
|
|
||||||
const Schema = require('./Schema.js');
|
const Schema = require('./Schema.js');
|
||||||
const GraphQLQuery = require('./Query.js');
|
const GraphQLQuery = require('./Query.js');
|
||||||
@ -470,7 +472,13 @@ const formatConnectionAggregator = function(fields, model, modelName) {
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const formatModelConnectionsGQL = function(fields, model, name, modelResolver) {
|
const formatModelConnectionsGQL = function(
|
||||||
|
fields,
|
||||||
|
model,
|
||||||
|
name,
|
||||||
|
modelResolver,
|
||||||
|
plugin
|
||||||
|
) {
|
||||||
const { globalId } = model;
|
const { globalId } = model;
|
||||||
|
|
||||||
const connectionGlobalId = `${globalId}Connection`;
|
const connectionGlobalId = `${globalId}Connection`;
|
||||||
@ -501,7 +509,50 @@ const formatModelConnectionsGQL = function(fields, model, name, modelResolver) {
|
|||||||
},
|
},
|
||||||
resolver: {
|
resolver: {
|
||||||
Query: {
|
Query: {
|
||||||
[`${pluralName}Connection`](obj, options, context) {
|
async [`${pluralName}Connection`](obj, options, { context }) {
|
||||||
|
// need to check
|
||||||
|
|
||||||
|
const ctx = Object.assign(_.clone(context), {
|
||||||
|
request: Object.assign(_.clone(context.request), {
|
||||||
|
graphql: null,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const policiesFn = [
|
||||||
|
policyUtils.globalPolicy(
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
handler: `${name}.find`,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
plugin
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
policyUtils.get(
|
||||||
|
'plugins.users-permissions.permissions',
|
||||||
|
plugin,
|
||||||
|
policiesFn,
|
||||||
|
`GraphQL connection "${name}" `,
|
||||||
|
name
|
||||||
|
);
|
||||||
|
|
||||||
|
// Execute policies stack.
|
||||||
|
const policy = await compose(policiesFn)(ctx);
|
||||||
|
|
||||||
|
// Policy doesn't always return errors but they update the current context.
|
||||||
|
if (
|
||||||
|
_.isError(ctx.request.graphql) ||
|
||||||
|
_.get(ctx.request.graphql, 'isBoom')
|
||||||
|
) {
|
||||||
|
return ctx.request.graphql;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Something went wrong in the policy.
|
||||||
|
if (policy) {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -60,152 +60,161 @@ const buildAssocResolvers = (model, name, { plugin }) => {
|
|||||||
const { primaryKey, associations = [] } = model;
|
const { primaryKey, associations = [] } = model;
|
||||||
|
|
||||||
return associations
|
return associations
|
||||||
.filter(association => model.attributes[association.alias].private !== true)
|
.filter(association => model.attributes[association.alias].private !== true)
|
||||||
.reduce((resolver, association) => {
|
.reduce((resolver, association) => {
|
||||||
switch (association.nature) {
|
switch (association.nature) {
|
||||||
case 'oneToManyMorph': {
|
case 'oneToManyMorph': {
|
||||||
resolver[association.alias] = async obj => {
|
resolver[association.alias] = async obj => {
|
||||||
const entry = await contentManager.fetch(
|
const entry = await contentManager.fetch(
|
||||||
{
|
|
||||||
id: obj[primaryKey],
|
|
||||||
model: name,
|
|
||||||
},
|
|
||||||
plugin,
|
|
||||||
[association.alias]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set the _type only when the value is defined
|
|
||||||
if (entry[association.alias]) {
|
|
||||||
entry[association.alias]._type = _.upperFirst(association.model);
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry[association.alias];
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'manyMorphToOne':
|
|
||||||
case 'manyMorphToMany':
|
|
||||||
case 'manyToManyMorph': {
|
|
||||||
resolver[association.alias] = async obj => {
|
|
||||||
// eslint-disable-line no-unused-vars
|
|
||||||
const [withRelated, withoutRelated] = await Promise.all([
|
|
||||||
contentManager.fetch(
|
|
||||||
{
|
{
|
||||||
id: obj[primaryKey],
|
id: obj[primaryKey],
|
||||||
model: name,
|
model: name,
|
||||||
},
|
},
|
||||||
plugin,
|
plugin,
|
||||||
[association.alias],
|
[association.alias]
|
||||||
false
|
|
||||||
),
|
|
||||||
contentManager.fetch(
|
|
||||||
{
|
|
||||||
id: obj[primaryKey],
|
|
||||||
model: name,
|
|
||||||
},
|
|
||||||
plugin,
|
|
||||||
[]
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const entry =
|
|
||||||
withRelated && withRelated.toJSON
|
|
||||||
? withRelated.toJSON()
|
|
||||||
: withRelated;
|
|
||||||
|
|
||||||
entry[association.alias].map((entry, index) => {
|
|
||||||
const type =
|
|
||||||
_.get(withoutRelated, `${association.alias}.${index}.kind`) ||
|
|
||||||
_.upperFirst(
|
|
||||||
_.camelCase(
|
|
||||||
_.get(
|
|
||||||
withoutRelated,
|
|
||||||
`${association.alias}.${index}.${association.alias}_type`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) ||
|
|
||||||
_.upperFirst(_.camelCase(association[association.type]));
|
|
||||||
|
|
||||||
entry._type = type;
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
});
|
|
||||||
|
|
||||||
return entry[association.alias];
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
resolver[association.alias] = async (obj, options) => {
|
|
||||||
// Construct parameters object to retrieve the correct related entries.
|
|
||||||
const params = {
|
|
||||||
model: association.model || association.collection,
|
|
||||||
};
|
|
||||||
|
|
||||||
let queryOpts = {
|
|
||||||
source: association.plugin,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get refering model.
|
|
||||||
const ref = association.plugin
|
|
||||||
? strapi.plugins[association.plugin].models[params.model]
|
|
||||||
: strapi.models[params.model];
|
|
||||||
|
|
||||||
if (association.type === 'model') {
|
|
||||||
params[ref.primaryKey] = _.get(
|
|
||||||
obj,
|
|
||||||
[association.alias, ref.primaryKey],
|
|
||||||
obj[association.alias]
|
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
const queryParams = Query.amountLimiting(options);
|
// Set the _type only when the value is defined
|
||||||
queryOpts = {
|
if (entry[association.alias]) {
|
||||||
...queryOpts,
|
entry[association.alias]._type = _.upperFirst(association.model);
|
||||||
...Query.convertToParams(_.omit(queryParams, 'where')), // Convert filters (sort, limit and start/skip)
|
}
|
||||||
...Query.convertToQuery(queryParams.where),
|
|
||||||
|
return entry[association.alias];
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'manyMorphToOne':
|
||||||
|
case 'manyMorphToMany':
|
||||||
|
case 'manyToManyMorph': {
|
||||||
|
resolver[association.alias] = async obj => {
|
||||||
|
// eslint-disable-line no-unused-vars
|
||||||
|
const [withRelated, withoutRelated] = await Promise.all([
|
||||||
|
contentManager.fetch(
|
||||||
|
{
|
||||||
|
id: obj[primaryKey],
|
||||||
|
model: name,
|
||||||
|
},
|
||||||
|
plugin,
|
||||||
|
[association.alias],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
contentManager.fetch(
|
||||||
|
{
|
||||||
|
id: obj[primaryKey],
|
||||||
|
model: name,
|
||||||
|
},
|
||||||
|
plugin,
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const entry =
|
||||||
|
withRelated && withRelated.toJSON
|
||||||
|
? withRelated.toJSON()
|
||||||
|
: withRelated;
|
||||||
|
|
||||||
|
entry[association.alias].map((entry, index) => {
|
||||||
|
const type =
|
||||||
|
_.get(withoutRelated, `${association.alias}.${index}.kind`) ||
|
||||||
|
_.upperFirst(
|
||||||
|
_.camelCase(
|
||||||
|
_.get(
|
||||||
|
withoutRelated,
|
||||||
|
`${association.alias}.${index}.${association.alias}_type`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ||
|
||||||
|
_.upperFirst(_.camelCase(association[association.type]));
|
||||||
|
|
||||||
|
entry._type = type;
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
});
|
||||||
|
|
||||||
|
return entry[association.alias];
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
resolver[association.alias] = async (obj, options) => {
|
||||||
|
// Construct parameters object to retrieve the correct related entries.
|
||||||
|
const params = {
|
||||||
|
model: association.model || association.collection,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
let queryOpts = {
|
||||||
((association.nature === 'manyToMany' && association.dominant) ||
|
source: association.plugin,
|
||||||
association.nature === 'manyWay') &&
|
};
|
||||||
_.has(obj, association.alias) // if populated
|
|
||||||
) {
|
// Get refering model.
|
||||||
_.set(
|
const ref = association.plugin
|
||||||
queryOpts,
|
? strapi.plugins[association.plugin].models[params.model]
|
||||||
['query', ref.primaryKey],
|
: strapi.models[params.model];
|
||||||
|
|
||||||
|
if (association.type === 'model') {
|
||||||
|
params[ref.primaryKey] = _.get(
|
||||||
|
obj,
|
||||||
|
[association.alias, ref.primaryKey],
|
||||||
obj[association.alias]
|
obj[association.alias]
|
||||||
? obj[association.alias]
|
|
||||||
.map(val => val[ref.primaryKey] || val)
|
|
||||||
.sort()
|
|
||||||
: []
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
_.set(queryOpts, ['query', association.via], obj[ref.primaryKey]);
|
const queryParams = Query.amountLimiting(options);
|
||||||
|
queryOpts = {
|
||||||
|
...queryOpts,
|
||||||
|
...Query.convertToParams(_.omit(queryParams, 'where')), // Convert filters (sort, limit and start/skip)
|
||||||
|
...Query.convertToQuery(queryParams.where),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
((association.nature === 'manyToMany' &&
|
||||||
|
association.dominant) ||
|
||||||
|
association.nature === 'manyWay') &&
|
||||||
|
_.has(obj, association.alias) // if populated
|
||||||
|
) {
|
||||||
|
_.set(
|
||||||
|
queryOpts,
|
||||||
|
['query', ref.primaryKey],
|
||||||
|
obj[association.alias]
|
||||||
|
? obj[association.alias]
|
||||||
|
.map(val => val[ref.primaryKey] || val)
|
||||||
|
.sort()
|
||||||
|
: []
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_.set(
|
||||||
|
queryOpts,
|
||||||
|
['query', association.via],
|
||||||
|
obj[ref.primaryKey]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const loaderName = association.plugin
|
const loaderName = association.plugin
|
||||||
? `${association.plugin}__${params.model}`
|
? `${association.plugin}__${params.model}`
|
||||||
: params.model;
|
: params.model;
|
||||||
|
|
||||||
return association.model
|
return association.model
|
||||||
? strapi.plugins.graphql.services.loaders.loaders[loaderName].load({
|
? strapi.plugins.graphql.services.loaders.loaders[
|
||||||
params,
|
loaderName
|
||||||
options: queryOpts,
|
].load({
|
||||||
single: true,
|
params,
|
||||||
})
|
options: queryOpts,
|
||||||
: strapi.plugins.graphql.services.loaders.loaders[loaderName].load({
|
single: true,
|
||||||
options: queryOpts,
|
})
|
||||||
association,
|
: strapi.plugins.graphql.services.loaders.loaders[
|
||||||
});
|
loaderName
|
||||||
};
|
].load({
|
||||||
break;
|
options: queryOpts,
|
||||||
|
association,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return resolver;
|
return resolver;
|
||||||
}, {});
|
}, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildModel = (model, name, { plugin, isGroup = false } = {}) => {
|
const buildModel = (model, name, { plugin, isGroup = false } = {}) => {
|
||||||
@ -475,7 +484,8 @@ const buildShadowCRUD = (models, plugin) => {
|
|||||||
attributes,
|
attributes,
|
||||||
model,
|
model,
|
||||||
name,
|
name,
|
||||||
queries.plural
|
queries.plural,
|
||||||
|
plugin
|
||||||
);
|
);
|
||||||
if (modelAggregator) {
|
if (modelAggregator) {
|
||||||
acc.definition += modelAggregator.type;
|
acc.definition += modelAggregator.type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user