public void UpdatePackageVersion(NapackVersionIdentifier packageVersion, NapackVersion updatedVersion)
 {
     if (packageStore.ContainsKey(packageVersion.GetFullName()))
     {
         packageStore[packageVersion.GetFullName()] = updatedVersion;
     }
 }
        /// <summary>
        /// Creates and saves a new napack.
        /// </summary>
        /// <param name="napackName">The name of the napack</param>
        /// <param name="newNapack">The new napack to create/save</param>
        /// <param name="napackSpec">The napack specification</param>
        public void SaveNewNapack(string napackName, NewNapack newNapack, NapackSpec napackSpec)
        {
            NapackVersionIdentifier version        = new NapackVersionIdentifier(napackName, 1, 0, 0);
            NapackMetadata          metadata       = NapackMetadata.CreateFromNewNapack(napackName, newNapack);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapack.NewNapackVersion);

            foreach (string author in newNapack.NewNapackVersion.Authors)
            {
                AddAuthorConsumption(author, version);
            }

            foreach (string userId in newNapack.metadata.AuthorizedUserIds)
            {
                AddUserAuthorization(userId, napackName);
            }

            foreach (NapackMajorVersion consumedPackage in newNapack.NewNapackVersion.Dependencies)
            {
                AddConsumingPackage(consumedPackage, version);
            }

            // Add the new napack to all the various stores.
            NapackStats stats = new NapackStats();

            stats.AddVersion(newNapack.NewNapackVersion);

            searchIndices.Add(version.NapackName, NapackSearchIndex.CreateFromMetadataAndStats(metadata, stats));

            statsStore.Add(version.NapackName, stats);
            packageMetadataStore.Add(version.NapackName, metadata);
            packageStore.Add(version.GetFullName(), packageVersion);
            specStore.Add(version.GetFullName(), napackSpec);
        }
Beispiel #3
0
        public void SaveNewNapack(string napackName, NewNapack newNapack, NapackSpec napackSpec)
        {
            NapackVersionIdentifier version        = new NapackVersionIdentifier(napackName, 1, 0, 0);
            NapackMetadata          metadata       = NapackMetadata.CreateFromNewNapack(napackName, newNapack);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapack.NewNapackVersion);

            foreach (string author in newNapack.NewNapackVersion.Authors)
            {
                AddItem(author.ToUpperInvariant(), version, AuthorPackageTable, "authorName", "packageVersionList", false);
            }

            foreach (string userId in newNapack.metadata.AuthorizedUserIds)
            {
                AddItem(userId.ToUpperInvariant(), napackName, UserPackageTable, "userId", "packageNameList", true);
            }

            foreach (NapackMajorVersion consumedPackage in newNapack.NewNapackVersion.Dependencies)
            {
                AddItem(consumedPackage.ToString(), version, PackageConsumersTable, "packageMajorVersionId", "consumingPackages", false);
            }

            // Add the new napack to all the various stores.
            NapackStats stats = new NapackStats();

            stats.AddVersion(newNapack.NewNapackVersion);

            ExecuteTransactionCommand((command) =>
            {
                string statsEncoded = Serializer.Serialize(stats);
                command.Parameters.Add(napackName);
                command.Parameters.Add(statsEncoded);
                command.CommandText = $"INSERT INTO {PackageStatsTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();

                string metadataEncoded        = Serializer.Serialize(metadata);
                string safeDescriptionAndTags = GetSafeDescriptionAndTags(metadata);
                command.Parameters.Add(napackName);
                command.Parameters.Add(safeDescriptionAndTags);
                command.Parameters.Add(metadataEncoded);
                command.CommandText = $"INSERT INTO {PackageMetadataTable} VALUES ($1, $2, $3)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();

                string napackSpecEncoded = Serializer.Serialize(napackSpec);
                command.Parameters.Add(version.GetFullName());
                command.Parameters.Add(napackSpecEncoded);
                command.CommandText = $"INSERT INTO {PackageSpecsTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();

                string packageVersionEncoded = Serializer.Serialize(packageVersion);
                command.Parameters.Add(version.GetFullName());
                command.Parameters.Add(packageVersionEncoded);
                command.CommandText = $"INSERT INTO {PackageStoreTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();
            });
        }
