1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.wiki.user.script

File WikiUserManagerScriptService.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

16
160
32
1
668
357
64
0.4
5
32
2

Classes

Class Line # Actions
WikiUserManagerScriptService 57 160 0% 64 5
0.9759615797.6%
 

Contributing tests

This file is covered by 68 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.wiki.user.script;
21   
22    import java.util.ArrayList;
23    import java.util.Collection;
24   
25    import javax.inject.Inject;
26    import javax.inject.Named;
27    import javax.inject.Provider;
28    import javax.inject.Singleton;
29   
30    import org.xwiki.component.annotation.Component;
31    import org.xwiki.context.Execution;
32    import org.xwiki.model.reference.DocumentReference;
33    import org.xwiki.model.reference.DocumentReferenceResolver;
34    import org.xwiki.model.reference.WikiReference;
35    import org.xwiki.script.service.ScriptService;
36    import org.xwiki.security.authorization.AccessDeniedException;
37    import org.xwiki.security.authorization.AuthorizationManager;
38    import org.xwiki.security.authorization.Right;
39    import org.xwiki.wiki.descriptor.WikiDescriptorManager;
40    import org.xwiki.wiki.user.MemberCandidacy;
41    import org.xwiki.wiki.user.MembershipType;
42    import org.xwiki.wiki.user.UserScope;
43    import org.xwiki.wiki.user.WikiUserManager;
44    import org.xwiki.wiki.user.WikiUserManagerException;
45   
46    import com.xpn.xwiki.XWikiContext;
47   
48    /**
49    * Script service to manage how the user are supported in a wiki.
50    *
51    * @since 5.3M2
52    * @version $Id: 569b56ae5060434bb59350ee1c7d7d52d6eacd46 $
53    */
54    @Component
55    @Named("wiki.user")
56    @Singleton
 
