PYTHON + FLASK + MONGODB

Your complete AttendX application

The standalone application uses only Python, Jinja2, HTML, and CSS. No JavaScript.

This platform hosts a React preview, not a running Python server. The ZIP contains the separate, complete Flask/MongoDB application for local execution.

From source to secure attendance

01

Install dependencies

cd AttendX
python -m venv .venv
pip install -r requirements.txt
02

Configure & initialize

Copy .env.example to .env
Set MONGO_URI and FLASK_SECRET_KEY
flask --app app init-db
03

Create admin & start

flask --app app create-admin
flask --app app run

The README covers MongoDB setup, student registration, class sessions, duplicate checks, authorized/unauthorized network tests, and deployment limits.

Project files 19

AttendX/README.mdREAD ONLY
# AttendX — Protocol Zero

**Smart Attendance. Secure Campus.** A locally runnable hackathon prototype using Python 3, Flask, MongoDB, PyMongo, Jinja2, HTML5 and CSS3. The Flask application contains no JavaScript files or script tags. Its Content Security Policy explicitly prohibits scripts.

## Hosting note

The accompanying hosted React interface is a visual preview and source-download tool only. This platform cannot run a persistent Flask server. Extract/download the `AttendX/` project and run it locally for real authentication, MongoDB storage and server-side IP verification. The React preview is not part of the standalone Flask application. No GenMB SDK or React dependency is used by the Flask project.

## File placement

Keep this directory layout intact:

```
AttendX/
  app.py
  config.py
  requirements.txt
  README.md
  .env.example
  .gitignore
  templates/
    base.html
    login.html
    register.html
    student_dashboard.html
    attendance.html
    attendance_history.html
    profile.html
    admin_dashboard.html
    students.html
    subjects.html
    attendance_records.html
    network_settings.html
    error.html
  static/
    style.css
```

Run commands from inside `AttendX/`. Flask automatically discovers `templates/` and `static/` relative to `app.py`.

## 1. Install Python dependencies

Use Python 3.11 or newer and a running MongoDB Community server or MongoDB Atlas cluster.

```bash
cd AttendX
python -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell instead:
# .venv\Scripts\Activate.ps1
pip install -r requirements.txt
```

## 2. Configure MongoDB and secrets

Install MongoDB Community using the installation procedure for your operating system, start its service and confirm it listens on localhost. Alternatively create an Atlas cluster, a least-privilege database user and a restricted network access list; copy its connection string into your private `.env`. Atlas requires your Flask server's outbound IP to be permitted. Do not allow every IP in a production Atlas access list.

Copy `.env.example` to `.env`:

```bash
# macOS/Linux
cp .env.example .env
# Windows PowerShell: Copy-Item .env.example .env
python -c "import secrets; print(secrets.token_hex(32))"
```

Set `FLASK_SECRET_KEY` to that generated value. Set `MONGO_URI` to your private connection string and `MONGO_DB_NAME` to `attendx` or your chosen database. The unauthenticated localhost URI in `.env.example` is only a local example; require MongoDB authentication for deployment. Never commit `.env` or expose MongoDB to the public internet. No credentials are embedded in source.

Set `CAMPUS_TIMEZONE` to the actual IANA timezone of your campus. UTC is the default. All records retain UTC timestamps and a campus-local date/time. Use `SESSION_COOKIE_SECURE=false` only for local HTTP; use true when deployed over HTTPS. `ALLOW_LOCAL_TEST_NETWORK=true` allows only the explicit loopback test-network CLI command; it never bypasses IP verification.

Initialize the database:

```bash
flask --app app init-db
```

MongoDB creates the selected database/collections on their first index or document write. Connection errors are shown as friendly 503 pages and server logs; initialization reports CLI errors.

## 3. Create the first admin securely

```bash
flask --app app create-admin
```

Enter your own name, actual email and a strong password at the hidden prompt. No default admin password exists. Use 10–128 characters containing letters and a number. Public registration always creates a student and cannot select a privileged role.

Create additional faculty through the private CLI:

```bash
flask --app app create-admin --role faculty
```

Faculty can manage students, subjects, sessions and attendance. Only administrators can change authorized networks.

## 4. Start Flask

```bash
flask --app app run --host 127.0.0.1 --port 5000
# Or: python app.py
```

Open `http://127.0.0.1:5000`. Sign in with the admin account. This development server binds to loopback by default, with debugger disabled. It is not a production deployment server.

## 5. Test student attendance end-to-end

1. Sign in as admin. Add a student through Students, or register in a separate private browser window. Use your own test email and department (for instance Computer Science), year 2.
2. Add a subject in Subjects & sessions. Its department/year must exactly match the student's. Select an existing faculty/admin.
3. Authorize your test network using step 6.
4. Open a session for the subject. It starts immediately for the entered duration, 5–240 minutes; a session cannot cross campus midnight.
5. In the student browser, sign in and open Mark attendance. The actual server-observed IP and network authorization are shown.
6. During the open session, mark present. Verify the success message, history row and updated dashboard percentage. The server chooses status, date, time, enrollment and network evidence; it ignores any client-supplied alternative status or IP.
7. Resubmit the same session form (e.g. using browser history). The unique MongoDB index rejects duplicates. Two different sessions of the same subject on the same day can each receive exactly one record.
8. Sign in as faculty/admin, filter Attendance records by student, subject or date. Use the correction form to set present/absent/excused with a reason. The embedded audit records actor, status, time and reason; original IP evidence is retained. New manual entries are explicitly not network verified.
9. Verify student routes refuse signed-out requests and `/admin/dashboard` refuses student accounts with 403. Direct GET requests to mutation-only routes return 405. POST forms require a valid CSRF token.

## 6. Authorized and unauthorized network scenarios

### Authorized loopback test

With `ALLOW_LOCAL_TEST_NETWORK=true`:

```bash
flask --app app add-test-network --cidr 127.0.0.1/32
# If accessing through IPv6 loopback instead:
flask --app app add-test-network --cidr ::1/128
```

Access `http://127.0.0.1:5000`. Confirm Authorized in the student interface and successfully mark an open session. You can also add those addresses through the administrator's Network settings page. The CLI rejects non-loopback CIDRs.

### Unauthorized test without spoofing

In admin Network settings, edit every active range that matches the student's IP and uncheck Network is active, then save. Refresh the student's attendance page. It shows Unauthorized and the exact denial message. The mark button is disabled for clarity, but replaying an already-loaded valid attendance POST is independently rejected by the server. Open a new session if the previous one already has a record.

For a second real network scenario, bind to `0.0.0.0` in a controlled local environment, authorize only the actual intended campus/LAN CIDR, then access from a device outside it. Allow only necessary trusted firewall traffic; don't expose the development server publicly. Client IP can reflect NAT; allowlist the IP as observed by your deployment server, not necessarily a student's private Wi-Fi IP.

### Reverse proxies

The application ignores `X-Forwarded-For` by default. If deployed behind a known reverse proxy, set `TRUSTED_PROXY_CIDRS` to that proxy's exact address/range. The algorithm walks the forwarded chain right-to-left and stops at the first untrusted hop. Your proxy must append or replace the incoming client chain correctly, and your firewall must prevent unauthorized direct access through trusted proxy addresses. Never use `0.0.0.0/0`, `::/0`, or arbitrary untrusted ranges for proxy trust. Invalid forwarded IPs are denied.

Network verification confirms the server-observed source network, not physical classroom presence. It cannot distinguish devices sharing a NAT or prevent authorized-network VPN access; complement it with campus firewall/VPN policy. No fake IP override is provided.

Disable loopback test entries and set `ALLOW_LOCAL_TEST_NETWORK=false` before deployment.

## Attendance percentage

For each currently eligible subject, the denominator includes non-cancelled sessions that have started, whether or not a student submitted. Unmarked/absent sessions do not count as present. Explicitly excused sessions are excluded from the denominator. Percentage = present / (started eligible sessions - excused) × 100. A zero denominator displays 0%. The 75% dashboard target is a labeled recommended benchmark, not an institution-specific rule. This prototype uses current department/year eligibility; it does not model enrollment effective dates, so newly registered students include prior sessions for their current subjects.

## MongoDB schema and indexes

- `users`: requested fields including UUID `user_id`, hashed password and role. Unique `user_id` and normalized email.
- `subjects`: requested fields, UUID `subject_id`, unique name/department/year tuple.
- `class_sessions`: UUID `session_id`, subject, label, date, starts/ends timestamps, creator and cancellation flag. Required to distinguish multiple classes of the same subject on one date.
- `attendance`: all requested fields plus session, source, verified network and embedded correction audit. Unique `(student_id, subject_id, session_id)` prevents races/duplicates. Query indexes cover subject/date and student/date.
- `network_settings`: requested fields plus unique `network_id`, updated actor. Inactive networks remain editable.
- `auth_attempts`: hashed IP/email key, failure count and expiry; MongoDB TTL index removes expired attempts. Eight failed attempts within fifteen minutes throttle that IP/account pair.
- `audit_log`: reserved indexed collection; attendance correction history is stored atomically within each record instead, so a standalone MongoDB instance works without multi-document transactions.

No sample data is automatically persisted. The UI's source preview is clearly labeled demo data and does not represent the live MongoDB instance.

## Security and limits

Werkzeug password hashing, Flask signed sessions, server-reloaded roles, POST-only mutations, CSRF tokens on every form, strict no-script CSP, escaped Jinja content, bounded input, HTTPS cookie support, no-store responses, fail-closed allowlists and unique attendance indexes are included. Never trust user-entered roles, IPs or status. Administrators are created through an operator-controlled CLI, not the web registration form.

This is a hackathon prototype, not a complete institutional compliance system. Add managed backups, centralized security monitoring, password recovery/change flows, student identity verification, enrollment history and a production WSGI deployment before real institutional use. Student list/history/filter screens show at most 500 matching rows; session correction choices are limited to 500 latest sessions. You can narrow filters to inspect records. Database downtime never receives a fake success message.

## Automated local verification

`test_attendx.py` contains integration tests for login failure, duplicate registration, every rendered template, student/admin authorization, CSRF enforcement, authorized/unauthorized attendance, duplicate indexes and forged proxy headers. Run with MongoDB available:

```bash
python -m unittest -v test_attendx
```

Tests create a randomly named `attendx_test_...` database and remove it after the suite. Use a local MongoDB instance or a test-only account that can create/drop that test database. Tests never use the normal attendance database. The hosted preview cannot execute these Python/MongoDB integration tests; run them locally before relying on the prototype.

## Troubleshooting

- Configuration error at startup: generate a secret and set MONGO_URI in `.env`; make sure commands run from `AttendX/`.
- MongoDB 503: check the MongoDB service, database credentials, Atlas network allowlist and connection URI. Restart and rerun `init-db` after fixing it.
- Login does not persist on localhost: set `SESSION_COOKIE_SECURE=false` for HTTP only.
- No subjects: student's department/year must exactly match the subject's.
- No check-in button: open a current session and verify the actual network is active/authorized.
- Expired form: refresh to obtain a new CSRF token; session timeout is eight hours.
- Wrong time/day: configure CAMPUS_TIMEZONE and ensure server system time is correct.