Learning by doing: Reading books and trying to understand the (code) examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

138 lines
3.7 KiB

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