prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Login ID and Password fields for a learner/user should not be case sensitive.
  ## Summary
  
  Login ID and Password fields for a learner/user should not be case sensitive, this is especially for young learners and they struggle a lot to login itself.
  
  Please consider this change for Nalanda branch.
  
  ## System information
   - Version: Kolibri 0.4.0beta9
   - Operating system: Ubuntu 14.04 LTS
   - Browser: Chrome
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kolibri/auth/backends.py`
  Content:
  ```
  1 """
  2 Implements custom auth backends as described in the Django docs, for our custom user classes -- FacilityUser and
  3 DeviceOwner. The appropriate classes should be listed in the AUTHENTICATION_BACKENDS. Note that authentication
  4 backends are checked in the order they're listed.
  5 """
  6 
  7 from kolibri.auth.models import DeviceOwner, FacilityUser
  8 
  9 
  10 class FacilityUserBackend(object):
  11     """
  12     A class that implements authentication for FacilityUsers.
  13     """
  14 
  15     def authenticate(self, username=None, password=None, facility=None):
  16         """
  17         Authenticates the user if the credentials correspond to a FacilityUser for the specified Facility.
  18 
  19         :param username: a string
  20         :param password: a string
  21         :param facility: a Facility
  22         :return: A FacilityUser instance if successful, or None if authentication failed.
  23         """
  24         users = FacilityUser.objects.filter(username=username)
  25         if facility:
  26             users = users.filter(facility=facility)
  27         for user in users:
  28             if user.check_password(password):
  29                 return user
  30             # Allow login without password for learners for facilities that allow this.
  31             # Must specify the facility, to prevent accidental logins
  32             elif facility and user.dataset.learner_can_login_with_no_password and not user.roles.count():
  33                 return user
  34         return None
  35 
  36     def get_user(self, user_id):
  37         """
  38         Gets a user. Auth backends are required to implement this.
  39 
  40         :param user_id: A FacilityUser pk
  41         :return: A FacilityUser instance if a BaseUser with that pk is found, else None.
  42         """
  43         try:
  44             return FacilityUser.objects.get(pk=user_id)
  45         except FacilityUser.DoesNotExist:
  46             return None
  47 
  48 
  49 class DeviceOwnerBackend(object):
  50     """
  51     A class that implements authentication for DeviceOwners.
  52     """
  53 
  54     def authenticate(self, username=None, password=None, **kwargs):
  55         """
  56         Authenticates the user if the credentials correspond to a DeviceOwner.
  57 
  58         :param username: a string
  59         :param password: a string
  60         :return: A DeviceOwner instance if successful, or None if authentication failed.
  61         """
  62         try:
  63             user = DeviceOwner.objects.get(username=username)
  64             if user.check_password(password):
  65                 return user
  66             else:
  67                 return None
  68         except DeviceOwner.DoesNotExist:
  69             return None
  70 
  71     def get_user(self, user_id):
  72         """
  73         Gets a user. Auth backends are required to implement this.
  74 
  75         :param user_id: A BaseUser pk
  76         :return: A DeviceOwner instance if a BaseUser with that pk is found, else None.
  77         """
  78         try:
  79             return DeviceOwner.objects.get(pk=user_id)
  80         except DeviceOwner.DoesNotExist:
  81             return None
  82
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/kolibri/auth/backends.py b/kolibri/auth/backends.py
  --- a/kolibri/auth/backends.py
  +++ b/kolibri/auth/backends.py
  @@ -21,7 +21,7 @@
           :param facility: a Facility
           :return: A FacilityUser instance if successful, or None if authentication failed.
           """
  -        users = FacilityUser.objects.filter(username=username)
  +        users = FacilityUser.objects.filter(username__iexact=username)
           if facility:
               users = users.filter(facility=facility)
           for user in users:
  
verification_info: {"golden_diff": "diff --git a/kolibri/auth/backends.py b/kolibri/auth/backends.py\n--- a/kolibri/auth/backends.py\n+++ b/kolibri/auth/backends.py\n@@ -21,7 +21,7 @@\n         :param facility: a Facility\n         :return: A FacilityUser instance if successful, or None if authentication failed.\n         \"\"\"\n-        users = FacilityUser.objects.filter(username=username)\n+        users = FacilityUser.objects.filter(username__iexact=username)\n         if facility:\n             users = users.filter(facility=facility)\n         for user in users:\n", "issue": "Login ID and Password fields for a learner/user should not be case sensitive.\n## Summary\r\n\r\nLogin ID and Password fields for a learner/user should not be case sensitive, this is especially for young learners and they struggle a lot to login itself.\r\n\r\nPlease consider this change for Nalanda branch.\r\n\r\n## System information\r\n - Version: Kolibri 0.4.0beta9\r\n - Operating system: Ubuntu 14.04 LTS\r\n - Browser: Chrome\r\n\n", "before_files": [{"content": "\"\"\"\nImplements custom auth backends as described in the Django docs, for our custom user classes -- FacilityUser and\nDeviceOwner. The appropriate classes should be listed in the AUTHENTICATION_BACKENDS. Note that authentication\nbackends are checked in the order they're listed.\n\"\"\"\n\nfrom kolibri.auth.models import DeviceOwner, FacilityUser\n\n\nclass FacilityUserBackend(object):\n    \"\"\"\n    A class that implements authentication for FacilityUsers.\n    \"\"\"\n\n    def authenticate(self, username=None, password=None, facility=None):\n        \"\"\"\n        Authenticates the user if the credentials correspond to a FacilityUser for the specified Facility.\n\n        :param username: a string\n        :param password: a string\n        :param facility: a Facility\n        :return: A FacilityUser instance if successful, or None if authentication failed.\n        \"\"\"\n        users = FacilityUser.objects.filter(username=username)\n        if facility:\n            users = users.filter(facility=facility)\n        for user in users:\n            if user.check_password(password):\n                return user\n            # Allow login without password for learners for facilities that allow this.\n            # Must specify the facility, to prevent accidental logins\n            elif facility and user.dataset.learner_can_login_with_no_password and not user.roles.count():\n                return user\n        return None\n\n    def get_user(self, user_id):\n        \"\"\"\n        Gets a user. Auth backends are required to implement this.\n\n        :param user_id: A FacilityUser pk\n        :return: A FacilityUser instance if a BaseUser with that pk is found, else None.\n        \"\"\"\n        try:\n            return FacilityUser.objects.get(pk=user_id)\n        except FacilityUser.DoesNotExist:\n            return None\n\n\nclass DeviceOwnerBackend(object):\n    \"\"\"\n    A class that implements authentication for DeviceOwners.\n    \"\"\"\n\n    def authenticate(self, username=None, password=None, **kwargs):\n        \"\"\"\n        Authenticates the user if the credentials correspond to a DeviceOwner.\n\n        :param username: a string\n        :param password: a string\n        :return: A DeviceOwner instance if successful, or None if authentication failed.\n        \"\"\"\n        try:\n            user = DeviceOwner.objects.get(username=username)\n            if user.check_password(password):\n                return user\n            else:\n                return None\n        except DeviceOwner.DoesNotExist:\n            return None\n\n    def get_user(self, user_id):\n        \"\"\"\n        Gets a user. Auth backends are required to implement this.\n\n        :param user_id: A BaseUser pk\n        :return: A DeviceOwner instance if a BaseUser with that pk is found, else None.\n        \"\"\"\n        try:\n            return DeviceOwner.objects.get(pk=user_id)\n        except DeviceOwner.DoesNotExist:\n            return None\n", "path": "kolibri/auth/backends.py"}], "after_files": [{"content": "\"\"\"\nImplements custom auth backends as described in the Django docs, for our custom user classes -- FacilityUser and\nDeviceOwner. The appropriate classes should be listed in the AUTHENTICATION_BACKENDS. Note that authentication\nbackends are checked in the order they're listed.\n\"\"\"\n\nfrom kolibri.auth.models import DeviceOwner, FacilityUser\n\n\nclass FacilityUserBackend(object):\n    \"\"\"\n    A class that implements authentication for FacilityUsers.\n    \"\"\"\n\n    def authenticate(self, username=None, password=None, facility=None):\n        \"\"\"\n        Authenticates the user if the credentials correspond to a FacilityUser for the specified Facility.\n\n        :param username: a string\n        :param password: a string\n        :param facility: a Facility\n        :return: A FacilityUser instance if successful, or None if authentication failed.\n        \"\"\"\n        users = FacilityUser.objects.filter(username__iexact=username)\n        if facility:\n            users = users.filter(facility=facility)\n        for user in users:\n            if user.check_password(password):\n                return user\n            # Allow login without password for learners for facilities that allow this.\n            # Must specify the facility, to prevent accidental logins\n            elif facility and user.dataset.learner_can_login_with_no_password and not user.roles.count():\n                return user\n        return None\n\n    def get_user(self, user_id):\n        \"\"\"\n        Gets a user. Auth backends are required to implement this.\n\n        :param user_id: A FacilityUser pk\n        :return: A FacilityUser instance if a BaseUser with that pk is found, else None.\n        \"\"\"\n        try:\n            return FacilityUser.objects.get(pk=user_id)\n        except FacilityUser.DoesNotExist:\n            return None\n\n\nclass DeviceOwnerBackend(object):\n    \"\"\"\n    A class that implements authentication for DeviceOwners.\n    \"\"\"\n\n    def authenticate(self, username=None, password=None, **kwargs):\n        \"\"\"\n        Authenticates the user if the credentials correspond to a DeviceOwner.\n\n        :param username: a string\n        :param password: a string\n        :return: A DeviceOwner instance if successful, or None if authentication failed.\n        \"\"\"\n        try:\n            user = DeviceOwner.objects.get(username=username)\n            if user.check_password(password):\n                return user\n            else:\n                return None\n        except DeviceOwner.DoesNotExist:\n            return None\n\n    def get_user(self, user_id):\n        \"\"\"\n        Gets a user. Auth backends are required to implement this.\n\n        :param user_id: A BaseUser pk\n        :return: A DeviceOwner instance if a BaseUser with that pk is found, else None.\n        \"\"\"\n        try:\n            return DeviceOwner.objects.get(pk=user_id)\n        except DeviceOwner.DoesNotExist:\n            return None\n", "path": "kolibri/auth/backends.py"}]}