1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.admincentral;
35
36 import static info.magnolia.ui.api.app.AppInstanceController.HEADER_APPS;
37
38 import info.magnolia.context.Context;
39 import info.magnolia.event.EventBus;
40 import info.magnolia.i18nsystem.SimpleTranslator;
41 import info.magnolia.objectfactory.ComponentProvider;
42 import info.magnolia.ui.AlertBuilder;
43 import info.magnolia.ui.api.app.launcherlayout.AppLauncherLayout;
44 import info.magnolia.ui.api.app.launcherlayout.AppLauncherLayoutManager;
45 import info.magnolia.ui.api.event.AdmincentralEventBus;
46 import info.magnolia.ui.api.location.DefaultLocation;
47 import info.magnolia.ui.api.location.LocationChangedEvent;
48 import info.magnolia.ui.api.location.LocationController;
49 import info.magnolia.ui.framework.message.LocalMessageDispatcher;
50 import info.magnolia.ui.framework.message.MessagesManager;
51 import info.magnolia.ui.framework.task.LocalTaskDispatcher;
52 import info.magnolia.ui.framework.task.LocalTaskDispatcherManager;
53 import info.magnolia.usagemetrics.PrivacyNotice;
54
55 import java.util.Arrays;
56
57 import javax.inject.Inject;
58 import javax.inject.Named;
59
60 import org.apache.commons.lang3.StringUtils;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import com.vaadin.server.Page;
65 import com.vaadin.ui.Notification;
66 import com.vaadin.ui.UI;
67
68
69
70
71 public class ResurfaceUIPresenter {
72
73 private static final Logger log = LoggerFactory.getLogger(ResurfaceUIPresenter.class);
74
75 private final MessagesManager messagesManager;
76 private final LocalMessageDispatcher messageDispatcher;
77 private final LocalTaskDispatcher taskDispatcher;
78 private final LocalTaskDispatcherManager taskDispatcherManager;
79 private final LocationController locationController;
80 private final PrivacyNotice privacyNotice;
81 private final SimpleTranslator i18n;
82 private final AppLauncherLayout userLayout;
83 private final String userName;
84
85 @Inject
86 public ResurfaceUIPresenter(ComponentProvider componentProvider, AppLauncherLayoutManager appLauncherLayoutManager,
87 MessagesManager messagesManager, LocalTaskDispatcherManager taskDispatcherManager,
88 SimpleTranslator i18n, Context context, LocationController locationController,
89 PrivacyNotice privacyNotice, @Named(AdmincentralEventBus.NAME) EventBus eventBus, UI ui) {
90
91 this.userName = context.getUser().getName();
92
93 this.messagesManager = messagesManager;
94 this.messageDispatcher = componentProvider.newInstance(LocalMessageDispatcher.class, ui);
95 this.messagesManager.registerMessagesListener(userName, messageDispatcher);
96
97 this.taskDispatcherManager = taskDispatcherManager;
98 this.taskDispatcher = componentProvider.newInstance(LocalTaskDispatcher.class, ui);
99 this.taskDispatcherManager.registerLocalTasksListener(userName, taskDispatcher);
100
101 this.locationController = locationController;
102 this.userLayout = appLauncherLayoutManager.getLayoutForUser(context.getUser());
103
104 this.privacyNotice = privacyNotice;
105 this.i18n = i18n;
106
107 UI.getCurrent().setErrorHandler(new AdmincentralErrorHandler(messagesManager, i18n));
108 handleLocationChange(eventBus);
109 }
110
111 void start() {
112 String initialFragment = UI.getCurrent().getPage().getUriFragment();
113 checkAndNavigate(initialFragment);
114 this.showOnFirstLogin();
115 }
116
117
118
119
120
121 void stop() {
122 messagesManager.unregisterMessagesListener(userName, messageDispatcher);
123 taskDispatcherManager.unregisterLocalTasksListener(userName, taskDispatcher);
124 }
125
126
127
128
129
130 private void handleLocationChange(EventBus eventBus) {
131 Page.getCurrent().addPopStateListener(event -> {
132 String fragment = event.getPage().getUriFragment();
133 checkAndNavigate(fragment);
134 });
135
136 eventBus.addHandler(LocationChangedEvent.class, event -> {
137
138
139 if (StringUtils.isBlank(event.getNewLocation().toString())) {
140 Page.getCurrent().reload();
141 } else {
142 Page.getCurrent().setUriFragment(event.getNewLocation().toString());
143 }
144 });
145 }
146
147 private void checkAndNavigate(String fragment) {
148 DefaultLocation newLocation = fragment != null ? new DefaultLocation(fragment) : new DefaultLocation();
149
150
151 if (userLayout.containsApp(newLocation.getAppName()) || isHeaderApp(newLocation.getAppName())) {
152 locationController.goTo(newLocation);
153 } else {
154 log.debug("Denying user {} request to open app {} without permissions", userName, newLocation.getAppName());
155 }
156 }
157
158 private boolean isHeaderApp(String appName) {
159
160
161 return Arrays.stream(HEADER_APPS)
162 .anyMatch(headerAppName -> headerAppName.equalsIgnoreCase(appName));
163 }
164
165 private void showOnFirstLogin() {
166 if (!privacyNotice.currentUserHasAckedPrivacyNotice()) {
167
168
169 String aOpeningTag = "<a href=\"http://mgnl.io/privacy\" target=\"_blank\">";
170 AlertBuilder.alert(i18n.translate("admincentral.privacy.notice.title"))
171 .withLevel(Notification.Type.HUMANIZED_MESSAGE)
172 .withBody(i18n.translate("admincentral.privacy.notice.body", aOpeningTag, "</a>"))
173 .withOkButtonCaption("OK")
174 .buildAndOpen();
175 }
176 privacyNotice.storePrivacyNoticeAcknowledgment();
177 }
178 }