From 952a1d392d21943bbac05806f418d4165b9bc99d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sat, 17 Oct 2020 20:37:07 +0200
Subject: [PATCH] general: remove support for logged-in anonymous users
 (#47822)

---
 wcs/forms/root.py       |  7 ++-----
 wcs/qommon/ident/idp.py |  2 +-
 wcs/qommon/logger.py    |  1 +
 wcs/qommon/myspace.py   |  7 +++----
 wcs/qommon/saml2.py     |  8 +-------
 wcs/qommon/sessions.py  | 25 +++++--------------------
 6 files changed, 13 insertions(+), 37 deletions(-)

diff --git a/wcs/forms/root.py b/wcs/forms/root.py
index 5c92b4f9c..1d93c81d1 100644
--- a/wcs/forms/root.py
+++ b/wcs/forms/root.py
@@ -1120,9 +1120,7 @@ class FormPage(Directory, FormTemplateMixin):
         formdata.data = form_data
         formdata.receipt_time = time.localtime()
         if not get_request().is_in_backoffice():
-            session = get_session()
-            if session and session.user and not str(session.user).startswith('anonymous-'):
-                formdata.user_id = session.user
+            formdata.user = get_request().user
         formdata.store()
 
     def autosave(self):
@@ -1202,8 +1200,7 @@ class FormPage(Directory, FormTemplateMixin):
         else:
             # if submitting via frontoffice, attach current user, eventually
             # anonymous, to the formdata
-            if session and session.user and not str(session.user).startswith('anonymous-'):
-                filled.user_id = session.user
+            filled.user = get_request().user
             filled.store()
 
             if not filled.user_id:
diff --git a/wcs/qommon/ident/idp.py b/wcs/qommon/ident/idp.py
index 088e83c1d..ec5c88f92 100644
--- a/wcs/qommon/ident/idp.py
+++ b/wcs/qommon/ident/idp.py
@@ -160,7 +160,7 @@ class MethodDirectory(Directory):
             login_url += '?' + urllib.urlencode({'next': get_request().get_frontoffice_url()})
             return redirect(login_url)
 
-        if not get_request().user.anonymous:
+        if get_request().user:
             raise errors.AccessForbiddenError()
 
         form = Form(enctype = 'multipart/form-data', use_tokens = False)
diff --git a/wcs/qommon/logger.py b/wcs/qommon/logger.py
index ac6b23cdf..89ffc02d1 100644
--- a/wcs/qommon/logger.py
+++ b/wcs/qommon/logger.py
@@ -77,6 +77,7 @@ class Formatter(logging.Formatter):
                 else:
                     user_id = user.id
                     if type(user_id) is str and user_id.startswith('anonymous-'):
+                        # legacy; kept for ancient log entries
                         user_id = 'anonymous'
             else:
                 user_id = 'unlogged'
diff --git a/wcs/qommon/myspace.py b/wcs/qommon/myspace.py
index 693abb2d0..4b3403935 100644
--- a/wcs/qommon/myspace.py
+++ b/wcs/qommon/myspace.py
@@ -31,7 +31,6 @@ from wcs.qommon.admin.texts import TextsDirectory
 # This module depends upon the following protocol from the user class:
 #
 # protocol User:
-#   anonymous = boolean
 #   def can_go_in_admin(self): User -> boolean
 #   def can_go_in_backoffice(self): User -> boolean
 #   def get_formdef(self): User -> an object responding to the FormDef protocol
@@ -100,7 +99,7 @@ class MyspaceDirectory(Directory):
 
     def profile(self):
         user = get_request().user
-        if not user or user.anonymous:
+        if not user:
             raise errors.AccessUnauthorizedError()
 
         form = Form(enctype = 'multipart/form-data')
@@ -135,7 +134,7 @@ class MyspaceDirectory(Directory):
             raise errors.TraversalError()
 
         user = get_request().user
-        if not user or user.anonymous:
+        if not user:
             raise errors.AccessUnauthorizedError()
 
         form = Form(enctype = 'multipart/form-data')
@@ -171,7 +170,7 @@ class MyspaceDirectory(Directory):
 
     def remove(self):
         user = get_request().user
-        if not user or user.anonymous:
+        if not user:
             raise errors.AccessUnauthorizedError()
 
         form = Form(enctype = 'multipart/form-data')
diff --git a/wcs/qommon/saml2.py b/wcs/qommon/saml2.py
index 650e2387d..444e3754b 100644
--- a/wcs/qommon/saml2.py
+++ b/wcs/qommon/saml2.py
@@ -340,13 +340,7 @@ class Saml2Directory(Directory):
         if user:
             session.set_user(user.id)
         else:
-            session.set_user('anonymous-%s' % login.nameIdentifier.content)
-            if login.identity:
-                session.lasso_anonymous_identity_dump = login.identity.dump()
-            else:
-                # XXX: this situation happened with SSO initiated by IdP, this
-                # is not normal
-                pass
+            return error_page('Error associating user on SSO')
         session.lasso_identity_provider_id = login.remoteProviderId
         session.message = None
         return self.continue_to_after_url()
diff --git a/wcs/qommon/sessions.py b/wcs/qommon/sessions.py
index 33632e8b2..35c9765c6 100644
--- a/wcs/qommon/sessions.py
+++ b/wcs/qommon/sessions.py
@@ -83,7 +83,6 @@ class Session(QommonSession, CaptchaSession, StorableObject):
     name_identifier = None
     lasso_session_dump = None
     lasso_session_index = None
-    lasso_anonymous_identity_dump = None
     lasso_identity_provider_id = None
     message = None
     saml_authn_context = None
@@ -127,7 +126,6 @@ class Session(QommonSession, CaptchaSession, StorableObject):
     def has_info(self):
         return self.name_identifier or \
             self.lasso_session_dump or self.message or \
-            self.lasso_anonymous_identity_dump or \
             self.lasso_identity_provider_id or \
             self.saml_authn_context or \
             self.ident_idp_token or \
@@ -202,29 +200,19 @@ class Session(QommonSession, CaptchaSession, StorableObject):
 
     def has_user(self):
         user_id = QuixoteSession.get_user(self)
-        if user_id and not str(user_id).startswith('anonymous-'):
-            return True
-        return False
+        return bool(user_id)
 
     def get_user(self):
         user_id = QuixoteSession.get_user(self)
         if user_id:
-            if str(user_id).startswith('anonymous-'):
-                user = get_publisher().user_class()
-                user.id = user_id
-                user.anonymous = True
-                user.name_identifiers = [ self.name_identifier ]
-                user.lasso_dump = self.lasso_anonymous_identity_dump
-            else:
-                try:
-                    user = get_publisher().user_class.get(user_id)
-                except KeyError:
-                    return None
+            try:
+                user = get_publisher().user_class.get(user_id)
+            except KeyError:
+                return None
             if user.is_active:
                 return user
             else:
                 self.set_user(None)
-
         return None
 
     def set_user(self, user_id):
@@ -233,9 +221,6 @@ class Session(QommonSession, CaptchaSession, StorableObject):
         QuixoteSession.set_user(self, user_id)
         if user_id is None:
             return
-        if str(user_id).startswith('anonymous-'):
-            # do not store connection time for anonymous users
-            return
         try:
             user = get_publisher().user_class.get(user_id)
             user.last_seen = time.time()
-- 
2.28.0

