예제 #1
0
        public async Task ExecuteAsync(OctoContext context)
        {
            var json    = await new StreamReader(context.Request.Body).ReadToEndAsync();
            var request = JsonConvert.DeserializeObject <JObject>(json);

            var baseUrl  = request.GetValue("BaseUrl").ToString();
            var username = request.GetValue("Username").ToString();
            // If password here is null, it could be that they're clicking the test connectivity button after saving
            // the configuration as we won't have the value of the password on client side, so we need to retrieve it
            // from the database
            var password = string.IsNullOrEmpty(request.GetValue("Password").ToString())
                ? configurationStore.GetJiraPassword()
                : request.GetValue("Password").ToString();

            if (string.IsNullOrEmpty(baseUrl) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                context.Response.AsOctopusJson(ConnectivityCheckResponse.Failure(
                                                   string.IsNullOrEmpty(baseUrl) ? "Please provide a value for Jira Base Url." : null,
                                                   string.IsNullOrEmpty(username) ? "Please provide a value for Jira Username." : null,
                                                   string.IsNullOrEmpty(password) ? "Please provide a value for Jira Password." : null));
                return;
            }

            var jiraRestClient          = new JiraRestClient(baseUrl, username, password, log);
            var connectivityCheckResult = jiraRestClient.GetServerInfo().Result;

            context.Response.AsOctopusJson(connectivityCheckResult);
        }
        public async Task ExecuteAsync(OctoContext context)
        {
            var json    = await new StreamReader(context.Request.Body).ReadToEndAsync();
            var request = JsonConvert.DeserializeObject <JObject>(json);
            var baseUrl = request.GetValue("BaseUrl").ToString();

            var username = installationIdProvider.GetInstallationId().ToString();
            // If password here is null, it could be that they're clicking the test connectivity button after saving
            // the configuration as we won't have the value of the password on client side, so we need to retrieve it
            // from the database
            var password = string.IsNullOrEmpty(request.GetValue("Password").ToString()) ? configurationStore.GetConnectAppPassword() : request.GetValue("Password").ToString();

            if (string.IsNullOrEmpty(baseUrl) || string.IsNullOrEmpty(password))
            {
                context.Response.AsOctopusJson(ConnectivityCheckResponse.Failure(
                                                   string.IsNullOrEmpty(baseUrl) ? "Please provide a value for Jira Base Url." : null,
                                                   string.IsNullOrEmpty(password) ? "Please provide a value for Jira Connect App Password." : null)
                                               );
                return;
            }

            var token = connectAppClient.GetAuthTokenFromConnectApp(username, password);

            if (token is null)
            {
                context.Response.AsOctopusJson(ConnectivityCheckResponse.Failure("Failed to get authentication token from Jira Connect App."));
                return;
            }

            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

                var connectivityCheckPayload =
                    JsonConvert.SerializeObject(new JiraConnectAppConnectivityCheckRequest {
                    BaseHostUrl = baseUrl, OctopusInstallationId = username
                });
                var result = await client.PostAsync(
                    $"{configurationStore.GetConnectAppUrl()}/relay/connectivitycheck",
                    new StringContent(connectivityCheckPayload, Encoding.UTF8, "application/json"));

                if (!result.IsSuccessStatusCode)
                {
                    context.Response.AsOctopusJson(ConnectivityCheckResponse.Failure(result.StatusCode == HttpStatusCode.NotFound
                        ? $"Failed to find an installation for Jira host {configurationStore.GetBaseUrl()}. Please ensure you have installed the Octopus Deploy for Jira plugin from the [Atlassian Marketplace](https://marketplace.atlassian.com/apps/1220376/octopus-deploy-for-jira). [Learn more](https://g.octopushq.com/JiraIssueTracker)."
                        : $"Failed to check connectivity to Jira. Response code: {result.StatusCode}, Message: {result.Content.ReadAsStringAsync().GetAwaiter().GetResult()}")
                                                   );
                    return;
                }

                context.Response.AsOctopusJson(ConnectivityCheckResponse.Success);
            }
        }
예제 #3
0
        public async Task <ConnectivityCheckResponse> GetServerInfo()
        {
            using (var client = CreateHttpClient())
            {
                var response = await client.GetAsync($"{baseUrl}/{baseApiUri}/serverInfo");

                if (response.IsSuccessStatusCode)
                {
                    return(ConnectivityCheckResponse.Success);
                }

                return(ConnectivityCheckResponse.Failure(
                           $"Failed to connect to {baseUrl}. Response code: {response.StatusCode}{(!string.IsNullOrEmpty(response.ReasonPhrase) ? $"Reason: {response.ReasonPhrase}" : "")}"));
            }
        }
예제 #4
0
        public override async Task <IsPublicAccessibleReply> IsPublicAccessible(IsPublicAccessibleRequest request, ServerCallContext context)
        {
            bool isInstalled = _configurationProvider.TryGet(InstallService.INSTALLED_KEY, out string installedValue);

            if (isInstalled)
            {
                AppUser user = await _userManager.GetUserAsync(context.GetHttpContext().User);

                bool isInRole = await _userManager.IsInRoleAsync(user, "admin");

                if (!isInRole)
                {
                    throw new Exception("Unauthorized access");
                }
            }

            HttpClient client    = _httpClientFactory.CreateClient();
            Guid       challenge = Guid.NewGuid();
            ConnectivityCheckRequest connectivityCheckRequest = new ConnectivityCheckRequest
            {
                Hostname  = request.Hostname,
                Challenge = challenge.ToString(),
            };

            StringContent content = new StringContent(JsonSerializer.Serialize <ConnectivityCheckRequest>(connectivityCheckRequest));

            content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            try
            {
                HttpResponseMessage responseMessage = await client.PostAsync("https://connectivity-check-services.gatekeeper.page", content, context.CancellationToken);

                string responseBody = await responseMessage.Content.ReadAsStringAsync();

                ConnectivityCheckResponse response = JsonSerializer.Deserialize <ConnectivityCheckResponse>(responseBody);

                return(new IsPublicAccessibleReply
                {
                    State = (response.Success ? IsPublicAccessibleReply.Types.AccessibleReplyEnum.Success : IsPublicAccessibleReply.Types.AccessibleReplyEnum.Failure),
                });
            }
            catch { }

            return(new IsPublicAccessibleReply
            {
                State = IsPublicAccessibleReply.Types.AccessibleReplyEnum.Unknown
            });
        }
        public async Task <ConnectivityCheckResponse> ConnectivityCheck()
        {
            var connectivityCheckResponse = new ConnectivityCheckResponse();

            // make sure the user can authenticate
            try
            {
                using var response = await httpClient.GetAsync($"{baseUrl}/{baseApiUri}/myself");

                if (response.IsSuccessStatusCode)
                {
                    // make sure the user has browse projects permission
                    using var httpResponseMessage = await httpClient.GetAsync($"{baseUrl}/{baseApiUri}/mypermissions?permissions={BrowseProjectsKey}");

                    if (response.IsSuccessStatusCode)
                    {
                        var jsonContent = await httpResponseMessage.Content.ReadAsStringAsync();

                        var permissionsContainer = JsonConvert.DeserializeObject <PermissionSettingsContainer>(jsonContent);

                        if (permissionsContainer == null)
                        {
                            connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, "Unable to read permissions from response body");
                            return(connectivityCheckResponse);
                        }

                        if (!permissionsContainer.Permissions.ContainsKey(BrowseProjectsKey))
                        {
                            connectivityCheckResponse.AddMessage(
                                ConnectivityCheckMessageCategory.Error,
                                $"Permissions returned from Jira does not contain the {BrowseProjectsKey} permission details.");
                            return(connectivityCheckResponse);
                        }

                        var setting = permissionsContainer.Permissions[BrowseProjectsKey];
                        if (!setting.HavePermission)
                        {
                            connectivityCheckResponse.AddMessage(
                                ConnectivityCheckMessageCategory.Error,
                                $"User does not have the '{setting.Name}' permission in Jira");
                            return(connectivityCheckResponse);
                        }

                        return(connectivityCheckResponse);
                    }
                }

                connectivityCheckResponse.AddMessage(
                    ConnectivityCheckMessageCategory.Error,
                    $"Failed to connect to {baseUrl}. Response code: {response.StatusCode}{(!string.IsNullOrEmpty(response.ReasonPhrase) ? $" Reason: {response.ReasonPhrase}" : "")}");

                return(connectivityCheckResponse);
            }
            catch (HttpRequestException e)
            {
                connectivityCheckResponse.AddMessage(
                    ConnectivityCheckMessageCategory.Error,
                    $"Failed to connect to {baseUrl}. Reason: {e.Message}");
                return(connectivityCheckResponse);
            }
            catch (TaskCanceledException e)
            {
                connectivityCheckResponse.AddMessage(
                    ConnectivityCheckMessageCategory.Error,
                    $"Failed to connect to {baseUrl}. Reason: {e.Message}");
                return(connectivityCheckResponse);
            }
            catch
            {
                connectivityCheckResponse.AddMessage(
                    ConnectivityCheckMessageCategory.Error,
                    $"Failed to connect to {baseUrl}.");
                return(connectivityCheckResponse);
            }
        }
        public Task <IOctoResponseProvider> ExecuteAsync(IOctoRequest request)
        {
            var connectivityCheckResponse = new ConnectivityCheckResponse();

            try
            {
                var requestData = request.GetBody(Data);

                var baseUrl = requestData.BaseUrl;
                // If PersonalAccessToken here is null, it could be that they're clicking the test connectivity button after saving
                // the configuration as we won't have the value of the PersonalAccessToken on client side, so we need to retrieve it
                // from the database
                var personalAccessToken = requestData.PersonalAccessToken.ToSensitiveString();
                if (string.IsNullOrEmpty(personalAccessToken?.Value))
                {
                    personalAccessToken = configurationStore.GetConnections().FirstOrDefault(connection => connection.BaseUrl == baseUrl)?.PersonalAccessToken;
                }

                if (string.IsNullOrEmpty(baseUrl))
                {
                    connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, "Please provide a value for Azure DevOps Base Url.");
                    return(Task.FromResult(Result.Response(connectivityCheckResponse)));
                }

                var urls = AdoProjectUrls.ParseOrganizationAndProjectUrls(baseUrl);
                AdoProjectUrls[] projectUrls;
                if (urls.ProjectUrl != null)
                {
                    projectUrls = new[] { urls };
                }
                else
                {
                    var projectsResult = adoApiClient.GetProjectList(urls, personalAccessToken?.Value);
                    if (projectsResult is FailureResult failure)
                    {
                        connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, failure.ErrorString);
                        return(Task.FromResult(Result.Response(connectivityCheckResponse)));
                    }

                    var projects = (ISuccessResult <string[]>)projectsResult;

                    if (!projects.Value.Any())
                    {
                        connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, "Successfully connected, but unable to find any projects to test permissions.");
                        return(Task.FromResult(Result.Response(connectivityCheckResponse)));
                    }

                    projectUrls = projects.Value.Select(project => new AdoProjectUrls(urls.OrganizationUrl)
                    {
                        ProjectUrl = $"{urls.OrganizationUrl}/{project}"
                    }).ToArray();
                }

                var hasError = false;
                foreach (var projectUrl in projectUrls)
                {
                    var buildScopeTest = adoApiClient.CheckWeCanGetBuilds(projectUrl, personalAccessToken?.Value);
                    if (buildScopeTest is FailureResult buildScopeFailure)
                    {
                        connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, buildScopeFailure.ErrorString);
                        hasError = true;
                    }
                }

                if (!hasError)
                {
                    connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Info, "Successfully connected to Azure DevOps");

                    if (!configurationStore.GetIsEnabled())
                    {
                        connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Warning, "The Jira Issue Tracker is not enabled, so its functionality will not currently be available");
                    }
                }

                return(Task.FromResult(Result.Response(connectivityCheckResponse)));
            }
            catch (Exception ex)
            {
                connectivityCheckResponse.AddMessage(ConnectivityCheckMessageCategory.Error, ex.ToString());
                return(Task.FromResult(Result.Response(connectivityCheckResponse)));
            }
        }