/// <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());
        }
Esempio n. 2
0
        /// <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 &lt;Organization&gt; 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 &lt;item&gt; 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);
        }
Esempio n. 3
0
        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);
        }