feat: usos sign-in, private calendar feed and timetable archive
This commit is contained in:
commit
7d4e21f977
33 files changed
+3270
No files matched your search
@@ -0,0 +1,18 @@
|
||||
# What is stored and how
|
||||
|
||||
| Data | Form |
|
||||
|---|---|
|
||||
| USOS access token and its secret | AES-256-GCM with `TOKEN_ENC_KEY`, bound to the user id and the field |
|
||||
| Calendar address token | 32 random bytes; a SHA-256 hash to look the feed up, and an encrypted copy to show the address on the page |
|
||||
| Browser session | 32 random bytes in an `HttpOnly`, `SameSite=Lax` cookie for seven days; only its SHA-256 hash is stored |
|
||||
| Timetable | Plain: course, class type, group, room, building, address, lecturers, times |
|
||||
| Profile | USOS user id and name |
|
||||
|
||||
Only the `studies` and `offline_access` scopes are requested. No e-mail, no personal data, no grades.
|
||||
|
||||
- Revoking or reissuing the calendar address replaces the stored hash in one statement; the next request to the old address is answered with 404.
|
||||
- Sign-out revokes the token in USOS, then deletes the tokens, the calendar address and the sessions. With the checkbox, the user and the timetable are deleted as well.
|
||||
- When USOS rejects a token, it is deleted; the timetable stays until the user signs out with deletion.
|
||||
- Nothing is logged per request. Error logs carry the user id and the USOS error message, never a token, a signature or a calendar address. The reverse proxy in front must not log request paths of `/f/`.
|
||||
- Forms are protected against cross-site requests by the `Sec-Fetch-Site` and `Origin` check of Go's `http.CrossOriginProtection`. A sign-in is bound to the browser that started it by a one-time cookie.
|
||||
- The page sends `Content-Security-Policy: default-src 'none'` with inline styles only and has no scripts.
|
||||
@@ -0,0 +1,32 @@
|
||||
# USOS API notes
|
||||
|
||||
Checked against USOS API 7.3.1 at `usosapps.put.poznan.pl` on 2026-10-11, by reading `/developers/api/` and by calling the methods that need no key.
|
||||
|
||||
## Authorization
|
||||
|
||||
OAuth 1.0a with HMAC-SHA1 signatures, three legs: `services/oauth/request_token`, the user's browser at `services/oauth/authorize`, then `services/oauth/access_token`. Scopes are a USOS extension, passed to `request_token` as `scopes=studies|offline_access`.
|
||||
|
||||
- `studies` is what the timetable methods require.
|
||||
- Without `offline_access` an access token dies after two hours or when the user logs out of USOS. With it the token lives until it is revoked.
|
||||
- `services/oauth/revoke_token` revokes the token it is signed with. usoscal calls it on sign-out.
|
||||
- A user can also revoke the application in USOS itself. The next refresh then gets HTTP 401, and usoscal drops the stored token and keeps the timetable.
|
||||
|
||||
Requests are sent as POST with the OAuth parameters in the `Authorization` header and the method parameters in the body, so no token ever appears in a URL.
|
||||
|
||||
## Timetable
|
||||
|
||||
`services/tt/user` returns the activities of the signed-in user for `days` days starting at `start`.
|
||||
|
||||
- `days` is at most 7; 8 is answered with HTTP 400. A semester is therefore about twenty requests, a year about fifty.
|
||||
- `start` may be in the past. Weeks of the two previous semesters were returned by the public `services/tt/course_edition`, which shares the same parameters. Dates with no data give an empty list, not an error.
|
||||
- No request limits are documented. usoscal waits 200 ms between requests and refreshes each user once a day.
|
||||
- `fields` must only name fields that exist for every activity type in the answer. Asking for `related_user_ids` or `slot_number` while the week contains a `classgroup2` activity is answered with HTTP 500. usoscal asks for the class fields and, on a 500, repeats the request with the fields common to all types.
|
||||
- `sm_id` identifies a single meeting and is used as the event UID. Activities without it get a UID derived from their course, group, name and start.
|
||||
|
||||
`services/tt/upcoming_ical` is the export USOS offers itself. It has no date parameters and its documentation says that past events and events far in the future are not included, which is the reason this project exists.
|
||||
|
||||
## Other methods
|
||||
|
||||
- `services/users/users` gives lecturer names and titles by id, signed with the consumer key only.
|
||||
- `services/geo/building2` gives the postal address of a building, anonymously.
|
||||
- `services/terms/search` gives term dates, anonymously. The refresh horizon is the latest `finish_date` among terms shorter than 250 days that are running or start within 60 days, so the exam session after the last class is covered.
|
||||
Reference in new issue
Block a user