Google App Engine using UserProperty to link data - python

I am writing an application in GAE. In order to link the currently logged in user to data in my application I have been relying on equality between users.get_current_user() and members.user (see model below). Where I run into trouble is when the user signs in with an email address using different capitalization than his/her initial login (janeDoe#example.com != janedoe#example.com). What is the most reliable way to link the current user to application specific data?
class members(db.Model):
firstName=db.StringProperty(verbose_name='First Name',required=True)
lastName=db.StringProperty(verbose_name='Last Name',required=True)
user=db.UserProperty()

Don't use the username - call user.user_id(), and compare on that. It's guaranteed to remain the same, even if nickname or email address change.

Always convert username to lowercase and then do operations on it: when storing the first time and on later comparisons.

Related

Where does flask store token for password recovery?

I need to provide password recovery token in order to test it's functionality with integration test. But I can't trace the place its stored.
Apparently it doesn't. It hashes the user's current password [hash] and their id and sends that as token. Which is entirely reasonable, since that's already user-specific information stored in the database, no need to generate yet another token. And it will even invalidate itself once the password has been changed. I'd probably add a timestamp somewhere in there though so the link isn't valid forever.

Clean email field when new user is registering in Django?

As I know, standard new user process registration (Django 2.x) is validate email field only for exists and equals for E-mail Schemas. But users may be write e-mail address like this: JOHN_DOE#MAIL.COM (via Caps Lock) and save it to DB.
It's would be dangerous, because other user can register account for these e-mail, but in lowercase: john_doe#mail.com or similar, but still that e-mail address!
So, question now is how to (smart) clean up e-mail address when user is registering?. My ideas:
set email to lowercase before save to DB
check if it exist/unique in DB (in lowercase view, of course)
I search for best practice for solve this question, btw.
I would change it to lowercase and then save it because it looks like the least number of operations to be done. Also it should make the shortest code.
If you'll decide to check if it's unique in lowercase in DB and then save it you may end up checking DB two times (one when first check, 2nd when saving) if you'll implement it in wrong way.

Can facebook test users be verified?

It seems someone has asked this question before. However it is focus on the username, which I don't care about.
I have added a real email address to my test user and confirmed it by clicking on the verification email. However the test user is still marked as unverified.
This is a big problem when unit testing with test users.
graph = facebook.GraphAPI(oauth_access_token)
me = graph.get_object("me")
if 'verified' not in me or not me['verified']:
return False
I can't pass this line in my unit test, since test users are always unverified.
Any advice please?
https://developers.facebook.com/docs/graph-api/reference/v2.1/user:
Someone is considered verified if they take any of the following actions:
- Register for mobile
- Confirm their account via SMS
- Enter a valid credit card
… so simply confirming an email address does not even qualify as a “verified” criterion according to this.
If you do get an email back from the API, it should be confirmed by the user already. (Otherwise FB will not give it out in the first place.)
But you will not get an email address for every user. The user does not necessarily even have an email address on file with FB, so don’t rely on getting one to use in your app in the first place.

I can't send Emails using Django non-rel on GAE

Im trying to send a simple email to do the password recover of a user, the input is just a email to send the new password..
But i can't... i get this error
SMTPServerDisconnected: please run connect() first
I already tried a few examples, like, https://bitbucket.org/andialbrecht/appengine_emailbackends/overview, but i get the same error
I really need this, maybe someone can tell me how to use an alternative to code in my view to send an email...Also i changed the backend to
EMAIL_BACKEND = 'djangoappengine.mail.EmailBackend'
but nothing,i don't know how to use this backend anyway :(
Plz Help :(
maybe someone can tell me how to use an alternative to code in my view to send an email...
I can help with this, seeing as it seems that perhaps this repository you're trying to use is based on an earlier version of App Engine and is throwing the error due to a required code change somewhere in the library - either that or the fact that you changed the string from what the library recommends (your version: 'djangoappengine.mail.EmailBackend') to a string that seems to not be correct, as it's different to what the author of the repository directed you to use (their version: 'appengine_emailbackend.EmailBackend'), and this is causing trouble.
Whenever possible, I'd recommend seeing if there is an "app-engine-y" way to do something, before going to a third-party library or deploying a module somebody else wrote to hack in third-party capabilities, or looking for an advanced/experimental feature (for example, use Datastore first, rather than remotely connecting to a MySQL VM, unless you need MySQL). If you absolutely need that library, this is a different story, but if you just want to send emails, the Mail API is what you need. It's a convenient way to send emails on App Engine.
I'm going to assume in the following that you are storing your user's usernames and hashed passwords in custom-defined User-kind entities in your Datastore. If you have your users using simple OAuth to sign into your site, there is never any reason to "reset/recover password":
Create the <form action="/some/route" action="POST"> element on
the page where the user requests password recovery.
Put the code responsible for handling this form submission (they will input their email, or whatever account info they need for your code to find their User entity in the Datastore in a handler that will respond on that route.
In the handler, generate a unique token and store it in the Datastore. Send the token in the email that you generate and send using the Mail API (see the example code in the link to the docs I provided). This will allow your user to return to your site, authenticate with the token from the email, and then fill out a form to create a new password. You will then hash this password (with a salt) and store it in their User entity in your Datastore.
I'm skipping over the details of how to implement a "password recovery form", given what I said about OAuth and that you are probably really only concerned with how to send mail. In the email you send, for example, you can insert a hyperlink to your site with the token already inserted as a query param, so that the user doesn't have to copy and paste, etc.

Generating unique and opaque user IDs in Google App Engine

I'm working on an application that lets registered users create or upload content, and allows anonymous users to view that content and browse registered users' pages to find that content - this is very similar to how a site like Flickr, for example, allows people to browse its users' pages.
To do this, I need a way to identify the user in the anonymous HTTP GET request. A user should be able to type http://myapplication.com/browse/<userid>/<contentid> and get to the right page - should be unique, but mustn't be something like the user's email address, for privacy reasons.
Through Google App Engine, I can get the email address associated with the user, but like I said, I don't want to use that. I can have users of my application pick a unique user name when they register, but I would like to make that optional if at all possible, so that the registration process is as short as possible.
Another option is to generate some random cookie (a GUID?) during the registration process, and use that, I don't see an obvious way of guaranteeing uniqueness of such a cookie without a trip to the database.
Is there a way, given an App Engine user object, of getting a unique identifier for that object that can be used in this way?
I'm looking for a Python solution - I forgot that GAE also supports Java now. Still, I expect the techniques to be similar, regardless of the language.
Your timing is impeccable: Just yesterday, a new release of the SDK came out, with support for unique, permanent user IDs. They meet all the criteria you specified.
I think you should distinguish between two types of users:
1) users that have logged in via Google Accounts or that have already registered on your site with a non-google e-mail address
2) users that opened your site for the first time and are not logged in in any way
For the second case, I can see no other way than to generate some random string (e.g. via uuid.uuid4() or from this user's session cookie key), as an anonymous user does not carry any unique information with himself.
For users that are logged in, however, you already have a unique identifier -- their e-mail address. I agree with your privacy concerns -- you shouldn't use it as an identifier. Instead, how about generating a string that seems random, but is in fact generated from the e-mail address? Hashing functions are perfect for this purpose. Example:
>>> import hashlib
>>> email = 'user#host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'
>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7
As hashlib.sha1 is not a random function, but for given data returns always the same result, but it is proven to be practically irreversible, you can safely present the hashed key on the website without compromising user's e-mail address. Also, you can safely assume that no two hashes of distinct e-mails will be the same (they can be, but probability of it happening is very, very small). For more information on hashing functions, consult the Wikipedia entry.
Do you mean session cookies?
Try http://code.google.com/p/gaeutilities/
What DzinX said. The only way to create an opaque key that can be authenticated without a database roundtrip is using encryption or a cryptographic hash.
Give the user a random number and hash it or encrypt it with a private key. You still run the (tiny) risk of collisions, but you can avoid this by touching the database on key creation, changing the random number in case of a collision. Make sure the random number is cryptographic, and add a long server-side random number to prevent chosen plaintext attacks.
You'll end up with a token like the Google Docs key, basically a signature proving the user is authenticated, which can be verified without touching the database.
However, given the pricing of GAE and the speed of bigtable, you're probably better off using a session ID if you really can't use Google's own authentication.

Categories