Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Try to change usernames automatically (#290)
Browse files Browse the repository at this point in the history
Just needed to see how to pinpoint the case when a user is opting-in for
the first time.
  • Loading branch information
chadwhitacre committed Sep 13, 2012
1 parent fc54d00 commit 7b03954
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 43 deletions.
36 changes: 35 additions & 1 deletion gittip/networks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import random

from aspen import log
from aspen import log, Response
from aspen.utils import typecheck
from gittip import db
from psycopg2 import IntegrityError
Expand All @@ -21,6 +22,39 @@ def resolve_unclaimed(participant):
return out


ALLOWED_ASCII = set("0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
".,-_;:@ ")

def change_participant_id(website, old, suggested):
"""Raise response return None.
We want to be pretty loose with usernames. Unicode is allowed. So are
spaces. Control characters aren't. We also limit to 32 characters in
length.
"""
for i, c in enumerate(suggested):
if i == 32:
raise Response(413) # Request Entity Too Large (more or less)
elif ord(c) < 128 and c not in ALLOWED_ASCII:
raise Response(400) # Yeah, no.
elif c not in ALLOWED_ASCII:
raise Response(400) # XXX Burned by an Aspen bug. :`-(
# https://github.com/whit537/aspen/issues/102

if suggested in os.listdir(website.www_root):
raise Response(400)

if suggested != old:
rec = db.fetchone( "UPDATE participants SET id=%s WHERE id=%s " \
"RETURNING id", (suggested, old))
# May raise IntegrityError
assert rec is not None # sanity check
assert suggested == rec['id'] # sanity check


def get_a_participant_id():
"""Return a random participant_id.
Expand Down
41 changes: 3 additions & 38 deletions www/%participant_id/participant_id.json
Original file line number Diff line number Diff line change
@@ -1,51 +1,16 @@
import os

from aspen import Response
from gittip import db
from gittip.networks import change_participant_id
from psycopg2 import IntegrityError

ALLOWED_ASCII = set("0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
".,-_;:@ ")

FILENAMES = os.listdir(website.www_root)

# ========================================================================== ^L

if user.ANON:
raise Response(404)

new_participant_id = request.body['participant_id']


# Lightly sanitize input.
# =======================
# We want to be pretty loose with usernames. Unicode is allowed. So are spaces.
# Control characters aren't. We also limit to 32 characters in length.

for i, c in enumerate(new_participant_id):
if i == 32:
raise Response(413) # Request Entity Too Large (more or less)
elif ord(c) < 128 and c not in ALLOWED_ASCII:
raise Response(400) # Yeah, no.
elif c not in ALLOWED_ASCII:
raise Response(400) # XXX Burned by an Aspen bug. :`-(
# https://github.com/whit537/aspen/issues/102

if new_participant_id in FILENAMES:
raise Response(400)


# Persist
# =======

try:
if new_participant_id != user.id:
rec = db.fetchone( "UPDATE participants SET id=%s WHERE id=%s " \
"RETURNING id", (new_participant_id, user.id))
assert rec is not None # sanity check
assert new_participant_id == rec['id'] # sanity check
change_participant_id(website, user.id, new_participant_id)
response.body = {"participant_id": new_participant_id}
except IntegrityError:
response.code = 409 # Conflict
raise Response(409) # Conflict
11 changes: 9 additions & 2 deletions www/on/github/associate
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ participants in the Gittip community.
"""
from aspen import log, Response
from gittip import db
from gittip.networks import github, set_as_claimed
from gittip.networks import change_participant_id, github, set_as_claimed
from gittip.authentication import User
from psycopg2 import IntegrityError

# ========================== ^L

Expand All @@ -33,7 +34,13 @@ if login is None:
log(u"%s wants to %s" % (login, action))
if action == 'opt-in': # opt in
participant_id, is_claimed, is_locked, balance = github.upsert(user_info)
set_as_claimed(participant_id)
if not is_claimed:
try:
change_participant_id(website, participant_id, login)
participant_id = login
except (Response, IntegrityError):
pass
set_as_claimed(participant_id)
user = User.from_id(participant_id) # give them a session
else: # lock or unlock
if then != login:
Expand Down
11 changes: 9 additions & 2 deletions www/on/twitter/associate
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import requests
from oauth_hook import OAuthHook
from aspen import log, Response, json
from gittip import db
from gittip.networks import twitter, set_as_claimed
from gittip.networks import change_participant_id, twitter, set_as_claimed
from gittip.authentication import User
from urlparse import parse_qs
from psycopg2 import IntegrityError

# ========================== ^L

Expand Down Expand Up @@ -62,7 +63,13 @@ user_info['html_url'] = "https://twitter.com/" + screen_name
log(u"%s wants to %s" % (screen_name, action))
if action == 'opt-in': # opt in
participant_id, is_claimed, is_locked, balance = twitter.upsert(user_info)
set_as_claimed(participant_id)
if not is_claimed:
try:
change_participant_id(website, participant_id, screen_name)
participant_id = screen_name
except (Response, IntegrityError):
pass
set_as_claimed(participant_id)
user = User.from_id(participant_id) # give them a session
else: # lock or unlock
if then != screen_name:
Expand Down

0 comments on commit 7b03954

Please sign in to comment.