SUBTASK #86: Sessions and route protection in the Application Controller (2.0)

Aperta
#90 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@javi120467 ci sta già lavorando.

Dal 2/11/2026.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
22/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
flask, python

Direzione di ricerca

Start from the Application Controller package from #50, then add the auth module at backend/controller/auth.py with its tests in tests/controller/test_auth.py. The SECRET_KEY note goes in the .env section of README.md. Build the @requires and @public decorators and the /api/login, /api/logout and /api/me routes, and run the Flask test client tests without a database. Done when those tests pass and an unauthenticated GET /api/devices returns 401. The issue depends on #88, #89 and #50, which are not yet complete.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

backend Low Priority security subtask

What to do

Connect access control to the Flask app from #50: sign-in, sign-out and "who am I" endpoints, a secure session cookie, and a permission check on every API route, so a request that isn't allowed never reaches a service.

Background

  • Spec SEC-01, SEC-03, SEC-07, SEC-09, CP-01, CM-11; AT-13 (an action the role doesn't permit is rejected and logged)
  • System design 11.2: session cookie Secure, HttpOnly, SameSite=Strict; ApplicationController.checkPermissions() → AccessControlService.authorizeAction()
  • System design 12: Flask's built-in session handling
  • Permissions are subtask 2; sign-in is subtask 3. Session length is a decision on #PARENT.

Steps

  • Settings:
    • SECRET_KEY from .env. The app refuses to start if it's missing or shorter than 32 characters. The README shows how to make one: py -3.13 -c "import secrets; print(secrets.token_hex(32))"
    • Cookie: HttpOnly, SameSite=Strict, and Secure whenever the app is served over HTTPS (HTTPS itself arrives in M7)
    • Signed out after 8 hours in any case, and after 30 minutes without a request (a "last seen" time in the session, checked on each request)
  • Endpoints:
    • POST /api/login with {username, password}: 200 with the user (to_dict()) and their permissions, or 401 with {"error": reason}. On success, clear the session before storing the user id, so a session made before sign-in can't be reused (session fixation).
    • POST /api/logout: clears the session, 204
    • GET /api/me: the signed-in user and their permissions, or 401
  • Route protection:
    • @requires(Permission.X) on every route: loads the user from the session on each request; 401 if not signed in, timed out or disabled (and clears the session); 403 with the reason from authorize if the role isn't allowed; otherwise puts the user on flask.g.user
    • @public only on POST /api/login
    • A test that walks app.url_map and fails if any /api/ route has neither
  • Refused requests are logged at WARNING: user, permission and path, never the request body
  • Starting a scan (#51) takes the user from g.user, not from the request body (CM-11)
  • Requests that change data must be JSON (Content-Type: application/json), otherwise 415. Together with SameSite=Strict, this stops another website from submitting changes using a signed-in user's cookie (CSRF).
  • Unit tests (Flask test client, fake stores, a fake clock):
    • Signed out: every /api/ route except login gives 401
    • A viewer gets 403 on starting a scan, and 200 on the device list
    • The login response sets a cookie marked HttpOnly and SameSite=Strict
    • After sign-out, the old cookie gives 401
    • A user disabled after signing in gets 401 on their next request
    • 31 minutes without a request gives 401
    • No response body contains password_hash or $argon2
    • A refused request is logged without the password (assertLogs)
    • A form-encoded POST gives 415

Where

  • The Application Controller package from #50 (e.g. backend/controller/auth.py)
  • tests/controller/test_auth.py
  • README.md (the SECRET_KEY line in the .env section)

Done when

  • All the tests above pass without a database
  • With the app running, GET /api/devices signed out gives 401, and after signing in as a viewer gives the list

Depends on

  • Roles and permissions (#88) and Sign in (#89)
  • Application entry point and Application Controller (#50)
  • Scan and device API endpoints (#51)
Lingua principale
Python
Stelle
1
Fork
1
Merge medio
9h 31m
PR unite (30g)
36

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Bearkat-Professionals/Software-Engineering-Project

Tutte le issue di Bearkat-Professionals/Software-Engineering-Project

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.