Giter Club home page Giter Club logo

mustbe's Introduction

MustBe: Authorization Plumbing For NodeJS / Express Apps

MustBe is not a complete authorization framework, with roles and responsibilities and models and data access and everything that you need. Rather, it is the underlying plumbing that you need to secure your site. It allows you to fill in the necessary parts to manage data access, roles and users, and gives you the activity based plumbing to secure it all.

Authorization, Not Authentication

MustBe is an authorization system - the part of a security system that decides whether or not you are allowed to do something. This is the second of authentication and authorization, where authentication simply determines who you are.

Specifically, MustBe is an activity based authorization system. It allows you to verify that a user has permissions to perform any given activity in your application.

What Is Activity Based Authorization?

The gist of it is that you check whether or not a user has permission to perform an activity. How they get permission to do that activity is up to you. Maybe it's throug a role, maybe it's through data they have been assigned to. But the permission for the activity is what needs to be checked.

For more detail on this, check out my 2011 article on using activity based authorization checks. It will give you the core of what you need to know about whey role-based authorization checks are a bad idea, and why activity based permissions are the way to go.

Documentation

Detailed documentation about the configuration and use of MustBe can be found in the documentation folder.

Demo App

There is a small demo app located in the /demo folder of this repository. You can run the demo app by first installing the dependencies for mustbe with:

npm install

And then going in to the demo folder and running the following:

npm install

npm start

Now go to http://localhost:3000 and you will see a small demonstration of various MustBe features.

Getting Started

The first thing you need to do is install MustBe, and save it to your package.json file.

npm install --save mustbe

Configure Once In Your App

In your app.js (or whatever bootstraps your app), require the MustBe module, and also bring in a mustbe-config module which you will define in a moment.

Call the .config method on the mustBe object, and pass in the function that is exported from the config module.

// app.js

var mustBe = require("mustbe");
var mustBeConfig = require("./mustbe-config");
mustBe.configure(mustBeConfig);

Create The Configuration

Now you can create a mustbe-config.js file for your application. Having the config file separate from the app.js bootstrapper file helps to keep things clean.

Open the mustbe-config.js file and build your configuration. Provide configuration for your user identity, route helpers, activities and/or overrides.

Here is a basic configuration example from which you can start:

// ./mustbe-config.js
var mustBe = require("mustbe");
module.exports = function(config){

  config.routeHelpers(function(rh){
    // get the current user from the request object
    rh.getUser(function(req, cb){
      // return cb(err); if there is an error
      cb(null, req.user);
    });

    // what do we do when the user is not authorized?
    rh.notAuthorized(function(req, res, next){
      res.redirect("/login?msg=you are not authorized");
    });
  });

  config.activities(function(activities){
    // configure an activity with an authorization check
    activities.can("view thing", function(identity, params, cb){
      var id = params["id"];
      someLib.anotherThing(id, function(err, thing){
        if (err) { return cb(err); }
        var hasThing = !!thing;
        cb(null, hasThing);
      });
    });
  });

};

Now you can run the mustBe functions on your routes.

var mustbe = require("mustbe").routeHelpers();
var express = require("express");

var router = express.Router();
router.get("/:id", mustBe.authorized("view thing"), view);

function view(req, res, next){
  res.render("/something");
}

Be sure to read the full documentation, linked above, for the complete set of options and methods that can be called to configure and use MustBe.

MustBe is Copyright 2014 Muted Solutions, LLC. All Rights Reserved.

Distributed under MIT License.

mustbe's People

Contributors

cymen avatar foxandxss avatar justinchmura avatar loulin avatar melniker avatar micheee avatar secretfader avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mustbe's Issues

Parameter maps

I can't, for the life of me, seem to get the parameter maps to work.

Here's what I'm doing in my mustBe config

function authorizeEditBusiness(user, params, cb) {
  console.log(params); // Outputs "undefined" to the console
  cb(null, true);
}

config.parameterMaps(function(params){
  params.map({
    activity: "edit business",
    getParams: function(req){
      return { id: req["id"] }
      // I've even tried to return { id: 1 }
    }
  });
});

Any ideas? I'm using Express and Passport.

In case your wandering here's my entire mustbe.js config

'use strict';

// Module Dependencies
var mustBe = require('mustbe'),
  passport = require('passport'),
  _ = require('lodash');

module.exports = function(config) {
  // core config

  // Method for getting a user
  config.getUser(function(req, next) {
    passport.authenticate('bearer', { session: false }, function(err, user, info) {
      if (err) return next(err, null);
      return next(null, user);
    })(req, next);
  });

  // Is user authenticated
  config.isAuthenticated(function(user, cb) {
    cb(null, !!user);
  });

  // What to do when user is not authenticated
  config.notAuthenticated(function(req, res) {
    res.json(401, { message: 'Not authenticated' });
  });

  // What to do when user is not authorized to perform this action
  config.notAuthorized(function(req, res) {
    res.json(401, { message: 'Not authorized' });
  });

  // activity configuration
  config.activities(function(activities) {
    // 1) check if explicity denied
    // 2) if not explicitly denied, then check explicit allowance
    // 3) if not explicitly allowed, then check authorization

    activities.deny(function(user, activity, cb) {
      var isAnonymous = !user,
        isDenied = isAnonymous;

      cb(null, isAnonymous);
    });

    activities.allow(function(user, activity, cb) {
      var isAdmin = (_.indexOf(user.roles, 'admin') >= 0),
        isAllowed = isAdmin;

        cb(null, isAllowed);
    });

    activities.can('edit business', authorizeEditBusiness);
  });

  function authorizeEditBusiness(user, params, cb) {
    console.log(params);
    cb(null, true);
  }

  config.parameterMaps(function(params){

    params.map({
      activity: "edit business",
      getParams: function(req){
        return { id: req["id"] }
      }
    });
  });

};

Integrate with Apollo Data

First of all, thanks for all your work/sharing .. I have been following you for some time now. I think the idea behind mustBe its pretty cool and I would like to make it even more open. For example in my case i would like to call the authorization method from inside graphql resolvers. So no really a route because all graphql queries and mutations run form a single endpoint and also not really a middleware because I do not have enough data in the middleware to make a decision about authorization.

Basically what I would like to do is to call these methods from anywhere in my app. Do you think this would be a big change?

Error: Cannot find module 'rsvp'

Hi,

I am having trouble at npm start. I am facing

> [email protected] start /Users/siddharthsrivastava/Documents/sites/express/mustbe/demo
> node ./bin/www

module.js:338
throw err;
      ^
Error: Cannot find module 'rsvp'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/Users/siddharthsrivastava/Documents/sites/express/mustbe/mustbe/verifier/index.js:1:74)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)

npm ERR! Darwin 14.3.0 
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.4
npm ERR! npm  v2.10.1
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script 'node ./bin/www'.
npm ERR! This is most likely a problem with the mustbe-demo package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node ./bin/www
npm ERR! You can get their info via:
npm ERR!     npm owner ls mustbe-demo
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/siddharthsrivastava/Documents/sites/express/mustbe/demo/npm-debug.log

I tried installing rsvp module (npm install rsvp) but nothing. Also, tried clearing npm cache then also same.

Please guide.

Abandoned repo

Hi @derickbailey, I see the last commit is from 2015 and there are several PR waiting for your approval. We could advance the project if you named a contributor.

Community, any thoughts? What would be the most up to date fork?

cb ?

Hi,

What does 'cb' stand for in your code:
e.g. in:

config.userIdentity(function(id){

  // determine if this user is authenticated or not
  id.isAuthenticated(function(user, cb){
    // note that the "user" in this case, is the user
    // that was supplied by the routeHelpers.getUser function
    var isAuthenticated = false;
    if (user) {
      isAuthenticated = user.isLoggedIn();
    }
    cb(null, isAuthenticated);
  });

});

Thanks!

Flexible parameter injection

In our current project we have a lot of activities. We're currently looking into patching paramsFromRequest for our own version, so a parameter could be more easily injected into multiple activity handlers (i.e. check if the first argument of ParameterMap.prototype.map is an array of strings).

I'd just like to ask if you were willing to accept a PR for such a feature.

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.