Search code examples
c#restbitbucketatlassian-sourcetreebitbucket-api

How to download a private bitbucket.org repository using pure REST API calls, version 1 or 2


I'm trying to clone/download my private bitbucket.org repository using C#, but I want to do it using pure HTTPS REST calls, and not a third party lib, i want to learn how it works.

So far I could only find example code for version 1 of the api. This is what i've got working so far in C#:

static void AUthenticate()
    {
        var time = GenerateTimeStamp();
        var url = "https://bitbucket.org/api/1.0/oauth/request_token";
        var secret = "SECRET";
        var key = "KEY";

        var sigBaseStringParams = "";
        sigBaseStringParams += "oauth_callback=http%3A%2F%2Flocal%3Fdump";
        sigBaseStringParams += "&" + "oauth_consumer_key=" + key;
        sigBaseStringParams += "&" + "oauth_nonce=" + GetNonce();
        sigBaseStringParams += "&" + "oauth_signature_method=" + "HMAC-SHA1";
        sigBaseStringParams += "&" + "oauth_timestamp=" + time;
        sigBaseStringParams += "&" + "oauth_version=1.0";
        var sigBaseString = "POST&";
        sigBaseString += Uri.EscapeDataString(url) + "&" + Uri.EscapeDataString(sigBaseStringParams);

        var signature = GetSignature(sigBaseString, secret);

        var res = PostData(url, sigBaseStringParams + "&oauth_signature=" + Uri.EscapeDataString(signature));

        var items = GetParameters(res);

        var tokenSecret = items["oauth_token_secret"];
        var token = items["oauth_token"];
        var callbackConfirmed = items["oauth_callback_confirmed"];

        url = "https://bitbucket.org/api/1.0/oauth/authenticate?oauth_token=" + token;
    }

This authenticates and I get 3 values back. The last URL i paste into a browser, where i grant my application access and i end up with an oauth_verifier

Note: I don't really want to do this as I am writing a server program which won't really be able to send a user to a browser link (but one thing at a time)

I then run the following code:

var url = "https://bitbucket.org/api/1.0/oauth/access_token";

        var token = "TOKEN FROM PREV CALL";
        var time = GenerateTimeStamp();
        var sigBaseStringParams = "";
        //sigBaseStringParams += "oauth_callback=http%3A%2F%2Flocal%3Fdump";

        var secret = "SECRET";
        var key = "KEY";

        sigBaseStringParams += "oauth_consumer_key=" + key;
        sigBaseStringParams += "&" + "oauth_token=" + token;
        sigBaseStringParams += "&" + "oauth_nonce=" + GetNonce();
        sigBaseStringParams += "&" + "oauth_signature_method=" + "HMAC-SHA1";
        sigBaseStringParams += "&" + "oauth_timestamp=" + time;
        sigBaseStringParams += "&" + "oauth_verifier=AUTH VERIFIER FROM PREV CALL";
        var sigBaseString = "POST&";
        sigBaseString += Uri.EscapeDataString(url) + "&" + Uri.EscapeDataString(sigBaseStringParams);

        var tokenSecret = "TOKEN SECRET FROM PREVIOUS CALL";
        var signature = GetSignature(sigBaseString, secret, tokenSecret);

        var res = PostData(url, sigBaseStringParams + "&oauth_signature=" + Uri.EscapeDataString(signature));

This gives me a 400 bad request. I can't see much else.

I'm following the steps on this page: https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html#OAuthonBitbucketCloud-Refreshtokens

Why I'm doing this is because i want to eventually make a POST request (or GET) to this URL:

var url2 = "https://bitbucket.org/ACCOUNT/REPOSITORY/get/tip.zip?access_token="+token;

Because I think this will give me the entire repository in a zip file. If i put this in the browser it works because i'm logged into bitbucket.

If there is a newer/easier/better way i'm open to suggestions.

Thanks in advance


Solution

  • I found a very simple solution. I just had to provide credentials to a GET request:

     public static void Downloadfiles(string username, string password, string account, string repository, string pathToSave)
        {
            var creds = Base64Encode(String.Format("{0}:{1}", username, password));
    
            var url = String.Format("https://bitbucket.org/{0}/{1}/get/tip.zip", account, repository);
    
            using (var client = new WebClient())
            {
    
                client.Headers.Add("Authorization", "Basic " + creds);
                client.Headers.Add("Content-Type", "application/octet-stream");
                client.DownloadFile(url, pathToSave);
            }
        }