internal static Workshare.PolicyContent.ContentItem GetContentItem(IContentItem contentIn, bool keepContentBytes) { bool useFileInstead = false; if (null == contentIn) throw new ArgumentNullException("contentIn"); useFileInstead = contentIn.Properties.ContainsKey(ContentDataSourceKey); Workshare.PolicyContent.ContentItem contentOut = new Workshare.PolicyContent.ContentItem(); contentOut.ContentType = contentIn.Type; contentOut.Encrypted = contentIn.Encrypted; contentOut.Name = contentIn.Name; contentOut.DisplayName = contentIn.DisplayName; contentOut.Size = contentIn.Size; List<CustomProperty> properties = new List<CustomProperty>(); if (keepContentBytes && !useFileInstead) contentOut.Content = GetContentBytes(contentIn); if (useFileInstead) { string filename = contentIn.Properties[ContentDataSourceKey]; if (string.IsNullOrEmpty(filename)) // need to create new file then { filename = Path.GetTempFileName(); contentIn.Properties[ContentDataSourceKey] = filename; GetContentToFile(contentIn, filename); } } int index = 0; if (contentIn.Properties != null && contentIn.Properties.Count > 0) { HandleContentIds(contentIn, contentOut); foreach (KeyValuePair<string, string> kvp in contentIn.Properties) { CustomProperty cp = new CustomProperty(kvp.Key, kvp.Value); properties.Add(cp); } } contentOut.Properties = properties.ToArray(); contentOut.PolicySets = new PolicySet[contentIn.PolicySetCollection.Count]; index = 0; foreach (IPolicySetResponse response in contentIn.PolicySetCollection) { contentOut.PolicySets[index++] = PolicySetAdaptor.GetPolicySet(response); } return contentOut; }
private void AddRecordKeyToAttachmentProperties(Attachment attach, ContentItem ci) { List<CustomProperty> lcpAttach = new List<CustomProperty>(attach.Properties); if (lcpAttach.Exists( delegate(CustomProperty cp) { return (cp.Name == "RecordKey"); })) { return; } List<CustomProperty> lcpCI = new List<CustomProperty>(ci.Properties); lcpAttach.Add(lcpCI.Find( delegate(CustomProperty cp) { return (cp.Name == "RecordKey"); })); attach.Properties = lcpAttach.ToArray(); }
private ContentItem FindContentItemWithZeroParentIndex(ContentItem ci) { if (ci == null) return ci; List<CustomProperty> listProperties = new List<CustomProperty>(ci.Properties); if (listProperties.Exists( delegate(CustomProperty cp) { return ((cp.Name == "ParentIndex") && (cp.Value == "0")); })) { return ci; } else { ContentItem nextCI = m_listResponseContents.Find( delegate(ContentItem rci) { return (rci.Id == ci.ParentId); }); return FindContentItemWithZeroParentIndex(nextCI); } }
/// <summary>| /// We need this to handle the recursive parenting. /// </summary> /// <param name="response">The <see cref="Workshare.PolicyContent.Response"/></param> /// <param name="uiAction">The <see cref="UIAction"/> object for the content item</param> /// <param name="action">The <see cref="Workshare.PolicyContent.Action"/> object for the content item</param> /// <param name="contentItem"></param> /// <returns></returns> private static UIContentItem HandleParentContentItems(Response response, UIAction uiAction, PolicyContent.Action action, ContentItem contentItem) { UIContentItem parent = uiAction.GetContentItemById(contentItem.ParentId); if (parent == null) { CustomProperty parentIndex = Array.Find(contentItem.Properties, p => p.Name == "ParentIndex"); int index = (parentIndex == null ? -1 : Int32.Parse(parentIndex.Value)); if (index > -1) { parent = new UIContentItem(response.Contents[index], action, true); } if (parent != null) { if (parent.ParentId == null) { uiAction.ContentItems[parent.Id] = parent; } else { UIContentItem grandparent = HandleParentContentItems(response, uiAction, action, parent.ContentItem); grandparent.ChildContentItems[parent.Id] = parent; } } } return parent; }
public UIContentItem(ContentItem contentItem, Workshare.PolicyContent.Action action) : this(contentItem, action, false) { }
public UIContentItem(ContentItem contentItem, Workshare.PolicyContent.Action action, bool container) { if (contentItem == null) { throw new ArgumentNullException("contentItem"); } m_protectAction = action; m_container = container; m_contentItem = contentItem; m_rating = RatingEnum.Low; m_childContentItems = new Dictionary<string, UIContentItem>(); m_policies = new Dictionary<string, UIPolicy>(); m_selected = true; }
// The ID of the original document (which is going to be zipped) is now used for // the zip, and the original document will get a new ID. private void RearrangeItemAndContainerIds(ContentItem contentItem, out string newZipId, out string zipParentId) { Logger.LogInfo(string.Format("Original content item ID=\"{0}\", original parent ID=\"{1}\".", contentItem.Id, contentItem.ParentId)); // The attachment will be replaced with a zip. So keep the original content ID and use // it for this zip item, and use a new ID for the original document (as it is now inside the zip). // They need to have unique ID's so that they can be encrypted correctly. string documentsOldContentId = newZipId = contentItem.Id; contentItem.Id = Guid.NewGuid().ToString(); // The original item gets a new ID. zipParentId = contentItem.ParentId; contentItem.ParentId = newZipId; // The original item will be inside the new zip, so the new zip is its parent. Logger.LogInfo(string.Format("New content item ID=\"{0}\", new parent ID=\"{1}\".", contentItem.Id, contentItem.ParentId)); Logger.LogInfo(string.Format("Zip item ID=\"{0}\", zip parent ID=\"{1}\".", newZipId, zipParentId)); // Find if the document to be zipped is already password protected. if (_encryptionMap.ContainsKey(documentsOldContentId)) { Logger.LogDebug("The original content item was encrypted, so it's encryption map key will also be renamed."); // Rename the document's key. IContentEncryption contentEncryption = _encryptionMap[documentsOldContentId]; // Store the existing entry. _encryptionMap.Remove(documentsOldContentId); // Remove the old entry (the ID is now incorrect). _encryptionMap.Add(contentItem.Id, contentEncryption); // Re-add it with the new ID. } }
// Migrate content properties from the document to the zip. (This is a helper method for the Zip Action processing.) private static void MigrateContentPropertiesFromDocumentToZip(ContentItem documentContentItem, string zipFilePath, out CustomProperty[] zipProperties) { var docProps = new List<CustomProperty>(); // Precreate the local file name property in the zip's list. var zipProps = new List<CustomProperty> { new CustomProperty("LocalFileName", zipFilePath) }; // Iterate all properties and decide where to put them. foreach (CustomProperty property in documentContentItem.Properties) { switch (property.Name) { case "LocalFileName": // Only add the local file name to the doc's list. docProps.Add(property); break; case "RecordKey": // The record key is now only for the zip. zipProps.Add(property); break; default: // Add unknown properties to both property lists. docProps.Add(property); // Make a copy for the zip's list. zipProps.Add(new CustomProperty(property.Name, property.Value)); break; } } // Convert the lists into arrays which are returned. documentContentItem.Properties = docProps.ToArray(); zipProperties = zipProps.ToArray(); }
// This function creates a content item for zips created by the Zip Action. private ContentItem CreateZipContainer(string zipFilePath, ContentItem contentItem, string password) { // The ID of the original document (which is going to be zipped) is now used for // the zip, and the original document will get a new ID. string newZipId, parentId; RearrangeItemAndContainerIds(contentItem, out newZipId, out parentId); // Create a shallow clone of the policy sets array. var policySets = (PolicySet[]) contentItem.PolicySets.Clone(); // Arrange the properties accordingly. CustomProperty[] properties; MigrateContentPropertiesFromDocumentToZip(contentItem, zipFilePath, out properties); // Add a zip encryption for a Zip Action content item. AddZipActionEncryptor(newZipId, zipFilePath, password); // Create new content item for the zip that will be created by the Zip Action. return new ContentItem { ContentType = "ZIP", DisplayName = zipFilePath, Id = newZipId, Name = zipFilePath, ParentId = parentId, PolicySets = policySets, Properties = properties }; }
private static ContentItem FindOutermostZip(ContentItem contentItem, ContentItem[] contents) { if (contentItem == null) { return null; } // Start at the given item. ContentItem current = contentItem; // We have not found anything yet. ContentItem found = null; // Take this ToString out of the loop. string FileType_ZIP = FileType.ZIP.ToString(); do { if (current.ContentType == FileType_ZIP) { // Found a zip. It will be higher up the parent chain than any thus found, so store it as the current leader. found = current; } // Find the parent of the current item and store it as the now-current item. current = current.ParentId == null ? null : contents.FirstOrDefault(ci => ci.Id == current.ParentId); // If we're at the top then the parent ID would have been null. } while (current != null); // Return the found item, or null if not found. return found; }
public void TestAssociateZipActionArchiveWithContent(string docFileName, string zipFileName, string password) { // Use function currying to keep the password. Func<FileType, string, string, string, ContentItem> CreateContentItem = (ft, fp, ci, pi) => CreateZipActionContentItem(password, ft, fp, ci, pi); // A message with null parent ID, because it's the top-most element. const string emailBodyId = "1"; const string emailBodyName = "message subject/body"; ContentItem emailContentItem = CreateContentItem(FileType.Email, emailBodyName, emailBodyId, null); var emailAttachment = new Attachment(emailBodyName, emailBodyName, FileType.Email.ToString(), emailBodyId, emailBodyId, true); // A zip with parent being email const string zipId = "2"; string zipPath = Path.Combine(TestFileDirectory, zipFileName); ContentItem zipContentItem = CreateContentItem(FileType.ZIP, zipPath, zipId, emailBodyId); var zipAttachment = new Attachment(zipPath, zipPath, FileType.ZIP.ToString(), zipId, zipId, true); zipAttachment.File = new FcsFile(zipPath, Path.GetFileName(zipPath), zipId); // A doc with parent being zip. const string docId = "3"; string docPath = Path.Combine(TestFileDirectory, docFileName); ContentItem docContentItem = CreateContentItem(FileType.WordDocument, docPath, docId, zipId); var docAttachment = new Attachment(docPath, docPath, FileType.WordDocument.ToString(), docId, docId, true); docAttachment.File = new FcsFile(docPath, Path.GetFileName(docPath), docId); using (ContentEncryptionManager manager = new ContentEncryptionManager()) { if (!string.IsNullOrEmpty(password)) { manager.AddZipActionEncryptor(zipId, zipPath, password); } var contents = new ContentItem[] { emailContentItem, zipContentItem, docContentItem }; var response = new Response { Contents = contents }; var attachments = new Attachment[] { emailAttachment, zipAttachment, docAttachment }; var request = new Request { Attachments = attachments }; var enforce = new EnforceResponse { ModifiedRequest = request }; // The zip and it's document are not yet associated. Assert.AreEqual(0, zipAttachment.File.Files.Count, "The zip IFile should not contain any files before association."); Assert.IsFalse(zipAttachment.File.IsExpanded); if (!string.IsNullOrEmpty(password)) { Assert.AreEqual(null, zipAttachment.File.Password, "The zip IFile should not yet contain the password."); } bool cancelSend; manager.AssociateZipActionArchiveWithContent(enforce, response, out cancelSend); // The zip and it's document should now be associated. Assert.AreEqual(1, zipAttachment.File.Files.Count, "The zip IFile should contain 1 file after association."); Assert.IsTrue(zipAttachment.File.IsExpanded); if (!string.IsNullOrEmpty(password)) { Assert.AreEqual(password, zipAttachment.File.Password, "The zip IFile should now contain the correct password."); } } }