From 05dbcfdd1de545de0c982cf148a488838f7f6b0c Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 29 Mar 2018 16:30:47 +0200 Subject: [PATCH] OO-3299: more restriction in user management for user managers of organizations --- .../user/NewUsersNotificationsController.java | 28 ++++-- .../user/UsermanagerUserSearchController.java | 7 +- .../user/_content/newusersNotifications.html | 4 +- .../IdentityPowerSearchQueries.java | 19 ++++ .../IdentityPowerSearchQueriesImpl.java | 21 +++- .../_spring/notificationsContext.xml | 10 -- .../manager/NotificationsManagerImpl.java | 12 +-- .../restapi/NotificationsWebService.java | 6 +- .../NewUsersNotificationHandler.java | 24 ++++- .../UsersSubscriptionManager.java | 23 ++--- .../UsersSubscriptionManagerImpl.java | 95 +++++++++---------- .../user/ui/admin/IdentityListDataSource.java | 19 ++++ .../ui/admin/UserAdminMainController.java | 52 +++++----- .../user/ui/admin/UserSearchDataSource.java | 19 ++++ .../ui/admin/UserSearchTableController.java | 19 ++++ .../user/ui/admin/UserSearchTableModel.java | 19 ++++ .../OrganisationUserManagementController.java | 47 +++++++-- ...OrganisationsStructureAdminController.java | 10 +- .../ui/organisation/RoleListController.java | 80 ++++++++++++++++ .../_content/organisation_user_mgmt.html | 4 +- .../_i18n/LocalStrings_de.properties | 14 ++- .../component/RoleFlexiCellRenderer.java | 60 ++++++++++++ .../user/ui/organisation/event/RoleEvent.java | 46 +++++++++ .../org/olat/restapi/NotificationsTest.java | 27 ++++-- 24 files changed, 512 insertions(+), 153 deletions(-) create mode 100644 src/main/java/org/olat/user/ui/organisation/RoleListController.java create mode 100644 src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java create mode 100644 src/main/java/org/olat/user/ui/organisation/event/RoleEvent.java diff --git a/src/main/java/org/olat/admin/user/NewUsersNotificationsController.java b/src/main/java/org/olat/admin/user/NewUsersNotificationsController.java index 0fc4335fb59..4bd3ee5fc39 100644 --- a/src/main/java/org/olat/admin/user/NewUsersNotificationsController.java +++ b/src/main/java/org/olat/admin/user/NewUsersNotificationsController.java @@ -30,6 +30,7 @@ import org.olat.core.commons.services.notifications.ui.ContextualSubscriptionCon import org.olat.core.commons.services.notifications.ui.DateChooserController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.stack.TooledStackedPanel; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; @@ -37,6 +38,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.id.Identity; import org.olat.user.notification.UsersSubscriptionManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -51,20 +53,25 @@ import org.olat.user.notification.UsersSubscriptionManager; */ public class NewUsersNotificationsController extends BasicController { - private DateChooserController dateChooserController; + private final DateChooserController dateChooserController; private UsermanagerUserSearchController searchController; - private ContextualSubscriptionController subscriptionController; + private final ContextualSubscriptionController subscriptionController; - private VelocityContainer mainVC; + private final VelocityContainer mainVC; + private TooledStackedPanel stackedPanel; - public NewUsersNotificationsController(UserRequest ureq, WindowControl wControl) { + @Autowired + private UsersSubscriptionManager usersSubscriptionManager; + + public NewUsersNotificationsController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackedPanel) { super(ureq, wControl); + this.stackedPanel = stackedPanel; mainVC = createVelocityContainer("newusersNotifications"); // subscribe/unsubscribe - SubscriptionContext subContext = UsersSubscriptionManager.getInstance().getNewUsersSubscriptionContext(); - PublisherData publisherData = UsersSubscriptionManager.getInstance().getNewUsersPublisherData(); + SubscriptionContext subContext = usersSubscriptionManager.getNewUsersSubscriptionContext(); + PublisherData publisherData = usersSubscriptionManager.getNewUsersPublisherData(); subscriptionController = new ContextualSubscriptionController(ureq, getWindowControl(), subContext, publisherData); listenTo(subscriptionController); @@ -84,15 +91,16 @@ public class NewUsersNotificationsController extends BasicController { if(searchController != null) { removeAsListenerAndDispose(searchController); } - List<Identity> identities = UsersSubscriptionManager.getInstance().getNewIdentityCreated(compareDate); - searchController = new UsermanagerUserSearchController(ureq, getWindowControl(), identities, Identity.STATUS_VISIBLE_LIMIT, true, false); + + List<Identity> identities = usersSubscriptionManager.getNewIdentityCreated(compareDate, getIdentity(), ureq.getUserSession().getRoles()); + searchController = new UsermanagerUserSearchController(ureq, getWindowControl(), stackedPanel, identities, Identity.STATUS_VISIBLE_LIMIT, true, false); listenTo(searchController); mainVC.put("notificationsList", searchController.getInitialComponent()); if(identities.isEmpty()) { - mainVC.contextPut("hasNews", "false"); + mainVC.contextPut("hasNews", Boolean.FALSE); } else { - mainVC.contextPut("hasNews", "true"); + mainVC.contextPut("hasNews", Boolean.TRUE); } } diff --git a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java index b8465b74567..0bde3184a30 100644 --- a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java +++ b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java @@ -45,7 +45,6 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; -import org.olat.core.gui.components.panel.StackedPanel; import org.olat.core.gui.components.stack.TooledStackedPanel; import org.olat.core.gui.components.table.Table; import org.olat.core.gui.components.table.TableEvent; @@ -97,7 +96,6 @@ public class UsermanagerUserSearchController extends BasicController implements private static final String CMD_BULKEDIT = "bulkEditUsers"; private VelocityContainer userListVC, userSearchVC, mailVC; - private StackedPanel panel2; private TooledStackedPanel stackedPanel; @@ -207,10 +205,11 @@ public class UsermanagerUserSearchController extends BasicController implements * @param status * @param showEmailButton */ - public UsermanagerUserSearchController(UserRequest ureq, WindowControl wControl, List<Identity> identitiesList, - Integer status, boolean showEmailButton, boolean showTitle) { + public UsermanagerUserSearchController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackedPanel, + List<Identity> identitiesList, Integer status, boolean showEmailButton, boolean showTitle) { super(ureq, wControl); setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + this.stackedPanel = stackedPanel; isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); diff --git a/src/main/java/org/olat/admin/user/_content/newusersNotifications.html b/src/main/java/org/olat/admin/user/_content/newusersNotifications.html index 08302411166..fd1345b61b4 100644 --- a/src/main/java/org/olat/admin/user/_content/newusersNotifications.html +++ b/src/main/java/org/olat/admin/user/_content/newusersNotifications.html @@ -3,8 +3,8 @@ $r.render("newUsersSubscription") <div class="o_notifications_news_datechooser"> $r.render("dateChooser") </div> -#if ($hasNews == "false") - <p>$r.translate("notification.noNews")</p> +#if ($r.isFalse($hasNews)) + <div class="o_info">$r.translate("notification.noNews")</div> #else $r.render("notificationsList") #end \ No newline at end of file diff --git a/src/main/java/org/olat/basesecurity/IdentityPowerSearchQueries.java b/src/main/java/org/olat/basesecurity/IdentityPowerSearchQueries.java index 6ad469efa22..a4d9889a047 100644 --- a/src/main/java/org/olat/basesecurity/IdentityPowerSearchQueries.java +++ b/src/main/java/org/olat/basesecurity/IdentityPowerSearchQueries.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.basesecurity; import java.util.List; diff --git a/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java b/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java index 4ef611c4d07..817ebaa360a 100644 --- a/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java +++ b/src/main/java/org/olat/basesecurity/manager/IdentityPowerSearchQueriesImpl.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.basesecurity.manager; import java.util.ArrayList; @@ -437,7 +456,7 @@ public class IdentityPowerSearchQueriesImpl implements IdentityPowerSearchQuerie if(params.hasOrganisationParents()) { for(int i=0; i<params.getOrganisationParents().size(); i++) { String org = params.getOrganisationParents().get(i).getMaterializedPathKeys(); - dbq.setParameter("organisationParent_" + i, org); + dbq.setParameter("organisationParent_" + i, org + "%"); } } diff --git a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml index 0faef9070fa..7fb68ab1e98 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml +++ b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml @@ -12,7 +12,6 @@ <bean id="org.olat.course.nodes.ta.ReturnboxFileUploadNotificationHandler" class="org.olat.course.nodes.ta.ReturnboxFileUploadNotificationHandler"/> <bean id="org.olat.course.nodes.ta.SolutionFileUploadNotificationHandler" class="org.olat.course.nodes.ta.SolutionFileUploadNotificationHandler"/> <bean id="org.olat.modules.wiki.WikiPageChangeOrCreateNotificationHandler" class="org.olat.modules.wiki.WikiPageChangeOrCreateNotificationHandler" /> - <bean id="org.olat.user.notification.NewUsersNotificationHandler" class="org.olat.user.notification.NewUsersNotificationHandler" /> <bean id="notificationsManager" class="org.olat.core.commons.services.notifications.manager.NotificationsManagerImpl" > <property name="dbInstance" ref="database"/> @@ -43,15 +42,6 @@ </property> </bean> - <bean - id="org.olat.user.notification.UsersSubscriptionManager" class="org.olat.user.notification.UsersSubscriptionManagerImpl" - depends-on="coordinatorManager"> - <property name="autoSubscribe" value="false" /> - <property name="coordinator"> - <ref bean="coordinatorManager" /> - </property> - </bean> - <!-- Notification config: If you want to disable notificaition please comment out the corresponding entry in scheduler spring file in serviceconfig/org/olat/core/commons/scheduler/_spring/olatextconfig.xml diff --git a/src/main/java/org/olat/core/commons/services/notifications/manager/NotificationsManagerImpl.java b/src/main/java/org/olat/core/commons/services/notifications/manager/NotificationsManagerImpl.java index dd6d855ee45..dc195955ad4 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/manager/NotificationsManagerImpl.java +++ b/src/main/java/org/olat/core/commons/services/notifications/manager/NotificationsManagerImpl.java @@ -103,7 +103,7 @@ public class NotificationsManagerImpl extends NotificationsManager implements Us private static final int PUB_STATE_NOT_OK = 1; private static final int BATCH_SIZE = 500; private static final String LATEST_EMAIL_USER_PROP = "noti_latest_email"; - private final SubscriptionInfo NOSUBSINFO = new NoSubscriptionInfo(); + private static final SubscriptionInfo NOSUBSINFO = new NoSubscriptionInfo(); private final OLATResourceable oresMyself = OresHelper.lookupType(NotificationsManagerImpl.class); @@ -810,10 +810,6 @@ public class NotificationsManagerImpl extends NotificationsManager implements Us .getResultList(); } - /** - * - * @see org.olat.core.commons.services.notifications.NotificationsManager#getSubscriberIdentities(org.olat.core.commons.services.notifications.Publisher) - */ @Override public List<Identity> getSubscriberIdentities(Publisher publisher) { return dbInstance.getCurrentEntityManager() @@ -825,12 +821,13 @@ public class NotificationsManagerImpl extends NotificationsManager implements Us /** * @return the handler for the type */ + @Override public NotificationsHandler getNotificationsHandler(Publisher publisher) { String type = publisher.getType(); if (notificationHandlers == null) { synchronized(lockObject) { if (notificationHandlers == null) { // check again in synchronized-block, only one may create list - notificationHandlers = new HashMap<String,NotificationsHandler>(); + notificationHandlers = new HashMap<>(); Map<String, NotificationsHandler> notificationsHandlerMap = CoreSpringFactory.getBeansOfType(NotificationsHandler.class); Collection<NotificationsHandler> notificationsHandlerValues = notificationsHandlerMap.values(); for (NotificationsHandler notificationsHandler : notificationsHandlerValues) { @@ -849,7 +846,8 @@ public class NotificationsManagerImpl extends NotificationsManager implements Us private void deleteSubscriber(Subscriber subscriber) { dbInstance.deleteObject(subscriber); } - + + @Override public boolean deleteSubscriber(Long subscriberKey) { String sb = "delete from notisub sub where sub.key=:subscriberKey"; int rows = dbInstance.getCurrentEntityManager() diff --git a/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java b/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java index 7642d2f1f9d..79bd9afbb50 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java +++ b/src/main/java/org/olat/core/commons/services/notifications/restapi/NotificationsWebService.java @@ -212,13 +212,13 @@ public class NotificationsWebService { compareDate = man.getCompareDateFromInterval(man.getUserIntervalOrDefault(identity)); } - List<String> types = new ArrayList<String>(1); + List<String> types = new ArrayList<>(1); if(StringHelper.containsNonWhitespace(type)) { types.add(type); } Map<Subscriber,SubscriptionInfo> subsInfoMap = NotificationHelper.getSubscriptionMap(identity, locale, true, compareDate, types); - List<SubscriptionInfoVO> voes = new ArrayList<SubscriptionInfoVO>(); + List<SubscriptionInfoVO> voes = new ArrayList<>(); for(Map.Entry<Subscriber, SubscriptionInfo> entry: subsInfoMap.entrySet()) { SubscriptionInfo info = entry.getValue(); if(info.hasNews()) { @@ -234,7 +234,7 @@ public class NotificationsWebService { private SubscriptionInfoVO createSubscriptionInfoVO(Publisher publisher, SubscriptionInfo info) { SubscriptionInfoVO infoVO = new SubscriptionInfoVO(info); if(info.getSubscriptionListItems() != null && !info.getSubscriptionListItems().isEmpty()) { - List<SubscriptionListItemVO> itemVOes = new ArrayList<SubscriptionListItemVO>(info.getSubscriptionListItems().size()); + List<SubscriptionListItemVO> itemVOes = new ArrayList<>(info.getSubscriptionListItems().size()); String publisherType = publisher.getType(); String resourceType = publisher.getResName(); diff --git a/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java b/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java index 33f1e6456b0..8270f33d242 100644 --- a/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java +++ b/src/main/java/org/olat/user/notification/NewUsersNotificationHandler.java @@ -23,6 +23,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import org.olat.basesecurity.BaseSecurity; import org.olat.core.commons.services.notifications.NotificationHelper; import org.olat.core.commons.services.notifications.NotificationsHandler; import org.olat.core.commons.services.notifications.NotificationsManager; @@ -34,10 +35,13 @@ import org.olat.core.commons.services.notifications.model.TitleItem; import org.olat.core.gui.translator.Translator; import org.olat.core.gui.util.CSSHelper; import org.olat.core.id.Identity; +import org.olat.core.id.Roles; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -49,9 +53,17 @@ import org.olat.core.util.Util; * * @author srosse, stephane.rosse@frentix.com */ +@Service public class NewUsersNotificationHandler implements NotificationsHandler { private static final OLog log = Tracing.createLoggerFor(NewUsersNotificationHandler.class); + @Autowired + private BaseSecurity securityManager; + @Autowired + private NotificationsManager notificationsManager; + @Autowired + private UsersSubscriptionManager usersSubscriptionManager; + @Override public SubscriptionInfo createSubscriptionInfo(Subscriber subscriber, Locale locale, Date compareDate) { Publisher p = subscriber.getPublisher(); @@ -61,10 +73,12 @@ public class NewUsersNotificationHandler implements NotificationsHandler { Translator translator = Util.createPackageTranslator(this.getClass(), locale); // there could be news for me, investigate deeper try { - if (NotificationsManager.getInstance().isPublisherValid(p) && compareDate.before(latestNews)) { - List<Identity> identities = UsersSubscriptionManager.getInstance().getNewIdentityCreated(compareDate); + if (notificationsManager.isPublisherValid(p) && compareDate.before(latestNews)) { + Identity identity = subscriber.getIdentity(); + Roles roles = securityManager.getRoles(identity); + List<Identity> identities = usersSubscriptionManager.getNewIdentityCreated(compareDate, subscriber.getIdentity(), roles); if (identities.isEmpty()) { - si = NotificationsManager.getInstance().getNoSubscriptionInfo(); + si = notificationsManager.getNoSubscriptionInfo(); } else { translator = Util.createPackageTranslator(this.getClass(), locale); si = new SubscriptionInfo(subscriber.getKey(), p.getType(), new TitleItem(getItemTitle(identities, translator), CSSHelper.CSS_CLASS_GROUP), null); @@ -79,11 +93,11 @@ public class NewUsersNotificationHandler implements NotificationsHandler { } } } else { - si = NotificationsManager.getInstance().getNoSubscriptionInfo(); + si = notificationsManager.getNoSubscriptionInfo(); } } catch (Exception e) { log.error("Error creating new identity's notifications for subscriber: " + subscriber.getKey(), e); - si = NotificationsManager.getInstance().getNoSubscriptionInfo(); + si = notificationsManager.getNoSubscriptionInfo(); } return si; } diff --git a/src/main/java/org/olat/user/notification/UsersSubscriptionManager.java b/src/main/java/org/olat/user/notification/UsersSubscriptionManager.java index 4f1a0a1d5de..a7a154b1c4f 100644 --- a/src/main/java/org/olat/user/notification/UsersSubscriptionManager.java +++ b/src/main/java/org/olat/user/notification/UsersSubscriptionManager.java @@ -22,12 +22,11 @@ package org.olat.user.notification; import java.util.Date; import java.util.List; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.PublisherData; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.id.Identity; -import org.olat.core.manager.BasicManager; +import org.olat.core.id.Roles; /** @@ -41,23 +40,19 @@ import org.olat.core.manager.BasicManager; * * @author srosse */ -public abstract class UsersSubscriptionManager extends BasicManager { +public interface UsersSubscriptionManager { - public static final UsersSubscriptionManager getInstance() { - return (UsersSubscriptionManager) CoreSpringFactory.getBean(UsersSubscriptionManager.class.getCanonicalName()); - } + public SubscriptionContext getNewUsersSubscriptionContext(); - public abstract SubscriptionContext getNewUsersSubscriptionContext(); + public PublisherData getNewUsersPublisherData(); - public abstract PublisherData getNewUsersPublisherData(); + public Subscriber getNewUsersSubscriber(Identity identity); - public abstract Subscriber getNewUsersSubscriber(Identity identity); + public void subscribe(Identity identity); - public abstract void subscribe(Identity identity); + public void unsubscribe(Identity identity); - public abstract void unsubscribe(Identity identity); + public void markPublisherNews(); - public abstract void markPublisherNews(); - - public abstract List<Identity> getNewIdentityCreated(Date From); + public List<Identity> getNewIdentityCreated(Date from, Identity actingIdentity, Roles roles); } diff --git a/src/main/java/org/olat/user/notification/UsersSubscriptionManagerImpl.java b/src/main/java/org/olat/user/notification/UsersSubscriptionManagerImpl.java index 28ce07b7f00..a9cab470fbe 100644 --- a/src/main/java/org/olat/user/notification/UsersSubscriptionManagerImpl.java +++ b/src/main/java/org/olat/user/notification/UsersSubscriptionManagerImpl.java @@ -21,13 +21,14 @@ package org.olat.user.notification; import java.util.Collections; import java.util.Date; -import java.util.Iterator; import java.util.List; import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityManager; +import org.olat.basesecurity.Organisation; import org.olat.basesecurity.OrganisationRoles; +import org.olat.basesecurity.SearchIdentityParams; import org.olat.basesecurity.events.NewIdentityCreatedEvent; +import org.olat.basesecurity.manager.OrganisationDAO; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.PublisherData; @@ -36,12 +37,15 @@ import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.gui.control.Event; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.Roles; import org.olat.core.id.User; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OresHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** @@ -54,47 +58,41 @@ import org.olat.core.util.resource.OresHelper; * * @author srosse */ -public class UsersSubscriptionManagerImpl extends UsersSubscriptionManager implements GenericEventListener { +@Service +public class UsersSubscriptionManagerImpl implements UsersSubscriptionManager, GenericEventListener { public static final String NEW = "NewIdentityCreated"; - public static final Long RES_ID = new Long(0); + public static final Long RES_ID = Long.valueOf(0); public static final String RES_NAME = OresHelper.calculateTypeName(User.class); public static final OLATResourceable IDENTITY_EVENT_CHANNEL = OresHelper.lookupType(Identity.class); - private boolean autoSubscribe; + @Autowired + private BaseSecurity securityManager; + @Autowired + private OrganisationDAO organisationDao; + @Autowired + private NotificationsManager notificationsManager; - public UsersSubscriptionManagerImpl() { - // - } - - public void setCoordinator(CoordinatorManager coordinatorManager) { + @Autowired + public UsersSubscriptionManagerImpl(CoordinatorManager coordinatorManager) { coordinatorManager.getCoordinator().getEventBus().registerFor(this, null, IDENTITY_EVENT_CHANNEL); } - public void setAutoSubscribe(boolean autoSubscribe) { - this.autoSubscribe = autoSubscribe; - } - /** * Receive the event after the creation of new identities */ + @Override public void event(Event event) { if (event instanceof NewIdentityCreatedEvent) { markPublisherNews(); - if(autoSubscribe) { - NewIdentityCreatedEvent e = (NewIdentityCreatedEvent)event; - Identity identity = BaseSecurityManager.getInstance().loadIdentityByKey(e.getIdentityId()); - subscribe(identity); - } } } - /** - * - */ + @Override public SubscriptionContext getNewUsersSubscriptionContext() { return new SubscriptionContext(RES_NAME, RES_ID, NEW); } - + + @Override public PublisherData getNewUsersPublisherData() { ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(new OLATResourceable() { @Override @@ -102,42 +100,45 @@ public class UsersSubscriptionManagerImpl extends UsersSubscriptionManager imple @Override public String getResourceableTypeName() { return "NewIdentityCreated"; } }); - PublisherData publisherData = new PublisherData(RES_NAME, NEW, ce.toString()); - return publisherData; + return new PublisherData(RES_NAME, NEW, ce.toString()); } - + + @Override public Subscriber getNewUsersSubscriber(Identity identity) { SubscriptionContext context = getNewUsersSubscriptionContext(); - Publisher publisher = NotificationsManager.getInstance().getPublisher(context); + Publisher publisher = notificationsManager.getPublisher(context); if(publisher == null) { return null; } - return NotificationsManager.getInstance().getSubscriber(identity, publisher); + return notificationsManager.getSubscriber(identity, publisher); } /** * Subscribe to notifications of new identity created */ + @Override public void subscribe(Identity identity) { PublisherData data = getNewUsersPublisherData(); SubscriptionContext context = getNewUsersSubscriptionContext(); - NotificationsManager.getInstance().subscribe(identity, context, data); + notificationsManager.subscribe(identity, context, data); } /** * Unsubscribe to notifications of new identity created */ + @Override public void unsubscribe(Identity identity) { SubscriptionContext context = getNewUsersSubscriptionContext(); - NotificationsManager.getInstance().unsubscribe(identity, context); + notificationsManager.unsubscribe(identity, context); } /** * Call this method if there is new identities */ + @Override public void markPublisherNews() { SubscriptionContext context = getNewUsersSubscriptionContext(); - NotificationsManager.getInstance().markPublisherNews(context, null, true); + notificationsManager.markPublisherNews(context, null, true); } /** @@ -145,25 +146,23 @@ public class UsersSubscriptionManagerImpl extends UsersSubscriptionManager imple * The guest are also removed from the list. */ @Override - public List<Identity> getNewIdentityCreated(Date from) { - if(from == null) - return Collections.emptyList(); - - BaseSecurity manager = BaseSecurityManager.getInstance(); - OrganisationRoles[] guestRoles = { OrganisationRoles.guest }; - List<Identity> guests = manager.getIdentitiesByPowerSearch(null, null, true, guestRoles, null, from, null, null, null, Identity.STATUS_VISIBLE_LIMIT); - List<Identity> identities = manager.getIdentitiesByPowerSearch(null, null, true, null, null, from, null, null, null, Identity.STATUS_VISIBLE_LIMIT); - if(!identities.isEmpty() && !guests.isEmpty()) { - identities.removeAll(guests); - } - - for(Iterator<Identity> identityIt=identities.iterator(); identityIt.hasNext(); ) { - Identity identity = identityIt.next(); - if(identity.getCreationDate().before(from)) { - identityIt.remove(); + public List<Identity> getNewIdentityCreated(Date from, Identity actingIdentity, Roles roles) { + if(from == null || (!roles.isUserManager() && !roles.isOLATAdmin())) return Collections.emptyList(); + + List<Organisation> userManagerOrganisations = null; + if(!roles.isOLATAdmin()) { + userManagerOrganisations = organisationDao + .getOrganisations(actingIdentity, Collections.singletonList(OrganisationRoles.usermanager.name())); + if(userManagerOrganisations.isEmpty()) { + return Collections.emptyList(); } } - return identities; + SearchIdentityParams params = new SearchIdentityParams(); + params.setExcludedRoles(new OrganisationRoles[]{ OrganisationRoles.guest }); + params.setCreatedAfter(from); + params.setStatus(Identity.STATUS_VISIBLE_LIMIT); + params.setOrganisationParents(userManagerOrganisations); + return securityManager.getIdentitiesByPowerSearch(params, 0, -1); } } \ No newline at end of file diff --git a/src/main/java/org/olat/user/ui/admin/IdentityListDataSource.java b/src/main/java/org/olat/user/ui/admin/IdentityListDataSource.java index fa697a9cf4a..a364be7951e 100644 --- a/src/main/java/org/olat/user/ui/admin/IdentityListDataSource.java +++ b/src/main/java/org/olat/user/ui/admin/IdentityListDataSource.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.user.ui.admin; import java.util.ArrayList; diff --git a/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java b/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java index 49887592176..23049e2740c 100644 --- a/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java +++ b/src/main/java/org/olat/user/ui/admin/UserAdminMainController.java @@ -303,7 +303,7 @@ public class UserAdminMainController extends MainLayoutBasicController implement case "created.lastweek": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.DAY_OF_MONTH, -7); case "created.lastmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -1); case "created.sixmonth": return createUserSearchControllerAfterDate(ureq, bwControl, Calendar.MONTH, -6); - case "created.newUsersNotification": return new NewUsersNotificationsController(ureq, bwControl); + case "created.newUsersNotification": return new NewUsersNotificationsController(ureq, bwControl, content); // repository entry owners - authors case "coauthors": return createUserSearchController(ureq, bwControl, SearchIdentityParams.resources(GroupRoles.owner, null, null, new OrganisationRoles[] { OrganisationRoles.author }, Identity.STATUS_VISIBLE_LIMIT)); @@ -318,28 +318,19 @@ public class UserAdminMainController extends MainLayoutBasicController implement SearchIdentityParams.resources(null, GroupRoles.coach, null, null, Identity.STATUS_VISIBLE_LIMIT)); case "noauthentication": return createUserSearchController(ureq, bwControl, SearchIdentityParams.authenticationProviders(new String[]{ null }, Identity.STATUS_VISIBLE_LIMIT)); - default: return getControllerFromMenuCommand(ureq, bwControl, uobject); + case "userswithoutgroup": + List<Identity> usersWithoutGroup = securityManager.findIdentitiesWithoutBusinessGroup(Identity.STATUS_VISIBLE_LIMIT); + return new UsermanagerUserSearchController(ureq, bwControl, content, usersWithoutGroup, null, true, true); + case "userswithoutemail": + List<Identity> usersWithoutEmail = userManager.findVisibleIdentitiesWithoutEmail(); + return new UsermanagerUserSearchController(ureq, bwControl, content, usersWithoutEmail, null, true, true); + case "usersemailduplicates": + List<Identity> usersEmailDuplicates = userManager.findVisibleIdentitiesWithEmailDuplicates(); + return new UsermanagerUserSearchController(ureq, bwControl, content, usersEmailDuplicates, null, true, true); + default: return null; } } - private Controller getControllerFromMenuCommand(UserRequest ureq, WindowControl bwControl, Object uobject) { - UsermanagerUserSearchController ctrl; - if (uobject.equals("userswithoutgroup")) { - List<Identity> usersWithoutGroup = securityManager.findIdentitiesWithoutBusinessGroup(Identity.STATUS_VISIBLE_LIMIT); - ctrl = new UsermanagerUserSearchController(ureq, bwControl, usersWithoutGroup, null, true, true); - } else if (uobject.equals("userswithoutemail")) { - List<Identity> usersWithoutEmail = userManager.findVisibleIdentitiesWithoutEmail(); - ctrl = new UsermanagerUserSearchController(ureq, bwControl, usersWithoutEmail, null, true, true); - } else if (uobject.equals("usersemailduplicates")) { - List<Identity> usersEmailDuplicates = userManager.findVisibleIdentitiesWithEmailDuplicates(); - ctrl = new UsermanagerUserSearchController(ureq, bwControl, usersEmailDuplicates, null, true, true); - } else { - ctrl = null; - } - return ctrl; - } - - private Controller getController(UserRequest ureq, Organisation organisation) { SearchIdentityParams predefinedQuery = SearchIdentityParams.organisation(organisation, Identity.STATUS_VISIBLE_LIMIT); return createUserSearchController(ureq, getWindowControl(), predefinedQuery); @@ -468,7 +459,16 @@ public class UserAdminMainController extends MainLayoutBasicController implement private void buildTreeOrganisationSubMenu(GenericTreeNode accessNode) { List<Organisation> organisations; if(userManagerOrganisations != null) { - organisations = new ArrayList<>(userManagerOrganisations); + organisations = new ArrayList<>(); + List<Organisation> allOrganisations = organisationService.getOrganisations(); + for(Organisation organisation:allOrganisations) { + String path = organisation.getMaterializedPathKeys(); + for(Organisation userManagerOrganisation:userManagerOrganisations) { + if(path.startsWith(userManagerOrganisation.getMaterializedPathKeys())) { + organisations.add(organisation); + } + } + } } else { organisations = organisationService.getOrganisations(); } @@ -484,8 +484,8 @@ public class UserAdminMainController extends MainLayoutBasicController implement }); Organisation parentOrganisation = organisation.getParent(); - if(parentOrganisation == null) { - //this is a root + if(parentOrganisation == null || !keytoOrganisations.containsKey(parentOrganisation.getKey())) { + //this is a root, or the user has not access to parent accessNode.addChild(node); } else { Long parentKey = parentOrganisation.getKey(); @@ -532,8 +532,10 @@ public class UserAdminMainController extends MainLayoutBasicController implement private void buildTreeQueriesSubMenu(GenericTreeNode queriesNode) { appendNode("menu.userswithoutgroup", "menu.userswithoutgroup.alt", "userswithoutgroup", "o_sel_useradmin_userswithoutgroup", queriesNode); - appendNode("menu.users.without.email", "menu.users.without.email.alt", "userswithoutemail", "o_sel_useradmin_userswithoutemail", queriesNode); - appendNode("menu.users.email.duplicate", "menu.users.email.duplicate.alt", "usersemailduplicates", "o_sel_useradmin_usersemailduplicates", queriesNode); + if(isOlatAdmin) { + appendNode("menu.users.without.email", "menu.users.without.email.alt", "userswithoutemail", "o_sel_useradmin_userswithoutemail", queriesNode); + appendNode("menu.users.email.duplicate", "menu.users.email.duplicate.alt", "usersemailduplicates", "o_sel_useradmin_usersemailduplicates", queriesNode); + } appendNode("menu.created.lastweek", "menu.created.lastweek.alt", "created.lastweek", "o_sel_useradmin_createdlastweek", queriesNode); appendNode("menu.created.lastmonth", "menu.created.lastmonth.alt", "created.lastmonth", "o_sel_useradmin_createdlastmonth", queriesNode); appendNode("menu.created.sixmonth", "menu.created.sixmonth.alt", "created.sixmonth", "o_sel_useradmin_createdsixmonth", queriesNode); diff --git a/src/main/java/org/olat/user/ui/admin/UserSearchDataSource.java b/src/main/java/org/olat/user/ui/admin/UserSearchDataSource.java index bb5057f5f80..7c596a47315 100644 --- a/src/main/java/org/olat/user/ui/admin/UserSearchDataSource.java +++ b/src/main/java/org/olat/user/ui/admin/UserSearchDataSource.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.user.ui.admin; import java.util.Collections; diff --git a/src/main/java/org/olat/user/ui/admin/UserSearchTableController.java b/src/main/java/org/olat/user/ui/admin/UserSearchTableController.java index c94b67a172e..9917d8f6efe 100644 --- a/src/main/java/org/olat/user/ui/admin/UserSearchTableController.java +++ b/src/main/java/org/olat/user/ui/admin/UserSearchTableController.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.user.ui.admin; import java.util.Collections; diff --git a/src/main/java/org/olat/user/ui/admin/UserSearchTableModel.java b/src/main/java/org/olat/user/ui/admin/UserSearchTableModel.java index bd4a19635e3..5e9c347491f 100644 --- a/src/main/java/org/olat/user/ui/admin/UserSearchTableModel.java +++ b/src/main/java/org/olat/user/ui/admin/UserSearchTableModel.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.user.ui.admin; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataSourceModel; diff --git a/src/main/java/org/olat/user/ui/organisation/OrganisationUserManagementController.java b/src/main/java/org/olat/user/ui/organisation/OrganisationUserManagementController.java index 571494ada9f..32158f4c4f1 100644 --- a/src/main/java/org/olat/user/ui/organisation/OrganisationUserManagementController.java +++ b/src/main/java/org/olat/user/ui/organisation/OrganisationUserManagementController.java @@ -49,6 +49,7 @@ import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; @@ -56,6 +57,8 @@ import org.olat.core.id.Identity; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; import org.olat.user.ui.organisation.OrganisationUserManagementTableModel.MemberCols; +import org.olat.user.ui.organisation.component.RoleFlexiCellRenderer; +import org.olat.user.ui.organisation.event.RoleEvent; import org.springframework.beans.factory.annotation.Autowired; /** @@ -70,7 +73,7 @@ public class OrganisationUserManagementController extends FormBasicController { public static final String usageIdentifyer = UserTableDataModel.class.getCanonicalName(); private FlexiTableElement tableEl; - private FormLink addUserManagerButton; + private FormLink addMemberButton; private FormLink removeMembershipButton; private OrganisationUserManagementTableModel tableModel; @@ -78,6 +81,9 @@ public class OrganisationUserManagementController extends FormBasicController { private UserSearchController userSearchCtrl; private DialogBoxController confirmRemoveCtrl; + private RoleListController roleListCtrl; + private CloseableCalloutWindowController calloutCtrl; + private Organisation organisation; private final boolean membersManaged; private final boolean isAdministrativeUser; @@ -108,8 +114,9 @@ public class OrganisationUserManagementController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { if(!membersManaged) { - addUserManagerButton = uifactory.addFormLink("add.user.manager", formLayout, Link.BUTTON); - addUserManagerButton.setIconLeftCSS("o_icon o_icon-fw o_icon_add_member"); + addMemberButton = uifactory.addFormLink("add.member", formLayout, Link.BUTTON); + addMemberButton.setIconLeftCSS("o_icon o_icon-fw o_icon_add_member"); + addMemberButton.setIconRightCSS("o_icon o_icon_caret"); removeMembershipButton = uifactory.addFormLink("remove.memberships", formLayout, Link.BUTTON); } @@ -127,7 +134,7 @@ public class OrganisationUserManagementController extends FormBasicController { colIndex++; } - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(MemberCols.role)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(MemberCols.role, new RoleFlexiCellRenderer(getTranslator()))); tableModel = new OrganisationUserManagementTableModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout); @@ -175,7 +182,14 @@ public class OrganisationUserManagementController extends FormBasicController { } cmc.deactivate(); cleanUp(); - } else if(cmc == source) { + } else if(roleListCtrl == source) { + calloutCtrl.deactivate(); + cleanUp(); + if(event instanceof RoleEvent) { + RoleEvent re = (RoleEvent)event; + doSearchMember(ureq, re.getSelectedRole()); + } + } else if(cmc == source || calloutCtrl == source) { cleanUp(); } super.event(ureq, source, event); @@ -184,9 +198,11 @@ public class OrganisationUserManagementController extends FormBasicController { private void cleanUp() { removeAsListenerAndDispose(confirmRemoveCtrl); removeAsListenerAndDispose(userSearchCtrl); + removeAsListenerAndDispose(calloutCtrl); removeAsListenerAndDispose(cmc); confirmRemoveCtrl = null; userSearchCtrl = null; + calloutCtrl = null; cmc = null; } @@ -197,8 +213,8 @@ public class OrganisationUserManagementController extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - if(addUserManagerButton == source) { - doSearchMember(ureq, OrganisationRoles.usermanager); + if(addMemberButton == source) { + doRolleCallout(ureq); } else if(removeMembershipButton == source) { doConfirmRemoveAllMemberships(ureq); } @@ -227,6 +243,19 @@ public class OrganisationUserManagementController extends FormBasicController { loadModel(true); } + private void doRolleCallout(UserRequest ureq) { + removeAsListenerAndDispose(calloutCtrl); + removeAsListenerAndDispose(roleListCtrl); + + String title = translate("add.member"); + roleListCtrl = new RoleListController(ureq, getWindowControl(), OrganisationRoles.values()); + listenTo(roleListCtrl); + + calloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), roleListCtrl.getInitialComponent(), addMemberButton, title, true, null); + listenTo(calloutCtrl); + calloutCtrl.activate(); + } + private void doSearchMember(UserRequest ureq, OrganisationRoles role) { if(userSearchCtrl != null) return; @@ -234,8 +263,8 @@ public class OrganisationUserManagementController extends FormBasicController { userSearchCtrl.setUserObject(role); listenTo(userSearchCtrl); - cmc = new CloseableModalController(getWindowControl(), translate("close"), userSearchCtrl.getInitialComponent(), - true, translate("add.role." + role)); + String title = translate("add.member.role", new String[] { translate(role.name()) }); + cmc = new CloseableModalController(getWindowControl(), translate("close"), userSearchCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } diff --git a/src/main/java/org/olat/user/ui/organisation/OrganisationsStructureAdminController.java b/src/main/java/org/olat/user/ui/organisation/OrganisationsStructureAdminController.java index 60de54957f6..fd6f1374443 100644 --- a/src/main/java/org/olat/user/ui/organisation/OrganisationsStructureAdminController.java +++ b/src/main/java/org/olat/user/ui/organisation/OrganisationsStructureAdminController.java @@ -222,10 +222,12 @@ public class OrganisationsStructureAdminController extends FormBasicController i if(createOrganisationButton == source) { doCreateOrganisation(ureq); } else if(tableEl == source) { - SelectionEvent se = (SelectionEvent)event; - if("select".equals(se.getCommand())) { - OrganisationRow row = model.getObject(se.getIndex()); - doSelectOrganisation(ureq, row); + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + if("select".equals(event.getCommand())) { + OrganisationRow row = model.getObject(se.getIndex()); + doSelectOrganisation(ureq, row); + } } } else if (source instanceof FormLink) { FormLink link = (FormLink)source; diff --git a/src/main/java/org/olat/user/ui/organisation/RoleListController.java b/src/main/java/org/olat/user/ui/organisation/RoleListController.java new file mode 100644 index 00000000000..a8005a306c1 --- /dev/null +++ b/src/main/java/org/olat/user/ui/organisation/RoleListController.java @@ -0,0 +1,80 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.user.ui.organisation; + +import java.util.ArrayList; +import java.util.List; + +import org.olat.basesecurity.OrganisationRoles; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.user.ui.organisation.event.RoleEvent; + +/** + * + * Initial date: 29 mars 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RoleListController extends BasicController { + + private final VelocityContainer mainVC; + + public RoleListController(UserRequest ureq, WindowControl wControl, OrganisationRoles[] roles) { + super(ureq, wControl); + + mainVC = createVelocityContainer("tools"); + List<String> links = new ArrayList<>(roles.length); + for(OrganisationRoles role:roles) { + addLink(role, links); + } + mainVC.contextPut("links", links); + putInitialPanel(mainVC); + } + + private Link addLink(OrganisationRoles role, List<String> links) { + Link link = LinkFactory.createLink(role.name(), role.name(), getTranslator(), mainVC, this, Link.LINK); + link.setUserObject(role); + mainVC.put(role.name(), link); + links.add(role.name()); + return link; + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + if(source instanceof Link) { + Link link = (Link)source; + if(link.getUserObject() instanceof OrganisationRoles) { + fireEvent(ureq, new RoleEvent((OrganisationRoles)link.getUserObject())); + } + } + } +} diff --git a/src/main/java/org/olat/user/ui/organisation/_content/organisation_user_mgmt.html b/src/main/java/org/olat/user/ui/organisation/_content/organisation_user_mgmt.html index f600d9a0ede..84540626779 100644 --- a/src/main/java/org/olat/user/ui/organisation/_content/organisation_user_mgmt.html +++ b/src/main/java/org/olat/user/ui/organisation/_content/organisation_user_mgmt.html @@ -1,6 +1,6 @@ -#if($r.available("add.user.manager")) +#if($r.available("add.member")) <div class="o_button_group o_button_group_right"> - $r.render("add.user.manager") + $r.render("add.member") </div> #end $r.render("table") diff --git a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties index 258824d0895..cc4f731e588 100644 --- a/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/user/ui/organisation/_i18n/LocalStrings_de.properties @@ -1,6 +1,16 @@ #Fri Dec 08 12:29:12 CET 2017 -add.role.usermanager=$\:add.user.manager -add.user.manager=Benutzerverwalter hinzufügen +usermanager=Benutzerverwalter +sysadmin=Systemadministrator +administrator=Administrator +learnresourcemanager=Lernressourcenverwalter +groupmanager=Gruppenverwalter +poolmanager=Poolverwalter +curriculummanager=Curriculumverwalter +author=Author +user=Benutzer +guest=Gast +add.member=Benutzer hinzufügen +add.member.role=Benutzer hinzufügen als "{0}" admin.description=Organisationen verwalten admin.menu.title=Organisationen admin.menu.title.alt=Organisationen diff --git a/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java b/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java new file mode 100644 index 00000000000..e3077c88c8c --- /dev/null +++ b/src/main/java/org/olat/user/ui/organisation/component/RoleFlexiCellRenderer.java @@ -0,0 +1,60 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.user.ui.organisation.component; + +import org.olat.basesecurity.OrganisationRoles; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; + +/** + * + * Initial date: 29 mars 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RoleFlexiCellRenderer implements FlexiCellRenderer { + + private final Translator translator; + + public RoleFlexiCellRenderer(Translator translator) { + this.translator = translator; + } + + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, + URLBuilder ubu, Translator trans) { + if(cellValue instanceof OrganisationRoles) { + OrganisationRoles role = (OrganisationRoles)cellValue; + target.append(translator.translate(role.name())); + } else if(cellValue instanceof String) { + String val = (String)cellValue; + if(OrganisationRoles.valid(val)) { + target.append(translator.translate(OrganisationRoles.valueOf(val).name())); + } else { + target.append(StringHelper.escapeHtml(val)); + } + } + } +} diff --git a/src/main/java/org/olat/user/ui/organisation/event/RoleEvent.java b/src/main/java/org/olat/user/ui/organisation/event/RoleEvent.java new file mode 100644 index 00000000000..078463e2556 --- /dev/null +++ b/src/main/java/org/olat/user/ui/organisation/event/RoleEvent.java @@ -0,0 +1,46 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.user.ui.organisation.event; + +import org.olat.basesecurity.OrganisationRoles; +import org.olat.core.gui.control.Event; + +/** + * + * Initial date: 29 mars 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RoleEvent extends Event { + + private static final long serialVersionUID = -8941881101301854057L; + public static final String SELECT_ROLE = "select-role"; + + private final OrganisationRoles selectedRole; + + public RoleEvent(OrganisationRoles selectedRole) { + super(SELECT_ROLE); + this.selectedRole = selectedRole; + } + + public OrganisationRoles getSelectedRole() { + return selectedRole; + } +} diff --git a/src/test/java/org/olat/restapi/NotificationsTest.java b/src/test/java/org/olat/restapi/NotificationsTest.java index ecc069e3191..319cad3982a 100644 --- a/src/test/java/org/olat/restapi/NotificationsTest.java +++ b/src/test/java/org/olat/restapi/NotificationsTest.java @@ -54,6 +54,8 @@ import org.codehaus.jackson.type.TypeReference; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.olat.basesecurity.OrganisationRoles; +import org.olat.basesecurity.OrganisationService; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; @@ -65,6 +67,8 @@ import org.olat.core.commons.services.notifications.restapi.vo.PublisherVO; import org.olat.core.commons.services.notifications.restapi.vo.SubscriptionInfoVO; import org.olat.core.commons.services.notifications.restapi.vo.SubscriptionListItemVO; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; @@ -96,6 +100,8 @@ import org.springframework.beans.factory.annotation.Autowired; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class NotificationsTest extends OlatJerseyTestCase { + + private static final OLog log = Tracing.createLoggerFor(NotificationsTest.class); private static Identity userSubscriberId; private static Identity userAndForumSubscriberId; @@ -106,11 +112,15 @@ public class NotificationsTest extends OlatJerseyTestCase { @Autowired private DB dbInstance; @Autowired + private OrganisationService organisationService; + @Autowired private BusinessGroupService businessGroupService; @Autowired private NotificationsManager notificationManager; @Autowired private RepositoryManager repositoryManager; + @Autowired + private UsersSubscriptionManager usersSubscriptionManager; @Before public void setUp() throws Exception { @@ -119,9 +129,11 @@ public class NotificationsTest extends OlatJerseyTestCase { userSubscriberId = JunitTestHelper.createAndPersistIdentityAsUser("rest-notifications-test-1"); userAndForumSubscriberId = JunitTestHelper.createAndPersistIdentityAsUser("rest-notifications-test-2"); JunitTestHelper.createAndPersistIdentityAsUser("rest-notifications-test-3"); + //for the news + organisationService.addMember(userSubscriberId, OrganisationRoles.usermanager); - SubscriptionContext subContext = UsersSubscriptionManager.getInstance().getNewUsersSubscriptionContext(); - PublisherData publisherData = UsersSubscriptionManager.getInstance().getNewUsersPublisherData(); + SubscriptionContext subContext = usersSubscriptionManager.getNewUsersSubscriptionContext(); + PublisherData publisherData = usersSubscriptionManager.getNewUsersPublisherData(); if(!notificationManager.isSubscribed(userSubscriberId, subContext)) { notificationManager.subscribe(userSubscriberId, subContext, publisherData); } @@ -487,11 +499,12 @@ public class NotificationsTest extends OlatJerseyTestCase { private String addFile(VFSContainer folder) throws IOException { String filename = UUID.randomUUID().toString(); VFSLeaf file = folder.createChildLeaf(filename + ".jpg"); - OutputStream out = file.getOutputStream(true); - InputStream in = UserMgmtTest.class.getResourceAsStream("portrait.jpg"); - IOUtils.copy(in, out); - IOUtils.closeQuietly(in); - IOUtils.closeQuietly(out); + try(OutputStream out = file.getOutputStream(true); + InputStream in = UserMgmtTest.class.getResourceAsStream("portrait.jpg")) { + IOUtils.copy(in, out); + } catch(IOException e) { + log.error("", e); + } return file.getName(); } -- GitLab