Merge lp://staging/~sil/desktopcouch/create-oauth-tokens-startup into lp://staging/desktopcouch

Proposed by Stuart Langridge
Status: Rejected
Rejected by: Elliot Murphy
Proposed branch: lp://staging/~sil/desktopcouch/create-oauth-tokens-startup
Merge into: lp://staging/desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp://staging/~sil/desktopcouch/create-oauth-tokens-startup
Reviewer Review Type Date Requested Status
Mark G. Saye (community) Needs Fixing
Elliot Murphy (community) Needs Fixing
Joshua Blount (community) Approve
Review via email: mp+10481@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Stuart Langridge (sil) wrote :

Add oauth tokens as part of initial desktopcouch setup, and lock desktopcouch access to authenticated users only.

(NB: do not merge into desktopcouch trunk until http://issues.apache.org/jira/browse/COUCHDB-478 is in your couchdb build, or this will prevent access to your desktop Couch; it sets up an admin user in the ini file, but oauth authentication doesn't read from the ini file in Couch trunk; that's what the above patch is for.)

Revision history for this message
Joshua Blount (jblount) :
review: Approve
Revision history for this message
Elliot Murphy (statik) wrote :

I've packaged 0.10.0~svn806985~ppa1, which is a snapshot of the 0.10 branch that Jan created today, + the part of the patch for COUCHDB-478 that has not been applied to the branch yet.

After merging with trunk and resolving the merge conflicts, I get errors on a number of tests, all appear to have the same cause: 401 on a HEAD request.

===============================================================================
[ERROR]: desktopcouch.records.tests.test_server.TestCouchDatabase.test_record_exists

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/testtools/testcase.py", line 161, in run
    self.setUp()
  File "/home/emurphy/canonical/ubuntuone/shared/desktopcouch/trunk/desktopcouch/records/tests/test_server.py", line 44, in setUp
    self.dbname, create=True, uri=URI)
  File "/home/emurphy/canonical/ubuntuone/shared/desktopcouch/trunk/desktopcouch/records/server.py", line 58, in __init__
    if database not in self._server:
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 124, in __contains__
    self.resource.head(validate_dbname(name))
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 981, in head
    return self._request('HEAD', path, headers=headers, **params)
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 1035, in _request
    raise ServerError((status_code, error))
couchdb.client.ServerError: (401, '')
===============================================================================
[ERROR]: desktopcouch.records.tests.test_server.TestCouchDatabase.test_update_fields

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/testtools/testcase.py", line 161, in run
    self.setUp()
  File "/home/emurphy/canonical/ubuntuone/shared/desktopcouch/trunk/desktopcouch/records/tests/test_server.py", line 44, in setUp
    self.dbname, create=True, uri=URI)
  File "/home/emurphy/canonical/ubuntuone/shared/desktopcouch/trunk/desktopcouch/records/server.py", line 58, in __init__
    if database not in self._server:
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 124, in __contains__
    self.resource.head(validate_dbname(name))
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 981, in head
    return self._request('HEAD', path, headers=headers, **params)
  File "/usr/lib/pymodules/python2.6/couchdb/client.py", line 1035, in _request
    raise ServerError((status_code, error))
couchdb.client.ServerError: (401, '')

review: Needs Fixing
Revision history for this message
Stuart Langridge (sil) wrote :

> I've packaged 0.10.0~svn806985~ppa1, which is a snapshot of the 0.10 branch
> that Jan created today, + the part of the patch for COUCHDB-478 that has not
> been applied to the branch yet.
>
> After merging with trunk and resolving the merge conflicts, I get errors on a
> number of tests, all appear to have the same cause: 401 on a HEAD request.

