Conversation
|
closes #36 |
pablo-schmeiser
left a comment
There was a problem hiding this comment.
Very important and awaited feature!
Looks good to me 👍
Once @hd1ex approves this too, this is ready to be merged.
If @lewellien is still interested in this topic: They may want to review this as well.
|
Thanks for working on iCal support! My first question is: Does this also fix or works upon fixing #41? Can you split the OIDC stuff to another change? I'd rather review and integrate these two things step by step. |
Move _populate_user from AuthorizeSSOUser view into accounts/oidc.py as populate_user_from_oidc so it can be reused by the offline token refresh logic without a model-to-view circular dependency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e0f7a40 to
8eb1778
Compare
CalendarToken stores a unique per-user token for session-less iCal feed access. OIDCOfflineToken stores the OIDC refresh token and implements refresh_user_info() to sync groups from the identity provider before serving calendar data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce TokenAuthMixin that authenticates feed requests via
a CalendarToken URL parameter and refreshes OIDC user data
with a 10-minute cooldown. Register token feed URLs under
/calendar/token/<token>/{user,participation,organization,event}/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add token management views (create/regenerate/delete) and a Calendar Subscriptions card on the profile page showing copyable iCal URLs with regenerate and revoke controls. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the Calendar Subscriptions card from the left sidebar into the right column above Upcoming Shifts for better visibility. Add "Add to Calendar" buttons using the webcal:// protocol so users can subscribe with a single click from their device. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Combine the "Add to Calendar" button and the copyable URL input into one flex row per feed for a more compact layout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use the same card structure (p-3, center-items header row) as the user info card. Move regenerate and revoke buttons into the title row as icon-only buttons, and show the generate button there when no token exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add German translations for all calendar subscription strings. Rename "My Participations" to "My Shifts" for clarity. Increase spacing between subtitle text and feed sections. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove all obsolete (#~) entries including calendar-related strings and fix duplicate "My Shifts" entries that caused msgmerge errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8eb1778 to
11c13e0
Compare
3691cff to
11c13e0
Compare
| tokens = OIDCOfflineToken.objects.select_related('user').all() | ||
| total = tokens.count() | ||
| success = 0 | ||
| failed = 0 | ||
|
|
||
| self.stdout.write(f'Syncing {total} OIDC user(s)...') | ||
|
|
||
| for offline_token in tokens: | ||
| username = offline_token.user.username | ||
| if offline_token.refresh_user_info(): | ||
| success += 1 | ||
| logger.info('Synced user %s', username) | ||
| else: | ||
| failed += 1 | ||
| logger.warning('Failed to sync user %s', username) | ||
| if options['purge_expired']: | ||
| offline_token.delete() | ||
| logger.info('Purged expired token for user %s', username) | ||
|
|
||
| self.stdout.write(self.style.SUCCESS( | ||
| f'Done. {success} synced, {failed} failed (of {total} total).' | ||
| )) |
There was a problem hiding this comment.
Can you also print out the time how long a refresh run took, so an admin can get a feeling of the performance impact? I also saw some async stuff was added to Django recently. I don't know if it is easy to add but it maybe an option to improve overall reactiveness, if this task is IO heavy.
When does such a token expire? Do I understand it correctly that we have to refresh the token regularly and expired tokens can only be "refreshed" if the user does relogin?
If so, this only solves #41 for future deployments.
On a running system no tokens are there (yet?) so this implies for me some kind of purge when this change is rolled out:
- Terminate all user sessions (forcing them to relogin)
- Update all group memberships by
- either clearing them all and let the users log back in to rejoin
- or using some kind of other data source (e.g. LDAP). This also does not solve the problem for inactive users, so I am in favor of the first option.
Maybe some scripting/documentation to support this would be nice.
There was a problem hiding this comment.
The offline token expiry is handled by the OIDC IdP. This implementation currently does nothing on expiry. Ways to solve this is adding a grace period until the 30. June and begin clearing group associations and requiring re-authentication from then. The HaDiKo deployment of Shiftings should use quite short token periods which would force everybody using the App to have logged in at least once since then.
Create a system for persisting
offline_tokens for users that logged in via OpenID Connect. We can use this to periodically update the groups for users that haven't signed in for a while.Resolves #41