Merge lp://staging/~sil/desktopcouch/create-oauth-tokens-startup into lp://staging/desktopcouch
- create-oauth-tokens-startup
- Merge into trunk
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 | ||||
Related bugs: |
|
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 |
Commit message
Description of the change
Stuart Langridge (sil) wrote : | # |
Joshua Blount (jblount) : | # |
Elliot Murphy (statik) wrote : | # |
I've packaged 0.10.0~
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.
Traceback (most recent call last):
File "/usr/lib/
self.setUp()
File "/home/
self.dbname, create=True, uri=URI)
File "/home/
if database not in self._server:
File "/usr/lib/
self.
File "/usr/lib/
return self._request(
File "/usr/lib/
raise ServerError(
couchdb.
=======
[ERROR]: desktopcouch.
Traceback (most recent call last):
File "/usr/lib/
self.setUp()
File "/home/
self.dbname, create=True, uri=URI)
File "/home/
if database not in self._server:
File "/usr/lib/
self.
File "/usr/lib/
return self._request(
File "/usr/lib/
raise ServerError(
couchdb.
Stuart Langridge (sil) wrote : | # |
> I've packaged 0.10.0~
> 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://
Stuart Langridge (sil) wrote : | # |
> > I've packaged 0.10.0~
> > 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://
> 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...
Mark G. Saye (markgsaye) wrote : | # |
> bzr merge lp:~sil/desktopcouch/create-oauth-tokens-startup
M data/couchdb.tmpl
M desktopcouch/
Text conflict in desktopcouch/
1 conflicts encountered.
> bzr diff desktopcouch/
=== modified file 'desktopcouch/
--- desktopcouch/
+++ desktopcouch/
@@ -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.
+ACCEPTABLE_
+
def dump_ini(data, filename):
"""Dump INI data with sorted sections and keywords"""
fd = open(filename, 'w')
@@ -60,9 +62,38 @@
"""Write CouchDB ini file if not already present"""
+<<<<<<< TREE
if os.path.
return
ini = {
+=======
+ if os.path.
+ # load the username and password from the keyring
+ try:
+ data = gnomekeyring.
+ {'desktopcouch': 'basic'})
+ except gnomekeyring.
+ data = None
+ if data:
+ username, password = data[0]
+ 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_
+ return ''.join(
+ for x in range(count)])
+
+ ADMIN_ACCOUNT_
+ ADMIN_ACCOUNT_
+ CONSUMER_KEY = make_random_
+ CONSUMER_SECRET = make_random_
+ TOKEN = make_random_
+ TOKEN_SECRET = make_random_
+
+ local = {
+>>>>>>> MERGE-SOURCE
'couchdb': {
@@ -75,10 +106,51 @@
},
+ 'admins': {
+ ADMIN_ACCOUNT_
+ },
+ 'oauth_
+ CONSUMER_KEY: CONSUMER_SECRET
+ },
+ 'oauth_
+ TOKEN: TOKEN_SECRET
+ },
+ 'oauth_
+ TOKEN: ADMIN_ACCOUNT_
+ },
+ 'couch_httpd_auth': {
+ 'require_
+ }
}
+<<<<<<< TREE
dump...
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.
Elliot Murphy (statik) wrote : | # |
rejecting this branch, and merging thisfreds noauth, which combines everything as we discussed this morning.
Unmerged revisions
Preview Diff
1 | === modified file 'data/couchdb.tmpl' |
2 | --- data/couchdb.tmpl 2009-07-14 13:53:21 +0000 |
3 | +++ data/couchdb.tmpl 2009-08-20 12:55:54 +0000 |
4 | @@ -31,7 +31,7 @@ |
5 | come back to browse your CouchDB again.</p> |
6 | <p>Don't bookmark the CouchDB page itself, because its location may change!</p> |
7 | <p>Taking you to your Desktop CouchDB in <span>30</span> seconds... |
8 | -<a id="there" href="http://localhost:[[COUCHDB_PORT]]/_utils">take me |
9 | +<a id="there" href="http://[[COUCHDB_USERNAME]]:[[COUCHDB_PASSWORD]]@localhost:[[COUCHDB_PORT]]/_utils">take me |
10 | there straight away from now on</a> (remember to bookmark this page first!)</p> |
11 | </body> |
12 | </html> |
13 | |
14 | === modified file 'desktopcouch/start_local_couchdb.py' |
15 | --- desktopcouch/start_local_couchdb.py 2009-08-19 16:00:01 +0000 |
16 | +++ desktopcouch/start_local_couchdb.py 2009-08-20 12:55:54 +0000 |
17 | @@ -32,14 +32,16 @@ |
18 | """ |
19 | |
20 | from __future__ import with_statement |
21 | -import os, subprocess, sys, glob |
22 | +import os, subprocess, sys, glob, random, string |
23 | import desktopcouch |
24 | from desktopcouch import local_files |
25 | import xdg.BaseDirectory |
26 | import errno |
27 | -import time |
28 | +import time, gtk, gnomekeyring |
29 | from desktopcouch.records.server import CouchDatabase |
30 | |
31 | +ACCEPTABLE_USERNAME_PASSWORD_CHARS = string.lowercase + string.uppercase |
32 | + |
33 | def dump_ini(data, filename): |
34 | """Dump INI data with sorted sections and keywords""" |
35 | fd = open(filename, 'w') |
36 | @@ -56,18 +58,31 @@ |
37 | |
38 | def create_ini_file(): |
39 | """Write CouchDB ini file if not already present""" |
40 | - # FIXME add update trigger folder |
41 | - #update_trigger_dir = [ |
42 | - # 'lib', 'canonical', 'ubuntuone', 'cloud_server', 'update_triggers'] |
43 | - # |
44 | - #timestamp_trigger = os.path.join( |
45 | - # *update_trigger_dir + ['timestamp_trigger.py']) |
46 | - #update_trigger = os.path.join( |
47 | - # *update_trigger_dir + ['update_trigger.py']) |
48 | - |
49 | if os.path.exists(local_files.FILE_INI): |
50 | - return |
51 | - |
52 | + # load the username and password from the keyring |
53 | + try: |
54 | + data = gnomekeyring.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET, |
55 | + {'desktopcouch': 'basic'}) |
56 | + except gnomekeyring.NoMatchError: |
57 | + data = None |
58 | + if data: |
59 | + username, password = data[0].secret.split(":") |
60 | + return username, password |
61 | + # otherwise fall through; for some reason the access details aren't |
62 | + # in the keyring, so re-create the ini file and do it all again |
63 | + |
64 | + # randomly generate tokens and usernames |
65 | + def make_random_string(count): |
66 | + return ''.join([random.choice(ACCEPTABLE_USERNAME_PASSWORD_CHARS) |
67 | + for x in range(count)]) |
68 | + |
69 | + ADMIN_ACCOUNT_USERNAME = make_random_string(10) |
70 | + ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD = make_random_string(10) |
71 | + CONSUMER_KEY = make_random_string(10) |
72 | + CONSUMER_SECRET = make_random_string(10) |
73 | + TOKEN = make_random_string(10) |
74 | + TOKEN_SECRET = make_random_string(10) |
75 | + |
76 | local = { |
77 | 'couchdb': { |
78 | 'database_dir': local_files.DIR_DB, |
79 | @@ -81,9 +96,43 @@ |
80 | 'file': local_files.FILE_LOG, |
81 | 'level': 'info', |
82 | }, |
83 | + 'admins': { |
84 | + ADMIN_ACCOUNT_USERNAME: ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD |
85 | + }, |
86 | + 'oauth_consumer_secrets': { |
87 | + CONSUMER_KEY: CONSUMER_SECRET |
88 | + }, |
89 | + 'oauth_token_secrets': { |
90 | + TOKEN: TOKEN_SECRET |
91 | + }, |
92 | + 'oauth_token_users': { |
93 | + TOKEN: ADMIN_ACCOUNT_USERNAME |
94 | + }, |
95 | + 'couch_httpd_auth': { |
96 | + 'require_valid_user': 'true' |
97 | + } |
98 | } |
99 | |
100 | dump_ini(local, local_files.FILE_INI) |
101 | + # save admin account details in keyring |
102 | + item_id = gnomekeyring.item_create_sync( |
103 | + None, |
104 | + gnomekeyring.ITEM_GENERIC_SECRET, |
105 | + 'Desktop Couch user authentication', |
106 | + {'desktopcouch': 'basic'}, |
107 | + "%s:%s" % (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD), |
108 | + True) |
109 | + # and oauth tokens |
110 | + item_id = gnomekeyring.item_create_sync( |
111 | + None, |
112 | + gnomekeyring.ITEM_GENERIC_SECRET, |
113 | + 'Desktop Couch user authentication', |
114 | + {'desktopcouch': 'oauth'}, |
115 | + "%s:%s:%s:%s" % (CONSUMER_KEY, CONSUMER_SECRET, TOKEN, TOKEN_SECRET), |
116 | + True) |
117 | + |
118 | + |
119 | + return (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD) |
120 | |
121 | def run_couchdb(): |
122 | """Actually start the CouchDB process""" |
123 | @@ -146,7 +195,7 @@ |
124 | # than inefficiently just overwriting it regardless |
125 | db.add_view(view_name, mapjs, reducejs, dd_name) |
126 | |
127 | -def write_bookmark_file(): |
128 | +def write_bookmark_file(username, password): |
129 | """Write out an HTML document that the user can bookmark to find their DB""" |
130 | bookmark_file = os.path.join(local_files.DIR_DB, "couchdb.html") |
131 | |
132 | @@ -182,21 +231,24 @@ |
133 | pass |
134 | else: |
135 | fp = open(bookmark_file, "w") |
136 | - fp.write(html.replace("[[COUCHDB_PORT]]", port)) |
137 | + out = html.replace("[[COUCHDB_PORT]]", port) |
138 | + out = out.replace("[[COUCHDB_USERNAME]]", username) |
139 | + out = out.replace("[[COUCHDB_PASSWORD]]", password) |
140 | + fp.write(out) |
141 | fp.close() |
142 | print "Browse your desktop CouchDB at file://%s" % \ |
143 | os.path.realpath(bookmark_file) |
144 | |
145 | def start_couchdb(): |
146 | """Execute each step to start a desktop CouchDB""" |
147 | - create_ini_file() |
148 | + username, password = create_ini_file() |
149 | run_couchdb() |
150 | # Note that we do not call update_design_documents here. This is because |
151 | # Couch won't actually have started yet, so when update_design_documents |
152 | # calls the Records API, that will call back into get_pid and we end up |
153 | # starting Couch again. Instead, get_pid calls update_design_documents |
154 | # *after* Couch startup has occurred. |
155 | - write_bookmark_file() |
156 | + write_bookmark_file(username, password) |
157 | |
158 | |
159 | if __name__ == "__main__": |
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.)