Skip to content

feat: API Key and person UUID based meetecho APIs - #11719

Open
rjsparks wants to merge 6 commits into
ietf-tools:mainfrom
rjsparks:meetecho_person_uuid_v2
Open

feat: API Key and person UUID based meetecho APIs#11719
rjsparks wants to merge 6 commits into
ietf-tools:mainfrom
rjsparks:meetecho_person_uuid_v2

Conversation

@rjsparks

@rjsparks rjsparks commented Sep 4, 2026

Copy link
Copy Markdown
Member

Adds a parallel set of DRF endpoints for the session data Meetecho pushes, keyed by
Person UUID and authenticated by service token. The six existing personal-API-key
endpoints keep working, so Meetecho migrates on its own schedule with no coordinated
cutover.

New endpoints

Endpoint Body
POST /api/meeting/session/{id}/video-url/ {"url": ...}
POST /api/meeting/session/{id}/recording-name/ {"name": ...}
POST /api/meeting/session/{id}/bluesheet/ {"bluesheet": [{"name", "affiliation"}]}
POST /api/meeting/session/{id}/attendees/ {"attendees": [{"person_uuid", "join_time"}]}
POST /api/meeting/session/{id}/chatlog/ {"chatlog": [...]}
POST /api/meeting/session/{id}/polls/ {"polls": [...]}
GET /api/meeting/registration/attended/by-uuid/{uuid}/

JSON in, JSON out, X-Api-Key via api_key_endpoint. Errors use the project's
standardized error envelope.

Decisions

  • Identifiers. Only the attendees endpoint carried a person identifier
    (user_id, a User pk — the OIDC sub); it becomes person_uuid. Any UUID the
    datatracker issued resolves, including one superseded by a merge. Meetecho already
    gets these from the datatracker_uuid OIDC claim. Sessions stay addressed by pk.
  • Free text stays free text. Bluesheet names and chatlog authors are what the
    uploader observed, not person references — Meetecho can't always resolve a room
    attendee or chat participant to a Person.
  • Authorship. A token identifies an application, so request.user is
    AnonymousUser and document events are authored by the (System) Person. This also
    drops the Recording Manager role check: authorization is possession of the token.
  • All-or-nothing attendees. Matching the existing api, one unresolvable UUID rejects the
    request; the rows and an interim meeting's bluesheet are written in one transaction. A version
    that allows partial success is left as a future exercise.

Deploying

Needs seven APP_API_TOKENS keys: ietf.api.meeting.session.{video_url, recording_name,bluesheet,attendees,chatlog,polls} and
ietf.api.meeting.registration.attended_by_uuid. Separate keys so any one capability
can be withdrawn independently; the same token value can serve all seven.

Changes to existing behavior

Commits 1–3 touch code the existing endpoints share. Five of the six are
behavior-identical. The exceptions, both on a session with no official timeslot:

  • api_set_session_video_url and api_upload_bluesheet already answered 400 for that
    input, because require_api_key catches AttributeError. Only the message changes.
  • upload_session_bluesheets and finalize have no such catch, so they change from a
    500 to a form error and a user message.

Notes

Reviewed adversarially before merge; the findings are folded into the commits they
belong to. Known and deliberately not fixed here: the legacy recording-name endpoint
still does no length validation against its 64-character column.

rjsparks and others added 6 commits September 4, 2026 19:51
save_bluesheet() and generate_bluesheet() read request.user.person for the
document event author. Take the author as an argument instead, so a caller
whose request has no associated person can supply one. Existing callers pass
request.user.person, so behavior is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Move the chatlog/polls document write and the video URL update into
save_session_json_doc() and save_session_video_url(), and rewire
api_upload_chatlog, api_upload_polls and api_set_session_video_url onto them.
Lets the DRF endpoints that follow share one implementation with these.

save_session_video_url() returns an error when the session has no official
timeslot rather than raising AttributeError. api_set_session_video_url already
answered 400 for that input, because require_api_key catches AttributeError;
only the message changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…f raising

save_bluesheet() dereferenced the session's timeslot without checking for one,
raising AttributeError. Return the same error its sibling helpers return.

upload_session_bluesheets and finalize turn that into a form error and a user
message rather than a 500. api_upload_bluesheet already answered 400, because
require_api_key catches AttributeError; only the message changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…heet, chatlog and polls

Add api_key_endpoint authenticated counterparts of five of the personal API key
endpoints, taking JSON and returning JSON with DRF status codes. A token
identifies an application rather than a person, so document events are authored
by the (System) Person.

None of these five carries a person identifier. Bluesheet names and chatlog
authors stay free text.

Request values are bounded by the columns that store them.

The existing endpoints are unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Identify each attendee by Person UUID rather than by the User pk the existing
endpoint takes. Any UUID the datatracker has issued resolves, so one superseded
by a merge still works.

If any UUID fails to resolve the whole request is rejected and nothing is
recorded. The rows and an interim meeting's regenerated bluesheet are written
in one transaction.

join_time must carry an explicit UTC offset. DateTimeField would otherwise make
a naive value aware in the process timezone and shift it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add a Person UUID keyed counterpart of MeetingsAttendedByEmail, which is keyed
by an address the person may stop using. Lift the shared registration query to
module level so both endpoints use it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.37838% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.81%. Comparing base (e52df75) to head (f83f7ce).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
ietf/meeting/views.py 75.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #11719      +/-   ##
==========================================
+ Coverage   88.75%   88.81%   +0.05%     
==========================================
  Files         337      337              
  Lines       45420    45547     +127     
==========================================
+ Hits        40311    40451     +140     
+ Misses       5109     5096      -13     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant