LoginEx

Overview

In some cases, a server application requires the user to provide more information than just a username and password to perform the login action. Relativity Server, for example, also requires a Domain name or a User Access Level descriptor.

Of course it is possible to add several Login method overloads with different parameters accepted, but this approach has several major caveats:

  • The developer will have to keep in sync the _Intf file used in the client application(s) and the server RODL.
  • There could be dozens of possible login parameter combinations, so it will be difficult to cover them all with login service method definitions.
  • Code implementing the Login Service will soon bloat and become a mess with spaghetti-like code.

Resolving this problem was the main reason for introducing the LoginEx feature. It provides a clean and reliable solution for all of the above-mentioned caveats:

  • Single entry-point method
  • No need to import the server application RODL
  • All possible login parameter combinations can be covered by a single API method

LoginEx in details

Rather than passing individual parameters, LoginEx provides a common Login service interface based on the connection string approach that can, in addition to username and password, provide an arbitrary number of parameters required by the server. For example, Relativity Server has a Domain parameter and (optionally) a Schema parameter.

The format of the connection string is quite straightforward – several key-value pairs separated by a ; symbol, for example

User Id=Data;Password=Relativity;Domain=PCrade Sample;Schema=PCTrade

This LoginEx string (or login string) defines a connection with username Data and password Relativity, as well as two additional login parameters, Domain and Schema.

The default implementation of the LoginEx method extracts the username and password from the provided connection string and passes them to the Login method. The service implementation method LoginEx(String) should be overridden in case more advanced implementation is needed.

LoginEx connection string parser

Data Abstract provides built-in LoginEx connection string parser classes: LoginStringParser for .NET and TLoginString for Delphi.

Escaping special symbols

To use a semicolon (;) in a connection string entry name or value, the entire value should be surrounded by quotes ().

Custom Entry="Custom Entry=Inner Value;Something=Alpha""Value";"Custom Entry 2"=Some Value"" Here;

This connection string defines two key-value pairs:

  • Key Custom Entry, value Custom Entry=Inner Value;Something=Alpha"Value"
  • Key Custom Entry 2, value Some Value" Here

Note how the " symbol was escaped in the above key-value pairs.

Composing LoginEx method

At the first glance the login string van be composed using simple string concatenation:


var loginString = "User ID=" + userName + ";Password=" + password;

loginString := 'User ID=' + userName + ';Password=' + password;

Unfortunately such string concatenation might produce a non-valid login string. F.e. if the password value used contains special symblos like " or = then it should be escaped in the resulting login string. While value escaping rules are very simple, they still need to be implemented by the user code.

Luckily Data Abstract provides a helper class that simplifies login string composition by providing the default string escaping implementation:


var login = new RemObjects.SDK.SemicolonSeparatedString();
login["User ID"] = userName;
login["Password"] = password;
var loginString = login.ToString();
login := TStringList.Create;
try
  login.Delimiter := ';';
  login.Values('User ID') := userName;
  login.Values('Password') := password;
  loginString := login.DelimitedText;
finally
  login.Free;
end;

Calling LoginEx method

For Delphi and .NET, the proxy is created for BaseLoginService (the ancestor of all DataAbstract Login services) and the LoginEx method of the LoginService service is called. For Xcode, the DARemoteDataAdapter class provides login functionality out of the box via the loginWithString message for LoginEx.


(new RemObjects.DataAbstract.Server.BaseLoginService_Proxy
(message, clientChannel, "LoginService"))
    .LoginEx("User=UserName;Password=UserPassword");

DynamicRequest.ParamByName('aLoginString').AsString :=
  'User Id=UserName;Password=UserPassword';
DynamicRequest.Execute();

Dynamic Request setup:

lRemoteService := TRORemoteService.Create(nil);
lRemoteService.Channel := self.Channel;
lRemoteService.Message := self.Message;
lRemoteService.ServiceName :='LoginService';

lDynamicRequest := TRODynamicRequest.Create(nil);
lDynamicRequest.RemoteService := lRemoteService;
lDynamicRequest.MethodName := 'LoginEx';

lDynamicRequest.Params.Add('Result', rtBoolean, fResult);
lDynamicRequest.Params.Add('aLoginString', rtUTF8String, fIn);

[remoteDataAdapter loginWithString:@"User=UserName;Password=UserPassword"];

Summary

The LoginEx feature provides a unified, simple and easily extensible server login interface for client applications.