Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Ubuntu One API results in "401 UNAUTHORIZED" or "400 BAD REQUEST"

I am using Delphi XE2 with Indy 10 to access the Ubuntu One API. So far so good. I was able to get the OAuth Token from the Cloud as described. Now I want to start using the API (like described):

function TUbuntuOneApi.DoRequest(const URL: String): String;
var
  RequestParams: TStringList;
  HeaderIndex: Integer;
const
  OAuthAuthorisationHeader = 'OAuth realm="", oauth_version="%s", oauth_nonce="%s", oauth_timestamp="%s", oauth_consumer_key="%s", oauth_token="%s", oauth_signature_method="%s", oauth_signature="%s"';

begin
  RequestParams := SignOAuthRequestParams(URL, fOAuthAppToken, fOAuthAccessToken);

{  OAuth realm="", oauth_version="1.0",
  oauth_nonce="$nonce", oauth_timestamp="$timestamp",
  oauth_consumer_key="$consumer_key", oauth_token="$token",
  oauth_signature_method="PLAINTEXT",
  oauth_signature="$consumer_secret%26$token_secret"
  }

  HeaderIndex := IdHTTP.Request.CustomHeaders.IndexOfName('Authorization');
  if HeaderIndex >= 0 then
  begin
    IdHTTP.Request.CustomHeaders.Delete(HeaderIndex);
  end;

  // Solving: http://stackoverflow.com/questions/7323036/twitter-could-not-authenticate-with-oauth-401-error
  IdHTTP.Request.CustomHeaders.FoldLines := false;

  IdHTTP.Request.CustomHeaders.AddValue('Authorization', Format(OAuthAuthorisationHeader, [
      TIdURI.URLDecode(RequestParams.Values['oauth_version']),
      TIdURI.URLDecode(RequestParams.Values['oauth_nonce']),
      TIdURI.URLDecode(RequestParams.Values['oauth_timestamp']),
      TIdURI.URLDecode(RequestParams.Values['oauth_consumer_key']),
      TIdURI.URLDecode(RequestParams.Values['oauth_token']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature_method']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature'])
    ]));

  // Execute
  Result := IdHTTP.Get(URL);
  RequestParams.Free;
end;

function TUbuntuOneApi.Test: String;
begin
  //Result := DoRequest('https://one.ubuntu.com/api/file_storage/v1');
  Result := DoRequest('https://one.ubuntu.com/api/account/');
end;

Calling https://one.ubuntu.com/api/file_storage/v1 results in "401 UNAUTHORIZED". Calling https://one.ubuntu.com/api/account/ results in "400 BAD REQUEST". The OAuth Library is from SourceForge and works with Dropbox (Dropbox accepts the OAuth-Params if they are in the Query-String). The Tokens are correct and valid. What am I doing wrong?

BTW:

function SignOAuthRequestParams(const URL: String; OAuthAppToken, OAuthAccessToken: TOAuthToken): TStringList;
var
  Consumer: TOAuthConsumer;
  ARequest: TOAuthRequest;
  Response: String;
  HMAC: TOAuthSignatureMethod;
begin
  HMAC := TOAuthSignatureMethod_PLAINTEXT.Create;
  // Consumer erzeugen
  Consumer := TOAuthConsumer.Create(OAuthAppToken.Key, OAuthAppToken.Secret);

  // Request erzeugen
  ARequest := TOAuthRequest.Create(URL);
  ARequest := ARequest.FromConsumerAndToken(Consumer, OAuthAccessToken, URL);
  ARequest.Sign_Request(HMAC, Consumer, OAuthAccessToken);

  Result := TStringList.Create;
  Result.AddStrings(ARequest.Parameters);

  ARequest.Free;
  Consumer.Free;
  HMAC.Free;
end;
like image 253
rollstuhlfahrer Avatar asked Nov 13 '22 18:11

rollstuhlfahrer


1 Answers

At this point, the newly created token can be used to authenticate to other methods, on the Ubuntu SSO service, but can not yet be used with the Ubuntu One API. We need to tell Ubuntu One to copy the newly created token from the SSO service. This is done by issuing a GET request to the following URL, signed with the new OAuth token. From Ubuntu One: Authorization page.

Shame on me, I forgot to do that.

like image 173
rollstuhlfahrer Avatar answered Jan 04 '23 03:01

rollstuhlfahrer