Giter Club home page Giter Club logo

sharpbucket's Introduction

SharpBucket

Build status NuGet Version and Downloads count

SharpBucket is a .Net wrapper for the Bitbucket Cloud's REST APIs. It is written in in C#. With it you can have all the data of your repositories / issues at your fingertips.

How to get started

Installation

To install SharpBucket, run the following command in the Package Manager Console:

PM> Install-Package SharpBucket

Usage

See the SharpBucketCli Project or the unit tests to see how to use the wrapper.

Here's just a brief demo:

First let's set your entry point to the API:

// your main entry to the Bitbucket API, this one is for V2
var sharpBucket = new SharpBucketV2();
// authenticate with OAuth2 keys
sharpBucket.OAuth2ClientCredentials(consumerKey, consumerSecretKey);

There are various end points you can use. Let's look at the users end point:

// getting the users end point (accountName can be the name of a user or a team)
var userEndPoint = sharpBucket.UsersEndPoint("accountName");
// querying the Bitbucket API for various info
var userProfile = userEndPoint.GetProfile();
var user = userEndPoint.GetUser();
var followers = user.ListFollowers();
var follows = user.ListFollowing();
var userRepos = user.ListRepositories();

Sub end points are named Resource but are very similar to root end points. Let's look at the repository resource:

// getting the repositories end point
var repositoriesEndPoint = sharpBucket.RepositoriesEndPoint();
// getting the Repository resource for a specific repository
var repositoryResource = repositoriesEndPoint.RepositoryResource("accountName", "repoSlugOrName");
// getting the list of all the commits of the repository
var commits = repositoryResource.ListCommits();

Sending information is just as easy:

var newRepository = new Repository
                    {
                        name = "Sample",
                        language = "c#",
                        scm = "git"
                    };
var newRepositoryResult = repositoryResource.PostRepository(newRepository);

Pagination is handled internally, and we always return an aggregation of all pages by default. However you can provide few parameters to manage that behavior

// you can give us a maximum number of results to fetch on all list method
var followers = user.ListRepositories(50);

// And on some advanced list methods you can provide a ListParameters object
// that allow to inject filter and sort parameters
// see Atlassian documentation for the filter and sort syntax:
// https://developer.atlassian.com/bitbucket/api/2/reference/meta/filtering
var listParameters = new ListParameters { Filter = "name ~ \"erik/\"", Sort = "-name", Max = 50 };
var erikBranchesDesc = repositoryResource.BranchesResource.ListBranches(listParameters);

// we also provide few helpers to build your filters in FilterBuilder class:
FilterBuilder.ParseSingleQuotedString("name ~ 'erik/'"); // return "name ~ \"erik/\""
FilterBuilder.FormatDateTime(DateTime.UtcNow); // return something like "2000-12-31T23:59:59.999z"

SharpBucket uses a strict naming convention:

  • methods starting with List will return a collection of items (ListIssues() returns a list of issues)
  • methods starting with Enumerate will return a lazy enumeration of items (EnumerateSearchCodeSearchResults() returns a lazy page by page enumeration of SearchCodeSearchResults)
  • methods starting with Get will return an item (GetIssue(10) will return an issue with the id 10)
  • methods starting with Post are used for adding the item
  • methods starting with Put are used for updating the item
  • methods starting with Delete will delete the item

Authentication

There are three ways you can authenticate with SharpBucket:

  • via Oauth 2, which is preferred
  • via Oauth 1.0a
  • via Bitbucket username and password

Here is how you can use them:

Basic authentication

// authenticate with Bitbucket username and password
sharpBucket.BasicAuthentication(email, password);

OAuth 1.0 authentication

With OAuth you can choose between 2 legged and 3 legged authentication.

Two legged is as simple as basic authentication:

// authenticate with OAuth keys
sharpBucket.OAuth1TwoLeggedAuthentication(consumerKey, consumerSecretKey);

The three legged requires an additional step to retrieve the pin / verifier from Bitbucket. If you do not supply a callback url (or use โ€œoobโ€) you will be provided with a Bitbucket url that you can use to prompt your user to allow access to your application and retrieve a pin / verifier.

Here is a simple example of how you could use the pin / verifier retrieved from the browser:

var authenticator = sharpBucket.OAuth1ThreeLeggedAuthentication(consumerKey, consumerSecretKey, "oob");
var uri = authenticator.StartAuthentication();
Process.Start(uri);
var pin = Console.ReadLine();
// we can now do the final step by using the pin to get our access tokens
authenticator.AuthenticateWithPin(pin);

If you have a server able to receive Bitbucket's response, you would simply use your server's url as the callback and then wait for Bitbucket to send you the pin to that address.

If you already have tokens (those returned by AuthenticateWithPin method) you can simply skip the authentication process:

var authenticator = sharpBucket.OAuth1ThreeLeggedAuthentication(consumerKey, consumerSecretKey, oauthToken, oauthTokenSecret);

OAuth2 authentication

OAuth 2.0 offers a large choice of scenarios (bitbucket OAuth 2.0) but they are not yet all implemented.

Client credentials Grant is similar to OAuth1 two legged authentication:

// authenticate with OAuth keys
sharpBucket.OAuth2ClientCredentials(consumerKey, consumerSecretKey);

How much of the API is covered?

SharpBucket does not yet supply complete coverage of the API. However, the main functionality is covered and the remainder of the API should become covered sooner or later.

Contributing

Contributions are always welcome! Here is some short information about how and where to get started.

Continuous Integration from AppVeyor

The project is using AppVeyor's Continuous Integration Service which is free for open source projects. It is enabled for Pull Requests as well as the main branch.

Licensing, Dependencies and Influence

SharpBucket is licensed under MIT license.

Dependencies

Influence

SharpBucket was influenced by ServiceStack's Stripe api wrapper. The first versions of SharpBucket used ServiceStack's library, but has since moved to RestSharp.

sharpbucket's People

Contributors

adamkarl-zywave avatar asherber avatar bedirhan avatar bjorn1976 avatar casualrobin avatar dependabot[bot] avatar g-oliveira avatar getoxs avatar marcoregueira avatar mattbodey avatar matthewsmith91 avatar maxwellobi avatar mikefoden avatar mitjabezensek avatar mnivet avatar penev92 avatar shannonphillipl avatar soichisaito avatar techy2493 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sharpbucket's Issues

IteratePages assumes that next page is sequential

EndPoint.IteratePages() assumes that the page value in a next link will always be an integer that increments by 1. However, https://developer.atlassian.com/bitbucket/api/2/reference/meta/pagination points out that for some collections, the page value can be an "unpredictable hash" instead of a sequential number.

I ran into this while retrieving a list of tags.

var tags = tagResource.ListTags("myAccount", "myRepo");

// LIBRARY: GET /2.0/repositories/myAccount/myRepo/refs/tags/?pagelen=50
// BITBUCKET: next=https://api.bitbucket.org/2.0/repositories/myAccount/myRepo/refs/tags/?pagelen=50&page=xGCox
// LIBRARY: GET /2.0/repositories/twengg/abs-core/refs/tags/?pagelen=50&page=2
// BITBUCKET: 404 Not Found

I can put together a PR to pull the page value directly out of the next link, instead of just incrementing.

TLS problem in SharpBucketTests

I ran into an issue running tests in the SharpBucketTests project. The project targets .NET 4.0, which by default does not enable TLS 1.2. Since Bitbucket has turned off support for TLS 1.0 and 1.1, the tests all fail with an error from RestSharp that a TLS connection could not be established.

The easiest fix would be to change the tests project to target .NET 4.6.2, which does have TLS 1.2 enabled. (SharpBucket itself could continue to target 4.0.)

Another option would be to add a OneTimeSetup method to SampleRepositories to explicitly enable current TLS versions, like so:

[OneTimeSetUp]
public void OneTimeSetup()
{
    System.Net.ServicePointManager.SecurityProtocol =
        (SecurityProtocolType)3072     // TLS 1.2
        | (SecurityProtocolType)768    // TLS 1.1
        | SecurityProtocolType.Tls; 
}

Would like to help but...

