Capstone Project · Grade 8 · Chapter 9
Mini Project Part 1: Architecture & Engine
Designing the software blueprint, data schemas, pseudocode algorithms, and core security functions for CyberShield CLI.
Software Engineering Practice
Blueprinting Before Coding
Architects don't lay bricks without blueprints, and senior developers don't write code without system design diagrams! Spending 30 minutes on architecture saves 10 hours of refactoring.
Project Goal: Build CyberShield CLI — an interactive cybersecurity suite and password vault.
Lesson Objectives
What We Will Build Today
- Analyze Functional vs. Non-Functional Software Requirements.
- Design the 3-tier modular architecture (UI Shell, Logic Engine, Data Storage).
- Write formal pseudocode algorithms for password entropy calculation.
- Implement Core Security Modules (`evaluate_strength` & SHA-256 `hash_password`).
- Construct the main command-line loop shell.
Software Life Cycle
The Software Development Life Cycle (SDLC)
1. REQUIREMENTS
Define application features & user stories.
2. ARCHITECTURE
Design module interfaces & data schemas.
3. IMPLEMENT
Write clean Python functions & algorithms.
4. TEST & DEPLOY
Validate edge cases & package for users.
Project Specification
Project Brief: CyberShield CLI
An enterprise-grade command-line tool for security audits containing 4 primary features:
Feature 1: Strength Evaluator
Calculates entropy, length, character pool, and returns security score (0-100%).
Feature 2: Hash Generator
Computes cryptographic SHA-256 hashes with automatic random salt generation.
Feature 3: User Vault
Stores username, password hash, and salt pairs securely in memory.
Feature 4: File Persistence
Exports user vault and audit logs to persistent users.csv files.
Requirement Analysis
Functional vs. Non-Functional Requirements
Functional (What it does)
User selects options from a CLI menu. Evaluates password strength. Saves records to CSV files.
Non-Functional (Quality/Safety)
Must never crash on invalid user input (`try/except`). Must never store plaintext passwords in files.
System Architecture
CyberShield 3-Tier Module Map
Tier 1: UI Shell
Handles print() formatting, menu display loops, and raw input() captures.
Tier 2: Core Engine
Pure logic functions: evaluate_strength(), hash_password(), check_pwned().
Tier 3: Storage Layer
File I/O functions: save_vault_csv(), load_vault_csv(), append_log().
Data Structures
Designing In-Memory Data Schemas
Representing user accounts in memory as a dictionary of dictionary objects:
user_vault = {
"sara_admin": {
"salt": "a8f9c2",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"strength_score": 95
}
}
Algorithm Planning
Writing Strength Engine Pseudocode
PSEUDOCODE ALGORITHM
FUNCTION evaluate_strength(password):
score = 0
IF length >= 8 THEN score += 25
IF length >= 14 THEN score += 25
IF contains_uppercase AND contains_lowercase THEN score += 25
IF contains_digit AND contains_symbol THEN score += 25
RETURN score
Building Module 1
Implementing `evaluate_strength()`
def evaluate_strength(password):
score = 0
if len(password) >= 8: score += 25
if len(password) >= 14: score += 25
has_upper = any(c.isupper() for c in password)
has_lower = any(c.islower() for c in password)
has_digit = any(c.isdigit() for c in password)
has_symbol = any(not c.isalnum() for c in password)
if has_upper and has_lower: score += 25
if has_digit and has_symbol: score += 25
return min(100, score)
Building Module 2
Implementing `hash_password()` with `hashlib`
import hashlib
import secrets
def hash_password(password, salt=None):
if salt is None:
salt = secrets.token_hex(8) # Generates 16 random hex chars
salted_pwd = password + salt
pwd_hash = hashlib.sha256(salted_pwd.encode()).hexdigest()
return pwd_hash, salt
Building Module 3
Main Menu Command Loop
def display_menu():
print("\n=== CYBERSHIELD SECURITY CLI ===")
print("1. Test Password Strength")
print("2. Hash & Register User")
print("3. View Account Vault")
print("4. Exit")
def main():
while True:
display_menu()
choice = input("Select Option (1-4): ").strip()
if choice == "1":
pwd = input("Enter password to test: ")
print(f"Strength Score: {evaluate_strength(pwd)}%")
elif choice == "4":
print("Exiting CyberShield. Goodbye!")
break
Defensive Architecture
Handling Edge Case User Inputs
EDGE CASE TEST
What happens if a user presses Enter without typing a password? Or types special characters like \n or , inside their username?
Discussion: How must our input sanitization guard against breaking CSV parsing?
Spot the Mistake
Architecture Flaws in Initial Draft
# Flaw: Mixing UI printing inside calculation function!
def evaluate_and_print(p):
s = len(p) * 10
print(f"Score: {s}") # Hard to reuse or test!
# Fix: Separate calculation return from UI display!
Guided Practice
Writing Unit Tests for Security Core
Test your logic functions against target test cases before building the full UI:
# Test Suite Sandbox
assert evaluate_strength("123") == 0
assert evaluate_strength("Correct-Horse-Battery-2024!") == 100
h1, s1 = hash_password("Secret123")
h2, s2 = hash_password("Secret123", salt=s1)
assert h1 == h2 # Deterministic hash check passed!
print("ALL UNIT TESTS PASSED!")
Hands-on Lab
Pair Programming: Core Assembly
Work with a partner to assemble the 3 core functions into a clean Python file titled cybershield_engine.py.
Check Your Understanding
Which stage of the SDLC focuses on feature definition and user stories?
AImplementation / Coding
BRequirements Analysis
CUnit Testing
DDeployment
Click to reveal answer
Check Your Understanding
Why do we separate UI functions from Core Logic functions?
AIt doubles the execution speed of Python
BIt makes code reusable, modular, and easy to unit test
CIt prevents Python from creating bytecode
DIt eliminates the need for variables
Click to reveal answer
Check Your Understanding
What is the purpose of generating a random Salt during password hashing?
ATo shorten the length of the SHA-256 string
BTo ensure identical passwords generate completely different hashes
CTo store the password in plaintext for admins
DTo bypass 2FA authentication
Click to reveal answer
Check Your Understanding
Which Python module provides cryptographically secure random numbers?
Arandom
Bsecrets
Cmath
Dtime
Click to reveal answer
Peer Code Review
Code Quality & Readability Checklist
- Docstrings: Does every function have a clear docstring explaining parameters and return types?
- Naming: Are variable names descriptive (e.g.,
has_digit instead of d)?
- Modularity: Is any function longer than 25 lines?
Build Status Audit
Part 1 Milestone Completed Checklist
Completed Today
✅ Architecture Blueprint
✅ `evaluate_strength()` Engine
✅ `hash_password()` SHA-256 Engine
✅ CLI Menu Loop
Target for Part 2
⏳ CSV File Storage Persistence
⏳ Input Validation Guardrails
⏳ AI Password Advice Feature
⏳ Final Showcase Demo
Chapter Summary
Architecture & Engine Takeaways
- Always blueprint architecture before writing code.
- Keep logic functions pure and separate from UI input/print statements.
- Use cryptographic salt generation to secure hashes against dictionary attacks.
- Run unit tests early to catch edge case logical bugs.
Exit Ticket
Milestone Verification
Does your `hash_password()` function return a tuple containing both the hex hash string and the salt string? Demonstrate execution to your teacher.
Looking Ahead
Next Chapter: Mini Project Part 2
In Part 2, we will integrate CSV persistence, add defensive error handling, and showcase our finished CyberShield CLI application!
Milestone Summary
Part 1 Engine Operational
Your core cybersecurity engine is fully tested and ready for integration!