Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

129 řádky
4.8 KiB

  1. # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import time
  5. import unittest
  6. import frappe
  7. from frappe.auth import LoginAttemptTracker
  8. from frappe.frappeclient import FrappeClient, AuthError
  9. class TestAuth(unittest.TestCase):
  10. def __init__(self, *args, **kwargs):
  11. super(TestAuth, self).__init__(*args, **kwargs)
  12. self.test_user_email = 'test_auth@test.com'
  13. self.test_user_name = 'test_auth_user'
  14. self.test_user_mobile = '+911234567890'
  15. self.test_user_password = 'pwd_012'
  16. def setUp(self):
  17. self.tearDown()
  18. self.add_user(self.test_user_email, self.test_user_password,
  19. username=self.test_user_name, mobile_no=self.test_user_mobile)
  20. def tearDown(self):
  21. frappe.delete_doc('User', self.test_user_email, force=True)
  22. def add_user(self, email, password, username=None, mobile_no=None):
  23. first_name = email.split('@', 1)[0]
  24. user = frappe.get_doc(
  25. dict(doctype='User', email=email, first_name=first_name, username=username, mobile_no=mobile_no)
  26. ).insert()
  27. user.new_password = password
  28. user.save()
  29. frappe.db.commit()
  30. def set_system_settings(self, k, v):
  31. frappe.db.set_value("System Settings", "System Settings", k, v)
  32. frappe.db.commit()
  33. def test_allow_login_using_mobile(self):
  34. self.set_system_settings('allow_login_using_mobile_number', 1)
  35. self.set_system_settings('allow_login_using_user_name', 0)
  36. # Login by both email and mobile should work
  37. FrappeClient(frappe.get_site_config().host_name, self.test_user_mobile, self.test_user_password)
  38. FrappeClient(frappe.get_site_config().host_name, self.test_user_email, self.test_user_password)
  39. # login by username should fail
  40. with self.assertRaises(AuthError):
  41. FrappeClient(frappe.get_site_config().host_name, self.test_user_name, self.test_user_password)
  42. def test_allow_login_using_only_email(self):
  43. self.set_system_settings('allow_login_using_mobile_number', 0)
  44. self.set_system_settings('allow_login_using_user_name', 0)
  45. # Login by mobile number should fail
  46. with self.assertRaises(AuthError):
  47. FrappeClient(frappe.get_site_config().host_name, self.test_user_mobile, self.test_user_password)
  48. # login by username should fail
  49. with self.assertRaises(AuthError):
  50. FrappeClient(frappe.get_site_config().host_name, self.test_user_name, self.test_user_password)
  51. # Login by email should work
  52. FrappeClient(frappe.get_site_config().host_name, self.test_user_email, self.test_user_password)
  53. def test_allow_login_using_username(self):
  54. self.set_system_settings('allow_login_using_mobile_number', 0)
  55. self.set_system_settings('allow_login_using_user_name', 1)
  56. # Mobile login should fail
  57. with self.assertRaises(AuthError):
  58. FrappeClient(frappe.get_site_config().host_name, self.test_user_mobile, self.test_user_password)
  59. # Both email and username logins should work
  60. FrappeClient(frappe.get_site_config().host_name, self.test_user_email, self.test_user_password)
  61. FrappeClient(frappe.get_site_config().host_name, self.test_user_name, self.test_user_password)
  62. def test_allow_login_using_username_and_mobile(self):
  63. self.set_system_settings('allow_login_using_mobile_number', 1)
  64. self.set_system_settings('allow_login_using_user_name', 1)
  65. # Both email and username and mobile logins should work
  66. FrappeClient(frappe.get_site_config().host_name, self.test_user_mobile, self.test_user_password)
  67. FrappeClient(frappe.get_site_config().host_name, self.test_user_email, self.test_user_password)
  68. FrappeClient(frappe.get_site_config().host_name, self.test_user_name, self.test_user_password)
  69. class TestLoginAttemptTracker(unittest.TestCase):
  70. def test_account_lock(self):
  71. """Make sure that account locks after `n consecutive failures
  72. """
  73. tracker = LoginAttemptTracker(user_name='tester', max_consecutive_login_attempts=3, lock_interval=60)
  74. # Clear the cache by setting attempt as success
  75. tracker.add_success_attempt()
  76. tracker.add_failure_attempt()
  77. self.assertTrue(tracker.is_user_allowed())
  78. tracker.add_failure_attempt()
  79. self.assertTrue(tracker.is_user_allowed())
  80. tracker.add_failure_attempt()
  81. self.assertTrue(tracker.is_user_allowed())
  82. tracker.add_failure_attempt()
  83. self.assertFalse(tracker.is_user_allowed())
  84. def test_account_unlock(self):
  85. """Make sure that locked account gets unlocked after lock_interval of time.
  86. """
  87. lock_interval = 2 # In sec
  88. tracker = LoginAttemptTracker(user_name='tester', max_consecutive_login_attempts=1, lock_interval=lock_interval)
  89. # Clear the cache by setting attempt as success
  90. tracker.add_success_attempt()
  91. tracker.add_failure_attempt()
  92. self.assertTrue(tracker.is_user_allowed())
  93. tracker.add_failure_attempt()
  94. self.assertFalse(tracker.is_user_allowed())
  95. # Sleep for lock_interval of time, so that next request con unlock the user access.
  96. time.sleep(lock_interval)
  97. tracker.add_failure_attempt()
  98. self.assertTrue(tracker.is_user_allowed())