I have forked the repository. What I am hoping to do is use SharpBucket on an ASP.NET site to pull contributed items for a hosted service. I would have the pull triggered once per night as an automated task to look for the latest commit, compare to my site's latest copy, and pull any updated/new files.
To do this I need to implement the [src] https://confluence.atlassian.com/display/BITBUCKET/src+Resources portion of the API v1. I tried this but it will not let me return a simple string for the base-64 encoded text due to type restrictions on the generic methods. Is there another API already implemented that does something similar? I am thinking that right now I would need to add new methods for Get, Send, etc. that would handle a string return value instead of a typed value.
Thanks,
Bryan

Allow customizing Base URL

Currently the wrapper can't be used for on-prem hosted Bitbucket solutions. Customizing the base URL would fix that.

Retrieve commit details

I want to retrieve commit details, how does this work?
What should I do with the object I get?
It's also not utilized in your test project.

var sharpBucket = new SharpBucketV2();

sharpBucket.OAuth2LeggedAuthentication("", "");

var repositoryEndpoint = sharpBucket.RepositoriesEndPoint();
var repositoryResource = repositoryEndpoint.RepositoryResource("", "");
var commits = repositoryResource.ListCommits();

I also want to point out that I was confused in the first place because I used the NuGet package and tried to match the API with the code on GitHub, which wasn't possible because the versions differ.
I'd like to suggest to freeze the "productive" NuGet version in another branch at least.

What do you think?

Kind regards,

Timm

Naming of OAuth1 vs OAuth2 classes and methods

We have multiple classes and methods which name is not obvious to distinct OAuth1 vs OAuth2

In particular the following classes:

  • OAuthentication2Legged and OAuthentication3Legged which are OAuth1
  • OAuthentication2 which is OAuth2

And the corresponding methods in SharpBucket class:

  • OAuth2LeggedAuthentication and OAuth3LeggedAuthentication which are OAuth1
  • OAuthentication2 which is OAuth2

The issue comes from the fact that "OAuth 2 legged" is clearly not "Oauth2 legged", but when all is join in a method name its become hard to distinct both.
Can we try to deprecate that methods and classes for methods with more explicit naming ?

