1 23 24 package org.apache.slide.webdav.method; 25 26 import java.io.IOException ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Vector ; 31 import org.apache.slide.common.NamespaceAccessToken; 32 import org.apache.slide.common.ServiceAccessException; 33 import org.apache.slide.common.SlideException; 34 import org.apache.slide.common.Uri; 35 import org.apache.slide.content.NodeProperty; 36 import org.apache.slide.content.NodeRevisionDescriptor; 37 import org.apache.slide.content.NodeRevisionDescriptors; 38 import org.apache.slide.security.NodePermission; 39 import org.apache.slide.structure.ActionNode; 40 import org.apache.slide.structure.ObjectNode; 41 import org.apache.slide.structure.SubjectNode; 42 import org.apache.slide.webdav.WebdavException; 43 import org.apache.slide.webdav.WebdavServletConfig; 44 import org.apache.slide.webdav.event.WebdavEvent; 45 import org.apache.slide.webdav.util.AclConstants; 46 import org.apache.slide.webdav.util.PreconditionViolationException; 47 import org.apache.slide.webdav.util.ViolatedPrecondition; 48 import org.apache.slide.webdav.util.WebdavConstants; 49 import org.apache.slide.webdav.util.WebdavStatus; 50 import org.apache.slide.event.EventDispatcher; 51 import org.jdom.Element; 52 import org.jdom.JDOMException; 53 54 55 58 public class AclMethod extends AbstractWebdavMethod implements AclConstants, WriteMethod { 59 60 private String resourcePath; 61 private Vector permissions; 62 63 69 public AclMethod(NamespaceAccessToken token, WebdavServletConfig config) { 70 super(token, config); 71 } 72 73 78 protected void parseRequest() throws WebdavException { 79 80 permissions = new Vector (); 81 82 resourcePath = requestUri; 83 if (resourcePath == null) { 84 resourcePath = "/"; 85 } 86 87 try{ 88 Iterator aceIt = parseRequestContent(P_ACL).getChildren().iterator(); 89 while (aceIt.hasNext()) { 90 Element aceElm = (Element)aceIt.next(); 91 permissions.addAll( createNodePermissionList(aceElm) ); 92 } 93 } 94 catch (IOException e) { int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; 96 sendError( statusCode, e ); 97 throw new WebdavException( statusCode ); 98 } 99 catch (JDOMException e) { int statusCode = WebdavStatus.SC_BAD_REQUEST; 101 sendError( statusCode, e ); 102 throw new WebdavException( statusCode ); 103 } 104 catch (PreconditionViolationException e) { 105 try { 106 sendPreconditionViolation(e); 107 } catch (IOException x) {} 108 throw new WebdavException(e.getStatusCode()); 109 } 110 catch (SlideException e) { 111 int statusCode = WebdavStatus.SC_INTERNAL_SERVER_ERROR; 112 sendError( statusCode, e ); 113 throw new WebdavException( statusCode ); 114 } 115 } 116 117 private List createNodePermissionList( Element aceElm ) throws PreconditionViolationException, SlideException, JDOMException { 118 List result = new ArrayList (); 119 String objectUri = resourcePath; 120 String subjectUri = null; 121 String actionUri = null; 122 boolean negative = false; 123 boolean invert = false; 124 125 Element principalElm = aceElm.getChild(E_PRINCIPAL, DNSP); 127 if (principalElm == null) { 128 Element invertElm = aceElm.getChild(E_INVERT, DNSP); 129 if (invertElm != null) { 130 invert = true; 131 principalElm = invertElm.getChild(E_PRINCIPAL, DNSP); 132 } 133 } 134 if (principalElm != null) { 135 subjectUri = createSubjectUri(principalElm); 136 } 137 else { 138 throw new PreconditionViolationException( 139 new ViolatedPrecondition("missing-ace-principal", WebdavStatus.SC_BAD_REQUEST), resourcePath 140 ); 141 } 142 143 Element grantDenyElm = null; 145 Element grantElm = aceElm.getChild(E_GRANT, DNSP); 146 Element denyElm = aceElm.getChild(E_DENY, DNSP); 147 if (grantElm != null && denyElm == null) { 148 grantDenyElm = grantElm; 149 } 150 else if (grantElm == null && denyElm != null) { 151 negative = true; 152 grantDenyElm = denyElm; 153 } 154 else if(grantElm != null && denyElm != null) { 155 throw new PreconditionViolationException( 156 new ViolatedPrecondition("only-grant-or-deny-allowed", WebdavStatus.SC_BAD_REQUEST), resourcePath 157 ); 158 } 159 else if(grantElm == null && denyElm == null) { 160 throw new PreconditionViolationException( 161 new ViolatedPrecondition("missing-grant-or-deny", WebdavStatus.SC_BAD_REQUEST), resourcePath 162 ); 163 } 164 Iterator privilegeIt = grantDenyElm.getChildren(E_PRIVILEGE, DNSP).iterator(); 165 166 while (privilegeIt.hasNext()) { 167 Element privilegeElm = (Element)privilegeIt.next(); 168 actionUri = createActionUri(privilegeElm); 169 if (actionUri == null) { 170 throw new PreconditionViolationException( 171 new ViolatedPrecondition("not-supported-privilege", WebdavStatus.SC_BAD_REQUEST), resourcePath 172 ); 173 } 174 else { 175 NodePermission np = new NodePermission(objectUri, subjectUri, actionUri, true, negative); 176 np.setInvert(invert); 177 result.add(np); 178 } 179 } 180 return result; 181 } 182 183 private String createSubjectUri(Element principalElm) throws JDOMException, PreconditionViolationException { 184 Element elm = principalElm.getChild(E_HREF, DNSP); 185 if (elm != null) { 186 return getSlidePath(elm.getTextTrim()); 187 } 188 189 elm = principalElm.getChild(E_ALL, DNSP); 190 if (elm != null) { 191 return SubjectNode.ALL_URI; 192 } 193 194 elm = principalElm.getChild(E_AUTHENTICATED, DNSP); 195 if (elm != null) { 196 return SubjectNode.AUTHENTICATED_URI; 197 } 198 199 elm = principalElm.getChild(E_UNAUTHENTICATED, DNSP); 200 if (elm != null) { 201 return SubjectNode.UNAUTHENTICATED_URI; 202 } 203 204 elm = principalElm.getChild(E_SELF, DNSP); 205 if (elm != null) { 206 return SubjectNode.SELF_URI; 207 } 208 209 elm = principalElm.getChild(E_PROPERTY, DNSP); 210 if (elm != null) { 211 if (elm.getChild(E_OWNER, DNSP) != null) { 212 return SubjectNode.OWNER_URI; 213 } 214 else { 215 throw new PreconditionViolationException( 216 new ViolatedPrecondition("only-onwer-property-supported", WebdavStatus.SC_CONFLICT), resourcePath 217 ); 218 } 219 } 220 221 throw new PreconditionViolationException( 222 new ViolatedPrecondition("could-not-determine-principal", WebdavStatus.SC_BAD_REQUEST), resourcePath 223 ); 224 } 225 226 private String createActionUri(Element privilegeElm) throws JDOMException, PreconditionViolationException, SlideException { 227 Element privilegeChildElm = (Element)privilegeElm.getChildren().get(0); 228 String privilegeName = privilegeChildElm.getName(); 229 String privilegeNamespace = privilegeChildElm.getNamespaceURI(); 230 if (E_ALL.equals(privilegeName) && S_DAV.equals(privilegeNamespace)) { 231 return ActionNode.ALL_URI; 232 } 233 else { 234 ObjectNode actions = structure.retrieve(slideToken, token.getNamespaceConfig().getActionsPath()); 235 ObjectNode action = findAction(actions.getChildren().iterator(), privilegeName, privilegeNamespace); 236 return action != null ? action.getUri() : null; 237 } 238 } 239 240 249 private ObjectNode findAction(Iterator actionsIterator, String privilegeName, String privilegeNamespace) throws SlideException { 250 ObjectNode result = null; 251 while (result == null && actionsIterator.hasNext()) { 252 String aUriAsString = (String ) actionsIterator.next(); 253 ObjectNode aNode = structure.retrieve(slideToken, aUriAsString); 254 if (aNode.hasChildren()) { 255 result = findAction(aNode.getChildren().iterator(), privilegeName, privilegeNamespace); 256 } 257 else { 258 Uri aUri = token.getUri(slideToken, aUriAsString); 259 NodeRevisionDescriptors nrds = aUri.getStore().retrieveRevisionDescriptors(aUri); 260 NodeRevisionDescriptor latestNrd = aUri.getStore().retrieveRevisionDescriptor(aUri, nrds.getLatestRevision()); 261 NodeProperty aNamespaceAsNode = latestNrd.getProperty(AclConstants.P_PRIVILEGE_NAMESPACE, WebdavConstants.S_DAV); 262 String aNamespace = aNamespaceAsNode == null ? null : aNamespaceAsNode.getValue().toString(); 263 String aUriLastSegment = aUriAsString.substring(aUriAsString.lastIndexOf('/') + 1); 264 if (aUriLastSegment.equals(privilegeName) 265 && ((aNamespace != null && privilegeNamespace.equals(aNamespace)) 266 || (aNamespace == null && privilegeNamespace.equals(WebdavConstants.S_DAV)))) { 267 result = aNode; 268 } 269 } 270 } 271 return result; 272 } 273 274 280 private void checkPreconditions() throws PreconditionViolationException, ServiceAccessException { 281 resp.setStatus( WebdavStatus.SC_OK ); 282 } 283 284 289 protected void executeRequest() throws WebdavException, IOException { 290 291 slideToken.setForceStoreEnlistment(true); 293 294 try { 296 if (isLockNull(resourcePath)) { 297 int statusCode = WebdavStatus.SC_NOT_FOUND; 298 sendError( statusCode, "lock-null resource", new Object []{resourcePath} ); 299 throw new WebdavException( statusCode ); 300 } 301 } 302 catch (ServiceAccessException e) { 303 int statusCode = getErrorCode( e ); 304 sendError( statusCode, e ); 305 throw new WebdavException( statusCode ); 306 } 307 308 try { 309 if ( WebdavEvent.ACL.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(WebdavEvent.ACL, new WebdavEvent(this)); 310 311 checkPreconditions(); 312 security.setPermissions(slideToken, resourcePath, permissions.elements()); 313 } 314 catch (PreconditionViolationException e) { 315 sendPreconditionViolation(e); 316 throw e; 317 } 318 catch (Exception e) { 319 int statusCode = getErrorCode( e ); 320 sendError( statusCode, e ); 321 throw new WebdavException( statusCode ); 322 } 323 } 324 } 325 | Popular Tags |