• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

akvo / akvo-mis / #770
89%
main: 89%

Build:
Build:
LAST BUILD BRANCH: feature/273-two-phase-registration
DEFAULT BRANCH: main
Ran 29 Jul 2026 07:04AM UTC
Jobs 1
Files 113
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

29 Jul 2026 06:56AM UTC coverage: 88.745% (+0.2%) from 88.523%
#770

Pull #280

coveralls-python

web-flow
[#270] Filter every read by tenant (#281)

* [#270] Add the for_user tenant-scoping mechanism

Each tenant-owned model declares TENANT_PATH — the ORM lookup to its
owning tenant, "tenant" for direct-FK tables and a join like
"form__tenant" for derived ones — and gains Model.objects.for_user(user),
which filters uniformly by that path. A tenant-less user filters on
NULL and matches tenant-less rows, which is what keeps the existing
test suite (seeded tenant-less) green.

The method lives on the querysets via a shared mixin and is delegated
by each manager family, so callers write the same for_user everywhere
regardless of a model's manager. UserManager needs nothing of its own:
it already extends SoftDeletesManager and inherits the delegation.

TENANT_PATH is a deliberate opt-in — a model without it raises rather
than silently returning unscoped rows, so a forgotten declaration
fails loudly instead of leaking.

* [#270] Scope v1_data reads to the requester's tenant

Most of this app is keyed on a form id and builds its queryset from
form.form_form_data, so scoping the form lookup scopes the datapoint,
pending and draft lists with it: a foreign form id now 404s instead of
serving another tenant's submissions. Data-id-keyed lookups are scoped
directly, so a guessed id 404s rather than revealing that the row
exists.

The superuser branch of the list filter looked up the first root
administration in the table, which after multi-tenancy could be another
tenant's root; it is scoped too.

Those lookups also serve the PUT and DELETE handlers on the same views.
Leaving the write paths unscoped would have meant adding code to keep
them permissive, so they inherit the scoping. Full write-path
enforcement is still a separate iteration.

for_user reads the tenant with getattr because AnonymousUser has no
tenant attribute and a handful of endpoints are reachable without a
token — GET /api/v1/data/{id} among them. Anonymous callers now behave
like any tenant-less act... (continued)
Pull Request #280: Epic/multi tenant saas

5712 of 6609 branches covered (86.43%)

Branch coverage included in aggregate %.

10862 of 12067 relevant lines covered (90.01%)

0.9 hits per line

Coverage Regressions

Lines Coverage ∆ File
50
80.17
0.0% api/v1/v1_forms/views.py
47
85.55
0.41% api/v1/v1_users/serializers.py
41
91.03
0.03% api/v1/v1_forms/functions.py
41
84.8
1.31% api/v1/v1_users/views.py
37
85.98
0.0% api/v1/v1_data/views.py
16
90.94
3.44% api/v1/v1_profile/views.py
11
78.87
-0.54% utils/draft_model.py
8
95.58
0.0% api/v1/v1_mobile/views.py
8
89.53
1.48% api/v1/v1_users/models.py
7
93.67
0.0% api/v1/v1_visualization/views.py
6
95.26
0.09% api/v1/v1_data/models.py
6
96.2
0.2% api/v1/v1_forms/models.py
5
93.24
0.29% utils/soft_deletes_model.py
4
92.42
0.42% api/v1/v1_profile/management/commands/administration_seeder.py
3
98.67
0.16% api/v1/v1_profile/models.py
2
96.36
0.14% api/v1/v1_mobile/models.py
1
95.0
-0.83% api/v1/v1_data/management/commands/generate_config.py
1
95.83
0.6% api/v1/v1_jobs/models.py
1
95.45
-2.27% api/v1/v1_users/management/commands/fake_user_seeder.py
Jobs
ID Job ID Ran Files Coverage
1 #770.1 29 Jul 2026 07:04AM UTC 113
88.74
Source Files on build #770
  • Tree
  • List 113
  • Changed 22
  • Source Changed 0
  • Coverage Changed 22
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Pull Request #280
  • PR Base - main (#)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc