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.Layout;
66 import com.vaadin.ui.Notification;
67 import com.vaadin.ui.UI;
68
69
70
71
72 public class ResurfaceUIPresenter {
73
74 private static final Logger log = LoggerFactory.getLogger(ResurfaceUIPresenter.class);
75
76 private final MessagesManager messagesManager;
77 private final LocalMessageDispatcher messageDispatcher;
78 private final LocalTaskDispatcher taskDispatcher;
79 private final LocalTaskDispatcherManager taskDispatcherManager;
80 private final Context context;
81 private final LocationController locationController;
82 private final ResurfaceUILayout resurfaceUILayout;
83 private final PrivacyNotice privacyNotice;
84 private final SimpleTranslator i18n;
85 private final AppLauncherLayout userLayout;
86 private final String userName;
87
88 @Inject
89 public ResurfaceUIPresenter(ComponentProvider componentProvider, AppLauncherLayoutManager appLauncherLayoutManager,
90 MessagesManager messagesManager, LocalTaskDispatcherManager taskDispatcherManager,
91 SimpleTranslator i18n, Context context, LocationController locationController,
92 ResurfaceUILayout resurfaceUILayout, PrivacyNotice privacyNotice,
93 @Named(AdmincentralEventBus.NAME) EventBus eventBus, UI ui) {
94
95 this.context = context;
96 this.userName = this.context.getUser().getName();
97
98 this.messagesManager = messagesManager;
99 this.messageDispatcher = componentProvider.newInstance(LocalMessageDispatcher.class, ui);
100 this.messagesManager.registerMessagesListener(userName, messageDispatcher);
101
102 this.taskDispatcherManager = taskDispatcherManager;
103 this.taskDispatcher = componentProvider.newInstance(LocalTaskDispatcher.class, ui);
104 this.taskDispatcherManager.registerLocalTasksListener(userName, taskDispatcher);
105
106 this.locationController = locationController;
107 this.userLayout = appLauncherLayoutManager.getLayoutForUser(this.context.getUser());
108
109 this.resurfaceUILayout = resurfaceUILayout;
110 this.privacyNotice = privacyNotice;
111 this.i18n = i18n;
112
113 UI.getCurrent().setErrorHandler(new AdmincentralErrorHandler(messagesManager, i18n));
114 handleLocationChange(eventBus);
115 }
116
117 Layout start() {
118 String initialFragment = UI.getCurrent().getPage().getUriFragment();
119 checkAndNavigate(initialFragment);
120 this.showOnFirstLogin();
121 return resurfaceUILayout;
122 }
123
124
125
126
127
128 void stop() {
129 messagesManager.unregisterMessagesListener(userName, messageDispatcher);
130 taskDispatcherManager.unregisterLocalTasksListener(userName, taskDispatcher);
131 }
132
133
134
135
136
137 private void handleLocationChange(EventBus eventBus) {
138 Page.getCurrent().addPopStateListener(event -> {
139 String fragment = event.getPage().getUriFragment();
140 checkAndNavigate(fragment);
141 });
142
143 eventBus.addHandler(LocationChangedEvent.class, event -> {
144
145
146 if (StringUtils.isBlank(event.getNewLocation().toString())) {
147 Page.getCurrent().reload();
148 } else {
149 Page.getCurrent().setUriFragment(event.getNewLocation().toString());
150 }
151 });
152 }
153
154 private void checkAndNavigate(String fragment) {
155 DefaultLocation newLocation = fragment != null ? new DefaultLocation(fragment) : new DefaultLocation();
156
157
158 if (userLayout.containsApp(newLocation.getAppName()) || isHeaderApp(newLocation.getAppName())) {
159 locationController.goTo(newLocation);
160 } else {
161 log.debug("Denying user {} request to open app {} without permissions", userName, newLocation.getAppName());
162 }
163 }
164
165 private boolean isHeaderApp(String appName) {
166
167
168 return Arrays.stream(HEADER_APPS)
169 .anyMatch(headerAppName -> headerAppName.equalsIgnoreCase(appName));
170 }
171
172 private void showOnFirstLogin() {
173 if (!privacyNotice.currentUserHasAckedPrivacyNotice()) {
174
175
176 String aOpeningTag = "<a href=\"http://mgnl.io/privacy\" target=\"_blank\">";
177 AlertBuilder.alert(i18n.translate("admincentral.privacy.notice.title"))
178 .withLevel(Notification.Type.HUMANIZED_MESSAGE)
179 .withBody(i18n.translate("admincentral.privacy.notice.body", aOpeningTag, "</a>"))
180 .withOkButtonCaption("OK")
181 .buildAndOpen();
182 }
183 privacyNotice.storePrivacyNoticeAcknowledgment();
184 }
185 }