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