Giter VIP home page Giter VIP logo

http-users's Introduction

Framework components for node.js and the browser

Example HTTP Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http);

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example HTTPS Server:

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.http, {
  https: {
    cert: 'path/to/cert.pem',
    key: 'path/to/key.pem',
    ca: 'path/to/ca.pem'
  }
});

app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

app.start(8080);

Example CLI Application:

// example.js

var flatiron = require('flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: __dirname,
  usage: [
    'This is a basic flatiron cli application example!',
    '',
    'hello - say hello to somebody.'
  ]
});

app.cmd('hello', function () {
  app.prompt.get('name', function (err, result) {
    app.log.info('hello '+result.name+'!');
  })
})

app.start();

Run It:

% node example.js hello
prompt: name: world
info:   hello world!

Installation

Installing NPM (Node Package Manager)

  curl http://npmjs.org/install.sh | sh

Installing Flatiron

  [sudo] npm install flatiron

Installing Union (Required for flatiron.plugins.http)

  npm install union

Usage:

Start With flatiron.app:

flatiron.app is a broadway injection container. To be brief, what it does is allow plugins to modify the app object directly:

var flatiron = require('flatiron'),
    app = flatiron.app;

var hello = {
  attach: function (options) {
    this.hello = options.message || 'Why hello!';
  }
};

app.use(hello, {
  message: "Hi! How are you?"
});

// Will print, "Hi! How are you?"
console.log(app.hello);

Virtually all additional functionality in flatiron comes from broadway plugins, such as flatiron.plugins.http and flatiron.plugins.cli.

app.config

flatiron.app comes with a config plugin pre-loaded, which adds configuration management courtesy nconf. app.config has the same api as the nconf object.

The literal store is configured by default. If you want to use different stores you can easily attach them to the app.config instance.

// add the `env` store to the config
app.config.use('env');

// add the `file` store the the config
app.config.use('file', { file: 'path/to/config.json' });

// or using an alternate syntax
app.config.env().file({ file: 'path/to/config.json' });

// and removing stores
app.config.remove('literal');

app.log

flatiron.app will also load a log plugin during the init phase, which attaches a winston container to app.log. This logger is configured by combining the app.options.log property with the configuration retrieved from app.config.get('log').

Create An HTTP Server with flatiron.plugins.http(options):

This plugin adds http serving functionality to your flatiron app by attaching the following properties and methods:

Define Routes with app.router:

This is a director router configured to route http requests after the middlewares in app.http.before are applied. Example routes include:

// GET /
app.router.get('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.end('Hello world!\n');
});

// POST to /
app.router.post('/', function () {
  this.res.writeHead(200, { 'Content-Type': 'text/plain' });
  this.res.write('Hey, you posted some cool data!\n');
  this.res.end(util.inspect(this.req.body, true, 2, true) + '\n');
});

// Parameterized routes
app.router.get('/sandwich/:type', function (type) {
  if (~['bacon', 'burger'].indexOf(type)) {
    this.res.writeHead(200, { 'Content-Type': 'text/plain' });
    this.res.end('Serving ' + type + ' sandwich!\n');
  }
  else {
    this.res.writeHead(404, { 'Content-Type': 'text/plain' });
    this.res.end('No such sandwich, sorry!\n');
  }
});

app.router can also route against regular expressions and more! To learn more about director's advanced functionality, visit director's project page.

Access The Server with app.server:

This is a union middleware kernel.

Modify the Server Options with app.http:

This object contains options that are passed to the union server, including app.http.before, app.http.after and app.http.headers.

These properties may be set by passing them through as options:

app.use(flatiron.plugins.http, {
  before: [],
  after: []
});

You can read more about these options on the union project page.

Start The Server with app.start(port, <host>, <callback(err)>)

This method will both call app.init (which will call any asynchronous initialization steps on loaded plugins) and start the http server with the given arguments. For example, the following will start your flatiron http server on port 8080:

app.start(8080);

Create a CLI Application with flatiron.plugins.cli(options)

This plugin turns your app into a cli application framework. For example, [jitsu] (https://github.com/nodejitsu/jitsu) uses flatiron and the cli plugin.

Valid options include:

{
  "argvOptions": {}, // A configuration hash passed to the cli argv parser.
  "usage": [ "foo", "bar" ], // A message to show for cli usage. Joins arrays with `\n`.
  "dir": require('path').join(__dirname, 'lib', 'commands'), // A directory with commands to lazy-load
  "notFoundUsage": false // Disable help messages when command not found
}

Add lazy-loaded CLI commands with options.dir and app.commands:

Flatiron CLI will automatically lazy-load modules defining commands in the directory specified by options.dir. For example:

// example2.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  dir: path.join(__dirname, 'cmds')
});

app.start();
// cmd/highfive.js
var highfive = module.exports = function highfive (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

In the command, you expose a function of arguments and a callback. this is set to app, and the routing is taken care of automatically.

Here it is in action:

% node example2.js highfive Flatiron 
info:   High five to Flatiron!

You can also define these commands by adding them directly to app.commands yourself:

// example2b.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  cb(null);
};

app.start();
% node example2b.js highfive Flatiron 
info:   High five to Flatiron!

Callback will always be the last argument provided to a function assigned to command

