Return-Path: X-Original-To: apmail-couchdb-user-archive@www.apache.org Delivered-To: apmail-couchdb-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C200385A3 for ; Tue, 16 Aug 2011 10:22:52 +0000 (UTC) Received: (qmail 25185 invoked by uid 500); 16 Aug 2011 10:22:50 -0000 Delivered-To: apmail-couchdb-user-archive@couchdb.apache.org Received: (qmail 24809 invoked by uid 500); 16 Aug 2011 10:22:42 -0000 Mailing-List: contact user-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@couchdb.apache.org Delivered-To: mailing list user@couchdb.apache.org Received: (qmail 24800 invoked by uid 99); 16 Aug 2011 10:22:39 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 10:22:39 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [209.85.213.180] (HELO mail-yx0-f180.google.com) (209.85.213.180) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 10:22:31 +0000 Received: by yxi11 with SMTP id 11so5353317yxi.11 for ; Tue, 16 Aug 2011 03:22:10 -0700 (PDT) Received: by 10.42.28.133 with SMTP id n5mr5451082icc.77.1313490130131; Tue, 16 Aug 2011 03:22:10 -0700 (PDT) MIME-Version: 1.0 Received: by 10.42.173.1 with HTTP; Tue, 16 Aug 2011 03:21:50 -0700 (PDT) In-Reply-To: References: <4E371B93.8060303@kearns.net.au> From: Jason Smith Date: Tue, 16 Aug 2011 17:21:50 +0700 Message-ID: Subject: Re: to CouchApp or not to CouchApp To: user@couchdb.apache.org Content-Type: text/plain; charset=UTF-8 X-Virus-Checked: Checked by ClamAV on apache.org On Tue, Aug 16, 2011 at 4:31 PM, Marcello Nuccio wrote: >> Things to think about regarding CouchDB security: >> >> * Authentication: basic, cookie, BrowserID, http vs. https >> * Users >> * Roles >> * Database security objects >> * validate_doc_update() functions in each database >> >> I am pretty sure that is exhaustive. The best starting point to learn >> about CouchDB security is the "Definitive Guide" book. > > Thank you for audit_couchdb, Jason. It's a very useful tool. > > The missing piece for me is the ability to require authentication for > read access to a couchapp, in a browser friendly way [1]. > > Unfortunately (for me) this looks like a very rare use-case, so it > does not raise much interest... I hope to learn some Erlang soon, to > contribute to this issue... If that is a rare use-case then CouchDB is doomed. I think that issue, COUCHDB-1175, will eventually find a good solution. But, IMHO, CouchDB does not need Erlang development! It desperately needs developer tools and application components. It's time to ask whether the word "couchapp" does more harm than good. As a historical phenomenon, it is brilliant! The command-line tool is brilliant. But the word is meaningless. It is incoherent. It disappoints developers, setting expectations and then betraying them. I suggest that you drop down one level of abstraction. There is HTTP; there is CouchDB. You can fetch or store records, and use design documents. Now think about how to "cut with the grain" to achieve your goal. What are your requirements? 1. You have a database which is non-public. Users must log in first, no exceptions. Okay, so: private data. 2. You have a web page (the login prompt) which is public. Anonymous users must access it. Okay, so: public data. To me, that sounds like two databases, and three roles: anonymous, normal, and developer. 1. The welcome_mat database. Effectively this is an open-source app. * Readable by the public: _security.readers = [] * No updates allowed by anonymous users * No updates allowed by normal users * Yes updates if ("developer" in userCtx.roles) 2. The private_stuff database, has all of your application data and design docs except the welcome mat. * Not readable by the public: _security.readers = ["normal", "developer"] * Updates by anonymous users is not possible [1] * Yes updates by normal users: ("normal" in userCtx.roles) * No updates by developers: ("developer" in userCtx.roles) // that role is for software updates only Regarding the Accept headers and the correct Content-Type: yes, CouchDB has a bug here. It will be solved soon, but maybe you can work around it? With the welcome_mat, you have an unlimited, independent, full-blown web application environment to work with. You can use a different version of jQuery compared to private_stuff. You can use no jQuery and call XMLHttpRequest directly. You can check every browser and OS combination manually and write case-by-case code for each one--if necessary. This approach has problems. You will probably be forced to use background AJAX to determine the login status, and even to authenticate. (That gives you the flexibility: query /private_stuff, and anything except 200 OK indicates a bad login.) Also, when users are already logged in to the app but their cookie expires, the experience might suffer. On the other hand, you can move past this bug and focus on other things. IMHO, it doesn't matter how COUCHDB-1175 is resolved. A serious, polished, complete application using CouchDB will probably need the welcome_mat for many other reasons anyway. That is why I say "contribute tools" rather than "contribute Erlang." We all need welcome_mat, so it is worth building. This is HTTP. This is web development. Bringing an idea to completion, nothing ever works correctly anyway. That is the platform. Nothing ever works as planned. It's one disappointment after another. But, if you can work through the bugs, you've got an app on the most successful software platform ever (the web), and IMO the most visionary web platform ever (CouchDB). So I think it's worth it. [1] For defense-in-depth, you could confirm this by either (1) throwing an exception if the userCtx is anonymous, i.e. {"name":null, "roles":[]}, and/or (2) throw an exception if the security settings are wrong, i.e. if(secObj.readers.length == 0) -- Iris Couch