diff --git a/eea/volto/policy/overrides.zcml b/eea/volto/policy/overrides.zcml
index fa819e4..56ca04b 100644
--- a/eea/volto/policy/overrides.zcml
+++ b/eea/volto/policy/overrides.zcml
@@ -3,19 +3,19 @@
xmlns:zcml="http://namespaces.zope.org/zcml"
xmlns:browser="http://namespaces.zope.org/browser">
-
+
-
-
-
+
+
+
+ />
1:
+ principal_types = {
+ info["principal_type"] for info in infos if info["principal_type"]
+ }
+ if len(principal_types) > 1:
+ # Principals with the same ID but different types. Should not
+ # happen.
+ raise ValueError("Principal ID not unique: {}".format(info["id"]))
+ if not info["title"]:
+ for candidate in infos:
+ if candidate["title"]:
+ info["title"] = candidate["title"]
+ break
+
+ if (
+ info.get("pluginid", "") == "pasldap"
+ and info.get("principal_type", "") == "user"
+ and info.get("title", None) == info.get("id", "")
+ ):
+ user = acl_users.getUserById(info["id"])
+ info["title"] = user.getProperty("fullname")
+ return info
+
+
+def unique_terms(objects):
+ unique_objects = []
+ seen_values = set()
+
+ for obj in objects:
+ if obj.value not in seen_values:
+ unique_objects.append(obj)
+ seen_values.add(obj.value)
+
+ return unique_objects
class SimpleUserTerm(SimpleTerm):
@@ -24,6 +80,8 @@ class SimpleUserTerm(SimpleTerm):
class UsersFactory(BaseUsersFactory):
"""Factory creating a UsersVocabulary"""
+ _needs_search = False
+
@property
def items(self):
"""Return a list of users"""
@@ -46,11 +104,67 @@ def items(self):
simpleTerm.email = email
yield simpleTerm
+ def should_search(self, query):
+ if self._needs_search:
+ return True
+
+ return super().should_search(query)
+
def __call__(self, *args, **kwargs):
+ request = getRequest()
+ tokens = request.form.get("tokens", None)
+ if tokens:
+ self._needs_search = True
+ return self.original_tweaked__call__(*args, query=tokens)
+
vocabulary = PrincipalsVocabulary(list(self.items))
vocabulary.principal_source = self.source
return vocabulary
+ def original_tweaked__call__(self, context, query=""):
+ if not self.should_search(query):
+ vocabulary = PrincipalsVocabulary([])
+ vocabulary.principal_source = self.source
+ return vocabulary
+
+ acl_users = _get_acl_users()
+ cfg = SOURCES[self.source]
+
+ def term_triples():
+ """Generator for term triples (value, token, name)"""
+ for search_cfg in cfg["searches"]:
+ search = getattr(acl_users, search_cfg["search"])
+ searchargs = search_cfg["searchargs"].copy()
+ searchargs[search_cfg["searchattr"]] = query
+ infotree = {}
+ for info in search(**searchargs):
+ infotree.setdefault(info["id"], {}).setdefault(
+ info["principal_type"], []
+ ).append(info)
+
+ for principal_id, types_infos in infotree.items():
+ if len(types_infos) > 1 and not cfg["prefix"]:
+ raise ValueError(f"Principal ID not unique: {principal_id}")
+ for principal_type, principal_infos in types_infos.items():
+ if principal_type == "user":
+ pass
+ value = principal_id
+ info = merge_principal_infos(principal_infos, acl_users)
+ if cfg["prefix"]:
+ value = "{}:{}".format(info["principal_type"], value)
+ token = token_from_principal_info(info, prefix=cfg["prefix"])
+ yield (value, token, info["title"])
+
+ terms = unique_terms(
+ [
+ SimpleTerm(*term_triple)
+ for term_triple in filter(self.use_principal_triple, term_triples())
+ ]
+ )
+ vocabulary = PrincipalsVocabulary(terms)
+ vocabulary.principal_source = self.source
+ return vocabulary
+
@implementer(ISerializeToJson)
@adapter(SimpleUserTerm, Interface)