Skip to content

Comments

update to upstream/master#61

Open
stanley89 wants to merge 309 commits intopirati-cz:masterfrom
benadida:master
Open

update to upstream/master#61
stanley89 wants to merge 309 commits intopirati-cz:masterfrom
benadida:master

Conversation

@stanley89
Copy link

No description provided.

McCio and others added 30 commits March 4, 2019 22:54
Slashes aren't deemed necessary at start of URL patterns, but the actual check author recognized the too-strict approach for his check: https://stackoverflow.com/a/41450355
Should probably integrate with django-celery-results and/or django-celery-beat
benadida and others added 30 commits January 3, 2026 20:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Twitter authentication is no longer supported. This removes:
- Twitter auth backend (twitter.py)
- Twitter follow template
- Twitter URL configuration
- Twitter settings (API keys, DM tokens, etc.)
- Twitter share button from social buttons
- Twitter-related comments in LinkedIn module
* Add case-insensitive GitHub username matching at login time

Done by allowing an auth system to declare that it is case insensitive.


---------

Co-authored-by: Claude <noreply@anthropic.com>
…440)

* add a devlogin auth method for dev mode only to make testing easier

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add CSV export for election audit log

---------

Co-authored-by: Claude <noreply@anthropic.com>
* Prevent tabulation when votes are still pending verification

When votes are cast, they are queued for asynchronous verification via
Celery. If the queue is backed up, attempting to tally would exclude
these pending votes. This change:

- Adds num_pending_votes property to Election model to count unverified votes
- Excludes quarantined votes from pending count (they are intentionally held)
- Blocks the compute tally action when pending votes exist
- Shows a warning on the compute tally page if votes are pending
- Disables the tally button until all votes are verified
- Provides clear error messaging

---------

Co-authored-by: Claude <noreply@anthropic.com>
* Truncate email recipient names at 70 characters

Add format_recipient() helper in helios_auth/utils.py to centralize
email recipient formatting with 70-character name truncation. This
prevents Python3's email module from choking on long names.

The name is quoted per RFC 5322 to safely handle special characters.

Updated all auth system backends to use the helper function.
Added unit tests for the format_recipient helper.

* Fix validate_email API for py3-validate-email compatibility

Disable DNS and SMTP checks in validate_email calls to maintain
compatibility with py3-validate-email package which has a different
API than the original validate_email package.

---------

Co-authored-by: Claude <noreply@anthropic.com>
These flags were incorrectly added to validate_email calls. The
validate_email library handles DNS/SMTP checking appropriately by
default.
* Audit and update dependencies for security and maintenance

- Remove deprecated/unused packages:
  - boto (deprecated, superseded by boto3, django-ses uses boto3 internally)
  - unicodecsv (unnecessary on Python 3, not used in codebase)
  - oauth2client (deprecated Jan 2025, archived on GitHub)

- Update outdated packages with security fixes:
  - celery: 5.4.0 → 5.6.1 (memory leak fixes, Python 3.14 support)
  - pycryptodome: 3.20.0 → 3.23.0 (timing attack fixes)
  - rollbar: 1.0.0 → 1.3.0 (credential sanitization fixes)

- Add modern OAuth replacements:
  - google-auth + google-auth-oauthlib (replaces oauth2client for Google)
  - requests-oauthlib (for GitHub/GitLab OAuth flows)
  - requests (for Clever API calls)

- Migrate OAuth implementations:
  - google.py: Use google_auth_oauthlib.flow.Flow
  - github.py: Use requests_oauthlib.OAuth2Session
  - gitlab.py: Use requests_oauthlib.OAuth2Session
  - clever.py: Use requests with HTTPBasicAuth

* Remove Clever authentication system

Clever auth appears to be unused/unmaintained. Removes:
- helios_auth/auth_systems/clever.py
- Clever settings from settings.py
- Clever registration from auth_systems/__init__.py
- Special case in tests for Clever's restricted can_create_election


---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add admin user search feature

This commit adds a new admin feature to search for users and view all their
associated elections. Site administrators can now search for users by name
or user ID and see:
- Elections where the user is an administrator (creator or additional admin)
- Elections where the user is a registered voter
- Elections where the user is a trustee

Changes:
- Added user_search() view in helios/stats_views.py
- Created stats_user_search.html template
- Added /helios/stats/user-search route
- Added link to user search in admin dashboard

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Migrate CI/CD from Travis CI to GitHub Actions

Replace outdated Travis CI configuration with modern GitHub Actions workflow:
- Use Python 3.12 (matching runtime.txt)
- Test against PostgreSQL 14, 15, and 16
- Add pip caching for faster builds
- Install required LDAP system dependencies

---------

Co-authored-by: Claude <noreply@anthropic.com>
Update runtime.txt, CLAUDE.md, and GitHub Actions CI workflow to use
Python 3.13. All 183 tests pass with the new version.

Co-authored-by: Claude <noreply@anthropic.com>
Add a modular `can_add_voters_file()` method to the Election model that
returns whether voter file uploads are allowed. Uploads are blocked when:
- encrypted tally exists (encrypted_tally is set)
- tallying has started (tallying_started_at is set)

The method is used in both the view (to raise PermissionDenied) and the
template (to show a disabled button with explanation).

Note: We intentionally do NOT block on voting_ended_at because the admin
can extend voting, so ending voting alone doesn't mean the election is
truly closed.

Co-authored-by: Claude <noreply@anthropic.com>
* Add dual timezone display (UTC + local) for all timestamps

This change enhances timestamp display throughout Helios to show both
UTC and the user's local timezone, improving usability for voters and
administrators in different timezones.

Changes:
- Created JavaScript utility (timezone-display.js) to automatically
  convert UTC timestamps to show both UTC and local timezone