Beispiel #4
0
 public void UpdatePackageVersion(NapackVersionIdentifier packageVersion, NapackVersion updatedVersion)
 {
     ExecuteCommand($"UPDATE {PackageStoreTable} SET package = $1 WHERE packageVersion = $2", (command) =>
     {
         command.Parameters.Add(Serializer.Serialize(updatedVersion));
         command.Parameters.Add(packageVersion.GetFullName());
         command.ExecuteNonQuery();
         command.Parameters.Clear();
     });
 }
Beispiel #5
0
        public static NapackVersion CreateFromNewNapack(NewNapackVersion newNapackVersion)
        {
            NapackVersion version = new NapackVersion()
            {
                Authors      = newNapackVersion.Authors,
                Files        = newNapackVersion.Files,
                Dependencies = newNapackVersion.Dependencies ?? new List <NapackMajorVersion>()
            };

            return(version);
        }
Beispiel #6
0
        public ApiModule()
            : base("/api")
        {
            // Gets a Napack package or series of package versions.
            Get["/{packageName}/{version?}"] = parameters =>
            {
                string packageName = parameters.packageName;
                string version     = null;
                try
                {
                    version = parameters.version;
                }
                catch (RuntimeBinderException)
                {
                }

                if (version == null)
                {
                    NapackMetadata metadata = Global.NapackStorageManager.GetPackageMetadata(packageName, false);
                    return(View["NapackVersions", new VersionsModel(metadata)]);
                }
                else
                {
                    // Attempt to parse our the version string.
                    List <int> components;
                    try
                    {
                        components = version.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Select(item => int.Parse(item)).ToList();
                        if (components.Count != 3)
                        {
                            throw new Exception();
                        }
                    }
                    catch (Exception)
                    {
                        throw new InvalidNapackVersionException();
                    }

                    NapackVersionIdentifier versionId = new NapackVersionIdentifier(packageName, components[0], components[1], components[2]);
                    NapackSpec    spec           = Global.NapackStorageManager.GetPackageSpecification(versionId);
                    NapackVersion packageVersion = Global.NapackStorageManager.GetPackageVersion(versionId);

                    return(View["NapackApi", new ApiModel(versionId.GetFullName(), spec, packageVersion.Dependencies)]);
                }
            };
        }
        /// <summary>
        /// Saves a new napack version onto an existing napack.
        /// </summary>
        /// <param name="package">The package metadata.</param>
        /// <param name="currentVersion">The current version of the napack.</param>
        /// <param name="upversionType">The type of upversioning to perform.</param>
        /// <param name="newNapackVersion">The new napack version.</param>
        /// <param name="newVersionSpec">The napack specification.</param>
        public void SaveNewNapackVersion(NapackMetadata package, NapackVersionIdentifier currentVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion, NapackSpec newVersionSpec)
        {
            NapackVersionIdentifier nextVersion    = new NapackVersionIdentifier(currentVersion.NapackName, currentVersion.Major, currentVersion.Minor, currentVersion.Patch);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapackVersion);

            foreach (string author in newNapackVersion.Authors)
            {
                AddAuthorConsumption(author, nextVersion);
            }

            // Changes in user authorization do not occur through napack version updates.

            foreach (NapackMajorVersion consumedPackage in newNapackVersion.Dependencies)
            {
                AddConsumingPackage(consumedPackage, nextVersion);
            }

            UpdatePackageMetadataStore(package, nextVersion, upversionType, newNapackVersion);
            packageStore.Add(nextVersion.GetFullName(), packageVersion);
            specStore.Add(nextVersion.GetFullName(), newVersionSpec);
        }
