Merge lp:~sil/desktopcouch/not-so-random into lp:desktopcouch

Proposed by Stuart Langridge
Status: Rejected
Rejected by: Elliot Murphy
Proposed branch: lp:~sil/desktopcouch/not-so-random
Merge into: lp:desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp:~sil/desktopcouch/not-so-random
Reviewer Review Type Date Requested Status
Elliot Murphy (community) Approve
Tim Cole (community) Approve
Review via email: mp+10654@code.launchpad.net

Commit message

Use SystemRandom for passwords/tokens where proper unpredictable randomness matters.

To post a comment you must log in.
Revision history for this message
Stuart Langridge (sil) wrote :

Use SystemRandom for passwords/tokens where proper unpredictable randomness matters.

Revision history for this message
Tim Cole (tcole) :
review: Approve
Revision history for this message
Elliot Murphy (statik) :
review: Approve
Revision history for this message
Elliot Murphy (statik) wrote :

text conflict in desktopcouch/start_local_couchdb.py

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

text conflict in desktopcouch/start_local_couchdb.py

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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-25 13:22:30 +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,32 @@
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([
67+ random.SystemRandom().choice(ACCEPTABLE_USERNAME_PASSWORD_CHARS)
68+ for x in range(count)])
69+
70+ ADMIN_ACCOUNT_USERNAME = make_random_string(10)
71+ ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD = make_random_string(10)
72+ CONSUMER_KEY = make_random_string(10)
73+ CONSUMER_SECRET = make_random_string(10)
74+ TOKEN = make_random_string(10)
75+ TOKEN_SECRET = make_random_string(10)
76+
77 local = {
78 'couchdb': {
79 'database_dir': local_files.DIR_DB,
80@@ -81,9 +97,43 @@
81 'file': local_files.FILE_LOG,
82 'level': 'info',
83 },
84+ 'admins': {
85+ ADMIN_ACCOUNT_USERNAME: ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD
86+ },
87+ 'oauth_consumer_secrets': {
88+ CONSUMER_KEY: CONSUMER_SECRET
89+ },
90+ 'oauth_token_secrets': {
91+ TOKEN: TOKEN_SECRET
92+ },
93+ 'oauth_token_users': {
94+ TOKEN: ADMIN_ACCOUNT_USERNAME
95+ },
96+ 'couch_httpd_auth': {
97+ 'require_valid_user': 'true'
98+ }
99 }
100
101 dump_ini(local, local_files.FILE_INI)
102+ # save admin account details in keyring
103+ item_id = gnomekeyring.item_create_sync(
104+ None,
105+ gnomekeyring.ITEM_GENERIC_SECRET,
106+ 'Desktop Couch user authentication',
107+ {'desktopcouch': 'basic'},
108+ "%s:%s" % (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD),
109+ True)
110+ # and oauth tokens
111+ item_id = gnomekeyring.item_create_sync(
112+ None,
113+ gnomekeyring.ITEM_GENERIC_SECRET,
114+ 'Desktop Couch user authentication',
115+ {'desktopcouch': 'oauth'},
116+ "%s:%s:%s:%s" % (CONSUMER_KEY, CONSUMER_SECRET, TOKEN, TOKEN_SECRET),
117+ True)
118+
119+
120+ return (ADMIN_ACCOUNT_USERNAME, ADMIN_ACCOUNT_BASIC_AUTH_PASSWORD)
121
122 def run_couchdb():
123 """Actually start the CouchDB process"""
124@@ -146,7 +196,7 @@
125 # than inefficiently just overwriting it regardless
126 db.add_view(view_name, mapjs, reducejs, dd_name)
127
128-def write_bookmark_file():
129+def write_bookmark_file(username, password):
130 """Write out an HTML document that the user can bookmark to find their DB"""
131 bookmark_file = os.path.join(local_files.DIR_DB, "couchdb.html")
132
133@@ -182,21 +232,24 @@
134 pass
135 else:
136 fp = open(bookmark_file, "w")
137- fp.write(html.replace("[[COUCHDB_PORT]]", port))
138+ out = html.replace("[[COUCHDB_PORT]]", port)
139+ out = out.replace("[[COUCHDB_USERNAME]]", username)
140+ out = out.replace("[[COUCHDB_PASSWORD]]", password)
141+ fp.write(out)
142 fp.close()
143 print "Browse your desktop CouchDB at file://%s" % \
144 os.path.realpath(bookmark_file)
145
146 def start_couchdb():
147 """Execute each step to start a desktop CouchDB"""
148- create_ini_file()
149+ username, password = create_ini_file()
150 run_couchdb()
151 # Note that we do not call update_design_documents here. This is because
152 # Couch won't actually have started yet, so when update_design_documents
153 # calls the Records API, that will call back into get_pid and we end up
154 # starting Couch again. Instead, get_pid calls update_design_documents
155 # *after* Couch startup has occurred.
156- write_bookmark_file()
157+ write_bookmark_file(username, password)
158
159
160 if __name__ == "__main__":

Subscribers

People subscribed via source and target branches