parent
4900aafca9
commit
c6ce54ee87
2
Makefile
2
Makefile
|
@ -53,7 +53,7 @@ migrate: depends
|
|||
@echo ">> waiting a moment to make sure the database comes online.."
|
||||
@sleep 3
|
||||
$(COMPOSE) run --rm node \
|
||||
/usr/local/bin/node $(SEQUELIZE) db:migrate
|
||||
/usr/local/bin/node $(SEQUELIZE) db:migrate && \
|
||||
$(COMPOSE) run --rm node \
|
||||
/usr/local/bin/node $(SEQUELIZE) db:seed:all
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.bulkInsert('grants', [
|
||||
{
|
||||
name: 'rtyler',
|
||||
type: 'jest-example',
|
||||
},
|
||||
]);
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
}
|
||||
};
|
|
@ -29,6 +29,6 @@ export default (app) => {
|
|||
user: (req as any).user,
|
||||
query: req.query,
|
||||
}))
|
||||
.catch(err => res.render('notauthorized'));
|
||||
.catch(next);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ export default (app) => {
|
|||
res.setHeader('Content-Type', 'application/json');
|
||||
res.send(result);
|
||||
res.end();
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import logger from '../logger';
|
||||
|
||||
/**
|
||||
* This hook will apply the grants for the current user to the search query
|
||||
*/
|
||||
export default () => {
|
||||
return async context => {
|
||||
const grantedTypes = context.data.grants.filter(g => g != '*');
|
||||
|
||||
if (grantedTypes) {
|
||||
/*
|
||||
* If there are wildcard grants, we don't need to apply any restrictions
|
||||
* to the query
|
||||
*/
|
||||
if (context.data.grants.length > grantedTypes.length) {
|
||||
return context;
|
||||
}
|
||||
Object.assign(context.params.query, {
|
||||
'type': grantedTypes,
|
||||
});
|
||||
}
|
||||
return context;
|
||||
}
|
||||
};
|
|
@ -17,20 +17,17 @@ export default () => {
|
|||
return context.app.service('grants').find({
|
||||
query: {
|
||||
name: name,
|
||||
$or : [
|
||||
{
|
||||
type: type,
|
||||
},
|
||||
{
|
||||
type: '*',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
.then((records) => {
|
||||
if (records.length === 0) {
|
||||
throw new Forbidden('Not allowed, sorry buddy');
|
||||
}
|
||||
|
||||
if (!context.data) {
|
||||
context.data = {};
|
||||
}
|
||||
context.data.grants = records.map(r => r.type);
|
||||
return context;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
import { Application, HooksObject, Params, SKIP } from '@feathersjs/feathers';
|
||||
import { BadRequest, NotFound } from '@feathersjs/errors';
|
||||
import { QueryTypes } from 'sequelize';
|
||||
|
||||
import authorize from '../hooks/authorize';
|
||||
|
@ -14,16 +15,11 @@ import Event from '../models/event';
|
|||
export const bulkHooks : HooksObject = {
|
||||
before: {
|
||||
all: [
|
||||
authorize(),
|
||||
(context) => {
|
||||
/*
|
||||
* Allow skipping for our tests
|
||||
*/
|
||||
if (process.env.NODE_ENV != 'production') {
|
||||
return SKIP;
|
||||
}
|
||||
context.params.grants = context.data.grants
|
||||
return context;
|
||||
},
|
||||
authorize(),
|
||||
],
|
||||
},
|
||||
after: {},
|
||||
|
@ -42,8 +38,13 @@ export class Bulk {
|
|||
|
||||
public async find(params : Params) : Promise<any> {
|
||||
if (!params.query.type) {
|
||||
return Promise.resolve([]);
|
||||
return Promise.reject(new BadRequest('Request must have a `type` in the URL'));
|
||||
}
|
||||
const grantedTypes = params.grants.filter(g => (g == '*') || (g == params.query.type));
|
||||
if (grantedTypes.length == 0) {
|
||||
return Promise.reject(new NotFound('No data found'));
|
||||
}
|
||||
|
||||
/*
|
||||
* This is clearly stupid. I have no idea how we'll query very large
|
||||
* datasets from PostgreSQL but this at least gets us _everything_
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
|
||||
import { Application, HooksObject } from '@feathersjs/feathers';
|
||||
import service from 'feathers-sequelize';
|
||||
import { DataTypes } from 'sequelize';
|
||||
import { Operators, DataTypes } from 'sequelize';
|
||||
|
||||
import authorize from '../hooks/authorize';
|
||||
import applyGrant from '../hooks/apply-grant';
|
||||
import logger from '../logger';
|
||||
import db from '../models';
|
||||
import Event from '../models/event';
|
||||
|
@ -18,9 +19,11 @@ export const eventsHooks : HooksObject = {
|
|||
],
|
||||
find: [
|
||||
authorize(),
|
||||
applyGrant(),
|
||||
],
|
||||
get: [
|
||||
authorize(),
|
||||
applyGrant(),
|
||||
],
|
||||
create: [
|
||||
/*
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import url from 'url';
|
||||
import request from 'request-promise';
|
||||
|
||||
import app from '../src/app';
|
||||
import { Bulk } from '../src/service/bulk';
|
||||
|
||||
// Offsetting a bit to ensure that we can watch and run at the same time
|
||||
const port = (app.get('port') || 3030) + 10;
|
||||
const getUrl = pathname => url.format({
|
||||
hostname: app.get('host') || 'localhost',
|
||||
protocol: 'http',
|
||||
port,
|
||||
pathname
|
||||
});
|
||||
|
||||
describe('Acceptance tests for /evetns/bulk', () => {
|
||||
beforeEach((done) => {
|
||||
this.server = app.listen(port);
|
||||
this.server.once('listening', () => done());
|
||||
});
|
||||
afterEach(done => this.server.close(done));
|
||||
|
||||
describe('GET on /events/bulk', () => {
|
||||
it('without a type parameter should be empty', () => {
|
||||
return request(getUrl('/events/bulk'), {
|
||||
json: true,
|
||||
resolveWithFullResponse: true,
|
||||
}).then((response) => {
|
||||
expect(response.statusCode).toEqual(200);
|
||||
expect(response.body).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue