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