/// <summary> /// Gets the collection of file paths in the package. /// </summary> /// <returns>Collection of file paths in the package.</returns> public override ReadOnlyCollection <string> GetFilePaths() { if (m_isDisposed) { throw new ObjectDisposedException(GetType().Name); } return(m_spPackageReader.GetFilePaths()); }
/// <summary> /// Read the files from a package and import the package information into LearningStore. Only packages /// which may be executed can be imported into LearningStore. /// See the class overview information for details. /// </summary> /// <param name="packageReader">A reader to read the files in the package to be imported.</param> /// <param name="packageId">The identifier of the package whose files are being imported.</param> /// <returns>Returns the location of the package that was added.</returns> /// <remarks> /// <p/>This method copies all package files that are referenced in the manifest into a unique /// subdirectory in the basePath directory. /// /// <p/>This method will validate that the package does not have any errors when it is /// processed by the <c>PackageValidator</c> class. Warnings that occur during validaton /// will have no effect on adding the package. /// /// <p/>Only packages which can be excuted may be imported into LearningStore. A package may be /// executed if there is at least one <Organization> nodes within it. /// /// <p/>This method creates a transaction, regardless of whether or not it is called within /// a transaction. /// /// <p/>The identity passed to the constructor will be used to write the files to the file system. This /// account must have appropriate permissions to write to the basePath directory for the package store. /// /// <p/>The exceptions thrown by Directory.CreateDirectory() may also be thrown by this method. /// </remarks> /// <exception cref="PackageImportException">Thrown if the package to be added is not a /// <c>PackageType.ContentAggregation</c> or does not contain /// at least one <item> node.</exception> /// <exception cref="UnauthorizedAccessException">Thrown if the identity used to create this object /// does not have sufficient permissions in the file system directory.</exception> private string ImportFiles(PackageItemIdentifier packageId, PackageReader packageReader) { string relativePackageLocation; // package location unique to this pacakge // The outer try/catch block is there for security reasons. Search MSDN for // "WrapVulnerableFinallyClausesInOuterTry" to see details. try { string absPackageLocation = null; // Create directories using the identity account that was passed to the store. using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { // Create the directory, relative to m_basePath relativePackageLocation = CreatePackageDirectory(packageId.GetKey(), 100); // Get the absolution package location of the new package directory absPackageLocation = PackageReader.SafePathCombine(m_basePath, relativePackageLocation); } if (packageReader.GetType().Equals(typeof(ZipPackageReader))) { // Let the zip reader do its own copy, as it's more efficient. Do not impersonate, as the package reader // needs to use its own identity (not the the store's identity) to access the files // ZipPackageReader doesn't want the directory to exist. (We had to create it above to verify it was // possible). using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { Directory.Delete(absPackageLocation); } ZipPackageReader zipReader = packageReader as ZipPackageReader; zipReader.CopyTo(absPackageLocation); } else { foreach (string filePath in packageReader.GetFilePaths()) { using (Disposer disposer = new Disposer()) { string absFilePath; // absolute location of the file to write string absDirPath; // absolute location of the drectory to write to FileStream outputStream; // stream to write to // Get stream for file from package Stream pkgStream = packageReader.GetFileStream(filePath); disposer.Push(pkgStream); // Create subdirectory, if it's required using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { absFilePath = PackageReader.SafePathCombine(absPackageLocation, filePath); absDirPath = Path.GetDirectoryName(absFilePath); if (!File.Exists(absDirPath) && !Directory.Exists(absDirPath)) { // Create it Directory.CreateDirectory(absDirPath); } // Create file location to write outputStream = new FileStream(absFilePath, FileMode.Create); disposer.Push(outputStream); } // Copy from the pkgStream to the outputStream, using the correct identities Utilities.CopyStream(pkgStream, ImpersonationBehavior.UseImpersonatedIdentity, outputStream, m_impersonationBehavior); } } } using (ImpersonateIdentity id = new ImpersonateIdentity(m_impersonationBehavior)) { // Remove imsmanifest.xml from the target directory. It'll be stored in LearningStore and providing two // copies may cause confusion or sync issues. string manifestFilePath = PackageReader.SafePathCombine(absPackageLocation, "imsmanifest.xml"); File.Delete(manifestFilePath); } } catch { throw; } // Return the new package return(relativePackageLocation); }
internal static void Validate(PackageValidatorSettings packageValidatorSettings, PackageReader packageReader, bool logReplacement, ValidationResults log, ManifestReaderSettings manifestSettings, LrmSettings lrmSettings, out ManifestReader manifestReader) { ValidatorResources.Culture = LocalizationManager.GetCurrentCulture(); if (packageReader == null) { throw new ArgumentNullException("packageReader"); } ValidationResults manifestLog; XPathNavigator manifest; packageReader.CreateManifestNavigator(packageValidatorSettings.LrmRequirementValidation, lrmSettings.FixLrmViolations, out manifestLog, out manifest); if (manifestLog != null) { foreach (ValidationResult result in manifestLog.Results) { log.AddResult(result); } } manifestReader = new ManifestReader(packageReader, manifestSettings, packageValidatorSettings, logReplacement, log, manifest); if (packageValidatorSettings.MlcRequirementValidation != ValidationBehavior.None) { int activityCount = 0; if (manifestReader.Organizations.Count > 0) { foreach (OrganizationNodeReader nodeReader in manifestReader.Organizations) { activityCount += nodeReader.Activities.Count; } if (activityCount == 0) { ProcessError(packageValidatorSettings.MlcRequirementValidation, ValidatorResources.MlcViolationActivityMissing, log); } } else { ProcessError(packageValidatorSettings.MlcRequirementValidation, ValidatorResources.MlcViolationOrganizationMissing, log); } } ManifestValidator.Validate(manifestReader); // Add all files in the manifest to a Dictionary Dictionary <string, bool> manifestFilePaths = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase); foreach (ResourceNodeReader r in manifestReader.Resources.Values) { foreach (FileNodeReader fileNode in r.Files) { if (!fileNode.Location.IsAbsoluteUri) { // get the path component of the Location property, and URL decode the string // so it is a proper file path. string path = System.Web.HttpUtility.UrlDecode(RemoveQueryAndAnchor(fileNode.Location.OriginalString)); if (!manifestFilePaths.ContainsKey(path)) { manifestFilePaths.Add(path, true); } } } } ReadOnlyCollection <string> packageFilePaths = packageReader.GetFilePaths(); CheckManifestFiles(packageFilePaths, manifestFilePaths, log, packageValidatorSettings); CheckPackageFiles(packageFilePaths, manifestFilePaths, log, packageValidatorSettings); }