jbholden / cdcpool_google

0 stars 1 forks source link

Creating poolers #11

Open blreams opened 10 years ago

blreams commented 10 years ago

Before anyone can participate in the pool, they must become a valid pooler. This will require some form of registration. Registering requires the following information:

  1. Name (I suggest we require first and last name)
  2. Username (for login purposes, must be unique)
  3. Handle (alternate display string used on website reports, must be unique within our site)
  4. Email address (communication of deadlines, reminders, password resets, etc.)
  5. Password (I suggest we go with self-selected rather than randomly generated and sent to their email address with required password change upon first login)

Their name will have to be uniquified (to allow for poolers with the same name). But by requiring their name we can keep history on them.

Question 1: What requirements do we impose on Username? Min length? Max length? What character set is valid? Case sensitive?

Question 2: What requirements do we impose on Handle?

We should verify their email address to make sure it is functional. We could send them an email with a link that finalizes their registration.

Question 3: What requirements do we impose on Password? In addition to the above should we also impose: upper and lower case? mix of numbers, letters and special characters?

jbholden commented 10 years ago

Google Sign-In Have you given any thought about using the google sign in or do you want to go the custom route? https://developers.google.com/appengine/docs/python/users/

SSL I think we might be able to use SSL (this would be good for the login page) by doing this: https://developers.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Secure_URLs

Admin There should be a way to mark a user as "admin" and restrict access to the admin pages

Question 1 and Question 3 I would suggest copying what was done in the udacity web development class unless you want to do something else.

def valid_username(username):
    USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
    return USER_RE.match(username) != None

def valid_password(password):
    PASSWORD_RE = re.compile(r"^.{3,20}$")
    return PASSWORD_RE.match(password) != None

def valid_email(email):
    EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
    return EMAIL_RE.match(email) != None

Question 2 Is the handle the name that would show up on the leaderboard pages? It would be nice if this allowed you to identify the user in some manner. When viewing a leaderboard I would like to know the person that finished first, ahead of me, behind me, etc.

blreams commented 10 years ago

Using Google sign-in sure would be simpler all the way around. Likewise, it would be nice to allow poolers to sign in using other OpenID providers (Yahoo, Hotmail, Facebook, etc.). Either option relieves us of the burden of storing encrypted/hashed/salted/secreted passwords (which is a big obligation).

Why don't we operate under the assumption that all of our poolers would be willing to create a Google login if they don't already have one. Once we get further along I'll feel out our user base to see if anyone has any great heartburn over using a Google login to participate (not sure what to do if someone balks...we'll just have to play it by ear).

Given that assumption, we will have each pooler's email address. What other information do we need to collect?

As for Handle, I was thinking that some poolers may not want their name (and especially their email address) displayed on a publicly available website. What do you think about this. If we require our poolers to provide a unique handle, then we can display that on results pages if accessed without first logging in. Once they are logged in, they will see poolers' names instead.

If we allow poolers to sign-in using Google credentials, we still have to validate them as a legitimate pooler, right? I mean what if some unknown Google user signs in and we don't recognize who they are...we don't want them to have free run of the site.

blreams commented 10 years ago

We also need to collect timezone preference from the pooler.

jbholden commented 10 years ago

From a recent email: I did find a fairly self-contained implementation of user accounts for webapp2 along with a tutorial blog on github (https://github.com/abahgat/webapp2-user-accounts). It seemed straightforward although I didn't quite get how they were storing user info in the datastore. But once you set it up, it looked like all you had to do was to add a decorator to any of the handlers that required authentication. Would have to add to it the ability to have admin privileges for a subset of users. Also, I'm not sure how we link an authenticated user to a Player in the current datastore.

Also from an email: Question 2: Once we implement user authentication, is it reasonable to roll that out to allow people to view pool results online (ie. they would have to sign-up/register to create a login, then use that login to see the pool online).

jbholden commented 10 years ago

Here is an attempt to summarize how the Player class will change.

Before:

class Player(db.Model):
    name = db.StringProperty(required=True)
    years = db.ListProperty(int,required=True)

After:

class Player(db.Model):
    # name is the full name of the individual, what format?  "Brent Holden" or "Holden, Brent"
    # this name would show up if a user was logged in
    name = db.StringProperty(required=True)  

    # this name would show up on the public site (anyone can see it)
    handle = db.StringProperty(required=True)

    # same as above, years that the player has been in the pool
    years = db.ListProperty(int,required=True)

    # this would indicate if a player has paid for the year?  do we need this?
    years_paid = db.ListProperty(int,required=True)

    # this would be used to associate a signed in user with a Player
    # this is assigned at registration time (I'm not sure if type is string or not)
    user_id = db.StringProperty(required=True)

    # as described in above post, email used to send updates to
    alternate_email = db.EmailProperty()

    # as described in above post, email used for payments
    remote_payment_email = db.EmailProperty()

A couple of other things: