Reputation: 85
I want to set roles for a new user.
I tried updating roles array in metadata during signup but I get an error. If I remove the roles metadata new user is created just fine.
db.signUp(userId, 'pass', {
metadata: {
email: '[email protected]',
birthday: '1932-03-27T00:00:00.000Z',
likes: ['acrobatics', 'short pants', 'sidekickin\'']
roles: ['basic']
}
}, function (err, response) {
if (err) {
if (err.name === 'conflict') {
console.log('batman" already exists, choose another username')
// "batman" already exists, choose another username
} else if (err.name === 'forbidden') {
console.log('invalid username')
// invalid username
} else {
console.log('sign up error')
// HTTP error, cosmic rays, etc.
}
} else {
console.log('user signed up')
// login()
}
})
So I figured it out first modify the pouchdb-authentication index.js code to accept roles.
var signUp = pouchdbUtils.toPromise(function (username, password,roles, 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://mysi3te.org: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'));
}
var userId = 'org.couchdb.user:' + username;
var user = {
name: username,
password: password,
roles: roles,
type: 'user',
_id: userId,
};
updateUser(db, user, opts, callback);
});
Then you can send the roles in the sign up. I'm sending basic below
signUp()
function signUp () {
db.signUp(userId, 'pass', ['basic'], {
metadata: {
email: '[email protected]',
birthday: '1932-03-27T00:00:00.000Z',
likes: ['acrobatics', 'short pants', 'sidekickin\'']
}
}, function (err, response) {
if (err) {
if (err.name === 'conflict') {
console.log('batman" already exists, choose another username')
// "batman" already exists, choose another username
} else if (err.name === 'forbidden') {
console.log('invalid username', err)
// invalid username
} else {
console.log('sign up error', err)
// HTTP error, cosmic rays, etc.
}
} else {
console.log('user signed up', err)
login()
}
})
}
now you have to go to couchdb _user database _design/_auth document modify
else if (newDoc.roles.length > 0 ) {\n
set this to
else if (newDoc.roles.length > 0 && newDoc.roles[0] !== 'basic' ) {\n
Now you will have basic in your session and can add more roles my adjusting the code a bit. This allows me to set member role permissions easily to limit access to other databases. Or a simpler solution i found and tested is to add a new design doc to your database with the following code. It will only allow users that are logged in to access your database
{
"_id": "_design/usersOnly",
"_rev": "17-6fb7e6c0ccfca8b2e56738ad63e26107",
"language": "javascript",
"validate_doc_update": "\n function(newDoc, oldDoc, userCtx){ \n // check if user is logged in \n if(!userCtx.name){ throw({forbidden : 'No way.. login man!'});} \n //reqired fields to update \n function require(field){ var message = field + ' is required'; if(!newDoc[field]){ throw({'forbidden':message}) }} require('name'); }"
}
Upvotes: 1
Views: 999
Reputation: 13495
The validate function design documentation uses the _users design document as the primary example:
Example: The _design/_auth ddoc from _users database uses a validation function to ensure that documents contain some required fields and are only modified by a user with the _admin role:
...
} else if (newDoc.roles.length > 0) {
throw({forbidden: 'Only _admin may set roles'});
}
...
In fauxton (for example) you can login as the couchdb admin user and go to _users database and change the design (at your own peril), for example:
} else if (newDoc.roles.length > 0 && !("basic" === newRoles[0] && newDoc.roles.length === 1)) {
throw({forbidden: 'Only _admin may set roles'});
}
saving it as you would any other document. (I say peril, since subtle accidents in this design document can potentially allow unauthorized users to drastically raise their permissions.)
With such a change, new users are allowed to be created with the basic role by couchdb, so your client code works if it sets roles correctly. In pouchdb-authenticate this seems to be with opt.roles and not opt.metadata.roles, i.e.:
db.signUp(userId, 'pass', {
metadata: {
email: '[email protected]',
birthday: '1932-03-27T00:00:00.000Z',
likes: ['acrobatics', 'short pants', 'sidekickin\'']
},
roles: ['basic'] }, ... )
Upvotes: 1