public static async Task<SharePointClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            ResourceDiscoveryResult dcr = null;
            try
            {
                dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
            }
            catch (AuthenticationFailedException)
            {
                // If the user go back in the login page an Authentication exception is launched.
                return null;
            }

            _lastLoggedInUser = dcr.UserId;

            return new SharePointClient(ServiceEndpointUri, async () =>
            {
                return (await _discoveryContext.AuthenticationContext
                    .AcquireTokenSilentAsync(ServiceResourceId, _discoveryContext.AppIdentity.ClientId, new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(dcr.UserId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId))).AccessToken;
            });
        }
Example #2
0
        public static async Task <SharePointClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            ResourceDiscoveryResult dcr = null;

            try
            {
                dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
            }
            catch (AuthenticationFailedException)
            {
                // If the user go back in the login page an Authentication exception is launched.
                return(null);
            }

            _lastLoggedInUser = dcr.UserId;

            return(new SharePointClient(ServiceEndpointUri, async() =>
            {
                return (await _discoveryContext.AuthenticationContext
                        .AcquireTokenSilentAsync(ServiceResourceId, _discoveryContext.AppIdentity.ClientId, new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(dcr.UserId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId))).AccessToken;
            }));
        }
Example #3
0
        public static async Task <PullRequest> FindGithubPullRequestAsync(DiscoveryContext context, string repoOwner, string repoName, string creator, string title)
        {
            // Optimization: if the creator is the current user, we can rely on the cached list of pull requests
            if (creator.EqualsIgnoreCase(context.GithubClient.Connection.Credentials.Login))
            {
                return(context.PullRequestsCreatedByCurrentUser
                       .Where(p =>
                {
                    var success = Misc.DeriveGitHubRepositoryInfo(new Uri(p.Url), out string owner, out string name);
                    return owner.EqualsIgnoreCase(repoOwner) && name.EqualsIgnoreCase(repoName);
                })
                       .FirstOrDefault(i => i.Title.EqualsIgnoreCase(title)));
            }
            else
            {
                var request = new PullRequestRequest()
                {
                    State         = ItemStateFilter.Open,
                    SortProperty  = PullRequestSort.Created,
                    SortDirection = SortDirection.Descending
                };

                var pullRequests = await context.GithubClient.PullRequest.GetAllForRepository(repoOwner, repoName, request).ConfigureAwait(false);

                var pullRequest = pullRequests.FirstOrDefault(pr => pr.Title.EqualsIgnoreCase(title) && pr.User.Login.EqualsIgnoreCase(creator));

                return(pullRequest);
            }
        }
