Esempio n. 1
0
        /// <summary>
        /// Create a <see cref="IGitHubClient"/> based on a <see cref="Repository.Id"/> in a <see cref="Installation"/>
        /// </summary>
        /// <param name="installationId">The <see cref="InstallationId.Id"/></param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
        /// <returns>A <see cref="Task{TResult}"/> resulting in a new <see cref="IGitHubClient"/></returns>
        async Task <IGitHubClient> CreateInstallationClient(long installationId, CancellationToken cancellationToken)
        {
            var installation = await databaseContext.Installations.Where(x => x.Id == installationId).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);

            if (installation != null)
            {
                if (installation.AccessTokenExpiry < DateTimeOffset.Now.AddMinutes(-1))
                {
                    var newToken = await gitHubClientFactory.CreateAppClient().GitHubApps.CreateInstallationToken(installation.Id).ConfigureAwait(false);

                    installation.AccessToken       = newToken.Token;
                    installation.AccessTokenExpiry = newToken.ExpiresAt;
                    await databaseContext.Save(cancellationToken).ConfigureAwait(false);

                    return(gitHubClientFactory.CreateOauthClient(newToken.Token));
                }
                return(gitHubClientFactory.CreateOauthClient(installation.AccessToken));
            }

            //do a discovery
            var client          = gitHubClientFactory.CreateAppClient();
            var newInstallation = await client.GitHubApps.GetInstallationForCurrent(installationId).ConfigureAwait(false);

            var installationToken = await client.GitHubApps.CreateInstallationToken(newInstallation.Id).ConfigureAwait(false);

            var entity = new Models.Installation
            {
                Id                = newInstallation.Id,
                AccessToken       = installationToken.Token,
                AccessTokenExpiry = installationToken.ExpiresAt
            };

            databaseContext.Installations.Add(entity);
            await databaseContext.Save(cancellationToken).ConfigureAwait(false);

            //its either in newEntities now or it doesn't exist
            return(gitHubClientFactory.CreateOauthClient(entity.AccessToken));
        }
Esempio n. 2
0
        /// <summary>
        /// Create a <see cref="IGitHubClient"/> based on a <see cref="Repository.Id"/> in a <see cref="Installation"/>
        /// </summary>
        /// <param name="repositoryId">The <see cref="Repository.Id"/> of a <see cref="Repository"/> in the <see cref="Installation"/></param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
        /// <returns>A <see cref="Task{TResult}"/> resulting in a new <see cref="IGitHubClient"/></returns>
        async Task <IGitHubClient> CreateInstallationClient(long repositoryId, CancellationToken cancellationToken)
        {
            IReadOnlyList <Octokit.Installation> gitHubInstalls;
            List <Models.Installation>           allKnownInstalls;
            IGitHubClient client;
            var           installation = await databaseContext.Installations.Where(x => x.Repositories.Any(y => y.Id == repositoryId)).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);

            if (installation != null)
            {
                if (installation.AccessTokenExpiry < DateTimeOffset.Now.AddMinutes(-1))
                {
                    var newToken = await gitHubClientFactory.CreateAppClient().GitHubApps.CreateInstallationToken(installation.Id).ConfigureAwait(false);

                    installation.AccessToken       = newToken.Token;
                    installation.AccessTokenExpiry = newToken.ExpiresAt;
                    await databaseContext.Save(cancellationToken).ConfigureAwait(false);

                    return(gitHubClientFactory.CreateOauthClient(newToken.Token));
                }
                return(gitHubClientFactory.CreateOauthClient(installation.AccessToken));
            }

            //do a discovery
            client = gitHubClientFactory.CreateAppClient();

            //remove bad installs while we're here
            var allKnownInstallsTask = databaseContext.Installations.ToListAsync(cancellationToken);

            gitHubInstalls = await client.GitHubApps.GetAllInstallationsForCurrent().ConfigureAwait(false);

            allKnownInstalls = await allKnownInstallsTask.ConfigureAwait(false);

            databaseContext.Installations.RemoveRange(allKnownInstalls.Where(x => !gitHubInstalls.Any(y => y.Id == x.Id)));

            //add new installs for those that aren't
            var installsToAdd = gitHubInstalls.Where(x => !allKnownInstalls.Any(y => y.Id == x.Id));

            async Task <Models.Installation> CreateAccessToken(Octokit.Installation newInstallation)
            {
                AccessToken installationToken;

                try
                {
                    installationToken = await client.GitHubApps.CreateInstallationToken(newInstallation.Id).ConfigureAwait(false);
                }
                catch
                {
                    //LMAO WTF ARE LOGS
                    return(null);
                }

                var entity = new Models.Installation
                {
                    Id                = newInstallation.Id,
                    AccessToken       = installationToken.Token,
                    AccessTokenExpiry = installationToken.ExpiresAt,
                    Repositories      = new List <InstallationRepository>()
                };

                var repos = await gitHubClientFactory.GetInstallationRepositories(installationToken.Token, cancellationToken).ConfigureAwait(false);

                entity.Repositories.AddRange(repos.Select(x => new InstallationRepository {
                    Id = x.Id
                }));

                return(entity);
            }

            var newEntities = await Task.WhenAll(installsToAdd.Select(x => CreateAccessToken(x))).ConfigureAwait(false);

            await databaseContext.Installations.AddRangeAsync(newEntities.Where(x => x != null)).ConfigureAwait(false);

            await databaseContext.Save(cancellationToken).ConfigureAwait(false);

            //its either in newEntities now or it doesn't exist
            return(gitHubClientFactory.CreateOauthClient(newEntities.First(x => x.Repositories.Any(y => y.Id == repositoryId)).AccessToken));
        }