Skip to content

Instantly share code, notes, and snippets.

@trmcnvn
Last active November 3, 2016 15:28
Show Gist options
  • Save trmcnvn/6da2ae358a3ec96b8e8cf3157ebc2064 to your computer and use it in GitHub Desktop.
Save trmcnvn/6da2ae358a3ec96b8e8cf3157ebc2064 to your computer and use it in GitHub Desktop.
ember couchdb
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();
}
});
/* 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