Пример #1
0
 public AzurePipelinesController(
     IGitHubApplicationClientFactory gitHubApplicationClientFactory,
     IAzureDevOpsClientFactory azureDevOpsClientFactory,
     IOptions <BuildMonitorOptions> options,
     ILogger <AzurePipelinesController> logger)
 {
     _gitHubApplicationClientFactory = gitHubApplicationClientFactory;
     _azureDevOpsClientFactory       = azureDevOpsClientFactory;
     _options        = options;
     _logger         = logger;
     _clientLazy     = new Lazy <IAzureDevOpsClient>(BuildAzureDevOpsClient);
     _projectMapping = new Lazy <Task <Dictionary <string, string> > >(GetProjectMappingInternal);
 }
Пример #2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app,
            IMergePolicyRunnerFactory runnerFactory,
            IAzureDevOpsClientFactory azDoClientFactory,
            ILogger <Startup> logger)
        {
            app.UseSerilogRequestLogging();
            app.Use(ExceptionHandler);
            app.UseRouting();
            app.UseCors();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", Home);
                endpoints.MapPost("/jwt", JwtRoute);
                endpoints.MapPost("/webhook", Webhook).RequireAuthorization();
                endpoints.MapDelete("/policies", ClearPolicies);
            });

            async Task Home(HttpContext context)
            {
                await context.Response.WriteAsync("Merge-a-Bot");
            }

            async Task JwtRoute(HttpContext context)
            {
                using var sr = new StreamReader(context.Request.Body);
                var pat = await sr.ReadToEndAsync();

                if (string.IsNullOrEmpty(pat))
                {
                    context.Response.StatusCode = StatusCodes.Status400BadRequest;
                    await context.Response.WriteAsync("Body did not contain Personal Access Token");

                    return;
                }

                var claims = new List <Claim> {
                    new Claim(JwtRegisteredClaimNames.Sub, pat),
                };

                var token = new JwtSecurityToken(
                    issuer: JwtIssuer,
                    audience: null,
                    claims: claims,
                    expires: DateTime.UtcNow.Date.AddYears(1),
                    signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSigningKey)), SecurityAlgorithms.HmacSha256)
                    );

                var tokenValue = new JwtSecurityTokenHandler().WriteToken(token);
                await context.Response.WriteAsync(tokenValue);
            }

            async Task Webhook(HttpContext context)
            {
                var request = context.Request;

                if (!HttpMethods.IsPost(request.Method))
                {
                    return;
                }

                if (request.ContentType == null || !request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                {
                    return;
                }

                var payload = await WebhookDeserializer.DeserializeAsync(request.Body);

                var pat = context.User.FindFirstValue(ClaimTypes.NameIdentifier);

                if (payload != null)
                {
                    var azDoClient     = azDoClientFactory.Create(pat);
                    var organization   = payload.Resource.Repository.GetOrganization();
                    var baseUrl        = payload.Resource.Repository.GetBaseUrl();
                    var factoryContext = new MergePolicyRunnerFactoryContext(azDoClient, payload.Resource.Repository.Id, organization, baseUrl);
                    var runner         = await runnerFactory.CreateAsync(factoryContext);

                    await runner.RunAsync(azDoClient, payload);
                }
            }

            async Task ExceptionHandler(HttpContext context, Func <Task> next)
            {
                try
                {
                    await next();
                }
                catch (Exception ex)
                {
                    logger.LogError(new EventId(1, "UnhandledError"), ex, "Unhandled error");
                    context.Response.StatusCode = 200;
                }
            }

            Task ClearPolicies(HttpContext context)
            {
                var org    = context.Request.Query["organization"];
                var repoId = context.Request.Query["repositoryId"];

                if (string.IsNullOrEmpty(org) || string.IsNullOrEmpty(repoId))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    return(Task.CompletedTask);
                }
                runnerFactory.Clear(new MergePolicyRunnerFactoryContext(repoId, org));
                return(Task.CompletedTask);
            }
        }