Beispiel #1
0
        public async Task <IActionResult> Create([FromBody, Required] DefaultChannel.DefaultChannelCreateData data)
        {
            int     channelId = data.ChannelId;
            Channel channel   = await _context.Channels.FindAsync(channelId);

            if (channel == null)
            {
                return(NotFound(new ApiError($"The channel with id '{channelId}' was not found.")));
            }

            var defaultChannel = new Data.Models.DefaultChannel
            {
                Channel    = channel,
                Repository = data.Repository,
                Branch     = data.Branch,
                Enabled    = data.Enabled ?? true
            };
            await _context.DefaultChannels.AddAsync(defaultChannel);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(
                       new
            {
                action = "Get",
                id = defaultChannel.Id
            },
                       new DefaultChannel(defaultChannel)));
        }
        public async Task <IActionResult> DeleteChannel(int id)
        {
            Data.Models.Channel channel = await _context.Channels
                                          .Include(ch => ch.ChannelReleasePipelines)
                                          .FirstOrDefaultAsync(c => c.Id == id);

            if (channel == null)
            {
                return(NotFound());
            }

            // Ensure that there are no subscriptions associated with the channel
            if (await _context.Subscriptions.AnyAsync(s => s.ChannelId == id))
            {
                return(BadRequest(
                           new ApiError($"The channel with id '{id}' has associated subscriptions. " +
                                        "Please remove these before removing this channel.")));
            }

            if (channel.ChannelReleasePipelines != null && channel.ChannelReleasePipelines.Any())
            {
                return(BadRequest(
                           new ApiError($"The channel with id '{id}' has '{channel.ChannelReleasePipelines.Count()}' " +
                                        $"release pipeline(s) attached to it. Detach those release pipelines(s) first.")));
            }

            _context.Channels.Remove(channel);

            await _context.SaveChangesAsync();

            return(Ok(new Channel(channel)));
        }
        public override async Task <IActionResult> UpdateSubscription(Guid id, [FromBody] v2018_07_16.Models.SubscriptionUpdate update)
        {
            Data.Models.Subscription subscription = await _context.Subscriptions.Where(sub => sub.Id == id)
                                                    .FirstOrDefaultAsync();

            if (subscription == null)
            {
                return(NotFound());
            }

            var doUpdate = false;

            if (!string.IsNullOrEmpty(update.SourceRepository))
            {
                subscription.SourceRepository = update.SourceRepository;
                doUpdate = true;
            }

            if (update.Policy != null)
            {
                subscription.PolicyObject = update.Policy.ToDb();
                doUpdate = true;
            }

            if (!string.IsNullOrEmpty(update.ChannelName))
            {
                Data.Models.Channel channel = await _context.Channels.Where(c => c.Name == update.ChannelName)
                                              .FirstOrDefaultAsync();

                if (channel == null)
                {
                    return(BadRequest(
                               new ApiError(
                                   "The request is invalid",
                                   new[] { $"The channel '{update.ChannelName}' could not be found." })));
                }

                subscription.Channel = channel;
                doUpdate             = true;
            }

            if (update.Enabled.HasValue)
            {
                subscription.Enabled = update.Enabled.Value;
                doUpdate             = true;
            }

            if (doUpdate)
            {
                _context.Subscriptions.Update(subscription);
                await _context.SaveChangesAsync();
            }


            return(Ok(new Subscription(subscription)));
        }
        public async Task <IActionResult> CreateChannel([Required] string name, [Required] string classification)
        {
            var channelModel = new Data.Models.Channel {
                Name = name, Classification = classification
            };
            await _context.Channels.AddAsync(channelModel);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(new { action = "GetChannel", id = channelModel.Id }, new Channel(channelModel)));
        }
        public async Task <IActionResult> DeleteChannel(int id)
        {
            Data.Models.Channel channel = await _context.Channels.FirstOrDefaultAsync(c => c.Id == id);

            if (channel == null)
            {
                return(NotFound());
            }

            _context.Channels.Remove(channel);

            await _context.SaveChangesAsync();

            return(Ok(new Channel(channel)));
        }
        public virtual async Task <IActionResult> Create([FromBody, Required] Goal.GoalRequestJson goalData, [Required] String channelName, [Required] int definitionId)
        {
            Data.Models.Channel channel = await _context.Channels
                                          .FirstOrDefaultAsync(c => c.Name.Equals(channelName));

            if (channel == null)
            {
                return(NotFound());
            }
            Data.Models.GoalTime goal = await _context.GoalTime
                                        .FirstOrDefaultAsync(g => g.DefinitionId == definitionId && g.ChannelId == channel.Id);

            if (goal == null)
            {
                goal = new Data.Models.GoalTime
                {
                    DefinitionId = definitionId,
                    Minutes      = goalData.Minutes,
                    ChannelId    = channel.Id
                };
                await _context.GoalTime.AddAsync(goal);
            }
            else
            {
                goal.Minutes = goalData.Minutes;
                _context.GoalTime.Update(goal);
            }
            await _context.SaveChangesAsync();

            return(Ok(new Goal(goal)));
        }
        public async Task <IActionResult> Create([FromBody] SubscriptionData subscription)
        {
            Data.Models.Channel channel = await _context.Channels.Where(c => c.Name == subscription.ChannelName)
                                          .FirstOrDefaultAsync();

            if (channel == null)
            {
                return(BadRequest(
                           new ApiError(
                               "the request is invalid",
                               new[] { $"The channel '{subscription.ChannelName}' could not be found." })));
            }

            var subscriptionModel = new Data.Models.Subscription(subscription)
            {
                Channel = channel
            };
            await _context.Subscriptions.AddAsync(subscriptionModel);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(
                       new { action = "GetSubscription", id = subscriptionModel.Id },
                       new Subscription(subscriptionModel)));
        }
        private async Task UpdateUserAsync(ApplicationUser user,
                                           BuildAssetRegistryContext dbContext,
                                           UserManager <ApplicationUser> userManager,
                                           SignInManager <ApplicationUser> signInManager,
                                           GitHubClaimResolver gitHubClaimResolver)
        {
            using (IDbContextTransaction txn = await dbContext.Database.BeginTransactionAsync())
            {
                string token = await userManager.GetAuthenticationTokenAsync(user, GitHubScheme, "access_token");

                var newClaims = (await gitHubClaimResolver.GetUserInformationClaims(token)).Concat(
                    await gitHubClaimResolver.GetMembershipClaims(token)
                    ).Where(AccountController.ShouldAddClaimToUser);
                var currentClaims = (await userManager.GetClaimsAsync(user)).ToList();

                // remove old claims
                await userManager.RemoveClaimsAsync(user, currentClaims);

                // add new claims
                await userManager.AddClaimsAsync(user, newClaims);

                user.LastUpdated = DateTimeOffset.UtcNow;
                await dbContext.SaveChangesAsync();

                txn.Commit();
            }
        }
