| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| org.xwiki.index.internal.DefaultTasksManager | ||
| org.xwiki.index.internal.TasksStore | ||
| org.xwiki.index.internal.TaskExecutor | ||
| org.xwiki.index.internal.TaskApplicationReadyListener | ||
| org.xwiki.index.internal.DefaultLinksTaskConsumer | ||
| org.xwiki.index.internal.listener.LinksUpdateListener | ||
| org.xwiki.index.migration.R140300000XWIKI19614DataMigration | ||
| org.xwiki.index.migration.R140300001XWIKI19571DataMigration |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.invitation; | ||
|
|
||
| import org.jsoup.Jsoup; | ||
| import org.jsoup.nodes.Document; | ||
| import org.jsoup.nodes.Element; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.RenderingScriptServiceComponentList; | ||
| import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; | ||
| import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; | ||
| import org.xwiki.rendering.internal.macro.message.InfoMessageMacro; | ||
| import org.xwiki.test.annotation.ComponentList; | ||
| import org.xwiki.test.page.HTML50ComponentList; | ||
| import org.xwiki.test.page.PageTest; | ||
| import org.xwiki.test.page.TestNoScriptMacro; | ||
| import org.xwiki.test.page.XWikiSyntax21ComponentList; | ||
|
|
||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@code Invitation.InvitationConfig}. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @HTML50ComponentList | ||
| @XWikiSyntax21ComponentList | ||
| @RenderingScriptServiceComponentList | ||
| @ComponentList({ | ||
| InfoMessageMacro.class, | ||
| TestNoScriptMacro.class, | ||
| // Start - Required in addition of RenderingScriptServiceComponentList | ||
| DefaultExtendedRenderingConfiguration.class, | ||
| RenderingConfigClassDocumentConfigurationSource.class, | ||
| // End - Required in additional of RenderingScriptServiceComponentList | ||
| }) | ||
| class InvitationConfigPageTest extends PageTest | ||
| { | ||
| private static final DocumentReference INVITATION_CONFIG_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationConfig"); | ||
|
|
||
| @Test | ||
| void escapeInfoMessageInternalDocumentParameter() throws Exception | ||
| { | ||
| XWikiDocument invitationGuestActionsDocument = loadPage(INVITATION_CONFIG_DOCUMENT_REFERENCE); | ||
|
|
||
| // Set up the current doc in the context so that $doc is bound in scripts | ||
| this.context.setDoc( | ||
| this.xwiki.getDocument(new DocumentReference("xwiki", "]] {{noscript/}}", "Page"), this.context)); | ||
|
|
||
| Document document = Jsoup.parse(invitationGuestActionsDocument.getRenderedContent(this.context)); | ||
| Element infomessage = document.selectFirst(".infomessage"); | ||
| assertEquals("xe.invitation.internalDocument [Invitation.WebHome]", infomessage.text()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.invitation; | ||
|
|
||
| import org.jsoup.Jsoup; | ||
| import org.jsoup.nodes.Document; | ||
| import org.jsoup.nodes.Element; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.RenderingScriptServiceComponentList; | ||
| import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; | ||
| import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; | ||
| import org.xwiki.rendering.internal.macro.message.InfoMessageMacro; | ||
| import org.xwiki.test.annotation.ComponentList; | ||
| import org.xwiki.test.page.HTML50ComponentList; | ||
| import org.xwiki.test.page.PageTest; | ||
| import org.xwiki.test.page.TestNoScriptMacro; | ||
| import org.xwiki.test.page.XWikiSyntax21ComponentList; | ||
|
|
||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@code Invitation.InvitationGuestActions}. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @HTML50ComponentList | ||
| @XWikiSyntax21ComponentList | ||
| @RenderingScriptServiceComponentList | ||
| @ComponentList({ | ||
| InfoMessageMacro.class, | ||
| TestNoScriptMacro.class, | ||
| // Start - Required in addition of RenderingScriptServiceComponentList | ||
| DefaultExtendedRenderingConfiguration.class, | ||
| RenderingConfigClassDocumentConfigurationSource.class, | ||
| // End - Required in additional of RenderingScriptServiceComponentList | ||
| }) | ||
| class InvitationGuestActionsPageTest extends PageTest | ||
| { | ||
| private static final DocumentReference INVITATION_COMMON_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationCommon"); | ||
|
|
||
| private static final DocumentReference INVITATION_GUEST_ACTIONS_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationGuestActions"); | ||
|
|
||
| @BeforeEach | ||
| void setUp() throws Exception | ||
| { | ||
| loadPage(INVITATION_COMMON_DOCUMENT_REFERENCE); | ||
| } | ||
|
|
||
| @Test | ||
| void escapeInfoMessageInternalDocumentParameter() throws Exception | ||
| { | ||
| XWikiDocument invitationGuestActionsDocument = loadPage(INVITATION_GUEST_ACTIONS_DOCUMENT_REFERENCE); | ||
|
|
||
| // Set up the current doc in the context so that $doc is bound in scripts | ||
| this.context.setDoc( | ||
| this.xwiki.getDocument(new DocumentReference("xwiki", "]] {{noscript/}}", "Page"), this.context)); | ||
|
|
||
| Document document = Jsoup.parse(invitationGuestActionsDocument.getRenderedContent(this.context)); | ||
| Element infomessage = document.selectFirst(".infomessage"); | ||
| assertEquals("xe.invitation.internalDocument []] {{noscript/}}.WebHome]", infomessage.text()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.invitation; | ||
|
|
||
| import org.jsoup.Jsoup; | ||
| import org.jsoup.nodes.Document; | ||
| import org.jsoup.nodes.Element; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.RenderingScriptServiceComponentList; | ||
| import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; | ||
| import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; | ||
| import org.xwiki.rendering.internal.macro.message.InfoMessageMacro; | ||
| import org.xwiki.test.annotation.ComponentList; | ||
| import org.xwiki.test.page.HTML50ComponentList; | ||
| import org.xwiki.test.page.PageTest; | ||
| import org.xwiki.test.page.TestNoScriptMacro; | ||
| import org.xwiki.test.page.XWikiSyntax21ComponentList; | ||
|
|
||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@code Invitation.InvitationMailClass}. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @HTML50ComponentList | ||
| @XWikiSyntax21ComponentList | ||
| @RenderingScriptServiceComponentList | ||
| @ComponentList({ | ||
| InfoMessageMacro.class, | ||
| TestNoScriptMacro.class, | ||
| // Start - Required in addition of RenderingScriptServiceComponentList | ||
| DefaultExtendedRenderingConfiguration.class, | ||
| RenderingConfigClassDocumentConfigurationSource.class, | ||
| // End - Required in additional of RenderingScriptServiceComponentList | ||
| }) | ||
| class InvitationMailClassPageTest extends PageTest | ||
| { | ||
| private static final DocumentReference INVITATION_MAIL_CLASS_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationMailClass"); | ||
|
|
||
| @Test | ||
| void escapeInfoMessageInternalDocumentParameter() throws Exception | ||
| { | ||
| XWikiDocument invitationGuestActionsDocument = loadPage(INVITATION_MAIL_CLASS_DOCUMENT_REFERENCE); | ||
|
|
||
| // Set up the current doc in the context so that $doc is bound in scripts | ||
| this.context.setDoc( | ||
| this.xwiki.getDocument(new DocumentReference("xwiki", "]] {{noscript/}}", "Page"), this.context)); | ||
|
|
||
| Document document = Jsoup.parse(invitationGuestActionsDocument.getRenderedContent(this.context)); | ||
| Element infomessage = document.selectFirst(".infomessage"); | ||
| assertEquals("xe.invitation.internalDocument []] {{noscript/}}.WebHome]", infomessage.text()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.invitation; | ||
|
|
||
| import org.jsoup.Jsoup; | ||
| import org.jsoup.nodes.Document; | ||
| import org.jsoup.nodes.Element; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.RenderingScriptServiceComponentList; | ||
| import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; | ||
| import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; | ||
| import org.xwiki.rendering.internal.macro.message.InfoMessageMacro; | ||
| import org.xwiki.test.annotation.ComponentList; | ||
| import org.xwiki.test.page.HTML50ComponentList; | ||
| import org.xwiki.test.page.PageTest; | ||
| import org.xwiki.test.page.TestNoScriptMacro; | ||
| import org.xwiki.test.page.XWikiSyntax21ComponentList; | ||
|
|
||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@code Invitation.InvitationMemberActions}. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @HTML50ComponentList | ||
| @XWikiSyntax21ComponentList | ||
| @RenderingScriptServiceComponentList | ||
| @ComponentList({ | ||
| InfoMessageMacro.class, | ||
| TestNoScriptMacro.class, | ||
| // Start - Required in addition of RenderingScriptServiceComponentList | ||
| DefaultExtendedRenderingConfiguration.class, | ||
| RenderingConfigClassDocumentConfigurationSource.class, | ||
| // End - Required in additional of RenderingScriptServiceComponentList | ||
| }) | ||
| class InvitationMemberActionsPageTest extends PageTest | ||
| { | ||
| private static final DocumentReference INVITATION_COMMON_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationCommon"); | ||
|
|
||
| private static final DocumentReference INVITATION_MEMBER_ACTIONS_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationMemberActions"); | ||
|
|
||
| @BeforeEach | ||
| void setUp() throws Exception | ||
| { | ||
| loadPage(INVITATION_COMMON_DOCUMENT_REFERENCE); | ||
| } | ||
|
|
||
| @Test | ||
| void escapeInfoMessageInternalDocumentParameter() throws Exception | ||
| { | ||
| XWikiDocument invitationGuestActionsDocument = loadPage(INVITATION_MEMBER_ACTIONS_DOCUMENT_REFERENCE); | ||
|
|
||
| // Set a non-guest user as otherwise the rendering stops early. | ||
| this.context.setUserReference(new DocumentReference("xwiki", "XWiki", "U1")); | ||
|
|
||
| // Set up the current doc in the context so that $doc is bound in scripts | ||
| this.context.setDoc( | ||
| this.xwiki.getDocument(new DocumentReference("xwiki", "]] {{noscript/}}", "Page"), this.context)); | ||
|
|
||
| Document document = Jsoup.parse(invitationGuestActionsDocument.getRenderedContent(this.context)); | ||
| Element infomessage = document.selectFirst(".infomessage"); | ||
| assertEquals("xe.invitation.internalDocument []] {{noscript/}}.WebHome]", infomessage.text()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.invitation; | ||
|
|
||
| import org.jsoup.Jsoup; | ||
| import org.jsoup.nodes.Document; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.RenderingScriptServiceComponentList; | ||
| import org.xwiki.rendering.internal.configuration.DefaultExtendedRenderingConfiguration; | ||
| import org.xwiki.rendering.internal.configuration.RenderingConfigClassDocumentConfigurationSource; | ||
| import org.xwiki.rendering.internal.macro.message.InfoMessageMacro; | ||
| import org.xwiki.test.annotation.ComponentList; | ||
| import org.xwiki.test.page.HTML50ComponentList; | ||
| import org.xwiki.test.page.PageTest; | ||
| import org.xwiki.test.page.TestNoScriptMacro; | ||
| import org.xwiki.test.page.XWikiSyntax21ComponentList; | ||
|
|
||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@code Invitation.InvitationMembersCommon}. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @HTML50ComponentList | ||
| @XWikiSyntax21ComponentList | ||
| @RenderingScriptServiceComponentList | ||
| @ComponentList({ | ||
| InfoMessageMacro.class, | ||
| TestNoScriptMacro.class, | ||
| // Start - Required in addition of RenderingScriptServiceComponentList | ||
| DefaultExtendedRenderingConfiguration.class, | ||
| RenderingConfigClassDocumentConfigurationSource.class, | ||
| // End - Required in additional of RenderingScriptServiceComponentList | ||
| }) | ||
| class InvitationMembersCommonPageTest extends PageTest | ||
| { | ||
| private static final DocumentReference INVITATION_MEMBER_COMMON_DOCUMENT_REFERENCE = | ||
| new DocumentReference("xwiki", "Invitation", "InvitationMembersCommon"); | ||
|
|
||
| @Test | ||
| void escapeInfoMessageInternalDocumentParameter() throws Exception | ||
| { | ||
| XWikiDocument invitationGuestActionsDocument = loadPage(INVITATION_MEMBER_COMMON_DOCUMENT_REFERENCE); | ||
|
|
||
| // Set a non-guest user as otherwise the rendering stops early. | ||
| this.context.setUserReference(new DocumentReference("xwiki", "XWiki", "U1")); | ||
|
|
||
| // Set up the current doc in the context so that $doc is bound in scripts | ||
| this.context.setDoc( | ||
| this.xwiki.getDocument(new DocumentReference("xwiki", "]] {{noscript/}}", "InvitationMembersCommon"), | ||
| this.context)); | ||
|
|
||
| Document document = Jsoup.parse(invitationGuestActionsDocument.getRenderedContent(this.context)); | ||
| assertEquals("xe.invitation.internalDocument []] {{noscript/}}.WebHome]", | ||
| document.selectFirst(".infomessage").text()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.extension; | ||
|
|
||
| import org.xwiki.component.annotation.Role; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
|
|
||
| /** | ||
| * Provides operation to access to information relative to XARs provided by extensions. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @Role | ||
| public interface XARExtensionIndex | ||
| { | ||
| /** | ||
| * @param documentReference a document reference | ||
| * @return {@code true} if a given document reference is provided by an extension | ||
| */ | ||
| boolean isExtensionDocument(DocumentReference documentReference); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.migration; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| import javax.inject.Inject; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.xwiki.index.TaskManager; | ||
| import org.xwiki.model.reference.DocumentReferenceResolver; | ||
|
|
||
| import com.xpn.xwiki.XWikiContext; | ||
| import com.xpn.xwiki.XWikiException; | ||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
| import com.xpn.xwiki.store.migration.DataMigrationException; | ||
| import com.xpn.xwiki.store.migration.hibernate.AbstractHibernateDataMigration; | ||
|
|
||
| import static java.util.stream.Collectors.toList; | ||
|
|
||
| /** | ||
| * Allow to easily queue a document analysis task on a set documents to migrate. Sub-classes need to implement two | ||
| * methods: | ||
| * <ul> | ||
| * <li>{@link #selectDocuments()}: return the list of document ids to queue for migration</li> | ||
| * <li>{@link #getTaskType()}: the type of the task to queue documents to</li> | ||
| * </ul> | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| public abstract class AbstractDocumentsMigration extends AbstractHibernateDataMigration | ||
| { | ||
| @Inject | ||
| protected Logger logger; | ||
|
|
||
| @Inject | ||
| protected DocumentReferenceResolver<String> documentReferenceResolver; | ||
|
|
||
| @Inject | ||
| private TaskManager taskManager; | ||
|
|
||
| @Override | ||
| protected void hibernateMigrate() throws DataMigrationException | ||
| { | ||
| List<XWikiDocument> documents = selectDocuments() | ||
| .stream() | ||
| .map(this::convert) | ||
| .filter(Optional::isPresent) | ||
| .map(Optional::get) | ||
| .collect(toList()); | ||
| logBeforeQueuingTasks(documents); | ||
| for (XWikiDocument document : documents) { | ||
| logBeforeQueuingTask(document); | ||
| this.taskManager.addTask(this.getXWikiContext().getWikiId(), document.getId(), getTaskType()); | ||
| } | ||
| } | ||
|
|
||
| private Optional<XWikiDocument> convert(String documentReference) | ||
| { | ||
| XWikiContext context = getXWikiContext(); | ||
| try { | ||
| return Optional.of( | ||
| context.getWiki().getDocument(this.documentReferenceResolver.resolve(documentReference), context)); | ||
| } catch (XWikiException e) { | ||
| this.logger.error("Failed to resolve [{}]", documentReference, e); | ||
| return Optional.empty(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * @return the id of the task type to queue documents to | ||
| */ | ||
| protected abstract String getTaskType(); | ||
|
|
||
| /** | ||
| * @return the list of document ids to migrate | ||
| */ | ||
| protected abstract List<String> selectDocuments() throws DataMigrationException; | ||
|
|
||
| /** | ||
| * Prints an info log with the number of queued documents and the type of the task. | ||
| * | ||
| * @param documents the full list of documents that will be queued | ||
| */ | ||
| protected void logBeforeQueuingTasks(List<XWikiDocument> documents) | ||
| { | ||
| this.logger.info("[{}] documents queued to task [{}]", documents.size(), getTaskType()); | ||
| } | ||
|
|
||
| /** | ||
| * Prints an info logs with an individual document and well as its queued task. | ||
| * | ||
| * @param document a individual document that will be queued | ||
| */ | ||
| protected void logBeforeQueuingTask(XWikiDocument document) | ||
| { | ||
| this.logger.info("document [{}] queued to task [{}]", document, getTaskType()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.migration; | ||
|
|
||
| import java.util.Objects; | ||
| import java.util.Optional; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| import javax.inject.Singleton; | ||
|
|
||
| import org.xwiki.component.annotation.Component; | ||
| import org.xwiki.rendering.syntax.Syntax; | ||
|
|
||
| import static java.util.regex.Matcher.quoteReplacement; | ||
|
|
||
| /** | ||
| * Fix a content by looking for localization of {@code xe.invitation.internalDocument} and escaping its parameter. The | ||
| * translation fixed by this method is initially introduced by the invitation application but the fix is localed in | ||
| * oldcore so that the fix is applied on pages even if the invitation application has been uninstalled. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @Component(roles = InvitationInternalDocumentParameterEscapingFixer.class) | ||
| @Singleton | ||
| public class InvitationInternalDocumentParameterEscapingFixer | ||
| { | ||
| private static final Pattern PATTERN = Pattern.compile("(\\{\\{info}}" | ||
| + "\\$services\\.localization\\.render\\('xe\\.invitation\\.internalDocument', \\[)(\"[^\"]+\")(]\\)\\" | ||
| + "{\\{/info}})"); | ||
|
|
||
| /** | ||
| * @param content the context to fix | ||
| * @param syntax the syntax of the context to fix (xwiki/2.0 or xwiki/2.1) | ||
| * @return the context with the fix applied, or {@link Optional#empty()} if nothing needs to be fixed | ||
| */ | ||
| public Optional<String> fix(String content, Syntax syntax) | ||
| { | ||
| String escapedContent = PATTERN.matcher(content).replaceAll(matchResult -> { | ||
| if (matchResult.group(2).contains("services.rendering.escape")) { | ||
| return matchResult.group(); | ||
| } else { | ||
| // Concatenate the various groups of the regex while wrapping the localization argument with a | ||
| // call to the escaping script service. | ||
| String format = String.format("%s$services.rendering.escape(%s, '%s')%s", matchResult.group(1), | ||
| matchResult.group(2), syntax.toIdString(), matchResult.group(3)); | ||
| return quoteReplacement(format); | ||
| } | ||
| }); | ||
|
|
||
| if (Objects.equals(escapedContent, content)) { | ||
| return Optional.empty(); | ||
| } else { | ||
| return Optional.of(escapedContent); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.migration; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import javax.inject.Inject; | ||
| import javax.inject.Named; | ||
| import javax.inject.Provider; | ||
| import javax.inject.Singleton; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.xwiki.component.annotation.Component; | ||
| import org.xwiki.index.IndexException; | ||
| import org.xwiki.index.TaskConsumer; | ||
| import org.xwiki.model.reference.DocumentReference; | ||
| import org.xwiki.rendering.syntax.Syntax; | ||
|
|
||
| import com.xpn.xwiki.XWikiContext; | ||
| import com.xpn.xwiki.XWikiException; | ||
| import com.xpn.xwiki.doc.XWikiDocument; | ||
|
|
||
| /** | ||
| * Apply {@link InvitationInternalDocumentParameterEscapingFixer} on the documents queued by | ||
| * {@link R150000000XWIKI20285DataMigration} if applicable, and log the skipped ones. This translation key is initially | ||
| * introduced by the invitation application but the fix is localed in oldcore so that the fix is applied on pages even | ||
| * if the invitation application has been uninstalled. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @Component | ||
| @Singleton | ||
| @Named(InvitationInternalDocumentParameterEscapingTaskConsumer.HINT) | ||
| public class InvitationInternalDocumentParameterEscapingTaskConsumer implements TaskConsumer | ||
| { | ||
| /** | ||
| * This task consumer hint. | ||
| */ | ||
| public static final String HINT = "internal-document-parameter-escaping"; | ||
|
|
||
| @Inject | ||
| private Logger logger; | ||
|
|
||
| @Inject | ||
| private Provider<XWikiContext> contextProvider; | ||
|
|
||
| @Inject | ||
| private InvitationInternalDocumentParameterEscapingFixer invitationInternalDocumentParameterEscapingFixer; | ||
|
|
||
| @Override | ||
| public void consume(DocumentReference documentReference, String version) throws IndexException | ||
| { | ||
| try { | ||
| XWikiContext context = this.contextProvider.get(); | ||
| task(context.getWiki().getDocument(documentReference, context)); | ||
| } catch (XWikiException e) { | ||
| throw new IndexException(String.format("Failed to resolve document [%s]", documentReference), e); | ||
| } | ||
| } | ||
|
|
||
| private void task(XWikiDocument document) | ||
| { | ||
| Syntax syntax = document.getSyntax(); | ||
| if (List.of(Syntax.XWIKI_2_1, Syntax.XWIKI_2_0).contains(syntax)) { | ||
| try { | ||
| this.invitationInternalDocumentParameterEscapingFixer.fix(document.getContent(), document.getSyntax()) | ||
| .ifPresent(content -> { | ||
| document.setContent(content); | ||
| try { | ||
| XWikiContext context = this.contextProvider.get(); | ||
| context.getWiki().saveDocument(document, "Automatic bad escaping fix.", true, context); | ||
| this.logger.info("[{}] successfully fixed.", document); | ||
| } catch (XWikiException e) { | ||
| this.logger.error("Failed to save document [{}]", document, e); | ||
| } | ||
| }); | ||
| } catch (Exception e) { | ||
| this.logger.error("Unexpected error while fixing [{}]", document, e); | ||
| } | ||
| } else { | ||
| this.logger.warn( | ||
| "[{}] skipped because escaping for syntax [{}] is not supported. It is advised to review this file.", | ||
| document, syntax); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.migration; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import javax.inject.Inject; | ||
| import javax.inject.Named; | ||
| import javax.inject.Singleton; | ||
|
|
||
| import org.xwiki.component.annotation.Component; | ||
| import org.xwiki.internal.extension.XARExtensionIndex; | ||
| import org.xwiki.query.QueryException; | ||
|
|
||
| import com.xpn.xwiki.XWiki; | ||
| import com.xpn.xwiki.store.migration.DataMigrationException; | ||
| import com.xpn.xwiki.store.migration.XWikiDBVersion; | ||
|
|
||
| import static org.xwiki.query.Query.XWQL; | ||
|
|
||
| /** | ||
| * Search for documents with a known invalid content produced by code generation (i.e., that cannot be fixed by editing | ||
| * a xar file), and apply an automatic escaping fix. | ||
| * | ||
| * @version $Id$ | ||
| * @since 15.0RC1 | ||
| * @since 14.4.8 | ||
| * @since 14.10.4 | ||
| */ | ||
| @Component | ||
| @Named("R150000000XWIKI20285") | ||
| @Singleton | ||
| public class R150000000XWIKI20285DataMigration extends AbstractDocumentsMigration | ||
| { | ||
| @Inject | ||
| private XARExtensionIndex installedXARs; | ||
|
|
||
| @Override | ||
| public String getDescription() | ||
| { | ||
| return "Patch the InvitationConfig documents with improper escaping."; | ||
| } | ||
|
|
||
| @Override | ||
| public XWikiDBVersion getVersion() | ||
| { | ||
| return new XWikiDBVersion(150000000); | ||
| } | ||
|
|
||
| @Override | ||
| protected String getTaskType() | ||
| { | ||
| return InvitationInternalDocumentParameterEscapingTaskConsumer.HINT; | ||
| } | ||
|
|
||
| @Override | ||
| protected List<String> selectDocuments() throws DataMigrationException | ||
| { | ||
| XWiki wiki = getXWikiContext().getWiki(); | ||
| try { | ||
| // We select potentially impacted documents using like wildcards. This selection might lead to false | ||
| // positive that wild be filtered out by the more accurate regex in | ||
| // InvitationInternalDocumentParameterEscapingFixer. | ||
| return wiki.getStore().getQueryManager() | ||
| .createQuery("where doc.content " | ||
| + "like '%{{info}}%services.localization.render%xe.invitation.internalDocument%{{/info}}%'", XWQL) | ||
| .<String>execute() | ||
| .stream() | ||
| // Exclude document that are provided by extensions, because they are fixed using the usual xar upgrade | ||
| // mechanism. | ||
| .filter(documentReference -> !this.installedXARs.isExtensionDocument( | ||
| this.documentReferenceResolver.resolve(documentReference))) | ||
| .collect(Collectors.toList()); | ||
| } catch (QueryException e) { | ||
| throw new DataMigrationException( | ||
| String.format("Failed retrieve the list of all the documents for wiki [%s].", wiki.getName()), e); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| /* | ||
| * See the NOTICE file distributed with this work for additional | ||
| * information regarding copyright ownership. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.xwiki.internal.migration; | ||
|
|
||
| import java.util.Optional; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.Arguments; | ||
| import org.junit.jupiter.params.provider.MethodSource; | ||
| import org.xwiki.rendering.syntax.Syntax; | ||
| import org.xwiki.test.junit5.mockito.ComponentTest; | ||
| import org.xwiki.test.junit5.mockito.InjectMockComponents; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
|
||
| /** | ||
| * Test of {@link InvitationInternalDocumentParameterEscapingFixer}. | ||
| * | ||
| * @version $Id$ | ||
| */ | ||
| @ComponentTest | ||
| class InvitationInternalDocumentParameterEscapingFixerTest | ||
| { | ||
| @InjectMockComponents | ||
| private InvitationInternalDocumentParameterEscapingFixer fixer; | ||
|
|
||
| public static Stream<Arguments> fixSource() | ||
| { | ||
| return Stream.of( | ||
| Arguments.of( | ||
| "nothing to change 1\n" | ||
| + "{{info}}$services.localization.render('xe.invitation.internalDocument', [$noChange]){{/info}}" | ||
| + "nothing to change 2\n" | ||
| + "{{info}}$services.localization.render('xe.invitation.internalDocument', [\"$change\"]){{/info}}" | ||
| + "nothing to change 3", | ||
| Optional.of( | ||
| "nothing to change 1\n" | ||
| + "{{info}}$services.localization.render('xe.invitation.internalDocument', [$noChange]){{/info}}nothing to change 2\n" | ||
| + "{{info}}$services.localization.render('xe.invitation.internalDocument', [$services.rendering.escape(\"$change\", 'xwiki/2.1')]){{/info}}nothing to change 3" | ||
| ) | ||
| ), | ||
| Arguments.of( | ||
| "nothing to change 1\n" | ||
| + "{{info}}$services.localization.render('xe.invitation.internalDocument', [$noChange]){{/info}}" | ||
| + "nothing to change 2\n" | ||
| + "nothing to change 3", | ||
| Optional.empty() | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @MethodSource("fixSource") | ||
| void fix(String value, Optional<String> expected) | ||
| { | ||
| assertEquals(expected, this.fixer.fix(value, Syntax.XWIKI_2_1)); | ||
| } | ||
| } |