AdvDropbox.Connect Logic Incorrect

Hi Bart (if you are monitoring),


- Connect technique
You should be able to determine from the boolean result if the authentication worked or not.
Then use the OnConnected event to call SaveTokens.

According to my Testing now with a forms based application using the TADVDROPBOX component:

If there is no saved/persistent token:
  1. AdvDropbox.Connect RETURNS FALSE
  2. It cannot be used to determine if authentication worked
  3. OnConnected is fired
If there IS A SAVED/PERSISTENT TOKEN:
  1. AdvDropbox.Connect RETURNS TRUE
  2. It CAN be used to see if authentication worked
  3. OnConnected is fired
So using the boolean return of AdvDropbox.Connect is inconsistent and poorly implemented. It cannot be used reliably to see if authentication succeeded or failed unless my testing is completely wrong. I am assuming (and will need to test) that OnReceivedAccessToken and OnAccessDenied are a more reliable way of testing the success of AdvDropbox.Connect in all situations.

Can anyone please confirm the operation as I have described, particularly that AdvDropbox.Connect returns FALSE if there is no persistent token available and you need to do the login/allow for DROPBOX?

Thx,
Kevin

And further to my initial post on this matter:

To overcome the problem of your callback seemingly not functioning if setup in a Delphi DLL, I have created a small application that authorises Dropbox and passes the token to my DLL calling what is left of the signin process. This application uses a form so your callback will work. The form is not visible and (should) require NO interaction from the user.

If I use an internal Browser AND CANCEL out of the authorisation form (failing the authorisation) the AuthFormClose event is triggered (the AccessDenied event is not triggered), but I at least know the user has finished (and not authorised). Whilst it is a bit inelegant, I can check for a variable like 'Authorised' and if set to false then I know to terminate my application and that the user has not authorised Dropbox (ie. I would set 'Authorised' to true in the OnConnect event if it were triggered).

If OTOH I use an external browser and cancel out of that by closing the browser page, the AuthFormClose event is NOT triggered. In fact, as near as I can work out NOTHING is triggered. I have no way of knowing that the user simply killed the authorisation webpage. My application has nothing to indicate it has not connected and nothing to say that the authorisation has failed.

Again, how can I work around this, since external browser access is required for Dropbox to put your app into production????
  • We are assuming that using a DLL is causing trouble with the IndyServer that is required for the ExternalBrowser functionallity.
    We will further investigate this issue as soon as we have been able to allocate sufficient development time.

    - When ExternalBrowser is active the browser is opened through a shell execute.
    Detecting when an external browser has closed is technically difficult if not impossible.

Hi Bart,


There are two defects that I believe I identified:

DEFECT #1:

- We are assuming that using a DLL is causing trouble with the IndyServer that is required for the ExternalBrowser functionallity.
We will further investigate this issue as soon as we have been able to allocate sufficient development time.

No, it's not just the external browser, it's any browser. The events are not triggered (OnConnect and OnReceivedToken etc). The external browser just had the added issue of NOT triggering an event if the user terminated the webpage without authorising Dropbox. 

DEFECT #2:

- Connect technique
You should be able to determine from the boolean result if the authentication worked or not.

The other issue I highlighted was that the boolean return from the AdvDropbox.Connect was not consistent. If I have a valid token saved in the INI file and I do a AdvDropbox.Connect it returns TRUE (as expected). If I do not have a valid token in an INI file or indeed if the INI file has not yet been created, EVEN IF ADVDropbox.Connect succeeds it will always return FALSE. So you cannot use the boolean property of ADVDropboxConnect to see if Authentication worked or not as you previously suggested.

ISSUE

- When ExternalBrowser is active the browser is opened through a shell execute.
Detecting when an external browser has closed is technically difficult if not impossible.

This is an issue/limitation, clearly not a defect. That explains why no events are triggered by the closure of the webpage with the Dropbox Auth in it. Can you suggest what best practice might be to handle such an occurrence, a user with external browser simply closes the webpage without authorising Dropbox?

Do you put a timer in somewhere and if no (Valid) response by a certain period then timeout the process? Any suggestions?

Thx,
Kevin



Adding a timer is a good suggestion. I would recommend to manually add a timer to your application.

The workaround in XE7 did in fact work, but was messy using named pipes to communicate with the authentication process and managing the async comms between the DLL and the Forms application that did the Dropbox authentication.


Happy to report I did a convert and build with XE10.1 and it now works as expected within the DLL, ie. the TMS component detects the authentication and the ini file with the credentials. I have no idea why the same code works in XE10.1 and NOT in XE7, but as far as I am concerned it is now fixed (or the work around is to use XE10.1.

This function is now failing in the latest version when called from a DLL. So here's what I have done:


TMSDropbox.Connect RETURN FALSE even if I enter the correct DropboxID/Password. All of the things that are expected to happen do (NO INI FILE):
  1. OnConnected is fired
  2. OnReceivedTokens is fired
  3. etc etc
  4. The return from TCloudBase.Connected is NEVER set to TRUE even after a successful DOAUTH
  5. If I then try to do a Connect the INI File was created, the tokens saved and the connection succeeds
My fix is to do a TestTokens and set the result (this in CloudBase.PAS):

function TCloudBase.Connect: boolean;
var
  acc: boolean;

begin
  Result := false;

  if App.Key = '' then
    raise Exception.Create('Missing application key');

  LoadTokens;

  acc := TestTokens;

  if not acc then
  begin
    RefreshAccess;
    acc := TestTokens;
  end;

  if acc then
  begin
    Result := true;
    DoConnected;
  end
  else
    DoAuth;  // AT THIS POINT EVEN IF SUCCESSFUL RESULT IS STILL FALSE
  // OREX
  // Ensure the return is set to TRUE if success
  acc := TestTokens;   // Now returns TRUE
  if acc then
    Result := True;
  // OREX
end;



We are currently investigating this issue and will report back as soon as possible