Skip to main content

QR Code-Based Checkpoint Access Management System

Project description

QR In/Out - QR Code-Based Checkpoint Access Management System

Stars Sponsors Python Streamlit License

한국어 문서 | English

Admin Statistics Dashboard Host QR Code Display Guest QR Scan
Admin Dashboard Host QR Display Guest Check-In

Overview

QR In/Out is a comprehensive QR code-based checkpoint access management system built with Python and Streamlit. It enables organizations to deploy static or dynamic QR codes at designated checkpoints, allowing authorized visitors to check in and out by scanning codes via their mobile devices.

Key Features

  • Three Role-Based Pages

    • Admin: Manage checkpoints, guests, view activity logs, and configure system settings
    • Host: Display QR codes (static or dynamic) at checkpoint locations
    • Guest: Scan QR codes to check in/out, view personal visit history
  • Dual QR Code Modes

    • Static QR: Never expires, suitable for printable signage
    • Dynamic QR: Auto-refreshes every 30 minutes with HMAC-SHA256 signatures for enhanced security
  • Time-Based Access Control

    • Checkpoint-specific allowed hours
    • Guest-specific allowed hours (optional)
    • Timezone-aware validation using World Time API
    • Overnight shift support (e.g., 22:00 - 06:00)
  • Security Features

    • bcrypt password hashing for admin and checkpoint access
    • HMAC-SHA256 signatures for dynamic QR codes
    • Sequence number validation to prevent replay attacks
    • Time synchronization via World Time API to prevent local time manipulation
    • Soft delete mechanism to preserve data history
  • Enhanced User Experience (v1.2)

    • WiFi Info Display: Show network SSID/password on Host screen for guest convenience
    • Connection Status Monitoring: Real-time server and time API status with visual indicators
    • Sound Feedback: Audio confirmation for successful/failed scans (Web Audio API)
    • Remember Me: Save guest credentials locally via browser localStorage
    • Kiosk Mode: Continuous scanning mode for shared devices at checkpoints
    • High Contrast QR: Multiple display modes (default, high contrast, inverted) for various lighting conditions
  • Local Data Storage

    • JSON-based storage (no external database required)
    • Thread-safe concurrent access
    • Offline operation capability
    • Activity log persistence

Screenshots

Click to view all screenshots

Home

Home Page

Admin

Admin Login Checkpoint Management
Admin Login Checkpoint Management
Guest Management Activity Logs
Guest Management Activity Logs
Statistics Dashboard
Statistics Dashboard

Host

Host Login QR Code Display
Host Login QR Code Display

Guest

Guest Login QR Scan
Guest Login QR Scan
Visit History
Visit History

Technology Stack

  • Framework: Streamlit (Python web framework)
  • QR Generation: qrcode, Pillow
  • QR Scanning: pyzbar (requires zbar system library)
  • Time Synchronization: World Time API, TimeAPI.io
  • Authentication: bcrypt password hashing with salt
  • Data Storage: JSON files with thread-safe locks
  • Timezone Handling: pytz
  • Environment Management: python-dotenv

Installation

Option A: Install via pip (Recommended)

pip install qr-in-out

Option B: Install from source

git clone https://github.com/jakeleekr13-otter/qr_in_out.git
cd qr_in_out
pip install -r requirements.txt

System Dependencies (QR Scanning)

The pyzbar library requires the zbar shared library:

macOS (Homebrew):

brew install zbar

Ubuntu / Debian:

sudo apt-get install libzbar0

Windows: Usually pip install pyzbar includes necessary DLLs. If issues occur, install Visual C++ Redistributable Packages.

Environment Setup

cp .env.example .env
# Edit .env and set QR_SECRET_KEY (min 32 characters)
# Generate a key: python -c "import secrets; print(secrets.token_hex(32))"

Run

streamlit run app.py

The application will open at http://localhost:8501


Quick Start Guide

