Commit Graph
89 Commits
Author SHA1 Message Date
Herculino Trotta 039ad225d3 test(rules): cover object-level authorization for transaction rules
Regression tests for GHSA-83g9-vjqf-2j5q, one per endpoint the advisory
named plus the delete and view paths found alongside them: a non-owner
gets 403 on every mutation of a public or shared rule, and the object is
asserted unchanged afterwards.

Also covers the parts that are easy to regress in the other direction:
shared users keep read access, a shared user deleting only revokes their
own access, unowned rules stay claimable, and children of invisible rules
answer 404 rather than 403.

SharedObjectPredicateParityTests asserts is_visible_to agrees with
SharedObjectManager across every owner/visibility/shared combination.
The manager builds a Q and the predicate tests an instance, so they
cannot share an implementation and can otherwise drift apart.
2026-09-01 21:43:13 -03:00
Herculino Trotta 18d4ab7d11 fix(rules): enforce object-level authorization on rule endpoints
SharedObjectManager scopes querysets to what a user may see, which
includes other people's public and shared-with-them objects. Several
mutating rule endpoints treated that visibility as permission to write.

Generalise get_owned_object_or_403 into get_shared_object_or_error, which
takes an explicit access level instead of inferring one:

- READ requires the object to be visible; denial is 404 so the response
  does not confirm that an id exists.
- EDIT requires ownership; denial is 403, but only after the visibility
  check, so 403 never leaks the existence of an invisible object. This
  matters for TransactionRuleAction, whose manager is unscoped.

The previous owner_path resolved to a User and discarded the object, so
it could not express visibility at all. via= now points at the governing
SharedObject and is resolved with a plain getattr, so an unresolvable
path raises instead of silently granting access.

is_visible_to/is_editable_by replace is_accessible_by, which was never
called and tested visibility == "shared", a value that does not exist in
Visibility.

Also fixes two further holes in the same module:

- transaction_rule_delete fell through to delete() whenever the caller
  was not in shared_with, so any user could delete a public rule. Now
  only the owner deletes; a shared user revokes their own access.
- transaction_rule_view was read-only but is now explicitly READ, so
  rules shared with a user stay viewable.

The activate/deactivate control is hidden for rules the user does not
own, instead of rendering a button that always fails.

Refs GHSA-83g9-vjqf-2j5q
2026-09-01 21:25:46 -03:00
Moshe Levi 68a9286ce5 Fix BOLA on transaction-rule endpoints via get_owned_object_or_403
Add apps.common.functions.get_owned_object_or_403, an ownership-enforcing
variant of get_object_or_404, and apply it across every rules handler that
resolved a TransactionRule / (UpdateOrCreate)TransactionRuleAction from a URL id
without an owner check. Mirrors the check in transaction_rule_edit
(obj.owner and obj.owner != request.user); objects with no owner remain
accessible, preserving existing behaviour. Nested ownership (actions owned via
their parent rule) is handled with owner_path='rule.owner'.
2026-08-31 20:14:40 +03:00
4273c541c5 Add API tokens and OAuth2 client support for external integrations
- Personal API tokens (model, user-settings UI, admin, management command,
  DRF auth class) for non-interactive API access from automations like n8n.
  Raw token shown once; only a SHA-256 hash is stored; last_used_at writes
  are throttled.
- OAuth2 authorization server via django-oauth-toolkit with authorization
  server metadata and optional, off-by-default Dynamic Client Registration
  (RFC 7591), so remote OAuth/MCP clients can authenticate and self-register.
- Tests for token auth, DCR gating and the management commands, plus
  .env.example and README documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 19:15:31 +04:00
