Пример #1
0
        private Mock <IOptions <JenoConfiguration> > GetOptionsMock(JenoConfiguration configuration = null)
        {
            if (configuration == null)
            {
                configuration = new JenoConfiguration
                {
                    JenkinsUrl = JenkinsUrl,
                    UserName   = UserName,
                    Token      = Token,
                    Password   = Password,
                    Repository = new Dictionary <string, string>()
                    {
                        { ExampleRepo, ExamplePipeline },
                        { DefaultKey, DefaultPipeline },
                    }
                };
            }

            var options = new Mock <IOptions <JenoConfiguration> >();

            options.Setup(c => c.Value)
            .Returns(configuration);

            return(options);
        }
Пример #2
0
        public async Task TryToRunJobOnJenkinsWithCSRFProtectionWithoutSavedPassword_AskUserForPassword()
        {
            var basicAuthHeader = new BasicAuthenticationHeader(UserName, Password);
            var tokenAuthHeader = new BearerAuthenticationHeader(Token);

            var configuration = new JenoConfiguration
            {
                JenkinsUrl = JenkinsUrl,
                UserName   = UserName,
                Token      = Token,
                Password   = string.Empty,
                Repository = new Dictionary <string, string>()
                {
                    { "firstExampleRepoUrl", "firstExampleJob" },
                    { "secondExampleRepoUrl", "secondExampleJob" },
                    { DefaultKey, DefaultJob },
                }
            };

            var client = new MockHttpMessageHandler();

            client.Expect($"{JenkinsUrl}/{DefaultJob}/job/{Branch}/buildWithParameters")
            .WithHeaders("Authorization", $"{tokenAuthHeader.Scheme} {tokenAuthHeader.Parameter}")
            .Respond(request => new HttpResponseMessage
            {
                StatusCode   = HttpStatusCode.Forbidden,
                ReasonPhrase = "No valid crumb was included in the request"
            });
            client.Expect($"{JenkinsUrl}/crumbIssuer/api/json")
            .WithHeaders("Authorization", $"{basicAuthHeader.Scheme} {basicAuthHeader.Parameter}")
            .Respond(CrumbContentType, JsonConvert.SerializeObject(_crumbHeader));
            client.Expect($"{JenkinsUrl}/{DefaultJob}/job/{Branch}/buildWithParameters")
            .WithHeaders("Authorization", $"{basicAuthHeader.Scheme} {basicAuthHeader.Parameter}")
            .WithHeaders(_crumbHeader.CrumbRequestField, _crumbHeader.Crumb)
            .Respond(HttpStatusCode.OK);

            var httpClientFactory = new Mock <IHttpClientFactory>();

            httpClientFactory.Setup(s => s.CreateClient(It.IsAny <string>()))
            .Returns(client.ToHttpClient());

            var passwordProvider = GetUserConsoleMock();

            var command = new RunJob(GetDefaultGitMock().Object,
                                     GetEncryptorMock().Object,
                                     passwordProvider.Object,
                                     httpClientFactory.Object,
                                     GetOptionsMock(configuration).Object);

            var app = new CommandLineApplication();

            app.Command(command.Name, command.Command);

            var result = await app.ExecuteAsync(new string[] { Command });

            Assert.That(result, Is.EqualTo(JenoCodes.Ok));
            passwordProvider.Verify(s => s.ReadInput("password", true), Times.AtLeastOnce);
        }
Пример #3
0
        private Mock <IConfigurationSerializer> GetConfigurationSerializerMock(JenoConfiguration configuration)
        {
            var configurationProvider = new Mock <IConfigurationSerializer>();

            configurationProvider.Setup(s => s.ReadConfiguration())
            .Returns(Task.FromResult(configuration));
            configurationProvider.Setup(s => s.SaveConfiguration(It.IsAny <JenoConfiguration>()))
            .Returns(Task.CompletedTask);

            return(configurationProvider);
        }
