Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Disabling account deletion button for now, since deletion hits resour…

…ce limits; switching to MD5 hash of Google user ID as sync user name; added logout URL to start page
  • Loading branch information...
commit 2bb1a2cefc0fa98b08e471d0e5c4236655c6d931 1 parent 58e9bcd
@lmorchard authored
View
8 controllers/main.py
@@ -5,7 +5,7 @@
base_dir = os.path.dirname( os.path.dirname(__file__) )
sys.path.extend([ os.path.join(base_dir, d) for d in ('lib', 'extlib') ])
-import random, string, logging
+import random, string, logging, hashlib
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util, template
@@ -34,7 +34,8 @@ def get(self):
return self.render_template('main/start.html', {
'user': user,
'profile': profile,
- 'sync_url': '%s/sync/' % self.request.application_url
+ 'sync_url': '%s/sync/' % self.request.application_url,
+ 'logout_url': users.create_logout_url(self.request.uri)
})
def post(self):
@@ -49,8 +50,9 @@ def post(self):
# Create a new profile, with auto-generated password
new_profile = Profile(
+ user = user,
user_id = user.user_id(),
- user_name = user.nickname(),
+ user_name = hashlib.md5(user.user_id()).hexdigest(),
password = Profile.generate_password()
)
new_profile.put()
View
4 htdocs/css/main.css
@@ -1,4 +1,8 @@
/**
* Main styles
*/
+.sync_details { }
+.sync_details tr { }
+.sync_details tr th { width: 15ex; vertical-align: top; text-align: right; padding: 0.5em 0.25em 0.5em 0.25em; }
+.sync_details tr td { padding: 0.5em 0.25em 0.5em 0.25em; }
View
1  index.yaml
@@ -43,4 +43,3 @@ indexes:
# manually, move them above the marker line. The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.
-
View
41 lib/fxsync/models.py
@@ -14,8 +14,21 @@
WBO_PAGE_SIZE = 25
+def paginate(items, page_len):
+ """Paginage a list of items into a list of page lists"""
+ total_len = len(items)
+ num_pages = total_len / page_len
+ (d, m) = divmod(total_len, page_len)
+ if m > 0:
+ num_pages += 1
+ return (
+ items[ (i * page_len):(i * page_len + page_len) ]
+ for i in xrange(num_pages)
+ )
+
class Profile(db.Model):
"""Sync profile associated with logged in account"""
+ user = db.UserProperty(auto_current_user_add=True)
user_name = db.StringProperty(required=True)
user_id = db.StringProperty(required=True)
password = db.StringProperty(required=True)
@@ -46,28 +59,18 @@ def authenticate(cls, user_name, password):
return ( profile and profile.password == password )
def delete(self):
- w_keys = []
c_keys = []
cs = Collection.all().ancestor(self)
for c in cs:
c_keys.append(c.key())
- w_keys.extend(WBO.all(keys_only=True).ancestor(c))
- db.delete(w_keys)
+ while True:
+ # HACK: This smells like trouble - switch to Task Queue?
+ w_keys = WBO.all(keys_only=True).ancestor(c).fetch(500)
+ if not w_keys: break
+ db.delete(w_keys)
db.delete(c_keys)
db.Model.delete(self)
-def paginate(items, page_len):
- """Paginage a list of items into a list of page lists"""
- total_len = len(items)
- num_pages = total_len / page_len
- (d, m) = divmod(total_len, page_len)
- if m > 0:
- num_pages += 1
- return (
- items[ (i * page_len):(i * page_len + page_len) ]
- for i in xrange(num_pages)
- )
-
class Collection(db.Model):
profile = db.ReferenceProperty(Profile, required=True)
name = db.StringProperty(required=True)
@@ -78,7 +81,11 @@ class Collection(db.Model):
)
def delete(self):
- db.delete(WBO.all(keys_only=True).ancestor(self))
+ while True:
+ # HACK: This smells like trouble - switch to Task Queue?
+ w_keys = WBO.all(keys_only=True).ancestor(self).fetch(500)
+ if not w_keys: break
+ db.delete(w_keys)
db.Model.delete(self)
def retrieve(self,
@@ -156,6 +163,8 @@ def retrieve(self,
keys = [db.Key(x) for x in key_set]
key_pages = paginate(keys, WBO_PAGE_SIZE)
+ # Use the key pages for a combo result here.
+
final_query = WBO.all().ancestor(self).filter('__key__ IN', keys)
# Determine which sort order to use.
View
25 templates/main/start.html
@@ -3,9 +3,10 @@
{% block page_title %}Sync Start{% endblock %}
{% block content %}
-<h1>Sync Start</h1>
+<h1>Sync Profile</h1>
-<p>You are logged in as: <code>{{ user.nickname }}</code></p>
+<p>You are logged in as <code>{{ user.nickname }}</code>
+ (<a href="{{ logout_url }}">logout</a>).</p>
{% if not profile %}
@@ -16,27 +17,29 @@
</form>
{% else %}
-
- <p>A sync profile exists.</p>
- <dl>
- <dt>Server URL</dt><dd>{{sync_url}}</dd>
- <dt>User Name</dt><dd>{{ profile.user_name }}</dd>
- <dt>Password</dt>
- <dd>
+ <p>Use these custom server details when setting up Firefox Sync:</p>
+ <table class="sync_details">
+ <tr><th>Server URL</th><td>{{sync_url}}</td></tr>
+ <tr><th>User Name</th><td>{{ profile.user_name }}</td></tr>
+ <tr><th>Password</th>
+ <td>
<span>{{ profile.password }}</span>
<form action="" method="post">
<input type="hidden" name="action" value="regenerate_password" />
<input type="submit" value="Re-generate password" /></p>
</form>
- </dd>
- </dl>
+ </td></tr>
+ </table>
+ {% comment %}
+ <!-- TODO: Enable this in the future -->
<p>Would you like to delete the sync profile for this login?
<form action="" method="post">
<input type="hidden" name="action" value="delete_profile" />
<input type="submit" value="Yes, delete all my data, please." /></p>
</form>
+ {% endcomment %}
{% endif %}
View
2  test/sync_api_tests.py
@@ -714,7 +714,7 @@ def test_cascading_collection_delete(self):
def test_header_if_unmodified_since(self):
"""Ensure that X-If-Unmodified-Since header is honored in PUT / POST / DELETE"""
- pass
+ self.fail("TODO")
def build_wbo_parents_and_predecessors(self):
(p, c, ah) = (self.profile, self.collection, self.auth_header)
Please sign in to comment.
Something went wrong with that request. Please try again.