def post(self, request): """ Login a new user, expecting their uuid as the credentials. We return them a fresh token_level_0, token_level_1 """ allowed_addrs = os.environ.get('ALLOWED_REMOTE_ADDR') if not allowed_addrs: return ResponseMessage.FORBIDDEN('NO ALLOWED REMOTE ADDR DEFINED') remote_addr = request.META['REMOTE_ADDR'] if remote_addr not in allowed_addrs: return ResponseMessage.FORBIDDEN( 'FORBIDDEN. IP {}'.format(remote_addr)) users = User.objects.filter(uuid=request.data['uuid']) if users.count() == 0: return ResponseMessage.INVALID_CREDENTIALS user = users[0] l0 = TokenManager.generate(user, TokenType.LEVEL_ZERO) l1 = TokenManager.generate(user, TokenType.LEVEL_ONE) return JsonResponse( { 'token_level_0': l0.decode('ascii'), 'token_level_1': l1.decode('ascii') }, status=200)
def test_TokenManager_generate_weird_kind(self): with self.assertRaises(ValueError): TokenManager.generate(self.bob, TokenType(400)) with self.assertRaises(Exception): TokenManager.generate(self.bob, 400)
def test_TokenManager_validate_fails_on_wrong_kind(self): token = TokenManager.generate(self.bob, TokenType.LEVEL_ZERO) self.assertFalse( TokenManager.validate(self.bob, token, TokenType.LEVEL_ONE)) token = TokenManager.generate(self.bob, TokenType.LEVEL_ONE) self.assertFalse( TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO))
def test_TokenManager_token_expires(self, mock_TokenType): def instantly_expire(): return timedelta(seconds=-1) mock_TokenType.side_effect = instantly_expire user = self.bob token = TokenManager.generate(user, TokenType.LEVEL_ZERO) claims = TokenManager.validate(user, token, TokenType.LEVEL_ZERO) self.assertFalse(claims)
def post(self, request, actiontype=None): """ Checks if the given token is valid, expecting their uuid, token_level_1, token_level_0. Optional: Checks if the given user is permitted to perform the action. We return them a fresh token_level_1 on success. """ l0 = request.data['token_level_0'] l1 = request.data['token_level_1'] uuid = request.data['uuid'] # Verify the user id try: user = User.objects.get(uuid=uuid) except User.DoesNotExist: log.debug("User with uuid={} does not exist.".format(uuid)) return ResponseMessage.INVALID_CREDENTIALS # Verify the tokens are valid. claims0 = TokenManager.validate(user, l0, TokenType.LEVEL_ZERO) if not claims0: log.debug("LEVEL_ZERO is invalid.") return ResponseMessage.INVALID_CREDENTIALS claims1 = TokenManager.validate(user, l1, TokenType.LEVEL_ONE) if not claims1: log.debug("LEVEL_ONE is invalid.") return ResponseMessage.INVALID_CREDENTIALS # Finally check the action type if actiontype: if actiontype == 'prescription': if user.role != User.Role.DOCTOR: log.debug("User is unable to prescribe.") return ResponseMessage.FORBIDDEN('User cannot prescribe') elif actiontype == 'fulfil': if user.role != User.Role.PHARMACIST: log.debug("User is unable to fulfill.") return ResponseMessage.FORBIDDEN('User cannot fulfill') TokenManager.delete(user, claims1) # Refresh with the new token l1 = TokenManager.generate(user, TokenType.LEVEL_ONE) return JsonResponse({ 'token_level_1': l1.decode('ascii'), }, status=200)
def put(self, request): """ Peforms the password reset for the user with user.email=email if the token is a valid token attached to that user. """ uuid = request.data['uuid'] # Get the user from the email try: user = User.objects.get(uuid=uuid) except User.DoesNotExist: log.debug("User does not exist: uuid={}".format(uuid)) return ResponseMessage.INVALID_CREDENTIALS email = user.email.lower() password = request.data['password'] # Check password user = authenticate(username=email, password=password) if user is None: return ResponseMessage.INVALID_CREDENTIALS # Check tokens l0 = request.data['token_level_0'] l1 = request.data['token_level_1'] claims0 = TokenManager.validate(user, l0, TokenType.LEVEL_ZERO) if not claims0: log.debug("LEVEL_ZERO is invalid.") return ResponseMessage.INVALID_CREDENTIALS claims1 = TokenManager.validate(user, l1, TokenType.LEVEL_ONE) if not claims1: log.debug("LEVEL_ONE is invalid.") return ResponseMessage.INVALID_CREDENTIALS TokenManager.delete(user, claims1) l1 = TokenManager.generate(user, TokenType.LEVEL_ONE) log.info("User uuid={} has changed their password".format(user.uuid)) user.set_password(request.data['new_password']) user.save() return JsonResponse({ 'token_level_1': l1.decode('ascii'), }, status=201)
def post(self, request): """ Checks the user tokens, if valid returns the user secret for row encryption. Expecting token_level_0, token_level_1, uuid. Returns new token_level_0 and the secret. """ l0 = request.data['token_level_0'] l1 = request.data['token_level_1'] uuid = request.data['uuid'] # Verify the user id try: user = User.objects.get(uuid=uuid) except User.DoesNotExist as e: log.debug("User does not exist, looked for uuid={}: {}".format( uuid, str(e))) return ResponseMessage.INVALID_CREDENTIALS # Verify the tokens are valid. if not TokenManager.validate(user, l0, TokenType.LEVEL_ZERO): log.debug( "Invalid token_level_0 for user={} was detected: {}".format( user, l0)) return ResponseMessage.INVALID_CREDENTIALS if not TokenManager.validate(user, l0, TokenType.LEVEL_ZERO): log.debug( "Invalid token_level_1 for user={} was detected: {}".format( user, l1)) return ResponseMessage.INVALID_CREDENTIALS # Refresh with the new token l1 = TokenManager.generate(user, TokenType.LEVEL_ONE) return JsonResponse( { 'token_level_1': l1.decode('ascii'), 'secret': user.secret, }, status=200)
def post(self, request): """ Request a reset password link to be sent to the users email. This view will return a token that can be given to the ResetPassword views for resetting the user's password. """ try: user = User.objects.get(email=request.data['email'].lower()) except User.DoesNotExist: return ResponseMessage.INVALID_CREDENTIALS token = TokenManager.generate(user, TokenType.RESET_PASSWORD) return JsonResponse({"token": token.decode('utf8')}, status=200)
def post(self, request): """ Peforms the password reset for the user with user.email=email if the token is a valid token attached to that user. """ # Get the user from the email try: user = User.objects.get(email=request.data['email'].lower()) except User.DoesNotExist: return ResponseMessage.INVALID_CREDENTIALS token = request.data['token'] # Validate the token matches the user token claims = TokenManager.validate(user, token, TokenType.RESET_PASSWORD) if not claims: return ResponseMessage.INVALID_CREDENTIALS TokenManager.delete(user, claims) log.info("User uuid={} has changed their password".format(user.uuid)) user.set_password(request.data['password']) user.save() return JsonResponse({}, status=201)
def post(self, request): """ Login a new user, expecting their e-mail and password as the credentials. We return them a fresh token_level_0, token_level_1, and the UUID of the user. """ email = request.data['email'].lower() password = request.data['password'] user = authenticate(username=email, password=password) if user is None: return ResponseMessage.INVALID_CREDENTIALS l0 = TokenManager.generate(user, TokenType.LEVEL_ZERO) l1 = TokenManager.generate(user, TokenType.LEVEL_ONE) return JsonResponse( { 'token_level_0': l0.decode('ascii'), 'token_level_1': l1.decode('ascii'), 'uuid': user.uuid, }, status=200)
def post(self, request): """ Validates the token is of TokenType.RESET_PASSWORD """ # Get the user from the email try: user = User.objects.get(email=request.data['email'].lower()) except User.DoesNotExist: return ResponseMessage.INVALID_CREDENTIALS token = request.data['token'] # Validate the token matches the user token if not TokenManager.validate(user, token, TokenType.RESET_PASSWORD): return ResponseMessage.INVALID_CREDENTIALS return JsonResponse({}, status=200)
def post(self, request): """ Checks if the given token is valid, expecting their uuid, token_level_1, token_level_0. Optional: Checks if the given user is permitted to perform the action. We return them a fresh token_level_1 on success. """ l0 = request.data['token_level_0'] uuid = request.data['uuid'] # Verify the user id try: user = User.objects.get(uuid=uuid) except User.DoesNotExist: log.debug("User with uuid={} does not exist.".format(uuid)) return ResponseMessage.INVALID_CREDENTIALS # Verify the tokens are valid. claims0 = TokenManager.validate(user, l0, TokenType.LEVEL_ZERO) if not claims0: log.debug("LEVEL_ZERO is invalid.") return ResponseMessage.INVALID_CREDENTIALS return JsonResponse({}, status=200)
def post(self, request): """Invalidate the current user session.""" l0 = request.data['token_level_0'] l1 = request.data['token_level_1'] uuid = request.data['uuid'] try: user = User.objects.get(uuid=uuid) except User.DoesNotExist: log.debug("User does not exist: uuid={}".format(uuid)) return ResponseMessage.INVALID_CREDENTIALS # Verify the tokens are valid. claims = TokenManager.validate(user, l0, TokenType.LEVEL_ZERO) if claims: TokenManager.delete(user, claims) claims = TokenManager.validate(user, l1, TokenType.LEVEL_ONE) if claims: TokenManager.delete(user, claims) return JsonResponse({}, status=200)
def test_TokenManager_validate_fails_on_wrong_user(self): token = TokenManager.generate(self.bob, TokenType.LEVEL_ZERO) self.assertFalse( TokenManager.validate(self.alice, token, TokenType.LEVEL_ZERO)) self.assertTrue( TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO))
def test_TokenManager_validate_twice(self): token = TokenManager.generate(self.bob, TokenType.LEVEL_ZERO) self.assertTrue( TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO)) self.assertTrue( TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO))
def test_TokenManager_deletes(self): token = TokenManager.generate(self.bob, TokenType.LEVEL_ZERO) claims = TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO) self.assertTrue(TokenManager.delete(self.bob, claims)) self.assertFalse( TokenManager.validate(self.bob, token, TokenType.LEVEL_ZERO))
def test_TokenManager_generate(self): """Test the generation and validation of tokens""" user = self.bob for kind in list(TokenType): token = TokenManager.generate(user, kind) self.assertTrue(TokenManager.validate(user, token, kind))