mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-24 05:47:45 +08:00
Merge branch 'master' of github.com:Deployd/Deployd
This commit is contained in:
103
lib/app.js
103
lib/app.js
@@ -55,107 +55,4 @@ app.get('/routes', function(req, res) {
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
res.send({home: true});
|
||||
});
|
||||
|
||||
app.get('/config', function(req, res) {
|
||||
res.send({
|
||||
name: 'Hello World',
|
||||
host: 'foo.bar.com'
|
||||
})
|
||||
});
|
||||
|
||||
app.get('/models', function(req, res) {
|
||||
res.send({
|
||||
results: [{
|
||||
plugin: 'Users',
|
||||
name: 'Users',
|
||||
_id: 5432
|
||||
}]
|
||||
})
|
||||
});
|
||||
|
||||
app.get('/plugins', function(req, res) {
|
||||
res.send({
|
||||
results: [{
|
||||
name: 'Users',
|
||||
overview_html: '<p>The Users plugin lets you configure users...</p>',
|
||||
configurable_objects: [
|
||||
{
|
||||
name: "Roles and Permissions"
|
||||
, id: 1
|
||||
},
|
||||
{
|
||||
name: "Existing Users"
|
||||
, id: 2
|
||||
, list: "User List"
|
||||
, source: "/users"
|
||||
},
|
||||
{
|
||||
name: "Model",
|
||||
id: 3,
|
||||
model_description: {
|
||||
password:"password",
|
||||
uid:"email",
|
||||
removed:"boolean",
|
||||
name:"string",
|
||||
auth:"string"
|
||||
},
|
||||
plugin: "graph",
|
||||
_id: "4ec48fa3d1a11cd925000007"
|
||||
},
|
||||
{
|
||||
/*
|
||||
description: {
|
||||
uid: 'email',
|
||||
password: 'password',
|
||||
name: 'string',
|
||||
auth: 'string',
|
||||
removed: 'boolean'
|
||||
},
|
||||
|
||||
*/
|
||||
name: "New User"
|
||||
, id: 4
|
||||
, helper_text: "Fill out the form below to create a new user"
|
||||
, form: {
|
||||
action: "/user"
|
||||
, method: "POST"
|
||||
, fields: [
|
||||
{
|
||||
name: "name"
|
||||
, label: "Full Name"
|
||||
, type: "text"
|
||||
, required: true
|
||||
},
|
||||
{
|
||||
name: "uid"
|
||||
, label: "Email"
|
||||
, type: "email"
|
||||
, required: true
|
||||
},
|
||||
{
|
||||
name: "password"
|
||||
, label: "Password"
|
||||
, type: "password"
|
||||
, required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
_id: 1234
|
||||
},
|
||||
{
|
||||
name: "Phone",
|
||||
overview_html: '<p>The Phone plugin lets you configure phone stuff...</p>',
|
||||
configurable_objects: [
|
||||
{
|
||||
name: "Numbers"
|
||||
, id: 1
|
||||
}
|
||||
],
|
||||
|
||||
_id: 2345
|
||||
}]
|
||||
})
|
||||
});
|
||||
@@ -4,6 +4,8 @@ var Model = require('./model')
|
||||
|
||||
module.exports = Model.spawn({
|
||||
|
||||
isCollection: true,
|
||||
|
||||
initialize: function() {
|
||||
this.models = [];
|
||||
},
|
||||
@@ -47,6 +49,33 @@ module.exports = Model.spawn({
|
||||
this.models = changes;
|
||||
this.state = this._states.ready;
|
||||
this.emit('change:state');
|
||||
},
|
||||
|
||||
updateSettings: function() {
|
||||
// TODO, implement basic settings
|
||||
},
|
||||
|
||||
defineRoutes: function(app) {
|
||||
var collection = this.collection
|
||||
, model = this
|
||||
, plugin = this.plugin
|
||||
, base = (plugin === collection) ? '' : ('/' + plugin)
|
||||
, route = [base, collection].join('/')
|
||||
;
|
||||
|
||||
// one model
|
||||
app.get(route, function(req, res) {
|
||||
var query = req.query;
|
||||
|
||||
model
|
||||
.spawn()
|
||||
.for(req)
|
||||
.find(query)
|
||||
.set(req.body)
|
||||
.notify(res)
|
||||
.fetch()
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = {
|
||||
|
||||
find: ready(function(model) {
|
||||
var query = model.toQuery() || {}
|
||||
, id = model.get('_id')
|
||||
, id = model.get('_id') || (query && query._id)
|
||||
, _id = id && ObjectID(id)
|
||||
;
|
||||
|
||||
|
||||
68
lib/model.js
68
lib/model.js
@@ -9,6 +9,7 @@ var Model
|
||||
, db = require('./db')
|
||||
, compile = require('./types').compile
|
||||
, _ = require('underscore')
|
||||
, app = require('./app')
|
||||
;
|
||||
|
||||
var emitter = new EventEmitter();
|
||||
@@ -149,6 +150,7 @@ Model = module.exports = emitter.spawn({
|
||||
, actor = this.actor()
|
||||
, allowed = true
|
||||
, model = this
|
||||
, User = require('./plugins/users/user')
|
||||
;
|
||||
|
||||
if(requiresUser && !actor) {
|
||||
@@ -159,9 +161,9 @@ Model = module.exports = emitter.spawn({
|
||||
|
||||
if(permissions && rights && rights !== 'public') {
|
||||
// check permission against actor
|
||||
Model
|
||||
.spawn({collection: 'users', allowed: false})
|
||||
.set({_id: actor})
|
||||
User
|
||||
.spawn()
|
||||
.find({_id: actor})
|
||||
.notify(function(json) {
|
||||
// TODO cache groups on the req
|
||||
var groups = json.groups
|
||||
@@ -207,7 +209,7 @@ Model = module.exports = emitter.spawn({
|
||||
fn();
|
||||
},
|
||||
|
||||
for: function(req) {
|
||||
for: function(req) {
|
||||
if(req.session && req.session.user) {
|
||||
this.actor(req.session.user._id);
|
||||
}
|
||||
@@ -258,7 +260,7 @@ Model = module.exports = emitter.spawn({
|
||||
|
||||
set: function(changes) {
|
||||
var _self = this;
|
||||
|
||||
if(!changes) return this;
|
||||
Object.getOwnPropertyNames(changes).forEach(function(p) {
|
||||
if(_self.attributes[p] != changes[p]) {
|
||||
_self.attributes[p] = changes[p];
|
||||
@@ -347,7 +349,7 @@ Model = module.exports = emitter.spawn({
|
||||
return this;
|
||||
},
|
||||
|
||||
plugin: 'graph',
|
||||
plugin: 'models',
|
||||
|
||||
updateSettings: function() {
|
||||
var settings = Model.spawn()
|
||||
@@ -359,9 +361,8 @@ Model = module.exports = emitter.spawn({
|
||||
|
||||
if(this.description) {
|
||||
settings
|
||||
.find({name: this.name || this.collection, plugin: this.plugin})
|
||||
.find({collection: this.collection, plugin: this.plugin})
|
||||
.set({
|
||||
name: this.name || this.collection,
|
||||
description: this.description,
|
||||
plugin: this.plugin,
|
||||
collection: this.collection,
|
||||
@@ -394,12 +395,53 @@ Model = module.exports = emitter.spawn({
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
defineRoutes: function(app) {
|
||||
var collection = this.collection
|
||||
, model = this
|
||||
, plugin = this.plugin
|
||||
, base = (plugin === collection) ? '' : ('/' + plugin)
|
||||
, route = [base, collection].join('/')
|
||||
, idRoute = [route, ':id'].join('/')
|
||||
, methodMap = {
|
||||
GET: 'fetch',
|
||||
POST: 'save',
|
||||
PUT: 'save',
|
||||
DELETE: 'remove'
|
||||
}
|
||||
;
|
||||
|
||||
function handler(req, res) {
|
||||
var query = req.params
|
||||
, action = methodMap[req.method] || 'fetch'
|
||||
;
|
||||
|
||||
model
|
||||
.spawn()
|
||||
.for(req)
|
||||
.find(query)
|
||||
.set(req.body)
|
||||
.notify(res)
|
||||
[action]()
|
||||
;
|
||||
}
|
||||
|
||||
// create
|
||||
app.post(route, handler);
|
||||
// read
|
||||
app.get(idRoute, handler);
|
||||
// update
|
||||
app.put(idRoute, handler);
|
||||
// delete
|
||||
app.del(idRoute, handler);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var spawn = module.exports.spawn
|
||||
, _models = {}
|
||||
, _collections = {}
|
||||
;
|
||||
|
||||
module.exports.refreshSettings = function(collection) {
|
||||
@@ -407,10 +449,14 @@ module.exports.refreshSettings = function(collection) {
|
||||
}
|
||||
|
||||
module.exports.spawn = function(model) {
|
||||
var instance = spawn.apply(this, arguments);
|
||||
if(model && model.collection) {
|
||||
_models[instance.collection] = instance;
|
||||
var instance = spawn.apply(this, arguments)
|
||||
, cache = instance.isCollection ? _collections : _models;
|
||||
|
||||
if(model && model.collection && !cache[instance.collection]) {
|
||||
cache[instance.collection] = instance;
|
||||
instance.updateSettings();
|
||||
instance.defineRoutes(app);
|
||||
}
|
||||
|
||||
return instance;
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
var Model = require('../../model');
|
||||
|
||||
module.exports = Model.spawn({
|
||||
|
||||
collection: 'apps',
|
||||
plugin: 'app',
|
||||
|
||||
description: {
|
||||
name: {type: 'string', unique: true},
|
||||
creator: 'string',
|
||||
db: 'string',
|
||||
host: 'string'
|
||||
},
|
||||
|
||||
allowed: {
|
||||
read: 'creator',
|
||||
write: 'creator',
|
||||
remove: 'creator',
|
||||
create: 'user'
|
||||
},
|
||||
|
||||
save: function() {
|
||||
var name = this.get('name')
|
||||
, host = this.toHostName()
|
||||
, creator = this.get('creator')
|
||||
;
|
||||
|
||||
if(!creator) this.error('Must be logged in to create an app.', 'App');
|
||||
|
||||
if(host && creator) {
|
||||
if(this.isNew()) {
|
||||
this.set({name: name, host: host, db: this.toDatabaseName(), creator: creator});
|
||||
} else {
|
||||
this.restart(host);
|
||||
}
|
||||
}
|
||||
|
||||
Model.save.apply(this, arguments);
|
||||
},
|
||||
|
||||
toHostName: function() {
|
||||
var name = this.get('name')
|
||||
, app = name && name.replace(/ /g, '-')
|
||||
, creator = this.get('creator')
|
||||
;
|
||||
|
||||
return app.toLowerCase();
|
||||
},
|
||||
|
||||
toDatabaseName: function() {
|
||||
return this.toHostName().replace(/\./g, ':').toLowerCase();
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
var Collection = require('../../collection')
|
||||
, App = require('./app')
|
||||
;
|
||||
|
||||
module.exports = Collection.spawn({
|
||||
collection: 'apps',
|
||||
model: App
|
||||
});
|
||||
@@ -1,74 +0,0 @@
|
||||
// Balancer tells requests where to go
|
||||
// - If a internal host (ihost) is not found within its cache, it boots a deployd
|
||||
// app at a new ihost and saves this location to the central deployd db
|
||||
// - Subsequent requests should be mapped from host to ihost and routed
|
||||
|
||||
var bouncy = require('bouncy')
|
||||
, apps = {}
|
||||
, exec = require('child_process').exec
|
||||
, ERROR = '<h1>Not Found</h1>There is no app configured to listen to this host. Perhaps you mistyped the url?\n'
|
||||
, App = require('./app')
|
||||
;
|
||||
|
||||
bouncy(function (req, bounce) {
|
||||
var host = req.headers.host
|
||||
, app = App.spawn()
|
||||
;
|
||||
|
||||
if(apps[host]) {
|
||||
bounce(apps[host].ihost || currentHost(), apps[host].port);
|
||||
return;
|
||||
}
|
||||
|
||||
app.query = {host: host.replace('.deploydapp.com', '')};
|
||||
app
|
||||
.notify(function(json) {
|
||||
apps[host] = json;
|
||||
if(json.ihost && json.port) {
|
||||
bounce(app.ihost, json.port);
|
||||
} else if(json._id) {
|
||||
// app exists, but not on any internal hosts
|
||||
// set the internal host to the machine that spawned it
|
||||
json.ihost = currentHost();
|
||||
json.port = nextPort();
|
||||
|
||||
console.log(['deployd', "'" + JSON.stringify(json) + "'"].join(' '));
|
||||
|
||||
// then boot
|
||||
var d = exec(['deployd', "'" + JSON.stringify(json) + "'"].join(' '));
|
||||
|
||||
d.stdout
|
||||
.on('data', function(data) {
|
||||
console.log(data.toString());
|
||||
if(data.toString().indexOf('listening') > -1) {
|
||||
bounce(json.port);
|
||||
}
|
||||
});
|
||||
|
||||
d.stderr.on('data', function(data) {
|
||||
console.log(data.toString());
|
||||
});
|
||||
|
||||
|
||||
app.set(json).save();
|
||||
} else {
|
||||
var res = bounce.respond();
|
||||
res.writeHead(500, {
|
||||
'Content-Length': ERROR.length,
|
||||
'Content-Type': 'text/html'
|
||||
});
|
||||
res.end(ERROR);
|
||||
}
|
||||
})
|
||||
.fetch()
|
||||
;
|
||||
}).listen(80);
|
||||
|
||||
function nextPort() {
|
||||
process.last = (3001 || process.last);
|
||||
return process.last++;
|
||||
}
|
||||
|
||||
function currentHost() {
|
||||
return 'localhost';
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
var app = require('../../app')
|
||||
, App = require('./app')
|
||||
;
|
||||
|
||||
if(process.argv.length < 3) {
|
||||
require('./balancer');
|
||||
}
|
||||
|
||||
app.post('/app', function(req, res) {
|
||||
var session = req.session
|
||||
, me = session && session.user && session.user.email
|
||||
;
|
||||
|
||||
App
|
||||
.spawn()
|
||||
.for(req)
|
||||
.set({name: req.param('name'), creator: me})
|
||||
.notify(res)
|
||||
.save()
|
||||
;
|
||||
});
|
||||
|
||||
app.get('/app/:id', function(req, res) {
|
||||
App
|
||||
.spawn()
|
||||
.for(req)
|
||||
.set({_id: req.param('id')})
|
||||
.notify(res)
|
||||
.fetch()
|
||||
;
|
||||
});
|
||||
|
||||
app.del('/app/:id', function(req, res) {
|
||||
App
|
||||
.spawn()
|
||||
.for(req)
|
||||
.notify(res)
|
||||
.remove()
|
||||
;
|
||||
});
|
||||
|
||||
// views
|
||||
app.get('/my/apps', function(req, res) {
|
||||
res.render(__dirname + '/views/index.ejs');
|
||||
});
|
||||
|
||||
app.get('/login', function(req, res) {
|
||||
res.render(__dirname + '/views/login.ejs');
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
<div class="authed">
|
||||
<h2>My Apps</h2>
|
||||
<h3>alpha!</h3>
|
||||
<ul id="apps">
|
||||
</ul>
|
||||
<h4>Create an app...</h4>
|
||||
<input type="text" id="name" />
|
||||
<button id="create">create new</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
d('/search/apps', {creator: 'skawful@gmail.com'}, function(res) {
|
||||
$.each(res.results, function(i, item) {
|
||||
$('#apps').append(
|
||||
$('<li />').text(item.name + ' @ ' + item.host + '.deploydapp.com')
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
$('#create').click(function() {
|
||||
var name = $('#name').val();
|
||||
d('/app', {name: name}, function(res) {
|
||||
console.log(res);
|
||||
if(res._id) window.location.reload();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>index</title>
|
||||
<meta name="generator" content="TextMate http://macromates.com/">
|
||||
<meta name="author" content="ritchie">
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
|
||||
<script src="/deployd.js"></script>
|
||||
<script src="/libs/jquery.cookie.js"></script>
|
||||
<style>
|
||||
.authed, .not-authed {display: none;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Deployd</h1>
|
||||
<%- body %>
|
||||
<script>
|
||||
var active = $.cookie('deployd.sid') ? '.authed' : '.not-authed';
|
||||
console.log(active);
|
||||
$(active).show();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,37 +0,0 @@
|
||||
<div id="login-form">
|
||||
Username
|
||||
<input id="uid" type="text" />
|
||||
Password
|
||||
<input id="password" type="password" />
|
||||
<button id="login">login</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
d('/me', function(res) {
|
||||
if(res && res.uid)
|
||||
$('#login-form').html('Logged in as ' + res.uid);
|
||||
})
|
||||
|
||||
$('#login').click(function() {
|
||||
var info = {
|
||||
email: $('#uid').val(),
|
||||
password: $('#password').val()
|
||||
};
|
||||
|
||||
d('/user/login', info, function(res) {
|
||||
if(res.auth) {
|
||||
window.location = '/my/apps';
|
||||
} else {
|
||||
alert('login failed...');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#logout').click(function() {
|
||||
d('/user/logout', function() {
|
||||
window.location.reload();
|
||||
});
|
||||
})
|
||||
|
||||
</script>
|
||||
@@ -1,32 +0,0 @@
|
||||
var Settings = require('../settings/settings')
|
||||
, Setting = require('../settings/settings')
|
||||
, Model = require('../../model')
|
||||
;
|
||||
|
||||
var models = module.exports.models = {};
|
||||
var refresh = module.exports.refresh = function() {
|
||||
Settings
|
||||
.spawn()
|
||||
.find({plugin: 'graph'})
|
||||
.notify(function(model) {
|
||||
var m = models[model.name] = Model.spawn();
|
||||
m.description = model.description;
|
||||
m.allowed = model.allowed;
|
||||
m.collection = model.collection;
|
||||
m.plugin = model.plugin;
|
||||
})
|
||||
.fetch()
|
||||
;
|
||||
}
|
||||
|
||||
// initial refresh
|
||||
refresh();
|
||||
|
||||
// create or update general graph settings
|
||||
Setting
|
||||
.spawn()
|
||||
.set({plugin: 'graph', name: 'graph'})
|
||||
.save()
|
||||
;
|
||||
|
||||
|
||||
@@ -2,19 +2,10 @@ var app = require('../../app')
|
||||
, config = require('../../config').load()
|
||||
, Settings = require('./settings')
|
||||
, Setting = require('./setting')
|
||||
, graph = require('../graph')
|
||||
, models = require('../models')
|
||||
, Model = require('../../model')
|
||||
;
|
||||
|
||||
app.get('/settings', function(req, res) {
|
||||
Settings
|
||||
.spawn()
|
||||
.for(req)
|
||||
.notify(res)
|
||||
.fetch()
|
||||
;
|
||||
});
|
||||
|
||||
app.post('/settings', function(req, res) {
|
||||
Settings
|
||||
.spawn()
|
||||
@@ -22,7 +13,7 @@ app.post('/settings', function(req, res) {
|
||||
.find({name: req.body.name, plugin: req.body.plugin})
|
||||
.set(req.body)
|
||||
.notify(function(json) {
|
||||
if(req.body.plugin === 'graph') graph.refresh();
|
||||
if(req.body.plugin === 'models') models.refresh();
|
||||
else if(json.collection) Model.refreshSettings(json.collection);
|
||||
res.send(json);
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ var Model = require('../../model');
|
||||
module.exports = Model.spawn({
|
||||
|
||||
collection: 'settings',
|
||||
plugin: 'setting',
|
||||
plugin: 'settings',
|
||||
|
||||
description: {
|
||||
name: {type: 'string'},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var Collection = require('../../collection');
|
||||
|
||||
module.exports = Collection.spawn({
|
||||
collection: 'settings'
|
||||
collection: 'settings',
|
||||
plugin: 'settings'
|
||||
});
|
||||
@@ -1,34 +0,0 @@
|
||||
var Model = require('../../model');
|
||||
|
||||
var Group = module.exports = Model.spawn({
|
||||
|
||||
collection: 'groups',
|
||||
plugin: 'user',
|
||||
|
||||
description: {
|
||||
name: {type: 'string', unique: true},
|
||||
creator: 'string'
|
||||
},
|
||||
|
||||
allowed: {
|
||||
read: 'root',
|
||||
write: 'creator',
|
||||
remove: 'creator',
|
||||
create: 'root'
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var defaults = ['root', 'admin', 'public'];
|
||||
|
||||
defaults.forEach(function(group) {
|
||||
var g = {name: group, creator: 'root'};
|
||||
|
||||
Group
|
||||
.spawn()
|
||||
.unlock()
|
||||
.find(g)
|
||||
.set(g)
|
||||
.save()
|
||||
;
|
||||
});
|
||||
@@ -1,82 +0,0 @@
|
||||
var app = require('../../app')
|
||||
, Group = require('./group')
|
||||
, User = require('./user')
|
||||
, Users = require('./users')
|
||||
, ObjectID = require('mongodb').BSON
|
||||
;
|
||||
|
||||
function user(action, params, req, res) {
|
||||
User
|
||||
.spawn()
|
||||
.for(req)
|
||||
.set(params)
|
||||
.notify(res)
|
||||
[action]()
|
||||
;
|
||||
}
|
||||
|
||||
app.post('/user', function(req, res) {
|
||||
user('save', req.body, req, res);
|
||||
});
|
||||
|
||||
app.post('/user/login', function(req, res) {
|
||||
user('login', req.body, req, {
|
||||
send: function(u) {
|
||||
u.auth = req.sessionID;
|
||||
res.send(req.session.user = u);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/user/logout', function(req, res) {
|
||||
req.session.destroy(function() {
|
||||
res.send({auth: null});
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/me', function(req, res) {
|
||||
user('fetch', {email: req.session.user && req.session.user.email}, req, res);
|
||||
});
|
||||
|
||||
app.del('/me', function(req, res) {
|
||||
var u = req.session.user;
|
||||
if(u) user('remove', u, req, res);
|
||||
});
|
||||
|
||||
app.get('/user/:id', function(req, res) {
|
||||
User
|
||||
.spawn()
|
||||
.for(req)
|
||||
.find({_id: req.param('id')})
|
||||
.notify(res)
|
||||
.fetch()
|
||||
;
|
||||
});
|
||||
|
||||
app.post('/user/:email/group', function(req, res) {
|
||||
var changes = {}
|
||||
, group = req.body && req.body.group
|
||||
;
|
||||
|
||||
// TODO validate group
|
||||
changes['groups.' + group] = 1;
|
||||
User
|
||||
.spawn()
|
||||
.for(req)
|
||||
.find({email: req.param('email')})
|
||||
.set({$set: changes})
|
||||
.notify(res)
|
||||
.save()
|
||||
;
|
||||
});
|
||||
|
||||
app.get('/users', function(req, res) {
|
||||
Users
|
||||
.spawn({
|
||||
query: req.params
|
||||
})
|
||||
.for(req)
|
||||
.notify(res)
|
||||
.fetch()
|
||||
;
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
var Model = require('../../model')
|
||||
, ObjectID = require('mongodb').BSONPure.ObjectID
|
||||
, _ = require('underscore')
|
||||
;
|
||||
|
||||
module.exports = Model.spawn({
|
||||
|
||||
collection: 'users',
|
||||
|
||||
plugin: 'user',
|
||||
|
||||
description: {
|
||||
email: {type: 'email', unique: true},
|
||||
password: 'password',
|
||||
name: 'string',
|
||||
auth: 'string',
|
||||
removed: 'boolean',
|
||||
groups: 'object'
|
||||
},
|
||||
|
||||
allowed: {
|
||||
read: 'public',
|
||||
write: 'creator',
|
||||
remove: 'creator',
|
||||
create: 'public',
|
||||
special: {
|
||||
groups: {read: 'public', write: 'root'},
|
||||
email: {read: 'creator'}
|
||||
}
|
||||
},
|
||||
|
||||
toJSON: function() {
|
||||
var j = Model.toJSON.apply(this, arguments);
|
||||
|
||||
// remove password before sending to clients
|
||||
delete j.password;
|
||||
|
||||
return j;
|
||||
},
|
||||
|
||||
set: function(changes) {
|
||||
// prevent ever storing a real password
|
||||
changes.password && (changes.password = this.hash(changes.password));
|
||||
|
||||
return Model.set.apply(this, arguments);
|
||||
},
|
||||
|
||||
login: function() {
|
||||
if(!this.get('email') || !this.get('password')) this.error('User email and password are required', 'Required Field');
|
||||
|
||||
return this.fetch();
|
||||
},
|
||||
|
||||
hash: function(password) {
|
||||
return password + 'hash!';
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
var Collection = require('../../collection')
|
||||
, User = require('./user')
|
||||
;
|
||||
|
||||
module.exports = Collection.spawn({
|
||||
collection: 'users',
|
||||
model: User
|
||||
});
|
||||
@@ -23,7 +23,7 @@ var app = {
|
||||
var tests = {
|
||||
|
||||
'1. creating a user': {
|
||||
route: '/user',
|
||||
route: '/users',
|
||||
data: user,
|
||||
expect: {
|
||||
_id: 'toExist',
|
||||
@@ -34,7 +34,7 @@ var tests = {
|
||||
},
|
||||
|
||||
'3. add a user to group': {
|
||||
route: '/user/' + user.email + '/group',
|
||||
route: '/users/' + user.email + '/group',
|
||||
data: {group: 'root'},
|
||||
expect: {
|
||||
errors: 'toNotExist'
|
||||
@@ -42,7 +42,7 @@ var tests = {
|
||||
},
|
||||
|
||||
'4. login a user': {
|
||||
route: '/user/login',
|
||||
route: '/users/login',
|
||||
data: user,
|
||||
expect: {
|
||||
_id: 'toExist',
|
||||
@@ -102,7 +102,7 @@ var tests = {
|
||||
},
|
||||
|
||||
'9. validate users': {
|
||||
route: '/user',
|
||||
route: '/users',
|
||||
data: {asdf: 1234, uid: {foo: 'bar'}, password: 1111},
|
||||
expect: {
|
||||
errors: 'toExist'
|
||||
|
||||
Reference in New Issue
Block a user