Beispiel #9
0
        private async Task UpdateUserAsync(
            ApplicationUser user,
            BuildAssetRegistryContext dbContext,
            UserManager <ApplicationUser> userManager,
            SignInManager <ApplicationUser> signInManager)
        {
            using (IDbContextTransaction txn = await dbContext.Database.BeginTransactionAsync())
            {
                string token = await userManager.GetAuthenticationTokenAsync(user, GitHubScheme, "access_token");

                var          roles        = new HashSet <string>(await GetGithubRolesAsync(token));
                List <Claim> currentRoles = (await userManager.GetClaimsAsync(user))
                                            .Where(c => c.Type == ClaimTypes.Role)
                                            .ToList();

                // remove claims where github doesn't have the role anymore
                await userManager.RemoveClaimsAsync(user, currentRoles.Where(c => !roles.Contains(c.Value)));

                // add new claims
                await userManager.AddClaimsAsync(
                    user,
                    roles.Where(r => currentRoles.All(c => c.Value != r))
                    .Select(r => new Claim(ClaimTypes.Role, r, ClaimValueTypes.String, GitHubScheme)));

                user.LastUpdated = DateTimeOffset.UtcNow;
                await dbContext.SaveChangesAsync();

                txn.Commit();
            }
        }
Beispiel #10
0
        public async Task <IActionResult> Create([FromBody] BuildData build)
        {
            var buildModel = new Data.Models.Build(build)
            {
                DateProduced = DateTimeOffset.UtcNow,
                Dependencies = await _context.Builds.Where(b => build.Dependencies.Contains(b.Id)).ToListAsync()
            };
            await _context.Builds.AddAsync(buildModel);

            var defaultChannels = await _context.DefaultChannels
                                  .Where(dc => dc.Repository == buildModel.Repository && dc.Branch == buildModel.Branch)
                                  .Select(dc => dc.ChannelId)
                                  .ToListAsync();

            foreach (var channelId in defaultChannels)
            {
                await _context.BuildChannels.AddAsync(new Data.Models.BuildChannel
                {
                    ChannelId = channelId,
                    Build     = buildModel,
                });
            }
            await _context.SaveChangesAsync();

            return(CreatedAtRoute(new { action = "GetBuild", id = buildModel.Id }, new Build(buildModel)));
        }