Example #4
0
        public static async Task <GraphServiceClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverResourceAsync(GraphResourceId);

            _lastLoggedInUser = dcr.UserId;

            var clientCredential = new ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret);
            var authResult       = await _discoveryContext
                                   .AuthenticationContext
                                   .AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), clientCredential, GraphResourceId);

            var graphToken             = authResult.AccessToken;
            var authenticationProvider = new DelegateAuthenticationProvider(
                (requestMessage) =>
            {
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
                return(Task.FromResult(0));
            });

            return(new GraphServiceClient(authenticationProvider));
        }
        private async Task <SharePointClient> EnsureClientCreated()
        {
            DiscoveryContext disco = GetFromCache("DiscoveryContext") as DiscoveryContext;

            if (disco == null)
            {
                disco = await DiscoveryContext.CreateAsync();

                SaveInCache("DiscoveryContext", disco);
            }

            var dcr = await disco.DiscoverCapabilityAsync("MyFiles");

            var ServiceResourceId  = dcr.ServiceResourceId;
            var ServiceEndpointUri = dcr.ServiceEndpointUri;

            SaveInCache("LastLoggedInUser", dcr.UserId);

            return(new SharePointClient(ServiceEndpointUri, async() =>
            {
                return (await disco.AuthenticationContext.AcquireTokenByRefreshTokenAsync(
                            new SessionCache().Read("RefreshToken"),
                            new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(
                                disco.AppIdentity.ClientId,
                                disco.AppIdentity.ClientSecret),
                            ServiceResourceId)).AccessToken;
            }));
        }
        public async Task ExecuteAsync(DiscoveryContext context, TextWriter log)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            using (var excel = new ExcelPackage(new FileInfo(context.ExcelReportPath)))
            {
                var deprecatedAddins = context.Addins.Where(addin => addin.IsDeprecated).ToArray();
                var auditedAddins    = context.Addins.Where(addin => !addin.IsDeprecated && string.IsNullOrEmpty(addin.AnalysisResult.Notes)).ToArray();
                var exceptionAddins  = context.Addins.Where(addin => !addin.IsDeprecated && !string.IsNullOrEmpty(addin.AnalysisResult.Notes)).ToArray();

                var namedStyle = excel.Workbook.Styles.CreateNamedStyle("HyperLink");
                namedStyle.Style.Font.UnderLine = true;
                namedStyle.Style.Font.Color.SetColor(Color.Blue);

                // One worksheet per version of Cake
                foreach (var cakeVersion in Constants.CAKE_VERSIONS.OrderByDescending(cakeVersion => cakeVersion.Version))
                {
                    GenerateExcelWorksheet(auditedAddins, cakeVersion, AddinType.Addin | AddinType.Module, $"Cake {cakeVersion.Version}", excel);
                }

                // One worksheet for recipes
                GenerateExcelWorksheet(auditedAddins, null, AddinType.Recipe, "Recipes", excel);

                // Exceptions report
                GenerateExcelWorksheetWithNotes(exceptionAddins, "Exceptions", excel);

                // Deprecated report
                GenerateExcelWorksheetWithNotes(deprecatedAddins, "Deprecated", excel);

                // Save the Excel file
                excel.Save();
            }

            await Task.Delay(1).ConfigureAwait(false);
        }
        private async Task DeleteMergedBranches(DiscoveryContext context, IEnumerable <Branch> branches, TextWriter log)
        {
            // Delete branches when their corresponding PR has been merged
            foreach (var branch in branches)
            {
                var pullRequestsRequest = new PullRequestRequest()
                {
                    State         = ItemStateFilter.Closed,
                    SortProperty  = PullRequestSort.Updated,
                    SortDirection = SortDirection.Descending,
                    Head          = $"{context.Options.GithubUsername}:{branch.Name}"
                };
                var pullRequests = await context.GithubClient.Repository.PullRequest
                                   .GetAllForRepository(Constants.CAKE_REPO_OWNER, Constants.CAKE_WEBSITE_REPO_NAME, pullRequestsRequest)
                                   .ConfigureAwait(false);

                var pr = pullRequests.SingleOrDefault(pr => pr.Head.Sha == branch.Commit.Sha);

                if (pr != null && pr.Merged)
                {
                    await log.WriteLineAsync($"Deleting branch {context.Options.GithubUsername}/{Constants.CAKE_WEBSITE_REPO_NAME}/{branch.Name}").ConfigureAwait(false);

                    await context.GithubClient.Git.Reference
                    .Delete(context.Options.GithubUsername, Constants.CAKE_WEBSITE_REPO_NAME, $"heads/{branch.Name}")
                    .ConfigureAwait(false);
                }
            }
        }
        private async Task DeleteBranches(DiscoveryContext context, TextWriter log)
        {
            var sensitiveBranches = new[]
            {
                "develop",
                "master",
                "main",
                "publish/develop",
                "publish/master",
                "publish/main"
            };

            var branches = await context.GithubClient.Repository.Branch
                           .GetAll(context.Options.GithubUsername, Constants.CAKE_WEBSITE_REPO_NAME)
                           .ConfigureAwait(false);

            var safeBranches = branches
                               .Where(branch => !sensitiveBranches.Contains(branch.Name))
                               .ToArray();

            var dryRunBranches = safeBranches
                                 .Where(branch => branch.Name.StartsWith("dryrun", StringComparison.OrdinalIgnoreCase))
                                 .ToArray();

            var otherBranches = safeBranches
                                .Except(dryRunBranches)
                                .ToArray();

            await DeleteDryRunBranches(context, dryRunBranches, log).ConfigureAwait(false);
            await DeleteMergedBranches(context, otherBranches, log).ConfigureAwait(false);
        }
Example #9
0
        private async Task <ExchangeClient> EnsureClientCreated()
        {
            DiscoveryContext disco = GetFromCache("DiscoveryContext") as DiscoveryContext;

            if (disco == null)
            {
                disco = await DiscoveryContext.CreateAsync();

                SaveInCache("DiscoveryContext", disco);
            }

            string ServiceResourceId  = "https://outlook.office365.com";
            Uri    ServiceEndpointUri = new Uri("https://outlook.office365.com/ews/odata");

            var dcr = await disco.DiscoverResourceAsync(ServiceResourceId);

            SaveInCache("LastLoggedInUser", dcr.UserId);

            return(new ExchangeClient(ServiceEndpointUri, async() => {
                return (await disco.AuthenticationContext.AcquireTokenByRefreshTokenAsync(
                            new SessionCache().Read("RefreshToken"),
                            new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(
                                disco.AppIdentity.ClientId,
                                disco.AppIdentity.ClientSecret),
                            ServiceResourceId)).AccessToken;
            }));
        }
Example #10
0
        public AddinDiscoverer(Options options)
        {
            // Setup the Github client
            var proxy       = string.IsNullOrEmpty(options.ProxyUrl) ? null : new WebProxy(options.ProxyUrl);
            var credentials = !string.IsNullOrEmpty(options.GithubToken) ? new Credentials(options.GithubToken) : new Credentials(options.GithubUsername, options.GithuPassword);
            var connection  = new Connection(new ProductHeaderValue(Constants.PRODUCT_NAME), new HttpClientAdapter(() => HttpMessageHandlerFactory.CreateDefault(proxy)))
            {
                Credentials = credentials,
            };

            // This environment variable is used by NuGet.Configuration.ProxyCache to configure a proxy
            Environment.SetEnvironmentVariable("http_proxy", options.ProxyUrl);

            // Setup nuget
            var providers = new List <Lazy <INuGetResourceProvider> >();

            providers.AddRange(NuGet.Protocol.Core.Types.Repository.Provider.GetCoreV3());              // Add v3 API support
            var packageSource = new PackageSource("https://api.nuget.org/v3/index.json");

            // Setup the context that will be passed to each step
            _context = new DiscoveryContext()
            {
                Addins           = Array.Empty <AddinMetadata>(),
                GithubClient     = new GitHubClient(connection),
                GithubHttpClient = new HttpClientAdapter(() => HttpMessageHandlerFactory.CreateDefault(proxy)),
                HttpClient       = new HttpClient(new HttpClientHandler()
                {
                    Proxy = proxy, UseProxy = proxy != null
                }),
                NugetRepository = new SourceRepository(packageSource, providers),
                Options         = options,
                TempFolder      = Path.Combine(options.TemporaryFolder, Constants.PRODUCT_NAME),
                Version         = typeof(AddinDiscoverer).GetTypeInfo().Assembly.GetName().Version.ToString(3)
            };
        }
