From 05da2019fc7624f7d4cd48204ae81bfff00311d6 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Thu, 17 Nov 2022 10:56:30 +0100
Subject: [PATCH 2/2] api_views: handle ou-wise api-client checks (#71275)

---
 src/authentic2/api_views.py | 11 ++++++++++-
 tests/api/test_all.py       | 23 ++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/authentic2/api_views.py b/src/authentic2/api_views.py
index 1555fc2e9..bba008728 100644
--- a/src/authentic2/api_views.py
+++ b/src/authentic2/api_views.py
@@ -1431,6 +1431,13 @@ class CheckPasswordSerializer(serializers.Serializer):
 class CheckAPIClientSerializer(serializers.Serializer):
     identifier = serializers.CharField(required=True)
     password = serializers.CharField(required=True)
+    ou = serializers.SlugRelatedField(
+        queryset=OrganizationalUnit.objects.all(),
+        slug_field='slug',
+        default=None,
+        required=False,
+        allow_null=True,
+    )
 
 
 class CheckPasswordAPI(BaseRpcView):
@@ -1467,6 +1474,7 @@ class CheckAPIClientAPI(BaseRpcView):
     def rpc(self, request, serializer):
         identifier = serializer.validated_data['identifier']
         password = serializer.validated_data['password']
+        ou = serializer.validated_data.get('ou', None)
         api_client = None
         try:
             api_client = APIClient.objects.get(identifier=identifier, password=password)
@@ -1474,7 +1482,7 @@ class CheckAPIClientAPI(BaseRpcView):
             pass
 
         result = {}
-        if api_client is None:
+        if api_client is None or ou and ou != api_client.ou:
             result['err'] = 1
             result['err_desc'] = 'api client not found'
         else:
@@ -1484,6 +1492,7 @@ class CheckAPIClientAPI(BaseRpcView):
                 'is_anonymous': api_client.is_anonymous,
                 'is_authenticated': api_client.is_authenticated,
                 'is_superuser': api_client.is_superuser,
+                'ou': api_client.ou.slug if api_client.ou else None,
                 'restrict_to_anonymised_data': api_client.restrict_to_anonymised_data,
                 'roles': [role.uuid for role in api_client.apiclient_roles.all()],
             }
diff --git a/tests/api/test_all.py b/tests/api/test_all.py
index 6d313bacb..1ee4c343d 100644
--- a/tests/api/test_all.py
+++ b/tests/api/test_all.py
@@ -2787,7 +2787,7 @@ def test_user_profile_delete(app, superuser):
     )
 
 
-def test_check_api_client(app, superuser):
+def test_check_api_client(app, superuser, ou1, ou2):
     url = '/api/check-api-client/'
     payload = {'identifier': 'foo', 'password': 'bar'}
     resp = app.post_json(url, params=payload, status=401)
@@ -2816,3 +2816,24 @@ def test_check_api_client(app, superuser):
     assert data['is_superuser'] is False
     assert data['restrict_to_anonymised_data'] is False
     assert data['roles'] == [role1.uuid]
+    assert data['ou'] is None
+
+    api_client.ou = ou1
+    api_client.save()
+    resp = app.post_json(url, params=payload)
+    assert resp.json['data']['ou'] == 'ou1'
+
+    payload['ou'] = ou1.slug
+    resp = app.post_json(url, params=payload)
+    assert resp.json['data']['ou'] == 'ou1'
+
+    payload['ou'] = ou2.slug
+    resp = app.post_json(url, params=payload)
+    assert resp.json['err'] == 1
+    assert resp.json['err_desc'] == 'api client not found'
+
+    api_client.ou = None
+    api_client.save()
+    resp = app.post_json(url, params=payload)
+    assert resp.json['err'] == 1
+    assert resp.json['err_desc'] == 'api client not found'
-- 
2.38.1

