Reputation: 658
I do not seem to manage the file copy operating using the dropbox api. I can successfully authorize my client, download and upload files. The copy operation needs POST method to be used and I think this is where I produce wrong request. I am defining the POST Method for OAuth Authentication and use Indy TIdHTTP to Post the request, but I always receive the error code 403 - Permission denied.
Here is the dropbox api description: https://www.dropbox.com/developers/reference/api#fileops-copy
Here is part of my code:
ParamStr := Format('root=%s&from_path=%s&to_path=%s', [Root, EncodeFileName(FromPath), EncodeFileName(ToPath)]);
URL := 'https://api.dropbox.com/1/fileops/copy' + '?' + ParamStr;
Consumer := TOAuthConsumer.Create(Key, Secret);
AToken := TOAuthToken.Create(fToken, fTokenSecret);
HMAC := TOAuthSignatureMethod_HMAC_SHA1.Create;
ARequest := TOAuthRequest.Create('');
try
ARequest.HTTPURL := URL;
ARequest.Method := 'POST';
ARequest := ARequest.FromConsumerAndToken(Consumer, AToken, '');
ARequest.Sign_Request(HMAC, Consumer, AToken);
Params := TStringList.Create;
try
Params.Text := ParamStr + '&' + ARequest.GetString;
HTTP.Post(URL, Params);
finally
Params.Free;
end;
Upvotes: 22
Views: 4719
Reputation: 75
I think i might discovered whats wrong here. I am unaware of the TOAuthRequest class but I will guess that the GetString method gives the standart OAuth header 'Authorization Bearer {KEY}'. See that is header and the right way to add it to the http request is
HTTP.Request.CustomHeaders.AddValue('Authorization', <the rest of the string here>)
You on the other hand add that string to the body which may work for Get requests because the body(the authorization string) is mistaken for a header but with the POST method you have actual body before the authorization string and thus the OAuth string is ignored.
And lastly I don't think you need the parameters string in the body as well. An empty body should work just fine. The query string seems OK.
Example code:
ParamStr := Format('root=%s&from_path=%s&to_path=%s', [Root, EncodeFileName(FromPath), EncodeFileName(ToPath)]);
URL := 'https://api.dropbox.com/1/fileops/copy' + '?' + ParamStr;
Consumer := TOAuthConsumer.Create(Key, Secret);
AToken := TOAuthToken.Create(fToken, fTokenSecret);
HMAC := TOAuthSignatureMethod_HMAC_SHA1.Create;
ARequest := TOAuthRequest.Create('');
try
ARequest.HTTPURL := URL;
ARequest.Method := 'POST';
ARequest := ARequest.FromConsumerAndToken(Consumer, AToken, '');
ARequest.Sign_Request(HMAC, Consumer, AToken);
HTTP.Request.CustomHeaders.AddValue('Authorization', <parsed ARequest.GetString>)
HTTP.Post(URL);
Hope that this helps.
Upvotes: 1
Reputation: 126
As far as I know when using with indy the params are copied in the body of the message and not in the url try using something like:
http:Post(URL+encodeparams(params));
I'm not sure that this is the right syntax but that's the idea.
Upvotes: 1