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.setup;
35
36 import info.magnolia.cms.security.MgnlUserManager;
37 import info.magnolia.cms.security.Permission;
38 import info.magnolia.commands.impl.MarkNodeAsDeletedCommand;
39 import info.magnolia.jcr.util.NodeTypes;
40 import info.magnolia.module.AbstractModuleVersionHandler;
41 import info.magnolia.module.InstallContext;
42 import info.magnolia.module.delta.AddURIPermissionTask;
43 import info.magnolia.module.delta.AddUsersPermissionTask;
44 import info.magnolia.module.delta.ArrayDelegateTask;
45 import info.magnolia.module.delta.BootstrapConditionally;
46 import info.magnolia.module.delta.BootstrapSingleModuleResource;
47 import info.magnolia.module.delta.BootstrapSingleResource;
48 import info.magnolia.module.delta.CheckAndModifyPropertyValueTask;
49 import info.magnolia.module.delta.Condition;
50 import info.magnolia.module.delta.DeltaBuilder;
51 import info.magnolia.module.delta.FindAndChangeTemplateIdTask;
52 import info.magnolia.module.delta.FixUserRolePermissionsPropertyTask;
53 import info.magnolia.module.delta.MoveAndRenamePropertyTask;
54 import info.magnolia.module.delta.NoSameNameSiblingsCondition;
55 import info.magnolia.module.delta.NodeExistsDelegateTask;
56 import info.magnolia.module.delta.OrderFilterBeforeTask;
57 import info.magnolia.module.delta.OrderNodeBeforeTask;
58 import info.magnolia.module.delta.PartialBootstrapTask;
59 import info.magnolia.module.delta.PathExistenceDelegateTask;
60 import info.magnolia.module.delta.PropertyExistsDelegateTask;
61 import info.magnolia.module.delta.PropertyValueDelegateTask;
62 import info.magnolia.module.delta.QueryElementsAndDisplayWarningTask;
63 import info.magnolia.module.delta.RemoveInstallFilesTask;
64 import info.magnolia.module.delta.RemoveNodeTask;
65 import info.magnolia.module.delta.RemovePermissionTask;
66 import info.magnolia.module.delta.SetPropertyTask;
67 import info.magnolia.module.delta.Task;
68 import info.magnolia.module.delta.WarnTask;
69 import info.magnolia.module.delta.WebXmlConditionsUtil;
70 import info.magnolia.module.delta.WorkspaceXmlConditionsUtil;
71 import info.magnolia.repository.RepositoryConstants;
72 import info.magnolia.repository.RepositoryManager;
73 import info.magnolia.setup.for5_0.CheckOrCreateLastActivatedPropertyTask;
74 import info.magnolia.setup.for5_0.ConvertMetaDataUpdateTask;
75 import info.magnolia.setup.for5_0.Register50NodeTypeTask;
76 import info.magnolia.setup.for5_0.RemoveMetaDataInNodeTypeDefinitionTask;
77 import info.magnolia.setup.for5_2.AddActivatableMixinForContentNodeTask;
78 import info.magnolia.setup.for5_2.GrantReadPermissionToRolesTask;
79 import info.magnolia.setup.for5_2.IsNotAProblematicEnvironmentCondition;
80 import info.magnolia.setup.for5_2.RemoveOpenWFEPermissionsTask;
81 import info.magnolia.setup.initial.GenericTasks;
82
83 import java.util.ArrayList;
84 import java.util.Arrays;
85 import java.util.List;
86
87 import javax.inject.Inject;
88 import javax.jcr.ImportUUIDBehavior;
89
90 import com.google.common.collect.Lists;
91
92
93
94
95
96 public class CoreModuleVersionHandler extends AbstractModuleVersionHandler {
97 public static final String BOOTSTRAP_AUTHOR_INSTANCE_PROPERTY = "magnolia.bootstrap.authorInstance";
98 public static final String SECURITY_BASE_ROLE = "security-base";
99
100
101 private final BootstrapConditionally auditTrailManagerTask = new BootstrapConditionally("New auditory log configuration", "Install new configuration for auditory log manager.", "/mgnl-bootstrap/core/config.server.auditLogging.xml");
102 private final BootstrapSingleResource bootstrapWebContainerResources = new BootstrapSingleResource("Web container resources configuration", "Global configuration which resources are not meant to be handled by Magnolia. For instance JSP files.", "/mgnl-bootstrap/core/config.server.webContainerResources.xml");
103 private final BootstrapSingleModuleResource bootstrapChannelManagement = new BootstrapSingleModuleResource("ChannelManagement configuration", "", "config.server.rendering.channelManagement.xml");
104
105 private final BootstrapSingleModuleResource bootstrapChannelFilter = new BootstrapSingleModuleResource("ChannelFilter configuration", "", "config.server.filters.channel.xml");
106 private final Task placeChannelBeforeLogout = new OrderFilterBeforeTask("channel", new String[]{"logout"});
107
108 private final Task removeObsoleteInstallFiles = new RemoveInstallFilesTask("Remove obsolete dms templates install files", "templates/dms");
109
110 private final RepositoryManager repositoryManager;
111
112
113
114
115 protected static List<String> PERMISSIONS_FOR_LEGACY_PAGES = Arrays.asList(
116 "/.magnolia/pages/messages*",
117 "/.magnolia/pages/installedModulesList*",
118 "/.magnolia/pages/jcrUtils*",
119 "/.magnolia/pages/configuration*",
120 "/.magnolia/pages/logViewer*",
121 "/.magnolia/pages/sendMail*",
122 "/.magnolia/pages/users*",
123 "/.magnolia/pages/activationTools*",
124 "/.magnolia/pages/activationMonitor*",
125 "/.magnolia/pages/groovyInteractiveConsole*",
126 "/.magnolia/pages/migrationReport*",
127 "/.magnolia/pages/backup*",
128 "/.magnolia/pages/allModulesList*",
129 "/.magnolia/pages/cacheTools*",
130 "/.magnolia/pages/flows*",
131 "/.magnolia/pages/import*",
132 "/.magnolia/pages/export*",
133 "/.magnolia/pages/permission*",
134 "/.magnolia/pages/developmentUtils*"
135 );
136
137 protected Task updateSecurityBaseRolePermissions() {
138 ArrayDelegateTask permissionsTask = new ArrayDelegateTask("Update security-base role", "Disallows access to some sensitive URIs and grants basic access to AdminCentral.");
139 for (String path : PERMISSIONS_FOR_LEGACY_PAGES) {
140 permissionsTask.addTask(new RemovePermissionTask("", SECURITY_BASE_ROLE, "uri", path, AddURIPermissionTask.DENY));
141 }
142 permissionsTask.addTask(new RemovePermissionTask("", SECURITY_BASE_ROLE, RepositoryConstants.USER_ROLES, "/" + SECURITY_BASE_ROLE, Permission.READ));
143 return permissionsTask;
144 }
145
146 @Inject
147 public CoreModuleVersionHandler(RepositoryManager repositoryManager) {
148 super();
149 this.repositoryManager = repositoryManager;
150
151 register(DeltaBuilder.checkPrecondition("4.5", "5.0"));
152
153 register(DeltaBuilder.update("4.5.2", "")
154 .addTask(new PropertyExistsDelegateTask("Fix property name", "", RepositoryConstants.CONFIG, "/server/security/userManagers/system", "realName", new MoveAndRenamePropertyTask("Fix propertyName", "/server/security/userManagers/system", "realName", "/server/security/userManagers/system", "realmName")))
155 .addTask(new PropertyExistsDelegateTask("Fix property name", "", RepositoryConstants.CONFIG, "/server/security/userManagers/admin", "realName", new MoveAndRenamePropertyTask("Fix propertyName", "/server/security/userManagers/admin", "realName", "/server/security/userManagers/admin", "realmName"))));
156
157 register((DeltaBuilder.update("4.5.9", ""))
158 .addTask(new NodeExistsDelegateTask("AuditLogging configurations", "Add auditLogging configurations for delete action", "config", "/server/auditLogging/logConfigurations/delete", null, new PartialBootstrapTask("", "", "/mgnl-bootstrap/core/config.server.auditLogging.xml", "/auditLogging/logConfigurations/delete", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)))
159 .addTask(new CheckAndModifyPropertyValueTask("AuditLogging configurations", "Change auditLogging class", "config", "/server/auditLogging", "class", "info.magnolia.logging.AuditLoggingManager", "info.magnolia.audit.AuditLoggingManager")));
160
161 register(DeltaBuilder.update("5.0", "")
162 .addTask(new Register50NodeTypeTask("Register the new M5 node Type", "", RepositoryConstants.CONFIG))
163 .addTask(new RemoveMetaDataInNodeTypeDefinitionTask("Un register the metaData child node", "", RepositoryConstants.CONFIG))
164 .addTask(new ConvertMetaDataUpdateTask("Convert MetaData Task", "Remove the metaData sub node and replace them with mixIn when appropriate"))
165 .addTask(new RemoveNodeTask("Remove PageEditorServlet", "Remove obsolete PageEditorServlet configuration.", RepositoryConstants.CONFIG, "/server/filters/servlets/PageEditorServlet"))
166 .addTask(new RemoveNodeTask("Remove obsolete 'templating-editor' configuration", "", RepositoryConstants.CONFIG, "/modules/magnolia-templating-editor"))
167 .addTask(new PartialBootstrapTask("Bootstrap link transformers", "Bootstrap 'server/rendering/linkManagement/transformers", "/mgnl-bootstrap/core/config.server.rendering.linkManagement.xml", "/linkManagement/transformers")));
168 register((DeltaBuilder.update("5.0.1", ""))
169 .addTask(new CheckAndModifyPropertyValueTask("MIMEMapping", "Change xsl extension mime-type from text/xml to application/xml", RepositoryConstants.CONFIG, "/server/MIMEMapping/xsl", "mime-type", "text/xml", "application/xml"))
170 .addTask(new CheckAndModifyPropertyValueTask("MIMEMapping", "Change xml extension mime-type from text/xml to application/xml", RepositoryConstants.CONFIG, "/server/MIMEMapping/xml", "mime-type", "text/xml", "application/xml")));
171 register((DeltaBuilder.update("5.0.3", ""))
172 .addTask(new PartialBootstrapTask("JSON", "Add JSON mime-type", "/mgnl-bootstrap/core/config.server.MIMEMapping.xml", "/MIMEMapping/json")));
173 register((DeltaBuilder.update("5.1", ""))
174 .addTask(new WarnTask("respectOrderDocument parameter", "As of Magnolia 5.1, the respectOrderDocument parameter has been reintroduced in repo config files and set to true by default. You will need to set it manually for each workspace in your installation. Please, refer to the release notes for more details."))
175 .addTask(new RemoveNodeTask("Remove intercept filter", "Removes no longer used intercept filter.", RepositoryConstants.CONFIG, "/server/filters/cms/intercept")));
176 register((DeltaBuilder.update("5.1.1", ""))
177 .addTask(new NodeExistsDelegateTask("Set mgnl:lastActivated date of the user superuser", "Set mgnl:lastActivated date of the user superuser (if not set yet)", RepositoryConstants.USERS, "/system/superuser",
178 new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USERS, "/system/superuser")))
179 .addTask(new NodeExistsDelegateTask("Set mgnl:lastActivated date of the user anonymous", "Set mgnl:lastActivated date of the user anonymous (if not set yet)", RepositoryConstants.USERS, "/system/anonymous",
180 new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USERS, "/system/anonymous")))
181 .addTask(new NodeExistsDelegateTask("Set mgnl:lastActivated date of the superuser role", "Set mgnl:lastActivated date of the superuser role (if not set yet)", RepositoryConstants.USER_ROLES, "/superuser",
182 new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/superuser")))
183 .addTask(new NodeExistsDelegateTask("Set mgnl:lastActivated date of the anonymous role", "Set mgnl:lastActivated date of the anonymous role (if not set yet)", RepositoryConstants.USER_ROLES, "/anonymous",
184 new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/anonymous")))
185 .addTask(new NodeExistsDelegateTask("Set mgnl:lastActivated date of the security-base role", "Set mgnl:lastActivated date of the security-base role (if not set yet)", RepositoryConstants.USER_ROLES, "/security-base",
186 new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/security-base")))
187 .addTask(new FindAndChangeTemplateIdTask("Change template id mgnlDelete", "Change template id mgnlDeleted to ui-admincentral:deleted for all content marked as deleted in website repository", RepositoryConstants.WEBSITE, "mgnlDeleted", MarkNodeAsDeletedCommand.DELETED_NODE_TEMPLATE))
188 .addTask(new FindAndChangeTemplateIdTask("Change template id adminInterface:mgnlDeleted", "Change template id adminInterface:mgnlDeleted to ui-admincentral:deleted for all content marked as deleted in website repository", RepositoryConstants.WEBSITE, "adminInterface:mgnlDeleted", MarkNodeAsDeletedCommand.DELETED_NODE_TEMPLATE)));
189 register((DeltaBuilder.update("5.1.2", ""))
190 .addTask(new ChangeNodeTypeOfSubAppsTask("Change primary node type of subapps", "If primary node type of subapps node is set to " + NodeTypes.Content.NAME + " then change it to " + NodeTypes.ContentNode.NAME))
191 .addTask(new PartialBootstrapTask("Anonymous user", "Change anonymous user permission. He can't have write access to himself.", "/mgnl-bootstrap/core/users.system.anonymous.xml", "/anonymous/acl_users")));
192
193 register((DeltaBuilder.update("5.2.1", ""))
194 .addTask(new RemoveOpenWFEPermissionsTask("Find and remove all openWFE permissions from the userroles workspace", ""))
195 .addTask(new GrantReadPermissionToRolesTask("Set read-permission to role itself", "If a role do not have a read permission to itself, add it")));
196 register((DeltaBuilder.update("5.2.2", ""))
197 .addTask(removeObsoleteInstallFiles)
198 .addTask(new AddActivatableMixinForContentNodeTask("Add the mixIn '" + NodeTypes.Activatable.NAME + "' to the '" + NodeTypes.ContentNode.NAME + "' node type definition", "", RepositoryConstants.CONFIG)));
199 register((DeltaBuilder.update("5.2.3", ""))
200 .addTask(new RemovePermissionTask("Remove 'anonymous' role permission", "anonymous", RepositoryConstants.USER_ROLES, "/anonymous", Permission.READ)));
201
202 register((DeltaBuilder.update("5.3.2", ""))
203 .addTask(new NodeExistsDelegateTask("Add csrfSecurity Filter", "/server/filters/csrfSecurity",
204
205 new PathExistenceDelegateTask("Add csrfSecurity Filter", "", new String[]{"/server/filters/csrfSecurity/bypasses/BypassWhenVaadinRequest"}, new String[]{"/server/filters/csrfSecurity/bypasses/BypassWhenNotInAdminCentral", "/server/filters/csrfSecurity/bypasses/BypassWhenNotAuthenticated", "/server/filters/csrfSecurity/bypasses/BypassWhenNoQueryParameters"},
206 new PartialBootstrapTask("Add csrfSecurity Filter", "", "/mgnl-bootstrap/core/config.server.filters.xml", "/filters/csrfSecurity/bypasses/BypassWhenVaadinRequest", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)),
207
208 new PartialBootstrapTask("Add csrfSecurity Filter", "", "/mgnl-bootstrap/core/config.server.filters.xml", "/filters/csrfSecurity", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)))
209 .addTask(new NodeExistsDelegateTask("Order csrfSecurity Filter", "Put csrfSecurity before uriSecurity Filter.", RepositoryConstants.CONFIG, "/server/filters/uriSecurity",
210 new OrderNodeBeforeTask("Order csrfSecurity Filter", "Put csrfSecurity before uriSecurity Filter.", RepositoryConstants.CONFIG, "/server/filters/csrfSecurity", "uriSecurity"),
211 new WarnTask("CSRF Security Filter is inactive.", "CSRF Security Filter inactive. The installed csrfFilter would normally be ordered before the uriSecurity filter, but could not be moved there as a uriFilter node does not exist in the /server/filters node. The installed csrfFilter must be moved up the filters list manually.")))
212 .addTask(new NodeExistsDelegateTask("Add csrfSecurity Filter", "/server/auditLogging/logConfigurations/security", null,
213 new PartialBootstrapTask("Add 'security' AuditLogging logConfiguration.", "", "/mgnl-bootstrap/core/config.server.auditLogging.xml", "/auditLogging/logConfigurations/security", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW))));
214
215 register((DeltaBuilder.update("5.3.5", ""))
216
217 .addTask(new FixUserRolePermissionsPropertyTask("/superuser")));
218
219 register((DeltaBuilder.update("5.4.1", ""))
220 .addTask(updateSecurityBaseRolePermissions()));
221
222 register((DeltaBuilder.update("5.4.3", ""))
223 .addTask(new PropertyValueDelegateTask("Change MIME mapping of Javascript resources", "/server/MIMEMapping/js", "mime-type", "application/x-javascript", true,
224 new SetPropertyTask("config", "/server/MIMEMapping/js", "mime-type", "application/javascript"))));
225
226 register((DeltaBuilder.update("5.4.5", ""))
227 .addTask(new PartialBootstrapTask("Add mime mapping for .map", "Add mime mapping for .map", "/mgnl-bootstrap/core/config.server.MIMEMapping.xml", "/MIMEMapping/map")));
228
229 register((DeltaBuilder.update("5.4.6", ""))
230 .addTask(new QueryElementsAndDisplayWarningTask("Check SimpleUrlPatterns in user roles",
231 "SimpleUrlPattern no longer misinterprets dots as regular expression wildcard characters. User roles will be checked whether they are affected.",
232 RepositoryConstants.USER_ROLES, "SELECT * FROM [nt:base] WHERE path LIKE '%.%'", NodeTypes.Role.NAME,
233 "SimpleUrlPattern no longer misinterprets dots as regular expression wildcard characters. As a result, the following roles might need your attention:\n%s" +
234 "\nRead more at http://documentation.magnolia-cms.com/display/DOCS/Release+notes+for+Magnolia+5.4.6.",
235 Lists.newArrayList("/rest", "/security-base", "/anonymous", "/forum_ALL-moderator", "/forum_ALL-user", "/forum_ALL-admin", "/public-user-registration-base"))));
236
237 register((DeltaBuilder.update("5.4.7", ""))
238 .addTask(new AddUsersPermissionTask("Allow users to edit their timezone setting", "/", RepositoryConstants.USERS, AddUsersPermissionTask.USER_PATH_REPLACEMENT + "/timezone", Permission.ALL)
239 .exclude(MgnlUserManager.SYSTEM_USER, MgnlUserManager.ANONYMOUS_USER))
240 );
241
242 register(DeltaBuilder.update("5.4.8", "")
243 .addTask(new NodeExistsDelegateTask("If exists, remove legacy log4j servlet", "/server/filters/servlets/log4j", new RemoveNodeTask("", "/server/filters/servlets/log4j"))));
244 }
245
246 @Override
247 protected List<Task> getBasicInstallTasks(InstallContext ctx) {
248 final List<Task> tasks = new ArrayList<>();
249 tasks.addAll(GenericTasks.genericTasksForNewInstallation());
250 tasks.add(auditTrailManagerTask);
251 tasks.add(bootstrapWebContainerResources);
252 tasks.add(new BootstrapConditionally("Security", "Bootstraps security-base role.", "/mgnl-bootstrap/core/userroles.security-base.xml"));
253
254 tasks.add(new HashUsersPasswords());
255 tasks.add(bootstrapChannelManagement);
256 tasks.add(bootstrapChannelFilter);
257 tasks.add(placeChannelBeforeLogout);
258
259 return tasks;
260 }
261
262 @Override
263 protected List<Condition> getInstallConditions() {
264 final List<Condition> conditions = new ArrayList<>();
265
266 conditions.add(new IsNotAProblematicEnvironmentCondition());
267
268 final WebXmlConditionsUtil u = new WebXmlConditionsUtil(conditions);
269 u.servletIsNowWrapped("ActivationHandler");
270 u.servletIsNowWrapped("AdminTreeServlet");
271 u.servletIsNowWrapped("classpathspool");
272 u.servletIsNowWrapped("DialogServlet");
273 u.servletIsNowWrapped("PageServlet");
274 u.servletIsNowWrapped("log4j");
275 u.servletIsNowWrapped("FCKEditorSimpleUploadServlet");
276 u.servletIsDeprecated("uuidRequestDispatcher");
277 u.filterIsDeprecated("info.magnolia.cms.filters.MagnoliaManagedFilter", "info.magnolia.cms.filters.MgnlMainFilter");
278 u.filterMustBeRegisteredWithCorrectDispatchers("info.magnolia.cms.filters.MgnlMainFilter");
279 u.listenerIsDeprecated("info.magnolia.cms.servlets.PropertyInitializer", "info.magnolia.cms.servlets.MgnlServletContextListener");
280 u.listenerIsDeprecated("info.magnolia.cms.beans.config.ShutdownManager", "info.magnolia.cms.servlets.MgnlServletContextListener");
281 final WorkspaceXmlConditionsUtil u2 = new WorkspaceXmlConditionsUtil(conditions);
282 u2.textFilterClassesAreNotSet();
283
284 conditions.add(new SystemTmpDirCondition());
285 conditions.add(new NoSameNameSiblingsCondition(repositoryManager));
286
287 return conditions;
288 }
289 }
290