Beispiel #11
0
        public async Task <IActionResult> Create([FromBody, Required] DefaultChannel.DefaultChannelCreateData data)
        {
            int     channelId = data.ChannelId;
            Channel channel   = await _context.Channels.FindAsync(channelId);

            if (channel == null)
            {
                return(NotFound(new ApiError($"The channel with id '{channelId}' was not found.")));
            }

            Data.Models.DefaultChannel defaultChannel;

            // Due to abundant retry logic, we'll return a normal response even if this is creating a duplicate, by simply
            // returning the one that already exists vs. HTTP 409 / 500
            var existingInstance = _context.DefaultChannels
                                   .Where(d => d.Channel == channel &&
                                          d.Repository == data.Repository &&
                                          d.Branch == data.Branch)
                                   .FirstOrDefault();

            if (existingInstance != null)
            {
                defaultChannel = existingInstance;
            }
            else
            {
                defaultChannel = new Data.Models.DefaultChannel
                {
                    Channel    = channel,
                    Repository = data.Repository,
                    Branch     = data.Branch,
                    Enabled    = data.Enabled ?? true
                };
                await _context.DefaultChannels.AddAsync(defaultChannel);

                await _context.SaveChangesAsync();
            }
            return(CreatedAtRoute(
                       new
            {
                action = "Get",
                id = defaultChannel.Id
            },
                       new DefaultChannel(defaultChannel)));
        }
Beispiel #12
0
        public async Task <IActionResult> Create([FromBody] BuildData build)
        {
            Data.Models.Build buildModel = build.ToDb();
            buildModel.DateProduced = DateTimeOffset.UtcNow;
            buildModel.Dependencies = build.Dependencies != null ? await _context.Builds.Where(b => build.Dependencies.Contains(b.Id)).ToListAsync() : null;

            await _context.Builds.AddAsync(buildModel);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(new { action = "GetBuild", id = buildModel.Id }, new Build(buildModel)));
        }
Beispiel #13
0
        public async Task <IActionResult> AddAssetLocationToAsset(int assetId, [Required] string location, [Required] LocationType assetLocationType)
        {
            var assetLocation = new Data.Models.AssetLocation
            {
                Location = location,
                Type     = (Maestro.Data.Models.LocationType)assetLocationType,
            };

            Maestro.Data.Models.Asset asset = await _context.Assets
                                              .Include(a => a.Locations)
                                              .Where(a => a.Id == assetId)
                                              .SingleOrDefaultAsync();

            if (asset == null)
            {
                return(NotFound(new ApiError($"The asset with id '{assetId}' was not found.")));
            }

            // If asset location is already in asset, nothing to do
            if (asset.Locations != null &&
                asset.Locations.Any(existing => existing.Location.Equals(assetLocation.Location, StringComparison.OrdinalIgnoreCase) &&
                                    existing.Type == assetLocation.Type))
            {
                return(StatusCode((int)HttpStatusCode.NotModified));
            }

            asset.Locations = asset.Locations ?? new List <Data.Models.AssetLocation>();
            asset.Locations.Add(assetLocation);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(
                       new
            {
                action = "GetAsset",
                id = assetLocation.Id
            },
                       new AssetLocation(assetLocation)));
        }
