Guest User

Untitled

a guest
Jan 12th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.68 KB | None | 0 0
  1. class LoggingService(object):
  2. """
  3. Just a contrived logging class for demonstration purposes
  4. """
  5. def log_error(self, error):
  6. pass
  7.  
  8.  
  9. class UserService(object):
  10. """
  11. Provide a method to authenticate the user by performing some expensive DB or network operation.
  12. """
  13. def validate_credentials(self, username, password):
  14. print('> UserService::validate_credentials')
  15. return username == 'iainjames88' and password == 'secret'
  16.  
  17.  
  18. class User(LoggingService, UserService):
  19. """
  20. A User model class for demonstration purposes. In production, this code authenticates user credentials by calling
  21. super().validate_credentials and having the MRO resolve which class should handle this call.
  22. """
  23. def __init__(self, username, password):
  24. self.username = username
  25. self.password = password
  26.  
  27. def authenticate(self):
  28. if super().validate_credentials(self.username, self.password):
  29. return True
  30. super().log_error('Incorrect username/password combination')
  31. return False
  32.  
  33. class MockUserService(UserService):
  34. """
  35. Provide an implementation for validate_credentials() method. Now, calls from super() stop here when part of MRO.
  36. """
  37. def validate_credentials(self, username, password):
  38. print('> MockUserService::validate_credentials')
  39. return True
  40.  
  41.  
  42. class MockUser(User, MockUserService):
  43. """
  44. A wrapper class around User to change it's MRO so that MockUserService is injected before UserService.
  45. """
  46. pass
  47.  
  48. if __name__ == '__main__':
  49. # Normal useage of the User class which uses UserService to resolve super().validate_credentials() calls.
  50. user = User('iainjames88', 'secret')
  51. print(user.authenticate())
  52.  
  53. # Use the wrapper class MockUser which positions the MockUserService before UserService in the MRO. Since the class
  54. # MockUserService provides an implementation for validate_credentials() calls to super().validate_credentials() from
  55. # MockUser class will be resolved by MockUserService and not passed to the next in line.
  56. mock_user = MockUser('iainjames88', 'secret')
  57. print(mock_user.authenticate())
  58.  
  59. >>> print(MockUser('foo', 'bar').authenticate())
  60. > MockUserService::validate_credentials
  61. True
  62.  
  63. def validate_credentials(self, username, password):
  64. print('> MockUserService::validate_credentials')
  65. assert username_ok(username), 'username expected to be ok'
  66. assert password_ok(password), 'password expected to be ok'
  67. return True
  68.  
  69. >>> MockUser.mro()
  70. [<class '__main__.MockUser'>,
  71. <class '__main__.User'>,
  72. <class '__main__.LoggingService'>,
  73. <class '__main__.MockUserService'>,
  74. <class '__main__.UserService'>,
  75. <class 'object'>]
Add Comment
Please, Sign In to add comment