Пример #4
0
        public async Task PassRepositoryDefinedInConfiguration_RunJobSavedInConfiguration()
        {
            var exampleRepo = "firstExampleRepoUrl";
            var exampleJob  = "firstExampleJob";

            var configuration = new JenoConfiguration
            {
                JenkinsUrl = JenkinsUrl,
                UserName   = UserName,
                Token      = Token,
                Password   = Password,
                Repository = new Dictionary <string, string>()
                {
                    { exampleRepo, exampleJob },
                    { "secondExampleRepoUrl", "secondExampleJob" },
                    { DefaultKey, DefaultJob },
                }
            };

            var gitWrapper = new Mock <IGitClient>();

            gitWrapper.Setup(s => s.IsGitRepository(It.IsAny <string>()))
            .Returns(Task.FromResult(true));
            gitWrapper.Setup(s => s.GetRepoName(It.IsAny <string>()))
            .Returns(Task.FromResult(exampleRepo));
            gitWrapper.Setup(s => s.GetCurrentBranch(It.IsAny <string>()))
            .Returns(Task.FromResult(Branch));

            var client = new MockHttpMessageHandler();

            client.When($"{JenkinsUrl}/{exampleJob}/job/{Branch}/buildWithParameters")
            .Respond(HttpStatusCode.OK);

            var httpClientFactory = new Mock <IHttpClientFactory>();

            httpClientFactory.Setup(s => s.CreateClient(It.IsAny <string>()))
            .Returns(client.ToHttpClient());

            var command = new RunJob(gitWrapper.Object,
                                     GetEncryptorMock().Object,
                                     GetUserConsoleMock().Object,
                                     httpClientFactory.Object,
                                     GetOptionsMock(configuration).Object);

            var app = new CommandLineApplication();

            app.Command(command.Name, command.Command);
            var code = await app.ExecuteAsync(new string[] { Command });

            Assert.That(code, Is.EqualTo(JenoCodes.Ok));
        }
Пример #5
0
        public async Task SaveConfiguration(JenoConfiguration configuration)
        {
            _configuration[_jenoSection] = configuration;

            var serializedConfiguration = JsonConvert.SerializeObject(_configuration, new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver
                {
                    NamingStrategy = new CamelCaseNamingStrategy()
                },
                Formatting = Formatting.Indented
            });

            await File.WriteAllTextAsync(_configurationPath, serializedConfiguration);
        }
Пример #6
0
        public ShowConfiguration(ISerializer yamlSerializer, IOptions <JenoConfiguration> configuration, IUserConsole console)
        {
            _configuration  = configuration.Value;
            _console        = console;
            _yamlSerializer = yamlSerializer;

            Command = (app) =>
            {
                app.Description = Messages.ShowConfigurationCommandDescription;

                app.OnExecuteAsync(token =>
                {
                    _console.WriteLine(_yamlSerializer.Serialize(_configuration));
                    return(Task.FromResult(JenoCodes.Ok));
                });
            };
        }
Пример #7
0
        public void MissingTokenInConfiguration_InformUserAndShowLinkToTokenGenerator()
        {
            var configuration = new JenoConfiguration
            {
                JenkinsUrl = JenkinsUrl,
                UserName   = UserName,
                Token      = string.Empty,
                Password   = Password,
                Repository = new Dictionary <string, string>()
                {
                    { "firstExampleRepoUrl", "firstExampleJob" },
                    { "secondExampleRepoUrl", "secondExampleJob" },
                    { DefaultKey, DefaultJob },
                }
            };

            var client = new MockHttpMessageHandler();

            client.When($"{JenkinsUrl}/job/{DefaultJob}/job/{Branch}/buildWithParameters")
            .Respond(HttpStatusCode.OK);

            var httpClientFactory = new Mock <IHttpClientFactory>();

            httpClientFactory.Setup(s => s.CreateClient(It.IsAny <string>()))
            .Returns(client.ToHttpClient());

            var command = new RunJob(GetDefaultGitMock().Object,
                                     GetEncryptorMock().Object,
                                     GetUserConsoleMock().Object,
                                     httpClientFactory.Object,
                                     GetOptionsMock(configuration).Object);

            var app = new CommandLineApplication();

            app.Command(command.Name, command.Command);

            Assert.That(async() => await app.ExecuteAsync(new string[] { Command }), Throws.TypeOf <JenoException>()
                        .With.Property(nameof(JenoException.ExitCode)).EqualTo(JenoCodes.DefaultError)
                        .And.Property(nameof(JenoException.Message)).Contains("User token is undefined"));
        }
Пример #8
0
        public RunJob(IGitClient gitWrapper, IEncryptor encryptor, IUserConsole userConsole, IHttpClientFactory factory, IOptions <JenoConfiguration> configuration)
        {
            _gitWrapper    = gitWrapper;
            _client        = factory.CreateClient();
            _configuration = configuration.Value;
            _userConsole   = userConsole;
            _encryptor     = encryptor;

            Command = (CommandLineApplication app) =>
            {
                app.Description = Messages.RunJobDescription;

                var jobParameters = app.Argument("jobParameters", Messages.RunJobArgumentsDescription, true);

                app.OnExecuteAsync(async token =>
                {
                    var validationResult = _validator.Validate(_configuration);
                    if (!validationResult.IsValid)
                    {
                        throw new JenoException(string.Join(Environment.NewLine, validationResult.Errors));
                    }

                    var baseUrl = new Uri(_configuration.JenkinsUrl);

                    if (!await _gitWrapper.IsGitRepository(Directory.GetCurrentDirectory()))
                    {
                        throw new JenoException(Messages.NotGitRepoError);
                    }

                    var currentRepo = await _gitWrapper.GetRepoName(Directory.GetCurrentDirectory());
                    var jobNumber   = await _gitWrapper.GetCurrentBranch(Directory.GetCurrentDirectory());

                    var pipeline = _configuration.Repository.ContainsKey(currentRepo) ?
                                   _configuration.Repository[currentRepo] :
                                   _configuration.Repository[DefaulJobKey];

                    var jobUrl = new Uri(baseUrl, $"{pipeline}/job/{jobNumber}/buildWithParameters");

                    if (jobParameters.Values.Count > 0)
                    {
                        ValidateJobParameters(jobParameters.Values);

                        var builder   = new UriBuilder(jobUrl);
                        builder.Query = string.Join("&", jobParameters.Values);
                        jobUrl        = builder.Uri;
                    }

                    _client.DefaultRequestHeaders.Authorization = new BearerAuthenticationHeader(_configuration.Token);

                    var response = await _client.PostAsync(jobUrl, null);

                    if (response.StatusCode == HttpStatusCode.Forbidden)
                    {
                        var password = string.IsNullOrWhiteSpace(_configuration.Password) ?
                                       _userConsole.ReadInput("password", true) :
                                       _encryptor.Decrypt(_configuration.Password);

                        _client.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeader(_configuration.UserName, password);

                        var crumbUrl      = new Uri(baseUrl, "crumbIssuer/api/json");
                        var crumbResponse = await _client.GetAsync(crumbUrl);

                        if (!crumbResponse.IsSuccessStatusCode)
                        {
                            throw new JenoException($"{Messages.CsrfException}: {crumbResponse.ReasonPhrase}");
                        }

                        var crumbHeader = JsonConvert.DeserializeObject <CrumbHeader>(await crumbResponse.Content.ReadAsStringAsync());
                        _client.DefaultRequestHeaders.Add(crumbHeader.CrumbRequestField, crumbHeader.Crumb);
                        response = await _client.PostAsync(jobUrl, null);
                    }

                    if (!response.IsSuccessStatusCode)
                    {
                        throw new JenoException($"{Messages.JobException}: {response.ReasonPhrase}");
                    }

                    return(JenoCodes.Ok);
                });
            };
        }