1 17 18 19 20 package org.apache.lenya.ac.file; 21 22 import java.io.File ; 23 import java.io.FileFilter ; 24 import java.io.FileInputStream ; 25 import java.io.InputStream ; 26 import java.net.URI ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 30 import org.apache.avalon.framework.activity.Disposable; 31 import org.apache.avalon.framework.logger.AbstractLogEnabled; 32 import org.apache.avalon.framework.parameters.ParameterException; 33 import org.apache.avalon.framework.parameters.Parameterizable; 34 import org.apache.avalon.framework.parameters.Parameters; 35 import org.apache.avalon.framework.service.ServiceException; 36 import org.apache.avalon.framework.service.ServiceManager; 37 import org.apache.avalon.framework.service.Serviceable; 38 import org.apache.cocoon.util.NetUtils; 39 import org.apache.excalibur.source.Source; 40 import org.apache.excalibur.source.SourceResolver; 41 import org.apache.lenya.ac.AccessControlException; 42 import org.apache.lenya.ac.Accreditable; 43 import org.apache.lenya.ac.AccreditableManager; 44 import org.apache.lenya.ac.Policy; 45 import org.apache.lenya.ac.Role; 46 import org.apache.lenya.ac.User; 47 import org.apache.lenya.ac.cache.CachingException; 48 import org.apache.lenya.ac.cache.SourceCache; 49 import org.apache.lenya.ac.impl.Credential; 50 import org.apache.lenya.ac.impl.DefaultPolicy; 51 import org.apache.lenya.ac.impl.InheritingPolicyManager; 52 import org.apache.lenya.ac.impl.PolicyBuilder; 53 import org.apache.lenya.ac.impl.RemovedAccreditablePolicyBuilder; 54 import org.apache.lenya.ac.impl.URLPolicy; 55 import org.apache.lenya.xml.DocumentHelper; 56 import org.w3c.dom.Document ; 57 58 61 public class FilePolicyManager extends AbstractLogEnabled implements InheritingPolicyManager, 62 Parameterizable, Disposable, Serviceable { 63 64 67 public FilePolicyManager() { 68 } 69 70 75 protected SourceCache getCache() { 76 return cache; 77 } 78 79 private SourceCache cache; 80 81 protected static final String URL_FILENAME = "url-policy.acml"; 82 protected static final String SUBTREE_FILENAME = "subtree-policy.acml"; 83 protected static final String USER_ADMIN_URL = "/admin/users/"; 84 85 94 public DefaultPolicy buildURLPolicy(AccreditableManager controller, String url) 95 throws AccessControlException { 96 return buildPolicy(controller, url, URL_FILENAME); 97 } 98 99 108 public DefaultPolicy buildSubtreePolicy(AccreditableManager controller, String url) 109 throws AccessControlException { 110 return buildPolicy(controller, url, SUBTREE_FILENAME); 111 } 112 113 122 protected DefaultPolicy buildPolicy(AccreditableManager controller, String url, 123 String policyFilename) throws AccessControlException { 124 125 if (getLogger().isDebugEnabled()) { 126 getLogger().debug("Building policy for URL [" + url + "]"); 127 } 128 129 DefaultPolicy policy = null; 130 131 String policyUri = getPolicySourceURI(url, policyFilename); 132 if (getLogger().isDebugEnabled()) { 133 getLogger().debug("Policy source URI resolved to: " + policyUri); 134 } 135 136 try { 137 PolicyBuilder builder = new PolicyBuilder(controller); 138 policy = (DefaultPolicy) getCache().get(policyUri, builder); 139 } catch (CachingException e) { 140 throw new AccessControlException(e); 141 } 142 143 if (getLogger().isDebugEnabled()) { 144 getLogger().debug("Policy exists: [" + (policy != null) + "]"); 145 } 146 147 if (policy == null) { 148 policy = new DefaultPolicy(); 149 } 150 return policy; 151 } 152 153 162 protected String getPolicySourceURI(String url, String policyFilename) 163 throws AccessControlException { 164 if (url.startsWith("/")) { 165 url = url.substring(1); 166 } 167 168 File policyFile = new File (getPoliciesDirectory(), url + File.separator + policyFilename); 169 String policyUri = policyFile.toURI().toString(); 170 if (getLogger().isDebugEnabled()) { 171 getLogger().debug("Computing policy URI [" + policyUri + "]"); 172 } 173 return policyUri; 174 } 175 176 184 protected File getPolicyFile(String url, String policyFilename) throws AccessControlException { 185 String fileUri = getPolicySourceURI(url, policyFilename); 186 File file; 187 try { 188 file = new File (new URI (NetUtils.encodePath(fileUri))); 189 } catch (final Exception e) { 190 throw new AccessControlException(e); 191 } 192 return file; 193 } 194 195 202 public void saveURLPolicy(String url, DefaultPolicy policy) throws AccessControlException { 203 getLogger().debug("Saving URL policy for URL [" + url + "]"); 204 savePolicy(url, policy, URL_FILENAME); 205 } 206 207 214 public void saveSubtreePolicy(String url, DefaultPolicy policy) throws AccessControlException { 215 getLogger().debug("Saving subtree policy for URL [" + url + "]"); 216 savePolicy(url, policy, SUBTREE_FILENAME); 217 } 218 219 227 protected void savePolicy(String url, DefaultPolicy policy, String filename) 228 throws AccessControlException { 229 230 File file = getPolicyFile(url, filename); 231 savePolicy(policy, file); 232 } 233 234 241 protected void savePolicy(DefaultPolicy policy, File file) throws AccessControlException { 242 Document document = PolicyBuilder.savePolicy(policy); 243 244 try { 245 if (!file.exists()) { 246 file.getParentFile().mkdirs(); 247 if (!file.createNewFile()) { 248 throw new AccessControlException("File [" + file + "] could not be created."); 249 } 250 } 251 DocumentHelper.writeDocument(document, file); 252 } catch (AccessControlException e) { 253 throw e; 254 } catch (Exception e) { 255 throw new AccessControlException("Path: [" + file.getAbsolutePath() + "]", e); 256 } 257 } 258 259 263 public Policy getPolicy(AccreditableManager controller, String url) 264 throws AccessControlException { 265 266 return new URLPolicy(controller, url, this); 267 } 268 269 protected static final String DIRECTORY_PARAMETER = "directory"; 270 271 private String policiesDirectoryUri; 272 private File policiesDirectory; 273 274 277 public void parameterize(Parameters parameters) throws ParameterException { 278 if (parameters.isParameter(DIRECTORY_PARAMETER)) { 279 policiesDirectoryUri = parameters.getParameter(DIRECTORY_PARAMETER); 280 if (getLogger().isDebugEnabled()) { 281 getLogger().debug("Policies directory URI: " + policiesDirectoryUri); 282 } 283 } 284 } 285 286 293 public File getPoliciesDirectory() throws AccessControlException { 294 295 if (policiesDirectory == null) { 296 SourceResolver resolver = null; 297 Source source = null; 298 File directory; 299 300 try { 301 resolver = (SourceResolver) getServiceManager().lookup(SourceResolver.ROLE); 302 source = resolver.resolveURI(policiesDirectoryUri); 303 getLogger().debug("Policies directory source: [" + source.getURI() + "]"); 304 directory = new File (new URI (NetUtils.encodePath(source.getURI()))); 305 } catch (final Exception e) { 306 throw new AccessControlException("Resolving policies directory failed: ", e); 307 } finally { 308 if (resolver != null) { 309 if (source != null) { 310 resolver.release(source); 311 } 312 getServiceManager().release(resolver); 313 } 314 } 315 316 getLogger().debug( 317 "Policies directory resolved to [" + directory.getAbsolutePath() + "]"); 318 setPoliciesDirectory(directory); 319 } 320 321 return policiesDirectory; 322 } 323 324 327 public void service(ServiceManager manager) throws ServiceException { 328 this.serviceManager = manager; 329 this.cache = (SourceCache) manager.lookup(SourceCache.ROLE); 330 } 331 332 339 public void setPoliciesDirectory(File directory) throws AccessControlException { 340 getLogger().debug("Setting policies directory [" + directory.getAbsolutePath() + "]"); 341 if (!directory.isDirectory()) { 342 throw new AccessControlException("Policies directory invalid: [" 343 + directory.getAbsolutePath() + "]"); 344 } 345 policiesDirectory = directory; 346 } 347 348 352 public DefaultPolicy[] getPolicies(AccreditableManager controller, String url) 353 throws AccessControlException { 354 355 List policies = new ArrayList (); 356 357 Policy policy = buildURLPolicy(controller, url); 358 policies.add(policy); 359 360 String [] directories = url.split("/"); 361 url = ""; 362 363 for (int i = 0; i < directories.length; i++) { 364 url += directories[i] + "/"; 365 policy = buildSubtreePolicy(controller, url); 366 policies.add(policy); 367 } 368 369 return (DefaultPolicy[]) policies.toArray(new DefaultPolicy[policies.size()]); 370 } 371 372 375 public void dispose() { 376 377 if (getCache() != null) { 378 getServiceManager().release(getCache()); 379 } 380 381 if (getLogger().isDebugEnabled()) { 382 getLogger().debug("Disposing [" + this + "]"); 383 } 384 } 385 386 394 protected void removeAccreditable(AccreditableManager manager, Accreditable accreditable, 395 File policyDirectory) throws AccessControlException { 396 397 File [] policyFiles = policyDirectory.listFiles(new FileFilter () { 398 public boolean accept(File file) { 399 return file.getName().equals(SUBTREE_FILENAME) 400 || file.getName().equals(URL_FILENAME); 401 } 402 }); 403 404 try { 405 RemovedAccreditablePolicyBuilder builder = new RemovedAccreditablePolicyBuilder(manager); 406 builder.setRemovedAccreditable(accreditable); 407 for (int i = 0; i < policyFiles.length; i++) { 408 409 if (getLogger().isDebugEnabled()) { 410 getLogger().debug("Removing roles"); 411 getLogger().debug(" Accreditable: [" + accreditable + "]"); 412 getLogger().debug( 413 " File: [" + policyFiles[i].getAbsolutePath() + "]"); 414 } 415 416 InputStream stream = new FileInputStream (policyFiles[i]); 417 DefaultPolicy policy = builder.buildPolicy(stream); 418 policy.removeRoles(accreditable); 419 savePolicy(policy, policyFiles[i]); 420 } 421 } catch (Exception e) { 422 throw new AccessControlException(e); 423 } 424 425 File [] directories = policyDirectory.listFiles(new FileFilter () { 426 public boolean accept(File file) { 427 return file.isDirectory(); 428 } 429 }); 430 431 for (int i = 0; i < directories.length; i++) { 432 removeAccreditable(manager, accreditable, directories[i]); 433 } 434 435 } 436 437 441 public void accreditableRemoved(AccreditableManager manager, Accreditable accreditable) 442 throws AccessControlException { 443 444 if (getLogger().isDebugEnabled()) { 445 getLogger().debug("An accreditable was removed: [" + accreditable + "]"); 446 } 447 448 removeAccreditable(manager, accreditable, getPoliciesDirectory()); 449 450 if (accreditable instanceof User) { 451 Role role = URLPolicy.getAuthorRole(manager); 452 if (role != null) { 453 String url = USER_ADMIN_URL + ((User) accreditable).getId() + ".html"; 454 DefaultPolicy policy = buildSubtreePolicy(manager, url); 455 Credential credential = policy.getCredential(accreditable); 456 if (credential != null && credential.contains(role)) { 457 policy.removeRole(accreditable, role); 458 } 459 saveSubtreePolicy(url, policy); 460 } 461 } 462 } 463 464 private ServiceManager serviceManager; 465 466 471 protected ServiceManager getServiceManager() { 472 return serviceManager; 473 } 474 475 479 public void accreditableAdded(AccreditableManager manager, Accreditable accreditable) 480 throws AccessControlException { 481 if (accreditable instanceof User) { 482 Role role = URLPolicy.getAuthorRole(manager); 483 if (role != null) { 484 String url = USER_ADMIN_URL + ((User) accreditable).getId() + ".html"; 485 DefaultPolicy policy = buildSubtreePolicy(manager, url); 486 policy.addRole(accreditable, role); 487 saveSubtreePolicy(url, policy); 488 } 489 } 490 } 491 492 } | Popular Tags |