1 package org.jahia.services.webdav; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.FileNotFoundException ; 6 import java.io.InputStream ; 7 import java.security.Principal ; 8 import java.util.ArrayList ; 9 import java.util.Date ; 10 import java.util.Enumeration ; 11 import java.util.HashMap ; 12 import java.util.HashSet ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Map ; 16 import java.util.Properties ; 17 import java.util.Set ; 18 import java.util.Vector ; 19 20 import javax.transaction.Status ; 21 22 import org.apache.log4j.Logger; 23 import org.apache.slide.authenticate.CredentialsToken; 24 import org.apache.slide.authenticate.SecurityToken; 25 import org.apache.slide.common.CacheInfoToken; 26 import org.apache.slide.common.Domain; 27 import org.apache.slide.common.NamespaceAccessToken; 28 import org.apache.slide.common.PropertyName; 29 import org.apache.slide.common.ServiceAccessException; 30 import org.apache.slide.common.SlideException; 31 import org.apache.slide.common.SlideRuntimeException; 32 import org.apache.slide.common.SlideToken; 33 import org.apache.slide.common.SlideTokenImpl; 34 import org.apache.slide.common.SlideTokenWrapper; 35 import org.apache.slide.content.Content; 36 import org.apache.slide.content.NodeProperty; 37 import org.apache.slide.content.NodeRevisionContent; 38 import org.apache.slide.content.NodeRevisionDescriptor; 39 import org.apache.slide.content.NodeRevisionDescriptors; 40 import org.apache.slide.content.NodeRevisionNumber; 41 import org.apache.slide.content.RevisionDescriptorNotFoundException; 42 import org.apache.slide.event.VetoException; 43 import org.apache.slide.lock.Lock; 44 import org.apache.slide.lock.NodeLock; 45 import org.apache.slide.lock.ObjectIsAlreadyLockedException; 46 import org.apache.slide.macro.Macro; 47 import org.apache.slide.security.AccessDeniedException; 48 import org.apache.slide.security.NodePermission; 49 import org.apache.slide.security.Security; 50 import org.apache.slide.structure.ActionNode; 51 import org.apache.slide.structure.LinkedObjectNotFoundException; 52 import org.apache.slide.structure.ObjectNode; 53 import org.apache.slide.structure.ObjectNotFoundException; 54 import org.apache.slide.structure.Structure; 55 import org.apache.slide.structure.SubjectNode; 56 import org.apache.slide.webdav.WebdavException; 57 import org.apache.slide.webdav.util.WebdavUtils; 58 import org.apache.webdav.lib.util.WebdavStatus; 59 import org.jahia.bin.Jahia; 60 import org.jahia.data.containers.JahiaContainer; 61 import org.jahia.data.fields.JahiaField; 62 import org.jahia.data.files.JahiaFile; 63 import org.jahia.data.files.JahiaFileField; 64 import org.jahia.exceptions.JahiaException; 65 import org.jahia.params.ParamBean; 66 import org.jahia.registries.ServicesRegistry; 67 import org.jahia.services.acl.JahiaACLException; 68 import org.jahia.services.acl.JahiaBaseACL; 69 import org.jahia.services.containers.ContentContainerList; 70 import org.jahia.services.pages.ContentPage; 71 import org.jahia.services.sites.JahiaSite; 72 import org.jahia.services.usermanager.JahiaGroup; 73 import org.jahia.services.usermanager.JahiaGroupManagerService; 74 import org.jahia.services.usermanager.JahiaUser; 75 import org.jahia.services.usermanager.JahiaUserManagerService; 76 import org.jahia.services.webdav.stores.JahiaGroupNode; 77 import org.jahia.urls.URI; 78 79 86 public class DAVFileAccess { 87 public static String READ = "read"; 88 public static String WRITE = "write"; 89 public static String MANAGE = "manage"; 90 91 public static int UNSET = 0; 92 public static int GRANTED = 1; 93 public static int DENIED = 2; 94 public static int INHERITED = 4; 95 public static int SET = 8; 96 97 98 private static HashMap namespaces = new HashMap (); 99 100 protected static Logger logger = Logger.getLogger (DAVFileAccess.class); 101 102 private NamespaceHelper ns; 103 private SlideToken slideToken; 104 private ParamBean jParams; 105 private JahiaSite site; 106 private JahiaUser user; 107 private ObjectNode objectNode = null; 108 private NodeRevisionDescriptors revisionDescriptors = null; 109 private NodeRevisionDescriptor revisionDescriptor = null; 110 private Exception exception = null; 111 112 private String webDavServerPath = ""; 113 114 public DAVFileAccess (JahiaSite site, String path) { 115 setNamespace (site); 116 this.site = site; 117 slideToken = ns.rootToken; 118 setFile (path); 119 } 120 121 public DAVFileAccess (ParamBean jParams, JahiaSite site, JahiaUser user, String path) { 122 this.jParams = jParams; 123 this.site = site; 124 this.user = user; 125 if (jParams!= null) { 126 if (jParams.getRequest() != null) { 127 this.webDavServerPath = jParams.getRequest().getContextPath() 128 + "/webdav/site/" + jParams.getSiteKey(); 129 } else if (Jahia.getContextPath() != null) { 130 this.webDavServerPath = Jahia.getContextPath() 131 + "/webdav/site/" + jParams.getSiteKey(); 132 } 133 } 134 setNamespace (site); 135 136 CredentialsToken cred; 137 138 if (user != null) { 139 final String name = user.getUsername(); 140 cred = new CredentialsToken (new Principal () { 141 public String getName() { 142 return name; 143 } 144 }); 145 } else { 146 cred = new CredentialsToken (""); 147 } 148 slideToken = new SlideTokenImpl (cred); 149 slideToken.setEnforceLockTokens (true); 150 151 setFile (path); 152 } 153 154 private void setNamespace (JahiaSite site) { 155 if (!namespaces.containsKey (site)) { 156 ns = new NamespaceHelper (Domain.accessNamespace 157 (new SecurityToken (DAVFileAccess.class), site.getSiteKey ())); 158 namespaces.put (site, ns); 159 } else { 160 ns = (NamespaceHelper) namespaces.get (site); 161 } 162 } 163 164 private void setFile (String path) { 165 if (path != null && path.startsWith ("/")) { 166 try { 167 objectNode = ns.structure.retrieve (slideToken, path); 168 try { 169 revisionDescriptors = 170 ns.content.retrieve (slideToken, path); 171 revisionDescriptor = ns.content.retrieve (slideToken, 172 revisionDescriptors); 173 } catch (RevisionDescriptorNotFoundException e) { 174 } 175 } catch (SlideRuntimeException re) { 176 logger.debug ( 177 "Error when trying to get file at " + path + " (" + re.getMessage () + ")"); 178 exception = re; 179 } catch (SlideException e) { 180 logger.debug ( 181 "Error when trying to get file at " + path + " (" + e.getMessage () + ")"); 182 exception = e; 183 } 184 } 185 } 186 187 public void beginTransaction () { 188 try { 189 ns.token.begin (); 190 } catch (Exception e) { 191 logger.error("Error", e); 193 } 194 } 195 196 public void commitTransaction () { 197 try { 198 ns.token.commit (); 199 } catch (Exception e) { 200 logger.error("Error", e); 202 } 203 } 204 205 public void rollbackTransaction () { 206 try { 207 ns.token.rollback (); 208 } catch (Exception e) { 209 logger.error("Error", e); 211 } 212 } 213 214 public boolean isValid () { 215 return objectNode != null; 216 } 217 218 public Set comparePermsWithField (JahiaField theField) { 219 return comparePermsWithField(theField, null); 220 } 221 222 public Set comparePermsWithField (JahiaField theField, JahiaContainer theContainer) { 223 try { 224 JahiaFileField fField = (JahiaFileField) theField.getObject (); 225 if ((fField == null) || (fField.getRealName () == null) || (fField.getRealName () 226 .length () == 0)) { 227 return new HashSet (); 228 } 229 230 JahiaBaseACL acl; 231 232 if (theField.getID () <= 0) { 234 try { 235 if (theContainer != null) { 236 if (theContainer.getAclID() != 0) { 237 acl = theContainer.getACL(); 238 } else { 239 acl = new JahiaBaseACL(ContentContainerList.getContainerList(theContainer.getListID()).getAclID()); 240 } 241 } else { 242 acl = ContentPage.getPage (theField.getPageID ()).getACL (); 243 } 244 } catch (Exception e) { 245 return new HashSet (); 246 } 247 } else { 248 acl = theField.getACL (); 249 } 250 251 if (acl == null) { 252 return new HashSet (); 253 } 254 255 256 Map userMapping = new HashMap (); 257 Set allUsers = new HashSet (); 258 Vector users = acl.getUsernameList (null); 259 for (Iterator iterator = users.iterator (); iterator.hasNext ();) { 260 String jahiaUserKey = (String ) iterator.next (); 261 JahiaUser jahiaUser = ServicesRegistry.getInstance () 262 .getJahiaUserManagerService () 263 .lookupUser (jahiaUserKey); 264 if (jahiaUser != null) { 265 SubjectNode subjectNode = (SubjectNode) ns.structure.retrieve (ns.rootToken, 266 "/users/" + jahiaUser.getUsername ()); 267 if (acl.getPermission (jahiaUser, JahiaBaseACL.READ_RIGHTS)) { 268 allUsers.add (subjectNode); 269 userMapping.put (subjectNode, jahiaUser); 270 } 271 } 272 } 273 users = (acl.getGroupnameList (null)); 274 for (Iterator iterator = users.iterator (); iterator.hasNext ();) { 275 String jahiaUserKey = (String ) iterator.next (); 276 if (!jahiaUserKey.startsWith ( 277 JahiaGroupManagerService.ADMINISTRATORS_GROUPNAME + ":")) { 278 JahiaGroup jahiaGroup = ServicesRegistry.getInstance () 279 .getJahiaGroupManagerService () 280 .lookupGroup (jahiaUserKey); 281 if (jahiaGroup != null) { 282 JahiaGroupNode subjectNode = (JahiaGroupNode) ns.structure.retrieve (ns.rootToken, 283 "/groups/" + jahiaGroup.getGroupname () + "/members"); 284 if (acl.getPermission (jahiaGroup, JahiaBaseACL.READ_RIGHTS)) { 285 allUsers.add (subjectNode); 286 userMapping.put (subjectNode, jahiaGroup); 287 } 288 } 289 } 290 } 291 Set deniedUsers = new HashSet (); 292 Set grantedUsers = new HashSet (); 293 Map readPerms = getPermissions (READ); 294 for (Iterator iterator = allUsers.iterator (); iterator.hasNext ();) { 295 ObjectNode subjectNode = (ObjectNode) iterator.next (); 296 for (Iterator iterator2 = readPerms.keySet ().iterator (); iterator2.hasNext ();) { 297 298 String permissionSubject = (String ) iterator2.next (); 299 int state = ((Integer ) readPerms.get (permissionSubject)).intValue (); 300 if (permissionSubject.startsWith ("+")) { 301 permissionSubject = permissionSubject.substring (1); 302 } 303 if ((permissionSubject.startsWith ("/") && (subjectNode.getUri () 304 .startsWith (permissionSubject))) || 305 (!permissionSubject.startsWith ("/") && ( 306 ns.security.hasRole (subjectNode, permissionSubject) || 307 ((permissionSubject.equals ("nobody")||permissionSubject.equals ("all")) && subjectNode.getUri () 308 .equals ( 309 "/groups/" + JahiaGroupManagerService.GUEST_GROUPNAME + "/members")) || 310 ((permissionSubject.equals ("guest")||permissionSubject.equals ("unauthenticated")) && subjectNode.getUri ().equals ( 311 "/users/" + JahiaUserManagerService.GUEST_USERNAME)) || 312 ((permissionSubject.equals ("user")||permissionSubject.equals ("authenticated")) && subjectNode.getUri ().equals ( 313 "/groups/" + JahiaGroupManagerService.USERS_GROUPNAME + "/members")) || 314 (permissionSubject.equals ("root") && subjectNode.getUri ().equals ( 315 "/groups/" + JahiaGroupManagerService.ADMINISTRATORS_GROUPNAME + "/members")) 316 ) 317 )) { 318 if ((state & GRANTED) == GRANTED && (state & DENIED) == 0) { 319 grantedUsers.add (subjectNode); 320 } else if ((state & DENIED) == DENIED) { 321 deniedUsers.add (subjectNode); 322 } 323 } 324 } 325 } 326 Set result = new HashSet (allUsers); 327 result.addAll (deniedUsers); 328 result.removeAll (grantedUsers); 329 return result; 330 } catch (JahiaACLException e) { 331 logger.error("Error", e); } catch (ServiceAccessException e) { 333 logger.error("Error", e); } catch (ObjectNotFoundException e) { 335 logger.error("Error", e); } catch (VetoException e) { 337 logger.error("Error", e); } catch (LinkedObjectNotFoundException e) { 339 logger.error("Error", e); } catch (AccessDeniedException e) { 341 logger.error("Error", e); } 343 return new HashSet (); 344 } 345 346 public void alignPermsWithField (JahiaField theField, Set users) { 347 if (exception != null) { 348 return; 349 } 350 351 slideToken.setForceStoreEnlistment (true); 353 354 JahiaFileField fField = (JahiaFileField) theField.getObject (); 355 356 if ((fField == null) || (fField.getRealName () == null) || (fField.getRealName () 357 .length () == 0)) { 358 return; 359 } 360 361 for (Iterator iterator = users.iterator (); iterator.hasNext ();) { 362 String uri = (String ) iterator.next (); 363 if (uri.startsWith ("/groups")) { 364 uri = "+" + uri; 365 } 366 367 changePermissions(uri,"r--"); 368 } 369 } 370 371 372 public Map getPermissions (String actionString) { 373 if (exception != null) { 374 return new HashMap (); 375 } 376 377 ActionNode action = ns.getPermission (actionString); 378 379 Map subjects = new HashMap (); 380 boolean rootObjectReached = false; 381 382 ObjectNode courObject = objectNode; 383 384 try { 385 while (!rootObjectReached) { 386 Enumeration permissions = null; 387 permissions = ns.security.enumeratePermissions (ns.rootToken, courObject); 388 389 while (permissions.hasMoreElements ()) { 390 NodePermission permission = 391 (NodePermission) permissions.nextElement (); 392 393 if (!action.getUri ().startsWith (permission.getActionUri ())) { 394 continue; 395 } 396 397 String permissionSubject = permission.getSubjectUri (); 398 399 if (permissionSubject.equals ("~")) { 400 permissionSubject = objectNode.getUri (); 401 if (permissionSubject.startsWith ("/users/")) { 402 if (permissionSubject.indexOf ('/', 7) > -1) { 403 permissionSubject = 404 permissionSubject.substring (0, 405 permissionSubject.indexOf ('/', 7)); 406 } 407 } 408 } 409 if (permission.isInheritable () 410 || permission.getObjectUri ().equals (objectNode.getUri ())) { 411 412 int state; 413 if (!subjects.containsKey (permissionSubject)) { 414 state = UNSET; 415 } else { 416 state = ((Integer ) subjects.get (permissionSubject)).intValue (); 417 } 418 if ((state & SET) == 0) { 419 if (!permission.getObjectUri ().equals (objectNode.getUri ())) { 420 state |= INHERITED; 421 } 422 subjects.put (permissionSubject, 423 new Integer ( 424 state | (permission.isNegative () ? 425 DENIED : GRANTED))); 426 } 427 } 428 } 429 for (Iterator iterator = subjects.keySet ().iterator (); iterator.hasNext ();) { 430 String subject = (String ) iterator.next (); 431 int state = ((Integer ) subjects.get (subject)).intValue (); 432 if (state != UNSET) { 433 subjects.put (subject, new Integer (state | SET)); 434 } 435 } 436 437 courObject = ns.structure.getParent (ns.rootToken, courObject); 438 439 if (courObject == null) { 440 rootObjectReached = true; 441 } 442 } 443 } catch (SlideException e) { 444 return new HashMap (); 445 } 446 return subjects; 447 } 448 449 public boolean isWriteable () { 450 if (exception != null) { 451 return false; 452 } 453 try { 454 ns.lock.checkLock (slideToken, objectNode, ns.getPermission (WRITE)); 455 } catch (Exception e) { 456 return false; 457 } 458 String path = getPath (); 459 if (path.equals ("/") || ((path.startsWith ("/users") || path.startsWith ("/groups")) && (path.indexOf ( 460 "private") == -1 && path.indexOf ("public") == -1))) { 461 return false; 462 } 463 return true; 464 465 } 466 467 public boolean hasPermission (String perm) { 468 if (exception != null) { 469 return false; 470 } 471 try { 472 return ns.security.hasPermission (slideToken, objectNode, ns.getPermission (perm)); 473 } catch (SlideException e) { 474 logger.error("Error", e); return false; 476 } 477 } 478 479 public String createCollection (String colName) { 480 colName = JahiaWebdavBaseService.getInstance().cleanTitle(colName); 481 482 if (Jahia.getSettings().isTransformDirnames()) { 483 colName = cleanName(colName); 484 } 485 486 if (exception != null) { 487 return null; 488 } 489 490 slideToken.setForceStoreEnlistment (true); 492 493 String resourcePath = objectNode.getUri () + "/" + colName; 494 495 496 SubjectNode collection = new SubjectNode (); 497 NodeRevisionDescriptor revisionDescriptor = 498 new NodeRevisionDescriptor (0); 499 500 NodeProperty property = null; 501 502 property = new NodeProperty ("resourcetype", "<collection/>", true); 504 revisionDescriptor.setProperty (property); 505 506 revisionDescriptor.setCreationDate (new Date ()); 508 509 revisionDescriptor.setLastModified (new Date ()); 511 512 property = new NodeProperty ("getcontentlength", "0", true); 514 revisionDescriptor.setProperty (property); 515 516 property = new NodeProperty ("source", "", true); 518 revisionDescriptor.setProperty (property); 519 520 String owner = slideToken.getCredentialsToken ().getPublicCredentials (); 522 property = new NodeProperty ("owner", owner, true); 523 revisionDescriptor.setProperty (property); 524 525 if (ns.token.getNamespaceConfig ().getParameter ("ms") != null) { 526 527 532 533 540 541 546 547 property = new NodeProperty ("ishidden", "0", "MICROSOFT"); 549 revisionDescriptor.setProperty (property); 550 551 property = new NodeProperty ("iscollection", "1", "MICROSOFT"); 553 revisionDescriptor.setProperty (property); 554 555 property = new NodeProperty ("isreadonly", "0", "MICROSOFT"); 557 revisionDescriptor.setProperty (property); 558 559 property = new NodeProperty ("lastaccessed", 561 (new Date ()).toString (), "MICROSOFT"); 562 revisionDescriptor.setProperty (property); 563 564 } 565 566 try { 567 ns.structure.create (slideToken, collection, resourcePath); 568 ns.content.create (slideToken, resourcePath, revisionDescriptor, null); 569 } catch (Exception e) { 570 return null; 571 } 572 573 577 581 583 return colName; 584 } 585 586 public InputStream downloadFile () { 587 try { 588 return ns.content.retrieve 589 (slideToken, revisionDescriptors, 590 revisionDescriptor).streamContent (); 591 } catch (Exception e) { 592 logger.error("Error on resource :" + this.getPath(), e); } 594 return null; 595 } 596 597 606 public String uploadFile (String name, InputStream inputStream, String contentType, long contentLength, boolean isVersioned) { 607 name = JahiaWebdavBaseService.getInstance().cleanTitle(name); 608 609 if (Jahia.getSettings().isTransformFilenames()) { 610 name = cleanName(name); 611 } 612 613 if (exception != null) { 614 return null; 615 } 616 617 slideToken.setForceStoreEnlistment (true); 618 String resourcePath = objectNode.getUri () + "/" + name; 619 620 try { 621 try { 622 623 NodeRevisionDescriptors theRevisionDescriptors = 624 ns.content.retrieve (slideToken, resourcePath); 625 626 NodeRevisionNumber revisionNumber = 627 theRevisionDescriptors.getLatestRevision (); 628 NodeRevisionDescriptor oldRevisionDescriptor = null; 629 if (revisionNumber != null) { 630 try { 631 oldRevisionDescriptor = ns.content.retrieve 632 (slideToken, theRevisionDescriptors); 633 } catch (RevisionDescriptorNotFoundException e) { 634 logger.warn(e); 635 } 636 } 637 if (WebdavUtils.isCollection (oldRevisionDescriptor)) { 638 return null; 640 } 641 642 NodeRevisionDescriptor theRevisionDescriptor = null; 643 if (oldRevisionDescriptor == null) { 644 theRevisionDescriptor = new NodeRevisionDescriptor (); 645 } else { 646 theRevisionDescriptor = oldRevisionDescriptor; 647 theRevisionDescriptor.setContentLength (-1); 648 } 649 NodeRevisionContent revisionContent = 650 new NodeRevisionContent (); 651 revisionContent.setContent (inputStream); 653 654 NodeProperty property = null; 655 656 property = new NodeProperty 658 ("getcontentlength", new Long (contentLength), 659 true); 660 theRevisionDescriptor.setProperty (property); 661 662 theRevisionDescriptor.setLastModified (new Date ()); 664 665 String etag = resourcePath.hashCode () + "_" 667 + revisionNumber.hashCode () + "_" 668 + theRevisionDescriptor.getContentLength (); 669 property = new NodeProperty ("getetag", etag, true); 670 theRevisionDescriptor.setProperty (property); 671 672 property = theRevisionDescriptor.getProperty ("resourcetype"); 678 if ((property.getValue ()).equals ("<lock-null/>")) { 679 property = 680 new NodeProperty ("getcontentlanguage", "en", true); 681 theRevisionDescriptor.setProperty (property); 682 683 if (contentType == null) { 684 contentType = "application/octet-stream"; 685 } 686 property = new NodeProperty ("getcontenttype", contentType, 687 true); 688 theRevisionDescriptor.setProperty (property); 689 } 690 691 property = new NodeProperty ("resourcetype", "", true); 693 theRevisionDescriptor.setProperty (property); 694 695 ns.content.create (slideToken, resourcePath, theRevisionDescriptor, 696 revisionContent); 697 698 } catch (LinkedObjectNotFoundException e) { 699 logger.error("Error", e); 701 throw new WebdavException (WebdavStatus.SC_ACCEPTED, false); 707 } catch (ObjectNotFoundException e) { 708 709 SubjectNode subject = new SubjectNode (); 711 ns.structure.create (slideToken, subject, resourcePath); 713 714 NodeRevisionDescriptor theRevisionDescriptor = 715 new NodeRevisionDescriptor (contentLength); 716 717 NodeProperty property = null; 718 719 721 property = new NodeProperty ("resourcetype", "", true); 723 theRevisionDescriptor.setProperty (property); 724 725 property = new NodeProperty ("source", "", true); 727 theRevisionDescriptor.setProperty (property); 728 729 property = new NodeProperty ("getcontentlanguage", "en", true); 731 theRevisionDescriptor.setProperty (property); 732 733 property = new NodeProperty 735 ("getcontentlength", 736 new Long (contentLength), true); 737 theRevisionDescriptor.setProperty (property); 738 739 if (contentType == null) { 741 contentType = "application/octet-stream"; 742 } 743 property = new NodeProperty ("getcontenttype", contentType, 744 true); 745 theRevisionDescriptor.setProperty (property); 746 747 theRevisionDescriptor.setLastModified (new Date ()); 749 750 String etag = resourcePath.hashCode () + "_" 752 + (new NodeRevisionNumber ()).hashCode () + "_" 753 + contentLength; 754 property = new NodeProperty ("getetag", etag, true); 755 theRevisionDescriptor.setProperty (property); 756 757 String owner = 759 slideToken.getCredentialsToken ().getPublicCredentials (); 760 property = new NodeProperty ("owner", owner, true); 761 theRevisionDescriptor.setProperty (property); 762 763 if (ns.token.getNamespaceConfig ().getParameter ("ms") != null) { 764 765 property = new NodeProperty ("ishidden", "0", "MICROSOFT"); 767 theRevisionDescriptor.setProperty (property); 768 769 property = new NodeProperty ("iscollection", "0", 771 "MICROSOFT"); 772 theRevisionDescriptor.setProperty (property); 773 774 property = new NodeProperty ("isreadonly", "0", 776 "MICROSOFT"); 777 theRevisionDescriptor.setProperty (property); 778 779 property = new NodeProperty ("lastaccessed", 781 (new Date ()).toString (), 782 "MICROSOFT"); 783 theRevisionDescriptor.setProperty (property); 784 785 } 786 787 NodeRevisionContent revisionContent = 789 new NodeRevisionContent (); 790 revisionContent.setContent (inputStream); 791 ns.content.create (slideToken, resourcePath, isVersioned); 792 ns.content.create (slideToken, resourcePath, theRevisionDescriptor, 793 revisionContent); 794 } 795 } catch (Exception e) { 796 logger.error("Error uploading file to the WebDAV", e); 797 return null; 798 } 799 800 return name; 801 802 } 803 804 812 public String uploadFile(String name, File file, String contentType, 813 boolean isVersioned) 814 { 815 try 816 { 817 return uploadFile(name, new FileInputStream (file), contentType, file 818 .length(), isVersioned); 819 } 820 catch (FileNotFoundException ex) 821 { 822 logger.error("Error uploading file to the WebDAV", ex); 823 return null; 824 } 825 } 826 827 public JahiaFileField getJahiaFileField () { 828 JahiaFileField fField; 829 if (revisionDescriptor != null) { 830 String uri = objectNode.getUri (); 831 832 NodeProperty ownerProperty = revisionDescriptor.getProperty ("owner", 833 NodeProperty.DEFAULT_NAMESPACE); 834 String owner = ""; 835 if (ownerProperty != null) { 836 owner = ownerProperty.getValue ().toString (); 837 838 JahiaUser user = null; 840 try { 841 user = ServicesRegistry.getInstance (). 842 getJahiaSiteUserManagerService ().getMember ( 843 site.getID(), owner); 844 } catch (JahiaException je) { 845 logger.error ( 846 "Couldn't find site user " + owner + " on site " + site.getID(), 847 je); 848 } 849 if (user != null) { 850 owner += ":" + site.getID(); 851 } else { 852 owner += ":0"; 853 } 854 } 855 856 String contentType = revisionDescriptor.getContentType (); 857 int lastDot = uri.lastIndexOf("."); 858 if (lastDot > -1) { 859 String mimeType = Jahia.getStaticServletConfig().getServletContext().getMimeType(uri.substring(uri.lastIndexOf("/")+1).toLowerCase()); 860 if (mimeType != null) { 861 contentType = mimeType; 862 } 863 } 864 865 JahiaFile file = new JahiaFile (-1, -1, owner, 868 uri, uri, revisionDescriptor.getLastModifiedAsDate ().getTime (), revisionDescriptor.getContentLength (), contentType, getName (), "", String.valueOf (ServicesRegistry.getInstance () 876 .getJahiaVersionService ().getCurrentVersionID ()), JahiaFile.STATE_ACTIVE); 878 fField = new JahiaFileField (file, new Properties ()); 879 fField.setID (0); 880 URI url = null; 881 url = new URI (); 882 url.setPath ( 883 this.webDavServerPath + uri); 884 url.setURIStartingAtPath (true); 885 fField.setDownloadUrl (url.toString ()); 886 } else { 887 JahiaFile file = new JahiaFile (-1, -1, "", "", "", 0, 0, (exception == null) ? "" : exception.getClass ().getName (), "", "", String.valueOf (ServicesRegistry.getInstance () 898 .getJahiaVersionService ().getCurrentVersionID ()), JahiaFile.STATE_ACTIVE); 900 fField = new JahiaFileField (file, new Properties ()); 901 fField.setID (-1); 902 fField.setDownloadUrl ("#"); 903 } 904 return fField; 905 } 906 907 public Exception getException () { 908 return exception; 909 } 910 911 912 public String getPath () { 913 if (exception != null) { 914 return ""; 915 } 916 917 return objectNode.getUri (); 918 } 919 920 public boolean isCollection () { 921 if (exception != null) { 922 return false; 923 } 924 925 return WebdavUtils.isCollection (ns.token, slideToken, objectNode.getUri ()); 926 } 927 928 public List getChildren () { 929 if (exception != null) { 930 return new ArrayList (); 931 } 932 933 Enumeration en = objectNode.enumerateChildren (); 934 ArrayList list = new ArrayList (); 935 while (en.hasMoreElements ()) { 936 String s = (String ) en.nextElement (); 937 DAVFileAccess child = new DAVFileAccess (jParams, site, user, s); 938 if (child.getException () == null) { 939 list.add (child); 940 } 941 } 942 return list; 943 } 944 945 public boolean changePermissions (String user, String perm) { 946 if (exception != null) { 947 return false; 948 } 949 950 slideToken.setForceStoreEnlistment (true); 952 953 NodePermission r = new NodePermission(objectNode.getUri(), user, 954 "/actions/read", true, perm.charAt(JahiaBaseACL.READ_RIGHTS) == '-'); 955 NodePermission w = new NodePermission(objectNode.getUri(), user, 956 "/actions/write", true, perm.charAt(JahiaBaseACL.WRITE_RIGHTS) == '-'); 957 NodePermission a = new NodePermission(objectNode.getUri(), user, 958 "/actions/manage", true, perm.charAt(JahiaBaseACL.ADMIN_RIGHTS) == '-'); 959 try { 960 ns.security.grantPermission (slideToken, r); 961 ns.security.grantPermission (slideToken, w); 962 ns.security.grantPermission (slideToken, a); 963 } catch (Exception e) { 964 logger.debug("Exception occured during permission change",e); 965 return false; 966 } 967 return true; 968 } 969 970 public boolean revokePermissions (String user) { 971 if (exception != null) { 972 return false; 973 } 974 975 slideToken.setForceStoreEnlistment (true); 977 978 NodePermission r = new NodePermission (objectNode.getUri (), user, "/actions/read"); 979 NodePermission w = new NodePermission (objectNode.getUri (), user, "/actions/write"); 980 NodePermission a = new NodePermission (objectNode.getUri (), user, "/actions/manage"); 981 NodePermission r2 = new NodePermission (objectNode.getUri (), user, "/actions/read",true,true); 982 NodePermission w2 = new NodePermission (objectNode.getUri (), user, "/actions/write",true,true); 983 NodePermission a2 = new NodePermission (objectNode.getUri (), user, "/actions/manage",true,true); 984 try { 985 ns.security.revokePermission (slideToken, r); 986 ns.security.revokePermission (slideToken, w); 987 ns.security.revokePermission (slideToken, a); 988 ns.security.revokePermission (slideToken, r2); 989 ns.security.revokePermission (slideToken, w2); 990 ns.security.revokePermission (slideToken, a2); 991 } catch (Exception e) { 992 logger.debug("Exception occured during permission change",e); 993 return false; 994 } 995 return true; 996 } 997 998 public boolean hasRevisions () { 999 if (exception != null) { 1000 return false; 1001 } 1002 return revisionDescriptor != null; 1003 } 1004 1005 public Map getProperties () { 1006 HashMap res = new HashMap (); 1007 1008 if (exception != null) { 1009 return res; 1010 } 1011 1012 res.put("DAV:displayname",new NodeProperty(PropertyName.DISPLAY_NAME, "")); 1013 1014 Enumeration en = revisionDescriptor.enumerateProperties (); 1015 while (en.hasMoreElements ()) { 1016 NodeProperty nodeProperty = (NodeProperty) en.nextElement (); 1017 res.put (nodeProperty.getNamespace () + nodeProperty.getName (), nodeProperty); 1018 } 1019 return res; 1020 } 1021 1022 public String getName () { 1023 if (revisionDescriptor != null) { 1024 String name = revisionDescriptor.getName(); 1025 if (name != null && name.length() > 0) { 1026 return name; 1027 } 1028 } 1029 return getPath().substring(getPath().lastIndexOf('/') + 1); 1030 } 1031 1032 public void setName (String name) { 1033 if (revisionDescriptor != null) { 1034 slideToken.setForceStoreEnlistment (true); 1036 1037 revisionDescriptor.setName (name); 1038 try { 1039 ns.content.store (slideToken, objectNode.getUri (), revisionDescriptor, null); 1040 } catch (SlideException e) { 1041 logger.error("Error", e); 1042 } 1043 } 1044 } 1045 1046 1047 public Object getProperty (String namespace, String name) { 1048 if (exception != null) { 1049 return null; 1050 } 1051 1052 NodeProperty p = revisionDescriptor.getProperty (name, namespace); 1053 if (p != null) { 1054 return p.getValue (); 1055 } 1056 return null; 1057 } 1058 1059 public void setProperty (String namespace, String name, Object value, boolean prot) { 1060 if (exception != null) { 1061 return; 1062 } 1063 1064 slideToken.setForceStoreEnlistment (true); 1066 1067 revisionDescriptor.setProperty (new NodeProperty (name, value, namespace, "", prot)); 1068 try { 1069 ns.content.store (prot ? ns.rootToken : slideToken, objectNode.getUri (), 1070 revisionDescriptor, null); 1071 } catch (SlideException e) { 1072 logger.error("Error", e); } 1074 1075 } 1076 1077 public boolean renameFile (String newName) throws SlideException { 1078 if (exception != null) { 1079 return false; 1080 } 1081 if (isCollection()) { 1082 if (Jahia.getSettings().isTransformDirnames()) { 1083 newName = cleanName(newName); 1084 } 1085 } else { 1086 if (Jahia.getSettings().isTransformFilenames()) { 1087 newName = cleanName(newName); 1088 } 1089 } 1090 slideToken.setForceStoreEnlistment (true); 1092 1093 String uri = objectNode.getUri (); 1094 String origDir = uri.substring (0, uri.lastIndexOf ('/') + 1); 1095 String name = uri.substring (uri.lastIndexOf ('/') + 1); 1096 if (name.equals (newName)) { 1097 return false; 1098 } 1099 ns.macro.move (slideToken, uri, origDir + newName); 1100 objectNode = ns.structure.retrieve (slideToken, origDir + newName); 1101 return true; 1102 } 1103 1104 public boolean moveFile (String dest) throws SlideException { 1105 if (exception != null) { 1106 return false; 1107 } 1108 1109 slideToken.setForceStoreEnlistment (true); 1111 1112 String uri = objectNode.getUri (); 1113 String origDir = uri.substring (0, uri.lastIndexOf ('/')); 1114 String name = uri.substring (uri.lastIndexOf ('/')); 1115 if (origDir.equals (dest)) { 1116 return false; 1117 } 1118 ns.macro.move (slideToken, uri, dest + name); 1119 objectNode = ns.structure.retrieve (slideToken, dest + name); 1120 return true; 1121 } 1122 1123 public boolean copyFile (String dest) throws SlideException { 1124 if (exception != null) { 1125 return false; 1126 } 1127 if (isCollection()) { 1128 if (Jahia.getSettings().isTransformDirnames()) { 1129 dest = cleanName(dest); 1130 } 1131 } else { 1132 if (Jahia.getSettings().isTransformFilenames()) { 1133 dest = cleanName(dest); 1134 } 1135 } 1136 1137 slideToken.setForceStoreEnlistment (true); 1139 1140 String uri = objectNode.getUri (); 1141 String origDir = uri.substring (0, uri.lastIndexOf ('/')); 1142 String name = uri.substring (uri.lastIndexOf ('/') + 1); 1143 if (origDir.equals (dest)) { 1144 String newName = "copy_of_" + name; 1145 int index = 1; 1146 boolean exist = true; 1147 while (exist) { 1148 try { 1149 ns.structure.retrieve (ns.rootToken, dest + "/" + newName); 1150 newName = "copy_" + (++index) + "_of_" + name; 1151 } catch (ObjectNotFoundException e) { 1152 exist = false; 1153 } catch (SlideException e) { 1154 return false; 1155 } 1156 } 1157 name = newName; 1158 } 1159 ns.macro.copy (slideToken, objectNode.getUri (), dest + "/" + name); 1160 return true; 1161 } 1162 1163 public boolean deleteFile () throws SlideException { 1164 if (exception != null) { 1165 return false; 1166 } 1167 1168 slideToken.setForceStoreEnlistment (true); 1170 1171 ns.macro.delete (slideToken, objectNode.getUri ()); 1172 return true; 1173 } 1174 1175 public boolean lockFile (boolean rootLock) { 1176 if (exception != null) { 1177 return false; 1178 } 1179 NodeLock lockToken = 1182 new NodeLock (objectNode.getUri (), "/users/", 1183 ns.getPermission (DAVFileAccess.WRITE).getUri (), 1184 new Date (Long.MAX_VALUE), false, true); 1185 try { 1186 ns.lock.lock (ns.rootToken, lockToken); 1187 1188 try { 1189 lockToken = new NodeLock 1190 (lockToken, 1191 ns.getPermission (DAVFileAccess.WRITE).getUri ()); 1192 ns.lock.lock (slideToken, lockToken); 1193 } catch (ObjectIsAlreadyLockedException e) { 1194 } 1196 } catch (SlideException e) { 1197 return false; 1198 } 1199 1200 return true; 1201 } 1202 1203 public boolean unlockFile (boolean rootLock) { 1204 if (exception != null) { 1205 return false; 1206 } 1207 try { 1208 Enumeration locks = ns.lock.enumerateLocks (ns.rootToken, objectNode.getUri (), 1209 false); 1210 while (locks.hasMoreElements ()) { 1211 NodeLock nodeLock = (NodeLock) locks.nextElement (); 1212 ns.lock.unlock (ns.rootToken, nodeLock); 1213 } 1214 } catch (SlideException e) { 1215 logger.error("Error", e); 1216 return false; 1217 } 1218 return true; 1219 } 1220 1221 public boolean isLocked () { 1222 if (exception != null) { 1223 return false; 1224 } 1225 try { 1226 Enumeration locks = ns.lock.enumerateLocks (slideToken, objectNode.getUri (), false); 1227 return locks.hasMoreElements (); 1228 } catch (SlideException e) { 1229 return false; 1230 } 1231 } 1232 1233 public long getContentLength() 1234 { 1235 if (exception != null) { 1236 return -1L; 1237 } 1238 1239 return revisionDescriptor.getContentLength(); 1240 } 1241 1242 public String getContentType() 1243 { 1244 if (exception != null) { 1245 return null; 1246 } 1247 1248 return revisionDescriptor.getContentType(); 1249 } 1250 1251 public int getTransactionStatus() { 1252 try { 1253 return ns.token.getStatus(); 1254 } catch (Exception e) { 1255 logger.error("Error", e); 1257 } 1258 1259 return Status.STATUS_UNKNOWN; 1260 } 1261 1262 public boolean equals(final Object o) { 1263 if (this == o) return true; 1264 if (o == null || this.getClass() != o.getClass()) return false; 1265 1266 final DAVFileAccess davFileAccess = (DAVFileAccess) o; 1267 1268 return !(getPath() != null ? !getPath().equals(davFileAccess.getPath()) : davFileAccess.getPath() != null); 1269 } 1270 1271 public int hashCode() { 1272 return (getPath() != null ? getPath().hashCode() : 0); 1273 } 1274 1275 class NamespaceHelper { 1276 NamespaceAccessToken token; 1277 SlideToken rootToken; 1278 Structure structure; 1279 Security security; 1280 Content content; 1281 Lock lock; 1282 Macro macro; 1283 1284 Map perms = new HashMap (); 1285 1286 public NamespaceHelper (NamespaceAccessToken token) { 1287 this.token = token; 1288 structure = token.getStructureHelper (); 1289 security = token.getSecurityHelper (); 1290 content = token.getContentHelper (); 1291 lock = token.getLockHelper (); 1292 macro = token.getMacroHelper (); 1293 rootToken = new SlideTokenWrapper(new SlideTokenImpl (new CredentialsToken (new Principal () { 1294 public String getName () { 1295 return ""; 1296 } 1297 }))); 1298 rootToken.setForceSecurity(false); 1299 } 1300 1301 ActionNode getPermission (String perm) { 1302 if (!perms.containsKey (perm)) { 1303 try { 1304 perms.put (perm, structure.retrieve (rootToken, "/actions/" + perm)); 1305 } catch (SlideException e) { 1306 logger.error ("Cannot find action " + perm, e); 1307 return null; 1308 } 1309 } 1310 return (ActionNode) perms.get (perm); 1311 } 1312 1313 } 1314 1315 1316 public static String cleanName(String name) { 1317 if (name == null) return null; 1318 StringBuffer sb = new StringBuffer (name.length()); 1319 for (int i = 0; i < name.length(); i++) { 1320 char c = name.charAt(i); 1321 if (c>='\u0080') { 1322 if (c >= '\u00C0' && c < '\u00C6') sb.append('A'); 1323 else if (c == '\u00C6' ) sb.append("AE"); 1324 else if (c == '\u00C7' ) sb.append('C'); 1325 else if (c >= '\u00C8' && c < '\u00CC') sb.append('E'); 1326 else if (c >= '\u00CC' && c < '\u00D0') sb.append('I'); 1327 else if (c == '\u00D0' ) sb.append('D'); 1328 else if (c == '\u00D1' ) sb.append('N'); 1329 else if (c >= '\u00D2' && c < '\u00D7') sb.append('O'); 1330 else if (c == '\u00D7' ) sb.append('x'); 1331 else if (c == '\u00D8' ) sb.append('O'); 1332 else if (c >= '\u00D9' && c < '\u00DD') sb.append('U'); 1333 else if (c == '\u00DD' ) sb.append('Y'); 1334 else if (c == '\u00DF' ) sb.append("SS"); 1335 else if (c >= '\u00E0' && c < '\u00E6') sb.append('a'); 1336 else if (c == '\u00E6' ) sb.append("ae"); 1337 else if (c == '\u00E7' ) sb.append('c'); 1338 else if (c >= '\u00E8' && c < '\u00EC') sb.append('e'); 1339 else if (c >= '\u00EC' && c < '\u00F0') sb.append('i'); 1340 else if (c == '\u00F0' ) sb.append('d'); 1341 else if (c == '\u00F1' ) sb.append('n'); 1342 else if (c >= '\u00F2' && c < '\u00F7') sb.append('o'); 1343 else if (c == '\u00F7' ) sb.append('/'); 1344 else if (c == '\u00F8' ) sb.append('o'); 1345 else if (c >= '\u00F9' && c < '\u00FD') sb.append('u'); 1346 else if (c == '\u00FD' ) sb.append('y'); 1347 else if (c == '\u00FF' ) sb.append("y"); 1348 else if (c == '\u0152' ) sb.append("OE"); 1349 else if (c == '\u0153' ) sb.append("oe"); 1350 else sb.append('_'); 1351 } else { 1352 sb.append(c); 1353 } 1354 } 1355 return sb.toString(); 1356 } 1357 1358 1364 public static String normalizeDirName(String dirName) 1365 { 1366 String normalizedName = JahiaWebdavBaseService.getInstance().cleanTitle( 1367 dirName); 1368 1369 if (Jahia.getSettings().isTransformDirnames()) 1370 { 1371 normalizedName = cleanName(normalizedName); 1372 } 1373 return normalizedName; 1374 } 1375 1376 1382 public static String normalizeFileName(String fileName) 1383 { 1384 String normalizedName = JahiaWebdavBaseService.getInstance().cleanTitle( 1385 fileName); 1386 1387 if (Jahia.getSettings().isTransformFilenames()) 1388 { 1389 normalizedName = cleanName(normalizedName); 1390 } 1391 return normalizedName; 1392 } 1393 1394 static Set protectedProperties; 1395 1396 static { 1397 protectedProperties = new HashSet (); 1398 protectedProperties.add(PropertyName.CREATION_DATE); 1399 protectedProperties.add(PropertyName.CREATION_USER); 1400 protectedProperties.add(PropertyName.CONTENT_LANGUAGE); 1401 protectedProperties.add(PropertyName.CONTENT_LENGTH); 1402 protectedProperties.add(PropertyName.CONTENT_TYPE); 1403 protectedProperties.add(PropertyName.ETAG); 1404 protectedProperties.add(PropertyName.LAST_MODIFIED); 1405 protectedProperties.add(PropertyName.MODIFICATION_DATE); 1406 protectedProperties.add(PropertyName.MODIFICATION_USER); 1407 protectedProperties.add(PropertyName.OWNER); 1408 protectedProperties.add(PropertyName.RESOURCE_TYPE); 1409 } 1410} 1411 | Popular Tags |