My suggestion would be to harmonize the classes and methods names to be the same, and named like that:
OAuth2LeggedAuthentication => OAuthWith2LeggedAuthentication
OAuth3LeggedAuthentication => OAuthWith3LeggedAuthentication
OAuthentication2 => OAuth2WithClientCredentialsGrant (because it's named like that here : https://developer.atlassian.com/bitbucket/api/2/reference/meta/authentication, and it will let us the door open to implements others OAuth2 scenarios like the "Resource Owner Password Credentials Grant" which is probably an improvement of the BasicAuthentication that we already have)

Make paginated data iterable via generators

I realized belatedly that I probably should have used yield and returned IEnumerable<T> instead of List<T> in PR #10 . By using generators, we only make as many HTTP calls as are required for the user's purpose regardless of whether or not they know max ahead of time.

I'd like to either refactor the ListX functions to return IEnumerable<X> or at least add IterateX functions. I could do this very quickly. The result would be something like this:

        public List<Repository> ListRepositories(string accountName, int max = 0){
            var overrideUrl = _baseUrl + accountName + "/";
            return GetPaginatedValues<Repository>(overrideUrl, max);
        }

        public IEnumerable<Repository> IterateRepositories (string accountName) {
            var overrideUrl = _baseUrl + accountName + "/";
            foreach (var val in IteratePaginatedValues<Repository>(overrideUrl )) {
                yield return val;
            }
        }

I don't know that we need both versions, tho. Thoughts. @MitjaBezensek?

Able to clone code based on tag?

Not really an issue more of a question. I don't see any mention in the docs or the test apps about cloning the code in a repo, specifically cloning from a certain tag. Is this possible using this library?

SharpBucket.Send syntax causes a WebException when calling GetDiffForPullRequest

Using GetDiffForPullRequest() throws two exceptions:

{Data at the root level is invalid. Line 1, position 1."} System.Exception {System.Xml.XmlException}
and
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at SharpBucket.Authentication.Authenticate.GetResponse[T](String url, Method method, T body, IDictionary2 requestParameters) at SharpBucket.SharpBucket.Send[T](T body, Method method, String overrideUrl, IDictionary2 requestParameters) at SharpBucket.V2.EndPoints.RepositoriesEndPoint.GetDiffForPullRequest(String accountName, String repository, Int32 pullRequestId) at SharpBucket.V2.EndPoints.PullRequestResource.GetDiffForPullRequest()

Not sure what's up, but I tried using curl with https://api.bitbucket.org/2.0/repositories/{username}/{repo_slug}/refs/branches/ and I can see that the branches have diffs (some empty, some not). There's some sort of edge case with the data being parsed, although I'm not quite sure what it is specifically.

Unable to set issue.responsible when creating a new Issue?

Surely I'm missing smt... Using V1.

Issue newIssue = new Issue();
...
newIssue.responsible = new User();
newIssue.responsible.username = bitbucketAssigneeTextBox.Text.Trim();

RepositoriesEndPoint repositoryEndPoint = ConnectToBitbucket();
IssuesResource issuesResource = repositoryEndPoint.IssuesResource();
Issue newlyOpenedIssue = issuesResource.PostIssue(newIssue);
...

the code above produces the below POST body which of course Bitbucket doesn't support

...&priority=major&reported_by=SharpBucket.V1.Pocos.User..

There used to be NewIssue, ExistingIssue POCOs. Or should I implement them myself extending Issue.

PostRepository uses Repository.Name property without first converting to lowercase

namespace SharpBucket.V2.EndPoints

public class RepositoriesEndPoint : EndPoint
{
    ...
    internal Repository PostRepository(Repository repo, string accountName)
    {
        var overrideUrl = GetRepositoryUrl(accountName, repo.name, null);
        return _sharpBucketV2.Post(repo, overrideUrl);
    } 
    ...
}

The repo_slug needs to be lowercase, but the Repository.Name can contain uppercase characters

{
    "type": "error",
    "error": {
        "message": "Invalid slug. Slugs must be lowercase, alphanumerical, and may also contain underscores, dashes, or dots."
    }
}

Repo name/slug/etc. in repository functions

The various API calls under /repositories/{username}/{repo_slug} can take either the repo slug or the UUID as the final part of the path.

The corresponding methods in this library take a string parameter called repository, which can be either the slug (abc-repo) or the name (ABC Repo). Before building the URL to call, this parameter is run through a method to slugify it -- to make sure that it looks like a slug by replacing spaces and any other illegal chars with hyphens.

This leads to several thoughts:

  • The parameter is named poorly. It is not clear to a user what a string parameter called repository can hold.

  • Users cannot use the UUID to access a repository. BB requires the UUID to be enclosed in { }, and ParseSlug() will turn these characters into hyphens when the URL is constructed

  • It is not clear why the library allows the user to pass in a repo name, which is silently turned into a slug, when the API doesn't allow a repo name to be used.

I suggest that the parameter should be renamed to slugOrUuid, to make it clear what values the user can pass. The library can also provided a Slugify() helper function in case the user wants to turn a repo name into a slug, but it shouldn't perform this transformation on its own.

I'm on the fence as to whether the library should attempt to provide any formatting help if the user passes in a UUID. It would be simple to do:

if (Guid.TryParse(slugOrUuid, out var guid))
   slugOrUuid = guid.ToString("B");

This would help make sure that the UUID is in the format expected by BB. On the other hand, I can see the argument that this should be the responsibility of the user.

I'm interested in discussion on this topic, and I'm happy to work on a PR if it's decided that some of these changes should be adopted.

Creating a repository using v2 API

I'm struggling to create an issue using the v2 api, is this something that hasn't been implemented yet?

I've created a new repository using the POCO but can't see how it should be posted to the repositories endpoint.

Thanks!

Debug.Assert(!overrideUrl.Contains("?"))

I want to add in filtering, but according to this Debug.Assert(!overrideUrl.Contains("?")); line of code, you don't seem to want filtering? Why?

using SharpBucket.V2.Pocos;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;

namespace SharpBucket.V2.EndPoints
{
    public class EndPoint
    {
        // vanilla page length in many cases is 10, requiring lots of requests for larger collections
        private const int DEFAULT_PAGE_LEN = 50;

        protected readonly ISharpBucketV2 _sharpBucketV2;
        protected readonly string _baseUrl;

        public EndPoint(ISharpBucketV2 sharpBucketV2, string resourcePath)
        {
            _sharpBucketV2 = sharpBucketV2;
            _baseUrl = resourcePath;
        }

        /// <summary>
        /// Generator that allows lazy access to paginated resources.
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="overrideUrl"></param>
        /// <param name="pageLen"></param>
        /// <param name="requestParameters"></param>
        /// <returns></returns>
        private IEnumerable<List<TValue>> IteratePages<TValue>(string overrideUrl, int pageLen = DEFAULT_PAGE_LEN, IDictionary<string, object> requestParameters = null)
        {
            Debug.Assert(!String.IsNullOrEmpty(overrideUrl));
            Debug.Assert(!overrideUrl.Contains("?"));

            if (requestParameters == null)
            {
                requestParameters = new Dictionary<string, object>();
            }

            requestParameters["pagelen"] = pageLen;

            IteratorBasedPage<TValue> response;
            int page = 1;
            do
            {
                response = _sharpBucketV2.Get(new IteratorBasedPage<TValue>(), overrideUrl.Replace(SharpBucketV2.BITBUCKET_URL, ""), requestParameters);
                if (response == null)
                {
                    break;
                }

                yield return response.values;

                requestParameters["page"] = ++page;
            }
            while (!String.IsNullOrEmpty(response.next));
        }

        /// <summary>
        /// Returns a list of paginated values.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="overrideUrl">The override URL.</param>
        /// <param name="max">Set to 0 for unlimited size.</param>
        /// <param name="requestParameters"></param>
        /// <returns></returns>
        /// <exception cref="System.Net.WebException">Thrown when the server fails to respond.</exception>
        protected List<TValue> GetPaginatedValues<TValue>(string overrideUrl, int max = 0, IDictionary<string, object> requestParameters = null)
        {
            bool isMaxConstrained = max > 0;

            int pageLen = (isMaxConstrained && max < DEFAULT_PAGE_LEN) ? max : DEFAULT_PAGE_LEN;

            List<TValue> values = new List<TValue>();

            foreach (var page in IteratePages<TValue>(overrideUrl, pageLen, requestParameters))
            {
                if (page == null)
                {
                    break;
                }

                if (isMaxConstrained &&
                    values.Count + page.Count >= max)
                {
                    values.AddRange(page.GetRange(0, max - values.Count));
                    Debug.Assert(values.Count == max);
                    break;
                }

                values.AddRange(page);
            }

            return values;
        }
    }
}

Commit summary

I'd like to add the summary for each commit. The JSON looks like this:

"summary": {
    "raw": "[ABC-3392] a meaningful description\n",
    "markup": "markdown",
    "html": "<p>[<a rel=\"nofollow\" href=\"https://foo.atlassian.net/browse/ABC-3392\" target=\"_blank\" data-module-key=\"dvcs-connector-issue-key-linker\" data-link-key=\"dvcs-connector-issue-key-linker\" data-app-key=\"jira-bitbucket-connector-plugin.0277a6a4-4e3d-34e1-bab2-1c14de870122\" data-principal-uuid=\"{1b6feefd-32c1-4cb6-9e19-d662df20c277}\" class=\"ap-connect-dialog\">ABC-3392</a>] a meaningful description</p>",
    "type": "rendered"
},

In a local git repo, it's only the raw version that's useful; here the other fields show how BitBucket formats the summary for display -- in this case, it includes a link to the relevant issue in JIRA.

I'm happy to put together a PR, but should this property on Commit be a new Summary object, or should it just be a string with the raw value?

Improve the redirect logic

Currently we manually create a new request if some resource was redirected. This is due to the fact that RestSharp clears the headers on redirect. There's a way around this, which is described here.

Update documentation

  • OAuth2 was added
  • For testing purposes environment variables need to be set (add contributing info that explains this)
  • Setting the number of results (pagination) was added

Failing to set Auth Tokens > AuthenticatewithPin

Failing to authenticate and getting a System.Net.WebException

I have checked, the response is Unauthorized from the API.
The RestClient includes the authenticator with
ConsumerKey
ConsumerSecret
Token
TokenSecret
Verifier

This should be all that is needed to authenticate and receive the token I believe.


 public BitBucketController()
        {
            sharpbucket = new SharpBucket.V1.SharpBucketV1();
            authenticator = sharpbucket.OAuth3LeggedAuthentication(BitbucketApiKey, BitbucketApiSecret, "oob");
        }

        public void GetPin()
        {
            var uri = authenticator.StartAuthentication();
            Process.Start(uri);
        }

        public void Authenticate(string pin)
        {
            authenticator.AuthenticateWithPin(pin);
        }

Interpreting the v2 tests

I've added some support for paging in v2, but I'm unclear how to be certain I haven't broken anything. My own use is very narrow (polling repos), so there are a lot of code paths I'm not hitting during dev. Any tips on running the tests?

Improve the testing

The basic testing logic has been added but now we need to write additional tests. For now at least the tests that target the publicly accessible repos. Here is an example of how they might look like.

Apart from writing additional tests also consider running the tests on the AppVeyor CI. Would need to find a way to set up the authentication info on the AppVeyor project.

  • Write additional tests for the api calls that work on public repos.
  • Configure AppVeyor to run the tests, figure out how to deal with authentication - maybe environment variables.
  • Figure out the best way to run api calls for private repos (probably each developer should create a private repo just for testing and the testing logic should then keep this repo in a consistent state).
  • Clean up the Console test project when tests will be implemented. It should contain only a very brief, concise, clear guide about how you should use SharpBucket.
  • Some tests are brittle since they rely on third party accounts. Maybe create a repository on SharpBucket, so that it is under our control and wont change.

SharpBucketV1 End of life

As you know, the Version1 of Bitbucket Cloud API is deprecated and will be closed on 12 April 2019
https://confluence.atlassian.com/bitbucket/version-1-423626337.html

How should we managed that here ?
When should we start to drop the SharpBucketV1 class and all the code that is behind ?

  • As soon as possible ?
  • Or only after Bitbucket closed it ?

If I look at the current state of the developement of SharpBucket:
Release 0.7.2 Is the last one to have improved API V1 implementation (released in march)
Release 0.7.3 and all code already in master or in progress concern only API V2 implementation
So we can reasonably though that we won't maintain any more the API V1 implementation since nobody has shown any interest for that since months

In that context I suggest to tag the SharpBucketV1 class as obsolete for a next release. That release (0.8.0 if we are agree quickly ?) can be used by consumers to detect where they have code to change
Then in a next release (0.9.0 ?) we remove the class and all the code that is linked to API V1

Consumers that want to stay on the API V1 until the final date can stay on Release 0.7.3 (or on 0.8.0 with warnings), they are not forced to upgrade. So it should not stop us to stop supporting the API V1 before the final date.
Furthermore, at the final date our unit tests will break if we haven't drop the code before, which means that it would be better to drop that code not too late.

@MitjaBezensek, @asherber, are you agree with that strategy ?

Project Filter on RepositoriesEndPoint

what is the best way to get all repos for a certain project ?
currently , I only see one option that will get all repos from all projects under the Team account .

Release notes

With each release we should write release notes. This is especially critical at this early state since we quite often introduce breaking changes. This should help SharpBucket users with decisions about updating to the new version.

PostRepository Uses Repository.Name in the POST request URL

PostRepository uses the Repository.name property to populate the POST request URL.

    internal Repository PutRepository(Repository repo, string accountName)
    {
        var overrideUrl = GetRepositoryUrl(accountName, repo.name, null);
        return _sharpBucketV2.Put(repo, overrideUrl);
    }

While the repository name being used in the request URL is required to be lower cased and slugified, it is not a requirement for the repository's name to be lower case or slugified. These should be two separate values.

A simple solution would be to pass _repository from RepositoryResource.cs to RepositoriesEndpoint.PostRepository, similar to how it is done with PutRepository.

    internal Repository PostRepository(Repository repo, string accountName, string repository)
    {
        var overrideUrl = GetRepositoryUrl(accountName, repository, null);
        return _sharpBucketV2.Post(repo, overrideUrl);
    }

PullRequest activity endpoints missing approval data

The following endpoints currently have activity information, containing updates (and comments?). However, I am missing a separate data type for the approval of a pullrequest (and by whom).

  • /repositories/{username}/{repo_slug}/pullrequests/activity GET

    • Implemented by: PullRequestsResource.GetPullRequestLog()
    • Tested: yes
  • /repositories/{username}/{repo_slug}/pullrequests/{pull_request_id}/activity GET

    • Implemented by: PullRequestResource.GetPullRequestActivity()
    • Tested: yes

This functionality is listed in the BB documentation, and I have indeed seen it using curl, but I cannot retrieve it within C#.

(https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/pullrequests/activity)

Am I missing something or could this be added?

Add contributing info

Write a short guide about how other developers can help with contributing (how to setup their machines, what needs fixing, what libraries we are using,...).

2 legged OAuth seems broken

I cannot use the 2 legged OAuth1.0 authentication that is used in the console program. It seems that something was changed.

OAuth1 does not work for paginated request

The pagination seems to break the OAuth1 authentication. The problem is that the url is just appened to the base url of the resource. For OAuth1 this is problematic since oauth_signature is calculated based on it.

The solution might be quite simple. We should pass a List of parameters to the ExecuteRequest method which will then just add them as parameters like so: request.AddParameter("pagelen", 30);

I have tested this and it works. @0x1mason are you up for this one since you might be the most familiar with the logic of pagingation?

Projects API

Hi,

I can't see to find any reference to projects in the API. I've looked for the following:

  • A way to retrieve a list of projects for a team
  • A way to create a new project
  • A way to associate a repository with a particular project

Do these APIs exist or am I barking up the wrong tree?

Testing

Currently SharpBucket does not contain any tests, which makes it hard to make changes that affect many different parts. Since the code is mostly just 3rd party api calls it makes no sense to try to do classical unit tests since it would just be mocking everything.

An solution would be to implement integration tests like oktokit.net. Maybe create a repo with dummy data which can then be tested against. And for quite a few of the calls we can just use a public repo with a lot of data.

Any other thoughts?

Annoying typo

Should be called PullRequestsResource, not PullReqestsResource.

When I hit the rate limits of the API SharpBucket handle very badly the response

If I do a lot of API requests I may reach the rate limit setupt by bitucket.
In that case BitBucket return an HTTP 429 error response which is not handle at all by SharpBucket and start to an an erratic behavior since it try to interpret the result like if it was an HTTP 200 response.

Exemple of the BitBucket response:

HTTP/1.1 429 Unknown Status Code
Server: nginx
Vary: Authorization
Cache-Control: no-cache, no-store
Content-Type: text/plain
X-OAuth-Scopes: account, team, pullrequest, issue, snippet, webhook
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Date: Fri, 25 Jan 2019 14:55:24 GMT
X-Served-By: app-161
X-Static-Version: 81e1c2138b0b
ETag: "62dcd5481fd29816ecc5ae00be2da0b0"
X-Render-Time: 0.0162138938904
X-Credential-Type: oauth1
X-Accepted-OAuth-Scopes: repository
Connection: Keep-Alive
X-Version: 81e1c2138b0b
X-Request-Count: 447
X-Frame-Options: SAMEORIGIN
Content-Length: 46

Rate limit for this resource has been exceeded

NB: the X-Request-Count header seems to depends on the X-Served-By, but it doesn't seems to be of any help for this issue

Make the token available

Is there a way to access the access token?
I am attempting to run clone commands and need to pass along the token.

Thanks!

Bug in RepositoriesEndPoint.GetDiff() and GetPatch()?

I came across this while working on #90 .

Both GetDiff() and GetPatch() take an options parameter which is an object. Looking at the API here and here I think this parameter should be called spec and should just be a string; passing in a random object will cause errors.

In addition, GetDiff() should be able to take an object like ListParameters that provides context, path, ignore_whitespace, and binary.

I can put together a PR if you agree that these should be fixed.

How to make a commit?

Hi,
from a service I need to commit some files to our Bitbucket repo but I can't find the Commit method :-
The only one is a PullRequest one but I don't think that I must make a PR for each commit and then approve it :-P

Thanks
valse

OAuthentication2 problem

var sharpBucket = new SharpBucketV2();
sharpBucket.OAuthentication2(Key,Secret)

throws

System.Exception: 'Unable to retrieve OAuth2 Token:
0
'

Any help? Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.