app.commands.highfive = function (person, cb) {
  this.log.info('High five to ' + person + '!');
  console.log(arguments);
}
% node example2b.js highfive Flatiron lol haha
info:    High five to Flatiron!
{
  '0': 'Flatiron',
  '1': 'lol',
  '2': 'haha',
  '3': [Function]
}

Define Ad-Hoc Commands With app.cmd(path, handler):

This adds the cli routing path path to the app's CLI router, using the director route handler handler, aliasing app.router.on. cmd routes are defined the same way as http routes, except that it uses (a space) for a delimiter instead of /.

For example:

// example.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'usage: node test.js hello <person>',
    '',
    '  This will print "hello <person>"'
  ]
});

app.cmd('hello :person', function (person) {
  app.log.info('hello ' + person + '!');
});

app.start()

When you run this program correctly, it will say hello:

% node example.js hello person
info:   hello person!

If not, you get a friendly usage message:

% node test.js hello
help:   usage: node test.js hello <person>
help:
help:     This will print "hello <person>"

Check CLI Arguments with app.argv:

Once your app is started, app.argv will contain the optimist-parsed argv options hash, ready to go!

Here's an example:

// example3.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli);

app.start();

app.log.info(JSON.stringify(app.argv));

This prints:

% node example3.js
info:    {"_":[], "$0": "node ./example3.js"}

Awesome!

Add a Default Help Command with options.usage:

When attaching the CLI plugin, just specify options.usage to get a friendly default message for when there aren't any matching routes:

// example4.js
var flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    'Welcome to my app!',
    'Your command didn\'t do anything.',
    'This is expected.'
  ]
});

app.start();
% node example4.js 
help:   Welcome to my app!
help:   Your command didn't do anything.
help:   This is expected.

Start The Application with app.start(callback):

As seen in these examples, starting your app is as easy as app.start! this method takes a callback, which is called when an app.command completes. Here's a complete example demonstrating this behavior and how it integrates with options.usage:

// example5.js
var path = require('path'),
    flatiron = require('./lib/flatiron'),
    app = flatiron.app;

app.use(flatiron.plugins.cli, {
  usage: [
    '`node example5.js error`: Throws an error.',
    '`node example5.js friendly`: Does not throw an error.'
  ]
});

app.commands.error = function (cb) {
  cb(new Error('I\'m an error!'));
};

app.commands.friendly = function (cb) {
  cb(null);
}

app.start(function (err) {
  if (err) {
    app.log.error(err.message || 'You didn\'t call any commands!');
    app.log.warn('NOT OK.');
    return process.exit(1);
  }
  app.log.info('OK.');
});

Here's how our app behaves:

% node example5.js friendly
info:   OK.

% node example5.js error
error:  I'm an error!
warn:   NOT OK.

% node example5.js
help:   `node example2b.js error`: Throws an error.
help:   `node example2b.js friendly`: Does not throw an error.
error:  You didn't call any commands!
warn:   NOT OK.

Read More About Flatiron!

Articles

Sub-Projects

Tests

Tests are written in vows:

  $ npm test

License: MIT

http-users's People

Contributors

3rd-eden avatar avianflu avatar bmeck avatar chjj avatar cronopio avatar dscape avatar indexzero avatar jcrugzz avatar jfhbrook avatar marak avatar mmalecki avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

http-users's Issues

Password-salt mismatch suspected

When looking into a few reports on the "I cant log into the web-ui" issues, it was discovered that the users could not in fact authenticate to any of the api endpoints.

Further digging led me to suspect that there is a disconnect somewhere in what appears to be user creation that seems to make a salt value appear in the User doc (curl -u <user>:<pass> http://api.nodejitsu.com/users/<username>) that when a password is updated with a PUT (or jitsu users changepassword) the resulting password hash does not seem to use current password-salt of that user.

Decouple HTTP logic from User and Permission Resources.

Before a public release we should completely decouple the User and Permission resources from any HTTP specific logic.

The User and Permission resources should be part of a unified front / repository with other re-usable resources.

There is no reason this refactor should break any downstream dependencies.

Medium priority.

Inconsistent password restrictions

  1. Not allow blank passwords ( also see numer 3 )
  2. Allow special characters in passwords
  3. Implement minimal length of five chars and max length of 64 chars ( it's annoying to limit password length for people who use auto-generated passwords ).

This is not a mission critical ticket, but we should address it sometime soon.

Allow login with e-mail address

I've seen a lot of failed requests in our logs where users are trying to login with their e-mail account instead of using their username. It could be that they have forgotten their username or that they are just accustomed to logging in using an e-mail address as that's something that a lot of sites allow.

To decrease these login failures we should just support e-mail based logging in. There are 2 easy approaches in to fixing this:

  1. Use a regexp to check if the supplied username is a valid e-mail address and fetch the user resource based on e-mail adress.
  2. Just fallback to checking the e-mail address if account isn't found.

Move authorization and permission check logic from routing layer to resources

Currently the authorization logic for and permission check logic for Users and Permissions utilize Director's Router.before method to ensure there is no un-authorized access to any resources.

Instead of coupling the authorization and permission logic into one interface ( the http router ), we should move this code into the resource itself and utilize Resourceful's Resource.before method.

Any auth or permission errors would then be thrown back to the Router which would know how to delegate based on what Resource.before returns.

Sub-Ticket of #17

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.