public List <HosterRepository> GetRepositoryList(ConfigSource source) { var list = new List <HosterRepository>(); string className = this.GetType().Name; request.SetBaseUrl("https://api.bitbucket.org"); if (source.IsAuthenticated) { request.AddBasicAuthHeader(source.AuthName, source.Password); } string url = "/2.0/repositories/" + source.Name; while (url != null) { var result = request.Execute(url).Result; if (result.IsSuccessStatusCode) { var apiResponse = JsonConvert.DeserializeObject <BitbucketApiResponse>(result.Content); // #60: 2 months after Bitbucket's HG deprecation, their API still returns HG repos but cloning/pulling them fails -> ignore them foreach (var apiRepo in apiResponse.values.Where(x => x.scm.ToLower() != "hg")) { ScmType type; switch (apiRepo.scm.ToLower()) { case "git": type = ScmType.Git; break; default: throw new InvalidOperationException(string.Format(Resource.ApiInvalidScmType, apiRepo.full_name)); } var clone = apiRepo.links.clone.Where(r => r.name == "https").First(); string cloneurl = clone.href; var repo = new HosterRepository(apiRepo.full_name, apiRepo.slug, cloneurl, type); repo.SetPrivate(apiRepo.is_private); if (apiRepo.has_wiki) { string wikiUrl = cloneurl + "/wiki"; repo.SetWiki(true, wikiUrl.ToString()); } // TODO: Issues list.Add(repo); } url = apiResponse.next; } else { switch (result.Status) { case HttpStatusCode.Unauthorized: throw new AuthenticationException(string.Format(Resource.ApiAuthenticationFailed, source.AuthName)); case HttpStatusCode.Forbidden: throw new SecurityException(Resource.ApiMissingPermissions); case HttpStatusCode.NotFound: throw new InvalidOperationException(string.Format(Resource.ApiInvalidUsername, source.Name)); } } } return(list); }
public List <HosterRepository> GetRepositoryList(ConfigSource source) { var list = new List <HosterRepository>(); string className = this.GetType().Name; request.SetBaseUrl("https://api.bitbucket.org"); if (source.IsAuthenticated) { request.AddBasicAuthHeader(source.AuthName, source.Password); } string url = string.Empty; string apiUsername = null; // Issue #32: from Apr 29 2019, usernames (not team names) must be replaced by UUIDs if (source.Type.ToLower() == "user") { url = "/2.0/users/" + source.Name; var result = request.Execute(url).Result; if (result.IsSuccessStatusCode) { var apiResponse = JsonConvert.DeserializeObject <BitbucketApiUserResponse>(result.Content); if (apiResponse != null) { apiUsername = Uri.EscapeUriString(apiResponse.uuid); } } if (string.IsNullOrWhiteSpace(apiUsername)) { throw new InvalidOperationException(string.Format(Resource.ApiBitbucketCantGetUuid, source.Name)); } } else { apiUsername = source.Name; } url = "/2.0/repositories/" + apiUsername; while (url != null) { var result = request.Execute(url).Result; if (result.IsSuccessStatusCode) { var apiResponse = JsonConvert.DeserializeObject <BitbucketApiResponse>(result.Content); foreach (var apiRepo in apiResponse.values) { ScmType type; switch (apiRepo.scm.ToLower()) { case "hg": type = ScmType.Mercurial; break; case "git": type = ScmType.Git; break; default: throw new InvalidOperationException(string.Format(Resource.ApiInvalidScmType, apiRepo.full_name)); } var clone = apiRepo.links.clone.Where(r => r.name == "https").First(); string cloneurl = clone.href; var repo = new HosterRepository(apiRepo.full_name, apiRepo.slug, cloneurl, type); repo.SetPrivate(apiRepo.is_private); if (apiRepo.has_wiki) { string wikiUrl = cloneurl + "/wiki"; repo.SetWiki(true, wikiUrl.ToString()); } // TODO: Issues list.Add(repo); } url = apiResponse.next; } else { switch (result.Status) { case HttpStatusCode.Unauthorized: throw new AuthenticationException(string.Format(Resource.ApiAuthenticationFailed, source.AuthName)); case HttpStatusCode.Forbidden: throw new SecurityException(Resource.ApiMissingPermissions); case HttpStatusCode.NotFound: throw new InvalidOperationException(string.Format(Resource.ApiInvalidUsername, source.Name)); } } } return(list); }