Background Image
Table of Contents Table of Contents
Previous Page  319 / 478 Next Page
Information
Show Menu
Previous Page 319 / 478 Next Page
Page Background

Creating a User if Necessary

Next we should check that, if our

authenticate

function has a valid assertion from

Persona, but we don’t have a user record for that person in our database, we should

create one. Here’s the test for that:

accounts/tests/test_authentication.py (ch16l027).

def

test_creates_new_user_if_necessary_for_valid_assertion

(

self

,

mock_post

):

mock_post

.

return_value

.

json

.

return_value

=

{

'status'

:

'okay'

,

'email'

:

'a@b.com'

}

found_user

=

self

.

backend

.

authenticate

(

'an assertion'

)

new_user

=

User

.

objects

.

get

(

email

=

'a@b.com'

)

self

.

assertEqual

(

found_user

,

new_user

)

That fails in our application code when we try find an existing user with that email:

return User.objects.get(email=response.json()['email'])

django.contrib.auth.models.DoesNotExist: User matching query does not exist.

So we add a

try/except

, returning an “empty” user at first:

accounts/authentication.py (ch16l028).

if

response

.

ok

and

response

.

json

()[

'status'

]

==

'okay'

:

try

:

return

User

.

objects

.

get

(

email

=

response

.

json

()[

'email'

])

except

User

.

DoesNotExist

:

return

User

.

objects

.

create

()

And that fails, but this time it fails when the

test

tries to find the new user by email:

new_user = User.objects.get(email=

'a@b.com'

)

django.contrib.auth.models.DoesNotExist: User matching query does not exist.

And so we fix it by assigning the correct email addresss:

accounts/authentication.py (ch16l029).

if

response

.

ok

and

response

.

json

()[

'status'

]

==

'okay'

:

email

=

response

.

json

()[

'email'

]

try

:

return

User

.

objects

.

get

(

email

=

email

)

except

User

.

DoesNotExist

:

return

User

.

objects

.

create

(

email

=

email

)

That gets us to passing tests:

$

python3 manage.py test accounts

[...]

Ran 9 tests in 0.019s

OK

The get_user Method

The next thing we have to build is a

get_user

method for our authentication backend.

This method’s job is to retrieve a user based on their email address, or to return

None

if

it can’t find one. (That last wasn’t well documented at the time of writing, but that is the

interface we have to comply with. See

the source

for details.)

De-spiking Our Custom Authentication Backend: Mocking Out an Internet Request

|

291