1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.extension.internal.validator

File AbstractExtensionValidator.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

20
40
13
1
216
132
25
0.62
3.08
13
1.92

Classes

Class Line # Actions
AbstractExtensionValidator 48 40 0% 25 19
0.73972674%
 

Contributing tests

This file is covered by 29 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.extension.internal.validator;
21   
22    import javax.inject.Inject;
23    import javax.inject.Named;
24   
25    import org.apache.commons.lang3.EnumUtils;
26    import org.xwiki.component.namespace.Namespace;
27    import org.xwiki.component.namespace.NamespaceUtils;
28    import org.xwiki.extension.Extension;
29    import org.xwiki.extension.InstallException;
30    import org.xwiki.extension.InstalledExtension;
31    import org.xwiki.extension.UninstallException;
32    import org.xwiki.extension.handler.ExtensionValidator;
33    import org.xwiki.job.Request;
34    import org.xwiki.model.EntityType;
35    import org.xwiki.model.reference.DocumentReference;
36    import org.xwiki.model.reference.EntityReference;
37    import org.xwiki.model.reference.EntityReferenceResolver;
38    import org.xwiki.security.authorization.AccessDeniedException;
39    import org.xwiki.security.authorization.AuthorizationManager;
40    import org.xwiki.security.authorization.Right;
41   
42    /**
43    * Base class helper to implement {@link ExtensionValidator}.
44    *
45    * @version $Id: 744bce5ed2828e2607e5411aeb9a00c4ff7d6d1c $
46    * @since 9.0RC1
47    */
 
48    public abstract class AbstractExtensionValidator implements ExtensionValidator
49    {
50    /**
51    * The name of the property containing the reference of the current user.
52    */
53    public static final String PROPERTY_USERREFERENCE = "user.reference";
54   
55    /**
56    * The name of the property containing the reference of the current author.
57    */
58    public static final String PROPERTY_CALLERREFERENCE = "caller.reference";
59   
60    /**
61    * The name of the property indicating of rights should be checked.
62    */
63    public static final String PROPERTY_CHECKRIGHTS = "checkrights";
64   
65    @Inject
66    protected AuthorizationManager authorization;
67   
68    @Inject
69    @Named("relative")
70    protected EntityReferenceResolver<String> resolver;
71   
72    protected Right entityRight = Right.PROGRAM;
73   
74    /**
75    * @param property the property containing a user reference
76    * @param request the request of the job currently being executed
77    * @return the reference of the user found in the request
78    */
 
79  483 toggle public static DocumentReference getRequestUserReference(String property, Request request)
80    {
81  483 Object obj = request.getProperty(property);
82   
83  483 if (obj instanceof DocumentReference) {
84  483 return (DocumentReference) obj;
85    }
86   
87  0 return null;
88    }
89   
 
90  323 toggle protected void checkAccess(EntityReference reference, Right right, Request request) throws AccessDeniedException
91    {
92    // Context author
93  323 checkAccess(PROPERTY_CALLERREFERENCE, reference, right, request);
94   
95    // Context user
96  323 checkAccess(PROPERTY_USERREFERENCE, reference, right, request);
97    }
98   
 
99  646 toggle private void checkAccess(String propertyCallerreference, EntityReference reference, Right right, Request request)
100    throws AccessDeniedException
101    {
102  646 if (request.getProperty(propertyCallerreference) != null) {
103  483 this.authorization.checkAccess(right, getRequestUserReference(propertyCallerreference, request), reference);
104    }
105    }
106   
 
107  142 toggle @Override
108    public void checkInstall(Extension extension, String namespace, Request request) throws InstallException
109    {
110  142 if (request.getProperty(PROPERTY_CHECKRIGHTS) == Boolean.TRUE) {
111  138 checkInstallInternal(extension, namespace, request);
112    }
113    }
114   
 
115  187 toggle protected void checkAccess(Extension extension, String namespaceString, Request request)
116    throws AccessDeniedException
117    {
118  187 checkAccess(this.entityRight, namespaceString, request);
119    }
120   
 
121  187 toggle protected void checkAccess(Right entityRight, String namespaceString, Request request) throws AccessDeniedException
122    {
123  187 Namespace namespace = NamespaceUtils.toNamespace(namespaceString);
124   
125    // Root namespace
126  187 if (namespace == null) {
127  41 checkRootRight(entityRight, request);
128   
129  37 return;
130    }
131   
132  146 if (namespace.getType() != null) {
133    // User
134  138 if (namespace.getType().equals("user")) {
135  0 EntityReference reference = this.resolver.resolve(namespace.getValue(), EntityType.DOCUMENT);
136   
137  0 checkUserRight(reference, request);
138    }
139   
140    // Entity
141  138 EntityType entityType = EnumUtils.getEnum(EntityType.class, namespace.getType().toUpperCase());
142  138 if (entityType != null) {
143  138 EntityReference reference = this.resolver.resolve(namespace.getValue(), entityType);
144   
145  138 checkAccess(reference, entityRight, request);
146    }
147    }
148   
149    // Unknown namespace
150  144 checkNamespaceRight(namespace, Right.PROGRAM, request);
151    }
152   
 
153  136 toggle protected void checkInstallInternal(Extension extension, String namespace, Request request) throws InstallException
154    {
155  136 try {
156  136 checkAccess(extension, namespace, request);
157    } catch (AccessDeniedException e) {
158  4 throw new InstallException(String.format("Install of extension [%s] is not allowed", extension.getId()), e);
159    }
160    }
161   
 
162  41 toggle private void checkRootRight(Right entityRight, Request request) throws AccessDeniedException
163    {
164    // Need programming right for root namespace
165  41 checkAccess(null, entityRight, request);
166    }
167   
 
168  0 toggle private void checkUserRight(EntityReference reference, Request request) throws AccessDeniedException
169    {
170    // Context author
171  0 checkUserAccess(PROPERTY_CALLERREFERENCE, reference, request);
172   
173    // Context user
174  0 checkUserAccess(PROPERTY_USERREFERENCE, reference, request);
175    }
176   
 
177  0 toggle private void checkUserAccess(String property, EntityReference reference, Request request)
178    throws AccessDeniedException
179    {
180  0 if (request.getProperty(property) != null) {
181    // Allow a user to install an extension in its own namespace
182  0 DocumentReference currentAuthorReference = getRequestUserReference(property, request);
183   
184  0 if (!currentAuthorReference.equals(reference)) {
185    // Need programming right to register an extension in another user namespace
186  0 checkAccess(null, Right.PROGRAM, request);
187    }
188    }
189    }
190   
 
191  144 toggle private void checkNamespaceRight(Namespace namespace, Right program, Request request) throws AccessDeniedException
192    {
193    // Check programming right by default
194  144 checkAccess(null, Right.PROGRAM, request);
195    }
196   
 
197  53 toggle @Override
198    public void checkUninstall(InstalledExtension extension, String namespace, Request request)
199    throws UninstallException
200    {
201  53 if (request.getProperty(PROPERTY_CHECKRIGHTS) == Boolean.TRUE) {
202  53 checkUninstallInternal(extension, namespace, request);
203    }
204    }
205   
 
206  51 toggle protected void checkUninstallInternal(InstalledExtension extension, String namespace, Request request)
207    throws UninstallException
208    {
209  51 try {
210  51 checkAccess(extension, namespace, request);
211    } catch (AccessDeniedException e) {
212  4 throw new UninstallException(String.format("Uninstall of extension [%s] is not allowed", extension.getId()),
213    e);
214    }
215    }
216    }