Step 1: Admin Setup

  1. Navigate to 👤 Admin page
  2. First-time login uses default credentials (you'll be prompted to change password):
    • Username: admin
    • Password: admin
  3. IMPORTANT: Change the default password immediately

Step 2: Create Checkpoint

  1. In Admin page, go to Create Checkpoint section
  2. Fill in checkpoint details:
    • Name (e.g., "Main Entrance")
    • Location (e.g., "Building A, 1F")
    • Allowed Hours (e.g., 09:00 - 18:00)
    • QR Mode: Static (printable) or Dynamic (auto-refresh)
    • Admin Password (for Host page access)
  3. Select which guests are allowed to access this checkpoint
  4. Click Create Checkpoint

Step 3: Register Guests

  1. Go to Guest Management section
  2. Click Register New Guest
  3. Enter guest information:
    • Name (required)
    • Email (required)
    • Phone (optional)
    • Timezone (e.g., Asia/Seoul)
    • Allowed Checkpoints
    • Custom Allowed Hours (optional)
  4. Click Register Guest

Step 4: Display QR Code (Host)

  1. Navigate to 🖥️ Host page
  2. Select a checkpoint from dropdown
  3. Enter checkpoint's admin password
  4. QR code will be displayed:
    • Static QR: Download and print for permanent display
    • Dynamic QR: Keep browser open; refreshes automatically every 30 minutes

Step 5: Guest Check-In/Out

  1. Navigate to 👋 Guest page
  2. Enter Name and Email to authenticate
  3. Choose action: Check In or Check Out
  4. Scan QR code using:
    • Camera (mobile devices)
    • Upload QR Image (screenshot or file)
  5. System validates and logs activity
  6. View personal visit history in My Visit History section

New Features in v1.2

WiFi Information Display (Host)

When creating a checkpoint, optionally configure WiFi credentials. The Host page will display these for guest convenience:

  • WiFi SSID: Network name guests should connect to
  • WiFi Password: Network password

This is particularly useful when guests need to join a specific network to access the QR scanning page.

Connection Status Monitoring

Both Host and Guest pages now display real-time connection status:

Status Icon Description
All Connected Server and Time API both reachable
Partial ⚠️ Server connected, Time API unreachable (using local time)
Disconnected Cannot reach server

Sound Feedback (Guest)

Audio feedback plays automatically on scan results:

  • Success: Confirmation sound on successful check-in/out
  • Error: Alert sound on failed scan

Uses Web Audio API with HTML5 Audio fallback for broad browser support.

Remember Me (Guest)

Enable "Remember Me" on the Guest login page to save credentials locally:

  • Uses browser localStorage (never sent to server)
  • Persists across sessions
  • Clear with "Forget Me" button

Kiosk Mode (Guest)

For shared devices at checkpoint locations:

  • Enable "Kiosk Mode" checkbox after login
  • Continuous scanning without re-authentication
  • 5-minute timeout for security
  • No access to personal visit history

High Contrast QR Display (Host)

Choose QR display mode based on environment:

Mode Fill Color Background Best For
Default Black White Standard lighting
High Contrast Black Yellow Bright environments
Inverted White Black Dark environments

Size options: Small (8), Medium (12), Large (16), X-Large (20)


Usage Examples

Scenario 1: Office Building Access

Setup:

  • Create checkpoint: "Main Entrance"
  • Allowed hours: 08:00 - 20:00
  • QR mode: Dynamic (security)
  • Register employees as guests

Daily Use:

  • Host displays dynamic QR code on monitor at entrance
  • Employees scan QR code to check in when arriving (08:30)
  • Employees scan again to check out when leaving (18:15)
  • Admin monitors real-time activity logs

Scenario 2: Event Registration

Setup:

  • Create checkpoint: "Conference Registration Desk"
  • Allowed hours: 09:00 - 18:00
  • QR mode: Static (printable)
  • Register event attendees as guests

Event Day:

  • Print static QR code and place at registration desk
  • Attendees scan QR code upon arrival
  • Staff monitors check-in status via Admin dashboard
  • Export activity logs to CSV for attendance records

Scenario 3: Multi-Site Facility Management

Setup:

  • Create checkpoints for each building (A, B, C, D)
  • Different allowed hours per building
  • Assign specific guests to specific buildings
  • Guest-level time restrictions for contractors

Operations:

  • Each building displays its own QR code (static or dynamic)
  • Guests can only access authorized buildings
  • Contractor access automatically restricted to assigned hours
  • Activity logs track all cross-building movements

System Architecture

qr_in_out/
├── app.py                  # Main Streamlit entry point
├── pages/
│   ├── 1_👤_Admin.py      # Admin management interface
│   ├── 2_🖥️_Host.py       # QR code display page
│   └── 3_👋_Guest.py      # Guest check-in/out page
├── core/
│   ├── models.py           # Data models (Checkpoint, Guest, ActivityLog)
│   ├── storage.py          # JSON storage with thread-safe operations
│   ├── auth.py             # Authentication and password hashing
│   ├── qr_manager.py       # QR generation, validation, signatures
│   ├── time_service.py     # Time synchronization via World Time API
│   ├── time_validator.py   # Time-based access control validation
│   └── connection_health.py # Connection status monitoring (v1.2)
├── utils/
│   └── helpers.py          # Utility functions (email validation, lookups)
├── data/                   # JSON storage files (auto-created)
│   ├── checkpoints.json
│   ├── guests.json
│   ├── activity_logs.json
│   └── admin_settings.json
├── assets/
│   └── sounds/             # Audio feedback files (v1.2)
│       ├── success.mp3
│       └── error.mp3
├── docs/                   # Documentation and planning artifacts
│   └── planning-artifacts/
│       ├── PRD-Overview.md
│       ├── PRD-Admin.md
│       ├── PRD-Host.md
│       └── PRD-Guest.md
├── requirements.txt        # Python dependencies
└── README.md              # This file

Network Architecture

QR In/Out supports various network deployment scenarios depending on your organization's needs.

Deployment Scenarios

Scenario 1: LAN (Same Network)

All devices on the same local network

[Streamlit Server: 192.168.1.100:8501]
         │
    [Local Router]
    ┌────┴────┐
    │         │
[Host]    [Guest Mobile]
  • Use Case: Single office, event venue
  • Setup: All devices connect to the same WiFi
  • Guest Access: http://192.168.1.100:8501

Scenario 2: Cloud Deployment

Server accessible from anywhere

[Internet]
    │
[Cloud Server with Public IP]
    │
[Reverse Proxy (nginx/Caddy)]
    │
[Streamlit: localhost:8501]
  • Use Case: Multi-site facilities, remote checkpoints
  • Setup: Deploy to cloud provider (AWS, GCP, Azure, etc.)
  • Guest Access: https://yourdomain.com

Scenario 3: VPN/Remote Access

Secure remote access for distributed locations

[HQ Network]─────────[VPN Server]─────────[Remote Office Network]
      │                                            │
[Streamlit Server]                        [Host Device + Guests]
192.168.1.100:8501                          (VPN Clients)
  • Use Case: Corporate networks, high-security environments
  • Setup: Connect remote sites via VPN tunnel
  • Guest Access: After VPN connection, http://192.168.1.100:8501 (internal IP)

Note: In this scenario, guests also need VPN client access. For external visitors (no VPN), use Scenario 2 (Cloud Deployment) instead.

Firewall Configuration

Port Protocol Direction Description
8501 TCP Inbound Streamlit default port
443 TCP Outbound World Time API (HTTPS)
80 TCP Outbound World Time API (HTTP fallback)
53 UDP/TCP Outbound DNS (domain name resolution)

HTTPS Configuration

For production deployments, we recommend using HTTPS:

Option 1: Reverse Proxy (Recommended)

# nginx configuration
server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:8501;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Option 2: Streamlit Built-in SSL

streamlit run app.py --server.sslCertFile=cert.pem --server.sslKeyFile=key.pem

Security Considerations

Current Security Measures

  • Password hashing for admin and checkpoint access
  • HMAC-SHA256 signatures on dynamic QR codes
  • Sequence number validation to prevent replay attacks
  • Time synchronization to prevent local time manipulation
  • Soft delete mechanism (data preservation)
  • Thread-safe concurrent storage access

⚠️ Security Warnings

BEFORE PRODUCTION DEPLOYMENT:

Fixed in v1.0: Password hashing upgraded to bcrypt ✅ Fixed in v1.0: SECRET_KEY moved to environment variable ✅ Fixed in v1.0: Deleted guest authentication bypass patched

Still Required:

  1. Environment Configuration: Set QR_SECRET_KEY in .env file:

    # Copy .env.example to .env and set your secret key
    cp .env.example .env
    # Edit .env and set QR_SECRET_KEY to a secure random value
    
  2. Default Credentials: Change default admin password on first login (prompted automatically)

  3. HTTPS: Deploy with HTTPS in production (Streamlit supports via reverse proxy)

  4. Data Encryption: Consider encrypting sensitive data at rest for highly sensitive deployments

  5. File Permissions: Ensure data/ directory has restricted permissions (0700)

See SECURITY.md for detailed security analysis and additional recommendations.


Configuration

System Settings (Admin Page)

  • Admin Timezone: Default timezone for admin operations
  • Default Guest Timezone: Default timezone for new guests
  • QR Refresh Interval: Dynamic QR refresh period (default: 1800 seconds / 30 minutes)
  • Require Time Sync: Enforce time synchronization via World Time API

Environment Variables

Create .env file (not committed to git):

QR_SECRET_KEY=your-secure-random-key-here-min-32-chars
STREAMLIT_SERVER_PORT=8501

Data Models

Checkpoint

{
  "id": "uuid",
  "name": "Main Entrance",
  "location": "Building A, 1F",
  "allowed_hours": {"start_time": "09:00", "end_time": "18:00"},
  "qr_mode": "static" | "dynamic",
  "admin_password_hash": "hashed_password",
  "allowed_guests": ["guest_id_1", "guest_id_2"],
  "current_qr_sequence": 0,
  "wifi_ssid": "Office-Guest-WiFi",      # (v1.2) WiFi network name for Host display
  "wifi_password": "guest1234",           # (v1.2) WiFi password for Host display
  "deleted_at": null,
  "created_at": "2026-02-05T10:00:00Z",
  "updated_at": "2026-02-05T10:00:00Z"
}

Guest

{
  "id": "uuid",
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "+1-555-0100",
  "timezone": "America/New_York",
  "allowed_checkpoints": ["checkpoint_id_1"],
  "allowed_hours": {"start_time": "08:00", "end_time": "20:00"},
  "deleted_at": null,
  "created_at": "2026-02-05T10:00:00Z",
  "updated_at": "2026-02-05T10:00:00Z"
}

Activity Log

{
  "id": "uuid",
  "timestamp": "2026-02-05T14:30:00Z",
  "checkpoint_id": "checkpoint_uuid",
  "guest_id": "guest_uuid",
  "action": "check_in" | "check_out",
  "qr_code_used": "{...qr_content...}",
  "status": "success" | "failure",
  "failure_reason": null | "error message",
  "metadata": {"scanned_at": "2026-02-05T14:30:00Z"}
}

API Reference

Core Modules

TimeService

TimeService.get_current_time(timezone_str: str) -> Tuple[datetime, bool]
# Returns: (current_time, is_synchronized)
# Sources: World Time API → TimeAPI.io → Local system time

QRManager

QRManager.generate_static_qr_content(checkpoint_id: str) -> str
QRManager.generate_dynamic_qr_content(checkpoint_id, sequence, issued_at, expires_at) -> str
QRManager.verify_signature(qr_content: Dict) -> bool
QRManager.is_qr_expired(qr_content: Dict, current_time: datetime) -> bool

AuthManager

AuthManager.hash_password(password: str) -> str
AuthManager.verify_password(password: str, password_hash: str) -> bool

Troubleshooting

Common Issues

1. "pyzbar library is not available" Error

Cause: zbar system library not installed

Solution: Install system dependency:

# macOS
brew install zbar

# Ubuntu/Debian
sudo apt-get install libzbar0

2. Time Synchronization Failures

Symptoms: "Not Synchronized (Using Server Time)" warning

Causes:

  • No internet connection
  • World Time API unavailable
  • Firewall blocking API requests

Solution:

  • Check internet connection
  • Verify firewall allows HTTP/HTTPS to worldtimeapi.org and timeapi.io
  • System will fall back to local time with warning

3. QR Code Scan Fails with "Invalid Signature"

Cause: SECRET_KEY mismatch or QR code tampering

Solution:

  • Ensure SECRET_KEY is consistent across all components
  • Regenerate QR code from Host page
  • Do not manually edit QR code content

4. Guest Cannot Authenticate

Causes:

  • Email/name mismatch (check case sensitivity)
  • Guest deleted (soft delete)
  • Typos in email or name

Solution:

  • Verify exact spelling of name and email
  • Check Admin page to confirm guest is active (not deleted)
  • Email is case-insensitive but must match exactly

5. Access Denied During Allowed Hours

Causes:

  • Checkpoint allowed hours restriction
  • Guest-specific allowed hours restriction
  • Timezone mismatch

Solution:

  • Check both checkpoint AND guest allowed hours
  • Verify guest's timezone setting matches their actual location
  • Ensure current time is within BOTH time windows

Contributing

We welcome contributions! Please follow these guidelines:

  1. Fork the repository
  2. Create a branch for your feature (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone your fork
git clone https://github.com/jakeleekr13-otter/qr_in_out.git
cd qr-in-out

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Run tests (when available)
pytest

# Run application
streamlit run app.py

Code Style

  • Follow PEP 8 guidelines
  • Use type hints where applicable
  • Add docstrings to all public functions
  • Write unit tests for new features

Roadmap

Planned Features

  • Enhanced Security: bcrypt password hashing (completed in v1.0)
  • Network Architecture Documentation: Deployment guides and firewall settings (completed in v1.2)
  • WiFi Info Display: Show network credentials on Host screen (completed in v1.2)
  • Connection Status Monitoring: Real-time server and API status (completed in v1.2)
  • Sound Feedback: Audio confirmation for scan results (completed in v1.2)
  • Remember Me: Save guest credentials locally (completed in v1.2)
  • Kiosk Mode: Continuous scanning for shared devices (completed in v1.2)
  • High Contrast QR: Multiple display modes for accessibility (completed in v1.2)
  • Multi-Language Support: Internationalization (i18n)
  • Database Backend: PostgreSQL/MySQL option for larger deployments
  • Email Notifications: Alert guests on check-in/out
  • Mobile App: Native iOS/Android companion app
  • API Endpoints: REST API for third-party integrations
  • Analytics Dashboard: Advanced reporting and visualizations
  • Role-Based Access Control: Granular permissions for admin users
  • Audit Logs: Comprehensive admin action logging
  • Backup/Restore: Automated data backup functionality

License

This project is licensed under the MIT License - see the LICENSE file for details.


Acknowledgments


Support


💖 Support

If you find this tool useful, please consider supporting development!

Your support helps improve and maintain this project.


Disclaimer

This software is provided "as-is" without warranty. Please review security considerations before deploying in production environments. The default configuration is intended for development and testing purposes.


Made with ❤️ using Python and Streamlit

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qr_in_out-1.0.3.tar.gz (41.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qr_in_out-1.0.3-py3-none-any.whl (36.9 kB view details)

Uploaded Python 3

File details

Details for the file qr_in_out-1.0.3.tar.gz.

File metadata

  • Download URL: qr_in_out-1.0.3.tar.gz
  • Upload date:
  • Size: 41.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qr_in_out-1.0.3.tar.gz
Algorithm Hash digest
SHA256 707151414f3e2358d01b2c4cdf1ecb0cd7776728303012523f347daa2a815e56
MD5 4937afafe0cdef3783325f8eb1fcdc6e
BLAKE2b-256 212157468d809e3a40623d1a1f6b8ba0b517eb67b55dd9e7a2cfae05365ecbc5

See more details on using hashes here.

Provenance

The following attestation bundles were made for qr_in_out-1.0.3.tar.gz:

Publisher: publish.yml on jakeleekr13-otter/qr_in_out

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file qr_in_out-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: qr_in_out-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 36.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for qr_in_out-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 00289bd2b4b9ec2ced7d88a273b9cbe69e2771531c1c2d97cc3ab84ecb78336b
MD5 ee8d3bbd855022cd7366b79764e0f2af
BLAKE2b-256 8b2d3099303c42e1e6f91c4f77f207f15047a78095e2f9785b0aefd343a34b21

See more details on using hashes here.

Provenance

The following attestation bundles were made for qr_in_out-1.0.3-py3-none-any.whl:

Publisher: publish.yml on jakeleekr13-otter/qr_in_out

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page