Beispiel #14
0
        public virtual async Task <IActionResult> DeletePipeline(int id)
        {
            bool isPipelineInUse = await _context.ChannelReleasePipelines.AnyAsync(crp => crp.ReleasePipelineId == id);

            if (isPipelineInUse)
            {
                return(BadRequest(new ApiError($"The pipeline with id '{id}' is in use and cannot be deleted.")));
            }

            Data.Models.ReleasePipeline pipeline = await _context.ReleasePipelines
                                                   .FirstOrDefaultAsync(c => c.Id == id);

            if (pipeline == null)
            {
                return(NotFound());
            }

            _context.ReleasePipelines.Remove(pipeline);

            await _context.SaveChangesAsync();

            return(Ok(new ReleasePipeline(pipeline)));
        }
            public async Task ProcessAsync(JToken argumentToken)
            {
                // This method is called asynchronously whenever a new build is inserted in BAR.
                // It's goal is to compute the incoherent dependencies that the build have and
                // persist the list of them in BAR.

                int buildId = argumentToken.Value <int>();
                DependencyGraphBuildOptions graphBuildOptions = new DependencyGraphBuildOptions()
                {
                    IncludeToolset = false,
                    LookupBuilds   = false,
                    NodeDiff       = NodeDiff.None
                };

                try
                {
                    Data.Models.Build build = await _context.Builds.FindAsync(buildId);

                    DependencyGraph graph = await DependencyGraph.BuildRemoteDependencyGraphAsync(
                        _remoteFactory,
                        build.GitHubRepository ?? build.AzureDevOpsRepository,
                        build.Commit,
                        graphBuildOptions,
                        _logger);

                    var incoherencies = new List <Data.Models.BuildIncoherence>();

                    foreach (var incoherence in graph.IncoherentDependencies)
                    {
                        incoherencies.Add(new Data.Models.BuildIncoherence
                        {
                            Name       = incoherence.Name,
                            Version    = incoherence.Version,
                            Repository = incoherence.RepoUri,
                            Commit     = incoherence.Commit
                        });
                    }

                    _context.Entry(build).Reload();
                    build.Incoherencies = incoherencies;

                    _context.Builds.Update(build);
                    await _context.SaveChangesAsync();
                }
                catch (Exception e)
                {
                    _logger.LogWarning(e, $"Problems computing the dependency incoherencies for BAR build {buildId}");
                }
            }
Beispiel #16
0
        public virtual async Task <IActionResult> DeleteChannel(int id)
        {
            Data.Models.Channel channel = await _context.Channels
                                          .FirstOrDefaultAsync(c => c.Id == id);

            if (channel == null)
            {
                return(NotFound());
            }

            // Ensure that there are no subscriptions associated with the channel
            if (await _context.Subscriptions.AnyAsync(s => s.ChannelId == id))
            {
                return(BadRequest(
                           new ApiError($"The channel with id '{id}' has associated subscriptions. " +
                                        "Please remove these before removing this channel.")));
            }

            _context.Channels.Remove(channel);

            await _context.SaveChangesAsync();

            return(Ok(new Channel(channel)));
        }
        /// <summary>
        /// This method is called asynchronously whenever a new build is inserted in BAR.
        /// It's goal is to compute the incoherent dependencies that the build have and
        /// persist the list of them in BAR.
        /// </summary>
        /// <param name="buildId">Build id for which the incoherencies should be computed.</param>
        private async Task SetBuildIncoherencyInfoAsync(int buildId)
        {
            DependencyGraphBuildOptions graphBuildOptions = new DependencyGraphBuildOptions()
            {
                IncludeToolset = false,
                LookupBuilds   = false,
                NodeDiff       = NodeDiff.None
            };

            try
            {
                using (IServiceScope scope = ServiceScopeFactory.CreateScope())
                {
                    BuildAssetRegistryContext context = scope.ServiceProvider.GetRequiredService <BuildAssetRegistryContext>();

                    Data.Models.Build build = await context.Builds.FindAsync(buildId);

                    DependencyGraph graph = await DependencyGraph.BuildRemoteDependencyGraphAsync(
                        RemoteFactory,
                        build.GitHubRepository ?? build.AzureDevOpsRepository,
                        build.Commit,
                        graphBuildOptions,
                        Logger);

                    var incoherencies = new List <Data.Models.BuildIncoherence>();

                    foreach (var incoherence in graph.IncoherentDependencies)
                    {
                        build.Incoherencies.Add(new Data.Models.BuildIncoherence
                        {
                            Name       = incoherence.Name,
                            Version    = incoherence.Version,
                            Repository = incoherence.RepoUri,
                            Commit     = incoherence.Commit
                        });
                    }
                    context.Entry <Data.Models.Build>(build).Reload();
                    build.Incoherencies = incoherencies;

                    context.Builds.Update(build);
                    await context.SaveChangesAsync();
                }
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, $"Problems computing the dependency incoherencies for BAR build {buildId}");
            }
        }
