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

kobotoolbox / kpi / 23218570559
82%
master: 76%

Build:
Build:
LAST BUILD BRANCH: main
DEFAULT BRANCH: master
Ran 17 Mar 2026 10:10PM UTC
Jobs 10
Files 898
Run time 2min
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

17 Mar 2026 10:05PM UTC coverage: 82.074% (+0.03%) from 82.044%
23218570559

push

github

web-flow
feat(scim): add groups and service provider config endpoints DEV-1815 (#6797)

### 📣 Summary
This PR complements the SCIM implementation in kobo with Groups and
ServiceProviderConfig endpoints, which are required for providers like
Okta and Authentik.

* Added a ScimGroup model to store synced groups natively. 
* Created the /ServiceProviderConfig endpoint mapping to statically
announce our SCIM capabilities (e.g. PATCH is supported, bulk operations
are disabled).
* Created the /Groups CRUD endpoints to support list, create, update,
and patch requests from the IdP.
* Updated urls.py and serializers to correctly route and validate the
new payloads.
* Added unit tests in test_scim_groups_api.py
* Added simple provisioning to enable proper integration with test cases
* Handling of multi tenant IdP

### 👀 Preview steps

1. Test ServiceProviderConfig. The IdP uses this endpoint on
initialization to figure out what Kobo's SCIM layer supports.

```
curl -X GET http://localhost:8000/api/scim/v2/{idp_slug}/ServiceProviderConfig \
  -H "Authorization: Bearer {SCIM_TOKEN}"
```

2. Create a group, test how the IdP provisions a completely new group
directly to Kobo.

```
curl -X POST http://localhost:8000/api/scim/v2/{idp_slug}/Groups \
  -H "Authorization: Bearer {SCIM_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "displayName": "Test Admins Group",
    "externalId": "ext-group-123"
  }'
```
Note the returned id for the next step.

3. List groups, the IdP uses this to verify the initial sync state.
```
curl -X GET http://localhost:8000/api/scim/v2/{idp_slug}/Groups \
  -H "Authorization: Bearer {SCIM_TOKEN}"
```
4. Patch a Group (Add Members) simulating the IdP adding a user to the
group during an assignment event. (Replace group_id with the SCG id from
step 2, and user_id with a valid Django User ID).

```
curl -X PATCH http://localhost:8000/api/scim/v2/{idp_slug}/Groups/{group_id} \... (continued)

7612 of 11764 branches covered (64.71%)

105 of 258 new or added lines in 9 files covered. (40.7%)

2977 existing lines in 95 files now uncovered.

29211 of 35591 relevant lines covered (82.07%)

5.8 hits per line

New Missed Lines in Diff

Lines Coverage ∆ File
1
92.86
-0.48% kobo/apps/kobo_scim/models.py
2
90.0
-10.0% kobo/apps/kobo_scim/admin.py
2
82.93
3.76% kobo/apps/kobo_scim/serializers.py
148
26.05
-6.78% kobo/apps/kobo_scim/views.py

Uncovered Existing Lines

Lines Coverage ∆ File
1
0.0
-100.0% kobo/apps/openrosa/apps/logger/constants.py
1
63.33
-1.67% kobo/apps/openrosa/apps/main/models/user_profile.py
1
75.0
-25.0% kobo/apps/openrosa/libs/utils/storage.py
1
93.02
-2.33% kpi/backends.py
1
50.7
-0.47% kpi/renderers.py
1
75.0
-6.25% kpi/utils/drf_exceptions.py
1
86.67
-0.95% kpi/utils/object_permission.py
2
90.8
-2.3% kobo/apps/audit_log/signals.py
2
76.6
-4.26% kobo/apps/kobo_auth/models.py
2
61.54
-15.38% kobo/apps/openrosa/libs/utils/gravatar.py
2
82.14
-7.14% kobo/urls.py
2
80.0
-20.0% kpi/mixins/mfa.py
3
85.71
-6.12% kobo/apps/openrosa/apps/logger/exceptions.py
3
80.0
-20.0% kobo/apps/openrosa/apps/viewer/signals.py
3
50.0
-37.5% kobo/apps/openrosa/libs/mixins/anonymous_user_public_forms_mixin.py
3
46.67
-20.0% kobo/apps/openrosa/libs/serializers/tag_list_serializer.py
4
69.23
-30.77% kobo/apps/accounts/mfa/permissions.py
4
45.45
-36.36% kobo/apps/openrosa/koboform/__init__.py
4
75.12
-1.95% kpi/utils/mongo_helper.py
5
66.5
-1.22% kobo/apps/audit_log/models.py
5
72.22
-27.78% kobo/apps/openrosa/apps/logger/models/daily_xform_submission_counter.py
5
75.0
-25.0% kobo/apps/openrosa/apps/logger/models/monthly_xform_submission_counter.py
5
0.0
-38.46% kobo/apps/openrosa/apps/main/context_processors.py
5
50.0
-50.0% kobo/apps/openrosa/libs/mixins/openrosa_headers_mixin.py
5
66.67
-33.33% kobo/apps/openrosa/libs/serializers/note_serializer.py
5
76.47
-4.2% kobo/apps/stripe/utils/subscription_limits.py
6
66.67
-28.57% kobo/apps/openrosa/apps/api/viewsets/connect_viewset.py
6
0.0
-100.0% kobo/conftest.py
7
61.11
-9.72% kobo/apps/accounts/mfa/models.py
7
31.25
-43.75% kobo/apps/openrosa/libs/utils/string.py
8
64.0
-32.0% kobo/apps/openrosa/libs/permissions.py
8
58.51
-8.51% kobo/apps/stripe/utils/billing_dates.py
9
30.56
-8.33% kobo/apps/openrosa/apps/api/tools.py
9
62.07
-31.03% kobo/apps/openrosa/apps/api/viewsets/metadata_viewset.py
9
57.45
-9.57% kobo/apps/openrosa/libs/utils/middleware.py
10
58.33
-41.67% kobo/apps/openrosa/apps/api/viewsets/note_viewset.py
10
44.0
-40.0% kobo/apps/stripe/signals.py
10
30.12
-12.05% kpi/utils/storage.py
11
62.5
-34.38% kobo/apps/openrosa/apps/api/viewsets/attachment_viewset.py
11
60.29
-5.26% kpi/utils/xml.py
12
28.57
-28.57% kobo/apps/accounts/mfa/flows.py
12
76.02
-6.12% kobo/apps/openrosa/apps/logger/models/instance.py
12
44.9
-24.49% kobo/apps/openrosa/apps/logger/utils/counters.py
12
70.0
-30.0% kobo/apps/openrosa/libs/serializers/user_profile_serializer.py
13
75.66
-6.88% kobo/apps/openrosa/apps/logger/models/xform.py
13
62.82
-16.67% kpi/authentication.py
14
44.0
-56.0% kobo/apps/openrosa/libs/utils/model_tools.py
15
31.71
-36.59% kobo/apps/openrosa/apps/logger/xform_fs.py
15
41.94
-48.39% kobo/apps/openrosa/libs/authentication.py
15
34.78
-65.22% kobo/apps/openrosa/libs/models/signals.py
16
0.0
-43.24% kobo/apps/accounts/mfa/adapter.py
17
16.22
-45.95% kobo/apps/openrosa/apps/logger/utils/database_query.py
17
81.18
-6.67% kobo/apps/openrosa/apps/logger/xform_instance_parser.py
19
51.22
-23.17% kobo/apps/accounts/mfa/views.py
19
16.0
-76.0% kobo/apps/openrosa/apps/api/utils/xml.py
19
38.24
-55.88% kpi/parsers.py
20
29.67
-21.98% kobo/apps/openrosa/libs/utils/user_auth.py
23
55.46
-19.33% kobo/apps/openrosa/apps/logger/models/attachment.py
24
74.76
-23.3% kpi/utils/usage_calculator.py
26
35.71
-61.9% kobo/apps/openrosa/libs/mixins/labels_mixin.py
26
27.78
-72.22% kobo/apps/openrosa/libs/utils/decorators.py
27
34.0
-54.0% kobo/apps/data_collectors/authentication.py
27
49.06
-50.94% kobo/apps/openrosa/libs/serializers/attachment_serializer.py
28
41.27
-44.44% kobo/apps/openrosa/libs/serializers/data_serializer.py
29
40.48
-17.26% kobo/apps/openrosa/apps/main/models/meta_data.py
29
30.14
-19.86% kobo/apps/openrosa/libs/utils/viewer_tools.py
30
0.0
-75.0% kobo/apps/openrosa/apps/django_digest_backends/cache.py
33
49.51
-32.04% kobo/apps/openrosa/apps/viewer/models/export.py
34
37.96
-31.48% kobo/apps/openrosa/apps/logger/utils/instance.py
36
24.49
-73.47% kobo/apps/openrosa/apps/logger/import_tools.py
36
55.29
-42.35% kobo/apps/openrosa/libs/renderers/renderers.py
37
59.54
-28.24% kobo/apps/openrosa/apps/logger/signals.py
37
32.97
-40.66% kobo/apps/openrosa/libs/serializers/metadata_serializer.py
39
23.08
-30.0% kobo/apps/openrosa/apps/viewer/tasks.py
40
0.0
-40.82% kobo/apps/openrosa/apps/viewer/xls_writer.py
41
23.29
-56.16% kobo/apps/openrosa/libs/utils/image_tools.py
43
46.1
-15.99% kobo/apps/openrosa/apps/viewer/models/data_dictionary.py
43
57.87
-16.93% kobo/apps/openrosa/apps/viewer/models/parsed_instance.py
46
55.83
-38.33% kobo/apps/openrosa/libs/serializers/xform_serializer.py
49
28.57
-43.75% kobo/apps/openrosa/apps/logger/views.py
50
0.0
-47.17% kobo/apps/openrosa/apps/logger/tasks.py
52
34.81
-32.91% kobo/apps/openrosa/apps/api/viewsets/xform_viewset.py
58
0.0
-90.63% kobo/apps/openrosa/libs/data/query.py
59
46.96
-51.3% kobo/apps/openrosa/apps/api/viewsets/xform_submission_api.py
66
32.23
-54.55% kobo/apps/openrosa/apps/api/viewsets/data_viewset.py
71
33.62
-61.21% kobo/apps/openrosa/libs/filters.py
74
44.59
-47.13% kobo/apps/openrosa/apps/api/viewsets/xform_list_api.py
81
33.11
-53.64% kobo/apps/openrosa/apps/api/viewsets/briefcase_api.py
86
28.67
-60.14% kobo/apps/openrosa/apps/viewer/views.py
87
0.0
-87.88% kobo/apps/openrosa/libs/utils/backup_tools.py
93
33.96
-58.49% kobo/apps/openrosa/apps/api/permissions.py
206
0.0
-86.19% kobo/apps/openrosa/libs/utils/briefcase_client.py
215
18.97
-52.96% kobo/apps/openrosa/libs/utils/export_tools.py
218
45.03
-40.9% kobo/apps/openrosa/libs/utils/logger_tools.py
321
0.0
-90.68% kobo/apps/openrosa/apps/viewer/pandas_mongo_bridge.py
Jobs
ID Job ID Ran Files Coverage
1 23218570559.1 17 Mar 2026 10:10PM UTC 894
54.62
2 23218570559.2 17 Mar 2026 10:10PM UTC 894
53.08
3 23218570559.3 17 Mar 2026 10:10PM UTC 896
54.31
4 23218570559.4 17 Mar 2026 10:11PM UTC 894
53.12
5 23218570559.5 17 Mar 2026 10:12PM UTC 896
55.88
6 23218570559.6 17 Mar 2026 10:12PM UTC 896
61.3
7 23218570559.7 17 Mar 2026 10:12PM UTC 896
66.12
8 23218570559.8 17 Mar 2026 10:14PM UTC 896
54.48
9 23218570559.9 17 Mar 2026 10:26PM UTC 894
60.16
10 23218570559.10 17 Mar 2026 10:44PM UTC 898
68.38
Source Files on build 23218570559
  • Tree
  • List 898
  • Changed 8
  • Source Changed 0
  • Coverage Changed 8
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • 82446df5 on github
  • Prev Build on main (#23213286713)
  • Next Build on main (#23228590570)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc