TMSDropbox.CONNECT fails as does TESTTOKENS / DOAU

 thought this issue was resolved, but it's back just as bad as before. here's the issue in VCL Cloud Pack that just 'went away' when using XE10.2:


https://www.tmssoftware.com/site/forum/forum_posts.asp?TID=8255&title=advdropboxconnect-logic-incorrect

Now exactly the same/similar thing is happening when using FMX Cloud Pack and trying to authorise from within a dll:

      // Authorise Dropbox
      If not(TMSDropbox.Connect) then
        if signinTimeout then
          raise Exception.Create(inttostr(Ord(ERR_DBXAUTHTIMEOUT)))
        else
          raise Exception.Create(inttostr(Ord(ERR_DBXAUTHFAIL)));
  1. With ExternalBrowser False
  2. Execute .CONNECT
  3. Falls straight through to error condition
  4. BUT the internal browser appear
  5. The details are entered
  6. The INI file is created, but empty
  7. I get the message ...you can close the browser window now... ie. the software doesn't know it's using an internal browser
  8. If I user an external browser exactly the same
If I use the code that does a DOAUTH the same, nothing is recognised by  TMS code:

      TMSDropbox.LoadTokens;
      Authorised := TMSDropbox.TestTokens;

      if not(Authorised) then
      begin
        TMSDropbox.RefreshAccess;
        Authorised := TMSDropbox.TestTokens;
        if not(Authorised) then
          TMSDropbox.DoAuth;
      end;

DOAUTH does nothing, ie. there is no browser popped up (external or internal). 

Is there a fix, I don't want to go back to named pipes passing credentials around, that's just garbage....

Anyone have any ideas?

An update:


DoAuth actually pops a browser window. I have a TMSDropbox.SaveTokens directly after the block of code above. I can confirm that the code is hgetting to the TESTTOKENS, REFRESHACCESS, DOAUTH and SAVETOKENS code. The Token_Auth is being saved in the INI file. The Token_Access is NOT being saved. 

Subsequent authorisations (as in TESTTOKENS) checks for Token_Access being ''. If it is it just exits the function which it is doing. Having said that, the value of Token_Auth is being set and written to the INI file.
Hi,

I'm not sure what is causing this issue. 
We haven't had any similar reports from other users.

If the behavior is different between Delphi versions it's likely this is an internal Delphi issue.
Can you please confirm if authentication is working as expected for you in a standalone application?

Hi Bart,


Here's the setup:
  1. XE10.2
  2. Latest version of FMX Cloud Pack
  3. My DLL (Was working fine with VCL Cloud Pack) converted to Firemonkey
  4. Obviously the cloud libraries (VCL and FMX) are different