Example #11
0
        public async Task <ActionResult> Index(string authType)
        {
            if (authType == "O365")
            {
                try
                {
                    if (_discoveryContext == null)
                    {
                        _discoveryContext = await DiscoveryContext.CreateAsync();
                    }
                    var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);

                    _lastLoggedInUser = dcr.UserId;
                    string accessToken = (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret), ServiceResourceId)).AccessToken;

                    OAuthController.SaveAccessTokenInCache(ServiceResourceId, accessToken, DateTime.Now.AddMinutes(10).ToString());
                    return(new RedirectResult("/Home/App"));
                }
                catch (RedirectRequiredException ex)
                {
                    return(Redirect(ex.RedirectUri.ToString()));
                }
            }
            else
            {
                string redirectUri      = this.Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/Home/App";
                string authorizationUrl = OAuthController.GetAuthorizationUrl(ServiceResourceId, new Uri(redirectUri));
                return(new RedirectResult(authorizationUrl));
            }
        }
Example #12
0
        private IEnumerable <DiscoveredModel> GetModels(DiscoveryContext context)
        {
            IEnumerable <System.Type> cronusJobs = context.FindService <ICronusJob <object> >();

            foreach (var job in cronusJobs)
            {
                yield return(new DiscoveredModel(job, job, ServiceLifetime.Transient));
            }

            yield return(new DiscoveredModel(typeof(TypeContainer <ICronusJob <object> >), new TypeContainer <ICronusJob <object> >(cronusJobs)));

            yield return(new DiscoveredModel(typeof(InMemoryCronusJobRunner), typeof(InMemoryCronusJobRunner), ServiceLifetime.Transient));

            yield return(new DiscoveredModel(typeof(ICronusJobRunner), typeof(InMemoryCronusJobRunner), ServiceLifetime.Transient));

            yield return(new DiscoveredModel(typeof(IJobNameBuilder), typeof(DefaultJobNameBuilder), ServiceLifetime.Scoped));

            yield return(new DiscoveredModel(typeof(DefaultJobNameBuilder), typeof(DefaultJobNameBuilder), ServiceLifetime.Scoped));

            yield return(new DiscoveredModel(typeof(RebuildIndex_EventToAggregateRootId_JobFactory), typeof(RebuildIndex_EventToAggregateRootId_JobFactory), ServiceLifetime.Transient));

            yield return(new DiscoveredModel(typeof(Projection_JobFactory), typeof(Projection_JobFactory), ServiceLifetime.Transient));

            yield return(new DiscoveredModel(typeof(RebuildIndex_MessageCounter_JobFactory), typeof(RebuildIndex_MessageCounter_JobFactory), ServiceLifetime.Transient));

            yield return(new DiscoveredModel(typeof(ReplayPublicEvents_JobFactory), typeof(ReplayPublicEvents_JobFactory), ServiceLifetime.Transient));
        }
        public static ModelScheme <T> Create <T>(Specification <T> specification, ICapacityInfo capacityInfo)
        {
            ThrowHelper.NullArgument(specification, nameof(specification));

            var scopeBuilderContext = new ScopeBuilderContext();

            var rootSpecificationScopeId = scopeBuilderContext.GetOrRegisterSpecificationScope(specification);

            var discoveryContext = new DiscoveryContext(scopeBuilderContext, rootSpecificationScopeId);

            var rootSpecificationScope = (SpecificationScope <T>)scopeBuilderContext.Scopes[rootSpecificationScopeId];

            rootSpecificationScope.Discover(discoveryContext);

            if (capacityInfo is ICapacityInfoHelpersConsumer capacityInfoHelpersConsumer)
            {
                capacityInfoHelpersConsumer.InjectHelpers(CapacityInfoHelpers);
            }

            if (capacityInfo is IFeedableCapacityInfo feedableCapacityInfo && feedableCapacityInfo.ShouldFeed)
            {
                feedableCapacityInfo.Feed(discoveryContext);
            }

            return(new ModelScheme <T>(
                       scopeBuilderContext.Scopes,
                       rootSpecificationScopeId,
                       scopeBuilderContext.Errors,
                       discoveryContext.Errors.ToDictionary(p => p.Key, p => (IReadOnlyList <int>)p.Value),
                       discoveryContext.Paths.ToDictionary(p => p.Key, p => (IReadOnlyDictionary <string, string>)p.Value),
                       capacityInfo,
                       discoveryContext.ReferenceLoopRoots.Count > 0));
        }