Beispiel #18
0
        public virtual async Task <IActionResult> Create([FromBody] BuildData build)
        {
            Data.Models.Build buildModel = build.ToDb();
            buildModel.DateProduced = DateTimeOffset.UtcNow;
            if (build.Dependencies?.Count > 0)
            {
                return(BadRequest("This api version doesn't support build dependencies."));
            }
            await _context.Builds.AddAsync(buildModel);

            await _context.SaveChangesAsync();

            return(CreatedAtRoute(
                       new
            {
                action = "GetBuild",
                id = buildModel.Id
            },
                       new Models.Build(buildModel)));
        }
        public async Task <IActionResult> UpdateSubscription(Guid id, [FromBody] SubscriptionUpdate update)
        {
            Data.Models.Subscription subscription = await _context.Subscriptions.Where(sub => sub.Id == id).Include(sub => sub.Channel)
                                                    .FirstOrDefaultAsync();

            if (subscription == null)
            {
                return(NotFound());
            }

            var doUpdate = false;

            if (!string.IsNullOrEmpty(update.SourceRepository))
            {
                subscription.SourceRepository = update.SourceRepository;
                doUpdate = true;
            }

            if (update.Policy != null)
            {
                subscription.PolicyObject = update.Policy.ToDb();
                doUpdate = true;
            }

            if (update.PullRequestFailureNotificationTags != null)
            {
                if (!await AllNotificationTagsValid(update.PullRequestFailureNotificationTags))
                {
                    return(BadRequest(new ApiError("Invalid value(s) provided in Pull Request Failure Notification Tags; is everyone listed publicly a member of the Microsoft github org?")));
                }

                subscription.PullRequestFailureNotificationTags = update.PullRequestFailureNotificationTags;
                doUpdate = true;
            }

            if (!string.IsNullOrEmpty(update.ChannelName))
            {
                Data.Models.Channel channel = await _context.Channels.Where(c => c.Name == update.ChannelName)
                                              .FirstOrDefaultAsync();

                if (channel == null)
                {
                    return(BadRequest(
                               new ApiError(
                                   "The request is invalid",
                                   new[] { $"The channel '{update.ChannelName}' could not be found." })));
                }

                subscription.Channel = channel;
                doUpdate             = true;
            }

            if (update.Enabled.HasValue)
            {
                subscription.Enabled = update.Enabled.Value;
                doUpdate             = true;
            }

            if (doUpdate)
            {
                Data.Models.Subscription equivalentSubscription = await FindEquivalentSubscription(subscription);

                if (equivalentSubscription != null)
                {
                    return(Conflict(
                               new ApiError(
                                   "the request is invalid",
                                   new[]
                    {
                        $"The subscription '{equivalentSubscription.Id}' already performs the same update."
                    })));
                }

                _context.Subscriptions.Update(subscription);
                await _context.SaveChangesAsync();
            }


            return(Ok(new Subscription(subscription)));
        }