Questions about Gauth integration

31 views
Skip to first unread message

pdohe...@gmail.com

unread,
Mar 8, 2019, 1:40:38 PM3/8/19
to djangae-users
I'm following the "Gauth authentication" portion of the documentation but I'm running into some unexpected behavior.

I've configured urls.py and settings.py as specified by the documentation (the current settings are mostly a result of using the Djangae Scaffold) but at no point are users prompted to authenticate using or link their Google account. I've tried un/setting `DJANGAE_CREATE_UNKNOWN_USER` but this has no impact. (Perhaps this is because I'm running my app in development mode?)

I've also tried running commands inspired by sitepackages/prod/djangae/contrib/gauth/tests.py in my local shell in order to verify that the back-end configuration is correctly configured and that users can actually be authenticated against AppEngineUserAPIBackend but that fails because my User model (djangae.contrib.gauth_datastore.models.GaeDatastoreUser) seems to be missing required attributes: `AttributeError: 'GaeDatastoreUser' object has no attribute 'user_id'`.

So, am I misunderstanding how this is all supposed to work or have I (likely) misconfigured my application? (I'm happy to include genericized versions of my config, but as I said, they've come directly from Djangae Scaffold or the documentation.)

Any clarification or pointers to more comprehensive tutorials would be greatly appreciated.

Environment:
Djangae (0.9.11)
Django (1.11.19)

Luke Benstead

unread,
Mar 8, 2019, 2:49:05 PM3/8/19
to pdohe...@gmail.com, djangae-users
Hi!

Have you put something like @login_required (from django.contrib.auth.decorators) on your views?

--
You received this message because you are subscribed to the Google Groups "djangae-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to djangae-user...@googlegroups.com.
To post to this group, send email to djanga...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/djangae-users/3062993c-fcf4-4544-94c0-54e02ca6b70c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--

--
Luke Benstead
p.ota.to

pdohe...@gmail.com

unread,
Mar 8, 2019, 2:58:48 PM3/8/19
to djangae-users
Hi, Luke! Thanks for following up.

Yes. I have added that decorator and when the user lands on the page they see the standard login form (see below). They're able to enter _any_ email address and login when `DJANGAE_CREATE_UNKNOWN_USER=True` and get caught in an infinite loop when `DJANGAE_CREATE_UNKNOWN_USER=False`. In the first case, the `user` variable is populated, but there is no link to anything Google related and they aren't ever prompted to link their account or anything. 

djangae-login.png



Interestingly, I just noticed that when I run my Behave test suite with that decorator in place the browser _does_ get redirected to https://accounts.google.com/Login?continue=http://localhost:8080/ (This results in a 400 error page, but I'll address that problem once I can get there consistently from my dev environment.)

Luke Benstead

unread,
Mar 8, 2019, 3:00:39 PM3/8/19
to pdohe...@gmail.com, djangae-users
Aha, locally that is what you're supposed to see when you log in (for testing) - if you deploy that to App Engine though you'll be directed through Google sign in.


For more options, visit https://groups.google.com/d/optout.

pdohe...@gmail.com

unread,
Mar 8, 2019, 4:12:37 PM3/8/19
to djangae-users
Thanks. That's very good to know. For anyone who comes across this thread in the future, the behavior described above is documented here: https://cloud.google.com/appengine/docs/standard/python/users/#Python_Google_accounts_and_the_development_server

There are a few documentation improvements I've been thinking about submitting PRs for and I will add this to the list. I think it'd be very useful to have a summary of this behavior and a link to the App Engine user docs present in Djangae's Gauth entry. 

Now that all of that is out of the way, do you happen to know if:

1.) there a recommended way of simulating the App Engine user object during development? (For instance, in order to call methods like User#nickname.)
2.) how to prevent the Selenium browser from trying to kick off the production app/Google/app redirect flow?

Thanks for your help and quick replies! The Potato team has been very helpful and I've greatly enjoyed working with Djangae. :)

Adam Alton

