Securing couchdb and pouchdb replication - couchdb

I am trying to get my head around security in couchdb replication. I am looking at using pouchdb locally on clients and have the clients sync with a central couchdb. Each client has a doc that only they should be able to sync bidirectionally. How do I ensure users can only sync their own documents, yet have shared documents replicated one-way from couchdb to clients?

One database per user is quite common for CouchDB. In that case, you can allow each user to only access his own database:
https://stackoverflow.com/a/11686674
If each user needs just one document, then each database contains just one doc!

You can use "pouchdb-authentication" (https://github.com/nolanlawson/pouchdb-authentication)to secure your connection and PouchDB itself to sync the data with a remote CouchDB server (https://pouchdb.com/api.html#sync).
Use a "_design" document in each database to restrict access in a users database.

Related

Node Express Backend. How to manage mongodb connections? Mongodb users or collection of users?

I am developing a frontend with ANGULAR and backend with Node and Express. Is a simple backend for internal use in my company with a small quantity of users: 15-20. The backend connects to Mongodb. The mongo server is started with authentication and I can create users with built-in roles in mongo: read, write, etc.
But all the examples I found in tutorials usually creates a collection of users instead of using the mongodb built-in users.
As far I know, if use built-in mongo users I need to start a new connection for each user because the user and password is part of the Connection String URI
I have some doubts:
Is it a bad idea to use built-in users?
If I use built-in users. How to manage the logout of the user? I don't find examples.
"Users" in this context is usually connections to the database.
Lets say you have a database with data serving several applications. One which only has access to read the data, and another to write and update. You can make sure the read only app, wont write with 2 users of the database. Typically, you'll also have an admin user that has global all access for administrators.
When your coworkers wish to update some data through the second application. The application will authenticate to the database and write on their behalf. Whether or not someone has access to use the application to update data is not something the database should decide.
I hope this helps to understand the context of "user"

CouchDB Design for POS applciation

I am working to create POS(Point of sale) application using couchdb with angular. Since i am beginner to NoSQL world. Need guidance to how to design the system.
It should be cloud based application, where login user can create companies and each company has n locations.
In relational database sense, my database design look like this.
While logging to my application, username & password validated against license db. If they are valid application will connect their own company db.
Whenever user create new company, new database will be created, all their locations, invoices, payments are in their own db.
License db responsible for user accounts, payments and their plan and level of security(which screen they can access/edit).
The application has offline support using PouchDB. where relevant location details are downloaded to user browser, and they synced back to server DB.
Questions:
Is it ok to create database for each company.
If user wants offline operation, they can sync own location data only(filtered replication), if they want to access other location data, application should connect cloud DB.Is it possible?
I want the same code to query/insert data in couchdb & PouchDB. Is it possible?
Is couchdb map-reduce/mango query support complex reports
Is Angular+Couchdb is enough, or do I need any server side framework.I don't any third-party authentication right now.
How the above relational database design should be implemented in couch db
what are the other things i should think about this software design
Yes. One common design for CouchDB is to have a database per user. One per company is totally reasonable.
CouchDB supports filtered replication. You could setup a filtered replication for user's documents on a local database instance (PouchDB or CouchDB)
PouchDB allows you to connect to CouchDB. Basically, you could have a PouchDB library that does all your business operations. You would only need to change the database adapter for the cloud or client database.
Map/Reduce is pretty straight forward. It allows you to index documents and query them by their keys. You can easily change the values in your indexes and also use reduce functions. Mango queries are more flexible. A bit similar to MongoDB.
You might eventually needs an application layer but that's possible to use only CouchDB.

What are the advantages of CouchDB's validate_doc_update over a pre-DB validation server?

I am building a tiny service with API in front of a CouchDB database.
For the API, I needed to build a script verifying and pre-filtering user requests to achieve doc-specific read permissions.
I am still using CouchDB's user management for user accounts, but every request goes through an nodejs/express server that then builds the requests to the DBs.
Now I am wondering whether I should
use the design_docs and validate_doc_update functions of CouchDBs own query server to filter document updates
or
I can manage document updates within my express-server by checking the _security doc from there.
I suppose because the query-server talks directly to CouchDB through stdio validate_doc_update has performance advantages? How great are they over making a get-request to a CouchDB _security doc and the following with an insert request to CouchDB?
Are there any other advantages of one approach over the other?

How to only show documents to specific users in a shared database?

I'm managing a multiuser app using Ionic 3.x, PouchDB, CouchDB and a node.js server running Superlogin. The app is steadily growing and I want to introduce a new feature.
My app has normal users and superusers. Each normal and superuser in my application gets it's own user database. There is also a shared database, let's call it the generaldb.
And here's my problem: Both users can create documents. These documents are synced to the userdb as well as to the general db. These documents have, amongst other things, a keyword (e.g. "colour": "green"). Superusers have access to a specific key. (In the above example that would mean that there are for example 5 superusers who can access the key green.)
Now, no normal user should be able to read, update or write other user's documents on the generaldb. Superusers should be able to read, update or write documents in the generaldb depending on which key they have access to. But they should not be allowed to change documents that don't match their key.
How can I restrict access for normal users in the generaldb, so that only documents created by themselves are synced to their devices and so that they couldn't change other users documents?
How can I ensure, superusers can change normal users documents, as long as they have access to the correct key?
How can I ensure superusers cannot change their own key, so that when number 2 is accomplished, they cannot manually work around the system?
One of the ideas of mine is to only let the users access their own db and have the shared db only accessible by superusers and then do a filtered replication of the userdb to the shared db. But this only solves 1 and seems very inefficient.

What is the standard way to represent "business-logic users" in CouchDB?

I'm new to couchDB and still reading tutorials. My question is if it is the normal way to represent every user of my application as a new database user, as it seems to be explained that way everywhere I look?
Let's say I have an online game with many different players - would I create a new "database user" for every player who registers? Or would I make my own database "players" and create a sign-in logic in the app? Not being used to document-driven DB's it seems strange to me not to distinguish between db-users and users of my application...
You could do it either way. First about couchdb users
Users in couchdb are stored in a special _users database
Database permissions are handled by a special _security document. This is specific to every database.
In security documents you add users that you have already stored in the _users database previously.
So you can certainly create a database per user. Before doing that ask yourself if the data that you store in each database is truly independent. Because you can't run map reduce queries across databases. So if you are planning to do aggregation across data for different users then this approach will not work.
Couchdb can also help you with app level authentication. Since couchdb uses a cookie based authentication:
Store your "business logic users" in the special _users database.
Authenticate it with the _session endpoint.
Extract the cookie header and sent it with your application headers.
All the logic for authentication is implemented for you by couchdb. All you have got to do is manipulate headers. Send the cookie from your application and when authenticating with couchdb send it with couchdb's headers.
If you prefer to write entire session management in your application that is fine too. In this case simply store the users in your database and verify that they exist before authenticating them. Like you would do with another database.
The benefit of using couchdb is that it is secure by default --using pbkdf2 encryption scheme to encrypt passwords.
If you instead want to manage all docs using a single database, but still implementing read/write ACLs, you can check the Chatty Couchapp Tutorial app from Smileupps App Store
It's a pure couchapp, relying on CouchDB only as its backend. The tutorial is still work in progress but the couchapp is fully working and you can download its source code.
It implements role/user based read/write ACLs using a single CouchDB database. This way you don't have to setup N replications where N depends on the number of your users. You only have one database containing all your data, easy to be queried on the fly(with temporary views) and for maintenance operations. Of course you can decide to increase the number of database, depending on type of your data and use cases.
A single couchapp contains all the necessary code for frontend, admin dashboard and server side API implementing business rules
The user, depending on his roles have different access to different sections. i.e. he can access the frontend website, but not the admin dashboard.
You can install the free trial, then download the source code with Smileupps deployment tools, change it, upload it back and check your changes.

Resources