Example #14
0
        /// <summary>
        /// Checks that an Exchange client is available to the client.
        /// </summary>
        /// <returns>The Exchange Online client.</returns>
        public static async Task<ExchangeClient> EnsureCalendarClientCreatedAsync()
        {
            try
            {
                if (_discoveryContext == null)
                {
                    _discoveryContext = await DiscoveryContext.CreateAsync();
                }

                var dcr = await _discoveryContext.DiscoverResourceAsync(ExchangeServiceResourceId);

                _loggedInUser = dcr.UserId;

                return new ExchangeClient(ExchangeServiceEndpointUri, async () =>
                {
                    return (await _discoveryContext.AuthenticationContext.AcquireTokenSilentAsync(ExchangeServiceResourceId, _discoveryContext.AppIdentity.ClientId, new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(dcr.UserId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId))).AccessToken;
                });

            }
            catch (AuthenticationFailedException ex)
            {
                string errorText = String.Format(
                    "{0}, code {1}.  EnsureCalendarClientCreatedAsync - failed",
                    ex.ErrorDescription,
                    ex.ErrorCode);

                LoggingViewModel.Instance.Information = errorText;
            }

            return null;
        }
        public async Task<ActionResult> Index(string authType)
        {
            if (authType == "O365")
            {
                try
                {
                    if (_discoveryContext == null)
                    {
                        _discoveryContext = await DiscoveryContext.CreateAsync();
                    }
                    var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
                    _lastLoggedInUser = dcr.UserId;
                    string accessToken = (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret), ServiceResourceId)).AccessToken;

                    OAuthController.SaveAccessTokenInCache(ServiceResourceId, accessToken, DateTime.Now.AddMinutes(10).ToString());
                    return new RedirectResult("/Home/App");
                }
                catch (RedirectRequiredException ex)
                {
                    return Redirect(ex.RedirectUri.ToString());
                }
            }
            else
            {
                string redirectUri = this.Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/Home/App";
                string authorizationUrl = OAuthController.GetAuthorizationUrl(ServiceResourceId, new Uri(redirectUri));
                return new RedirectResult(authorizationUrl);
            }
        }
Example #16
0
        public static async Task <Issue> FindGithubIssueAsync(DiscoveryContext context, string repoOwner, string repoName, string creator, string title)
        {
            // Optimization: if the creator is the current user, we can rely on the cached list of issues
            if (creator.EqualsIgnoreCase(context.GithubClient.Connection.Credentials.Login))
            {
                return(context.IssuesCreatedByCurrentUser
                       .Where(i =>
                {
                    var success = Misc.DeriveGitHubRepositoryInfo(new Uri(i.Url), out string owner, out string name);
                    return owner.EqualsIgnoreCase(repoOwner) && name.EqualsIgnoreCase(repoName);
                })
                       .FirstOrDefault(i => i.Title.EqualsIgnoreCase(title)));
            }
            else
            {
                var request = new RepositoryIssueRequest()
                {
                    Creator       = creator,
                    State         = ItemStateFilter.Open,
                    SortProperty  = IssueSort.Created,
                    SortDirection = SortDirection.Descending
                };

                var issues = await context.GithubClient.Issue.GetAllForRepository(repoOwner, repoName, request).ConfigureAwait(false);

                var issue = issues.FirstOrDefault(i => i.Title.EqualsIgnoreCase(title));
                return(issue);
            }
        }
Example #17
0
        public async Task ExecuteAsync(DiscoveryContext context, TextWriter log)
        {
            var recommendedCakeVersion = Constants.CAKE_VERSIONS
                                         .OrderByDescending(cakeVersion => cakeVersion.Version)
                                         .First();

            context.Addins = await context.Addins
                             .ForEachAsync(
                async addin =>
            {
                if (addin.Type != AddinType.Recipe &&
                    !addin.IsDeprecated &&
                    !string.IsNullOrEmpty(addin.RepositoryName) &&
                    !string.IsNullOrEmpty(addin.RepositoryOwner))
                {
                    if (addin.AuditIssue != null && addin.AuditIssue.UpdatedAt.HasValue && DateTimeOffset.UtcNow.Subtract(addin.AuditIssue.UpdatedAt.Value).TotalDays > 90)
                    {
                        await AddCommentAsync(context.Options.DryRun, context, addin).ConfigureAwait(false);
                    }
                    else if (addin.AuditIssue == null)
                    {
                        var issue = await CreateIssueAsync(context.Options.DryRun, context, addin, recommendedCakeVersion).ConfigureAwait(false);
                        if (issue != null)
                        {
                            addin.AuditIssue = issue;
                            context.IssuesCreatedByCurrentUser.Add(issue);
                        }
                    }
                }

                return(addin);
            }, Constants.MAX_GITHUB_CONCURENCY)
                             .ConfigureAwait(false);
        }
        public async Task ExecuteAsync(DiscoveryContext context, TextWriter log)
        {
            var recommendedCakeVersion = Constants.CAKE_VERSIONS
                                         .OrderByDescending(cakeVersion => cakeVersion.Version)
                                         .First();

            context.Addins = await context.Addins
                             .OrderBy(a => a.Name)
                             .ForEachAsync(
                async addin =>
            {
                if (addin.Type != AddinType.Recipe &&
                    addin.AuditIssue != null &&
                    addin.AuditPullRequest == null &&
                    !string.IsNullOrEmpty(addin.RepositoryName) &&
                    !string.IsNullOrEmpty(addin.RepositoryOwner))
                {
                    var commits = new List <(string CommitMessage, IEnumerable <string> FilesToDelete, IEnumerable <(EncodingType Encoding, string Path, string Content)> FilesToUpsert)>();

                    await FixNuspec(context, addin, recommendedCakeVersion, commits).ConfigureAwait(false);
                    await FixCsproj(context, addin, recommendedCakeVersion, commits).ConfigureAwait(false);

                    if (commits.Any())
                    {
                        // Make sure we have enough API calls left before proceeding
                        var apiInfo      = context.GithubClient.GetLastApiInfo();
                        var requestsLeft = apiInfo?.RateLimit?.Remaining ?? 0;

                        if (requestsLeft > Constants.MIN_GITHUB_REQUESTS_THRESHOLD)
                        {
                            // Fork the addin repo if it hasn't been forked already and make sure it's up to date
                            var fork = await context.GithubClient.CreateOrRefreshFork(addin.RepositoryOwner, addin.RepositoryName).ConfigureAwait(false);

                            // This delay is important to avoid triggering GitHub's abuse protection
                            await Misc.RandomGithubDelayAsync().ConfigureAwait(false);

                            // Commit changes to a new branch and submit PR
                            var newBranchName = $"addin_discoverer_{DateTime.UtcNow:yyyy_MM_dd_HH_mm_ss}";
                            var pullRequest   = await Misc.CommitToNewBranchAndSubmitPullRequestAsync(context, fork, addin.AuditIssue?.Number, newBranchName, Constants.PULL_REQUEST_TITLE, commits).ConfigureAwait(false);

                            if (pullRequest != null)
                            {
                                addin.AuditPullRequest = pullRequest;
                                context.PullRequestsCreatedByCurrentUser.Add(pullRequest);
                            }

                            // This delay is important to avoid triggering GitHub's abuse protection
                            await Misc.RandomGithubDelayAsync().ConfigureAwait(false);
                        }
                        else
                        {
                            Console.WriteLine($"  Only {requestsLeft} GitHub API requests left. Therefore skipping PR for {addin.Name} despite the fact that we have {commits.Count} commits.");
                        }
                    }
                }

                return(addin);
            }, Constants.MAX_GITHUB_CONCURENCY)
                             .ConfigureAwait(false);
        }
Example #19
0
        private async Task <SharePointClient> EnsureClientCreated()
        {
            DiscoveryContext disco = GetFromCache("DiscoveryContext") as DiscoveryContext;

            if (disco == null)
            {
                disco = await DiscoveryContext.CreateAsync();

                SaveInCache("DiscoveryContext", disco);
            }

            var dcr = await disco.DiscoverCapabilityAsync(MyFilesCapability);

            var ServiceResourceId  = dcr.ServiceResourceId;
            var ServiceEndpointUri = dcr.ServiceEndpointUri;

            SaveInCache("LastLoggedInUser", dcr.UserId);

            return(new SharePointClient(ServiceEndpointUri, async() =>
            {
                Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential creds =
                    new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(
                        disco.AppIdentity.ClientId, disco.AppIdentity.ClientSecret);

                return (await disco.AuthenticationContext.AcquireTokenSilentAsync(
                            ServiceResourceId,
                            creds,
                            new UserIdentifier(dcr.UserId, UserIdentifierType.UniqueId))).AccessToken;
            }));
        }
Example #20
0
 public string GetDescription(DiscoveryContext context)
 {
     if (string.IsNullOrEmpty(context.Options.AddinName))
     {
         return("Download packages from NuGet");
     }
     return($"Download package for {context.Options.AddinName}");
 }
        private async Task <JObject> DownloadResourceFromGitHub(DiscoveryContext context, string resourceName)
        {
            var resourcePath = $"Source/Cake.AddinDiscoverer/{resourceName}";
            var contents     = await context.GithubClient.Repository.Content.GetAllContents(Constants.CAKE_CONTRIB_REPO_OWNER, Constants.ADDIN_DISCOVERER_REPO_NAME, resourcePath).ConfigureAwait(false);

            var jObject = JObject.Parse(contents[0].Content);

            return(jObject);
        }
        public Task ExecuteAsync(DiscoveryContext context, TextWriter log, CancellationToken cancellationToken)
        {
            context.Addins = context.Addins
                             .Where(addin => addin.Name.Equals(context.Options.AddinName, StringComparison.OrdinalIgnoreCase) || !context.ExcludedAddins.Any(excludedAddinName => addin.Name.IsMatch(excludedAddinName)))
                             .OrderBy(addin => addin.Name)
                             .ToArray();

            return(Task.CompletedTask);
        }
        public async Task ExecuteAsync(DiscoveryContext context)
        {
            context.Addins = context.Addins
                             .Where(addin => !context.ExcludedAddins.Any(excludedAddinName => addin.Name.IsMatch(excludedAddinName)))
                             .OrderBy(addin => addin.Name)
                             .ToArray();

            await Task.Delay(1).ConfigureAwait(false);
        }
