Last active
November 3, 2016 15:28
-
-
Save trmcnvn/6da2ae358a3ec96b8e8cf3157ebc2064 to your computer and use it in GitHub Desktop.
ember couchdb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Base from 'ember-simple-auth/authenticators/base'; | |
import { remote } from 'budget/adapters/application'; | |
import RSVP from 'rsvp'; | |
import run from 'ember-runloop'; | |
import get from 'ember-metal/get'; | |
export default Base.extend({ | |
restore(data) { | |
return new RSVP.Promise((resolve, reject) => { | |
if (get(data, 'name')) { | |
remote.getSession((err, response) => { | |
if (err || (response && response.userCtx.name === null)) { | |
reject(); | |
} else { | |
resolve(data); | |
} | |
}); | |
} else { | |
reject(); | |
} | |
}); | |
}, | |
authenticate(username, password) { | |
return new RSVP.Promise((resolve, reject) => { | |
remote.login(username, password) | |
.then((response) => run(() => resolve(response))) | |
.catch((err) => run(() => reject(err))); | |
}); | |
}, | |
invalidate() { | |
return remote.logout(); | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* jshint node:true */ | |
const http = require('http'); | |
const rsvp = require('rsvp'); | |
function putRequest(context, path, data, callback) { | |
const options = { | |
hostname: 'localhost', | |
port: 5984, | |
path: path, | |
method: 'PUT', | |
headers: { 'Content-Type': 'application/json' }, | |
auth: 'admin:password' | |
}; | |
const req = http.request(options, (res) => { | |
res.on('data', () => {}); | |
callback(res); | |
}); | |
req.on('error', () => { | |
context.status = 500; | |
context.body = '{ "ok": false }'; | |
}); | |
if (data !== null) { | |
req.write(JSON.stringify(data)); | |
} | |
req.end(); | |
} | |
function createUser(context, data) { | |
const path = `/_users/org.couchdb.user:${data.username}`; | |
const user = { | |
name: data.username, | |
password: data.password, | |
type: 'user', | |
roles: [data.username] | |
}; | |
return new rsvp.Promise((resolve, reject) => { | |
putRequest(context, path, user, (res) => { | |
res.on('data', (response) => { | |
const json = JSON.parse(response); | |
switch (json.error) { | |
case 'conflict': | |
reject('Username already exists.'); | |
break; | |
case 'forbidden': | |
reject('Username is invalid.'); | |
break; | |
} | |
}); | |
res.on('end', () => resolve(data.username.toLowerCase())); | |
}); | |
}); | |
} | |
function createDatabase(context, name) { | |
const path = `/db_${name}/`; | |
return new rsvp.Promise((resolve) => { | |
putRequest(context, path, null, (res) => { | |
res.on('end', () => resolve(name)); | |
}); | |
}); | |
} | |
function createSecurity(context, name) { | |
const path = `/db_${name}/_security`; | |
const data = { | |
members: { | |
names: [], | |
roles: [name] | |
}, | |
admins: { | |
names: [name], | |
roles: [] | |
} | |
}; | |
return new rsvp.Promise((resolve) => { | |
putRequest(context, path, data, (res) => { | |
res.on('end', () => resolve(name)); | |
}); | |
}); | |
} | |
function createValidate(context, name) { | |
const path = `/db_${name}/_design/security`; | |
const data = { | |
validate_doc_update: `function(newDoc, oldDoc, userCtx) { | |
if (userCtx.name !== '${name}' && userCtx.roles.indexOf('${name}') === -1) { | |
throw({ forbidden: 'Not Authorized' }); | |
} | |
}` | |
}; | |
return new rsvp.Promise((resolve) => { | |
putRequest(context, path, data, (res) => { | |
res.on('end', () => resolve()); | |
}); | |
}); | |
} | |
module.exports = function(context) { | |
if (context.request.query && (context.request.query.username && context.request.query.password)) { | |
return createUser(context, context.request.query) | |
.then((name) => createDatabase(context, name)) | |
.then((name) => createSecurity(context, name)) | |
.then((name) => createValidate(context, name)) | |
.then(() => { | |
context.status = 201; | |
context.body = '{ "ok": true }'; | |
}) | |
.catch((reason) => { | |
context.status = 400; | |
context.body = `{ "error": "${reason}" }`; | |
}); | |
} else { | |
context.status = 400; | |
context.body = '{ "ok": false }'; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment