Example #1
0
    async Task <IActionResult> IAdapterAuthorize.HandleCallbackAsync(DeploymentScope deploymentScope, HttpRequest request, IAuthorizationEndpoints authorizationEndpoints)
    {
        if (deploymentScope is null)
        {
            throw new ArgumentNullException(nameof(deploymentScope));
        }

        if (request is null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        if (authorizationEndpoints is null)
        {
            throw new ArgumentNullException(nameof(authorizationEndpoints));
        }

        var json = await request
                   .ReadJsonAsync()
                   .ConfigureAwait(false);

        var appId = json
                    .SelectToken("installation.app_id")?
                    .ToString();

        var token = await TokenClient
                    .GetAsync <GitHubToken>(deploymentScope)
                    .ConfigureAwait(false);

        if (token?.ApplicationId?.Equals(appId, StringComparison.OrdinalIgnoreCase) ?? false)
        {
            var action = json
                         .SelectToken("action")?
                         .ToString();

            switch (action)
            {
            case "created":

                token.InstallationId = json
                                       .SelectToken("installation.id")?
                                       .ToString();

                break;

            case "deleted":

                token = new GitHubToken(deploymentScope);
                break;

            case "suspend":

                token.Suspended = true;
                break;

            case "unsuspend":

                token.Suspended = false;
                break;

            default:

                token = null;
                break;
            }

            if (token is not null)
            {
                _ = await TokenClient
                    .SetAsync(token)
                    .ConfigureAwait(false);

                return(new OkResult());
            }
        }

        return(new NotFoundResult());
    }
Example #2
0
    async Task <IActionResult> IAdapterAuthorize.HandleAuthorizeAsync(DeploymentScope deploymentScope, HttpRequest request, IAuthorizationEndpoints authorizationEndpoints)
    {
        if (deploymentScope is null)
        {
            throw new ArgumentNullException(nameof(deploymentScope));
        }

        if (request is null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        if (authorizationEndpoints is null)
        {
            throw new ArgumentNullException(nameof(authorizationEndpoints));
        }

        var queryParams = Url.ParseQueryParams(request.QueryString.ToString());
        var queryState  = queryParams.GetValueOrDefault("state");
        var queryCode   = queryParams.GetValueOrDefault("code");
        var queryError  = queryParams.GetValueOrDefault("error");

        var session = await SessionClient
                      .GetAsync <GitHubSession>(deploymentScope)
                      .ConfigureAwait(false);

        session ??= await SessionClient
        .SetAsync(new GitHubSession(deploymentScope))
        .ConfigureAwait(false);

        var data = string.IsNullOrWhiteSpace(deploymentScope.InputData)
            ? default
            : TeamCloudSerialize.DeserializeObject <GitHubData>(deploymentScope.InputData);

        var token = await TokenClient
                    .GetAsync <GitHubToken>(deploymentScope)
                    .ConfigureAwait(false);

        if (string.IsNullOrEmpty(queryError) && Guid.TryParse(queryState, out var stateId))
        {
            if (!stateId.ToString().Equals(session.SessionId, StringComparison.OrdinalIgnoreCase))
            {
                return(new RedirectResult(authorizationEndpoints.AuthorizationUrl.SetQueryParam("error", "Session timed out.").ToString()));
            }
            else if (string.IsNullOrWhiteSpace(queryCode))
            {
                return(new RedirectResult(authorizationEndpoints.AuthorizationUrl.SetQueryParam("error", "Missing GitHub handshake information.").ToString()));
            }

            token ??= new GitHubToken(deploymentScope);

            // Using Flurl as Octokit doesn't support this API yet
            // https://github.com/octokit/octokit.net/issues/2138

            var url = $"https://api.github.com/app-manifests/{queryCode}/conversions";

            var response = await url
                           .WithHeader("User-Agent", GitHubConstants.ProductHeader.ToString())
                           .PostStringAsync(string.Empty)
                           .ConfigureAwait(false);

            if (!response.IsSuccessStatusCode())
            {
                return(new RedirectResult(authorizationEndpoints.AuthorizationUrl.SetQueryParam("error", $"Failed to get application token ({response.StatusCode} - {response.ResponseMessage.ReasonPhrase}).").ToString()));
            }

            var json = await response
                       .GetStringAsync()
                       .ConfigureAwait(false);

            TeamCloudSerialize.PopulateObject(json, token);

            if (string.IsNullOrEmpty(token.OwnerLogin))
            {
                token.OwnerLogin = JToken.Parse(json)
                                   .SelectToken("owner.login")
                                   .ToString();
            }

            token = await TokenClient
                    .SetAsync(token, true)
                    .ConfigureAwait(false);

            return(new ContentResult
            {
                StatusCode = (int)HttpStatusCode.OK,
                ContentType = "text/html",
                Content = Assembly.GetExecutingAssembly().GetManifestResourceTemplate($"{GetType().FullName}_Install.html", GetFormContext())
            });
        }
        else
        {
            return(new ContentResult
            {
                StatusCode = (int)HttpStatusCode.OK,
                ContentType = "text/html",
                Content = Assembly.GetExecutingAssembly().GetManifestResourceTemplate($"{GetType().FullName}_Register.html", GetFormContext())
            });
        }

        object GetFormContext() => new
        {
            deploymentScope        = deploymentScope,
            authorizationEndpoints = authorizationEndpoints,
            token     = token,
            data      = data,
            session   = session,
            error     = queryError ?? string.Empty,
            succeeded = queryParams.Contains("succeeded")
        };
    }