Example #24
0
        private async Task <IssueComment> AddCommentAsync(bool debugging, DiscoveryContext context, AddinMetadata addin)
        {
            var comment = new StringBuilder();

            comment.AppendLine($"We performed a follow up automated audit of your Cake addin and found that some (or all) issues previously identified have not been resolved.{Environment.NewLine}");
            comment.AppendLine($"We strongly encourage you to make the modifications previously highlighted.{Environment.NewLine}");

            if (addin.AnalysisResult.Icon == IconAnalysisResult.RawgitUrl)
            {
                comment.AppendLine($"In particular would would like to highlight the fact that you use the rawgit CDN to serve your addin's icon. On October 8 2018 the maintainer of rawgit made the [announcement](https://rawgit.com/) that rawgit would shutdown in October 2019. Therefore it's **urgent** that you change your addin's icon URL to the new recommended URL: `{Constants.NEW_CAKE_CONTRIB_ICON_URL}`.{Environment.NewLine}");
            }

            if (addin.AnalysisResult.Icon != IconAnalysisResult.EmbeddedCakeContrib && addin.AnalysisResult.Icon != IconAnalysisResult.EmbeddedFancyCakeContrib)
            {
                comment.AppendLine($"Please also note that the recommendation changed following .netcore3.0's release: you should now embedded the icon in your Nuget package. Read more about embedded icons in the [.nuspec reference](https://docs.microsoft.com/en-us/nuget/reference/nuspec#icon).{Environment.NewLine}");
            }

            comment.AppendLine($"{Environment.NewLine}This comment was created by a tool: Cake.AddinDiscoverer version {context.Version}{Environment.NewLine}");

            IssueComment issueComment = null;

            try
            {
                if (debugging)
                {
                    await File.WriteAllTextAsync(Path.Combine(context.TempFolder, $"Comment_{addin.Name}.txt"), comment.ToString()).ConfigureAwait(false);
                }
                else
                {
                    issueComment = await context.GithubClient.Issue.Comment.Create(addin.RepositoryOwner, addin.RepositoryName, addin.AuditIssue.Number, comment.ToString()).ConfigureAwait(false);
                }
            }
            catch (ApiException e) when(e.ApiError.Message.EqualsIgnoreCase("Issues are disabled for this repo"))
            {
                // There's a NuGet package with a project URL that points to a fork which doesn't allow issue.
                // Therefore it's safe to ignore this error.
            }
            catch (ApiException e) when(e.StatusCode == System.Net.HttpStatusCode.NotFound)
            {
                // I know of at least one case where the URL in the NuGet metadata points to a repo that has been deleted.
                // Therefore it's safe to ignore this error.
            }
#pragma warning disable CS0168 // Variable is declared but never used
            catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
            {
                Debugger.Break();
                throw;
            }
            finally
            {
                // This delay is important to avoid triggering GitHub's abuse protection
                await Misc.RandomGithubDelayAsync().ConfigureAwait(false);
            }

            return(issueComment);
        }
        public AddinDiscoverer(Options options)
        {
            // Setup the Github client
            var proxy       = string.IsNullOrEmpty(options.ProxyUrl) ? null : new WebProxy(options.ProxyUrl);
            var credentials = !string.IsNullOrEmpty(options.GithubToken) ? new Credentials(options.GithubToken) : new Credentials(options.GithubUsername, options.GithuPassword);
            var connection  = new Connection(new ProductHeaderValue(Constants.PRODUCT_NAME), new HttpClientAdapter(() => HttpMessageHandlerFactory.CreateDefault(proxy)))
            {
                Credentials = credentials,
            };

            // Setup nuget
            var providers = new List <Lazy <INuGetResourceProvider> >();

            providers.AddRange(NuGet.Protocol.Core.Types.Repository.Provider.GetCoreV3());              // Add v3 API support
            var packageSource = new PackageSource("https://api.nuget.org/v3/index.json");

            // Setup the context that will be passed to each step
            _context = new DiscoveryContext()
            {
                Addins           = Array.Empty <AddinMetadata>(),
                GithubClient     = new GitHubClient(connection),
                GithubHttpClient = new HttpClientAdapter(() => HttpMessageHandlerFactory.CreateDefault(proxy)),
                HttpClient       = new HttpClient(new HttpClientHandler()
                {
                    Proxy = proxy, UseProxy = proxy != null
                }),
                NugetRepository = new SourceRepository(packageSource, providers),
                Options         = options,
                TempFolder      = Path.Combine(options.TemporaryFolder, Constants.PRODUCT_NAME),
                Version         = typeof(AddinDiscoverer).GetTypeInfo().Assembly.GetName().Version.ToString(3)
            };

            // Using '.CodeBase' because it returns where the assembly is located when not executing (in other words, the 'permanent' path of the assembly).
            // '.Location' would seem more intuitive but in the case of shadow copied assemblies, it would return a path in a temp directory.
            var currentPath       = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
            var currentFolder     = Path.GetDirectoryName(currentPath);
            var exclusionFilePath = Path.Combine(currentFolder, "exclusionlist.json");
            var inclusionFilePath = Path.Combine(currentFolder, "inclusionlist.json");

            using (var sr = new StreamReader(exclusionFilePath))
            {
                var json    = sr.ReadToEnd();
                var jObject = JObject.Parse(json);

                _context.ExcludedAddins = jObject.Property("packages")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
                _context.ExcludedTags   = jObject.Property("labels")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
            }

            using (var sr = new StreamReader(inclusionFilePath))
            {
                var json    = sr.ReadToEnd();
                var jObject = JObject.Parse(json);

                _context.IncludedAddins = jObject.Property("packages")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
            }
        }