Now heres the step by step of what happens:
  1. Run Test App which calls the DLL Function to sign in to Dropbox
  2. The TMSDropbox component is setup (EXTERNALBROWSER := FALSE)
  3. I step through the coed and it gets to this line: CreateOAuthForm(url,nil,nil);
  4. The first thing that is shown (for about 1 second) in the browser Windows is this:

  5. Then the main Dropbox Credentials screen, but note the icons on the top line (they should not be there for an internal browser:

  6. I put in valid credentials and the system likes it and takes me to the ALLOW screen (note I'm logged into Dropbox):

  7. I then allow Access and show a messageBox with the credentials (only TOKEN_AUTH) has been set:

  8. Ad finally I look in the INI file and see what have been saved by SAVETOKENS and, as expected it's the TOKEN_AUTH only:

With a standalone application:
  1. USING CONNECT
  2. If I use CONNECT, the boolean return is FALSE
  3. If I then do a CONNECT again the boolean is TRUE
  4. So it appears to connect, it just returns with FALSE, but does update the INI File
  5. The INI File works second time around
  6. If I use CONNECT and then try to use a property immediately after it returns FALSE (TMSDropbox.Info.UserName) this works
  7. So clearly it's returning incorrectly, but is working 
  8. USING DOAUTH
  9. If I Use DOAUTH, this appears to work first time through
  10. If I then try to use a property immediately after (TMSDropbox.Info.UserName) this works
  11. In both cases the Dropbox Form is disposed of correctly and the INI file is updated with both AUTH_TOKEN and ACCESS_TOKEN
NOTE that the weird (1st image) Blank{7844584E-.....} is still displayed before the login screen.

Quick Follow up:


If I use a standalone to get the INI file updated, the DLL will authenticate. Note that  none of the TMSDropbox callbacks are triggered:

      OnConnected 
      OnAccessDenied
      OnAuthFormClose 
      OnReceivedAccessToken 

If I don't have a valid INI file and do a DOAUTH, the OnAuthFormClose is triggered EVEN THOUGH the form is still displaying ....Authentication successful, you can close this form now... (and the authentication wasn't successful;
When the code in FMX.TMSCloudbase.pas gets to SAVETOKENS, then TOKEN_AUTH has a value and TOKEN_ACCES is blank. I guess my question is, where in the code does Token_Acces get set?

procedure TTMSFMXCloudBase.SaveTokens;
var
  Settings: TIniFile;
  {$IFDEF MSWINDOWS}
  RegInifile: TReginifile;
  {$ENDIF}
  fld: TField;
  ex: string;
begin
  if (PersistTokens.Key = '') or (PersistTokens.Section = '') then
    Exit;


  ex := GetExtraData;

  case PersistTokens.Location of
  plIniFile:
    begin
      Settings := TIniFile.Create(PersistTokens.Key);

      Settings.WriteString(PersistTokens.Section,'ACCESS_TOKEN',EnDeCrypt(Token_Access));
      Settings.WriteString(PersistTokens.Section,'AUTH_TOKEN',EnDeCrypt(Token_Auth));
   Settings.WriteString(PersistTokens.Section,'ACCESS_TOKEN_SECRET',EnDeCrypt(Token_Access_Secret));
      Settings.WriteString(PersistTokens.Section,'AUTH_TOKEN_SECRET',EnDeCrypt(Token_Auth_Secret));
      Settings.WriteString(PersistTokens.Section,'REFRESH_TOKEN',EnDeCrypt(Token_Refresh));
      Settings.WriteString(PersistTokens.Section,'EXTRA_DATA',EnDeCrypt(ex));

      Settings.Free;
    end;

So I can see that Token_Access gets set in FMX.TMSCloudCustomDropbox in Protected procedure GetAuthToken (yes that does a getAccessToken, confusing choice of procedure names).


So when I run the DoAuth this procedure DOES NOT get called. If I unprotected the function, and explicitly call it AFTER DoAuth, it gets called, does an ONCONNECTED and an ONRECEIVEDACCSSTOKEN and actually connects. 

If I then do a SAVETOKENS the INI file Now has the Token_Auth and Token_Access. 

The QUESTION then is:
Why when I run the DoAuth from a standalone application does FMX.TMSCloudCustomDropbox.GetAuthToken get called, yet when I run DoAuth from a DLL then FMX.TMSCloudCustomDropbox.GetAuthToken DOES NOT get called (I have proven this by single stepping through the code of each)??????
We are currently investigating this issue and will report back as soon as possible.

I'm porting my code to OSX. Component named TMSDropbox.


The TMSDropbox.CONNECT fails even when using the TMS Dropbox component. 

I get the ID/Password window, I get the ALLOW window yet TMSDropbox.Connect returns FALSE.

If I then try to use the values (like TMSDropbox.GetAccountInfo and then TMSDropbox.Info.Surname) I get a valid return. So TMSDropbox.Connect has actually succeeded, it's just not returning TRUE.

This sort of makes the component unusable, have you a test routine for OSX and TMSDropbox.Connect????

Hi,


Have you tried using the CloudStorageDemo application which should be working as expected for OSX and includes the TMSFMXCloudDropBox control?

If the problem persists, please provide the following information so I can further investigate this.
- The version of Delphi you are using
- The version of OSX you are using
- Does the issue occur in the CloudStorageDemo?

Hi,


This is essentially the same issue as my other post....where is the INI File....

I can use the demo to do the INIFile thing (the demo does save the tokens on the mac, I'm yet to find exactly where, but I can sort this out).  

The big problem is that storage.connect returns FALSE even though it succeeds, this was the problem I was having when doing the storage.connect from a DLL. Now it is happening even in your demo.

If the problem persists, please provide the following information so I can further investigate this.
- The version of Delphi you are using
Delphi 10.2.3 Community

- The version of OSX you are using
OSX High Sierra 10.13.6

- Does the issue occur in the CloudStorageDemo?
Yes, your code fails. You do NOT have a test for connect returning (a boolean) you only do this:

Storage.Connect;

But if you check the boolean return IT IS FALSE EVEN THOUGH THE CONNECTION SUCCEEDED

if not(Storage.Connect) then
  showmessage('Connection Failed');   <<<<---- This is displayed even though connect succeeded




And just some more code to show what's happening with macOS:


procedure TfrmEmpyreanMain.Button18Click(Sender: TObject);
var
  isConnected: boolean;

begin
  try
    // Signin
    TMSDropbox.Connect; <<<---THIS RETURNS FALSE

    isConnected := TMSDropbox.TestTokens;
    if not(isConnected) then   <<<-----THIS FAILS (SO TESTTOKENS FAILS)
    begin
      // Error message
      TDAMessageBox.MessageDialog(etc etc....
    end;

    TMSDropbox.GetAccountInfo;  <<<<-----THIS SUCCEEDS

  finally

  end;
end;
Sorry previous was an Accident.

Now your DEMO does not work, ie. even the simplest TMSDropbox.Connect does not work in the main form (let alone in a DLL which is constantly causing me grief).

Here's your DEMO code (I explicitly reference the Dropbox component):

  RadioGroup1.Enabled := false;

  if not(TMSFMXCloudDropBox1.Connect) then
    showmessage ('Connection Failed');
end;

Here is the result:



At this point, the browser window pops and I can put in credentials (if not already) and then press ALLOW. After that the BROWSER tells me all is well. I have put in a TESTTOKENS button and it also tells me that all is well:

procedure TForm4.Button1Click(Sender: TObject);
var
  isConnected: boolean;
begin
    isConnected := False;
    isConnected := TMSFMXCloudDropBox1.TestTokens;
    if isConnected then
      showmessage('Dropbox IS Connected!!!!')
     else
      showmessage('Dropbox IS NOT Connected!!!!')
end;

And here's the result of testing the tokens:


As you can see it really is connected. This is very confusing.

So I'm fighting the front end, and in my DLL I'm having these and other issues, like for example, the onConnected and onAccessTokenreceived are not being triggered. I can confirm I'm receiving (now) the AUTH TOKEN, but not receiving the ACCESS TOKEN.

The whole connect thing is fairly weak and very fragile. Just sayin'

So for an external browser, can you please look at your demo code (CloudStorageDemo) and confirm that storage.Connect fails even though the connection has actually occurred?

Hi,


Please note that the Connect call will only return True if a valid access token is available.
If not the Authentication process is started and the Connect call returns false as the connection isn't active yet.
Then wait for the OnConnected event to trigger indicating the authentication process succeeded and the connection is made.

Hi Bart,


OK that makes sense and is consistent with what I'm seeing. I just assumed you had some sort of waitnofreeze code embedded in the source (that I could not find - because it isn't there).

Thanks, Kevin