Skip to content

Commit

Permalink
Moves transform to MongoTransform
Browse files Browse the repository at this point in the history
- Adds ACL query injection in MongoTransform
  • Loading branch information
flovilmart committed Mar 31, 2016
1 parent 8a6903a commit 69dd1ab
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 35 deletions.
2 changes: 1 addition & 1 deletion spec/transform.spec.js → spec/MongoTransform.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// These tests are unit tests designed to only test transform.js.

var transform = require('../src/transform');
var transform = require('../src/Adapters/Storage/Mongo/MongoTransform');

var dummySchema = {
data: {},
Expand Down
5 changes: 5 additions & 0 deletions src/Adapters/Storage/Mongo/MongoSchemaCollection.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import MongoCollection from './MongoCollection';
import * as transform from './MongoTransform';

function _mongoSchemaQueryFromNameQuery(name: string, query) {
return _mongoSchemaObjectFromNameFields(name, query);
Expand Down Expand Up @@ -55,4 +56,8 @@ export default class MongoSchemaCollection {
upsertSchema(name: string, query: string, update) {
return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update);
}

get transform() {
return transform;
}
}
7 changes: 6 additions & 1 deletion src/Adapters/Storage/Mongo/MongoStorageAdapter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

import MongoCollection from './MongoCollection';
import MongoSchemaCollection from './MongoSchemaCollection';
import {parse as parseUrl, format as formatUrl} from '../../../vendor/mongodbUrl';
import { parse as parseUrl, format as formatUrl } from '../../../vendor/mongodbUrl';
import * as transform from './MongoTransform';

let mongodb = require('mongodb');
let MongoClient = mongodb.MongoClient;
Expand Down Expand Up @@ -78,6 +79,10 @@ export class MongoStorageAdapter {
});
});
}

get transform() {
return transform;
}
}

export default MongoStorageAdapter;
Expand Down
23 changes: 23 additions & 0 deletions src/transform.js → src/Adapters/Storage/Mongo/MongoTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,27 @@ function untransformObject(schema, className, mongoObject, isNestedObject = fals
}
}

function addWriteACL(mongoWhere, acl) {
var writePerms = [
{_wperm: {'$exists': false}}
];
for (var entry of acl) {
writePerms.push({_wperm: {'$in': [entry]}});
}
return {'$and': [mongoWhere, {'$or': writePerms}]};
}

function addReadACL(mongoWhere, acl) {
var orParts = [
{"_rperm" : { "$exists": false }},
{"_rperm" : { "$in" : ["*"]}}
];
for (var entry of acl) {
orParts.push({"_rperm" : { "$in" : [entry]}});
}
return {'$and': [mongoWhere, {'$or': orParts}]};
}