Beispiel #8
0
        public void SaveNewNapackVersion(NapackMetadata package, NapackVersionIdentifier currentVersion, NapackAnalyst.UpversionType upversionType, NewNapackVersion newNapackVersion, NapackSpec newVersionSpec)
        {
            NapackVersionIdentifier nextVersion    = new NapackVersionIdentifier(currentVersion.NapackName, currentVersion.Major, currentVersion.Minor, currentVersion.Patch);
            NapackVersion           packageVersion = NapackVersion.CreateFromNewNapack(newNapackVersion);

            foreach (string author in newNapackVersion.Authors)
            {
                AddItem(author.ToUpperInvariant(), nextVersion, AuthorPackageTable, "authorName", "packageVersionList", false);
            }

            //
            // // Changes in user authorization do not occur through napack version updates.
            //

            foreach (NapackMajorVersion consumedPackage in newNapackVersion.Dependencies)
            {
                AddItem(consumedPackage.ToString(), nextVersion, PackageConsumersTable, "packageMajorVersionId", "consumingPackages", false);
            }

            ExecuteTransactionCommand((command) =>
            {
                string napackSpecEncoded = Serializer.Serialize(newVersionSpec);
                command.Parameters.Add(nextVersion.GetFullName());
                command.Parameters.Add(napackSpecEncoded);
                command.CommandText = $"INSERT INTO {PackageSpecsTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();

                string packageVersionEncoded = Serializer.Serialize(packageVersion);
                command.Parameters.Add(nextVersion.GetFullName());
                command.Parameters.Add(packageVersionEncoded);
                command.CommandText = $"INSERT INTO {PackageStoreTable} VALUES ($1, $2)";
                command.ExecuteNonQuery();
                command.Parameters.Clear();
            });

            // Our lock is cleared at last here.
            UpdatePackageMetadataStore(package, nextVersion, upversionType, newNapackVersion);
        }
