Skip to content

Commit

Permalink
Merge branch 'sb/287' into 'master'
Browse files Browse the repository at this point in the history
backend for agnostic campaigns

See merge request debtcollective/debtcollective!174
  • Loading branch information
Alexandre Marcondes committed Jan 25, 2018
2 parents afb1592 + 523fc61 commit 9125217
Show file tree
Hide file tree
Showing 30 changed files with 445 additions and 123 deletions.
19 changes: 16 additions & 3 deletions controllers/Admin/Collectives/CampaignsController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* globals neonode, CONFIG, Class, Admin, RestfulController, Collective, DisputeTool,
NotFoundError, Campaign */
NotFoundError, Campaign, logger */

const fs = require('fs-extra');

Expand Down Expand Up @@ -28,6 +28,7 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({
{
before(req, res, next) {
res.locals.selectedCollective = req.params.collective_id;
logger.debug(`Identified selectedCollective (${res.locals.selectedCollective})`);
next();
},
actions: ['new', 'edit', 'update'],
Expand All @@ -54,6 +55,8 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({

prototype: {
_loadCampaign(req, res, next) {
logger.debug(`Loading campaign ${req.params.id}`);

Admin.Collectives.Campaign.query()
.where('id', req.params.id)
.include('collective')
Expand All @@ -64,6 +67,7 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({

req.campaign = campaign[0];
res.locals.campaign = campaign[0];
logger.debug(`Campaign ${req.params.id} loaded from db`);
return next();
})
.catch(next);
Expand All @@ -79,14 +83,16 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({
campaign.collectiveId = req.params.collective_id;
campaign.active = true;

logger.debug(`Creating new campaign ${campaign.title}`);

campaign.save()
.then(() => {
if (req.files && req.files.image && req.files.image.length > 0) {
const image = req.files.image[0];

return campaign.attach('cover', image.path, {
fileSize: image.size,
mimeType: image.mimetype || image.mimeType
mimeType: image.mimetype || image.mimeType,
})
.then(() => {
fs.unlinkSync(image.path);
Expand All @@ -104,6 +110,7 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({
);
})
.catch((err) => {
logger.error(`Unable to create campaign ${campaign.title}: ${err} ${err.stack}`);
res.status(400);

res.locals.errors = err.errors || err;
Expand All @@ -113,10 +120,13 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({
},

edit(req, res) {
logger.debug(`Someone is updating campaign ${req.campaign.title}`);
res.render('admin/campaigns/edit');
},

update(req, res) {
logger.debug(`Updating campaign ${req.campaign.title}`);

req.campaign.updateAttributes(req.body);

const active = req.body.active === 'true';
Expand All @@ -132,7 +142,7 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({

return req.campaign.attach('cover', image.path, {
fileSize: image.size,
mimeType: image.mimetype || image.mimeType
mimeType: image.mimetype || image.mimeType,
})
.then(() => {
fs.unlinkSync(image.path);
Expand Down Expand Up @@ -161,8 +171,11 @@ Class(Admin.Collectives, 'CampaignsController').inherits(RestfulController)({
activate(req, res, next) {
req.campaign.active = true;

logger.debug('Activating campaign ${req.campaign.title}');

req.campaign.save()
.then(() => {
logger.debug(`Successfully activated campaign ${req.campaign.title}`);
req.flash('success', 'The campaign is now active.');
res.redirect(CONFIG.router.helpers.Campaigns.show.url(req.campaign.id));
})
Expand Down
2 changes: 1 addition & 1 deletion controllers/Admin/Collectives/UsersController.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ Admin.UsersController = Class(Admin.Collectives, 'UsersController').inherits(Res
},
{
before(req, res, next) {
Collective.query()
Collective.queryVisible()
.where('id', req.params.collective_id)
.then(([collective]) => {
req.collective = collective;
Expand Down
4 changes: 2 additions & 2 deletions controllers/Admin/CollectivesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Admin.CollectivesController = Class(Admin, 'CollectivesController').inherits(Res
// Load Collectives
{
before(req, res, next) {
Admin.Collective.query()
Admin.Collective.queryVisible()
.include('tools')
.orderBy('created_at', 'DESC')
.then((collectives) => {
Expand Down Expand Up @@ -63,7 +63,7 @@ Admin.CollectivesController = Class(Admin, 'CollectivesController').inherits(Res
],
prototype: {
_loadCollective(req, res, next) {
Collective.query()
Collective.queryVisible()
.where({ id: req.params.id })
.include('tools')
.then(([collective]) => {
Expand Down
2 changes: 1 addition & 1 deletion controllers/Admin/UsersController.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Admin.UsersController = Class(Admin, 'UsersController').inherits(RestfulControll
res.locals._backUrl = req.query._backUrl;
}

Collective.query()
Collective.queryVisible()
.orderBy('created_at', 'ASC')
.then((collectives) => {
req.collectives = collectives;
Expand Down
5 changes: 5 additions & 0 deletions controllers/CampaignsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
User, Event, EventAssistant, KBTopic, KBPost */

const path = require('path');

const RESTfulAPI = require(path.join(process.cwd(), 'lib', 'RESTfulAPI'));

const marked = require('marked');
Expand Down Expand Up @@ -305,6 +306,10 @@ const CampaignsController = Class('CampaignsController').inherits(RestfulControl
res.render('campaigns/show');
},

index(req, res) {
res.render('campaigns/index');
},

join(req, res, next) {
const knex = Campaign.knex();
const debtAmount = (req.body.debt_amount * 100) || 0;
Expand Down
2 changes: 1 addition & 1 deletion controllers/CollectivesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const CollectivesController = Class('CollectivesController').inherits(RestfulCon
// Load Collectives
{
before(req, res, next) {
Collective.query()
Collective.queryVisible()
.orderBy('created_at', 'DESC')
.then((collectives) => Promise.all(collectives.map((c) => {
const subquery = Campaign.query()
Expand Down
13 changes: 8 additions & 5 deletions controllers/PostsController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* global Class, CONFIG, RestfulController, NotFoundError, Post, PostsController,
PostImage, neonode, Campaign, Account */
PostImage, neonode, Campaign, Account, logger */

const _ = require('lodash');
const sanitize = require('sanitize-html');
Expand Down Expand Up @@ -169,6 +169,8 @@ const PostsController = Class('PostsController').inherits(RestfulController)({
},

create(req, res) {
logger.debug(`Creating a new post by ${req.user.id}`);

let builder = false;

const controller = neonode.controllers.Posts;
Expand All @@ -186,10 +188,11 @@ const PostsController = Class('PostsController').inherits(RestfulController)({
}

if (!builder) {
builder = Promise.reject(new Error('Invalid post type'));
logger.debug(`New post by ${req.user.id} had invalid post type ${req.body.type}`);
return Promise.reject(new Error('Invalid post type'));
}

builder
return builder
.then((post) => {
res.json(post);
})
Expand Down Expand Up @@ -397,10 +400,10 @@ const PostsController = Class('PostsController').inherits(RestfulController)({
}

if (!builder) {
builder = Promise.reject(new Error('Invalid post type'));
return Promise.reject(new Error('Invalid post type'));
}

builder
return builder
.then(() => {
res.json(post);
})
Expand Down
14 changes: 9 additions & 5 deletions controllers/UsersController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* globals Class, RestfulController, User, NotFoundError,
CONFIG, Collective, Account, DisputeTool */
CONFIG, Collective, Account, DisputeTool, logger */
const Promise = require('bluebird');
const fs = require('fs-extra');
const createQueue = require('../workers/utils').createQueue;
Expand Down Expand Up @@ -86,9 +86,13 @@ const UsersController = Class('UsersController').inherits(RestfulController)({

user.role = 'User';

logger.debug(`Creating a new user ${user.email}`);

if (!Array.isArray(req.body.collectiveIds)) {
req.body.collectiveIds = [req.body.collectiveIds];
}
const collectiveIds = req.body.collectiveIds;
collectiveIds.push(Collective.invisibleId);

User.transaction(trx =>
user
Expand All @@ -106,7 +110,7 @@ const UsersController = Class('UsersController').inherits(RestfulController)({
.del()
)
.then(() => {
const userCollectives = req.body.collectiveIds.map(
const userCollectives = collectiveIds.map(
collectiveId => ({
user_id: user.id,
collective_id: collectiveId,
Expand All @@ -118,12 +122,11 @@ const UsersController = Class('UsersController').inherits(RestfulController)({
.transacting(trx)
.insert(userCollectives);
})
.then(() =>
Promise.each(req.body.collectiveIds, collectiveId =>
Collective.query()
.then(() => Promise.each(collectiveIds, collectiveId => Collective.query()
.transacting(trx)
.where('id', collectiveId)
.then(([collective]) => {
logger.debug(`Incrementing ${collective.name} userCount for new user ${user.id}`)
collective.userCount++;

return collective.transacting(trx).save();
Expand All @@ -150,6 +153,7 @@ const UsersController = Class('UsersController').inherits(RestfulController)({
.save();
})
.catch(err => {
logger.debug(`Unable to create user ${user.email} because of error: ${err}${err.stack}`);
res.status(400);

if (err.message === 'Must provide a password') {
Expand Down
2 changes: 1 addition & 1 deletion middlewares/CSRFError.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if (sessions === false) {
module.exports = (req, res, next) => next();
} else {
module.exports = (err, req, res, next) => {
logger.error('CSRF', err, res.locals._csrf);
logger.error('CSRFError (check redis server)', err, res.locals._csrf);
next(err);
};
}
Expand Down
2 changes: 1 addition & 1 deletion middlewares/locals.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = function locals(req, res, next) {
res.locals.STRIPE_PUBLISHABLE_KEY = CONFIG.env().stripe.publishable;

if (!req.user) {
return Collective.query().then((collectives) => {
return Collective.queryVisible().then((collectives) => {
res.locals.COLLECTIVES = collectives;
next();
});
Expand Down
1 change: 1 addition & 0 deletions model-relations/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ User.relations = {
},

debtTypes: {
// will never return the invisible collective (see `query` in `models/Collective.js`)
type: 'HasManyThrough',
relatedModel: Collective,
ownerCol: 'id',
Expand Down
7 changes: 7 additions & 0 deletions models/Collective.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Collective = Class('Collective').inherits(Krypton.Model).includes(Krypton.
maxFileSize: 5242880,
acceptedMimeTypes: [/image/],
})),
invisibleId: '00000000-0000-0000-0000-000000000000',

prototype: {
init(config) {
Expand All @@ -50,6 +51,12 @@ const Collective = Class('Collective').inherits(Krypton.Model).includes(Krypton.
return this;
},
},

queryVisible(...args) {
return Krypton.Model.query.call(this, ...args)
.whereNot('id', this.invisibleId);
}

});

module.exports = Collective;
18 changes: 11 additions & 7 deletions seeds/20171116114842_collectives.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable max-len */

exports.seed = (knex) => {
return knex('Collectives').del()
exports.seed = (knex) =>
knex('Collectives').del()
.then(() => {
const collectives = [
{
Expand Down Expand Up @@ -108,13 +108,17 @@ Debt has isolated us and made us feel alone and ashamed. We have come out of the
We are committed to direct action, mutual aid and campaign support.`,
},
{
id: '00000000-0000-0000-0000-000000000000',
name: 'Invisible Collective',
description: 'This collective is a placeholder for agnostic campaigns, and is invisible to users. All users are "members" of this invisible, non-collective collective.',
},
];

return knex('Collectives').insert(collectives.map((collective) => {
return Object.assign(collective, {
return knex('Collectives').insert(collectives.map((collective) =>
Object.assign(collective, {
created_at: new Date(),
updated_at: new Date(),
});
}));
})
));
});
};
16 changes: 16 additions & 0 deletions seeds/20171118114842_add_users_to_collectives.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
exports.seed = (knex) => {
const collectiveId = '00000000-0000-0000-0000-000000000000';

return knex.transaction(trx =>
knex('UsersCollectives').transacting(trx).del().where('collective_id', collectiveId)
.then(() => knex('Users').select('id'))
.then((users) =>
Promise.all(users.map(user =>
knex('UsersCollectives').transacting(trx)
.insert({ user_id: user.id, collective_id: collectiveId })
))
.then(() => knex('Collectives').where('id', collectiveId).transacting(trx)
.update({ user_count: users.length })
))
);
};
Loading

0 comments on commit 9125217

Please sign in to comment.