- Added CSS styling (timezone-display.css) for professional display
- Created Django template filter 'utc_time' to mark timestamps for
  conversion
- Updated DateTimeLocalWidget to include timezone display assets
- Enhanced base template to load timezone JS/CSS globally
- Updated key templates (election_view, voters_list, etc.) to use
  the new timezone filter
- DateTime input fields now show helper text with both timezones

The solution is client-side JavaScript based, using the browser's
timezone for local conversion. This requires no server-side changes
to timezone handling and works seamlessly with existing UTC storage.

---------

Co-authored-by: Claude <noreply@anthropic.com>
- Replace requirements.txt with pyproject.toml for modern dependency management
- Add uv.lock for reproducible builds
- Update INSTALL.md with uv installation instructions
- Update CLAUDE.md commands to use uv run
- Add .venv to .gitignore for uv's virtual environment

Closes #458

Co-authored-by: Claude <noreply@anthropic.com>
Replace pip-style runtime.txt (python-3.13.11) with uv-style
.python-version file (3.13) for Heroku Python version pinning.
Only specifies major.minor version as requested.

Co-authored-by: Claude <noreply@anthropic.com>
GitHub changed to expect comma-separated scopes instead of space-separated.
The requests_oauthlib library joins scope lists with spaces by default,
producing "read:user user:email", but GitHub now expects "read:user,user:email".

Changed the scope parameter from a list to a comma-separated string to match
GitHub's current requirements.

Co-authored-by: Claude <noreply@anthropic.com>
* Propagate LinkedIn OAuth errors for debugging

Remove bare except clauses that were silently swallowing errors during
LinkedIn authentication. Previously, failures in get_request_token()
would return None and errors in http_wrapper() would return empty
strings, making it impossible to diagnose OAuth issues.

Now exceptions propagate up to Django, allowing debug mode to display
the full traceback with the actual error message.

---------

Co-authored-by: Claude <noreply@anthropic.com>
* Migrate LinkedIn auth from OAuth 1.0a to OAuth 2.0

- Rewrite linkedin.py to use requests_oauthlib.OAuth2Session
- Use LinkedIn's OpenID Connect userinfo endpoint for user data
- Add CSRF protection with OAuth state parameter validation
- Update settings to use LINKEDIN_CLIENT_ID and LINKEDIN_CLIENT_SECRET
- Remove custom oauthclient directory (no longer needed)

The custom OAuth 1.0a client was used solely for LinkedIn. Now that
LinkedIn supports OAuth 2.0, we can use the same pattern as GitHub
and other OAuth2 providers.


---------

Co-authored-by: Claude <noreply@anthropic.com>
)

Add include_client_id=True to fetch_token() call so that client_id
and client_secret are sent as POST body parameters instead of in
HTTP Basic Auth headers. LinkedIn's token endpoint expects credentials
in the request body and returns "missing client_secret" when they are
only sent via Basic Auth.

Co-authored-by: Claude <noreply@anthropic.com>
LinkedIn returns scopes as comma-separated (e.g., "email,openid,profile")
in token responses, but we were sending space-separated scopes. This caused
the OAuth library's scope validation to fail due to format mismatch.

Changed scope format to match LinkedIn's response format.

Co-authored-by: Claude <noreply@anthropic.com>
- Renamed can_add_voters_file() to can_modify_voters() to better reflect
  that it controls both voter uploads and deletions
- Refactored voter_delete view to reuse can_modify_voters() instead of
  duplicating the check logic
- Updated voter list template to hide the delete [x] button when voter
  modifications are blocked, providing better UX
- Updated template variable names: upload_disabled_reason ->
  modify_voters_disabled_reason for consistency

Co-authored-by: Claude <noreply@anthropic.com>
* Fix button styling to use consistent Foundation CSS classes

Updated action buttons throughout the application to use proper Foundation
CSS button classes instead of default browser styling or inline style overrides.


---------

Co-authored-by: Claude <noreply@anthropic.com>
)

Completed brainstorming session. Design includes:
- Lit 3.x web components with props-drilling state management
- Crypto layer copied unchanged for independence
- 4 implementation phases: setup, voting flow, crypto, polish
- Runs at /booth2026/ alongside existing booth

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
* Add soft delete functionality for elections

Implements soft delete for elections using a deleted_at
timestamp. Elections marked as deleted are hidden from everyone except the site admins.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add database index on election deleted_at field

The deleted_at field is used by ElectionActiveManager to filter out
soft-deleted elections on every query (deleted_at__isnull=True).
Adding an index improves query performance.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Reduce PostgreSQL test matrix from versions 14, 15, 16 to just 16.
This speeds up CI builds while still ensuring compatibility with
the latest stable PostgreSQL release.

Co-authored-by: Claude <noreply@anthropic.com>
Uses Django's conditional aggregation (filter=Q(...)) to correctly count and find the max cast_at only for votes within the cutoff period, and create a more efficient query.

Co-authored-by: Claude <noreply@anthropic.com>
Based on analysis of query patterns across the codebase, add indexes to
improve performance for common lookups:

Priority 1 (Critical):
- Voter.uuid: Used in get_by_election_and_uuid() for voter detail pages
- CastVote(verified_at, invalidated_at): Used in num_pending_votes,
  admin dashboard, and verify_cast_votes background task
- CastVote.vote_hash: Used in ballot verification lookups
- Trustee.uuid: Used in trustee dashboard access

Priority 2 (High):
- Election.featured_p: Used in get_featured() for homepage display
- ElectionLog(election, at): Used in audit log display with ordering

Priority 3 (Medium):
- AuditedBallot(election, vote_hash): Used in ballot audit lookups

Co-authored-by: Claude <noreply@anthropic.com>
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.