Beispiel #9
0
        public AdminModule()
            : base("/admin")
        {
            // Shuts down the Napack Framework Server cleanly.
            Post["/shutdown"] = parameters =>
            {
                AdminModule.ValidateAdmin(this.Context);
                Global.ShutdownEvent.Set();
                return(this.Response.AsJson(new { UtcTime = DateTime.UtcNow }, HttpStatusCode.ImATeapot));
            };

            // Performs the specified user modification to the given user.
            Patch["/users"] = parameters =>
            {
                UserModification userModification = SerializerExtensions.Deserialize <UserModification>(this.Context);
                AdminModule.ValidateAdmin(this.Context);

                UserIdentifier user = Global.NapackStorageManager.GetUser(userModification.UserId);
                switch (userModification.Operation)
                {
                case Operation.DeleteUser:
                    return(UsersModule.DeleteUser(this.Response, user));

                case Operation.UpdateAccessKeys:
                    UsersModule.AssignSecretsAndSendVerificationEmail(user);
                    Global.NapackStorageManager.UpdateUser(user);
                    break;
                }

                return(this.Response.AsJson(new
                {
                    OperationPerformed = userModification.Operation
                }));
            };

            // Recalls a package.
            Post["/recall/{packageName}/{majorVersion}"] = parameters =>
            {
                string packageName  = parameters.packageName;
                int    majorVersion = int.Parse(parameters.majorVersion);
                AdminModule.ValidateAdmin(this.Context);

                NapackMetadata             metadata             = Global.NapackStorageManager.GetPackageMetadata(packageName, true);
                NapackMajorVersionMetadata majorVersionMetadata = metadata.GetMajorVersion(majorVersion);
                majorVersionMetadata.Recalled = true;
                Global.NapackStorageManager.UpdatePackageMetadata(metadata);

                return(this.Response.AsJson(new
                {
                    VersionRecalled = majorVersion
                }));
            };

            // Deletes a package.
            //
            // Deleting a Napack involves removing:
            // - The package statistics.
            // - All of the specs.
            // - All of the packages.
            // - The metadata

            // In addition, the package is removed from.
            // - The listing of packages an author has authored.
            // - The listing of packages a user has access to.
            // - Each package that took a dependency on this package*
            //
            // Finally, an email is sent to all affected users and authorized users.
            Delete["/manage/{packageName}"] = parameters =>
            {
                string packageName = parameters.packageName;
                AdminModule.ValidateAdmin(this.Context);

                // TODO there's a lot of hardening that can be done here to prevent failures.
                NapackMetadata metadata = Global.NapackStorageManager.GetPackageMetadata(packageName, true);
                Global.NapackStorageManager.RemovePackageStatistics(packageName);

                foreach (string authorizedUser in metadata.AuthorizedUserIds)
                {
                    Global.NapackStorageManager.RemoveAuthoredPackages(authorizedUser, packageName);
                }

                Dictionary <string, List <NapackVersionIdentifier> > packagesToRemovePerAuthor = new Dictionary <string, List <NapackVersionIdentifier> >();
                foreach (KeyValuePair <int, NapackMajorVersionMetadata> majorVersion in metadata.Versions)
                {
                    foreach (KeyValuePair <int, List <int> > minorVersion in majorVersion.Value.Versions)
                    {
                        foreach (int patchVersion in minorVersion.Value)
                        {
                            NapackVersionIdentifier versionIdentifier = new NapackVersionIdentifier(packageName, majorVersion.Key, minorVersion.Key, patchVersion);
                            NapackVersion           version           = Global.NapackStorageManager.GetPackageVersion(versionIdentifier);

                            foreach (string author in version.Authors)
                            {
                                if (!packagesToRemovePerAuthor.ContainsKey(author))
                                {
                                    packagesToRemovePerAuthor.Add(author, new List <NapackVersionIdentifier>());
                                }

                                packagesToRemovePerAuthor[author].Add(versionIdentifier);
                            }

                            Global.NapackStorageManager.RemovePackageVersion(versionIdentifier);
                            Global.NapackStorageManager.RemovePackageSpecification(versionIdentifier);
                        }
                    }
                }

                HashSet <string> affectedPackages = new HashSet <string>();
                foreach (NapackMajorVersion majorVersion in metadata.Versions.Keys.Select(value => new NapackMajorVersion(packageName, value)))
                {
                    List <NapackVersionIdentifier> consumingPackages = Global.NapackStorageManager.GetPackageConsumers(majorVersion).ToList();
                    foreach (NapackVersionIdentifier consumingPackage in consumingPackages)
                    {
                        NapackVersion version = Global.NapackStorageManager.GetPackageVersion(consumingPackage);
                        if (version.Dependencies.Remove(majorVersion))
                        {
                            Global.NapackStorageManager.UpdatePackageVersion(consumingPackage, version);
                            affectedPackages.Add(consumingPackage.NapackName);
                        }
                    }
                }

                HashSet <string> affectedUsers = new HashSet <string>();
                foreach (string affectedPackage in affectedPackages)
                {
                    NapackMetadata affectedPackageMetadata = Global.NapackStorageManager.GetPackageMetadata(affectedPackage, true);
                    foreach (string authorizedUserId in affectedPackageMetadata.AuthorizedUserIds)
                    {
                        affectedUsers.Add(authorizedUserId);
                    }
                }

                // Send the emails now that we're all done.
                foreach (string authorizedUserId in metadata.AuthorizedUserIds)
                {
                    UserIdentifier user = Global.NapackStorageManager.GetUser(authorizedUserId);
                    Global.EmailManager.SendPackageDeletionEmail(user, packageName, false);
                    Global.NapackStorageManager.UpdateUser(user);
                }

                foreach (string authorizedUserId in affectedUsers)
                {
                    UserIdentifier user = Global.NapackStorageManager.GetUser(authorizedUserId);
                    Global.EmailManager.SendPackageDeletionEmail(user, packageName, true);
                    Global.NapackStorageManager.UpdateUser(user);
                }

                return(this.Response.AsJson(new
                {
                    AuthorizedUsersNotified = metadata.AuthorizedUserIds,
                    AffectedUsersNotified = affectedUsers,
                    Deleted = true
                }, HttpStatusCode.Gone));
            };
        }