| @ -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 | |||