Example #26
0
        private async Task <RecipeFile[]> GetRecipeFilesAsync(DiscoveryContext context, CakeVersion currentCakeVersion, CakeVersion nextCakeVersion, CakeVersion latestCakeVersion)
        {
            var directoryContent = await context.GithubClient.Repository.Content.GetAllContents(Constants.CAKE_CONTRIB_REPO_OWNER, Constants.CAKE_RECIPE_REPO_NAME, "Cake.Recipe/Content").ConfigureAwait(false);

            var cakeFiles = directoryContent.Where(c => c.Type == new StringEnum <ContentType>(ContentType.File) && c.Name.EndsWith(".cake", StringComparison.OrdinalIgnoreCase));

            var recipeFiles = await cakeFiles
                              .ForEachAsync(
                async cakeFile =>
            {
                var contents = await context.GithubClient.Repository.Content.GetAllContents(Constants.CAKE_CONTRIB_REPO_OWNER, Constants.CAKE_RECIPE_REPO_NAME, cakeFile.Path).ConfigureAwait(false);

                var recipeFile = new RecipeFile()
                {
                    Name    = cakeFile.Name,
                    Path    = cakeFile.Path,
                    Content = contents[0].Content
                };

                foreach (var addinReference in recipeFile.AddinReferences)
                {
                    addinReference.LatestVersionForCurrentCake = context.Addins.SingleOrDefault(addin =>
                    {
                        return(addin.Name.Equals(addinReference.Name, StringComparison.OrdinalIgnoreCase) &&
                               !addin.IsPrerelease &&
                               (currentCakeVersion == null || (addin.AnalysisResult.CakeCoreVersion.IsUpToDate(currentCakeVersion.Version) && addin.AnalysisResult.CakeCommonVersion.IsUpToDate(currentCakeVersion.Version))) &&
                               (nextCakeVersion == null || !(addin.AnalysisResult.CakeCoreVersion.IsUpToDate(nextCakeVersion.Version) && addin.AnalysisResult.CakeCommonVersion.IsUpToDate(nextCakeVersion.Version))));
                    })?.NuGetPackageVersion;

                    addinReference.LatestVersionForLatestCake = context.Addins.SingleOrDefault(addin =>
                    {
                        return(addin.Name.Equals(addinReference.Name, StringComparison.OrdinalIgnoreCase) &&
                               !addin.IsPrerelease &&
                               (latestCakeVersion != null && (addin.AnalysisResult.CakeCoreVersion.IsUpToDate(latestCakeVersion.Version) && addin.AnalysisResult.CakeCommonVersion.IsUpToDate(latestCakeVersion.Version))));
                    })?.NuGetPackageVersion;
                }

                var nugetPackageMetadataClient = context.NugetRepository.GetResource <PackageMetadataResource>();
                await recipeFile.ToolReferences.ForEachAsync(
                    async toolReference =>
                {
                    var searchMetadata            = await nugetPackageMetadataClient.GetMetadataAsync(toolReference.Name, false, false, new SourceCacheContext(), NullLogger.Instance, CancellationToken.None).ConfigureAwait(false);
                    var mostRecentPackageMetadata = searchMetadata.OrderByDescending(p => p.Published).FirstOrDefault();
                    if (mostRecentPackageMetadata != null)
                    {
                        toolReference.LatestVersion = mostRecentPackageMetadata.Identity.Version.ToNormalizedString();
                    }
                }, Constants.MAX_NUGET_CONCURENCY)
                .ConfigureAwait(false);

                return(recipeFile);
            }, Constants.MAX_GITHUB_CONCURENCY)
                              .ConfigureAwait(false);

            return(recipeFiles);
        }
Example #27
0
        public static async Task<CapabilityDiscoveryResult> DiscoverMail()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverCapabilityAsync("Mail");
            return dcr;
        }
        private IEnumerable <Type> GetAllTypesImplementingOpenGenericType(DiscoveryContext context, Type openGenericType)
        {
            var resolverTypes = context.Assemblies
                                .SelectMany(asm => asm.GetLoadableTypes())
                                .Where(type => type.IsAbstract == false && type.IsInterface == false && type.GetInterfaces()
                                       .Where(candidate => candidate.IsGenericType)
                                       .Any(candidate => openGenericType.IsAssignableFrom(candidate.GetGenericTypeDefinition())));

            return(resolverTypes);
        }
