Skip to content

Commit

Permalink
Fixed merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
vamsee committed Nov 14, 2019
2 parents eec6c13 + be4e183 commit 74a3f7a
Show file tree
Hide file tree
Showing 21 changed files with 2,869 additions and 112 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.git
.gitlab-ci.yml
.gitattributes
.gitignore
./test/performance/docker-compose.yml
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = function GruntConfig(grunt) {
mochaOptions: ['--exit']
},
coverage: {
src: ['test/test.js'],
src: ['test/test.js', 'test/aggregation-fn-groupby-test.js', 'test/aggregation-fn-having-test.js'],
options: {
timeout: 60000,
check: {
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
+ [start()](#start--)
+ [addContextField(name, property)](#addcontextfield-name--property-)
+ [removeForceId](#removeforceid)
+ [setACLToBaseEntity](#setACLToBaseEntity)
+ [observers](#observers)
* [Configurations](#configurations)
* [Remote End point (RestAPI)](#remote-end-point--restapi-)
Expand Down Expand Up @@ -481,6 +482,21 @@ If you want to disable this, you can use **disableForceIdForUserModels** setting
**About ForceId** : In loopback 3, ForceId setting is done on model which is **true** by default. In this case, user/programmer cannot create a record on model by passing his/her own id. Id is always generated by loopback. To disable this setting, you can use removeForceId call.
### setACLToBaseEntity
This function should be called to set default ACL on BaseEntity Model. in oeCloud 2.x, BaseEntity doesn't have any ACL applied. Therefore, all operations on all models which are derived from BaseEntity are possible. To prevent that, programmer can call this method.
```javaScript
var oecloud = require('oe-cloud');
oecloud.setACLToBaseEntity({
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$unauthenticated",
"permission": "DENY"
});
// oecloud.boot() and other code
```
Remember that this has to be done before other models are loaded - meaning it should be done before you call boot().
### observers
Expand Down
8 changes: 0 additions & 8 deletions common/models/base-entity.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@
},
"validations": [],
"relations": {},
"acls": [
{
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$unauthenticated",
"permission": "DENY"
}
],
"methods": {}
}

47 changes: 46 additions & 1 deletion lib/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var debug = require('debug')('oe-cloud:oe-cloud');
var async = require('async');
var jutil = require('loopback-datasource-juggler/lib/jutil');
var observerMixin = require('loopback-datasource-juggler/lib/observer');
var fs = require('fs');

wrapper.initWrapper();

Expand All @@ -30,13 +31,15 @@ function getRootFolder() {
try {
rootFolder = path.dirname(module.parent.parent.filename);
} catch (e) {
// eslint-disable-next-line no-console
console.error('**** ERROR : Not able to get root folder from parent module. ****', e);
}

if (!rootFolder || process.env.FIXEDSERVER) {
try {
rootFolder = process.cwd() + '/server';
} catch (e) {
// eslint-disable-next-line no-console
console.error('**** ERROR : Not able to get current working directory. ****', e);
}
}
Expand Down Expand Up @@ -69,7 +72,26 @@ app.createServer = function () {
if ( app.server ) {
return app.server;
}
var server = require('http').createServer(app);

var server;
if (process.env.REQUIRE_HTTPS === true || process.env.REQUIRE_HTTPS === 'true') {
var keyPath = process.env.SSL_KEY_PATH || '';
var certPath = process.env.SSL_CERT_PATH || '';
if (!(keyPath && certPath)) {
throw new Error('HTTPS Enabled but SSL_KEY_PATH or SSL_CERT_PATH are not defined');
}
/**
* SSL_KEY_PATH & SSL_CERT_PATH should be absolute paths
*/
let configOptions = {
key: fs.readFileSync(keyPath).toString(),
cert: fs.readFileSync(certPath).toString()
};
server = require('https').createServer(configOptions, app);
} else {
server = require('http').createServer(app);
}

app.server = server;
return server;
};
Expand Down Expand Up @@ -147,9 +169,11 @@ app.start = function () {
return app.listen( () => {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
// eslint-disable-next-line no-console
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
// eslint-disable-next-line no-console
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
Expand Down Expand Up @@ -241,6 +265,8 @@ app.addContextField('roles', {
});


// Atul : This utility function is used to remove forceId settings from model
// This is important for User/Role etc models from loopback
app.removeForceId = function (modelName) {
var model = loopback.getModelByType(modelName);
model.settings.forceId = false;
Expand All @@ -257,6 +283,25 @@ app.removeForceId = function (modelName) {
}
};


// Atul : By Default unauthenticated users can do WRITE operations on BaseEntity. To keep backward compatibility, application can call this function to set ACL on BaseEntity
// Remember that, if programmer wants to call this function to set ACL, it has to be done before boot.
// "acls":
// {
// "accessType": "WRITE",
// "principalType": "ROLE",
// "principalId": "$unauthenticated",
// "permission": "DENY"
// }
app.setACLToBaseEntity = function (acl) {
if (!Array.isArray(acl)) {
app.addSettingsToBaseEntity({acls: [acl]});
} else {
app.addSettingsToBaseEntity({acls: acl});
}
};


app.registry.modelBuilder.registerCustomType('timestamp', 'date');
var emailPattern = '^(([^<>()[\\]\\\\.,;:\\s@\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\"]+)*)|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$';
app.registry.modelBuilder.registerCustomType('email', 'string', { pattern: emailPattern });
Expand Down
2 changes: 1 addition & 1 deletion lib/loopback-boot-utility/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function normalizeMixinName(str, normalization) {
switch (normalization) {
case false:
case 'none': return str;

// eslint-disable-next-line no-undefined
case undefined:
case 'classify':
str = String(str).replace(/([A-Z]+)/g, ' $1').trim();
Expand Down
2 changes: 2 additions & 0 deletions lib/loopback-datasource-juggler-wrapper/coerce.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ DataAccessObject._coerce = function (where, options) {
}

var val = where[p];
// eslint-disable-next-line no-undefined
if (val === null || val === undefined) {
continue;
}
Expand Down Expand Up @@ -243,6 +244,7 @@ DataAccessObject._coerce = function (where, options) {
// Coerce the array items
if (Array.isArray(val)) {
for (var i = 0; i < val.length; i++) {
// eslint-disable-next-line no-undefined
if (val[i] !== null && val[i] !== undefined) {
val[i] = DataType(val[i]);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/loopback-datasource-juggler-wrapper/dao-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const assert = require('assert');
const async = require('async');
require('./coerce');

/* eslint-disable no-undefined */

/* eslint-disable no-unused-vars */
// Atul : Keep this function for reference
// function checkForOverrideAndCall(self, fn, args, optionIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const HasOne = require('loopback-datasource-juggler/lib/relation-definition').Ha
const ModelBaseClass = require('loopback-datasource-juggler/lib/model.js');
const g = require('strong-globalize')();

/* eslint-disable no-undefined */

// Atul : Functions from relation-definition.js are overloaded. These functions are overriden so that
// this.fetch() call, options can be passed. HasOne.prototype.update and destroy() overriden
// default loopback-datasource-juggler doesn't pass options and hence it would crash
Expand Down Expand Up @@ -39,6 +41,7 @@ HasOne.prototype.update = function (targetModelData, options, cb) {
cb = cb || utils.createPromiseCallback();
var definition = this.definition;
var fk = this.definition.keyTo;
// eslint-disable-next-line handle-callback-err
this.fetch(null, options, function (err, targetModel) {
if (targetModel instanceof ModelBaseClass) {
// Ensures Foreign Key cannot be changed!
Expand All @@ -60,6 +63,7 @@ HasOne.prototype.destroy = function (options, cb) {
}
cb = cb || utils.createPromiseCallback();
var definition = this.definition;
// eslint-disable-next-line handle-callback-err
this.fetch(null, options, function (err, targetModel) {
if (targetModel instanceof ModelBaseClass) {
targetModel.destroy(options, cb);
Expand Down
21 changes: 10 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "oe-cloud",
"version": "2.0.0",
"version": "2.1.0",
"description": "oe-cloud modularization aka oecloud.io",
"engines": {
"node": ">=6"
Expand All @@ -15,15 +15,15 @@
},
"dependencies": {
"async": "2.6.1",
"lodash": "4.17.11",
"compression": "1.7.3",
"cookie-parser": "1.4.3",
"loopback": "3.22.3",
"loopback-datasource-juggler": "3.24.0",
"cors": "2.8.5",
"lodash": "4.17.14",
"loopback": "3.26.0",
"loopback-boot": "2.27.1",
"loopback-component-explorer": "5.4.0",
"loopback-datasource-juggler": "3.24.0",
"mustache": "2.3.2",
"oe-logger": "2.0.0",
"oe-logger": "^2.0.0",
"serve-favicon": "2.5.0",
"serve-static": "1.13.2",
"strong-error-handler": "2.3.2"
Expand All @@ -35,7 +35,7 @@
"chai-things": "0.2.0",
"chalk": "1.1.1",
"eslint": "4.10.0",
"grunt": "1.0.3",
"grunt": "1.0.4",
"grunt-banner": "0.6.0",
"grunt-cli": "1.3.2",
"grunt-contrib-clean": "2.0.0",
Expand All @@ -46,11 +46,10 @@
"grunt-mocha-test": "0.13.3",
"istanbul": "0.4.5",
"mocha": "5.2.0",
"oe-connector-mongodb": "^2.0.0",
"oe-connector-postgresql": "^2.0.0",
"superagent-defaults": "0.1.14",
"supertest": "3.4.2",
"oe-skeleton": "2.0.0",
"oe-connector-mongodb": "2.0.0",
"oe-connector-postgresql": "2.0.0"
"supertest": "3.4.2"
},
"author": "Atul Pandit <[email protected]>",
"repository": {
Expand Down
18 changes: 12 additions & 6 deletions server/boot/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* Bangalore, India. All Rights Reserved.
*
*/
// Atul : This script is used to enable authentication for the application
// Also 'enableAuthCookie' is introduced. if this option is set then cookie is created when user login using user.login()
// When user logs out, cookie is deleted. This is helpfule at least for node-red because node-red application does not
// send access Token as part of URL / or AuthSession header
// Atul : This script includes aboutMe() API. This API returned user information to caller including context

// Author : Atul
// This script has many user/authentication related functionalities.
const loopback = require('loopback');

// Atul : This script includes aboutMe() API. This API returned user information to caller including context
function aboutMe() {
var userModel = loopback.getModelByType('User');
userModel.aboutMe = function (options, cb) {
Expand Down Expand Up @@ -92,6 +92,9 @@ module.exports = function enableAuthentication(server) {
server.removeForceId('RoleMapping');
}

// Atul : Below code will add Roles of the logged in user to AccessToken.
// As accessToken fields are available in context ( and henc options ), programmer can use list of Roles user belongs to
// roles field is added to AccessToken on load.js file
var accessTokenModel = loopback.getModelByType('AccessToken');
accessTokenModel.observe('before save', function (ctx, next) {
if (!ctx.isNewInstance) {
Expand Down Expand Up @@ -135,7 +138,10 @@ module.exports = function enableAuthentication(server) {
});
});


// Atul : This script is used to enable authentication for the application
// Also 'enableAuthCookie' is introduced. if this option is set then cookie is created when user login using user.login()
// When user logs out, cookie is deleted. This is helpfule at least for node-red because node-red application does not
// send access Token as part of URL / or AuthSession header
var enableAuthCookie = server.get('enableAuthCookie');
if (!enableAuthCookie) {
return;
Expand Down
1 change: 1 addition & 0 deletions server/boot/db-models.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function loadModelsFromDB(app, cb) {
// design break when used fetchAllScopes
modelDefinition.find({where: {filebased: false}}, {fetchAllScopes: true}, (err, result) => {
if (err) {
// eslint-disable-next-line no-console
console.error('******* Could not able to load models from Database ********* ');
return cb();
}
Expand Down
Loading

0 comments on commit 74a3f7a

Please sign in to comment.