Coder Social home page Coder Social logo

sails-multitenancy-example's Introduction

sails-multitenancy-example

Build Status

Sails with Multitenancy by using dynamically loaded Tenant-specific collections and their corresponding connections.

See Pull Requests:


Step 1

Generate a project

sails generate new sails-multitenancy-example

Step 2

Install sails-generate-auth:

npm install sails-generate-auth --save

Step 3

Generate the authentication source code:

sails generate auth

Add dependencies for Passport authentication

We will be using Passport with Passport-local strategy, for this example app.

npm install --save passport
npm install --save passport-local
npm install --save validator
npm install --save bcryptjs

Step 4

Configure for authentication. See https://github.com/kasperisager/sails-generate-auth#requirements

config/passport.js

Setup appropriate Passport providers.

config/bootstrap.js

Add following line:

sails.services.passport.loadStrategies();

config/policies.js

Add following line:

'*': [ 'passport' ]

config/routes.json

Add routes:

'get /login': 'AuthController.login',
'get /logout': 'AuthController.logout',
'get /register': 'AuthController.register',

'post /auth/local': 'AuthController.callback',
'post /auth/local/:action': 'AuthController.callback',

'get /auth/:provider': 'AuthController.provider',
'get /auth/:provider/callback': 'AuthController.callback',
'get /auth/:provider/:action': 'AuthController.callback',

config/models.js

If you see