Example #29
0
        public void Should_Initialize_WithDefaultValues()
        {
            var actions = Substitute.For <IDiscoveryContextActions>();

            var context = new DiscoveryContext(actions, 0);

            context.Errors.Should().BeEmpty();
            context.Paths.Should().BeEmpty();
            context.ReferenceLoopRoots.Should().BeEmpty();
        }
        public async Task ExecuteAsync(DiscoveryContext context, TextWriter log, CancellationToken cancellationToken)
        {
            var exclusionListAsJObject = await GetResourceFile(context, "exclusionlist.json").ConfigureAwait(false);

            var inclusionListAsJObject = await GetResourceFile(context, "inclusionlist.json").ConfigureAwait(false);

            context.ExcludedAddins = exclusionListAsJObject.Property("packages")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
            context.ExcludedTags   = exclusionListAsJObject.Property("labels")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
            context.IncludedAddins = inclusionListAsJObject.Property("packages")?.Value.ToObject <string[]>() ?? Array.Empty <string>();
        }
 private Task <JObject> GetResourceFile(DiscoveryContext context, string resourceName)
 {
     if (context.Options.UseLocalResources)
     {
         return(Task.FromResult <JObject>(GetLocalResource(resourceName)));
     }
     else
     {
         return(DownloadResourceFromGitHub(context, resourceName));
     }
 }
 public string GetDescription(DiscoveryContext context)
 {
     if (string.IsNullOrEmpty(context.Options.AddinName))
     {
         return("Search NuGet for all packages matching 'Cake.*'");
     }
     else
     {
         return($"Search NuGet for {context.Options.AddinName}");
     }
 }
        public static Uri SignOut(string postLogoutRedirect)
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = new DiscoveryContext();
            }

            _discoveryContext.ClearCache();

            return _discoveryContext.GetLogoutUri<SessionCache>(postLogoutRedirect);
        }
        public static Uri SignOut(string postLogoutRedirect)
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = new DiscoveryContext();
            }

            _discoveryContext.ClearCache();

            return(_discoveryContext.GetLogoutUri <SessionCache>(postLogoutRedirect));
        }
        public async Task<ActionResult> O365API()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }
            var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
            _lastLoggedInUser = dcr.UserId;
            string accessToken = (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret), ServiceResourceId)).AccessToken;

            OAuthController.SaveAccessTokenInCache(ServiceResourceId, accessToken, DateTime.Now.AddMinutes(10).ToString());
            return new RedirectResult("/Home/App");
        }
        public static Uri SignOut(string postLogoutRedirect)
        {
            DiscoveryContext _discoveryContext = System.Web.HttpContext.Current.Session["DiscoveryContext"] as DiscoveryContext;

            if (_discoveryContext == null)
            {
                _discoveryContext = new DiscoveryContext();
                System.Web.HttpContext.Current.Session["DiscoveryContext"] = _discoveryContext;
            }

            _discoveryContext.ClearCache();

            return _discoveryContext.GetLogoutUri<SessionCache>(postLogoutRedirect);
        }
        public static async Task SignOut()
        {
            if (string.IsNullOrEmpty(_lastLoggedInUser))
            {
                return;
            }

            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            await _discoveryContext.LogoutAsync(_lastLoggedInUser);
        }
        public static async Task<ExchangeClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);

            _lastLoggedInUser = dcr.UserId;

            return new ExchangeClient(ServiceEndpointUri, async () =>
            {
                return (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret), ServiceResourceId)).AccessToken;
            });
        }
        public static async Task<AadGraphClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);

            _lastLoggedInUser = dcr.UserId;

            return new AadGraphClient(new Uri(ServiceEndpointUri, dcr.TenantId), async () =>
            {
                return (await _discoveryContext.AuthenticationContext.AcquireTokenSilentAsync(ServiceResourceId, _discoveryContext.AppIdentity.ClientId, new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(dcr.UserId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId))).AccessToken;
            });
        }
Example #40
0
        public static async Task<SharePointClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverCapabilityAsync(MyFilesCapability);

            var ServiceResourceId = dcr.ServiceResourceId;
            var ServiceEndpointUri = dcr.ServiceEndpointUri;

            _lastLoggedInUser = dcr.UserId;

            // Create the MyFiles client proxy:
            return new SharePointClient(ServiceEndpointUri, async () =>
            {
                return (await _discoveryContext.AuthenticationContext.AcquireTokenSilentAsync(ServiceResourceId, _discoveryContext.AppIdentity.ClientId, new Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier(dcr.UserId, Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifierType.UniqueId))).AccessToken;
            });
        }
        public static async Task<GraphServiceClient> EnsureClientCreated()
        {
            if (_discoveryContext == null)
            {
                _discoveryContext = await DiscoveryContext.CreateAsync();
            }

            var dcr = await _discoveryContext.DiscoverResourceAsync(GraphResourceId);

            _lastLoggedInUser = dcr.UserId;

            var clientCredential = new ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret);
            var authResult = await _discoveryContext
                                    .AuthenticationContext
                                    .AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"), clientCredential, GraphResourceId);
            var graphToken = authResult.AccessToken;
            var authenticationProvider = new DelegateAuthenticationProvider(
                (requestMessage) =>
                {
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
                    return Task.FromResult(0);
                });
            return new GraphServiceClient(authenticationProvider);
        }