public (bool, string) VerifyPackage(string packageId) { Manifest manifest = this.GetManifest(packageId); if (manifest == null) { throw new PackageNotFoundException(packageId); } StringBuilder hashes = new StringBuilder(); string[] files = files = _hashService.SortFileArrayForHashing(manifest.Files.Select(r => r.Path).ToArray()); List <string> missingFiles = new List <string>(); foreach (string filePath in files) { ManifestItem manifestItem = manifest.Files.FirstOrDefault(r => r.Path == filePath); string directFilePath = Path.Combine(_settings.RepositoryPath, manifestItem.Path, manifestItem.Hash, "bin"); if (File.Exists(directFilePath)) { hashes.Append(_hashService.FromString(manifestItem.Path)); hashes.Append(_hashService.FromFile(directFilePath).Item1); } else { missingFiles.Add(directFilePath); } } if (missingFiles.Any()) { return(false, $"Expected package files missing : {string.Join(",", missingFiles)}"); } string finalHash = _hashService.FromString(hashes.ToString()); if (finalHash != manifest.Hash) { return(false, $"Actual package hash {finalHash} does not match expected manifest hash {manifest.Hash}"); } return(true, string.Empty); }
/// <summary> /// /// </summary> /// <param name="manifest"></param> public PackageCreateResult CreatePackage(PackageCreateArguments newPackage) { List <string> transactionLog = new List <string>(); try { _log.LogInformation("Package create started"); // validate the contents of "newPackage" object if (!newPackage.Files.Any()) { return new PackageCreateResult { ErrorType = PackageCreateErrorTypes.MissingValue, PublicError = "Files collection is empty." } } ; if (string.IsNullOrEmpty(newPackage.Id)) { return new PackageCreateResult { ErrorType = PackageCreateErrorTypes.MissingValue, PublicError = "Id is required." } } ; // ensure package does not already exist if (_indexReader.PackageNameInUse(newPackage.Id)) { return new PackageCreateResult { ErrorType = PackageCreateErrorTypes.PackageExists } } ; // if archive, ensure correct file count if (newPackage.IsArchive && newPackage.Files.Count() != 1) { return new PackageCreateResult { ErrorType = PackageCreateErrorTypes.InvalidFileCount } } ; // write attachments to work folder long size = newPackage.Files.Sum(f => f.Content.Length); _workspace.Initialize(); // if archive, unzip if (newPackage.IsArchive) { _workspace.AddArchiveContent(newPackage.Files.First().Content); } else { foreach (PackageCreateItem formFile in newPackage.Files) { _workspace.AddIncomingFile(formFile.Content, formFile.FileName); } } // get all files which were uploaded, sort alphabetically for combined hashing string[] files = _workspace.GetIncomingFileNames().ToArray(); files = _hashService.SortFileArrayForHashing(files); // prevent deletes of empty repository folders this package might need to write to LinkLock.Instance.Lock(newPackage.Id); _log.LogInformation("Hashing package content"); IDictionary <string, string> hashes = new Dictionary <string, string>(); foreach (string file in files) { hashes.Add(file, null); } files.AsParallel().ForAll(delegate(string filePath) { try { // get hash of incoming file (string, long)fileProperties = _workspace.GetIncomingFileProperties(filePath); lock (hashes) { hashes[filePath] = (_hashService.FromString(filePath) + fileProperties.Item1); } // todo : this would be a good place to confirm that existingPackageId is actually valid _workspace.WriteFile(filePath, fileProperties.Item1, fileProperties.Item2, newPackage.Id); } catch (Exception ex) { // give exception more context throw new Exception($"Error processing hash for file {filePath}", ex); } }); _workspace.Manifest.Description = newPackage.Description; _log.LogInformation("Writing package manifest"); // calculate package hash from child hashes _workspace.WriteManifest(newPackage.Id, _hashService.FromString(string.Join(string.Empty, hashes.Values))); _workspace.Dispose(); if (_settings.AutoCreateArchiveOnPackageCreate) { _log.LogInformation("Generating package archive"); using (Stream stream = _indexReader.GetPackageAsArchive(newPackage.Id)){ } } return(new PackageCreateResult { Success = true, PackageHash = _workspace.Manifest.Hash }); } catch (Exception ex) { _log.LogError(ex, "Unexpected error"); return(new PackageCreateResult { ErrorType = PackageCreateErrorTypes.UnexpectedError }); } finally { if (!string.IsNullOrEmpty(newPackage.Id)) { LinkLock.Instance.Unlock(newPackage.Id); } } }