Index: main/plugin-core/i18n/messages_en.xml
===================================================================
--- main/plugin-core/i18n/messages_en.xml (revision 43460)
+++ main/plugin-core/i18n/messages_en.xml (working copy)
@@ -40,6 +40,10 @@
E-mail address used by default as the sender of the e-mails. <br/>The <b>Ametys.org <admin@ametys.org></b> form can be used.
System administrator email
E-mail address of the system administrator for alert purposes.
+
+ Massive sending
+ Send to all
+ When this case is unchecked, if allowed users by a right on a context are any connected user, no one is returned. This is a security to avoid massive mail sending by mistake.<br/> Check this case for going back to a normal behavior et return all users in this specific case.
Applications
Index: main/plugin-core/i18n/messages_fr.xml
===================================================================
--- main/plugin-core/i18n/messages_fr.xml (revision 43460)
+++ main/plugin-core/i18n/messages_fr.xml (working copy)
@@ -40,6 +40,10 @@
Adresse e-mail utilisée par défaut comme expéditeur des mails.<br/>La forme <b>Ametys.org <admin@ametys.org></b> peut être utilisée.
Email de l'administrateur système
Adresse email de l'adminitrateur système afin de recevoir des alertes par mail.
+
+ Envoi massif
+ Envoyer à tous
+ Lorsque cette case est décochée, si les utilisateurs autorisés par un droit sur un contexte sont tous les utilisateurs, aucun n'est renvoyé. Ceci est une sécurité afin d'éviter un envoi massif de mail par erreur.<br/> Cochez cette case pour avoir un comportement normal et retourner tous les utilisateurs dans ce cas spécifique.
Applications
Index: main/plugin-core/plugin.xml
===================================================================
--- main/plugin-core/plugin.xml (revision 43460)
+++ main/plugin-core/plugin.xml (working copy)
@@ -195,6 +195,24 @@
+
+
+
+ PLUGINS_CORE_MAIL_CONFIG_ANYCONNECTED_USER_RETURN_ALL_DESCRIPTION
+
+
+
+ false
+ PLUGINS_CORE_MAIL_CONFIG_CATEGORY
+ PLUGINS_CORE_MAIL_CONFIG_ANYCONNECTED_USER_RETURN_ALL_GROUP
+
+
+
Index: main/plugin-core/src/org/ametys/core/right/AllowedUsers.java
===================================================================
--- main/plugin-core/src/org/ametys/core/right/AllowedUsers.java (revision 0)
+++ main/plugin-core/src/org/ametys/core/right/AllowedUsers.java (revision 0)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 Anyware Services
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ametys.core.right;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections.CollectionUtils;
+
+import org.ametys.core.user.User;
+import org.ametys.core.user.UserIdentity;
+import org.ametys.core.user.UserManager;
+
+/**
+ * Wrapper class to represent a set of allowed users, which can eventually be anonymous or any connected user.
+ */
+public class AllowedUsers
+{
+ private boolean _anonymous;
+ private boolean _anyConnectedUser;
+ private Set _allowedUsers;
+ private Set _deniedUsers;
+ private UserManager _userManager;
+ private Set _populationContexts;
+
+ /**
+ * Creates an object representing allowed users.
+ * @param anonymous true to indicate any anonymous user is allowed
+ * @param anyConnectedUser if anonymous is false, true to indicate any connected user is allowed
+ * @param allowedUsers the allowed users, not taking into account the denied users. Must be null if anonymous or anyConnectedUser is true, must not otherwise.
+ * @param deniedUsers the denied users. Must be null if anonymous is true, must not otherwise.
+ * @param userManager The user manager
+ * @param populationContexts The population contexts for retrieving users from user manager. Can be null if anyConnectedUser is false
+ */
+ public AllowedUsers(boolean anonymous, boolean anyConnectedUser, Set allowedUsers, Set deniedUsers, UserManager userManager, Set populationContexts)
+ {
+ _anonymous = anonymous;
+ _anyConnectedUser = anyConnectedUser;
+ _allowedUsers = allowedUsers;
+ _deniedUsers = deniedUsers;
+ _userManager = userManager;
+ _populationContexts = populationContexts;
+ }
+
+ /**
+ * Returns true if any anonymous user is allowed
+ * @return true if any anonymous user is allowed
+ */
+ public boolean isAnonymousAllowed()
+ {
+ return _anonymous;
+ }
+
+ /**
+ * Returns true if any connected user is allowed
+ * @return true if any connected user is allowed
+ */
+ public boolean isAnyConnectedUserAllowed()
+ {
+ return !_anonymous && _anyConnectedUser;
+ }
+
+ /**
+ * Computes the actual allowed users, taking into account the anyconnected, allowed and denied users.
+ * If anonymous is allowed, it will return an empty list.
+ * @param returnAll Set this to true to have normal behavior, and return all users in case {@link AllowedUsers#isAnyConnectedUserAllowed()} returns true. Set this to false to return an empty list in case {@link AllowedUsers#isAnyConnectedUserAllowed()} returns true
+ * @return the computed actual allowed users
+ */
+ public Set actualAllowedUsers(boolean returnAll)
+ {
+ if (_anonymous || _anyConnectedUser && !returnAll)
+ {
+ return Collections.EMPTY_SET;
+ }
+ else if (_anyConnectedUser)
+ {
+ // Retrieve all users from the user manager, and remove just the denied ones
+ Set allUsers = _userManager.getUsersByContext(_populationContexts).stream().map(User::getIdentity).collect(Collectors.toSet());
+
+ return new HashSet<>(CollectionUtils.removeAll(allUsers, _deniedUsers));
+ }
+ else
+ {
+ // It's just _allowedUsers, minus _deniedUsers
+ return new HashSet<>(CollectionUtils.removeAll(_allowedUsers, _deniedUsers));
+ }
+ }
+}
Index: main/plugin-core/src/org/ametys/core/right/ProfileAssignmentStorageExtensionPoint.java
===================================================================
--- main/plugin-core/src/org/ametys/core/right/ProfileAssignmentStorageExtensionPoint.java (revision 43460)
+++ main/plugin-core/src/org/ametys/core/right/ProfileAssignmentStorageExtensionPoint.java (working copy)
@@ -278,7 +278,7 @@
*/
public AccessResult getPermissionForAnyConnectedUser (Set profileIds, Object object)
{
- getLogger().debug("Try to determine permission for Anonymous on context {} and profiles {}", object, profileIds);
+ getLogger().debug("Try to determine permission for AnyConnectedUser on context {} and profiles {}", object, profileIds);
AccessResult result = AccessResult.UNKNOWN;
@@ -288,11 +288,11 @@
Set deniedProfiles = getDeniedProfilesForAnyConnectedUser(object);
if (deniedProfiles.contains(profileId))
{
- return AccessResult.ANONYMOUS_DENIED;
+ return AccessResult.ANY_CONNECTED_DENIED;
}
else if (allowedProfiles.contains(profileId))
{
- result = AccessResult.ANONYMOUS_ALLOWED;
+ result = AccessResult.ANY_CONNECTED_ALLOWED;
}
}
@@ -328,7 +328,7 @@
}
}
- getLogger().debug("The permissions by users on context {} and profiles {} are: ", object, profileIds, result);
+ getLogger().debug("The permissions by users on context {} and profiles {} are: {}", object, profileIds, result);
return result;
}
Index: main/plugin-core/src/org/ametys/core/right/RightManager.java
===================================================================
--- main/plugin-core/src/org/ametys/core/right/RightManager.java (revision 43460)
+++ main/plugin-core/src/org/ametys/core/right/RightManager.java (working copy)
@@ -36,10 +36,15 @@
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.Request;
import org.apache.commons.lang.StringUtils;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
@@ -69,7 +74,7 @@
/**
* Abstraction for testing a right associated with a resource and a user from a single source.
*/
-public class RightManager extends AbstractLogEnabled implements UserListener, GroupListener, Serviceable, Configurable, Initializable, RequestListener, ThreadSafe, Component
+public class RightManager extends AbstractLogEnabled implements UserListener, GroupListener, Serviceable, Configurable, Initializable, RequestListener, ThreadSafe, Component, Contextualizable
{
/** For avalon service manager */
public static final String ROLE = RightManager.class.getName();
@@ -124,6 +129,8 @@
* We are caching the set of profiles instead of right id because many rights belong to the exact same profiles
*/
private final ThreadLocal