CouchDB write/read only (no edit) user
Toolchain/frameworks
I'm using django==2.1.3
and python-cloudant==2.1.3
and running CouchDB ver. 2.2.0
, and pretty much doing all of my setup/configuration through Fauxton
. I like to think that I know my way around python/django in general, and I'm testing this approach in a small little project to see how it works
Problem Description
Suppose I have a fairly simple CRUD application with just 1 model:
class Asset(models.Model):
asset_id = models.CharField(max_length=32)
asset_name = models.CharField(max_length=32)
and I have a view that I use to create the asset
class CreateAssetView(views.View):
def get(self, request, *args, **kwargs):
#some code here
def post(self, request, *args, **kwargs):
#some code here|
#log request data into database
client = CouchDB('myusername', 'mypassword', url='http://127.0.0.1:5984', connect=True)
db = client['assets']
log_data = {'view_name': self.view_name, 'post_data': post_data,'user': request.user.username,
'time': str(timezone.now())}
db.create_document(log_data)
return render(...)
I understand that I should be doing the logging portion using a middleware (which I plan to) and probably just use django's CreateView
in that case, I'm doing this approach for now just during early development.
What I'm having a problem wrapping my head around is creating a user with myusername
and mypassword
that has the permissions to:
- Write new documents
- Read old documents
not edit already created documents
I could even settle for 1 and 3 only (and only use admin to read). I spent a little bit of time playing around with Fauxton
's interface for permissions, but I can only basically create a user
and assign a role
(couldn't even get to assigning a password :/)
clarification
The Asset
is not a CouchDB
document, that's a normal SQL model, I only want to dump the logs with post data to CouchDB
Any help/gudiance/documentation pointers would be really appreciated
python django nosql couchdb python-cloudant
add a comment |
Toolchain/frameworks
I'm using django==2.1.3
and python-cloudant==2.1.3
and running CouchDB ver. 2.2.0
, and pretty much doing all of my setup/configuration through Fauxton
. I like to think that I know my way around python/django in general, and I'm testing this approach in a small little project to see how it works
Problem Description
Suppose I have a fairly simple CRUD application with just 1 model:
class Asset(models.Model):
asset_id = models.CharField(max_length=32)
asset_name = models.CharField(max_length=32)
and I have a view that I use to create the asset
class CreateAssetView(views.View):
def get(self, request, *args, **kwargs):
#some code here
def post(self, request, *args, **kwargs):
#some code here|
#log request data into database
client = CouchDB('myusername', 'mypassword', url='http://127.0.0.1:5984', connect=True)
db = client['assets']
log_data = {'view_name': self.view_name, 'post_data': post_data,'user': request.user.username,
'time': str(timezone.now())}
db.create_document(log_data)
return render(...)
I understand that I should be doing the logging portion using a middleware (which I plan to) and probably just use django's CreateView
in that case, I'm doing this approach for now just during early development.
What I'm having a problem wrapping my head around is creating a user with myusername
and mypassword
that has the permissions to:
- Write new documents
- Read old documents
not edit already created documents
I could even settle for 1 and 3 only (and only use admin to read). I spent a little bit of time playing around with Fauxton
's interface for permissions, but I can only basically create a user
and assign a role
(couldn't even get to assigning a password :/)
clarification
The Asset
is not a CouchDB
document, that's a normal SQL model, I only want to dump the logs with post data to CouchDB
Any help/gudiance/documentation pointers would be really appreciated
python django nosql couchdb python-cloudant
add a comment |
Toolchain/frameworks
I'm using django==2.1.3
and python-cloudant==2.1.3
and running CouchDB ver. 2.2.0
, and pretty much doing all of my setup/configuration through Fauxton
. I like to think that I know my way around python/django in general, and I'm testing this approach in a small little project to see how it works
Problem Description
Suppose I have a fairly simple CRUD application with just 1 model:
class Asset(models.Model):
asset_id = models.CharField(max_length=32)
asset_name = models.CharField(max_length=32)
and I have a view that I use to create the asset
class CreateAssetView(views.View):
def get(self, request, *args, **kwargs):
#some code here
def post(self, request, *args, **kwargs):
#some code here|
#log request data into database
client = CouchDB('myusername', 'mypassword', url='http://127.0.0.1:5984', connect=True)
db = client['assets']
log_data = {'view_name': self.view_name, 'post_data': post_data,'user': request.user.username,
'time': str(timezone.now())}
db.create_document(log_data)
return render(...)
I understand that I should be doing the logging portion using a middleware (which I plan to) and probably just use django's CreateView
in that case, I'm doing this approach for now just during early development.
What I'm having a problem wrapping my head around is creating a user with myusername
and mypassword
that has the permissions to:
- Write new documents
- Read old documents
not edit already created documents
I could even settle for 1 and 3 only (and only use admin to read). I spent a little bit of time playing around with Fauxton
's interface for permissions, but I can only basically create a user
and assign a role
(couldn't even get to assigning a password :/)
clarification
The Asset
is not a CouchDB
document, that's a normal SQL model, I only want to dump the logs with post data to CouchDB
Any help/gudiance/documentation pointers would be really appreciated
python django nosql couchdb python-cloudant
Toolchain/frameworks
I'm using django==2.1.3
and python-cloudant==2.1.3
and running CouchDB ver. 2.2.0
, and pretty much doing all of my setup/configuration through Fauxton
. I like to think that I know my way around python/django in general, and I'm testing this approach in a small little project to see how it works
Problem Description
Suppose I have a fairly simple CRUD application with just 1 model:
class Asset(models.Model):
asset_id = models.CharField(max_length=32)
asset_name = models.CharField(max_length=32)
and I have a view that I use to create the asset
class CreateAssetView(views.View):
def get(self, request, *args, **kwargs):
#some code here
def post(self, request, *args, **kwargs):
#some code here|
#log request data into database
client = CouchDB('myusername', 'mypassword', url='http://127.0.0.1:5984', connect=True)
db = client['assets']
log_data = {'view_name': self.view_name, 'post_data': post_data,'user': request.user.username,
'time': str(timezone.now())}
db.create_document(log_data)
return render(...)
I understand that I should be doing the logging portion using a middleware (which I plan to) and probably just use django's CreateView
in that case, I'm doing this approach for now just during early development.
What I'm having a problem wrapping my head around is creating a user with myusername
and mypassword
that has the permissions to:
- Write new documents
- Read old documents
not edit already created documents
I could even settle for 1 and 3 only (and only use admin to read). I spent a little bit of time playing around with Fauxton
's interface for permissions, but I can only basically create a user
and assign a role
(couldn't even get to assigning a password :/)
clarification
The Asset
is not a CouchDB
document, that's a normal SQL model, I only want to dump the logs with post data to CouchDB
Any help/gudiance/documentation pointers would be really appreciated
python django nosql couchdb python-cloudant
python django nosql couchdb python-cloudant
edited Nov 20 '18 at 1:33
robotHamster
asked Nov 20 '18 at 1:25
robotHamsterrobotHamster
343216
343216
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Overview
Couchdb has one overriding level of administrator setup in configuration instead of setup in the _users
database and assigned the _admin
permission to prevent any possibility of being locked out.
Each individual database then has a rough level security policy of 2 levels:
- admins
- members
specified via:
- names
- roles
making 4 fields.
These levels control access slightly differently for the 2 types of documents a db can contain:
- id:
_design/*
- Design documents can contain functions that will be executed in some context - id:
other
- Normal documents are just normal data
Both levels of database access have read access to all documents in the database, but admins have write access to _design documents. Write access to normal documents is usually given to all users granted any access to the db, but can be limited by validate design documents.
To Summarize
The process for setting a unique security policy up is:
- Experience the provided validate design document as a consumer while setting up _users.
- Setup a new database and its basic security giving your users member access.
- Add a design doc to the new database with a validate function that restricts member write access.
1 Setting up _users entries
Add a role to a user
As an admin add role: ["logger"]
to a user's doc and save it, note that this must be done by admin due to this part of the default _users design document:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (oldRoles.length !== newRoles.length) {
throw({forbidden: 'Only _admin may edit roles'});
}
Change the password for the user.
Either the admin or the user can change their password by setting password:"mynewpassword"
in their document (which couchdb will transform into a hashed/salted password during the save process). This works for a user since they can add/modify fields aside from their name and roles, as long as a user is editing their own doc:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (userCtx.name !== newDoc.name) {
throw({
forbidden: 'You may only update your own user document.'
});
}
// then checks that they don't modify roles
You could repeat this process with a user you assign an adminlogger
role to create a delegated administrator that you assign permissions to can reconfigure a database or you can continue to use the couchdb admin with its _admin
role for all administration.
2 Setup a new database and its basic security
Create a db named logger
assign the logger a security policy:
{
"admins": {
"names": [
],
"roles": [
"adminlogger"
]
},
"members": {
"names": [
],
"roles": [
"logger"
]
}
}
3. Create a new validate design document in the new db
As either _admin user or a user with the adminlogger
role create a new validate design doc by copying the _users design document, removing the _rev and modifying the function:
// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
// Don't let non-admins write a pre-existing document:
if (!is_server_or_database_admin()) {
if (!!oldDoc) {
throw({
forbidden: 'You may not update existing documents.'
});
}
}
// Where the function to define admins can be copied verbatim from the doc:
var is_server_or_database_admin = function(userCtx, secObj) {
// see if the user is a server admin
if(userCtx.roles.indexOf('_admin') !== -1) {
return true; // a server admin
}
// see if the user a database admin specified by name
if(secObj && secObj.admins && secObj.admins.names) {
if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
return true; // database admin
}
}
// see if the user a database admin specified by role
if(secObj && secObj.admins && secObj.admins.roles) {
var db_roles = secObj.admins.roles;
for(var idx = 0; idx < userCtx.roles.length; idx++) {
var user_role = userCtx.roles[idx];
if(db_roles.indexOf(user_role) !== -1) {
return true; // role matches!
}
}
}
return false; // default to no admin
}
}
If you followed these steps then the user you gave the logger role in step 1 can run your code to write new documents only in logger database configured in steps 2 and 3.
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my_users
db only has the design doc (even though I had created users using the permissions window in fauxton)
– robotHamster
Dec 2 '18 at 23:44
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384941%2fcouchdb-write-read-only-no-edit-user%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Overview
Couchdb has one overriding level of administrator setup in configuration instead of setup in the _users
database and assigned the _admin
permission to prevent any possibility of being locked out.
Each individual database then has a rough level security policy of 2 levels:
- admins
- members
specified via:
- names
- roles
making 4 fields.
These levels control access slightly differently for the 2 types of documents a db can contain:
- id:
_design/*
- Design documents can contain functions that will be executed in some context - id:
other
- Normal documents are just normal data
Both levels of database access have read access to all documents in the database, but admins have write access to _design documents. Write access to normal documents is usually given to all users granted any access to the db, but can be limited by validate design documents.
To Summarize
The process for setting a unique security policy up is:
- Experience the provided validate design document as a consumer while setting up _users.
- Setup a new database and its basic security giving your users member access.
- Add a design doc to the new database with a validate function that restricts member write access.
1 Setting up _users entries
Add a role to a user
As an admin add role: ["logger"]
to a user's doc and save it, note that this must be done by admin due to this part of the default _users design document:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (oldRoles.length !== newRoles.length) {
throw({forbidden: 'Only _admin may edit roles'});
}
Change the password for the user.
Either the admin or the user can change their password by setting password:"mynewpassword"
in their document (which couchdb will transform into a hashed/salted password during the save process). This works for a user since they can add/modify fields aside from their name and roles, as long as a user is editing their own doc:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (userCtx.name !== newDoc.name) {
throw({
forbidden: 'You may only update your own user document.'
});
}
// then checks that they don't modify roles
You could repeat this process with a user you assign an adminlogger
role to create a delegated administrator that you assign permissions to can reconfigure a database or you can continue to use the couchdb admin with its _admin
role for all administration.
2 Setup a new database and its basic security
Create a db named logger
assign the logger a security policy:
{
"admins": {
"names": [
],
"roles": [
"adminlogger"
]
},
"members": {
"names": [
],
"roles": [
"logger"
]
}
}
3. Create a new validate design document in the new db
As either _admin user or a user with the adminlogger
role create a new validate design doc by copying the _users design document, removing the _rev and modifying the function:
// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
// Don't let non-admins write a pre-existing document:
if (!is_server_or_database_admin()) {
if (!!oldDoc) {
throw({
forbidden: 'You may not update existing documents.'
});
}
}
// Where the function to define admins can be copied verbatim from the doc:
var is_server_or_database_admin = function(userCtx, secObj) {
// see if the user is a server admin
if(userCtx.roles.indexOf('_admin') !== -1) {
return true; // a server admin
}
// see if the user a database admin specified by name
if(secObj && secObj.admins && secObj.admins.names) {
if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
return true; // database admin
}
}
// see if the user a database admin specified by role
if(secObj && secObj.admins && secObj.admins.roles) {
var db_roles = secObj.admins.roles;
for(var idx = 0; idx < userCtx.roles.length; idx++) {
var user_role = userCtx.roles[idx];
if(db_roles.indexOf(user_role) !== -1) {
return true; // role matches!
}
}
}
return false; // default to no admin
}
}
If you followed these steps then the user you gave the logger role in step 1 can run your code to write new documents only in logger database configured in steps 2 and 3.
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my_users
db only has the design doc (even though I had created users using the permissions window in fauxton)
– robotHamster
Dec 2 '18 at 23:44
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
add a comment |
Overview
Couchdb has one overriding level of administrator setup in configuration instead of setup in the _users
database and assigned the _admin
permission to prevent any possibility of being locked out.
Each individual database then has a rough level security policy of 2 levels:
- admins
- members
specified via:
- names
- roles
making 4 fields.
These levels control access slightly differently for the 2 types of documents a db can contain:
- id:
_design/*
- Design documents can contain functions that will be executed in some context - id:
other
- Normal documents are just normal data
Both levels of database access have read access to all documents in the database, but admins have write access to _design documents. Write access to normal documents is usually given to all users granted any access to the db, but can be limited by validate design documents.
To Summarize
The process for setting a unique security policy up is:
- Experience the provided validate design document as a consumer while setting up _users.
- Setup a new database and its basic security giving your users member access.
- Add a design doc to the new database with a validate function that restricts member write access.
1 Setting up _users entries
Add a role to a user
As an admin add role: ["logger"]
to a user's doc and save it, note that this must be done by admin due to this part of the default _users design document:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (oldRoles.length !== newRoles.length) {
throw({forbidden: 'Only _admin may edit roles'});
}
Change the password for the user.
Either the admin or the user can change their password by setting password:"mynewpassword"
in their document (which couchdb will transform into a hashed/salted password during the save process). This works for a user since they can add/modify fields aside from their name and roles, as long as a user is editing their own doc:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (userCtx.name !== newDoc.name) {
throw({
forbidden: 'You may only update your own user document.'
});
}
// then checks that they don't modify roles
You could repeat this process with a user you assign an adminlogger
role to create a delegated administrator that you assign permissions to can reconfigure a database or you can continue to use the couchdb admin with its _admin
role for all administration.
2 Setup a new database and its basic security
Create a db named logger
assign the logger a security policy:
{
"admins": {
"names": [
],
"roles": [
"adminlogger"
]
},
"members": {
"names": [
],
"roles": [
"logger"
]
}
}
3. Create a new validate design document in the new db
As either _admin user or a user with the adminlogger
role create a new validate design doc by copying the _users design document, removing the _rev and modifying the function:
// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
// Don't let non-admins write a pre-existing document:
if (!is_server_or_database_admin()) {
if (!!oldDoc) {
throw({
forbidden: 'You may not update existing documents.'
});
}
}
// Where the function to define admins can be copied verbatim from the doc:
var is_server_or_database_admin = function(userCtx, secObj) {
// see if the user is a server admin
if(userCtx.roles.indexOf('_admin') !== -1) {
return true; // a server admin
}
// see if the user a database admin specified by name
if(secObj && secObj.admins && secObj.admins.names) {
if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
return true; // database admin
}
}
// see if the user a database admin specified by role
if(secObj && secObj.admins && secObj.admins.roles) {
var db_roles = secObj.admins.roles;
for(var idx = 0; idx < userCtx.roles.length; idx++) {
var user_role = userCtx.roles[idx];
if(db_roles.indexOf(user_role) !== -1) {
return true; // role matches!
}
}
}
return false; // default to no admin
}
}
If you followed these steps then the user you gave the logger role in step 1 can run your code to write new documents only in logger database configured in steps 2 and 3.
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my_users
db only has the design doc (even though I had created users using the permissions window in fauxton)
– robotHamster
Dec 2 '18 at 23:44
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
add a comment |
Overview
Couchdb has one overriding level of administrator setup in configuration instead of setup in the _users
database and assigned the _admin
permission to prevent any possibility of being locked out.
Each individual database then has a rough level security policy of 2 levels:
- admins
- members
specified via:
- names
- roles
making 4 fields.
These levels control access slightly differently for the 2 types of documents a db can contain:
- id:
_design/*
- Design documents can contain functions that will be executed in some context - id:
other
- Normal documents are just normal data
Both levels of database access have read access to all documents in the database, but admins have write access to _design documents. Write access to normal documents is usually given to all users granted any access to the db, but can be limited by validate design documents.
To Summarize
The process for setting a unique security policy up is:
- Experience the provided validate design document as a consumer while setting up _users.
- Setup a new database and its basic security giving your users member access.
- Add a design doc to the new database with a validate function that restricts member write access.
1 Setting up _users entries
Add a role to a user
As an admin add role: ["logger"]
to a user's doc and save it, note that this must be done by admin due to this part of the default _users design document:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (oldRoles.length !== newRoles.length) {
throw({forbidden: 'Only _admin may edit roles'});
}
Change the password for the user.
Either the admin or the user can change their password by setting password:"mynewpassword"
in their document (which couchdb will transform into a hashed/salted password during the save process). This works for a user since they can add/modify fields aside from their name and roles, as long as a user is editing their own doc:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (userCtx.name !== newDoc.name) {
throw({
forbidden: 'You may only update your own user document.'
});
}
// then checks that they don't modify roles
You could repeat this process with a user you assign an adminlogger
role to create a delegated administrator that you assign permissions to can reconfigure a database or you can continue to use the couchdb admin with its _admin
role for all administration.
2 Setup a new database and its basic security
Create a db named logger
assign the logger a security policy:
{
"admins": {
"names": [
],
"roles": [
"adminlogger"
]
},
"members": {
"names": [
],
"roles": [
"logger"
]
}
}
3. Create a new validate design document in the new db
As either _admin user or a user with the adminlogger
role create a new validate design doc by copying the _users design document, removing the _rev and modifying the function:
// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
// Don't let non-admins write a pre-existing document:
if (!is_server_or_database_admin()) {
if (!!oldDoc) {
throw({
forbidden: 'You may not update existing documents.'
});
}
}
// Where the function to define admins can be copied verbatim from the doc:
var is_server_or_database_admin = function(userCtx, secObj) {
// see if the user is a server admin
if(userCtx.roles.indexOf('_admin') !== -1) {
return true; // a server admin
}
// see if the user a database admin specified by name
if(secObj && secObj.admins && secObj.admins.names) {
if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
return true; // database admin
}
}
// see if the user a database admin specified by role
if(secObj && secObj.admins && secObj.admins.roles) {
var db_roles = secObj.admins.roles;
for(var idx = 0; idx < userCtx.roles.length; idx++) {
var user_role = userCtx.roles[idx];
if(db_roles.indexOf(user_role) !== -1) {
return true; // role matches!
}
}
}
return false; // default to no admin
}
}
If you followed these steps then the user you gave the logger role in step 1 can run your code to write new documents only in logger database configured in steps 2 and 3.
Overview
Couchdb has one overriding level of administrator setup in configuration instead of setup in the _users
database and assigned the _admin
permission to prevent any possibility of being locked out.
Each individual database then has a rough level security policy of 2 levels:
- admins
- members
specified via:
- names
- roles
making 4 fields.
These levels control access slightly differently for the 2 types of documents a db can contain:
- id:
_design/*
- Design documents can contain functions that will be executed in some context - id:
other
- Normal documents are just normal data
Both levels of database access have read access to all documents in the database, but admins have write access to _design documents. Write access to normal documents is usually given to all users granted any access to the db, but can be limited by validate design documents.
To Summarize
The process for setting a unique security policy up is:
- Experience the provided validate design document as a consumer while setting up _users.
- Setup a new database and its basic security giving your users member access.
- Add a design doc to the new database with a validate function that restricts member write access.
1 Setting up _users entries
Add a role to a user
As an admin add role: ["logger"]
to a user's doc and save it, note that this must be done by admin due to this part of the default _users design document:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (oldRoles.length !== newRoles.length) {
throw({forbidden: 'Only _admin may edit roles'});
}
Change the password for the user.
Either the admin or the user can change their password by setting password:"mynewpassword"
in their document (which couchdb will transform into a hashed/salted password during the save process). This works for a user since they can add/modify fields aside from their name and roles, as long as a user is editing their own doc:
// DB: _users doc: _design/_auth
function(newDoc, oldDoc, userCtx, secObj) {
..
if (userCtx.name !== newDoc.name) {
throw({
forbidden: 'You may only update your own user document.'
});
}
// then checks that they don't modify roles
You could repeat this process with a user you assign an adminlogger
role to create a delegated administrator that you assign permissions to can reconfigure a database or you can continue to use the couchdb admin with its _admin
role for all administration.
2 Setup a new database and its basic security
Create a db named logger
assign the logger a security policy:
{
"admins": {
"names": [
],
"roles": [
"adminlogger"
]
},
"members": {
"names": [
],
"roles": [
"logger"
]
}
}
3. Create a new validate design document in the new db
As either _admin user or a user with the adminlogger
role create a new validate design doc by copying the _users design document, removing the _rev and modifying the function:
// DB: logger doc: _design/auth
function(newDoc, oldDoc, userCtx, secObj) {
// Don't let non-admins write a pre-existing document:
if (!is_server_or_database_admin()) {
if (!!oldDoc) {
throw({
forbidden: 'You may not update existing documents.'
});
}
}
// Where the function to define admins can be copied verbatim from the doc:
var is_server_or_database_admin = function(userCtx, secObj) {
// see if the user is a server admin
if(userCtx.roles.indexOf('_admin') !== -1) {
return true; // a server admin
}
// see if the user a database admin specified by name
if(secObj && secObj.admins && secObj.admins.names) {
if(secObj.admins.names.indexOf(userCtx.name) !== -1) {
return true; // database admin
}
}
// see if the user a database admin specified by role
if(secObj && secObj.admins && secObj.admins.roles) {
var db_roles = secObj.admins.roles;
for(var idx = 0; idx < userCtx.roles.length; idx++) {
var user_role = userCtx.roles[idx];
if(db_roles.indexOf(user_role) !== -1) {
return true; // role matches!
}
}
}
return false; // default to no admin
}
}
If you followed these steps then the user you gave the logger role in step 1 can run your code to write new documents only in logger database configured in steps 2 and 3.
edited Dec 3 '18 at 10:30
answered Nov 23 '18 at 20:39
lossleaderlossleader
9,43011829
9,43011829
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my_users
db only has the design doc (even though I had created users using the permissions window in fauxton)
– robotHamster
Dec 2 '18 at 23:44
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
add a comment |
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my_users
db only has the design doc (even though I had created users using the permissions window in fauxton)
– robotHamster
Dec 2 '18 at 23:44
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my
_users
db only has the design doc (even though I had created users using the permissions window in fauxton)– robotHamster
Dec 2 '18 at 23:44
Thanks for the explanation! This is embarrasing but I've been scratching my head for a while and cant find the "user docs" you are referring to. my
_users
db only has the design doc (even though I had created users using the permissions window in fauxton)– robotHamster
Dec 2 '18 at 23:44
1
1
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
@robotHamster it sounds like you were adding _admins instead of normal users? You can create a user in the _usersdb by creating a new document with the fields in 1.7.2.2, you can do it in fauxton as long as you change the _id field from a random one to org.couchdb.user:[username] (1.7.2.1).
– lossleader
Dec 3 '18 at 10:37
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384941%2fcouchdb-write-read-only-no-edit-user%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown