Browse Source

fix(hybrid-cloud): Fix de/serialization of RpcUser for social auth (#64220)

Fixes SENTRY-2FKY

---------

Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
Alberto Leal 1 year ago
parent
commit
4d17d3eb60
3 changed files with 48 additions and 2 deletions
  1. 10 2
      src/social_auth/utils.py
  2. 0 0
      tests/social_auth/__init__.py
  3. 38 0
      tests/social_auth/test_utils.py

+ 10 - 2
src/social_auth/utils.py

@@ -13,6 +13,9 @@ from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import Model
 
+from sentry.services.hybrid_cloud import RpcModel
+from sentry.services.hybrid_cloud.user import RpcUser
+
 LEAVE_CHARS = getattr(settings, "SOCIAL_AUTH_LOG_SANITIZE_LEAVE_CHARS", 4)
 
 
@@ -123,7 +126,9 @@ def model_to_ctype(val):
     """Converts values that are instance of Model to a dictionary
     with enough information to retrieve the instance back later."""
     if isinstance(val, Model):
-        val = {"pk": val.pk, "ctype": ContentType.objects.get_for_model(val).pk}
+        return {"pk": val.pk, "ctype": ContentType.objects.get_for_model(val).pk}
+    if isinstance(val, RpcModel):
+        return val.dict()
     return val
 
 
@@ -133,7 +138,10 @@ def ctype_to_model(val):
         ctype = ContentType.objects.get_for_id(val["ctype"])
         ModelClass = ctype.model_class()
         assert ModelClass is not None
-        val = ModelClass.objects.get(pk=val["pk"])
+        return ModelClass.objects.get(pk=val["pk"])
+
+    if isinstance(val, dict) and "username" in val and "name" in val:
+        return RpcUser.parse_obj(val)
     return val
 
 

+ 0 - 0
tests/social_auth/__init__.py


+ 38 - 0
tests/social_auth/test_utils.py

@@ -0,0 +1,38 @@
+from django.contrib.contenttypes.models import ContentType
+
+from sentry.services.hybrid_cloud.user.serial import serialize_rpc_user
+from sentry.testutils.cases import TestCase
+from sentry.testutils.silo import no_silo_test
+from social_auth.utils import ctype_to_model, model_to_ctype
+
+
+@no_silo_test
+class TestSocialAuthUtils(TestCase):
+    def test_model_to_ctype(self):
+        val = model_to_ctype(1)
+        assert val == 1
+
+        val = model_to_ctype(None)
+        assert val is None
+
+        user = self.create_user()
+        val = model_to_ctype(user)
+        assert val == {"pk": user.id, "ctype": ContentType.objects.get_for_model(user).pk}
+
+        rpc_user = serialize_rpc_user(user)
+        val = model_to_ctype(rpc_user)
+        assert val == rpc_user.dict()
+
+    def test_ctype_to_model(self):
+        val = ctype_to_model(1)
+        assert val == 1
+
+        val = ctype_to_model(None)
+        assert val is None
+
+        user = self.create_user()
+        ctype_val = {"pk": user.id, "ctype": ContentType.objects.get_for_model(user).pk}
+        assert ctype_to_model(ctype_val) == user
+
+        rpc_user = serialize_rpc_user(user)
+        assert ctype_to_model(rpc_user.dict()) == rpc_user