From 687b2a8f25d72495c3db6f2d76eb03e6c4f658f4 Mon Sep 17 00:00:00 2001 From: tmeissner Date: Thu, 11 Sep 2014 23:42:30 +0200 Subject: [PATCH] added case study of chapter 4: auth module --- python_3_oop/chapter04/auth.py | 138 +++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 python_3_oop/chapter04/auth.py diff --git a/python_3_oop/chapter04/auth.py b/python_3_oop/chapter04/auth.py new file mode 100644 index 0000000..98b1021 --- /dev/null +++ b/python_3_oop/chapter04/auth.py @@ -0,0 +1,138 @@ +import hashlib + + +class User: + + def __init__(self, username, password): + '''Create a new user object. The password will be encrypted before + storing''' + self.username = username + self.password = self._encrypt_pw(password) + self.is_logged_in = False + + def _encrypt_pw(self, password): + '''Encrypt the password with the username and return the sha digest.''' + hash_string = self.username + password + hash_string = hash_string.encode("utf8") + return hashlib.sha256(hash_string).hexdigest() + + def check_password(self, password): + '''Return True if the password is valid for this user, + False otherwise''' + encrypted = self._encrypt_pw(password) + return encrypted == self.password + + +class Authenticator: + + def __init__(self): + '''Construct an authenticator to manage users logging in and out. + The User objects are stored in a simple dictionary''' + self.users = {} + + def add_user(self, username, password): + '''Add a User object with given username & password to the users + dictionary after checking if given username & password are valid''' + if username in self.users: + raise UsernameAlreadyExists(username) + if len(password) < 6: + raise PasswordTooShort(username) + self.users[username] = User(username, password) + + def login(self, username, password): + try: + user = self.users[username] + except KeyError: + raise InvalidUsername(username) + if not user.check_password(password): + raise InvalidPassword(username, user) + user.is_logged_in = True + return True + + def is_logged_in(self, username): + if username in self.users: + return self.users[username].is_logged_in + return False + + +authenticator = Authenticator() + + +class Authorizor(): + + def __init__(self, authenticator): + self.authenticator = authenticator + self.permissions = {} + + def add_permission(self, perm_name): + '''Create a new permission that users can be added to''' + try: + perm_set = self.permissions[perm_name] + except KeyError: + self.permissions[perm_name] = set() + else: + raise PermissionError("Permission exists") + + def permit_user(self, perm_name, username): + '''Grant the given permission to the given user''' + try: + perm_set = self.permissions[perm_name] + except KeyError: + raise PermissionError("Permission does not exist") + else: + if username not in self.authenticator.users: + raise InvalidUsername(username) + perm_set.add(username) + + def check_permission(self, perm_name, username): + if not self.authenticator.is_logged_in(username): + raise NotLoggedInError(username) + try: + perm_set = self.permissions[perm_name] + except KeyError: + raise PermissionError("Permission does not exist") + if username not in perm_set: + raise NotPermittedError(username) + else: + return True + + +authorizor = Authorizor(authenticator) + + +# Exception classes + +class AuthException(Exception): + + def __init__(self, username, user = None): + super().__init__(username, user) + self.username = username + self.user = user + + +class UsernameAlreadyExists(AuthException): + pass + + +class PasswordTooShort(AuthException): + pass + + +class InvalidUsername(AuthException): + pass + + +class InvalidPassword(AuthException): + pass + + +class NotLoggedInError(AuthException): + pass + + +class NotPermittedError(AuthException): + pass + + +class PermissionError(Exception): + pass