Yep. This is a COuch bug (http://issues.apache.org/jira/browse/COUCHDB-479) the fix for which has not yet been merged into trunk :-(

Revision history for this message
Stuart Langridge (sil) wrote :

> > I've packaged 0.10.0~svn806985~ppa1, which is a snapshot of the 0.10 branch
> > that Jan created today, + the part of the patch for COUCHDB-478 that has not
> > been applied to the branch yet.
> >
> > After merging with trunk and resolving the merge conflicts, I get errors on
> a
> > number of tests, all appear to have the same cause: 401 on a HEAD request.
>
> Yep. This is a COuch bug (http://issues.apache.org/jira/browse/COUCHDB-479)
> the fix for which has not yet been merged into trunk :-(

Ah, it may have been merged now, looking at the bug report, but I don't know if it's in our packages yet...

Revision history for this message
Mark G. Saye (markgsaye) wrote :
Download full text (5.6 KiB)

> bzr merge lp:~sil/desktopcouch/create-oauth-tokens-startup
 M data/couchdb.tmpl
 M desktopcouch/start_local_couchdb.py
Text conflict in desktopcouch/start_local_couchdb.py
1 conflicts encountered.

> bzr diff desktopcouch/start_local_couchdb.py
=== modified file 'desktopcouch/start_local_couchdb.py'
--- desktopcouch/start_local_couchdb.py 2009-08-21 22:45:24 +0000
+++ desktopcouch/start_local_couchdb.py 2009-08-24 11:12:48 +0000
@@ -34,14 +34,16 @@
 """

 from __future__ import with_statement
-import os, subprocess, sys, glob
+import os, subprocess, sys, glob, random, string
 import desktopcouch
 from desktopcouch import local_files
 import xdg.BaseDirectory
 import errno
-import time
+import time, gtk, gnomekeyring
 from desktopcouch.records.server import CouchDatabase

+ACCEPTABLE_USERNAME_PASSWORD_CHARS = string.lowercase + string.uppercase
+
 def dump_ini(data, filename):
     """Dump INI data with sorted sections and keywords"""
     fd = open(filename, 'w')
@@ -60,9 +62,38 @@
         ini_path=local_files.FILE_INI, db_dir=local_files.DIR_DB,
         log_path=local_files.FILE_LOG, port="0"):
     """Write CouchDB ini file if not already present"""
+<<<<<<< TREE
     if os.path.exists(ini_path):
         return
     ini = {
+=======
+ if os.path.exists(local_files.FILE_INI):
+ # load the username and password from the keyring
+ try:
+ data = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,
+ {'desktopcouch': 'basic'})
+ except gnomekeyring.NoMatchError:
+ data = None
+ if data:
+ username, password = data[0].secret.split(":")
+ return username, password
+ # otherwise fall through; for some reason the access details aren't
+ # in the keyring, so re-create the ini file and do it all again
+
+ # randomly generate tokens and usernames
+ def make_random_string(count):
+ return ''.join([random.choice(ACCEPTABLE_USERNAME_PASSWORD_CHARS)
+ for x in range(count)])
+
+ ADMIN_ACCOUNT_USERNAME = make_random_string(10)
+ ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD = make_random_string(10)
+ CONSUMER_KEY = make_random_string(10)
+ CONSUMER_SECRET = make_random_string(10)
+ TOKEN = make_random_string(10)
+ TOKEN_SECRET = make_random_string(10)
+
+ local = {
+>>>>>>> MERGE-SOURCE
         'couchdb': {
             'database_dir': db_dir,
             'view_index_dir': db_dir,
@@ -75,10 +106,51 @@
             'file': log_path,
             'level': 'info',
         },
+ 'admins': {
+ ADMIN_ACCOUNT_USERNAME: ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD
+ },
+ 'oauth_consumer_secrets': {
+ CONSUMER_KEY: CONSUMER_SECRET
+ },
+ 'oauth_token_secrets': {
+ TOKEN: TOKEN_SECRET
+ },
+ 'oauth_token_users': {
+ TOKEN: ADMIN_ACCOUNT_USERNAME
+ },
+ 'couch_httpd_auth': {
+ 'require_valid_user': 'true'
+ }
     }
+<<<<<<< TREE
     dump...

Read more...

review: Needs Fixing
Revision history for this message
Elliot Murphy (statik) wrote :

> Ah, it may have been merged now, looking at the bug report, but I don't know
> if it's in our packages yet...

Yep, I made sure that the commit which included the purported fix for COUCHDB-479 was included in the couchdb snapshot, but looks like the fix for COUCHDB-479 was broken. We're waiting for couchdb devs to give us a working fix.

Revision history for this message
Elliot Murphy (statik) wrote :

rejecting this branch, and merging thisfreds noauth, which combines everything as we discussed this morning.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/couchdb.tmpl'
--- data/couchdb.tmpl 2009-07-14 13:53:21 +0000
+++ data/couchdb.tmpl 2009-08-20 12:55:54 +0000
@@ -31,7 +31,7 @@
31come back to browse your CouchDB again.</p>31come back to browse your CouchDB again.</p>
32<p>Don't bookmark the CouchDB page itself, because its location may change!</p>32<p>Don't bookmark the CouchDB page itself, because its location may change!</p>
33<p>Taking you to your Desktop CouchDB in <span>30</span> seconds...33<p>Taking you to your Desktop CouchDB in <span>30</span> seconds...
34<a id="there" href="http://localhost:[[COUCHDB_PORT]]/_utils">take me34<a id="there" href="http://[[COUCHDB_USERNAME]]:[[COUCHDB_PASSWORD]]@localhost:[[COUCHDB_PORT]]/_utils">take me
35there straight away from now on</a> (remember to bookmark this page first!)</p>35there straight away from now on</a> (remember to bookmark this page first!)</p>
36</body>36</body>
37</html>37</html>
3838
=== modified file 'desktopcouch/start_local_couchdb.py'
--- desktopcouch/start_local_couchdb.py 2009-08-19 16:00:01 +0000
+++ desktopcouch/start_local_couchdb.py 2009-08-20 12:55:54 +0000
@@ -32,14 +32,16 @@
32"""32"""
3333
34from __future__ import with_statement34from __future__ import with_statement
35import os, subprocess, sys, glob35import os, subprocess, sys, glob, random, string
36import desktopcouch36import desktopcouch
37from desktopcouch import local_files37from desktopcouch import local_files
38import xdg.BaseDirectory38import xdg.BaseDirectory
39import errno39import errno
40import time40import time, gtk, gnomekeyring
41from desktopcouch.records.server import CouchDatabase41from desktopcouch.records.server import CouchDatabase
4242
43ACCEPTABLE_USERNAME_PASSWORD_CHARS = string.lowercase + string.uppercase
44
43def dump_ini(data, filename):45def dump_ini(data, filename):
44 """Dump INI data with sorted sections and keywords"""46 """Dump INI data with sorted sections and keywords"""
45 fd = open(filename, 'w')47 fd = open(filename, 'w')
@@ -56,18 +58,31 @@
5658
57def create_ini_file():59def create_ini_file():
58 """Write CouchDB ini file if not already present"""60 """Write CouchDB ini file if not already present"""
59 # FIXME add update trigger folder
60 #update_trigger_dir = [
61 # 'lib', 'canonical', 'ubuntuone', 'cloud_server', 'update_triggers']
62 #
63 #timestamp_trigger = os.path.join(
64 # *update_trigger_dir + ['timestamp_trigger.py'])
65 #update_trigger = os.path.join(
66 # *update_trigger_dir + ['update_trigger.py'])
67
68 if os.path.exists(local_files.FILE_INI):61 if os.path.exists(local_files.FILE_INI):
69 return62 # load the username and password from the keyring
7063 try:
64 data = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,
65 {'desktopcouch': 'basic'})
66 except gnomekeyring.NoMatchError:
67 data = None
68 if data:
69 username, password = data[0].secret.split(":")
70 return username, password
71 # otherwise fall through; for some reason the access details aren't
72 # in the keyring, so re-create the ini file and do it all again
73
74 # randomly generate tokens and usernames
75 def make_random_string(count):
76 return ''.join([random.choice(ACCEPTABLE_USERNAME_PASSWORD_CHARS)
77 for x in range(count)])
78
79 ADMIN_ACCOUNT_USERNAME = make_random_string(10)
80 ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD = make_random_string(10)
81 CONSUMER_KEY = make_random_string(10)
82 CONSUMER_SECRET = make_random_string(10)
83 TOKEN = make_random_string(10)
84 TOKEN_SECRET = make_random_string(10)
85
71 local = {86 local = {
72 'couchdb': {87 'couchdb': {
73 'database_dir': local_files.DIR_DB,88 'database_dir': local_files.DIR_DB,
@@ -81,9 +96,43 @@
81 'file': local_files.FILE_LOG,96 'file': local_files.FILE_LOG,
82 'level': 'info',97 'level': 'info',
83 },98 },
99 'admins': {
100 ADMIN_ACCOUNT_USERNAME: ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD
101 },
102 'oauth_consumer_secrets': {
103 CONSUMER_KEY: CONSUMER_SECRET
104 },
105 'oauth_token_secrets': {
106 TOKEN: TOKEN_SECRET
107 },
108 'oauth_token_users': {
109 TOKEN: ADMIN_ACCOUNT_USERNAME
110 },
111 'couch_httpd_auth': {
112 'require_valid_user': 'true'
113 }
84 }114 }
85115
86 dump_ini(local, local_files.FILE_INI)116 dump_ini(local, local_files.FILE_INI)
117 # save admin account details in keyring
118 item_id = gnomekeyring.item_create_sync(
119 None,
120 gnomekeyring.ITEM_GENERIC_SECRET,
121 'Desktop Couch user authentication',
122 {'desktopcouch': 'basic'},
123 "%s:%s" % (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD),
124 True)
125 # and oauth tokens
126 item_id = gnomekeyring.item_create_sync(
127 None,
128 gnomekeyring.ITEM_GENERIC_SECRET,
129 'Desktop Couch user authentication',
130 {'desktopcouch': 'oauth'},
131 "%s:%s:%s:%s" % (CONSUMER_KEY, CONSUMER_SECRET, TOKEN, TOKEN_SECRET),
132 True)
133
134
135 return (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD)
87136
88def run_couchdb():137def run_couchdb():
89 """Actually start the CouchDB process"""138 """Actually start the CouchDB process"""
@@ -146,7 +195,7 @@
146 # than inefficiently just overwriting it regardless195 # than inefficiently just overwriting it regardless
147 db.add_view(view_name, mapjs, reducejs, dd_name)196 db.add_view(view_name, mapjs, reducejs, dd_name)
148197
149def write_bookmark_file():198def write_bookmark_file(username, password):
150 """Write out an HTML document that the user can bookmark to find their DB"""199 """Write out an HTML document that the user can bookmark to find their DB"""
151 bookmark_file = os.path.join(local_files.DIR_DB, "couchdb.html")200 bookmark_file = os.path.join(local_files.DIR_DB, "couchdb.html")
152201
@@ -182,21 +231,24 @@
182 pass231 pass
183 else:232 else:
184 fp = open(bookmark_file, "w")233 fp = open(bookmark_file, "w")
185 fp.write(html.replace("[[COUCHDB_PORT]]", port))234 out = html.replace("[[COUCHDB_PORT]]", port)
235 out = out.replace("[[COUCHDB_USERNAME]]", username)
236 out = out.replace("[[COUCHDB_PASSWORD]]", password)
237 fp.write(out)
186 fp.close()238 fp.close()
187 print "Browse your desktop CouchDB at file://%s" % \239 print "Browse your desktop CouchDB at file://%s" % \
188 os.path.realpath(bookmark_file)240 os.path.realpath(bookmark_file)
189241
190def start_couchdb():242def start_couchdb():
191 """Execute each step to start a desktop CouchDB"""243 """Execute each step to start a desktop CouchDB"""
192 create_ini_file()244 username, password = create_ini_file()
193 run_couchdb()245 run_couchdb()
194 # Note that we do not call update_design_documents here. This is because246 # Note that we do not call update_design_documents here. This is because
195 # Couch won't actually have started yet, so when update_design_documents247 # Couch won't actually have started yet, so when update_design_documents
196 # calls the Records API, that will call back into get_pid and we end up248 # calls the Records API, that will call back into get_pid and we end up
197 # starting Couch again. Instead, get_pid calls update_design_documents249 # starting Couch again. Instead, get_pid calls update_design_documents
198 # *after* Couch startup has occurred.250 # *after* Couch startup has occurred.
199 write_bookmark_file()251 write_bookmark_file(username, password)
200252
201253
202if __name__ == "__main__":254if __name__ == "__main__":

Subscribers

People subscribed via source and target branches