View Javadoc
1   /**
2    * This file Copyright (c) 2003-2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.setup;
35  
36  import info.magnolia.cms.security.Permission;
37  import info.magnolia.commands.impl.MarkNodeAsDeletedCommand;
38  import info.magnolia.jcr.util.NodeNameHelper;
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.FilterOrderingTask;
52  import info.magnolia.module.delta.FindAndChangeTemplateIdTask;
53  import info.magnolia.module.delta.FixUserRolePermissionsPropertyTask;
54  import info.magnolia.module.delta.HasPropertyDelegateTask;
55  import info.magnolia.module.delta.IsModuleInstalledOrRegistered;
56  import info.magnolia.module.delta.MoveAndRenamePropertyTask;
57  import info.magnolia.module.delta.NewPropertyTask;
58  import info.magnolia.module.delta.NoSameNameSiblingsCondition;
59  import info.magnolia.module.delta.NodeExistsDelegateTask;
60  import info.magnolia.module.delta.OrderFilterBeforeTask;
61  import info.magnolia.module.delta.OrderNodeBeforeTask;
62  import info.magnolia.module.delta.PartialBootstrapTask;
63  import info.magnolia.module.delta.PathExistenceDelegateTask;
64  import info.magnolia.module.delta.QueryElementsAndDisplayWarningTask;
65  import info.magnolia.module.delta.RemoveInstallFilesTask;
66  import info.magnolia.module.delta.RemoveNodeTask;
67  import info.magnolia.module.delta.RemovePermissionTask;
68  import info.magnolia.module.delta.RemovePropertyTask;
69  import info.magnolia.module.delta.SetPropertyTask;
70  import info.magnolia.module.delta.Task;
71  import info.magnolia.module.delta.ValueOfPropertyDelegateTask;
72  import info.magnolia.module.delta.WarnTask;
73  import info.magnolia.module.delta.WebXmlConditionsUtil;
74  import info.magnolia.module.delta.WorkspaceXmlConditionsUtil;
75  import info.magnolia.objectfactory.Components;
76  import info.magnolia.repository.RepositoryConstants;
77  import info.magnolia.repository.RepositoryManager;
78  import info.magnolia.setup.for5_0.CheckOrCreateLastActivatedPropertyTask;
79  import info.magnolia.setup.for5_0.ConvertMetaDataUpdateTask;
80  import info.magnolia.setup.for5_0.Register50NodeTypeTask;
81  import info.magnolia.setup.for5_0.RemoveMetaDataInNodeTypeDefinitionTask;
82  import info.magnolia.setup.for5_2.AddActivatableMixinForContentNodeTask;
83  import info.magnolia.setup.for5_2.GrantReadPermissionToRolesTask;
84  import info.magnolia.setup.for5_2.IsNotAProblematicEnvironmentCondition;
85  import info.magnolia.setup.for5_2.RemoveOpenWFEPermissionsTask;
86  import info.magnolia.setup.for6_0.RemoveMIMEIconsTask;
87  import info.magnolia.setup.initial.GenericTasks;
88  
89  import java.util.ArrayList;
90  import java.util.Arrays;
91  import java.util.List;
92  import java.util.UUID;
93  
94  import javax.inject.Inject;
95  import javax.jcr.ImportUUIDBehavior;
96  
97  import com.google.common.collect.Lists;
98  
99  /**
100  * Special VersionHandler for the core module. As it does not extend {@link info.magnolia.module.DefaultModuleVersionHandler} it has a special getBasicInstallTasks(InstallContext) that
101  * e.g. will not automatically bootstrap xml-files placed in mgnl-bootstrap/core.
102  */
103 public class CoreModuleVersionHandler extends AbstractModuleVersionHandler {
104     public static final String BOOTSTRAP_AUTHOR_INSTANCE_PROPERTY = "magnolia.bootstrap.authorInstance";
105     public static final String SECURITY_BASE_ROLE = "security-base";
106 
107     // TODO : why is this a BootstrapConditionally and not a BootstrapSingleResource ?
108     private final BootstrapConditionallyapConditionally">BootstrapConditionally auditTrailManagerTask = new BootstrapConditionally("New auditory log configuration", "Install new configuration for auditory log manager.", "/mgnl-bootstrap/core/config.server.auditLogging.xml");
109     private final BootstrapSingleResourceesource">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");
110     private final BootstrapSingleModuleResourcegleModuleResource">BootstrapSingleModuleResource bootstrapChannelManagement = new BootstrapSingleModuleResource("ChannelManagement configuration", "", "config.server.rendering.channelManagement.xml");
111 
112     private final BootstrapSingleModuleResourcepSingleModuleResource">BootstrapSingleModuleResource bootstrapChannelFilter = new BootstrapSingleModuleResource("ChannelFilter configuration", "", "config.server.filters.channel.xml");
113     private final Task placeChannelBeforeLogout = new OrderFilterBeforeTask("channel", new String[]{"logout"});
114 
115     private final Task removeObsoleteInstallFiles = new RemoveInstallFilesTask("Remove obsolete dms templates install files", "templates/dms");
116 
117     private final RepositoryManager repositoryManager;
118 
119     /**
120      * Cleans up security-base role from no longer valid URis (basically legacy adminInterface pages not yet ported to M5). Also allows basic access to AdminCentral.
121      */
122     protected static List<String> PERMISSIONS_FOR_LEGACY_PAGES = Arrays.asList(
123             "/.magnolia/pages/messages*",
124             "/.magnolia/pages/installedModulesList*",
125             "/.magnolia/pages/jcrUtils*",
126             "/.magnolia/pages/configuration*",
127             "/.magnolia/pages/logViewer*",
128             "/.magnolia/pages/sendMail*",
129             "/.magnolia/pages/users*",
130             "/.magnolia/pages/activationTools*",
131             "/.magnolia/pages/activationMonitor*",
132             "/.magnolia/pages/groovyInteractiveConsole*",
133             "/.magnolia/pages/migrationReport*",
134             "/.magnolia/pages/backup*",
135             "/.magnolia/pages/allModulesList*",
136             "/.magnolia/pages/cacheTools*",
137             "/.magnolia/pages/flows*",
138             "/.magnolia/pages/import*",
139             "/.magnolia/pages/export*",
140             "/.magnolia/pages/permission*",
141             "/.magnolia/pages/developmentUtils*"
142     );
143 
144     protected Task updateSecurityBaseRolePermissions() {
145         ArrayDelegateTaskrrayDelegateTask">ArrayDelegateTask permissionsTask = new ArrayDelegateTask("Update security-base role", "Disallows access to some sensitive URIs and grants basic access to AdminCentral.");
146         for (String path : PERMISSIONS_FOR_LEGACY_PAGES) {
147             permissionsTask.addTask(new RemovePermissionTask("", SECURITY_BASE_ROLE, "uri", path, AddURIPermissionTask.DENY));
148         }
149         permissionsTask.addTask(new RemovePermissionTask("", SECURITY_BASE_ROLE, RepositoryConstants.USER_ROLES, "/" + SECURITY_BASE_ROLE, Permission.READ));
150         return permissionsTask;
151     }
152 
153     @Inject
154     public CoreModuleVersionHandler(RepositoryManager repositoryManager, NodeNameHelper nodeNameHelper) {
155         super();
156         this.repositoryManager = repositoryManager;
157 
158         register(DeltaBuilder.checkPrecondition("4.5", "5.0"));
159 
160         register(DeltaBuilder.update("4.5.2", "")
161                 .addTask(new HasPropertyDelegateTask("Fix property name", "", RepositoryConstants.CONFIG, "/server/security/userManagers/system", "realName", new MoveAndRenamePropertyTask("Fix propertyName", "/server/security/userManagers/system", "realName", "/server/security/userManagers/system", "realmName")))
162                 .addTask(new HasPropertyDelegateTask("Fix property name", "", RepositoryConstants.CONFIG, "/server/security/userManagers/admin", "realName", new MoveAndRenamePropertyTask("Fix propertyName", "/server/security/userManagers/admin", "realName", "/server/security/userManagers/admin", "realmName"))));
163 
164         register((DeltaBuilder.update("4.5.9", ""))
165                 .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)))
166                 .addTask(new CheckAndModifyPropertyValueTask("AuditLogging configurations", "Change auditLogging class", "config", "/server/auditLogging", "class", "info.magnolia.logging.AuditLoggingManager", "info.magnolia.audit.AuditLoggingManager")));
167 
168         register(DeltaBuilder.update("5.0", "")
169                 .addTask(new Register50NodeTypeTask("Register the new M5 node Type", "", RepositoryConstants.CONFIG))
170                 .addTask(new RemoveMetaDataInNodeTypeDefinitionTask("Un register the metaData child node", "", RepositoryConstants.CONFIG))
171                 .addTask(new ConvertMetaDataUpdateTask("Convert MetaData Task", "Remove the metaData sub node and replace them with mixIn when appropriate"))
172                 .addTask(new RemoveNodeTask("Remove PageEditorServlet", "Remove obsolete PageEditorServlet configuration.", RepositoryConstants.CONFIG, "/server/filters/servlets/PageEditorServlet"))
173                 .addTask(new RemoveNodeTask("Remove obsolete 'templating-editor' configuration", "", RepositoryConstants.CONFIG, "/modules/magnolia-templating-editor"))
174                 .addTask(new BootstrapSingleModuleResource("Bootstrap link transformers", "Bootstrap 'server/rendering/linkManagement/transformers", "config.server.rendering.linkManagement.xml", "/linkManagement/transformers")));
175         register((DeltaBuilder.update("5.0.1", ""))
176                 .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"))
177                 .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")));
178         register((DeltaBuilder.update("5.0.3", ""))
179                 .addTask(new BootstrapSingleModuleResource("JSON", "Add JSON mime-type", "config.server.MIMEMapping.xml", "/MIMEMapping/json")));
180         register((DeltaBuilder.update("5.1", ""))
181                 .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."))
182                 .addTask(new RemoveNodeTask("Remove intercept filter", "Removes no longer used intercept filter.", RepositoryConstants.CONFIG, "/server/filters/cms/intercept")));
183         register((DeltaBuilder.update("5.1.1", ""))
184                 .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",
185                         new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USERS, "/system/superuser")))
186                 .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",
187                         new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USERS, "/system/anonymous")))
188                 .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",
189                         new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/superuser")))
190                 .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",
191                         new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/anonymous")))
192                 .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",
193                         new CheckOrCreateLastActivatedPropertyTask("", "", RepositoryConstants.USER_ROLES, "/security-base")))
194                 .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))
195                 .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)));
196         register((DeltaBuilder.update("5.1.2", ""))
197                 .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))
198                 .addTask(new BootstrapSingleModuleResource("Anonymous user", "Change anonymous user permission. He can't have write access to himself.", "users.system.anonymous.xml", "/anonymous/acl_users")));
199 
200         register((DeltaBuilder.update("5.2.1", ""))
201                 .addTask(new RemoveOpenWFEPermissionsTask("Find and remove all openWFE permissions from the userroles workspace", ""))
202                 .addTask(new GrantReadPermissionToRolesTask("Set read-permission to role itself", "If a role do not have a read permission to itself, add it")));
203         register((DeltaBuilder.update("5.2.2", ""))
204                 .addTask(removeObsoleteInstallFiles)
205                 .addTask(new AddActivatableMixinForContentNodeTask("Add the mixIn '" + NodeTypes.Activatable.NAME + "' to the '" + NodeTypes.ContentNode.NAME + "' node type definition", "", RepositoryConstants.CONFIG)));
206         register((DeltaBuilder.update("5.2.3", ""))
207                 .addTask(new RemovePermissionTask("Remove 'anonymous' role permission", "anonymous", RepositoryConstants.USER_ROLES, "/anonymous", Permission.READ)));
208 
209         register((DeltaBuilder.update("5.3.2", ""))
210                 .addTask(new NodeExistsDelegateTask("Add csrfSecurity Filter", "/server/filters/csrfSecurity",
211                         /* Partially bootstrap new bypass for Vaadin requests if filter already exists */
212                         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"},
213                                 new PartialBootstrapTask("Add csrfSecurity Filter", "", "/mgnl-bootstrap/core/config.server.filters.xml", "/filters/csrfSecurity/bypasses/BypassWhenVaadinRequest", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)),
214                         /* Partially bootstrap whole csrf filter if it doesn't exists */
215                         new PartialBootstrapTask("Add csrfSecurity Filter", "", "/mgnl-bootstrap/core/config.server.filters.xml", "/filters/csrfSecurity", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW)))
216                 .addTask(new NodeExistsDelegateTask("Order csrfSecurity Filter", "Put csrfSecurity before uriSecurity Filter.", RepositoryConstants.CONFIG, "/server/filters/uriSecurity",
217                         new OrderNodeBeforeTask("Order csrfSecurity Filter", "Put csrfSecurity before uriSecurity Filter.", RepositoryConstants.CONFIG, "/server/filters/csrfSecurity", "uriSecurity"),
218                         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.")))
219                 .addTask(new NodeExistsDelegateTask("Add csrfSecurity Filter", "/server/auditLogging/logConfigurations/security", null,
220                         new PartialBootstrapTask("Add 'security' AuditLogging logConfiguration.", "", "/mgnl-bootstrap/core/config.server.auditLogging.xml", "/auditLogging/logConfigurations/security", ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW))));
221 
222         register((DeltaBuilder.update("5.3.5", ""))
223 
224                 .addTask(new FixUserRolePermissionsPropertyTask("/superuser")));
225 
226         register((DeltaBuilder.update("5.4.1", ""))
227                 .addTask(updateSecurityBaseRolePermissions()));
228 
229         register((DeltaBuilder.update("5.4.3", ""))
230                 .addTask(new ValueOfPropertyDelegateTask("Change MIME mapping of Javascript resources", "/server/MIMEMapping/js", "mime-type", "application/x-javascript", true,
231                         new SetPropertyTask("config", "/server/MIMEMapping/js", "mime-type", "application/javascript"))));
232 
233         register((DeltaBuilder.update("5.4.5", ""))
234                 .addTask(new BootstrapSingleModuleResource("Add mime mapping for .map", "Add mime mapping for .map", "config.server.MIMEMapping.xml", "/MIMEMapping/map")));
235 
236         register((DeltaBuilder.update("5.4.6", ""))
237                 .addTask(new QueryElementsAndDisplayWarningTask("Check SimpleUrlPatterns in user roles",
238                         "SimpleUrlPattern no longer misinterprets dots as regular expression wildcard characters. User roles will be checked whether they are affected.",
239                         RepositoryConstants.USER_ROLES, "SELECT * FROM [nt:base] WHERE path LIKE '%.%'", NodeTypes.Role.NAME,
240                         "SimpleUrlPattern no longer misinterprets dots as regular expression wildcard characters. As a result, the following roles might need your attention:\n%s" +
241                                 "\nRead more at http://documentation.magnolia-cms.com/display/DOCS/Release+notes+for+Magnolia+5.4.6.",
242                         Lists.newArrayList("/rest", "/security-base", "/anonymous", "/forum_ALL-moderator", "/forum_ALL-user", "/forum_ALL-admin", "/public-user-registration-base"))));
243 
244         register((DeltaBuilder.update("5.4.7", ""))
245                 .addTask(new AddUsersPermissionTask("Allow users to edit their timezone setting", "/admin", RepositoryConstants.USERS, AddUsersPermissionTask.USER_PATH_REPLACEMENT + "/timezone", Permission.ALL, nodeNameHelper)));
246 
247         register(DeltaBuilder.update("5.4.8", "")
248                 .addTask(new NodeExistsDelegateTask("If exists, remove legacy log4j servlet", "/server/filters/servlets/log4j", new RemoveNodeTask("", "/server/filters/servlets/log4j"))));
249 
250         register(DeltaBuilder.update("5.4.9", "")
251                 .addTask(new AddActivatableMixinForMgnlResourceTask("Update mgnl:resource node type", "Add mgnl:activatable mixin to the mgnl:resource node type", RepositoryConstants.WEBSITE))
252         );
253 
254         register(DeltaBuilder.update("5.5", "")
255                 .addTask(new MigrateVersionWorkspacesToNewStructureTask(repositoryManager))
256                 .addTasks(getLockableMixinAdditionTasksForAllWorkspaces())
257                 .addTask(new NodeExistsDelegateTask("Add korean language into system languages", "/server/i18n/system/ko", null,
258                         new BootstrapSingleModuleResource("", "", "config.server.i18n.system.xml", "/system/languages/ko")))
259         );
260 
261         register(DeltaBuilder.update("5.5.4", "")
262                 .addTask(new BootstrapSingleModuleResource("Add mime mapping for YAML", "Add mime mapping for YAML", "config.server.MIMEMapping.xml", "/MIMEMapping/x-yaml"))
263                 .addTask(new RenameVersionNodesTask(repositoryManager))
264         );
265 
266         register(DeltaBuilder.update("6.0", "")
267                 .addTask(new NodeExistsDelegateTask("Enable csrfTokenSecurity filter", "Adds or enables csrfTokenSecurity filter.", "config", "/server/filters/csrfTokenSecurity",
268                         new ValueOfPropertyDelegateTask("Enable csrfTokenSecurity filter", "/server/filters/csrfTokenSecurity", "enabled", "false", false,
269                             new RemovePropertyTask("", "/server/filters/csrfTokenSecurity", "enabled")),
270                         new ArrayDelegateTask("Add csrfTokenSecurity filter", "",
271                             new BootstrapSingleModuleResource("", "", "config.server.filters.xml", "/filters/csrfTokenSecurity"),
272                             new NodeExistsDelegateTask("", "/server/filters/login",
273                                 new OrderNodeBeforeTask("Order csrfTokenSecurity Filter", "Put csrfTokenSecurity before login filter.", RepositoryConstants.CONFIG, "/server/filters/csrfTokenSecurity", "login"),
274                                 new WarnTask("CSRF Token Security Filter is inactive.", "CSRF Token Security Filter inactive. The installed csrfTokenSecurity filter must be moved up in the filters list and enabled manually.")))))
275                 .addTask(new RemoveMIMEIconsTask("Find and remove all legacy 'icon' properties", "", RepositoryConstants.CONFIG, "/server/MIMEMapping"))
276                 .addTask(new BootstrapSingleModuleResource("Add WOFF2 MIME type", "", "config.server.MIMEMapping.xml", "/MIMEMapping/woff2"))
277         );
278         register(DeltaBuilder.update("6.1", "")
279                 .addTask(new NodeExistsDelegateTask("Add publish node into auditLogging config", "/server/auditLogging/logConfigurations/publish", null,
280                                 new BootstrapSingleModuleResource("", "add publish node", "config.server.auditLogging.xml", "/auditLogging/logConfigurations/publish")))
281                 .addTask(new NodeExistsDelegateTask("Add unpublish node into auditLogging config", "/server/auditLogging/logConfigurations/unpublish", null,
282                                 new BootstrapSingleModuleResource("", "add unpublish node", "config.server.auditLogging.xml", "/auditLogging/logConfigurations/unpublish")))
283                 .addTask(createInstanceUuid())
284         );
285         register(DeltaBuilder.update("6.2", "")
286                 .addTask(new NodeExistsDelegateTask("Change the multipart filter implementation", "/server/filters/multipartRequest",
287                         new SetPropertyTask("config", "/server/filters/multipartRequest", "class", "info.magnolia.cms.filters.MultipartRequestFilter"),
288                         new WarnTask("Multipart filter does not exist", "Changing the multipart filter implementation to MultipartRequestFilter cannot be done since the multipart filter path does not exist.")))
289         );
290 
291         register(DeltaBuilder.update("6.2.1", "")
292                 .addTask(new IsModuleInstalledOrRegistered("Clean up device detection module", "Remove configuration of module device detection if it is not installed", "device-detection", null,
293                         new ArrayDelegateTask("",
294                                 new NodeExistsDelegateTask("Remove /modules/device-detection if existing", "/modules/device-detection",
295                                         new RemoveNodeTask("", "/modules/device-detection")),
296                                 new NodeExistsDelegateTask("Remove server/filters/deviceDetection if existing", "/server/filters/deviceDetection",
297                                         new RemoveNodeTask("", "/server/filters/deviceDetection")),
298                                 new NodeExistsDelegateTask("Remove server/rendering/channelManagement/channels/device if existing", "/server/rendering/channelManagement/channels/device",
299                                         new RemoveNodeTask("", "/server/rendering/channelManagement/channels/device")))) {
300                     @Override
301                     protected boolean condition(InstallContext ctx) {
302                         return ctx.isModuleRegistered("device-detection");//Only check from context
303                     }
304                 })
305         );
306 
307         register(DeltaBuilder.update("6.2.4", "")
308                 .addTask(new AllowOptionMethodForRequestsTask())
309                 .addTask(new WarnOnCorsAddedByAddHeadersFilter())
310                 .addTask(new BootstrapSingleModuleResource("config.server.filters.cors.yaml"))
311                 .addTask(new NodeExistsDelegateTask("Order CORS filter", "/server/filters/uriSecurity", new FilterOrderingTask("cors", new String[] { "uriSecurity" })))
312         );
313 
314         register(DeltaBuilder.update("6.2.6", "")
315                 .addTask(new NodeExistsDelegateTask("Order CORS filter", "/server/filters/cors",
316                         new NodeExistsDelegateTask("", "/server/filters/uriSecurity", new OrderFilterBeforeTask("cors", new String[]{"uriSecurity"}))
317                 ))
318         );
319     }
320 
321     /**
322      * @deprecated since 5.6, use {@link #CoreModuleVersionHandler(RepositoryManager, NodeNameHelper)} instead.
323      */
324     @Deprecated
325     public CoreModuleVersionHandler(RepositoryManager repositoryManager) {
326         this(repositoryManager, Components.getComponent(NodeNameHelper.class));
327     }
328 
329     private List<Task> getLockableMixinAdditionTasksForAllWorkspaces() {
330         List<Task> tasks = Lists.newArrayList();
331         for (String workspaceName : repositoryManager.getWorkspaceNames()) {
332             tasks.add(new AddLockableMixinToVersionableMixinTask("",
333                     "Adding lockable mixing as supertype to versionable mixin for workspace '{" + workspaceName + "}'", workspaceName));
334             tasks.add(new AddLockableMixinToActivatableMixinTask("",
335                     "Adding lockable mixing as supertype to activatable mixin for workspace '{" + workspaceName + "}'", workspaceName));
336         }
337         return tasks;
338     }
339 
340     private Task createInstanceUuid() {
341         return new NewPropertyTask("Create an instance UUID", "/server", "instanceUuid", UUID.randomUUID().toString());
342     }
343 
344     @Override
345     protected List<Task> getBasicInstallTasks(InstallContext ctx) {
346         final List<Task> tasks = new ArrayList<>();
347         tasks.addAll(GenericTasks.genericTasksForNewInstallation());
348         tasks.add(auditTrailManagerTask);
349         tasks.add(bootstrapWebContainerResources);
350         tasks.add(new BootstrapConditionally("Security", "Bootstraps security-base role.", "/mgnl-bootstrap/core/userroles.security-base.xml"));
351         // always hash passwords. Task will not re-hash so it is safe to run this op at any time, multiple times.
352         tasks.add(bootstrapChannelManagement);
353         tasks.add(bootstrapChannelFilter);
354         tasks.add(placeChannelBeforeLogout);
355         tasks.add(new BootstrapSingleModuleResource("config.server.filters.cors.yaml"));
356         tasks.add(new FilterOrderingTask("cors", new String[] { "uriSecurity" }));
357         tasks.add(createInstanceUuid());
358 
359         return tasks;
360     }
361 
362     @Override
363     protected List<Condition> getInstallConditions() {
364         final List<Condition> conditions = new ArrayList<>();
365 
366         conditions.add(new IsNotAProblematicEnvironmentCondition());
367 
368         final WebXmlConditionsUtilonsUtil.html#WebXmlConditionsUtil">WebXmlConditionsUtil u = new WebXmlConditionsUtil(conditions);
369         u.servletIsNowWrapped("ActivationHandler");
370         u.servletIsNowWrapped("AdminTreeServlet");
371         u.servletIsNowWrapped("classpathspool");
372         u.servletIsNowWrapped("DialogServlet");
373         u.servletIsNowWrapped("PageServlet");
374         u.servletIsNowWrapped("log4j");
375         u.servletIsNowWrapped("FCKEditorSimpleUploadServlet");
376         u.servletIsDeprecated("uuidRequestDispatcher");
377         u.filterIsDeprecated("info.magnolia.cms.filters.MagnoliaManagedFilter", "info.magnolia.cms.filters.MgnlMainFilter");
378         u.filterMustBeRegisteredWithCorrectDispatchers("info.magnolia.cms.filters.MgnlMainFilter");
379         u.listenerIsDeprecated("info.magnolia.cms.servlets.MgnlServletContextListener", "info.magnolia.init.MagnoliaServletContextListener");
380         final WorkspaceXmlConditionsUtilnsUtil.html#WorkspaceXmlConditionsUtil">WorkspaceXmlConditionsUtil u2 = new WorkspaceXmlConditionsUtil(conditions);
381         u2.textFilterClassesAreNotSet();
382 
383         conditions.add(new SystemTmpDirCondition());
384         conditions.add(new NoSameNameSiblingsCondition(repositoryManager));
385 
386         return conditions;
387     }
388 }
389