57    public class WikiUserManagerScriptService implements ScriptService
58    {
59    /**
60    * The key under which the last encountered error is stored in the current execution context.
61    */
62    private static final String WIKIUSERERROR_KEY = "scriptservice.wiki.user.error";
63   
64    @Inject
65    private WikiUserManager wikiUserManager;
66   
67    @Inject
68    private WikiDescriptorManager wikiDescriptorManager;
69   
70    @Inject
71    private AuthorizationManager authorizationManager;
72   
73    @Inject
74    private Provider<XWikiContext> xcontextProvider;
75   
76    @Inject
77    private DocumentReferenceResolver<String> documentReferenceResolver;
78   
79    /**
80    * Provides access to the current context.
81    */
82    @Inject
83    private Execution execution;
84   
85    /**
86    * Get the error generated while performing the previously called action.
87    *
88    * @return an eventual exception or {@code null} if no exception was thrown
89    */
 
90  50 toggle public Exception getLastError()
91    {
92  50 return (Exception) this.execution.getContext().getProperty(WIKIUSERERROR_KEY);
93    }
94   
95    /**
96    * Store a caught exception in the context, so that it can be later retrieved using {@link #getLastError()}.
97    *
98    * @param e the exception to store, can be {@code null} to clear the previously stored exception
99    * @see #getLastError()
100    */
 
101  38 toggle private void setLastError(Exception e)
102    {
103  38 this.execution.getContext().setProperty(WIKIUSERERROR_KEY, e);
104    }
105   
106    /**
107    * @return the user scope
108    */
 
109  40 toggle public UserScope getUserScope()
110    {
111  40 return getUserScope(wikiDescriptorManager.getCurrentWikiId());
112    }
113   
114    /**
115    * @param wikiId Id of the wiki to test
116    * @return the user scope
117    */
 
118  43 toggle public UserScope getUserScope(String wikiId)
119    {
120  43 try {
121  43 return wikiUserManager.getUserScope(wikiId);
122    } catch (WikiUserManagerException e) {
123  1 setLastError(e);
124  1 return null;
125    }
126    }
127   
128    /**
129    * Check that all required permissions are respected by both the script and the user.
130    *
131    * @param wikiId the id of the wiki concerned by the operation
132    *
133    * @throws AccessDeniedException if the permissions are not respected
134    */
 
135  21 toggle private void checkRights(String wikiId) throws AccessDeniedException
136    {
137  21 checkRights(wikiId, null);
138    }
139   
140    /**
141    * Check that all required permissions are respected by both the script and the user.
142    *
143    * @param wikiId the id of the wiki concerned by the operation
144    * @param user the user concerned by the operation
145    *
146    * @throws AccessDeniedException if the permissions are not respected
147    */
 
148  48 toggle private void checkRights(String wikiId, DocumentReference user) throws AccessDeniedException
149    {
150  48 XWikiContext context = xcontextProvider.get();
151   
152    // Does the script author have the admin right?
153    //
154    // The goal is to avoid that a non-granted user writes a script, which could be executed by an administrator,
155    // which uses this script service to perform "nasty" operations, like being invited to a sub-wiki.
156    //
157    // By the past, we checked for the programing right, but it was too restrictive, as it make impossible to
158    // a user without programing rights to create a wiki and then invite some peoples in it.
159  48 authorizationManager.checkAccess(Right.ADMIN, context.getDoc().getAuthorReference(),
160    context.getDoc().getDocumentReference());
161   
162    // Is the user concerned by the operation?
163  40 if (user != null && user.equals(context.getUserReference())) {
164    // If the user is concerned, then she has the right to perform this operation.
165  18 return;
166    }
167   
168    // Does the current user have the admin right?
169  22 authorizationManager.checkAccess(Right.ADMIN, context.getUserReference(), new WikiReference(wikiId));
170    }
171   
172    /**
173    * Check that all required permissions are respected by both the script and the user concerned by a candidacy.
174    *
175    * @param candidacy the candidacy concerned by the operation
176    *
177    * @throws AccessDeniedException if the permissions are not respected
178    */
 
179  15 toggle private void checkRights(MemberCandidacy candidacy) throws AccessDeniedException
180    {
181  15 checkRights(candidacy.getWikiId(), documentReferenceResolver.resolve(candidacy.getUserId()));
182    }
183   
184   
185    /**
186    * @param wikiId Id of the wiki to change
187    * @param scope scope to set
188    * @return true if it succeed
189    */
 
190  6 toggle public boolean setUserScope(String wikiId, String scope)
191    {
192  6 try {
193  6 checkRights(wikiId);
194  4 wikiUserManager.setUserScope(wikiId, UserScope.valueOf(scope.toUpperCase()));
195    } catch (WikiUserManagerException | AccessDeniedException | IllegalArgumentException e) {
196  4 setLastError(e);
197  4 return false;
198    }
199   
200  2 return true;
201    }
202   
203    /**
204    * @return the membership type of the current wiki
205    */
 
206  1 toggle public MembershipType getMembershipType()
207    {
208  1 return getMembershipType(wikiDescriptorManager.getCurrentWikiId());
209    }
210   
211    /**
212    * @param wikiId Id of the wiki to test
213    * @return the membership type of the specified wiki
214    */
 
215  4 toggle public MembershipType getMembershipType(String wikiId)
216    {
217  4 try {
218  4 return wikiUserManager.getMembershipType(wikiId);
219    } catch (WikiUserManagerException e) {
220  1 setLastError(e);
221  1 return null;
222    }
223    }
224   
225    /**
226    * @param wikiId Id of the wiki to change
227    * @param type the membership type to set
228    * @return true if it succeed
229    */
 
230  4 toggle public boolean setMembershipType(String wikiId, String type)
231    {
232  4 try {
233  4 checkRights(wikiId);
234  2 wikiUserManager.setMembershipType(wikiId, MembershipType.valueOf(type.toUpperCase()));
235    } catch (WikiUserManagerException | AccessDeniedException | IllegalArgumentException e) {
236  4 setLastError(e);
237  4 return false;
238    }
239   
240  0 return true;
241    }
242   
243    /**
244    * @param wikiId if the the wiki
245    * @return the list of all the members (global users) or null if something failed.
246    */
 
247  2 toggle public Collection<String> getMembers(String wikiId)
248    {
249  2 try {
250  2 return wikiUserManager.getMembers(wikiId);
251    } catch (WikiUserManagerException e) {
252  1 setLastError(e);
253  1 return null;
254    }
255    }
256   
257    /**
258    * To know if a user is a member of a wiki.
259    *
260    * @param userId Id of the user
261    * @param wikiId Id of the wiki
262    * @return if the user is a member of the specified wiki or null if some problems occur
263    */
 
264  157 toggle public Boolean isMember(String userId, String wikiId)
265    {
266  157 try {
267  157 return wikiUserManager.isMember(userId, wikiId);
268    } catch (WikiUserManagerException e) {
269  1 setLastError(e);
270  1 return null;
271    }
272    }
273   
274    /**
275    * Add a user as a member.
276    *
277    * @param userId UserID to add
278    * @param wikiId Id of the wiki
279    * @return true if it succeed
280    */
 
281  3 toggle public boolean addMember(String userId, String wikiId)
282    {
283  3 try {
284  3 checkRights(wikiId);
285  1 wikiUserManager.addMember(userId, wikiId);
286    } catch (AccessDeniedException | WikiUserManagerException e) {
287  2 setLastError(e);
288  2 return false;
289    }
290   
291  1 return true;
292    }
293   
294    /**
295    * Add a list of users as a members.
296    *
297    * @param userIds List of userID to add
298    * @param wikiId Id of the wiki
299    * @return true if it succeed
300    */
 
301  3 toggle public boolean addMembers(Collection<String> userIds, String wikiId)
302    {
303  3 try {
304  3 checkRights(wikiId);
305  1 wikiUserManager.addMembers(userIds, wikiId);
306    } catch (AccessDeniedException | WikiUserManagerException e) {
307  2 setLastError(e);
308  2 return false;
309    }
310   
311  1 return true;
312    }
313   
314    /**
315    * Remove a member.
316    *
317    * @param userId UserID to remove
318    * @param wikiId Id the the wiki
319    * @return true if it succeed
320    */
 
321  3 toggle public boolean removeMember(String userId, String wikiId)
322    {
323  3 try {
324  3 checkRights(wikiId);
325  1 wikiUserManager.removeMember(userId, wikiId);
326    } catch (AccessDeniedException | WikiUserManagerException e) {
327  2 setLastError(e);
328  2 return false;
329    }
330   
331  1 return true;
332    }
333   
 
334  7 toggle private boolean canSeeCandidacy(MemberCandidacy candidacy)
335    {
336  7 XWikiContext context = xcontextProvider.get();
337   
338    // Test if the user is concerned by the candidacy...
339  7 DocumentReference candidacyUser = documentReferenceResolver.resolve(candidacy.getUserId());
340  7 if (context.getUserReference().equals(candidacyUser)) {
341    // Hide the admin private comment
342  3 candidacy.setAdminPrivateComment(null);
343  3 return true;
344    }
345   
346    // Otherwise the user must be an admin.
347  4 return authorizationManager.hasAccess(Right.ADMIN, context.getUserReference(),
348    new WikiReference(candidacy.getWikiId()));
349    }
350   
351    /**
352    * Get the specified candidacy.
353    *
354    * @param wikiId Id of the wiki concerned by the candidacy
355    * @param candidacyId id of the candidacy
356    * @return the candidacy or null if problems occur
357    */
 
358  4 toggle public MemberCandidacy getCandidacy(String wikiId, int candidacyId)
359    {
360    // Get the candidacy
361  4 MemberCandidacy candidacy = null;
362  4 try {
363  4 candidacy = wikiUserManager.getCandidacy(wikiId, candidacyId);
364    // Check the rights
365  3 if (!canSeeCandidacy(candidacy)) {
366  1 setLastError(new WikiUserManagerScriptServiceException("You are not allowed to see this candidacy."));
367  1 candidacy = null;
368    }
369    } catch (WikiUserManagerException e) {
370  1 setLastError(e);
371    }
372   
373  4 return candidacy;
374    }
375   
376    /**
377    * Filter from a list of candidacies those that the current user has the right to see.
378    *
379    * @param candidacies list to filter
380    * @return the filtered list
381    */
 
382  2 toggle private Collection<MemberCandidacy> filterAuthorizedCandidacies(Collection<MemberCandidacy> candidacies)
383    {
384  2 Collection<MemberCandidacy> authorizedCandidacies = new ArrayList<MemberCandidacy>();
385   
386  2 for (MemberCandidacy candidacy : candidacies) {
387  4 if (canSeeCandidacy(candidacy)) {
388  2 authorizedCandidacies.add(candidacy);
389    }
390    }
391   
392  2 return authorizedCandidacies;
393    }
394   
395    /**
396    * Get all the invitations to join a wiki.
397    *
398    * @param wikiId id of the wiki to join
399    * @return a list of invitations to join this wiki or null if some problems occur
400    */
 
401  2 toggle public Collection<MemberCandidacy> getAllInvitations(String wikiId)
402    {
403  2 try {
404  2 Collection<MemberCandidacy> candidacies = wikiUserManager.getAllInvitations(wikiId);
405  1 return filterAuthorizedCandidacies(candidacies);
406    } catch (WikiUserManagerException e) {
407  1 setLastError(e);
408  1 return null;
409    }
410    }
411   
412    /**
413    * @param user DocumentReference to the user to test
414    * @param wikiId id of the wiki to test
415    * @return either or not the user has a pending invitation to join the wiki, null if some problems occur
416    */
 
417  4 toggle public Boolean hasPendingInvitation(DocumentReference user, String wikiId)
418    {
419    // Guest users never have pending invitations!
420  4 if (user == null) {
421  0 return false;
422    }
423   
424  4 try {
425  4 checkRights(wikiId, user);
426  3 return wikiUserManager.hasPendingInvitation(user, wikiId);
427    } catch (AccessDeniedException | WikiUserManagerException e) {
428  2 setLastError(e);
429    }
430   
431  2 return null;
432    }
433   
434    /**
435    * @param user DocumentReference to the user to test
436    * @param wikiId id of the wiki to test
437    * @return either or not the user has a pending request to join the wiki, null if some problems occur
438    */
 
439  4 toggle public Boolean hasPendingRequest(DocumentReference user, String wikiId)
440    {
441    // Guest users never have pending requests!
442  4 if (user == null) {
443  0 return false;
444    }
445   
446  4 try {
447  4 checkRights(wikiId, user);
448  3 return wikiUserManager.hasPendingRequest(user, wikiId);
449    } catch (AccessDeniedException | WikiUserManagerException e) {
450  2 setLastError(e);
451    }
452   
453  2 return null;
454    }
455   
456    /**
457    * Get all the join requests for a wiki that the current user has the right to see.
458    *
459    * @param wikiId id of the wiki to join
460    * @return a list of join request for this wiki or null if some problems occur
461    */
 
462  2 toggle public Collection<MemberCandidacy> getAllRequests(String wikiId)
463    {
464  2 try {
465  2 Collection<MemberCandidacy> candidacies = wikiUserManager.getAllRequests(wikiId);
466  1 return filterAuthorizedCandidacies(candidacies);
467    } catch (WikiUserManagerException e) {
468  1 setLastError(e);
469  1 return null;
470    }
471    }
472   
473    /**
474    * Join a wiki.
475    *
476    * @param userId userId to add to the wiki
477    * @param wikiId id of the wiki
478    * @return true if it succeed
479    */
 
480  3 toggle public boolean join(String userId, String wikiId)
481    {
482    // Check if the current user is userId
483  3 XWikiContext context = xcontextProvider.get();
484  3 DocumentReference candidacyUser = documentReferenceResolver.resolve(userId);
485  3 if (!context.getUserReference().equals(candidacyUser)) {
486  1 setLastError(new WikiUserManagerException(String.format("User [%s] cannot call "
487    + "$services.wiki.user.join() with an other userId.", context.getUserReference())));
488  1 return false;
489    }
490   
491  2 try {
492  2 wikiUserManager.join(userId, wikiId);
493    } catch (WikiUserManagerException e) {
494  1 setLastError(e);
495  1 return false;
496    }
497  1 return true;
498    }
499   
500    /**
501    * Leave a wiki.
502    *
503    * @param userId userId to remove from the wiki
504    * @param wikiId id of the wiki
505    * @return true if it succeed
506    */
 
507  3 toggle public boolean leave(String userId, String wikiId)
508    {
509    // Check if the current user is userId
510  3 XWikiContext context = xcontextProvider.get();
511  3 DocumentReference candidacyUser = documentReferenceResolver.resolve(userId);
512  3 if (!context.getUserReference().equals(candidacyUser)) {
513  1 setLastError(new WikiUserManagerException(String.format("User [%s] cannot call $services.wiki.user.leave()"
514    + " with an other userId.", context.getUserReference())));
515  1 return false;
516    }
517   
518    // Leave the wiki
519  2 try {
520  2 wikiUserManager.leave(userId, wikiId);
521    } catch (WikiUserManagerException e) {
522  1 setLastError(e);
523  1 return false;
524    }
525   
526  1 return true;
527    }
528   
529    /**
530    * Perform a request to join a wiki.
531    *
532    * @param userId UserID of the requester
533    * @param wikiId Id of the wiki to join
534    * @param message Message that motivates the request
535    * @return the generated candidacy
536    */
 
537  4 toggle public MemberCandidacy askToJoin(String userId, String wikiId, String message)
538    {
539  4 try {
540  4 checkRights(wikiId, documentReferenceResolver.resolve(userId));
541  2 return wikiUserManager.askToJoin(userId, wikiId, message);
542    } catch (AccessDeniedException | WikiUserManagerException e) {
543  2 setLastError(e);
544  2 return null;
545    }
546    }
547   
548    /**
549    * Accept the request to join the wiki.
550    *
551    * @param request request to accept
552    * @param message message about the acceptance
553    * @param privateComment private comment that only the administrator can see
554    * @return true if it succeed
555    */
 
556  3 toggle public boolean acceptRequest(MemberCandidacy request, String message, String privateComment)
557    {
558  3 try {
559  3 checkRights(request);
560  2 wikiUserManager.acceptRequest(request, message, privateComment);
561  2 return true;
562    } catch (AccessDeniedException | WikiUserManagerException e) {
563  1 setLastError(e);
564    }
565   
566  1 return false;
567    }
568   
569    /**
570    * Refuse the request to join the wiki.
571    *
572    * @param request request to refuse
573    * @param message message about the refusal
574    * @param privateComment private comment that only the administrator can see
575    * @return true if it succeed
576    */
 
577  3 toggle public boolean refuseRequest(MemberCandidacy request, String message, String privateComment)
578    {
579  3 try {
580  3 checkRights(request);
581  2 wikiUserManager.refuseRequest(request, message, privateComment);
582  2 return true;
583    } catch (AccessDeniedException | WikiUserManagerException e) {
584  1 setLastError(e);
585    }
586   
587  1 return false;
588    }
589   
590    /**
591    * Cancel a candidacy.
592    *
593    * @param candidacy Candidacy to cancel
594    * @return true if it succeed
595    */
 
596  3 toggle public boolean cancelCandidacy(MemberCandidacy candidacy)
597    {
598  3 try {
599  3 checkRights(candidacy);
600  2 wikiUserManager.cancelCandidacy(candidacy);
601  2 return true;
602    } catch (AccessDeniedException | WikiUserManagerException e) {
603  1 setLastError(e);
604    }
605   
606  1 return false;
607    }
608   
609    /**
610    * Invite a global user to a wiki.
611    *
612    * @param userId Id of the user to add
613    * @param wikiId Id of the wiki to join
614    * @param message MemberCandidacy message
615    * @return The generated invitation or null if problems occur
616    */
 
617  2 toggle public MemberCandidacy invite(String userId, String wikiId, String message)
618    {
619  2 try {
620  2 checkRights(wikiId);
621  1 return wikiUserManager.invite(userId, wikiId, message);
622    } catch (AccessDeniedException | WikiUserManagerException e) {
623  1 setLastError(e);
624    }
625   
626  1 return null;
627    }
628   
629    /**
630    * Accept the invitation to join a wiki.
631    *
632    * @param invitation invitation to accept
633    * @param message message that goes along the acceptance
634    * @return true if it succeed
635    */
 
636  3 toggle public boolean acceptInvitation(MemberCandidacy invitation, String message)
637    {
638  3 try {
639  3 checkRights(invitation);
640  2 wikiUserManager.acceptInvitation(invitation, message);
641  2 return true;
642    } catch (AccessDeniedException | WikiUserManagerException e) {
643  1 setLastError(e);
644    }
645   
646  1 return false;
647    }
648   
649    /**
650    * Refuse the invitation to join a wiki.
651    *
652    * @param invitation invitation to refuse
653    * @param message message that goes along the refusal
654    * @return true if it succeed
655    */
 
656  3 toggle public boolean refuseInvitation(MemberCandidacy invitation, String message)
657    {
658  3 try {
659  3 checkRights(invitation);
660  2 wikiUserManager.refuseInvitation(invitation, message);
661  2 return true;
662    } catch (AccessDeniedException | WikiUserManagerException e) {
663  1 setLastError(e);
664    }
665   
666  1 return false;
667    }
668    }