Herculino Trotta 34a2b6bfd4 fix(procrastinate): close Django connections around jobs 2026-05-02 16:15:26 -03:00
Herculino Trotta c7ff6db0bf feat(app): add sanity checks for env variables 2025-12-26 09:55:57 -03:00
Herculino Trotta dc33fda5d3 feat: prevent background tasks from running all at once 2025-12-13 15:07:38 -03:00
Herculino Trotta 0b0d760bab feat: guess what, more changes 2025-11-11 20:21:01 -03:00
Herculino Trotta 7e37948616 feat: more changes and fixes 2025-11-09 15:31:50 -03:00
Herculino Trotta cd54df6f2d feat: more changes and fixes 2025-11-08 14:06:01 -03:00
Herculino Trotta a63367a772 feat: first batch of work 2025-11-01 03:15:44 -03:00
Herculino Trotta cae73376db Merge pull request #358
feat(rules): many improvements
2025-09-07 10:07:19 -03:00
Herculino Trotta 70c8c1e07c fix(ui): unable to CTRL + A amount fields 2025-09-05 23:04:12 -03:00
Herculino Trotta c738f5ee29 changes 2025-09-02 09:47:27 -03:00
Herculino Trotta dd2b9ead7e fix(common:tasks): remove_old_jobs always failing 2025-08-24 10:41:26 -03:00
Herculino Trotta 7e4defb9cc refactor: remove debug prints 2025-08-16 17:38:22 -03:00
Herculino Trotta 0c63552d1b feat: add today button to MonthYearPicker 2025-08-15 22:54:04 -03:00
Herculino Trotta 65c61f76ff feat(locale): add space-dot and space-comma number formatting options, where the thousand separator is a space 2025-08-10 12:34:29 -03:00
Herculino Trotta 66a5e6d613 fix(locale): get_format doesn't override number formatting if use_l10n is None 2025-08-10 12:23:41 -03:00
Herculino Trotta a544dc4943 feat(tasks:check_for_updates): add env variable to disable checking 2025-08-06 16:58:58 -03:00
Herculino Trotta 5b6c123fa1 refactor: properly name shareable objects generic fields 2025-07-27 23:19:39 -03:00
Herculino Trotta 569d08711c feat(sharing): add action for turning shareable objects into public or private on Django Admin 2025-07-27 23:17:14 -03:00
Herculino Trotta 76822224a0 feat: check and notify users of new versions
checks are done against github's API with one request every 12 hours
2025-07-27 01:28:27 -03:00
Herculino Trotta 0832ec75ca fix: visual bug when backspacing on the "amount" field 2025-07-09 20:24:27 -03:00
Herculino Trotta 60d367dec5 feat: allow loading any available datepicker languages
instead of a pre-configured list
2025-06-29 14:40:41 -03:00
Herculino Trotta b27633a28e fix: broken distribution chart when number format is set to dot-comma 2025-06-29 01:31:43 -03:00
Herculino Trotta 1f2902eea9 Merge branch 'main' into feat/oidc-integration 2025-06-20 02:03:48 -03:00
Herculino Trotta d3b354e2b8 feat: add quick transactions 2025-06-20 02:01:09 -03:00
Herculino Trotta c8d316857f feat: changes 2025-06-16 21:33:59 -03:00
Herculino Trotta 281a0fccda fix: prevent SharedObjects from being shared with their owner
#247
2025-04-27 16:07:54 -03:00
Herculino Trotta d807bd5da3 feat: user management screen; allow users to edit their profile 2025-04-13 19:00:25 -03:00
Herculino Trotta 4955fbde33 feat(demo): add dummy data 2025-04-01 01:05:28 -03:00
Herculino Trotta d26907ea94 fix(common:fields:month_year): unable to load data with a date 2025-04-01 01:04:20 -03:00
Herculino Trotta 90323049eb fix(common:tasks): reset_demo_data not running via cron 2025-03-31 03:02:28 -03:00
Herculino Trotta 47d34f3c27 feat(app): add a demo mode 2025-03-31 02:14:00 -03:00
Herculino Trotta 046e02d506 feat(app): add environment variables to automatically create superuser on startup 2025-03-31 02:11:13 -03:00
Herculino Trotta 020dd74f80 feat: multi tenancy support 2025-03-08 12:03:17 -03:00
Herculino Trotta d433375522 feat(datepicker): disable input and fix toggling dates 2025-02-17 21:36:11 -03:00
Herculino Trotta 195a8a68d6 feat: insight page 2025-02-16 00:14:23 -03:00
Herculino Trotta 865618e054 feat(dca): link transactions to DCA 2025-02-15 00:41:06 -03:00
Herculino Trotta 852ffd5634 feat: cleanup and format logs 2025-02-07 11:31:14 -03:00
Herculino Trotta 85794f5c01 feat: expose current version 2025-01-31 11:15:15 -03:00
Herculino Trotta 0b83ad6b3e feat: allow for a subset of markdown (bold, italics, strikethrough, links) when displaying notes 2025-01-29 13:52:46 -03:00
Herculino Trotta cab79b4203 feat: cleanup expired sessions every first day of month at 6am 2025-01-28 21:32:41 -03:00
Herculino Trotta 9a7ccb0973 feat: add "Clear cache" button to user menu 2025-01-27 21:49:32 -03:00
Herculino Trotta 233b9629a2 fix(security): toasts and month_year_picker accessible without login 2025-01-27 21:41:55 -03:00
Herculino Trotta 187c56c96c refactor: remove user attr from datepicker
since monkey patched get_format already does what we want
2025-01-27 13:25:06 -03:00
Herculino Trotta 3796112d77 feat: monkey patch get_format to return usersettings 2025-01-27 13:22:21 -03:00
Herculino Trotta a08548bb13 feat: add local access to user and request from anywhere 2025-01-27 13:19:28 -03:00
Herculino Trotta 7fe446e510 refactor: remove custom_date filter 2025-01-27 13:18:57 -03:00