
/**
 * Module dependencies
 */
var cU = require('../../assets/lib/common-utilities')
  , mongoose = require('mongoose')
  , msg = require('../../config/messages')
  , Q = require('q')
  , _ = require('underscore');

/**
 * Models
 */
var User = mongoose.model('User');

/**
 * Index
 * GET /api/users
 */
exports.index = function *(next) {
  var users = yield Q.ninvoke(User, 'find');
  this.body = yield cU.censor(users, ['_id', '__v', 'hash', 'salt']);
}

/**
 * Show
 * GET /api/users/:username
 */
exports.show = function *(next) {
  var user = yield Q.ninvoke(User, 'findOne', { username: this.params.username });
  if (!user) return yield next; // 404 Not Found
  this.body = yield cU.censor(user, ['_id', '__v', 'hash', 'salt']);
}

/**
 * Create
 * POST /api/users
 */
exports.create = function *(next) {
  var user = new User(this.request.body);
  yield Q.ninvoke(user, 'save');
  this.user = user;
  this.session.user = user.id; // Serialize user to session
  this.status = 201; // 201 Created
  this.body = yield cU.created('user', user, user.username);
}

/**
 * Update
 * PUT /api/users/:username
 */
exports.update = function *(next) {
  var user = yield Q.ninvoke(User, 'findOne', { username: this.params.username });
  if (!user) return yield next; // 404 Not Found
  user = _.extend(user, this.request.body);
  yield Q.ninvoke(user, 'save');
  this.body = yield cU.updated('user', user, user.username);
}

/**
 * Destroy
 * DELETE /api/users/:username
 */
exports.destroy = function *(next) {
  var user = yield Q.ninvoke(User, 'findOneAndRemove', { username: this.params.username });
  if (!user) return yield next; // 404 Not Found
  this.session = {};
  this.body = yield cU.deleted('user', user, user.username);
}

/*------------------------------------*\
    Images
\*------------------------------------*/

exports.images = {

  /**
   * CREATE
   * POST /api/users/:username/image
   */
  create: function *(next) {
    var user = yield Q.ninvoke(User, 'findOne', { username: this.params.username });
    if (!user) return yield next; // 404 Not Found
    if (this.req.files.file) user.images = [ this.req.files.file ];
    yield Q.ninvoke(user, 'save');
    var readStream = this.req.files.file.path;
    console.log(this.req.files);
    yield next;
  },

  /**
   * DESTROY
   * DELETE /api/users/:username/image
   */
  destroy: function *(next) {
    yield next;
  }
}

/*------------------------------------*\
    Authentication / Session
\*------------------------------------*/

/**
 * Sign in
 * POST /api/users/sign-in
 */
exports.authenticate = function *(next) {
  var msgJSONArray = [];
  if (typeof this.request.body.username === 'undefined') msgJSONArray.push(cU.msg(msg.username.isNull, 'validation', 'username'));
  if (typeof this.request.body.password === 'undefined') msgJSONArray.push(cU.msg(msg.password.isNull, 'validation', 'password'));
  if (msgJSONArray.length > 0) {
    this.status = 422; // 422 Unprocessable Entity
    this.body = yield cU.body(msgJSONArray);
    return;
  }
  var user = yield Q.ninvoke(User, 'findOne', { username: this.request.body.username });
  if (!user) {
    this.status = 401; // 401 Unauthorized
    this.body = yield cU.body(cU.msg(msg.authentication.incorrect.user(this.request.body.username), 'authentication', 'user'));
    return;
  }
  if (!user.authenticate(this.request.body.password, user.salt)) {
    this.status = 401; // 401 Unauthorized
    this.body = yield cU.body(cU.msg(msg.authentication.incorrect.password, 'authentication', 'user'));
    return;
  }
  this.user = user;
  this.session.user = user.id; // Serialize user to session
  this.status = 201; // 201 Created
  this.body = yield cU.body(cU.msg(msg.authentication.success(user.username), 'success', 'user', cU.censor(user, ['_id', '__v', 'hash', 'salt']))); // 201 Created
}

/**
 * Deserialize user from session
 * Make available to app as this.user
 */
exports.session = function () {
  return function *(next) {

    // deserialize user from session
    if (this.session.user && !this.user) {
      try {
        this.user = yield Q.ninvoke(User, 'findById', this.session.user);
      } catch (err) {
        console.failure('There was an error while trying to deserialize session user', { id: this.session.user }, err.stack);
      }
    }
    yield next;

    // populate cookie for frontend -- presence of this cookie does not grant authenticated access on backend
    if (this.user) {
      this.cookies.set('auth', JSON.stringify({ isAuthenticated: true, username: this.user.username }), { httpOnly: false, overwrite: true });
    } else {
      this.cookies.set('auth', JSON.stringify({ isAuthenticated: false }), { httpOnly: false, overwrite: true });
    }
  }
}

/**
 * Sign out
 * DELETE /api/users/sign-out
 */
exports.signOut = function *(next) {
  this.user = null;
  this.session = null;
  this.body = yield cU.body(cU.msg('logout'));
}

@@ -260,24 +260,129 @@
 l('User');%0A%0A
+/**%0A * Mongo exclude paramater%0A */%0Avar exclude = %7B _id: 0, __v: 0, hash: 0, salt: 0, 'images._id': 0 %7D;%0A%0A
 /**%0A * Index
@@ -445,17 +445,17 @@
 %7B%0A  
-var users
+this.body
  = y
@@ -485,78 +485,21 @@
 ind'
-);%0A  this.body = yield cU.censor(users, %5B'_id', '__v', 'hash', 'salt'%5D
+, %7B%7D, exclude
 );%0A%7D

simplify users controller