Add: permissions

It's now possible to limit the models rest routes are created for. This
is done via a `models` option that can be simple to complex. The readme
has been updated to reflect this.
This commit is contained in:
Joey Baker 2016-07-21 17:39:35 -07:00
parent 6c46ff68d0
commit a64a55af0d
2 changed files with 100 additions and 32 deletions

View File

@ -29,11 +29,33 @@ await register({
options: {
prefix: '/v1',
name: 'db', // the same name you used for configuring `hapi-sequelize` (options.name)
defaultConfig: { ... } // passed as `config` to all routes created
defaultConfig: { ... }, // passed as `config` to all routes created
models: ['cat', 'dog'] // only the cat and dog models will have routes created
// or
models: {
// possible methods: list, get, scope, create, destroy, destroyAll, destroyScope, update
cat: ['get', 'list'], // the cat model only has get and list methods enabled
dog: true, // the dog model has all methods enabled
bat: {
methods: ['list'],
config: { ... } // if provided, overrides the default config
}
}
}
});
```
### Methods
* list: get all rows in a table
* get: get a single row
* scope: reference a [sequelize scope](http://docs.sequelizejs.com/en/latest/api/model/#scopeoptions-model)
* create: create a new row
* destroy: delete a row
* destroyAll: delete all models in the table
* destroyScope: use a [sequelize scope](http://docs.sequelizejs.com/en/latest/api/model/#scopeoptions-model) to find rows, then delete them
* update: update a row
Please note that you should register `hapi-sequelize-crud` after defining your
associations.

View File

@ -4,24 +4,66 @@ import _ from 'lodash';
import { parseInclude, parseWhere } from './utils';
import { notFound } from 'boom';
let prefix;
let defaultConfig;
export default (server, model, options) => {
prefix = options.prefix;
defaultConfig = options.defaultConfig;
list(server, model);
get(server, model);
scope(server, model);
create(server, model);
destroy(server, model);
destroyAll(server, model);
destroyScope(server, model);
update(server, model);
const createAll = ({server, model, prefix, config}) => {
Object.keys(methods).forEach((method) => {
methods[method]({server, model, prefix, config});
});
};
export const list = (server, model) => {
/*
The `models` option, becomes `permissions`, and can look like:
```
models: ['cat', 'dog']
```
or
```
models: {
cat: ['list', 'get']
, dog: true // all
}
```
*/
export default (server, model, {prefix, defaultConfig: config, models: permissions}) => {
const modelName = model._singular;
if (!permissions) {
createAll({server, model, prefix, config});
}
else if (Array.isArray(permissions) && permissions.includes(modelName)) {
createAll({server, model, prefix, config});
}
else if (_.isPlainObject(permissions)) {
const permittedModels = Object.keys(permissions);
if (permissions[modelName] === true) {
createAll({server, model, prefix, config});
}
else if (permittedModels.includes(modelName)) {
if (Array.isArray(permissions[modelName])) {
permissions[modelName].forEach((method) => {
methods[method]({server, model, prefix, config});
});
}
else if (_.isPlainObject(permissions[modelName])) {
permissions[modelName].methods.forEach((method) => {
methods[method]({
server,
model,
prefix,
config: permissions[modelName].config || config,
});
});
}
}
}
};
export const list = ({server, model, prefix, config}) => {
server.route({
method: 'GET',
path: `${prefix}/${model._plural}`,
@ -40,11 +82,11 @@ export const list = (server, model) => {
reply(list);
},
config: defaultConfig,
config,
});
};
export const get = (server, model) => {
export const get = ({server, model, prefix, config}) => {
server.route({
method: 'GET',
path: `${prefix}/${model._singular}/{id?}`,
@ -68,11 +110,11 @@ export const get = (server, model) => {
id: joi.any(),
}),
},
}, defaultConfig),
}, config),
});
};
export const scope = (server, model) => {
export const scope = ({server, model, prefix, config}) => {
const scopes = Object.keys(model.options.scopes);
server.route({
@ -94,11 +136,11 @@ export const scope = (server, model) => {
scope: joi.string().valid(...scopes),
}),
},
}, defaultConfig),
}, config),
});
};
export const create = (server, model) => {
export const create = ({server, model, prefix, config}) => {
server.route({
method: 'POST',
path: `${prefix}/${model._singular}`,
@ -110,11 +152,11 @@ export const create = (server, model) => {
reply(instance);
},
config: defaultConfig,
config,
});
};
export const destroy = (server, model) => {
export const destroy = ({server, model, prefix, config}) => {
server.route({
method: 'DELETE',
path: `${prefix}/${model._singular}/{id?}`,
@ -131,11 +173,11 @@ export const destroy = (server, model) => {
reply(list.length === 1 ? list[0] : list);
},
config: defaultConfig,
config,
});
};
export const destroyAll = (server, model) => {
export const destroyAll = ({server, model, prefix, config}) => {
server.route({
method: 'DELETE',
path: `${prefix}/${model._plural}`,
@ -151,11 +193,11 @@ export const destroyAll = (server, model) => {
reply(list.length === 1 ? list[0] : list);
},
config: defaultConfig,
config,
});
};
export const destroyScope = (server, model) => {
export const destroyScope = ({server, model, prefix, config}) => {
const scopes = Object.keys(model.options.scopes);
server.route({
@ -179,11 +221,11 @@ export const destroyScope = (server, model) => {
scope: joi.string().valid(...scopes),
}),
},
}, defaultConfig),
}, config),
});
};
export const update = (server, model) => {
export const update = ({server, model, prefix, config}) => {
server.route({
method: 'PUT',
path: `${prefix}/${model._singular}/{id}`,
@ -208,9 +250,13 @@ export const update = (server, model) => {
validate: {
payload: joi.object().required(),
},
}, defaultConfig),
}, config),
});
};
import * as associations from './associations/index';
export { associations };
const methods = {
list, get, scope, create, destroy, destroyAll, destroyScope, update,
};