Excuse my interruption, but it looks like this app
does not have a project-wide "migrate" setting configured yet.
(perhaps this is the first time you're lifting it with models?)

In short, this setting controls whether/how Sails will attempt to automatically
rebuild the tables/collections/sets/etc. in your database schema.
You can read more about the "migrate" setting here:
http://sailsjs.org/#/documentation/concepts/ORM/model-settings.html?q=migrate

In a production environment (NODE_ENV==="production") Sails always uses
migrate:"safe" to protect inadvertent deletion of your data.
However during development, you have a few other options for convenience:

1. safe  - never auto-migrate my database(s). I will do it myself (by hand)
2. alter - auto-migrate, but attempt to keep my existing data (experimental)
3. drop  - wipe/drop ALL my data and rebuild models every time I lift Sails

What would you like Sails to do?

info: To skip this prompt in the future, set `sails.config.models.migrate`.
info: (conventionally, this is done in `config/models.js`)

warn: ** DO NOT CHOOSE "2" or "3" IF YOU ARE WORKING WITH PRODUCTION DATA **

prompt: ?:

Setup migration, so the Sails warning does not appear, by adding the following line to config/models.js:

migrate: 'alter'

Step 5

Configure your connection to enable multitenancy.

In config file config/connections.js edit the connection, localDiskDb, which we are using for this app and add the following:

// === Multitenancy support ===
isMultiTenant: true, // Enable Multi-Tenancy feature
availableTenants: ['localhost:1337', 'tenant2'], // Tenants that pass validation
configForTenant: function(tenantId, config, cb) { // For Waterline
    // console.log('configForTenant', tenantId);
    // Validate Tenant
    if (config.availableTenants.indexOf(tenantId) !== -1) {
        // Tenant is allowed
        config.fileName = tenantId;
        return cb(null, config);
    } else {
        // Tenant is not allowed
        return cb(new Error("Invalid tenant " + tenantId + "!"));
    }
}

The config.availableTenants is only an example of how you may want to validate your Tenant requests. Feel free to change this to however you like, or not even validate at all!

Step 6

Since each tenant has their own User and Passport collections you must modify the original source code generated by sails-generate-auth.

Apply the .tenant API to each of the collections calls, User and Passport, in api/services/protocols/local.js.

For instance, User.find().exec() becomes User.tenant(req.session.tenant).find().exec(). Note the addition of .tenant(req.session.tenant) to the collection.

This will mean that those calls to User or Passport will now be scoped around the tenant as specified by req.session.tenant.

Step 7

Test that you can currently register and login.

Start Sails server

sails lift

Register

Go to http://localhost:1337/register

Example User:

Login

Go to http://localhost:1337/login and login with the same information you used to register above.

sails-multitenancy-example's People

Contributors

glavin001 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sails-multitenancy-example's Issues

Not working on sails-mongo

I try example with sails-mongo:
1.Install sails-mongo

sudo npm install sails-mongo

2.package.json

{
  "name": "sails-multitenancy-example",
  "private": true,
  "version": "0.0.0",
  "description": "a Sails application",
  "keywords": [],
  "dependencies": {
    "bcryptjs": "^2.1.0",
    "ejs": "~0.8.4",
    "grunt": "0.4.2",
    "grunt-contrib-clean": "~0.5.0",
    "grunt-contrib-coffee": "~0.10.1",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-copy": "~0.5.0",
    "grunt-contrib-cssmin": "~0.9.0",
    "grunt-contrib-jst": "~0.6.0",
    "grunt-contrib-less": "0.11.1",
    "grunt-contrib-uglify": "~0.4.0",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-sails-linker": "~0.9.5",
    "grunt-sync": "~0.0.4",
    "include-all": "~0.1.3",
    "passport": "^0.2.1",
    "passport-local": "^1.0.0",
    "rc": "~0.5.0",
    "sails": "git+https://github.com/Glavin001/sails.git",
    "sails-disk": "~0.10.0",
    "sails-generate-auth": "^0.2.0",
    "validator": "^3.27.0"
  },
  "scripts": {
    "start": "node app.js",
    "debug": "node debug app.js"
  },
  "main": "app.js",
  "repository": {
    "type": "git",
    "url": "git://github.com/glavin/sails-multitenancy-example2.git"
  },
  "author": "glavin",
  "license": ""
}

3.connection.js

someMongodbServer: {
    adapter: 'sails-mongo',
    host: 'localhost',
    port: 27017,
    // user: 'username',
    // password: 'password',
    // database: 'your_mongo_db_name_here'

    // === Multitenancy support ===
    isMultiTenant: true, // Enable Multi-Tenancy feature
    availableTenants: ['localhost:1337', 'tenant2', 'abc', 'xyz'], // Tenants that pass validation
    configForTenant: function(tenantId, config, cb) { // For Waterline
        // console.log('configForTenant', tenantId);
        // Validate Tenant
        if (config.availableTenants.indexOf(tenantId) !== -1) {
            // Tenant is allowed
            console.log(tenantId);
            config.fileName = tenantId;
            return cb(null, config);
        } else {
            // Tenant is not allowed
            return cb(new Error("Invalid tenant " + tenantId + "!"));
        }
    }
  },
  1. file policy tenant.js
module.exports = function(req, res, next) {
    var tenantId = req.headers.host;
    tenantId = tenantId.substring(0, tenantId.indexOf('.'));
    //tanantId = tenantId.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g,'');
    // Important: `req.session.tenant` is where you attach the tenant identifer
    req.session.tenant = tenantId;
    //console.log(req.session.tenant);
    // Policy complete, continue...
    next();
};

5.I use Nginx working reverse proxy mode for 2 host abc.xxx.com, xyz.xxx.com with config:

 location / {
            proxy_pass http://localhost:1337;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

Every things working ok, but database do not create and save, it not working.

Thanks you!

Cannot read property 'joins' of undefined

Hi you!

I made the following on my code:

 Game
    .tenant(req.session.tenant)
    .find({}).populate('developer').exec(function findCB(err,found){
        res.view({
          title: "Game Management",
          data : found,
          errors    : req.flash('error')
        });
    });

I get errors:

error: Sending 500 ("Server Error") response: 
 TypeError: Cannot read property 'joins' of undefined
    at _createParentOperation (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:255:15)
    at _stageOperations (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:171:39)
    at _buildOperations (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:153:21)
    at new module.exports (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/operations.js:40:26)
    at /Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/basic.js:252:26
    at /Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/collection/index.js:85:24
    at createTenantCollection (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/dql/tenant.js:85:20)
    at /Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/dql/tenant.js:123:18
    at bound.module.exports.connections.someMongodbServer.configForTenant (/Users/chipgata/Projects/ui-data-tracking/config/connections.js:75:20)
    at bound.module.exports (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/dql/tenant.js:68:23)
    at bound [as tenant] (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
    at bound.Collection._resolveCollection (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/collection/index.js:84:18)
    at bound [as _resolveCollection] (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
    at bound.module.exports.find (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/finders/basic.js:248:10)
    at bound [as find] (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
    at Deferred.exec (/Users/chipgata/Projects/ui-data-tracking/node_modules/sails/node_modules/waterline/lib/waterline/query/deferred.js:501:16) [TypeError: Cannot read property 'joins' of undefined]

Please tell me I'm wrong place

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.