unread,
Mar 11, 2019, 7:21:14 AM3/11/19
to pdohe...@gmail.com, djangae-users
1.) there a recommended way of simulating the App Engine user object during development? (For instance, in order to call methods like User#nickname.)

The `google.appengine.api.users` API is still available, so you can import that and then call `users.get_current_user()` to get the User object.  Or for mocking things in tests you can use `users.User` and instantiate your own instance of a User object.

Note that if you're using Gauth but you're also accessing the `google.appengine.api.users` API directly then you can potentially get yourself in a twist.  If you've got Gauth configured correctly, then `request.user.username` should always be the same user ID as `google.appengine.api.users.get_current_user().user_id()`, but just be aware that if you're accessing the users API directly then there's the potential to confuse things.

2.) how to prevent the Selenium browser from trying to kick off the production app/Google/app redirect flow?

I'm not very familiar with Selenium, but I guess the first question is: why do you want to prevent it from going through that flow? 

pdohe...@gmail.com

unread,
Mar 11, 2019, 8:16:07 AM3/11/19
to djangae-users
> The `google.appengine.api.users` API is still available, so you can import that and then call `users.get_current_user()` to get the User object.  Or for mocking things in tests you can use `users.User` and instantiate your own instance of a User object.

This is useful information. Thanks.

> I'm not very familiar with Selenium, but I guess the first question is: why do you want to prevent it from going through that flow? 

I would expect the test sandbox would behave like the local sandbox with respect to GAuth redirect behavior. (Even more so, really, as fewer/no external HTTP requests will result in faster, more robust test suite runs.)

I haven't looked into this issue since the end of the last week, but perhaps it's possible to achieve the same behavior or use the local sandbox by passing kwargs to test_execute_from_command_line. Though, my worry about using the local sandbox would be that my local/dev database would be destroyed after the test run.

Adam Alton

unread,
Mar 25, 2019, 1:37:28 PM3/25/19
to pdohe...@gmail.com, djangae-users
Apologies for the slow reply.
 
I would expect the test sandbox would behave like the local sandbox with respect to GAuth redirect behavior. (Even more so, really, as fewer/no external HTTP requests will result in faster, more robust test suite runs.)
 
I haven't looked into this issue since the end of the last week, but perhaps it's possible to achieve the same behavior or use the local sandbox by passing kwargs to test_execute_from_command_line. Though, my worry about using the local sandbox would be that my local/dev database would be destroyed after the test run.

Ah, so are you saying that there's currently a difference between the auth flow when running tests on the SDK (i.e. manage.py test) and when running the SDK server (i.e. manage.py runserver)?

Adam

pdohe...@gmail.com

unread,
Mar 26, 2019, 3:03:52 PM3/26/19
to djangae-users
> Ah, so are you saying that there's currently a difference between the auth flow when running tests on the SDK (i.e. manage.py test) and when running the SDK server (i.e. manage.py runserver)?

Yes. That is the behavior I was seeing which prompted me to start this thread.

Adam Alton

unread,
Mar 27, 2019, 7:24:43 AM3/27/19
to pdohe...@gmail.com, djangae-users
Ah, right.  I thought it was about the difference between production and local.

Right, so when running the local server, the login flow redirects to http://localhost:8000/_ah/login?continue=/path/, but when running the tests locally, the login flow redirects to https://www.google.com/accounts/Login?continue=http%3A//localhost%3A8080/path/.

The behaviour for the server is correct, in that it uses the fake login flow so that you can test using different logins locally.  Why that behaviour changes when running the tests I'm not entirely sure.  It would need some digging into the SDK code for `google.appengine.api.users.create_login_url` to see what it's doing and why it behaves differently when running the tests.

My guess is that it's something to do with the SDK's Testbed module.  In djangae, where we setup the sandbox for the test environment, we use the testbed (code).  And that presumably somehow results in the 'init_user_stub' method of the Testbed being called.  And my guess is that maybe `enable=True` is being passed (or not being overridden), which results in it trying to use the 'real' service rather than the fake service which the local server uses.

Maybe this is as simple as extending the MINIMAL_STUBS dict to have an entry for `initi_user_stub` with `{"enable": False}`?

Adam



Reply all
Reply to author
Forward
0 new messages