diff --git a/.eslintignore b/.eslintignore index 398a1eb..9c8d714 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,7 @@ -/client/ -/coverage/ -/node_modules/ -server/dropdb.js -/lib/expression-language/expression-syntax-parser.js -/test/ +build/ +client/ +coverage/ +node_modules/ +test/ +drop.js +Gruntfile.js diff --git a/.eslintrc b/.eslintrc index 8f2f7cc..6edc78f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -111,7 +111,7 @@ "no-undefined": 1, // http://eslint.org/docs/rules/no-undefined "no-with": 2, // http://eslint.org/docs/rules/no-with "handle-callback-err": 1, // http://eslint.org/docs/rules/handle-callback-err - "radix": 2, // http://eslint.org/docs/rules/radix + "radix": 0, // http://eslint.org/docs/rules/radix "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife "yoda": 2, // http://eslint.org/docs/rules/yoda diff --git a/.gitignore b/.gitignore index 3bff760..7b1734a 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ out/ *.zip /common/models/test package-lock.json +oracle-user.sh diff --git a/Gruntfile.js b/Gruntfile.js index 022f7ad..ae3aa38 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,38 +10,6 @@ module.exports = function GruntConfig(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), - mkdir: { - all: { - options: { - create: ['dist'] - } - } - }, - - copy: { - main: { - files: [ - // includes files within path and its sub-directories - { - expand: true, - src: ['**', '!node_modules/**', '!coverage/**'], - dest: 'dist/' - } - ] - } - }, - - mochaTest: { - test: { - options: { - quiet: false, - clearRequireCache: true, - timeout: 100000 - }, - src: ['test/*.spec.js'] - } - }, - clean: { coverage: { src: ['coverage/'] @@ -56,7 +24,7 @@ module.exports = function GruntConfig(grunt) { mochaOptions: ['--exit'] }, coverage: { - src: 'test/test.js', + src: 'test/*.spec.js', options: { timeout: 60000, check: { @@ -72,12 +40,8 @@ module.exports = function GruntConfig(grunt) { }); // Add the grunt-mocha-test tasks. - grunt.loadNpmTasks('grunt-mocha-test'); - grunt.loadNpmTasks('grunt-mocha-istanbul'); grunt.loadNpmTasks('grunt-contrib-clean'); - - grunt.loadNpmTasks('grunt-mkdir'); - grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-mocha-istanbul'); grunt.registerTask('test-with-coverage', ['clean:coverage', 'mocha_istanbul']); }; diff --git a/README.md b/README.md index b2215ea..d90615f 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,22 @@ -# oe-validation +# oe-component-passport -This project implements validation functionality on Models. +This project implements multiple authentication capability provided by passportjs. ## Pre-requisites * oe-cloud * oe-logger * loopback-component-passport +* Configure model-config.json of application with UserIdentity and UserCredential with proper datasource as per application's datasource configuration ## Features 1. Local and 3rd party authentication support (like Facebook, google oauth authentication) 2. JWT authentication support -3. Configurable "Cookie" generation with users/login api (set ENABLE_COOKIE=true) +3. JWT as access_token +4. Configurable "Cookie" generation with users/login api (set ENABLE_COOKIE=true) +5. Parameterized providers.json ### Difference from previous version of oe-cloud @@ -36,8 +39,61 @@ Usage of this module needs an entry in package.json and also an entry to applica ``` Inside your application, authentication can be done using "/User/login" or "/auth/local" which returns access_token as payload and in cookie if configured. +### Configure model-config.json + +Add UserIdentity and UserCredential models in your application's model-config.json (in your application's server directory) with correct dataSource name. +Also set public true or false depending on your requirement to expose those as REST API or not. + +``` +"UserCredential": { + "dataSource": "db", + "public": false + }, + "UserIdentity": { + "dataSource": "db", + "public": false + } +``` + +### Parameterized providers.json + +You can write providers json like this where you can parameterise a value like *${variable_name}* + +``` javascript +{ + "local": { + "provider": "local", + "module": "passport-local", + "usernameField": "${userfieldname}", + "passwordField": "${PASSWORD_FIELD_NAME}", + "authPath": "/auth/local", + "successRedirect": "/explorer", + "failureRedirect": "/login", + "failureFlash": false, + "callbackHTTPMethod": "post", + "setAccessToken": true + } +} + +``` +In above example, usernameField value would be set to value of environment (or configuration) variable '**userfieldname**' and passwordField value would be from environment (or configuration) variable '**PASSWORD_FIELD_NAME**'. If those environmental variables are not set or not in configuration, '' (blank string) would be assigned. + +### JWT_FOR_ACCESS_TOKEN +To improve performance JWT can be used as access token. to enable that, set following environmental variable +``` javascript +JWT_SECRET_KEY = 'secret' +JWT_FOR_ACCESS_TOKEN = true; +``` +*JWT_SECRET_KEY* could be any secret consisting alphanumeric value. + + +Please note that this implementation of JWT just replaces generic access-token with JWT and saves checking user id from database for api every request that needs authentication (ACL). + +To implement custom JWT payload to have user roles(to use in ACL varification) and other details; override User.login function along with User.prototype.createAccessToken and AccessToken.resolve + +For any other login related customization, like password complexity, password history etc; please extend User model and add customized code in extended model (some example available in oe-demo-app) + -Examples are coming up in oe-demo-app project. diff --git a/lib/passport.js b/lib/passport.js index 5262cd2..821fe38 100644 --- a/lib/passport.js +++ b/lib/passport.js @@ -49,15 +49,51 @@ module.exports.configurePassport = function configurePassport(app, providerConfi // Merge util will merge providers.json from each dependent module and pass configurePassport() with this parameter try { config = providerConfigParameter ? providerConfigParameter : require(path.join(app.locals.apphome, 'providers.json')); + config = getUpdatedConfigObject(config); } catch (err) { console.error('could not load login configuration ', path.join(app.locals.apphome, 'providers.json'), ' https://docs.strongloop.com/display/public/LB/Configuring,providers.json ', err); process.exit(1); } - // var flash = require('connect-flash'); + function checkDynamicParam(value) { + var PARAM_REGEX = /\$\{(\w+)\}$/; + var match = value.match(PARAM_REGEX); + if (match) { + var appValue = process.env[match[1]] || app.get(match[1]) || ''; + if (appValue !== undefined) { + value = appValue; + } else { + console.warn('%s does not resolve to a valid value. ' + + '"%s" must be resolvable by app.get().', value, match[1]); + } + } + return value; + } + function getUpdatedConfigObject(element) { + if (typeof element === 'string') { + return checkDynamicParam(element); + } else if (Array.isArray(element)) { + return element.map(getUpdatedConfigObject); + } else if (typeof element !== 'object' || element === null) { + return element; + } + // recurse into object props + var interpolated = {}; + Object.keys(element).forEach(configKey => { + var value = element[configKey]; + if (Array.isArray(value)) { + interpolated[configKey] = value.map(getUpdatedConfigObject); + } else if (typeof value === 'string') { + interpolated[configKey] = checkDynamicParam(value); + } else if (typeof value === 'object' && Object.keys(value).length) { + interpolated[configKey] = getUpdatedConfigObject(value); + } else { + interpolated[configKey] = value; + } + }); + return interpolated; + } - // boot(app, __dirname); - // app.emit('ready'); // to support JSON-encoded bodies var jsonremoting = { limit: '1mb' diff --git a/package.json b/package.json index b280dc9..aa9ddf5 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,20 @@ { "name": "oe-component-passport", - "version": "2.1.0", - "description": "oe-cloud modularization project", + "version": "2.2.0", + "description": "oe-cloud module to initialize passport component supporting regular strategies and JWT as access token", "engines": { "node": ">=6" }, "main": "index.js", "scripts": { "pretest": "npm install --no-optional", - "test": "mocha --no-timeouts test/test.js", + "test": "mocha --no-timeouts test/*.spec.js", "lint": "eslint .", "fix-lint": "eslint --fix .", "grunt-cover": "grunt test-with-coverage" }, "dependencies": { - "body-parser": "1.9.0", + "body-parser": "1.19.0", "cookie-parser": "1.4.3", "jsonwebtoken": "8.4.0", "loopback-component-passport": "3.10.0", @@ -31,25 +31,21 @@ "async": "2.6.1", "babel-eslint": "7.2.3", "chai": "3.4.1", - "chai-datetime": "1.4.0", "chai-things": "0.2.0", "chalk": "1.1.1", "eslint": "4.10.0", "grunt": "1.0.4", - "grunt-banner": "0.6.0", "grunt-cli": "1.3.2", "grunt-contrib-clean": "2.0.0", - "grunt-contrib-copy": "1.0.0", - "grunt-jsbeautifier": "0.2.13", - "grunt-mkdir": "1.0.0", "grunt-mocha-istanbul": "5.0.2", - "grunt-mocha-test": "0.13.3", "istanbul": "0.4.5", "mocha": "5.2.0", + "oe-cloud": "^2.0.0", + "oe-connector-mongodb": "^2.0.0", + "oe-connector-oracle": "^2.0.0", + "oe-connector-postgresql": "^2.0.0", "superagent-defaults": "0.1.14", - "supertest": "3.4.2", - "loopback-connector-mongodb": "3.9.2", - "oe-cloud": "^2.0.0" + "supertest": "3.4.2" }, "author": "Dipayan Aich ", "repository": { diff --git a/server/model-config.json b/server/model-config.json index 93a3575..7d1c5e2 100644 --- a/server/model-config.json +++ b/server/model-config.json @@ -6,14 +6,5 @@ "mixins": [ "../common/mixins" ] - }, - "UserCredential": { - "dataSource": "db", - "public": false - }, - "UserIdentity": { - "dataSource": "db", - "public": false } - } diff --git a/test/bootstrap.js b/test/bootstrap.js new file mode 100644 index 0000000..1727889 --- /dev/null +++ b/test/bootstrap.js @@ -0,0 +1,46 @@ +var oecloud = require('oe-cloud'); +var logger = require('oe-logger'); +var log = logger('test-bootstrapper'); + +// var loopback = require('loopback'); +// oecloud.attachMixinsToBaseEntity("SkeletonMixin"); +process.env.userfieldname = 'username'; +process.env.PASSWORD_FIELD_NAME = 'password'; +process.env.JWT_SECRET_KEY = 'secret'; +process.env.JWT_FOR_ACCESS_TOKEN = true; + +oecloud.observe('loaded', function (ctx, next) { + console.log('oe-cloud modules loaded'); + return next(); +}); + +var testContext = { + ctx: { + tenantId: 'test-tenant' + } +}; + +oecloud.get('/info', function (req, res) { + return res.end(JSON.stringify({'status': 'logged in', 'access-token': res.accessToken})); +}); + +oecloud.get('/failed', function (req, res) { + return res.end(JSON.stringify({'status': 'failed'})); +}); + +oecloud.boot(__dirname, function (err) { + if (err) { + log.error(testContext, err); + // console.log('Error:', err) + process.exit(1); + } + oecloud.start(); + oecloud.emit('test-start'); +}); + +module.exports = new Promise(booted => + oecloud.on('test-start', () => { + // debugger; + // console.log('booted'); + booted(); + } ) ); diff --git a/test/datasources.json b/test/datasources.json index 10ff94c..5af8443 100644 --- a/test/datasources.json +++ b/test/datasources.json @@ -7,7 +7,6 @@ "name": "transient", "connector": "transient" }, - "db": { "host": "localhost", "port": 27017, @@ -15,7 +14,7 @@ "database": "oe-component-passport-test", "password": "admin", "name": "db", - "connector": "mongodb", + "connector": "oe-connector-mongodb", "user": "admin", "connectionTimeout": 500000, "connectTimeoutMS": 500000, diff --git a/test/datasources.mongo.js b/test/datasources.mongo.js index fd6db9a..9c7175c 100644 --- a/test/datasources.mongo.js +++ b/test/datasources.mongo.js @@ -5,27 +5,24 @@ * */ var mongoHost = process.env.MONGO_HOST || 'localhost'; +var mongoPort = process.env.MONGO_PORT ? parseInt(process.env.MONGO_PORT) : 27017; var dbName = process.env.DB_NAME || 'oe-component-passport-test'; -module.exports = -{ - "memdb": { - "name": "memdb", - "connector": "memory" +module.exports = { + 'memdb': { + 'name': 'memdb', + 'connector': 'memory' }, - "transient": { - "name": "transient", - "connector": "transient" + 'transient': { + 'name': 'transient', + 'connector': 'transient' }, - "db": { - "host": mongoHost, - "port": 27017, - "url": "mongodb://" + mongoHost + ":27017/" + dbName, - "database": dbName, - "password": "admin", - "name": "db", - "connector": "mongodb", - "user": "admin", - "connectionTimeout": 500000 + 'db': { + 'host': mongoHost, + 'port': mongoPort, + 'url': 'mongodb://' + mongoHost + ':' + mongoPort + '/' + dbName, + 'database': dbName, + 'name': 'db', + 'connector': 'oe-connector-mongodb', + 'connectionTimeout': 500000 } }; - diff --git a/test/datasources.oracle.js b/test/datasources.oracle.js index 8792ffd..b6f012a 100644 --- a/test/datasources.oracle.js +++ b/test/datasources.oracle.js @@ -4,16 +4,10 @@ * Bangalore, India. All Rights Reserved. * */ -/** - ** - ** ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), - ** Bangalore, India. All Rights Reserved. - ** - **/ -var oracleSID = process.env.ORACLE_SID || 'orclpdb.ad.infosys.com'; +var oracleSID = process.env.ORACLE_SID || 'ORCLCDB'; var oracleHost = process.env.ORACLE_HOST || 'localhost'; -var oraclePort = process.env.ORACLE_PORT || 1521; +var oraclePort = process.env.ORACLE_PORT ? parseInt(process.env.ORACLE_PORT) : 1521; var oracleUserName = process.env.ORACLE_USERNAME || 'oeadmin'; var oracleUserPassword = process.env.ORACLE_PASSWORD || 'oeadmin'; @@ -36,5 +30,3 @@ module.exports = { 'user': oracleUserName } }; - - diff --git a/test/datasources.postgres.js b/test/datasources.postgres.js index bdf1e9a..f53190b 100644 --- a/test/datasources.postgres.js +++ b/test/datasources.postgres.js @@ -5,29 +5,27 @@ * */ var postgresHost = process.env.POSTGRES_HOST || 'localhost'; +var postgresPort = process.env.POSTGRES_PORT ? parseInt(process.env.POSTGRES_PORT) : 5432; var dbName = process.env.DB_NAME || 'oe-component-passport-test'; -module.exports = -{ - "memdb": { - "name": "memdb", - "connector": "memory" +module.exports = { + 'memdb': { + 'name': 'memdb', + 'connector': 'memory' }, - "transient": { - "name": "transient", - "connector": "transient" + 'transient': { + 'name': 'transient', + 'connector': 'transient' }, - - "db": { - "host": postgresHost, - "port": 5432, - "url": "postgres://postgres:postgres@" + postgresHost + ":5432/" + dbName, - "database": dbName, - "password": "postgres", - "name": "db", - "connector": "loopback-connector-postgresql", - "user": "postgres", - "max": 50, - "connectionTimeout": 50000 + 'db': { + 'host': postgresHost, + 'port': postgresPort, + 'url': 'postgres://postgres:postgres@' + postgresHost + ':' + postgresPort + '/' + dbName, + 'database': dbName, + 'password': 'postgres', + 'name': 'db', + 'connector': 'oe-connector-postgresql', + 'user': 'postgres', + 'max': 50, + 'connectionTimeout': 50000 } }; - diff --git a/test/local-login.spec.js b/test/local-login.spec.js new file mode 100644 index 0000000..ef76839 --- /dev/null +++ b/test/local-login.spec.js @@ -0,0 +1,123 @@ +/** + * + * ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), + * Bangalore, India. All Rights Reserved. + * + */ +var chalk = require('chalk'); +var bootstrap = require('./bootstrap'); +var app = require('oe-cloud'); +models = app.models; +var defaultContext = {'ctx': {'tenantId': 'default'}}; +var chai = require('chai'); +chai.use(require('chai-things')); +var expect = chai.expect; +var defaults = require('superagent-defaults'); +var supertest = require('supertest'); +var api = defaults(supertest(app)); +var accessToken = ''; + +describe(chalk.blue('model-validation PropertyLevel Validation test'), function () { + this.timeout(600000); + before('wait for boot', function (done) { + bootstrap.then(() => { + // debugger + // create user + done(); + }) + .catch(done); + }); + + before('create user', function (done) { + var userData = { + 'id': 'admin', + 'username': 'admin', + 'email': 'admin@ev.com', + 'password': 'admin', + 'emailVerified': false + }; + models.User.create(userData, defaultContext, function (err, user) { + if (err) { + done(err); + } else { + user.updateAttributes({'emailVerified': true }, defaultContext, function (err) { + done(err); + }); + } + }); + }); + + after('remove user', function (done) { + models.User.destroyById('admin', function (err) { + models.ModelDefinition.destroyById('tEsTmOdEl', function (err) { + done(err); + }); + }); + }); + + it('should login using auth/local', function (done) { + api.post('/auth/local') + .set('Accept', 'application/json') + .send({ + 'username': 'admin', + 'password': 'admin' + }) + .expect(302) + .expect('Location', '/info') + .end(function (err) { + if (err) {done(err);} + + expect(err).to.be.null; + console.info('login successful'); + done(); + }); + }); + + it('should fail to login using auth/local', function (done) { + api.post('/auth/local') + .set('Accept', 'application/json') + .send({ + 'username': 'admin', + 'password': 'admin1' + }) + .expect(302) + .expect('Location', '/failed') + .end(function (err) { + if (err) {done(err);} + + expect(err).to.be.null; + console.info('login failed as expected'); + done(); + }); + }); + + it('should contain access token which is a JWT', function (done) { + models.User.login({'username': 'admin', 'password': 'admin'}, function (err, res) { + accessToken = res.accessToken; + expect(res.accessToken).to.be.defined; + expect(res.accessToken.split('.').length).equals(3); + done(err); + }); + }); + + it('should successfully POST with access token which is a JWT', function (done) { + api.post('/api/ModelDefinitions?access_token=' + accessToken) + .set('Accept', 'application/json') + .send({ + 'id': 'tEsTmOdEl', + 'name': 'TestModel', + 'properties': { + 'customer name': 'string', + 'type': 'number' + } + }) + .expect(200) + .end(function (err, response) { + if (err) {done(err);} + + expect(err).to.be.null; + expect(response.body.name).equals('TestModel'); + done(); + }); + }); +}); diff --git a/test/model-config.json b/test/model-config.json index e57ec4d..dab39af 100644 --- a/test/model-config.json +++ b/test/model-config.json @@ -1,38 +1,15 @@ { "_meta": { "sources": [ - "loopback/common/models", - "loopback/server/models", - "./common/models", - "./test/common/models", - "./models" + "../common/models" ], "mixins": [ - "loopback/common/mixins", - "loopback/server/mixins", - "./common/mixins", - "../common/mixins", - "./mixins" + "../common/mixins" ] }, "User": { - "dataSource": "db" - }, - "AccessToken": { - "dataSource": "db", - "public": false - }, - "ACL": { - "dataSource": "db", - "public": false - }, - "RoleMapping": { - "dataSource": "db", - "public": false - }, - "Role": { "dataSource": "db", - "public": false + "public": true }, "UserCredential": { "dataSource": "db", @@ -42,4 +19,5 @@ "dataSource": "db", "public": true } -} + +} \ No newline at end of file diff --git a/test/oracle-utility.js b/test/oracle-utility.js index 153da7f..40a1734 100644 --- a/test/oracle-utility.js +++ b/test/oracle-utility.js @@ -15,22 +15,29 @@ // ORACLE_SYSUSER // ORACLE_SYSPASSWORD // ORACLE_SID -// CI_PROJECT_NAME // CI_PROJECT_NAMESPACE +// CI_PROJECT_NAME var oracledb = require('oracledb'); var async = require('async'); +var fs = require('fs'); +var os = require('os'); + var oracleHost = process.env.ORACLE_HOST || 'localhost'; -var oraclePort = process.env.ORACLE_PORT || 1521; +var oraclePort = process.env.ORACLE_PORT ? parseInt(process.env.ORACLE_PORT) : 1521; +var oracleSID = process.env.ORACLE_SID || 'ORCLCDB'; var oracleConnectSettings = { 'password': process.env.ORACLE_SYSPASSWORD || 'manager1', 'user': process.env.ORACLE_SYSUSER || 'sys', - 'connectString': oracleHost + ':' + oraclePort + '/' + (process.env.ORACLE_SID || 'orclpdb.ad.infosys.com') + 'connectString': oracleHost + ':' + oraclePort + '/' + oracleSID }; -var userName = process.env.CI_PROJECT_NAMESPACE.toUpperCase() + '-' + (process.env.CI_PROJECT_NAME || 'oecloud').toUpperCase(); -var password = process.env.CI_PROJECT_NAMESPACE.toLowerCase(); +var namespace = process.env.CI_PROJECT_NAMESPACE ? process.env.CI_PROJECT_NAMESPACE.replace(/[^a-zA-Z0-9]/g, '') : 'oecloudio'; +var name = process.env.CI_PROJECT_NAME ? process.env.CI_PROJECT_NAME.replace(/[^a-zA-Z0-9]/g, '') : 'oecloud'; + +var userName = namespace.toUpperCase() + '_' + name.toUpperCase(); +var password = namespace.toLowerCase(); var grants = [ 'CREATE VIEW', @@ -44,30 +51,32 @@ var grants = [ ]; function createUser(connection, cb) { - var sql = 'alter session set "_ORACLE_SCRIPT"=true'; - connection.execute(sql, function (e, r) { - if (e) { - console.error('Ignoring error of alter session. UserName : ' + userName + ' Error :' + e); + var alterSQL = 'alter session set "_ORACLE_SCRIPT"=true'; + connection.execute(alterSQL, function (alterErr, alterRes) { + if (alterErr) { + console.error('Ignoring error of alter session. UserName : ' + userName + ' Error :' + alterErr); } - console.log(sql, ' ......... ok'); - var sql = 'CREATE USER "' + userName + '" IDENTIFIED BY ' + password; + console.log(alterSQL, ' ......... ok'); - connection.execute(sql, function (err, result) { - if (err) { - throw new Error('Unable to create user ' + userName + ' Error :' + err); + var createUserSQL = 'CREATE USER "' + userName + '" IDENTIFIED BY ' + password; + connection.execute(createUserSQL, function (createErr, createRes) { + if (createErr) { + console.error(createErr); + throw new Error('Unable to create user ' + userName); } - console.log(sql, ' ......... ok'); - async.each(grants, function (g, callback) { - var sql = 'GRANT ' + g + ' to "' + userName + '"'; + console.log(createUserSQL, ' ......... ok'); - connection.execute(sql, function (err2, result2) { - if (err2) { - throw new Error('Unable to execute grant ' + sql); + async.each(grants, function (g, callback) { + var grantSQL = 'GRANT ' + g + ' to "' + userName + '"'; + connection.execute(grantSQL, function (grantErr, grantRes) { + if (grantErr) { + console.error(grantErr); + throw new Error('Unable to execute grant ' + grantSQL); } - console.log(sql, ' ......... ok'); + console.log(grantSQL, ' ......... ok'); return callback(); }); - }, function (err) { + }, function (grantAsyncErr) { console.log('User ' + userName + ' Created successfully'); return cb(); }); @@ -75,78 +84,83 @@ function createUser(connection, cb) { }); } - function dropTables(cb) { - var oracleConnectSettings2 = Object.assign({}, oracleConnectSettings); - oracleConnectSettings2.user = userName; - oracleConnectSettings2.password = password; - - oracledb.getConnection( - oracleConnectSettings2, - function (err, connection) { - if (err) { - throw new Error('Unable to connect to Oracle Database ' + JSON.stringify(oracleConnectSettings)); + var oracleUserConnectSettings = { + 'password': password, + 'user': userName, + 'connectString': oracleHost + ':' + oraclePort + '/' + oracleSID + }; + + oracledb.getConnection(oracleUserConnectSettings, function (userConnectionErr, connection) { + if (userConnectionErr) { + console.error(userConnectionErr); + throw new Error('Unable to connect to Oracle Database ' + JSON.stringify(oracleUserConnectSettings)); + } + + var totalRows = 1000; + var selectDropTableSQL = "select 'drop table \"' || table_name || '\"' from all_tables where owner = '" + userName + "'"; + connection.execute(selectDropTableSQL, {}, { maxRows: totalRows }, function (selectDropErr, selectDropRes) { + if (selectDropErr) { + console.error(selectDropErr); + throw new Error('Unable to find tables ' + userName); } - var sql = "select 'drop table \"' || table_name || '\"' from all_tables where owner = '" + userName + "'"; - var totalRows = 1000; - connection.execute(sql, {}, {maxRows: totalRows}, function (err, result) { - if (err) { - throw new Error('Unable to find tables ' + userName + ' Error :' + err); - } - connection.execute(sql, {}, {maxRows: totalRows}, function (err2, result2) { - if (err2) { - throw new Error('Unable to execute droping of table ' + sql); - } - if (!result2 || !result2.rows || result2.rows.length === 0) { - return cb(); + if (!selectDropRes || !selectDropRes.rows || selectDropRes.rows.length === 0) { + return cb(); + } + + async.each(selectDropRes.rows, function (row, callback) { + var dropTableSQL = row[0]; + connection.execute(dropTableSQL, function (dropTableErr, dropTableRes) { + if (dropTableErr) { + console.error(dropTableErr); + throw new Error('Unable to drop table\nSQL: ' + sql); } - async.each(result2.rows, function (row, callback) { - var sql = row[0]; - connection.execute(sql, function (err2, result2) { - if (err2) { - throw new Error('Unable to drop table\nERROR : ' + err2 + '\nSQL : ' + sql); - } - console.log(sql, ' ......... ok'); - return callback(); - }); - }, function (err) { - console.log('Tables of user ' + userName + ' dropped successfully'); - return cb(); - }); + console.log(dropTableSQL, ' ......... ok'); + return callback(); }); + }, function (dropAsyncErr) { + console.log('Tables of user ' + userName + ' dropped successfully'); + return cb(); }); }); + }); } -oracledb.getConnection( - oracleConnectSettings, - function (err, connection) { +function generateUserBundle() { + console.log("Generating oracle user details shell script"); + fs.writeFileSync('./oracle-user.sh', '#!/bin/sh' + os.EOL); + fs.appendFileSync('./oracle-user.sh', 'export ORACLE_USERNAME=' + userName + os.EOL); + fs.appendFileSync('./oracle-user.sh', 'export ORACLE_PASSWORD=' + password + os.EOL); +} + +oracledb.getConnection(oracleConnectSettings, function (connectionErr, connection) { + if (connectionErr) { + console.error(connectionErr); + throw new Error('Unable to connect to Oracle Database ' + JSON.stringify(oracleConnectSettings)); + } + var sql = "select username, user_id from dba_users where username = '" + userName + "'"; + console.log(sql); + connection.execute(sql, function (err, result) { if (err) { - throw new Error('Unable to connect to Oracle Database ' + JSON.stringify(oracleConnectSettings)); + console.error(err); return; } - var sql = "select username, user_id from dba_users where username = '" + userName + "'"; - console.log(sql); - connection.execute(sql, - function (err, result) { + if (!result.rows || result.rows.length == 0) { + createUser(connection, function (err) { if (err) { - console.error(err); return; + return process.exit(1); } - if (!result.rows || result.rows.length == 0) { - createUser(connection, function (err) { - if (err) { - return process.exit(1); - } - return process.exit(); - }); - } else { - dropTables(function (err) { - if (err) { - return process.exit(1); - } - return process.exit(); - }); + generateUserBundle(); + return process.exit(); + }); + } else { + dropTables(function (err) { + if (err) { + return process.exit(1); } + generateUserBundle(); + return process.exit(); }); + } }); - +}); diff --git a/test/providers.json b/test/providers.json index d8e4a76..c6b8e7e 100644 --- a/test/providers.json +++ b/test/providers.json @@ -2,117 +2,17 @@ "local": { "provider": "local", "module": "passport-local", - "usernameField": "username", - "passwordField": "password", + "usernameField": "${userfieldname}", + "passwordField": "${PASSWORD_FIELD_NAME}", "authPath": "/auth/local", - "successRedirect": "/explorer", - "failureRedirect": "/", + "successRedirect": "/info", + "failureRedirect": "/failed", "failureFlash": false, "callbackHTTPMethod": "post", - "setAccessToken": true - }, - "ldap": { - "provider": "ldap", - "authScheme":"ldap", - "module": "passport-ldapauth", - "authPath": "/auth/ldap", - "successRedirect": "/auth/account", - "failureRedirect": "/ldap", - "session": true, - "failureFlash": true, - "profileAttributesFromLDAP": { - "login": "uid", - "username": "uid", - "displayName": "displayName", - "email": "mail", - "externalId": "uid" - }, - "server":{ - "url": "ldap://ldap-server:1234", - "searchBase": "dc=domain,dc=fr", - "searchFilter": "(cn={{username}})" - } - }, - "facebook-login": { - "provider": "facebook", - "module": "passport-facebook", - "profileFields": ["gender", "link", "locale", "name", "timezone", - "verified", "email", "updated_time"], - "clientID": "{facebook-client-id-1}", - "clientSecret": "{facebook-client-secret-1}", - "callbackURL": "/auth/facebook/callback", - "authPath": "/auth/facebook", - "callbackPath": "/auth/facebook/callback", - "successRedirect": "/auth/account", - "failureRedirect": "/login", - "scope": ["email"], - "failureFlash": true - }, - "google-login": { - "provider": "google", - "module": "passport-google-oauth", - "strategy": "OAuth2Strategy", - "clientID": "{google-client-id-1}", - "clientSecret": "{google-client-secret-1}", - "callbackURL": "/auth/google/callback", - "authPath": "/auth/google", - "callbackPath": "/auth/google/callback", - "successRedirect": "/auth/account", - "failureRedirect": "/login", - "scope": ["email", "profile"], - "failureFlash": true - }, - "twitter-login": { - "provider": "twitter", - "authScheme": "oauth", - "module": "passport-twitter", - "callbackURL": "/auth/twitter/callback", - "authPath": "/auth/twitter", - "callbackPath": "/auth/twitter/callback", - "successRedirect": "/auth/account", - "failureRedirect": "/login", - "consumerKey": "{twitter-consumer-key}", - "consumerSecret": "{twitter-consumer-secret}", - "failureFlash": true - }, - "facebook-link": { - "provider": "facebook", - "module": "passport-facebook", - "clientID": "{facebook-client-id-2}", - "clientSecret": "{facebook-client-secret-2}", - "callbackURL": "/link/facebook/callback", - "authPath": "/link/facebook", - "callbackPath": "/link/facebook/callback", - "successRedirect": "/auth/account", - "failureRedirect": "/login", - "scope": ["email", "user_likes"], - "link": true, - "failureFlash": true - }, - "google-link": { - "provider": "google", - "module": "passport-google-oauth", - "strategy": "OAuth2Strategy", - "clientID": "{google-client-id-2}", - "clientSecret": "{google-client-secret-2}", - "callbackURL": "/link/google/callback", - "authPath": "/link/google", - "callbackPath": "/link/google/callback", - "successRedirect": "/auth/account", - "failureRedirect": "/login", - "scope": ["email", "profile"], - "link": true, - "failureFlash": true + "setAccessToken": true, + "session": false, + "forceDefaultCallback": true, + "cookie": true, + "json": true } - - - - - - - - - - - } diff --git a/test/server.js b/test/server.js index 34111d7..213fa1a 100644 --- a/test/server.js +++ b/test/server.js @@ -10,6 +10,13 @@ var oecloud = require('oe-cloud'); oecloud.observe('loaded', function (ctx, next) { return next(); }); +oecloud.get('/info', function (req, res) { + return res.end(JSON.stringify({'status': 'logged in', 'access-token': req.accessToken})); +}); + +oecloud.get('/failed', function (req, res) { + return res.end(JSON.stringify({'status': 'failed'})); +}); oecloud.boot(__dirname, function (err) { oecloud.start(); diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 75af11c..0000000 --- a/test/test.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * - * 2018-2019 EdgeVerve Systems Limited (a fully owned Infosys subsidiary), - * Bangalore, India. All Rights Reserved. - * - */ - -// Author : Atul -var oecloud = require('oe-cloud'); - -oecloud.observe('loaded', function (ctx, next) { - return next(); -}) - -oecloud.boot(__dirname, function (err) { - if (err) { - console.log(err); - process.exit(1); - } - var loopback = require('loopback'); - oecloud.start(); - oecloud.emit('test-start'); -}); - -describe('Oe Passport Component Test Started', function () { - this.timeout(15000); - it('Waiting for application to start', function (done) { - oecloud.on('test-start', function () { - done(); - }); - }); -}); - - -