You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2022/02/07 15:56:22 UTC

[allura] 02/02: [#8409] User.anonymous() is an in-memory object, not queried from db now

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8409
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9a41eaf39e99d83a8a89ce8668f1cecee7f21644
Author: Dave Brondsema <db...@slashdotmedia.com>
AuthorDate: Fri Feb 4 16:21:07 2022 -0500

    [#8409] User.anonymous() is an in-memory object, not queried from db now
---
 Allura/allura/ext/user_profile/user_main.py        |  2 +-
 Allura/allura/model/auth.py                        | 22 +++++++++++++++++++++-
 .../allura/tests/functional/test_user_profile.py   |  6 ++----
 Allura/allura/tests/model/test_auth.py             | 22 ++++++++++++++++++++++
 Allura/allura/websetup/bootstrap.py                |  6 ++----
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index 22b4200..7ab48a5 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -127,7 +127,7 @@ class UserProfileController(BaseController, FeedController):
         require_access(c.project, 'read')
 
     def _check_can_message(self, from_user, to_user):
-        if from_user is User.anonymous():
+        if from_user.is_anonymous():
             flash('You must be logged in to send user messages.', 'info')
             redirect(six.ensure_text(request.referer or '/'))
 
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index c656065..3784886 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -810,7 +810,27 @@ class User(MappedClass, ActivityNode, ActivityObject, SearchIndexable):
 
     @classmethod
     def anonymous(cls):
-        return User.query.get(_id=None)
+        anon = cls(
+            _id=None,
+            username='*anonymous',
+            display_name='Anonymous')
+        session(anon).expunge(anon)  # don't save this transient Anon record
+        return anon
+
+    def __eq__(self, o):
+        # maybe could do all _id equal, but not sure.  Just supporting *anonymous user for now
+        if self._id is None:
+            return isinstance(o, User) and hasattr(o, '_id') and o._id == self._id
+        else:
+            return super().__eq__(o)
+
+    def __hash__(self):
+        # Since we've implemented __eq__ we need to provide a __hash__ implementation
+        # https://docs.python.org/3/reference/datamodel.html#object.__hash__
+        if self._id is None:
+            return 0
+        else:
+            return super().__hash__()
 
     def is_anonymous(self):
         return self._id is None or self.username == ''
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index ecaa6f5..123d2af 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -184,8 +184,7 @@ class TestUserProfile(TestController):
         r = self.app.get('/u/test-user/profile/send_message',
                          extra_environ={'username': str('*anonymous')},
                          status=302)
-        assert 'You must be logged in to send user messages.' in self.webflash(
-            r)
+        assert 'You must be logged in to send user messages.' in self.webflash(r)
 
         r = self.app.post('/u/test-user/profile/send_user_message',
                           params={'subject': 'test subject',
@@ -193,8 +192,7 @@ class TestUserProfile(TestController):
                                   'cc': 'on'},
                           extra_environ={'username': str('*anonymous')},
                           status=302)
-        assert 'You must be logged in to send user messages.' in self.webflash(
-            r)
+        assert 'You must be logged in to send user messages.' in self.webflash(r)
 
     @td.with_user_project('test-user')
     def test_link_to_send_message_form(self):
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 6752eb3..7a592c6 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -236,6 +236,28 @@ def test_user_by_email_address(log):
     assert_equal(M.User.by_email_address('invalid'), None)
 
 
+def test_user_equality():
+    assert_equal(M.User.by_username('test-user'), M.User.by_username('test-user'))
+    assert_equal(M.User.anonymous(), M.User.anonymous())
+    assert_equal(M.User.by_username('*anonymous'), M.User.anonymous())
+
+    assert_not_equal(M.User.by_username('test-user'), M.User.by_username('test-admin'))
+    assert_not_equal(M.User.by_username('test-user'), M.User.anonymous())
+    assert_not_equal(M.User.anonymous(), None)
+    assert_not_equal(M.User.anonymous(), 12345)
+    assert_not_equal(M.User.anonymous(), M.User())
+
+
+def test_user_hash():
+    assert M.User.by_username('test-user') in {M.User.by_username('test-user')}
+    assert M.User.anonymous() in {M.User.anonymous()}
+    assert M.User.by_username('*anonymous') in {M.User.anonymous()}
+
+    assert M.User.by_username('test-user') not in {M.User.by_username('test-admin')}
+    assert M.User.anonymous() not in {M.User.by_username('test-admin')}
+    assert M.User.anonymous() not in {0, None}
+
+
 @with_setup(setUp)
 def test_project_role():
     role = M.ProjectRole(project_id=c.project._id, name='test_role')
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index a6d40d0..88c4b1e 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -90,10 +90,8 @@ def bootstrap(command, conf, vars):
     index.run([''])
 
     log.info('Registering root user & default neighborhoods')
-    M.User(
-        _id=None,
-        username='*anonymous',
-        display_name='Anonymous')
+    anon = M.User.anonymous()
+    session(M.User).save(anon)
 
     # never make a user project for the root user
     if create_test_data: