Skip to content

Commit 54bcc5a

Browse files
pjeanjeantmortagne
authored andcommitted
XWIKI-21663: Improve Scheduler access
1 parent 8493435 commit 54bcc5a

File tree

5 files changed

+82
-190
lines changed

5 files changed

+82
-190
lines changed

xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties

+1
Original file line numberDiff line numberDiff line change
@@ -2896,6 +2896,7 @@ xe.scheduler.job.backtolist=Back to the job list
28962896
xe.scheduler.job.object=This sheet must be applied to a page that holds a scheduler job object.
28972897
xe.scheduler.updateJobClassComment=Created/Updated Scheduler Job Class definition
28982898
xe.scheduler.invalidToken=Invalid token, please try again by clicking on the desired action below.
2899+
xe.scheduler.missingProgrammingRights=This action requires programming rights.
28992900

29002901
### Statistics application
29012902
xe.statistics.activity=Activity Statistics

xwiki-platform-core/xwiki-platform-scheduler/xwiki-platform-scheduler-ui/pom.xml

+21
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,26 @@
9797
<type>test-jar</type>
9898
<scope>test</scope>
9999
</dependency>
100+
<!-- Provides the component list for SecurityAuthorizationScriptService. -->
101+
<dependency>
102+
<groupId>org.xwiki.platform</groupId>
103+
<artifactId>xwiki-platform-security-authorization-script</artifactId>
104+
<version>${project.version}</version>
105+
<scope>test</scope>
106+
</dependency>
107+
<dependency>
108+
<groupId>org.xwiki.platform</groupId>
109+
<artifactId>xwiki-platform-security-authorization-script</artifactId>
110+
<version>${project.version}</version>
111+
<type>test-jar</type>
112+
<scope>test</scope>
113+
</dependency>
114+
<!-- Provides TranslationMacro -->
115+
<dependency>
116+
<groupId>org.xwiki.platform</groupId>
117+
<artifactId>xwiki-platform-localization-macro</artifactId>
118+
<version>${project.version}</version>
119+
<scope>test</scope>
120+
</dependency>
100121
</dependencies>
101122
</project>

xwiki-platform-core/xwiki-platform-scheduler/xwiki-platform-scheduler-ui/src/main/resources/Scheduler/WebHome.xml

+30-23
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
##
4242
#set ($scheduler = $xwiki.scheduler)
4343
##
44-
## If the sheet is called with an action ($request.do), let us first process this action
44+
## If the sheet is called with an action ($request.do), let us first process this action after checking the user has
45+
## programming rights.
4546
## Possible values are : "schedule", "pause", "resume", "unschedule", "delete"
4647
##
4748
#if ("$!request.do" != '' &amp;&amp; "$!request.which" != '')
@@ -51,23 +52,29 @@
5152
#set ($tJobHolder = $request.which)
5253
#set ($jobDoc = $xwiki.getDocument($tJobHolder))
5354
#set ($jobObj = $jobDoc.getObject('XWiki.SchedulerJobClass'))
54-
#if (!$services.csrf.isTokenValid($request.form_token))
55+
#if (!$services.security.authorization.hasAccess('programming', $xcontext.userReference, $doc.documentReference))
56+
##
57+
## Check that the user has programming rights
58+
##
59+
{{error}}{{translation key='xe.scheduler.missingProgrammingRights'/}}{{/error}}
60+
61+
#elseif (!$services.csrf.isTokenValid($request.form_token))
5562
##
5663
## Check that the CSRF token matches the user before any operation
5764
##
58-
{{error}}$services.localization.render('xe.scheduler.invalidToken'){{/error}}
65+
{{error}}{{translation key='xe.scheduler.invalidToken'/}}{{/error}}
5966

6067
#elseif ($request.do == 'schedule')
6168
##
6269
## Schedule a job
6370
##
6471
#set ($ok = $scheduler.scheduleJob($jobObj))
6572
#if (!$ok)
66-
{{error}}$xcontext.get('error'){{/error}}
73+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
6774

6875
#else
6976
#set ($jobName = "$jobObj.get('jobName')")
70-
{{info}}$services.localization.render('xe.scheduler.jobscheduled', [$jobName, $scheduler.getNextFireTime($jobObj)]){{/info}}
77+
{{info}}$escapetool.xml($services.localization.render('xe.scheduler.jobscheduled', [$jobName, $scheduler.getNextFireTime($jobObj)])){{/info}}
7178

7279
#end
7380
#elseif ($request.do == 'pause')
@@ -76,10 +83,10 @@
7683
##
7784
#set ($ok = $scheduler.pauseJob($jobObj))
7885
#if (!$ok)
79-
{{error}}$xcontext.get('error'){{/error}}
86+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
8087

8188
#else
82-
{{info}}$services.localization.render('xe.scheduler.paused', [$jobObj.get('jobName')]){{/info}}
89+
{{info}}$escapetool.xml($services.localization.render('xe.scheduler.paused', [$jobObj.get('jobName')])){{/info}}
8390

8491
#end
8592
#elseif ($request.do == 'resume')
@@ -88,10 +95,10 @@
8895
##
8996
#set ($ok = $scheduler.resumeJob($jobObj))
9097
#if (!$ok)
91-
{{error}}$xcontext.get('error'){{/error}}
98+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
9299

93100
#else
94-
{{info}}$services.localization.render('xe.scheduler.resumed', [$jobObj.get('jobName'), $scheduler.getNextFireTime($jobObj)]){{/info}}
101+
{{info}}$escapetool.xml($services.localization.render('xe.scheduler.resumed', [$jobObj.get('jobName'), $scheduler.getNextFireTime($jobObj)])){{/info}}
95102

96103
#end
97104
#elseif ($request.do == 'unschedule')
@@ -100,10 +107,10 @@
100107
##
101108
#set ($ok = $scheduler.unscheduleJob($jobObj))
102109
#if (!$ok)
103-
{{error}}$xcontext.get('error'){{/error}}
110+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
104111

105112
#else
106-
{{info}}$services.localization.render('xe.scheduler.unscheduled', [$jobObj.get('jobName')]){{/info}}
113+
{{info}}$escapetool.xml($services.localization.render('xe.scheduler.unscheduled', [$jobObj.get('jobName')])){{/info}}
107114

108115
#end
109116
#elseif ($request.do == 'delete')
@@ -118,7 +125,7 @@
118125
#set ($deleteRedirect = $xwiki.getURL($jobObj.getName(), 'delete'))
119126
$response.sendRedirect($deleteRedirect)
120127
#else
121-
{{error}}$xcontext.get('error'){{/error}}
128+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
122129

123130
#end
124131
#else
@@ -131,23 +138,23 @@
131138
##
132139
#set ($ok = $scheduler.triggerJob($jobObj))
133140
#if (!$ok)
134-
{{error}}$xcontext.get('error'){{/error}}
141+
{{error}}$escapetool.xml($xcontext.get('error')){{/error}}
135142

136143
#else
137-
{{info}}$services.localization.render('xe.scheduler.triggered', [$jobObj.get('jobName')]){{/info}}
144+
{{info}}$escapetool.xml($services.localization.render('xe.scheduler.triggered', [$jobObj.get('jobName')])){{/info}}
138145

139146
#end
140147
#end
141148
#end
142-
$services.localization.render('xe.scheduler.welcome')
149+
{{translation key='xe.scheduler.welcome'/}}
143150

144-
= $services.localization.render('xe.scheduler.jobs.list') =
151+
= {{translation key='xe.scheduler.jobs.list'/}} =
145152

146153
##
147154
## Retrieve all scheduler jobs
148155
## Display their name, status, possible next fire time, and available actions
149156
##
150-
|=(%scope="col"%)$services.localization.render('xe.scheduler.jobs.name')|=(%scope="col"%)$services.localization.render('xe.scheduler.jobs.status')|=(%scope="col"%)$services.localization.render('xe.scheduler.jobs.next')|=(%scope="col"%)$services.localization.render('xe.scheduler.jobs.actions')
157+
|=(%scope="col"%){{translation key='xe.scheduler.jobs.name'/}}|=(%scope="col"%){{translation key='xe.scheduler.jobs.status'/}}|=(%scope="col"%){{translation key='xe.scheduler.jobs.next'/}}|=(%scope="col"%){{translation key='xe.scheduler.jobs.actions'/}}
151158
#foreach ($docName in $services.query.xwql('from doc.object(XWiki.SchedulerJobClass) as jobs where doc.fullName &lt;&gt; ''XWiki.SchedulerJobTemplate''').execute())
152159
#set ($jobHolder = $xwiki.getDocument($docName))
153160
#set ($job = $jobHolder.getObject('XWiki.SchedulerJobClass'))
@@ -159,7 +166,7 @@ $services.localization.render('xe.scheduler.welcome')
159166
#if ($status != 'None')
160167
#set ($firetime = $scheduler.getNextFireTime($job))
161168
#else
162-
#set ($firetime = $services.localization.render('xe.scheduler.jobs.next.undefined'))
169+
#set ($firetime = "{{translation key='xe.scheduler.jobs.next.undefined'/}}")
163170
#end
164171
#set ($actions = ['trigger'])
165172
#if ($status == 'None')
@@ -170,7 +177,7 @@ $services.localization.render('xe.scheduler.welcome')
170177
#set ($ok = $actions.addAll(['resume', 'unschedule']))
171178
#end
172179
#set ($ok = $actions.add('delete'))
173-
|$job.get('jobName')|$status|$firetime|**$services.localization.render('xe.scheduler.jobs.actions.access')** [[$services.localization.render('xe.scheduler.jobs.actions.view')&gt;&gt;$services.rendering.escape($jobHolder.fullName, 'xwiki/2.1')]]#if($jobHolder.hasAccessLevel('programming')) [[$services.localization.render('xe.scheduler.jobs.actions.edit')&gt;&gt;path:${jobHolder.getURL('edit')}]]#end **$services.localization.render('xe.scheduler.jobs.actions.manage')**#foreach($action in $actions) [[$services.localization.render("xe.scheduler.jobs.actions.$action")&gt;&gt;path:$doc.getURL('view', $escapetool.url({'do': $action, 'which': $jobHolder.fullName, 'form_token': $services.csrf.token}))]]#end
180+
|$job.get('jobName')|$status|$firetime|**{{translation key='xe.scheduler.jobs.actions.access'/}}** [[{{translation key='xe.scheduler.jobs.actions.view'/}}&gt;&gt;$services.rendering.escape($jobHolder.fullName, 'xwiki/2.1')]]#if($jobHolder.hasAccessLevel('programming')) [[{{translation key='xe.scheduler.jobs.actions.edit'/}}&gt;&gt;path:${jobHolder.getURL('edit')}]]#end **{{translation key='xe.scheduler.jobs.actions.manage'/}}**#foreach($action in $actions) [[{{translation key='xe.scheduler.jobs.actions.$action'/}}&gt;&gt;path:$doc.getURL('view', $escapetool.url({'do': $action, 'which': $jobHolder.fullName, 'form_token': $services.csrf.token}))]]#end
174181

175182
#end
176183
#if ($doc.hasAccessLevel('programming'))
@@ -181,12 +188,12 @@ $services.localization.render('xe.scheduler.welcome')
181188
## schedule, pause, etc.
182189
##
183190

184-
= $services.localization.render('xe.scheduler.jobs.create') =
191+
= {{translation key='xe.scheduler.jobs.create'/}} =
185192

186193
##
187194
## Form to create a new Job
188195
##
189-
{{info}}$services.localization.render('xe.scheduler.jobs.explaincreate'){{/info}}
196+
{{info}}{{translation key='xe.scheduler.jobs.explaincreate'/}}{{/info}}
190197

191198
{{html}}
192199
&lt;form action="$doc.getURL('create')" id="newdoc" class="form-inline"&gt;&lt;div&gt;
@@ -195,7 +202,7 @@ $services.localization.render('xe.scheduler.welcome')
195202
&lt;input type="hidden" name="template" value="XWiki.SchedulerJobTemplate" /&gt;
196203
&lt;input type="hidden" name="sheet" value="1" /&gt;
197204
&lt;input type="hidden" name="space" value="Scheduler"/&gt;
198-
&lt;label class="sr-only" for="page"&gt;$services.localization.render('xe.scheduler.jobs.create.nameTip')&lt;/label&gt;
205+
&lt;label class="sr-only" for="page"&gt;$escapetool.xml($services.localization.render('xe.scheduler.jobs.create.nameTip'))&lt;/label&gt;
199206
&lt;input id="page" name="page" size="30" type="text"
200207
placeholder="$escapetool.xml($services.localization.render('xe.scheduler.jobs.create.nameTip'))" /&gt;
201208
&lt;span class="buttonwrapper"&gt;
@@ -207,7 +214,7 @@ $services.localization.render('xe.scheduler.welcome')
207214

208215
#else
209216

210-
{{warning}}$services.localization.render('xe.scheduler.jobs.warning'){{/warning}}
217+
{{warning}}{{translation key='xe.scheduler.jobs.warning'/}}{{/warning}}
211218

212219
#end
213220
{{/velocity}}</content>

xwiki-platform-core/xwiki-platform-scheduler/xwiki-platform-scheduler-ui/src/main/resources/Scheduler/WebPreferences.xml

+1-167
Original file line numberDiff line numberDiff line change
@@ -114,176 +114,10 @@
114114
<groups>XWiki.XWikiAdminGroup</groups>
115115
</property>
116116
<property>
117-
<levels>admin,edit</levels>
117+
<levels>view,edit,comment,delete,admin</levels>
118118
</property>
119119
<property>
120120
<users/>
121121
</property>
122122
</object>
123-
<object>
124-
<name>Scheduler.WebPreferences</name>
125-
<number>1</number>
126-
<className>XWiki.XWikiGlobalRights</className>
127-
<guid>0b2c7da3-315a-4a6d-b782-5de0b20b6497</guid>
128-
<class>
129-
<name>XWiki.XWikiGlobalRights</name>
130-
<customClass/>
131-
<customMapping/>
132-
<defaultViewSheet/>
133-
<defaultEditSheet/>
134-
<defaultWeb/>
135-
<nameField/>
136-
<validationScript/>
137-
<allow>
138-
<defaultValue>1</defaultValue>
139-
<disabled>0</disabled>
140-
<displayFormType>select</displayFormType>
141-
<displayType>allow</displayType>
142-
<name>allow</name>
143-
<number>4</number>
144-
<prettyName>Allow/Deny</prettyName>
145-
<unmodifiable>0</unmodifiable>
146-
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
147-
</allow>
148-
<groups>
149-
<cache>0</cache>
150-
<disabled>0</disabled>
151-
<displayType>input</displayType>
152-
<multiSelect>1</multiSelect>
153-
<name>groups</name>
154-
<number>1</number>
155-
<picker>1</picker>
156-
<prettyName>Groups</prettyName>
157-
<relationalStorage>0</relationalStorage>
158-
<separator> </separator>
159-
<size>5</size>
160-
<unmodifiable>0</unmodifiable>
161-
<classType>com.xpn.xwiki.objects.classes.GroupsClass</classType>
162-
</groups>
163-
<levels>
164-
<cache>0</cache>
165-
<disabled>0</disabled>
166-
<displayType>select</displayType>
167-
<multiSelect>1</multiSelect>
168-
<name>levels</name>
169-
<number>2</number>
170-
<prettyName>Levels</prettyName>
171-
<relationalStorage>0</relationalStorage>
172-
<separator> </separator>
173-
<size>3</size>
174-
<unmodifiable>0</unmodifiable>
175-
<classType>com.xpn.xwiki.objects.classes.LevelsClass</classType>
176-
</levels>
177-
<users>
178-
<cache>0</cache>
179-
<disabled>0</disabled>
180-
<displayType>input</displayType>
181-
<multiSelect>1</multiSelect>
182-
<name>users</name>
183-
<number>3</number>
184-
<picker>1</picker>
185-
<prettyName>Users</prettyName>
186-
<relationalStorage>0</relationalStorage>
187-
<separator> </separator>
188-
<size>5</size>
189-
<unmodifiable>0</unmodifiable>
190-
<classType>com.xpn.xwiki.objects.classes.UsersClass</classType>
191-
</users>
192-
</class>
193-
<property>
194-
<allow>0</allow>
195-
</property>
196-
<property>
197-
<groups>XWiki.XWikiAllGroup</groups>
198-
</property>
199-
<property>
200-
<levels>view</levels>
201-
</property>
202-
<property>
203-
<users/>
204-
</property>
205-
</object>
206-
<object>
207-
<name>Scheduler.WebPreferences</name>
208-
<number>2</number>
209-
<className>XWiki.XWikiGlobalRights</className>
210-
<guid>fef3f075-e0ed-46d1-991f-680326129a9d</guid>
211-
<class>
212-
<name>XWiki.XWikiGlobalRights</name>
213-
<customClass/>
214-
<customMapping/>
215-
<defaultViewSheet/>
216-
<defaultEditSheet/>
217-
<defaultWeb/>
218-
<nameField/>
219-
<validationScript/>
220-
<allow>
221-
<defaultValue>1</defaultValue>
222-
<disabled>0</disabled>
223-
<displayFormType>select</displayFormType>
224-
<displayType>allow</displayType>
225-
<name>allow</name>
226-
<number>4</number>
227-
<prettyName>Allow/Deny</prettyName>
228-
<unmodifiable>0</unmodifiable>
229-
<classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
230-
</allow>
231-
<groups>
232-
<cache>0</cache>
233-
<disabled>0</disabled>
234-
<displayType>input</displayType>
235-
<multiSelect>1</multiSelect>
236-
<name>groups</name>
237-
<number>1</number>
238-
<picker>1</picker>
239-
<prettyName>Groups</prettyName>
240-
<relationalStorage>0</relationalStorage>
241-
<separator> </separator>
242-
<size>5</size>
243-
<unmodifiable>0</unmodifiable>
244-
<classType>com.xpn.xwiki.objects.classes.GroupsClass</classType>
245-
</groups>
246-
<levels>
247-
<cache>0</cache>
248-
<disabled>0</disabled>
249-
<displayType>select</displayType>
250-
<multiSelect>1</multiSelect>
251-
<name>levels</name>
252-
<number>2</number>
253-
<prettyName>Levels</prettyName>
254-
<relationalStorage>0</relationalStorage>
255-
<separator> </separator>
256-
<size>3</size>
257-
<unmodifiable>0</unmodifiable>
258-
<classType>com.xpn.xwiki.objects.classes.LevelsClass</classType>
259-
</levels>
260-
<users>
261-
<cache>0</cache>
262-
<disabled>0</disabled>
263-
<displayType>input</displayType>
264-
<multiSelect>1</multiSelect>
265-
<name>users</name>
266-
<number>3</number>
267-
<picker>1</picker>
268-
<prettyName>Users</prettyName>
269-
<relationalStorage>0</relationalStorage>
270-
<separator> </separator>
271-
<size>5</size>
272-
<unmodifiable>0</unmodifiable>
273-
<classType>com.xpn.xwiki.objects.classes.UsersClass</classType>
274-
</users>
275-
</class>
276-
<property>
277-
<allow>0</allow>
278-
</property>
279-
<property>
280-
<groups/>
281-
</property>
282-
<property>
283-
<levels>view</levels>
284-
</property>
285-
<property>
286-
<users>XWiki.XWikiGuest</users>
287-
</property>
288-
</object>
289123
</xwikidoc>

0 commit comments

Comments
 (0)