def test_jwt(self): token = RequestToken(id=1, scope="foo").save() admin = RequestTokenAdmin(RequestToken, None) self.assertEqual(admin.jwt(token), token.jwt()) token = RequestToken() self.assertRaises(MissingRequiredClaimError, token.jwt) self.assertEqual(admin.jwt(token), None)
def test_save(self): token = RequestToken().save() self.assertIsNotNone(token) self.assertIsNone(token.user) self.assertEqual(token.scope, '') self.assertEqual(token.login_mode, RequestToken.LOGIN_MODE_NONE) self.assertIsNone(token.expiration_time) self.assertIsNone(token.not_before_time) self.assertEqual(token.data, {}) self.assertIsNotNone(token.issued_at) self.assertEqual(token.max_uses, 1) self.assertEqual(token.used_to_date, 0) token.issued_at = None token = token.save(update_fields=['issued_at']) self.assertIsNone(token.issued_at) now = tz_now() expires = now + datetime.timedelta(minutes=JWT_SESSION_TOKEN_EXPIRY) with mock.patch('request_token.models.tz_now', lambda: now): token = RequestToken(login_mode=RequestToken.LOGIN_MODE_SESSION, user=self.user, scope="foo") self.assertIsNone(token.issued_at) self.assertIsNone(token.expiration_time) token.save() self.assertEqual(token.issued_at, now) self.assertEqual(token.expiration_time, expires)
def test_defaults(self): token = RequestToken() self.assertIsNone(token.user) self.assertEqual(token.scope, '') self.assertEqual(token.login_mode, RequestToken.LOGIN_MODE_NONE) self.assertIsNone(token.expiration_time) self.assertIsNone(token.not_before_time) self.assertEqual(token.data, {}) self.assertIsNone(token.issued_at) self.assertEqual(token.max_uses, 1) self.assertEqual(token.used_to_date, 0)
def test_defaults(self): log = RequestTokenLog(token=self.token, user=self.user) self.assertEqual(log.user, self.user) self.assertEqual(log.token, self.token) self.assertEqual(log.user_agent, '') self.assertEqual(log.client_ip, None) self.assertIsNone(log.timestamp) token = RequestToken(user=self.user) self.assertIsNotNone(str(token)) self.assertIsNotNone(repr(token))
def test_parsed(self): token = RequestToken(id=1, scope="foo", data='{"foo": true}').save() admin = RequestTokenAdmin(RequestToken, None) parsed = admin._parsed(token) self.assertTrue("header" in parsed) self.assertTrue("claims" in parsed) self.assertTrue("signature" in parsed) # if the token is invalid we get None back with mock.patch.object(RequestToken, "jwt", side_effect=Exception()): self.assertIsNone(admin._parsed(token))
def test_is_valid(self, mock_now): now = tz_now() mock_now.return_value = now token = RequestToken() admin = RequestTokenAdmin(RequestToken, None) token.not_before_time = now + datetime.timedelta(minutes=1) self.assertTrue(token.not_before_time > now) self.assertFalse(admin.is_valid(token)) token.not_before_time = None token.expiration_time = now - datetime.timedelta(minutes=1) self.assertTrue(token.expiration_time < now) self.assertFalse(admin.is_valid(token)) token.expiration_time = None token.max_uses = 1 token.used_to_date = 1 self.assertFalse(admin.is_valid(token)) # finally make it valid token.max_uses = 10 self.assertTrue(admin.is_valid(token))
def test_claims(self): token = RequestToken() # raises error with no id set - put into context manager as it's # an attr, not a callable self.assertEqual(len(token.claims), 3) self.assertEqual(token.max, 1) self.assertEqual(token.sub, '') self.assertIsNone(token.jti) self.assertIsNone(token.aud) self.assertIsNone(token.exp) self.assertIsNone(token.nbf) self.assertIsNone(token.iat) # now let's set some properties token.user = self.user self.assertEqual(token.aud, self.user.id) self.assertEqual(len(token.claims), 4) token.login_mode = RequestToken.LOGIN_MODE_REQUEST self.assertEqual(token.claims['mod'], RequestToken.LOGIN_MODE_REQUEST[:1].lower()) self.assertEqual(len(token.claims), 4) now = tz_now() now_sec = to_seconds(now) token.expiration_time = now self.assertEqual(token.exp, now_sec) self.assertEqual(len(token.claims), 5) token.not_before_time = now self.assertEqual(token.nbf, now_sec) self.assertEqual(len(token.claims), 6) # saving updates the id and issued_at timestamp with mock.patch('request_token.models.tz_now', lambda: now): token.save() self.assertEqual(token.iat, now_sec) self.assertEqual(token.jti, token.id) self.assertEqual(len(token.claims), 8)
def test_log(self): token = RequestToken().save() factory = RequestFactory() request = factory.get('/') request.user = AnonymousUser() request.META = {} response = HttpResponse("foo", status=123) def assertUsedToDate(expected): token.refresh_from_db(fields=['used_to_date']) self.assertEqual(token.used_to_date, expected) log = token.log(request, response) self.assertEqual(RequestTokenLog.objects.get(), log) self.assertEqual(log.user, None) self.assertEqual(log.token, token) self.assertEqual(log.user_agent, 'unknown') self.assertEqual(log.client_ip, 'unknown') self.assertEqual(log.status_code, 123) assertUsedToDate(1) request.META['REMOTE_ADDR'] = '192.168.0.1' log = token.log(request, response) self.assertEqual(log.client_ip, '192.168.0.1') assertUsedToDate(2) request.META['HTTP_X_FORWARDED_FOR'] = '192.168.0.2' log = token.log(request, response) self.assertEqual(log.client_ip, '192.168.0.2') assertUsedToDate(3) request.META['HTTP_USER_AGENT'] = 'test_agent' log = token.log(request, response) self.assertEqual(log.user_agent, 'test_agent') token.refresh_from_db(fields=['used_to_date']) assertUsedToDate(4)
def test_log(self): token = RequestToken().save() factory = RequestFactory() request = factory.get("/") request.user = AnonymousUser() request.META = {} response = HttpResponse("foo", status=123) def assertUsedToDate(expected): token.refresh_from_db(fields=["used_to_date"]) self.assertEqual(token.used_to_date, expected) log = token.log(request, response) self.assertEqual(RequestTokenLog.objects.get(), log) self.assertEqual(log.user, None) self.assertEqual(log.token, token) self.assertEqual(log.user_agent, "unknown") self.assertEqual(log.client_ip, None) self.assertEqual(log.status_code, 123) assertUsedToDate(1) request.META["REMOTE_ADDR"] = "192.168.0.1" log = token.log(request, response) self.assertEqual(log.client_ip, "192.168.0.1") assertUsedToDate(2) request.META["HTTP_X_FORWARDED_FOR"] = "192.168.0.2" log = token.log(request, response) self.assertEqual(log.client_ip, "192.168.0.2") assertUsedToDate(3) request.META["HTTP_USER_AGENT"] = "test_agent" log = token.log(request, response) self.assertEqual(log.user_agent, "test_agent") token.refresh_from_db(fields=["used_to_date"]) assertUsedToDate(4)
def test_json(self): """Test the data field is really JSON.""" token = RequestToken(data={"foo": True}) token.save() self.assertTrue(token.data['foo'])
def test_string_repr(self): token = RequestToken(user=self.user) self.assertIsNotNone(str(token)) self.assertIsNotNone(repr(token))
def test_claims(self): token = RequestToken(id=1, scope="foo").save() admin = RequestTokenAdmin(RequestToken, None) self.assertEqual(admin._claims(token), pretty_print(token.claims))
def test_request_token(self): request = HttpRequest() request.token = RequestToken() context = request_token(request) assert context['request_token'] == request.token.jwt()
def test_validate_max_uses_disabled(self): token = RequestToken(max_uses=0, used_to_date=0) token.validate_max_uses() token.used_to_date = 1 token.validate_max_uses()
def test_validate_max_uses(self): token = RequestToken(max_uses=1, used_to_date=0) token.validate_max_uses() token.used_to_date = token.max_uses self.assertRaises(MaxUseError, token.validate_max_uses)
def test_jwt(self): token = RequestToken(id=1, scope='foo').save() jwt = token.jwt() self.assertEqual(decode(jwt), token.claims)
def test_clean(self): # LOGIN_MODE_NONE doesn't care about user. token = RequestToken(login_mode=RequestToken.LOGIN_MODE_NONE) token.clean() token.user = self.user token.clean() # request mode token.login_mode = RequestToken.LOGIN_MODE_REQUEST token.clean() token.user = None self.assertRaises(ValidationError, token.clean) def reset_session(): """Reset properties so that token passes validation.""" token.login_mode = RequestToken.LOGIN_MODE_SESSION token.user = self.user token.issued_at = tz_now() token.expiration_time = token.issued_at + datetime.timedelta( minutes=1) token.max_uses = 1 def assertValidationFails(field_name): with self.assertRaises(ValidationError) as ctx: token.clean() self.assertTrue(field_name in dict(ctx.exception)) # check the rest_session works! reset_session() token.clean() token.max_uses = 10 assertValidationFails('max_uses') reset_session() token.user = None assertValidationFails('user') reset_session() token.expiration_time = None assertValidationFails('expiration_time')