public async Task <IActionResult> Post([FromBody] UploadPackageRequestDto uploadPackageRequestDto) { IList <PackageFile> files = uploadPackageRequestDto.PackageFiles .Select(file => new PackageFile(file.FileName, file.FileContent)) .ToList(); // put a hard limit on the amount of files per package for now if (files.Count > 99) { return(this.BadRequest("can not have more then 100 items in a package")); } PackageFile ethereumPm = files.FirstOrDefault(f => f.FileName == Constants.EthereumPmJson); if (ethereumPm == null) { return(this.BadRequest("To upload a package you need a `ethereum-pm.json` file")); } JObject ethereumPmJson; try { ethereumPmJson = JObject.Parse(ethereumPm.FileContent); } catch (Exception) { return(this.BadRequest("Invalid JSON - `ethereum-pm.json`")); } EthereumPmMetaData metaData = new EthereumPmMetaData() { Description = (string)ethereumPmJson["description"], GitHub = (string)ethereumPmJson["github"], Private = (bool?)ethereumPmJson["private"] ?? false, Team = (string)ethereumPmJson["team"], Keywords = (IList <string>)ethereumPmJson["keywords"] }; PackageFiles packageFiles = new PackageFiles ( uploadPackageRequestDto.PackageVersion, uploadPackageRequestDto.PackageName, (IReadOnlyCollection <PackageFile>)files ); try { UnpackedJwt unpackedJwt = this._jwtService.UnpackJwtClaimsToProfile(User.Claims.ToList()); await this._packageService.UploadPackageAsync(packageFiles, metaData, unpackedJwt.Username); } catch (Exception ex) { return(this.BadRequest(ex)); } return(this.Ok()); }
/// <summary> /// /// </summary> /// <param name="packageFiles"></param> /// <param name="ethereumPmMetaData"></param> /// <param name="jwtUsername"></param> /// <returns></returns> public async Task UploadPackageAsync(PackageFiles packageFiles, EthereumPmMetaData ethereumPmMetaData, string jwtUsername) { PackageDetailsEntity packageDetails = await this._dynamoDbService.GetItemAsync <PackageDetailsEntity>(packageFiles.PackageName); // if it is null then its a brand new package if (packageDetails == null) { // should be in a transaction which i will put in, as if one of these // fails then i want to roll back all the data, i don't really want to // to insert then delete so will look at dynamodb to see if this rollback // logic exists TeamsEntity teamsEntity = null; // if it is a package for a team if (!string.IsNullOrEmpty(ethereumPmMetaData.Team)) { teamsEntity = await this._dynamoDbService.GetItemAsync <TeamsEntity>(ethereumPmMetaData.Team); if (teamsEntity == null) { throw new Exception("Team does not exists"); } packageDetails = new PackageDetailsEntity { PackageName = packageFiles.PackageName, Version = new List <string> { packageFiles.Version }, Description = ethereumPmMetaData.Description, Keywords = ethereumPmMetaData.Keywords, Private = ethereumPmMetaData.Private, Team = ethereumPmMetaData.Team, GitHub = ethereumPmMetaData.GitHub, Owner = ethereumPmMetaData.Team, LatestVersion = packageFiles.Version, Deprecated = false, CreatedOn = DateTime.UtcNow }; } else { packageDetails = new PackageDetailsEntity { PackageName = packageFiles.PackageName, Version = new List <string> { packageFiles.Version }, Description = ethereumPmMetaData.Description, Keywords = ethereumPmMetaData.Keywords, Private = ethereumPmMetaData.Private, Team = ethereumPmMetaData.Team, GitHub = ethereumPmMetaData.GitHub, Owner = jwtUsername, LatestVersion = packageFiles.Version, Deprecated = false, AdminUsers = new List <string> { jwtUsername }, Users = new List <string> { jwtUsername }, CreatedOn = DateTime.UtcNow }; } await this._dynamoDbService.PutItemAsync <PackageDetailsEntity>(packageDetails); if (teamsEntity != null) { if (teamsEntity.Packages == null || teamsEntity.Packages.GetType() != typeof(List <string>)) { teamsEntity.Packages = new List <string>(); } teamsEntity.Packages.Add(packageFiles.PackageName); await this._dynamoDbService.PutItemAsync <TeamsEntity>(teamsEntity); } else { // as they have authenticated with the request the user should always exist // do not want to do a load on db to check each time UsersEntity usersEntity = await this._dynamoDbService.GetItemAsync <UsersEntity>(jwtUsername); if (usersEntity.Packages == null || usersEntity.Packages.GetType() != typeof(List <string>)) { usersEntity.Packages = new List <string>(); } usersEntity.Packages.Add(packageFiles.PackageName); await this._dynamoDbService.PutItemAsync <UsersEntity>(usersEntity); } } else { if (!this.UpdatingPackageHigherVersionThenCurrent(packageDetails.LatestVersion, packageFiles.Version)) { throw new Exception("Your package version is not higher then the current one"); } bool allowedToUpdatePackage = await this.AllowedToUpdatePackageAsync(packageDetails.Team, packageDetails.AdminUsers, jwtUsername); if (!allowedToUpdatePackage) { throw new Exception("You are not allowed to update this package"); } packageDetails.Version.Add(packageFiles.Version); packageDetails.GitHub = ethereumPmMetaData.GitHub; packageDetails.LatestVersion = packageFiles.Version; packageDetails.Description = ethereumPmMetaData.Description; packageDetails.Keywords = ethereumPmMetaData.Keywords; await this._dynamoDbService.PutItemAsync <PackageDetailsEntity>(packageDetails); } // upload the files last, this means it all has been successfully inserted into // the db string keyName = $"{packageFiles.PackageName}/{packageFiles.Version}"; await this._s3Service.UploadFilesAsync(packageFiles.Files.ToS3Files(), keyName); }