|
| 1 | +from abc import ABC, abstractmethod |
| 2 | + |
| 3 | +# Request object that holds user and requested daya |
| 4 | + |
| 5 | +class Request: |
| 6 | + def __init__(self, username, password, role, data): |
| 7 | + self.username = username |
| 8 | + self.password = password |
| 9 | + self.role = role |
| 10 | + self.data = data |
| 11 | + |
| 12 | +# Abstract Handler |
| 13 | +class Handler(ABC): |
| 14 | + def __init__(self): |
| 15 | + self.next_handler = None |
| 16 | + |
| 17 | + def set_next(self, handler): |
| 18 | + self._next_handler = handler |
| 19 | + return handler |
| 20 | + |
| 21 | + @abstractmethod |
| 22 | + def handle(self, request: Request): |
| 23 | + pass |
| 24 | + |
| 25 | +# Concreate Handler 1: Authentication |
| 26 | +class AuthHandler(Handler): |
| 27 | + def handle(self, request: Request): |
| 28 | + print("[AuthHandler] Checking authentication...") |
| 29 | + if request.username == "john" and request.password == "1234": |
| 30 | + print("Authenticated") |
| 31 | + if self._next_handler: |
| 32 | + return self._next_handler.handle(request) |
| 33 | + else: |
| 34 | + print("Authentication failed") |
| 35 | + return "Access Denied: Invalid Credentials" |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +# Concrete Handler 2: Authorization |
| 40 | +class RoleHandler(Handler): |
| 41 | + def handle(self, request: Request): |
| 42 | + print("[RoleHandler] Checking role...") |
| 43 | + if request.role == "admin" or request.role == "user": |
| 44 | + print(f"Authorized as {request.role}") |
| 45 | + if self._next_handler: |
| 46 | + return self._next_handler.handle(request) |
| 47 | + else: |
| 48 | + print("Authorization failed") |
| 49 | + return "Access Denied: Unauthorized Role" |
| 50 | + |
| 51 | + |
| 52 | +# Concrete Handler 3: Validation |
| 53 | +class ValidationHandler(Handler): |
| 54 | + def handle(self, request: Request): |
| 55 | + print("[ValidationHandler] Validating request data...") |
| 56 | + if "item" in request.data and "quantity" in request.data: |
| 57 | + print("Request data is valid") |
| 58 | + if self._next_handler: |
| 59 | + return self._next_handler.handle(request) |
| 60 | + else: |
| 61 | + print("Invalid request data") |
| 62 | + return "Bad Request: Missing order details" |
| 63 | + |
| 64 | +# Final Handler: Order Handler |
| 65 | +class OrderHandler(Handler): |
| 66 | + def handle(self, request: Request): |
| 67 | + print(f"[OrderHandler] Processing order...") |
| 68 | + return f"Order Placed for {request.data['quantity']} x {request.data['item']} by {request.username}" |
| 69 | + |
| 70 | +# Client Code |
| 71 | + |
| 72 | +if __name__ == "__main__": |
| 73 | + auth = AuthHandler() |
| 74 | + role = RoleHandler() |
| 75 | + validate = ValidationHandler() |
| 76 | + order = OrderHandler() |
| 77 | + |
| 78 | + auth.set_next(role).set_next(role).set_next(validate).set_next(order) |
| 79 | + |
| 80 | + # Request Valid |
| 81 | + # Request 1: Valid |
| 82 | + print("\n--- Request 1: Valid Order ---") |
| 83 | + request1 = Request("john", "1234", "admin", {"item": "Laptop", "quantity": 2}) |
| 84 | + response1 = auth.handle(request1) |
| 85 | + print("Response:", response1) |
| 86 | + |
| 87 | + # Request 2: Invalid password |
| 88 | + print("\n--- Request 2: Invalid Credentials ---") |
| 89 | + request2 = Request("john", "wrong", "admin", {"item": "Laptop", "quantity": 2}) |
| 90 | + response2 = auth.handle(request2) |
| 91 | + print("Response:", response2) |
| 92 | + |
| 93 | + # Request 3: Unauthorized Role |
| 94 | + print("\n--- Request 3: Unauthorized Role ---") |
| 95 | + request3 = Request("john", "1234", "guest", {"item": "Laptop", "quantity": 2}) |
| 96 | + response3 = auth.handle(request3) |
| 97 | + print("Response:", response3) |
| 98 | + |
| 99 | + # Request 4: Missing Data |
| 100 | + print("\n--- Request 4: Missing Order Data ---") |
| 101 | + request4 = Request("john", "1234", "user", {"item": "Mouse"}) |
| 102 | + response4 = auth.handle(request4) |
| 103 | + print("Response:", response4) |
| 104 | + |
| 105 | + |
0 commit comments