From 7475f8e784c1154a4fa3978f6e319bc61a06f009 Mon Sep 17 00:00:00 2001
From: Calum Mackervoy <c.mackervoy@gmail.com>
Date: Mon, 23 Mar 2020 18:43:37 +0000
Subject: [PATCH] removing all uses of urlid in username

---
 djangoldp/models.py       | 10 +++++-----
 djangoldp/serializers.py  | 15 ++++++++-------
 djangoldp/tests/runner.py |  1 +
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/djangoldp/models.py b/djangoldp/models.py
index 08452c91..10a420e4 100644
--- a/djangoldp/models.py
+++ b/djangoldp/models.py
@@ -1,4 +1,3 @@
-import validators
 from urllib.parse import urlparse
 from django.conf import settings
 from django.contrib.auth import get_user_model
@@ -189,10 +188,11 @@ def auto_urlid(sender, instance, **kwargs):
 
 if 'djangoldp_account' not in settings.DJANGOLDP_PACKAGES:
     def webid(self):
-        # hack : We user webid as username for external user (since it's an uniq identifier too)
-        if validators.url(self.username):
-            webid = self.username
-        # unable to use username, so use user-detail URL with primary key
+        # an external user should have urlid set
+        webid = getattr(self, 'urlid', None)
+        if webid is not None and urlparse(settings.BASE_URL).netloc != urlparse(webid).netloc:
+            webid = self.urlid
+        # local user use user-detail URL with primary key
         else:
             webid = '{0}{1}'.format(settings.BASE_URL, reverse_lazy('user-detail', kwargs={'pk': self.pk}))
         return webid
diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py
index a7b4d9a9..c4e52fc7 100644
--- a/djangoldp/serializers.py
+++ b/djangoldp/serializers.py
@@ -1,10 +1,10 @@
+import uuid
 from collections import OrderedDict, Mapping, Iterable
 from typing import Any
 from urllib import parse
 
 from django.conf import settings
 from django.contrib.auth import get_user_model
-from django.contrib.auth.models import AbstractUser
 from django.core.exceptions import ImproperlyConfigured
 from django.core.exceptions import ValidationError as DjangoValidationError, FieldDoesNotExist
 from django.core.urlresolvers import get_resolver, resolve, get_script_prefix, Resolver404
@@ -491,13 +491,14 @@ class LDPSerializer(HyperlinkedModelSerializer):
         return serializer
 
     def to_internal_value(self, data):
-        user_case = self.Meta.model is get_user_model() and '@id' in data and not data['@id'].startswith(
+        is_user_and_external = self.Meta.model is get_user_model() and '@id' in data and not data['@id'].startswith(
             settings.BASE_URL)
-        if user_case:
+        if is_user_and_external:
             data['username'] = 'external'
         ret = super().to_internal_value(data)
-        if user_case:
-            ret['username'] = data['@id']
+        if is_user_and_external:
+            ret['urlid'] = data['@id']
+            ret.pop('username')
         return ret
 
     def get_value(self, dictionary):
@@ -562,8 +563,8 @@ class LDPSerializer(HyperlinkedModelSerializer):
                     field_name in validated_data) and not field_name is None:
                 many_to_many.append((field_name, validated_data.pop(field_name)))
         validated_data = self.remove_empty_value(validated_data)
-        if model is get_user_model() and 'urlid' in validated_data and not 'username' in validated_data:
-            validated_data['username'] = validated_data.pop('urlid')
+        if model is get_user_model() and not 'username' in validated_data:
+            validated_data['username'] = uuid.uuid4()
         instance = model.objects.create(**validated_data)
 
         for field_name, value in many_to_many:
diff --git a/djangoldp/tests/runner.py b/djangoldp/tests/runner.py
index 12162f6c..87acd84f 100644
--- a/djangoldp/tests/runner.py
+++ b/djangoldp/tests/runner.py
@@ -37,6 +37,7 @@ settings.configure(DEBUG=False,
                        }
                    },
                    AUTH_USER_MODEL='tests.User',
+                   ANONYMOUS_USER_NAME = None,
                    AUTHENTICATION_BACKENDS=(
                        'django.contrib.auth.backends.ModelBackend', 'guardian.backends.ObjectPermissionBackend'),
                    ROOT_URLCONF='djangoldp.urls',
-- 
GitLab