Skip to content

Commit

Permalink
feat(admins): add signUpAdmin and deleteAdmin
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitjes committed Nov 23, 2017
1 parent 1bcbe6c commit cb8991d
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 1 deletion.
101 changes: 101 additions & 0 deletions src/admins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { AuthError, getBaseUrl, getConfigUrl, wrapError } from './utils';

import ajaxCore from 'pouchdb-ajax';
import { assign, toPromise } from 'pouchdb-utils';

var getMembership = toPromise(function (opts, callback) {
var db = this;
if (typeof callback === 'undefined') {
callback = opts;
opts = {};
}

var url = getBaseUrl(db) + '/_membership';
var ajaxOpts = assign({
method: 'GET',
url: url,
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});

var signUpAdmin = toPromise(function (username, password, opts, callback) {
var db = this;
if (typeof callback === 'undefined') {
callback = typeof opts === 'undefined' ? (typeof password === 'undefined' ?
username : password) : opts;
opts = {};
}
if (['http', 'https'].indexOf(db.type()) === -1) {
return callback(new AuthError('This plugin only works for the http/https adapter. ' +
'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
} else if (!username) {
return callback(new AuthError('You must provide a username'));
} else if (!password) {
return callback(new AuthError('You must provide a password'));
}

db.getMembership(opts, function (error, membership) {
var nodeName;
if (error) {
if (error.error !== 'illegal_database_name') {
return callback(error);
} else {
// Some couchdb-1.x-like server
nodeName = undefined;
}
} else {
// Some couchdb-2.x-like server
nodeName = membership.all_nodes[0];
}

var configUrl = getConfigUrl(db, nodeName);
var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
var ajaxOpts = assign({
method: 'PUT',
url: url,
processData: false,
body: '"' + password + '"',
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
});

var deleteAdmin = toPromise(function (username, opts, callback) {
var db = this;
if (typeof callback === 'undefined') {
callback = typeof opts === 'undefined' ? username : opts;
opts = {};
}
if (['http', 'https'].indexOf(db.type()) === -1) {
return callback(new AuthError('This plugin only works for the http/https adapter. ' +
'So you should use new PouchDB("http://mysite.com:5984/mydb") instead.'));
} else if (!username) {
return callback(new AuthError('You must provide a username'));
}

db.getMembership(opts, function (error, membership) {
var nodeName;
if (error) {
if (error.error !== 'illegal_database_name') {
return callback(error);
} else {
// Some couchdb-1.x-like server
nodeName = undefined;
}
} else {
// Some couchdb-2.x-like server
nodeName = membership.all_nodes[0];
}

var configUrl = getConfigUrl(db, nodeName);
var url = (opts.configUrl || configUrl) + '/admins/' + encodeURIComponent(username);
var ajaxOpts = assign({
method: 'DELETE',
url: url,
processData: false,
}, opts.ajax || {});
ajaxCore(ajaxOpts, wrapError(callback));
});
});

export { getMembership, deleteAdmin, signUpAdmin };
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

import { deleteAdmin, getMembership, signUpAdmin } from "./admins";
import { getSession, logIn, logOut } from "./authentication";
import {
changePassword,
Expand All @@ -19,6 +20,10 @@ plugin.logout = logOut;
plugin.logOut = logOut;
plugin.getSession = getSession;

plugin.getMembership = getMembership;
plugin.signUpAdmin = signUpAdmin;
plugin.deleteAdmin = deleteAdmin;

plugin.getUsersDatabaseUrl = getUsersDatabaseUrl;
plugin.signup = signUp;
plugin.signUp = signUp;
Expand Down
6 changes: 5 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ function getBaseUrl(db) {
}
}

function getConfigUrl(db, nodeName) {
return urlJoin(getBaseUrl(db), (nodeName ? '/_node/' + nodeName : '') + '/_config');
}

function getUsersUrl(db) {
return urlJoin(getBaseUrl(db), '/_users');
}
Expand Down Expand Up @@ -47,4 +51,4 @@ function AuthError(message) {

inherits(AuthError, Error);

export { AuthError, getSessionUrl, getUsersUrl, wrapError };
export { AuthError, getBaseUrl, getConfigUrl, getSessionUrl, getUsersUrl, wrapError };
73 changes: 73 additions & 0 deletions test/test.admins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use strict';

var PouchDB = require('pouchdb-memory');
var Authentication = require('../lib');
PouchDB.plugin(Authentication);

var utils = require('./test-utils');
var chai = require('chai');
var should = chai.should();

describe('admins', function () {

var dbHost = 'http://localhost:5984';
var dbName = dbHost + '/testdb';

var db;

beforeEach(function () {
db = new PouchDB(dbName);
return utils.ensureUsersDatabaseExists(db);
});

afterEach(function () {
return db.logOut().then(function () {
return db.destroy();
});
});

it('Create and delete admin', function () {
return testCreateDeleteAdmin({});
});

it('Create and delete admin with config url', function () {
return db.getMembership().then(function (membership) {
// Some couchdb-2.x-like server
return membership.all_nodes[0];
}).catch(function () {
// Some couchdb-1.x-like server
return undefined;
}).then(function (nodeName) {
var opts = {
configUrl: dbHost + (nodeName ? '/_node/' + nodeName : '') + '/_config',
};

return testCreateDeleteAdmin(opts);
});
});

function testCreateDeleteAdmin(opts) {
return db.signUpAdmin('anna', 'secret', opts).then(function (res) {
should.exist(res);

return db.logIn('anna', 'secret').then(function (res) {
res.ok.should.equal(true);

return db.deleteAdmin('anna', opts).then(function (res) {
should.exist(res);

return db.logOut().then(function () {

return db.logIn('anna', 'secret').then(function () {
should.fail('shouldn\'t have worked');
}, function (err) {
should.exist(err);
err.error.should.equal('unauthorized');
err.reason.should.equal('Name or password is incorrect.');
});
});
});
});
});
}
});

0 comments on commit cb8991d

Please sign in to comment.