Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ Specify the desired lifespan of a token with `EXPIRING_TOKEN_LIFESPAN` in
[timedelta object](https://docs.python.org/2/library/datetime.html#timedelta-objects).
If not set, the default is 30 days.

Also there is a field called `ALWAYS_RESET_TOKEN`, which allows token to be reset everytime this is checked.
If not set, default is False

```python
import datetime
EXPIRING_TOKEN_LIFESPAN = datetime.timedelta(days=25)
ALWAYS_RESET_TOKEN = True
```

[Set the authentication scheme](http://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme) to `rest_framework_expiring_authtoken.authentication.ExpiringTokenAuthentication`
Expand Down
2 changes: 1 addition & 1 deletion rest_framework_expiring_authtoken/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ class Meta(object):
def expired(self):
"""Return boolean indicating token expiration."""
now = timezone.now()
if self.created < now - token_settings.EXPIRING_TOKEN_LIFESPAN:
if (self.created < now - token_settings.EXPIRING_TOKEN_LIFESPAN) or token_settings.ALWAYS_RESET_TOKEN:
return True
return False
16 changes: 16 additions & 0 deletions rest_framework_expiring_authtoken/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,25 @@ def EXPIRING_TOKEN_LIFESPAN(self):
"""
try:
val = settings.EXPIRING_TOKEN_LIFESPAN

except AttributeError:
val = timedelta(days=30)

return val

@property
def ALWAYS_RESET_TOKEN(self):
"""
Return if token should be reset every time at login

Defaults to False
"""
try:
val = settings.ALWAYS_RESET_TOKEN

except AttributeError:
val = False

return val

token_settings = TokenSettings()
12 changes: 12 additions & 0 deletions tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,15 @@ def test_expired_token(self):
self.assertEqual(e.__str__(), 'Token has expired')
else:
self.fail("AuthenticationFailed not raised.")

def test_always_reset_token(self):
"""Check that token always expires."""
with self.settings(ALWAYS_RESET_TOKEN=True):
sleep(0.001)

try:
self.test_instance.authenticate_credentials(self.key)
except AuthenticationFailed as e:
self.assertEqual(e.__str__(), 'Token has expired')
else:
self.fail("AuthenticationFailed not raised.")
25 changes: 25 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,28 @@ def test_post_expired_token(self):
self.assertEqual(token.user, self.user)
self.assertEqual(response.data['token'], token.key)
self.assertTrue(key_1 != key_2)

def test_post_always_reset_token(self):
"""Check that expired tokens are replaced."""
token = ExpiringToken.objects.create(user=self.user)
key_1 = token.key

# Make the first token expire.
with self.settings(ALWAYS_RESET_TOKEN=True):
sleep(0.001)
response = self.client.post(
'/obtain-token/',
{
'username': self.username,
'password': self.password
}
)

self.assertEqual(response.status_code, status.HTTP_200_OK)

# Check token was renewed and the response contains the token key.
token = ExpiringToken.objects.first()
key_2 = token.key
self.assertEqual(token.user, self.user)
self.assertEqual(response.data['token'], token.key)
self.assertTrue(key_1 != key_2)