Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
rename "readers" to "members" in _security object, keep backwards com…
…patibility with old security objects"

git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1039619 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
jchris committed Nov 27, 2010
1 parent 2c6d3df commit b09703f510f8eb6dd0941c760fa6f726e2ca766a
Showing 5 changed files with 65 additions and 42 deletions.
@@ -16,12 +16,12 @@
<h2>Security</h2>
<fieldset>
<p class="help">
Each database contains lists of admins and readers.
Admins and readers are each defined by <tt>names</tt> and <tt>roles</tt>, which are lists of strings.
Each database contains lists of admins and members.
Admins and members are each defined by <tt>names</tt> and <tt>roles</tt>, which are lists of strings.
</p>

<h3>Admins</h3>
<p class="help">Database admins can update design documents and edit the readers list.</p>
<p class="help">Database admins can update design documents and edit the admin and member lists.</p>
<table summary=""><tbody><tr>
<th><label>Names:</label></th>
<td><input type="text" name="admin_names" size="40"></td>
@@ -31,14 +31,14 @@ <h3>Admins</h3>
</tr>
</tbody></table>

<h3>Readers</h3>
<p class="help">Database readers can access the database. If no readers are defined, the database is public.</p>
<h3>Members</h3>
<p class="help">Database members can access the database. If no members are defined, the database is public.</p>
<table summary=""><tbody><tr>
<th><label>Names:</label></th>
<td><input type="text" name="reader_names" size="40"></td>
<td><input type="text" name="member_names" size="40"></td>
</tr><tr>
<th><label>Roles:</label></th>
<td><input type="text" name="reader_roles" size="40"></td>
<td><input type="text" name="member_roles" size="40"></td>
</tr>
</tbody></table>

@@ -189,26 +189,34 @@
}

this.databaseSecurity = function() {
function namesAndRoles(r, key) {
var names = [];
var roles = [];
if (r && typeof r[key + "s"] === "object") {
if ($.isArray(r[key + "s"]["names"])) {
names = r[key + "s"]["names"];
}
if ($.isArray(r[key + "s"]["roles"])) {
roles = r[key + "s"]["roles"];
}
}
return {names : names, roles: roles};
};

$.showDialog("dialog/_database_security.html", {
load : function(d) {
db.getDbProperty("_security", {
success: function(r) {
["admin", "reader"].forEach(function(key) {
var names = [];
var roles = [];

if (r && typeof r[key + "s"] === "object") {
if ($.isArray(r[key + "s"]["names"])) {
names = r[key + "s"]["names"];
}
if ($.isArray(r[key + "s"]["roles"])) {
roles = r[key + "s"]["roles"];
}
}

$("input[name=" + key + "_names]", d).val(JSON.stringify(names));
$("input[name=" + key + "_roles]", d).val(JSON.stringify(roles));
});
var admins = namesAndRoles(r, "admin")
, members = namesAndRoles(r, "member");
if (members.names.length + members.roles.length == 0) {
// backwards compatibility with readers for 1.x
members = namesAndRoles(r, "reader");
}
$("input[name=admin_names]", d).val(JSON.stringify(admins.names));
$("input[name=admin_roles]", d).val(JSON.stringify(admins.roles));
$("input[name=member_names]", d).val(JSON.stringify(members.names));
$("input[name=member_roles]", d).val(JSON.stringify(members.roles));
}
});
},
@@ -220,13 +228,13 @@
names: [],
roles: []
},
readers: {
members: {
names: [],
roles: []
}
};

["admin", "reader"].forEach(function(key) {
["admin", "member"].forEach(function(key) {
var names, roles;

try {
@@ -37,7 +37,7 @@ couchTests.reader_acl = function(debug) {
T(secretDb.open("baz").foo == "bar");

T(secretDb.setSecObj({
"readers" : {
"members" : {
roles : ["super-secret-club"],
names : ["joe","barb"]
}
@@ -64,13 +64,13 @@ couchTests.reader_acl = function(debug) {
CouchDB.logout();

// make anyone with the top-secret role an admin
// db admins are automatically readers
// db admins are automatically members
T(secretDb.setSecObj({
"admins" : {
roles : ["top-secret"],
names : []
},
"readers" : {
"members" : {
roles : ["super-secret-club"],
names : ["joe","barb"]
}
@@ -90,14 +90,14 @@ couchTests.reader_acl = function(debug) {
CouchDB.logout();
T(CouchDB.session().userCtx.roles.indexOf("_admin") != -1);

// admin now adds the top-secret role to the db's readers
// admin now adds the top-secret role to the db's members
// and removes db-admins
T(secretDb.setSecObj({
"admins" : {
roles : [],
names : []
},
"readers" : {
"members" : {
roles : ["super-secret-club", "top-secret"],
names : ["joe","barb"]
}
@@ -124,10 +124,10 @@ couchTests.reader_acl = function(debug) {
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
T(secretDb.open("baz").foo == "bar");
// readers can query stored views
// members can query stored views
T(secretDb.view("foo/bar").total_rows == 1);

// readers can't do temp views
// members can't do temp views
try {
var results = secretDb.query(function(doc) {
emit(null, null);
@@ -137,13 +137,28 @@ couchTests.reader_acl = function(debug) {
T(true && "temp view is admin only");
}


CouchDB.logout();

// works with readers (backwards compat with 1.0)
T(secretDb.setSecObj({
"admins" : {
roles : [],
names : []
},
"readers" : {
roles : ["super-secret-club", "top-secret"],
names : ["joe","barb"]
}
}).ok);

T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
T(secretDb.open("baz").foo == "bar");

// can't set non string reader names or roles
try {
secretDb.setSecObj({
"readers" : {
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : ["joe","barb"]
}
@@ -153,7 +168,7 @@ couchTests.reader_acl = function(debug) {

try {
secretDb.setSecObj({
"readers" : {
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : ["joe",22]
}
@@ -163,7 +178,7 @@ couchTests.reader_acl = function(debug) {

try {
secretDb.setSecObj({
"readers" : {
"members" : {
roles : ["super-secret-club", {"top-secret":"awesome"}],
names : "joe"
}
@@ -623,7 +623,7 @@ couchTests.replication = function(debug) {
names: [],
roles: ["admin"]
},
readers: {
members: {
names: [],
roles: ["reader"]
}
@@ -687,7 +687,7 @@ couchTests.replication = function(debug) {
names: [],
roles: ["bar"]
},
readers: {
members: {
names: [],
roles: ["foo"]
}
@@ -184,15 +184,15 @@ describe 'CouchDB instance'

describe '.setSecObj'
it 'should return ok true'
db.setSecObj({"readers":{"names":["laura"],"roles":["president"]}}).ok.should.be_true
db.setSecObj({"members":{"names":["laura"],"roles":["president"]}}).ok.should.be_true
end

it 'should save a well formed object into the _security object '
db.should.receive("request", "once").with_args("PUT", "/spec_db/_security", {body: '{"readers":{"names":["laura"],"roles":["president"]}}'})
db.setSecObj({"readers": {"names" : ["laura"], "roles" : ["president"]}})
db.should.receive("request", "once").with_args("PUT", "/spec_db/_security", {body: '{"members":{"names":["laura"],"roles":["president"]}}'})
db.setSecObj({"members": {"names" : ["laura"], "roles" : ["president"]}})
end

it 'should throw an error when the readers or admins object is malformed'
it 'should throw an error when the members or admins object is malformed'
-{ db.setSecObj({"admins":["cylon"]}) }.should.throw_error
end

0 comments on commit b09703f

Please sign in to comment.