From e0a4ae1648b1d54a423dc31fed5a18187da74ae6 Mon Sep 17 00:00:00 2001
From: Thomas Mortagne <thomas.mortagne@gmail.com>
Date: Fri, 7 Oct 2016 10:30:26 +0200
Subject: [PATCH] XWIKI-13783: Filter job is not executed with the right wiki
 or user context

---
 .../filter/script/FilterScriptService.java    |   9 +
 .../job/JobRequestContextInitializer.java     |  91 +++++++++
 .../com/xpn/xwiki/job/JobRequestContext.java  | 176 ++++++++++++++++++
 .../main/resources/META-INF/components.txt    |   1 +
 4 files changed, 277 insertions(+)
 create mode 100644 xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/internal/job/JobRequestContextInitializer.java
 create mode 100644 xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/job/JobRequestContext.java

diff --git a/xwiki-platform-core/xwiki-platform-filter/xwiki-platform-filter-script/src/main/java/org/xwiki/filter/script/FilterScriptService.java b/xwiki-platform-core/xwiki-platform-filter/xwiki-platform-filter-script/src/main/java/org/xwiki/filter/script/FilterScriptService.java
index 898c70c9c3c..b62ad85dd12 100644
--- a/xwiki-platform-core/xwiki-platform-filter/xwiki-platform-filter-script/src/main/java/org/xwiki/filter/script/FilterScriptService.java
+++ b/xwiki-platform-core/xwiki-platform-filter/xwiki-platform-filter-script/src/main/java/org/xwiki/filter/script/FilterScriptService.java
@@ -51,6 +51,9 @@
 import org.xwiki.security.authorization.ContextualAuthorizationManager;
 import org.xwiki.security.authorization.Right;
 
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.job.JobRequestContext;
+
 /**
  * Expose various FilterStream related APIs to scripts.
  * 
@@ -77,6 +80,9 @@ public class FilterScriptService extends AbstractFilterScriptService
     @Inject
     private JobExecutor jobExecutor;
 
+    @Inject
+    private Provider<XWikiContext> xcontextProvider;
+
     @Inject
     @Named(FilterStreamConverterJob.JOBTYPE)
     private Provider<Job> jobProvider;
@@ -138,6 +144,9 @@ private Job convert(FilterStreamType inputType, Map<String, Object> inputPropert
                 new FilterStreamConverterJobRequest(inputType, inputProperties, outputType, folded, outputProperties);
 
             if (async) {
+                // Give a few context related values to the job
+                request.setProperty(JobRequestContext.KEY, new JobRequestContext(this.xcontextProvider.get()));
+
                 this.lastJob = this.jobExecutor.execute(FilterStreamConverterJob.JOBTYPE, request);
             } else {
                 // Not using the job executor to make sure to be executed in the current thread
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/internal/job/JobRequestContextInitializer.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/internal/job/JobRequestContextInitializer.java
new file mode 100644
index 00000000000..2588865d86e
--- /dev/null
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/internal/job/JobRequestContextInitializer.java
@@ -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 com.xpn.xwiki.internal.job;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.xwiki.component.annotation.Component;
+import org.xwiki.job.event.JobStartedEvent;
+import org.xwiki.observation.AbstractEventListener;
+import org.xwiki.observation.event.Event;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.job.JobRequestContext;
+
+/**
+ * Automatically set various context values before the actual job start.
+ * 
+ * @version $Id$
+ * @since 8.4RC1
+ */
+@Component
+@Named("com.xpn.xwiki.internal.job.JobRequestContextInitializer")
+@Singleton
+public class JobRequestContextInitializer extends AbstractEventListener
+{
+    @Inject
+    private Provider<XWikiContext> xcontextProvider;
+
+    /**
+     * The default constructor.
+     */
+    public JobRequestContextInitializer()
+    {
+        super(JobRequestContextInitializer.class.getName(), new JobStartedEvent());
+    }
+
+    @Override
+    public void onEvent(Event event, Object source, Object data)
+    {
+        JobStartedEvent jobStartedEvent = (JobStartedEvent) event;
+
+        JobRequestContext jobRequestContext = jobStartedEvent.getRequest().getProperty(JobRequestContext.KEY);
+
+        if (jobRequestContext != null) {
+            XWikiContext xcontext = this.xcontextProvider.get();
+
+            if (xcontext != null) {
+                // Wiki id
+                if (jobRequestContext.isWikiIdSet()) {
+                    xcontext.setWikiId(jobRequestContext.getWikiId());
+                }
+
+                // User
+                if (jobRequestContext.isUserReferenceSet()) {
+                    xcontext.setUserReference(jobRequestContext.getUserReference());
+                }
+
+                // Document
+                if (jobRequestContext.isDocumentSet()) {
+                    xcontext.setDoc(jobRequestContext.getDocument());
+                }
+
+                // Secure document
+                if (jobRequestContext.isSDocumentSet()) {
+                    xcontext.put(XWikiDocument.CKEY_SDOC, jobRequestContext.getSDocument());
+                }
+            }
+        }
+    }
+}
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/job/JobRequestContext.java b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/job/JobRequestContext.java
new file mode 100644
index 00000000000..56eeee7dcf3
--- /dev/null
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/job/JobRequestContext.java
@@ -0,0 +1,176 @@
+/*
+ * 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 com.xpn.xwiki.job;
+
+import org.xwiki.job.Request;
+import org.xwiki.model.reference.DocumentReference;
+
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.doc.XWikiDocument;
+
+/**
+ * Contains various information about the context which asked for a job execution.
+ * 
+ * @version $Id$
+ * @since 8.3RC1
+ */
+public class JobRequestContext
+{
+    /**
+     * The key to user in the {@link Request} properties map.
+     */
+    public static final String KEY = "oldcore.xwikicontext";
+
+    private boolean wikiIdSet;
+
+    private String wikiId;
+
+    private boolean documentSet;
+
+    private XWikiDocument document;
+
+    private boolean sDocumentSet;
+
+    private XWikiDocument sDocument;
+
+    private boolean userReferenceSet;
+
+    private DocumentReference userReference;
+
+    /**
+     * Default constructor.
+     */
+    public JobRequestContext()
+    {
+    }
+
+    /**
+     * @param xcontext the XWiki context to extract informations from
+     */
+    public JobRequestContext(XWikiContext xcontext)
+    {
+        if (xcontext != null) {
+            setWikiId(xcontext.getWikiId());
+            setUserReference(xcontext.getUserReference());
+            setDocument(xcontext.getDoc());
+            setSDocument((XWikiDocument) xcontext.get(XWikiDocument.CKEY_SDOC));
+        }
+    }
+
+    /**
+     * @return true if the identifier of the wiki has been set
+     */
+    public boolean isWikiIdSet()
+    {
+        return this.wikiIdSet;
+    }
+
+    /**
+     * @return the identifier of the wiki
+     */
+    public String getWikiId()
+    {
+        return this.wikiId;
+    }
+
+    /**
+     * @param wikiId the identifier of the wiki
+     */
+    public void setWikiId(String wikiId)
+    {
+        this.wikiId = wikiId;
+        this.wikiIdSet = true;
+    }
+
+    /**
+     * @return true if the reference of the user has been set
+     */
+    public boolean isUserReferenceSet()
+    {
+        return this.userReferenceSet;
+    }
+
+    /**
+     * @return the reference of the user
+     */
+    public DocumentReference getUserReference()
+    {
+        return this.userReference;
+    }
+
+    /**
+     * @param userReference the reference of the user
+     */
+    public void setUserReference(DocumentReference userReference)
+    {
+        this.userReference = userReference;
+        this.userReferenceSet = true;
+    }
+
+    /**
+     * @return true of the current document has been set
+     */
+    public boolean isDocumentSet()
+    {
+        return this.documentSet;
+    }
+
+    /**
+     * @param document the current document
+     */
+    public void setDocument(XWikiDocument document)
+    {
+        this.document = document;
+        this.documentSet = true;
+    }
+
+    /**
+     * @return the current document
+     */
+    public XWikiDocument getDocument()
+    {
+        return this.document;
+    }
+
+    /**
+     * @return true if the document holding the current author has been set
+     */
+    public boolean isSDocumentSet()
+    {
+        return this.sDocumentSet;
+    }
+
+    /**
+     * @param sdocument the document holding the current author
+     */
+    public void setSDocument(XWikiDocument sdocument)
+    {
+        this.sDocument = sdocument;
+        this.sDocumentSet = true;
+    }
+
+    /**
+     * @return the document holding the current author
+     */
+    public XWikiDocument getSDocument()
+    {
+        return this.sDocument;
+    }
+}
diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/META-INF/components.txt b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/META-INF/components.txt
index e1d6ea7a058..76297e02feb 100644
--- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/META-INF/components.txt
+++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/META-INF/components.txt
@@ -17,6 +17,7 @@ com.xpn.xwiki.internal.event.CommentEventGeneratorListener
 com.xpn.xwiki.internal.event.XClassPropertyEventGeneratorListener
 com.xpn.xwiki.internal.event.XObjectEventGeneratorListener
 com.xpn.xwiki.script.display.DisplayScriptService
+com.xpn.xwiki.internal.job.JobRequestContextInitializer
 com.xpn.xwiki.internal.localization.XWikiLocalizationContext
 com.xpn.xwiki.internal.mandatory.EditModeClassDocumentInitializer
 com.xpn.xwiki.internal.mandatory.GlobalRedirectDocumentInitializer
-- 
GitLab