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.."
|
@echo ">> waiting a moment to make sure the database comes online.."
|
||||||
@sleep 3
|
@sleep 3
|
||||||
$(COMPOSE) run --rm node \
|
$(COMPOSE) run --rm node \
|
||||||
/usr/local/bin/node $(SEQUELIZE) db:migrate
|
/usr/local/bin/node $(SEQUELIZE) db:migrate && \
|
||||||
$(COMPOSE) run --rm node \
|
$(COMPOSE) run --rm node \
|
||||||
/usr/local/bin/node $(SEQUELIZE) db:seed:all
|
/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,
|
user: (req as any).user,
|
||||||
query: req.query,
|
query: req.query,
|
||||||
}))
|
}))
|
||||||
.catch(err => res.render('notauthorized'));
|
.catch(next);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ export default (app) => {
|
||||||
res.setHeader('Content-Type', 'application/json');
|
res.setHeader('Content-Type', 'application/json');
|
||||||
res.send(result);
|
res.send(result);
|
||||||
res.end();
|
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({
|
return context.app.service('grants').find({
|
||||||
query: {
|
query: {
|
||||||
name: name,
|
name: name,
|
||||||
$or : [
|
|
||||||
{
|
|
||||||
type: type,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: '*',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((records) => {
|
.then((records) => {
|
||||||
if (records.length === 0) {
|
if (records.length === 0) {
|
||||||
throw new Forbidden('Not allowed, sorry buddy');
|
throw new Forbidden('Not allowed, sorry buddy');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!context.data) {
|
||||||
|
context.data = {};
|
||||||
|
}
|
||||||
|
context.data.grants = records.map(r => r.type);
|
||||||
return context;
|
return context;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Application, HooksObject, Params, SKIP } from '@feathersjs/feathers';
|
import { Application, HooksObject, Params, SKIP } from '@feathersjs/feathers';
|
||||||
|
import { BadRequest, NotFound } from '@feathersjs/errors';
|
||||||
import { QueryTypes } from 'sequelize';
|
import { QueryTypes } from 'sequelize';
|
||||||
|
|
||||||
import authorize from '../hooks/authorize';
|
import authorize from '../hooks/authorize';
|
||||||
|
@ -14,16 +15,11 @@ import Event from '../models/event';
|
||||||
export const bulkHooks : HooksObject = {
|
export const bulkHooks : HooksObject = {
|
||||||
before: {
|
before: {
|
||||||
all: [
|
all: [
|
||||||
|
authorize(),
|
||||||
(context) => {
|
(context) => {
|
||||||
/*
|
context.params.grants = context.data.grants
|
||||||
* Allow skipping for our tests
|
|
||||||
*/
|
|
||||||
if (process.env.NODE_ENV != 'production') {
|
|
||||||
return SKIP;
|
|
||||||
}
|
|
||||||
return context;
|
return context;
|
||||||
},
|
},
|
||||||
authorize(),
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
after: {},
|
after: {},
|
||||||
|
@ -42,8 +38,13 @@ export class Bulk {
|
||||||
|
|
||||||
public async find(params : Params) : Promise<any> {
|
public async find(params : Params) : Promise<any> {
|
||||||
if (!params.query.type) {
|
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
|
* This is clearly stupid. I have no idea how we'll query very large
|
||||||
* datasets from PostgreSQL but this at least gets us _everything_
|
* datasets from PostgreSQL but this at least gets us _everything_
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
|
|
||||||
import { Application, HooksObject } from '@feathersjs/feathers';
|
import { Application, HooksObject } from '@feathersjs/feathers';
|
||||||
import service from 'feathers-sequelize';
|
import service from 'feathers-sequelize';
|
||||||
import { DataTypes } from 'sequelize';
|
import { Operators, DataTypes } from 'sequelize';
|
||||||
|
|
||||||
import authorize from '../hooks/authorize';
|
import authorize from '../hooks/authorize';
|
||||||
|
import applyGrant from '../hooks/apply-grant';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import db from '../models';
|
import db from '../models';
|
||||||
import Event from '../models/event';
|
import Event from '../models/event';
|
||||||
|
@ -18,9 +19,11 @@ export const eventsHooks : HooksObject = {
|
||||||
],
|
],
|
||||||
find: [
|
find: [
|
||||||
authorize(),
|
authorize(),
|
||||||
|
applyGrant(),
|
||||||
],
|
],
|
||||||
get: [
|
get: [
|
||||||
authorize(),
|
authorize(),
|
||||||
|
applyGrant(),
|
||||||
],
|
],
|
||||||
create: [
|
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