var DateCoder = {
JSONToDatabase(json) {
return new Date(json.iso);
Expand Down Expand Up @@ -831,5 +852,7 @@ module.exports = {
transformCreate: transformCreate,
transformUpdate: transformUpdate,
transformWhere: transformWhere,
addReadACL: addReadACL,
addWriteACL: addWriteACL,
untransformObject: untransformObject
};
41 changes: 10 additions & 31 deletions src/Controllers/DatabaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ var mongodb = require('mongodb');
var Parse = require('parse/node').Parse;

var Schema = require('./../Schema');
var transform = require('./../transform');
const deepcopy = require('deepcopy');

// options can contain:
Expand Down Expand Up @@ -122,7 +121,7 @@ DatabaseController.prototype.validateObject = function(className, object, query,
// Filters out any data that shouldn't be on this REST-formatted object.
DatabaseController.prototype.untransformObject = function(
schema, isMaster, aclGroup, className, mongoObject) {
var object = transform.untransformObject(schema, className, mongoObject);
var object = this.adapter.transform.untransformObject(schema, className, mongoObject);

if (className !== '_User') {
return object;
Expand Down Expand Up @@ -168,17 +167,11 @@ DatabaseController.prototype.update = function(className, query, update, options
.then(() => this.handleRelationUpdates(className, query.objectId, update))
.then(() => this.adaptiveCollection(className))
.then(collection => {
var mongoWhere = transform.transformWhere(schema, className, query);
var mongoWhere = this.adapter.transform.transformWhere(schema, className, query);
if (options.acl) {
var writePerms = [
{_wperm: {'$exists': false}}
];
for (var entry of options.acl) {
writePerms.push({_wperm: {'$in': [entry]}});
}
mongoWhere = {'$and': [mongoWhere, {'$or': writePerms}]};
mongoWhere = this.adapter.transform.addWriteACL(mongoWhere, options.acl);
}
mongoUpdate = transform.transformUpdate(schema, className, update);
mongoUpdate = this.adapter.transform.transformUpdate(schema, className, update);
return collection.findOneAndUpdate(mongoWhere, mongoUpdate);
})
.then(result => {
Expand Down Expand Up @@ -305,16 +298,9 @@ DatabaseController.prototype.destroy = function(className, query, options = {})
})
.then(() => this.adaptiveCollection(className))
.then(collection => {
let mongoWhere = transform.transformWhere(schema, className, query);

let mongoWhere = this.adapter.transform.transformWhere(schema, className, query, options);
if (options.acl) {
var writePerms = [
{ _wperm: { '$exists': false } }
];
for (var entry of options.acl) {
writePerms.push({ _wperm: { '$in': [entry] } });
}
mongoWhere = { '$and': [mongoWhere, { '$or': writePerms }] };
mongoWhere = this.adapter.transform.addWriteACL(mongoWhere, options.acl);
}
return collection.deleteMany(mongoWhere);
})
Expand Down Expand Up @@ -350,7 +336,7 @@ DatabaseController.prototype.create = function(className, object, options) {
.then(() => this.handleRelationUpdates(className, null, object))
.then(() => this.adaptiveCollection(className))
.then(coll => {
var mongoObject = transform.transformCreate(schema, className, object);
var mongoObject = this.adapter.transform.transformCreate(schema, className, object);
return coll.insertOne(mongoObject);
})
.then(result => {
Expand Down Expand Up @@ -552,7 +538,7 @@ DatabaseController.prototype.find = function(className, query, options = {}) {
if (options.sort) {
mongoOptions.sort = {};
for (let key in options.sort) {
let mongoKey = transform.transformKey(schema, className, key);
let mongoKey = this.adapter.transform.transformKey(schema, className, key);
mongoOptions.sort[mongoKey] = options.sort[key];
}
}
Expand All @@ -569,16 +555,9 @@ DatabaseController.prototype.find = function(className, query, options = {}) {
.then(() => this.reduceInRelation(className, query, schema))
.then(() => this.adaptiveCollection(className))
.then(collection => {
let mongoWhere = transform.transformWhere(schema, className, query);
let mongoWhere = this.adapter.transform.transformWhere(schema, className, query);
if (!isMaster) {
let orParts = [
{"_rperm" : { "$exists": false }},
{"_rperm" : { "$in" : ["*"]}}
];
for (let acl of aclGroup) {
orParts.push({"_rperm" : { "$in" : [acl]}});
}
mongoWhere = {'$and': [mongoWhere, {'$or': orParts}]};
mongoWhere = this.adapter.transform.addReadACL(mongoWhere, aclGroup);
}
if (options.count) {
delete mongoOptions.limit;
Expand Down
3 changes: 1 addition & 2 deletions src/Schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
// TODO: hide all schema logic inside the database adapter.

var Parse = require('parse/node').Parse;
var transform = require('./transform');

const defaultColumns = Object.freeze({
// Contain the default columns for every parse object type (except _Join collection)
Expand Down Expand Up @@ -416,7 +415,7 @@ class Schema {
// If 'freeze' is true, refuse to update the schema for this field.
validateField(className, key, type, freeze) {
// Just to check that the key is valid
transform.transformKey(this, className, key);
this._collection.transform.transformKey(this, className, key);

if( key.indexOf(".") > 0 ) {
// subdocument key (x.y) => ok if x is of type 'object'
Expand Down

0 comments on commit 69dd1ab

Please sign in to comment.