Windows and Web integration through Thinfinity® jsRO (Javascript Remote Objects) – Part 3

Now that we’ve learned how to create a remote object and expose it on the Web, let’s see how to interact with jsRO objects in more detail.

 

The jsRO Object life cycle and the predefined Javascript Events

Let’s begin by noting that the jsRO objects are always defined inside the application and propagated to the browser. You can’t add new properties, methods or events to these objects in the browser side, but you can retrieve and modify property values, invoke objects’ methods and handle their events.

Four predefined Javascript events are related to the jsRO object life cycle, associated to its creation, updating and destruction.

Starting from the first ApplyModel invoked in the application, jsRO will create the object and propagate it to the browser, where it will trigger the created event:

on(“model:object”, “created”, ...)

also, for the properties that are created with an assigned value, jsRO will replicate their initial values in the browser and fire the corresponding events (one per property):

on(“model:object.property”, “changed”, ...)

and from that moment on, it will keep the state of the properties in the application and the browser synchronized with each other.

If the model needs to be updated by the addition of new attributes (such as new properties, events or methods) a new ApplyModel must be invoked, which will, now that the model has been created, fire a changed event on the model.

on(“model:object”, “changed”, ...)

Finally, if the object is destroyed in the application, the deleted event will be triggered and the object will be destroyed in Javascript too.

on(“model:object”, “deleted”)

This last event will also be triggered when closing the application.

Javascript "Model" Events

The opposite direction: OnPropertyChange(), OnSet() and OnGet() events

When publishing a model, jsRO will keep the created object’s state in the application and the browser side synchronized with each other. Each time a property is updated in the application side, this change fires an event to the browser, where, in addition to updating the value, it can be handled by the corresponding .on(“model:object.property”, “change”, …) event, if it has been declared.

When a property is updated on the browser side, this change is sent in the opposite direction (that is, from the web to the application) and triggers an OnPropertyChange event in the instantiated JSObject object. This  would be a good place to do things like propagating the change of a property’s value to some other element of the application, updating a group of values in a database, etc.

jsRO can also handle changes in its objects’ properties through the declaration of the OnSet and OnGet property events.

By invoking the ApplyChanges method on a JSObject object, its properties collection is traversed and any declared OnGet event is triggered.

Using Property OnGet

Whenever the value of a property is modified in the browser this change is propagated to the same property in the application side. If in the application the modified property has the OnSet event defined with its corresponding callback, the callback will be executed.

Using Property OnSetThe way to add the OnSet and OnGet event handlers to a property is based on their definitions.  It can be done when adding the property or afterwards, but always remember to invoke the ApplyModel method so that the model is propagated to the browser.

The following example shows how the browser can retrieve the application form background color in the #RRGGBB format, and also how to change the background color using a value sent from the browser. Since the desktop application doesn’t interpret colors the same way the web does, we need a conversion that works both ways.

The Delphi code for this example is:

// Creates the remote object
FRo := TJSObject.Create('ro');

// Property definition
FRo.Properties.Add('backgroundColor')
   .OnGet(TJSBinding.Create(
      procedure(const Parent: IJSObject; const Prop: IJSproperty)
      begin
         Prop.AsString := '#'
            + IntToHex(GetRValue(ColorToRGB(Form1.Color)), 2)
            + IntToHex(GetGValue(ColorToRGB(Form1.Color)), 2)
            + IntToHex(GetBValue(ColorToRGB(Form1.Color)), 2);
      end))
   .OnSet(TJSBinding.Create(
      procedure(const Parent: IJSObject; const Prop: IJSproperty)
      var value: string;
      begin
         value := LowerCase(Prop.AsString);
         if ((Length(value) = 7) and (copy(value, 1, 1) = '#')) then
         begin
            try
               Form1.Color := RGB(
                  StrToInt('$' + Copy(value, 2, 2)),
                  StrToInt('$' + Copy(value, 4, 2)),
                  StrToInt('$' + Copy(value, 6, 2))
               );
            except
            end;
         end;
      end));
   ...

Now, let’s see how to achieve this in .Net (C#):

// Creates the remote object
ro = new JSObject("ro");

// Property definition
ro.Properties.Add("backgroundColor")
   .OnGet(new JSBinding(
      // This anonymous procedure do the actual get
      delegate(IJSObject Parent, IJSProperty Prop)
      {
         Prop.AsString = "#"
            + this.BackColor.R.ToString("X2")
            + this.BackColor.G.ToString("X2")
            + this.BackColor.B.ToString("X2");
      }))
   .OnSet(new JSBinding(
      // This anonymous procedure do the actual set
      delegate(IJSObject Parent, IJSProperty Prop)
      {
         string value = Prop.AsString.ToLower();
         Regex reColor = new Regex(@"^#([0-9,a-f]{6})$");
         Match match = reColor.Match(value);
         if (match.Success)
         {
            string color = match.Groups[1].Value;
            this.BackColor = Color.FromArgb(
               int.Parse(color.Substring(0, 2), NumberStyles.AllowHexSpecifier),
               int.Parse(color.Substring(2, 2), NumberStyles.AllowHexSpecifier),
               int.Parse(color.Substring(4, 2), NumberStyles.AllowHexSpecifier)
            );
         }
      }));

To change the background color of the application to red, we just need to assign the property value in Javascript:

ro.backgroundColor = “#FF0000”;

This is the end of our presentation about predefined events and jsRO property setters and getters. In coming installments we will analyze how to work with remote methods and how to define custom events to jsRO object.

 

Cybele Software, Inc. Security Bulletin

Thinfinity Remote Desktop Workstation vulnerability: Summary

Thinfinity Remote Desktop Workstation v3.0.0.3 includes the following vulnerability:

A generic directory traversal flaw was found. After testing both Thinfinity Remote Desktop Workstation version 3.0.0.0 and version 3.0.0.3, the flaw is only present in the later version.

Successful exploitation of this vulnerability could result in the possibility of downloading a file off the remote Windows host (i.e. via the default port 8081 or whichever other port it is configured to use). The flaw was present whether or not “File Transfer” was enabled -regardless of the security mode in use (i.e. None, Digest or Windows Logon).

Note: This vulnerability does not affect Thinfinity Remote Desktop Server.

Continue reading

Implementing Single Sign-On authentication: How to use CAS with Thinfinity® Remote Desktop

security-padlockApplication integration in a web environment could require several instances of authentication, which sometimes can lead to annoying gaffes and mix-ups. Fortunately, the Single Sign On method will help us achieve the unified authentication of these users in a very simple and straightforward way. Let’s see how to implement it in Thinfinity® Remote Desktop.

 

What is CAS?

Central Authentication Service (“CAS”) is an authentication protocol, originally written at Yale University, created to provide a trusted Single Sign On (SSO) method for a web application to validate a user. Its purpose is to permit a user to access multiple applications while providing their credentials (such as user name, password, etc.) just a single time. Once the user is authenticated by an SSO, he/she doesn’t need to render his/her security credentials again.

 

The CASAuth demo

The CASAuth demo, which gets distributed in the product installation, is a simple example you can use to test your CAS authentication environment with Thinfinity® Remote Desktop. You can easily locate it from a shortcut in the Start menu, inside Thinfinity/Remote Desktop Server/Thinfinity Remote Desktop Server Demos. There are some simple but important things you should note along the way, so make sure to follow each step carefully. Let’s start!

In login.aspx.cs you have to replace the CASHOST with the URL of your CAS server. In a testing environment, for example, this might be:

 private const string CASHOST = "https://localhost:8081/cas-server-webapp-4.0.0/";

Make sure you are using a valid certificate so ASP.NET doesn’t reject it. If you don’t have a valid certificate, you can replace the certificate validation function with the following code:

 bool MyServerCertificateValidationCallback(object sender,
      X509Certificate certificate, X509Chain chain,
      System.Net.Security.SslPolicyErrors sslPolicyErrors)
 {
      return true;
 } 

and then assign this function to the ServicePointManager.ServerCertificateValidationCallback:

 ServicePointManager.ServerCertificateValidationCallback = MyServerCertificateValidationCallback;

If everything went as planned, these changes would ensure your CAS server is reached and, in case you are not already logged in, you would be redirected to this server to validate the user.

We now need to make some changes in the Default.aspx.cs page. At this point you have to replace the value of APIKey variable with the appropriate one from your environment. This variable is in the server ini configuration file. (Note: for information on how to find it please refer to: http://www.cybelesoft.com/helps/thinfinity/remote-desktop/server/apikey.html).

Also, you will notice that the dhc.Init method is being called. You have to replace the value passed to this function with the URL needed to reach your Thinfinity Remote Desktop server. Be careful! You need to make this change in the Default.aspx page too:


replacing http://localhost:8443 with the actual URL of your Thinfinity Remote Desktop Server.

Finally, there is a very important setting in this example that needs to be addressed. In Thinfinity Remote Desktop users can get access by using some methods related with the Single Sign On (SSO) feature. Currently, two SSO methods are implemented: Google’s OAuth authentication and Radius authentication. An alternative option is to authenticate directly through Active Directory or using the Windows user authentication.

One of the last lines in Default.aspx.cs states

encQuery = HttpUtility.UrlEncode(dhc.EncodeStr("_userid=" + Userid + "&_apikey=" + APIKey + "&_ssologin=1"));

On that line you have a very important setting: _ssologin. The use cases for this parameter are:

_ssologin=1 The authentication acts as a Google’s Oauth authentication and the Oauth mapping will be used to correctly identify the user.
_ssologin=2 The authentication acts as a Radius authentication and the Radius mapping will be used to correctly identify the user.
Not present If you remove the _ssologin from the string encoding process, the Active Directory or Windows authentication will be used.

(More info at http://www.cybelesoft.com/helps/thinfinity/remote-desktop/server/single-sign-on.html)

With all these settings correctly established, you will be able to use CAS as the authentication method for your Thinfinity Remote Desktop-enabled solution.

Thinfinity® VirtualUI Video: Getting Started with Thinfinity VirtualUI (.Net)

We’d like to invite you to check out our latest video “Getting Started with Thinfinity VirtualUI (.Net)” that can be found in our Thinfinity Google+ page.

 

How to add the VirtualUI library to a .Net application

In this new installment of our video tutorials we show how to add the Thinfinity® VirtualUI™ library to a .Net application and to publish it to be accessed from the Web.

Don’t forget! Check this blog and visit our Google+ page often to find tips, news and videos that will help you get the most out of Thinfinity VirtualUI!

More online content is yet to come!

Please feel free to send us comments or feedback and connect with us on your social network.

Windows and Web integration through Thinfinity® jsRO (Javascript Remote Objects) – Part 2

As stated in our previous article, the jsRO models are created in the application and then transmitted to the browser, where they can be consumed from Javascript through a Thinfinity.jsRO class instance.

To analyze this sequence in more detail, let’s take a look at a couple of complete cases. The next two examples create an “ro” object, which has a “text” property with the value “Hello!”.

In Delphi, in the Create method of the form:

// Creates the remote object and its property
 ro := TJSObject.Create('ro');
 ro.Properties.Add('text');
 ro.ApplyModel;

In C# (.Net Winform application), in the form constructor:

// Creates the remote object and its property
 ro = new JSObject("ro");
 ro.Properties.Add("text");
 ro.ApplyModel();

The ro.ApplyModel call propagates the created object to the browser, where it will be exposed as a javascript object.

In the browser side, to process changes in the replicated object, we have to add the jsRO’s javascript library to the HTML document and write a few extra lines of code.

Let’s see how to work with this object in Javascript:

$(document).ready(function () {
      ...
      ...
      var jsro = new Thinfinity.JsRO();
      var ro = null;
      ...
      ...
      jsro.on('model:ro', 'created', function () {
         ro = jsro.model.ro;
      });
   });

The first thing you can identify in the Javascript example above is how the Thinfinity.JsRO object is instantiated. This object must be created once, and its function is both to keep synchronized all registered models as well as manage all the remote application’s incoming and outgoing messages. So, through the jsro.on(‘model:ro’, ‘created’, ….) event we can get access to the model, a JSON version of the object created at the remote application.

The following is the sequence diagram for the creation of an object:

jsRO object creation

Once the object is instantiated, the only thing that remains is to read and/or write its properties. But, how will we be made aware of the changes produced in the object properties instantiated in the original application?

To address the changes in each model we should add a handler associated with the name of the object, as follows:

// Changes at Model level
jsro.on('model:ro', 'changed', function (obj) {
     alert(“The object ‘ro’ was changed: “ + JSON.stringify(obj))
});

// Changes at property level
jsro.on('model:ro.text', 'changed', function (obj) {
     alert(“The property ‘text’ of ‘ro’ was changed: “ + JSON.stringify(obj))
});

The next line assigns the “newvalue” string to the property text:

jsro.model.ro.text = “newvalue”;

When assigned, the new value for ro.text property is automatically synchronized with the Delphi/C# version of this remotable object.

In the next installment we will see how to work with these properties in a more neat and advanced way through the introduction of getters and setters.

Windows and Web integration through Thinfinity® jsRO (Javascript Remote Objects) – Introduction

One of Thinfinity VirtualUI’s strengths is, without a doubt, its web integration capabilities. Once the app was published, the urge of going beyond simple cosmetic changes usually appears, and one may wish to combine the application with native web resources, such as personalized web searches, multimedia resources, specialized information and data, and the like.

Some other times data just needs to be visually arranged in a different pattern from how it is presented to the user by the original application. Or the interface needs to be replaced or enhanced to better accommodate the device on which it is being accessed, for a more adequate functionality and integration.

Javascript Remote Objects (jsRO) is a framework designed to facilitate these and many other possible scenarios, by allowing a bidirectional communication between a web page or application and a Windows application. But, most importantly, to make that blending with the greatest possible transparency.

The key point is that jsRO enables the creation of objects in a Windows application that can be replicated on the browser as native Javascript objects. Every pair of objects keep in sync with each other on both ends of the communication, and behaves as the same entity. This synchronization ensures bidirectional interaction and therefore immediately replicating changes in the jsRO objects’ properties, both on the browser and the Windows application.

Web integration: jsRO 00 Comunication Model

This communication is made possible by two components: a dll library (Thinfinity VirtualUI SDK) that has to be added to the Windows application, and a Javascript library (Thinfinity jsRo) that must be added to the web page. By adding a few more lines of code to the Windows application, jsRO objects are ready to be created and published on a browser.

jsRO 00 Model Creation And Exposition

The diagram above shows the sequence of how a jsRO object is first created in the Windows application, then propagated, and finally presented on the browser, ready to be used in Javascript. From this point forward, any changes made on any of the objects created will be reflected accordingly on its counterpart.

 

jsRO objects architecture

The jsRO model is based on the creation of an object in the Windows application and its replication as a Javascript object in the browser. Both objects are connected and synchronized, thus enabling a dialogue between the Windows application and the website via Javascript.

A jsRO object can have properties, methods and events: the properties allow for data synchronization through both application and browser sides; the methods make possible the remote calling of application code; and the events help us to fire, from the Windows application, messages to the browser that could to be caught from javascript callbacks.

 

Object Properties

The jsRO object properties are synchronized on both the application and the browser sides. When a property value changes on one end it is spread to the other, firing an event handler that lets you take an action if necessary.

jsRO-00-Properties

 

Remote methods

When a remote method is called on the browser side, it method handler callback is called on the application. Additionally, the returned result value can be processed by a javascript callback.

jsRO-00-Methods

 

Remote events

Remote events allow developers to submit non-visual changes from the application to the javascript side. When the application fires an event, it is transmitted to the browser, enabling the javascript to receive and process it.

jsRO 00 Events

 

Hopefully, this is enough to get you started. In the next post we will learn how to create a jsRO object in our program to expose application’s data in the browser.

Then, in upcoming entries, we will be adding more complexities to leverage this framework to its full potential.

 

Thinfinity® VirtualUI Video: Getting Started with Thinfinity VirtualUI (Delphi)

We’d like to invite you to check out our new video “Getting Started with Thinfinity VirtualUI (Delphi)” that can be found in our Thinfinity Google+ page.

 

How to add the VirtualUI library to a Delphi application

If you are interested in finding tips and videos that will help you get the most out of Thinfinity Remote Desktop and Thinfinity VirtualUI, check this blog and our Google+ page often! We will continue expanding our online content and keep you updated with the latest information.

Please feel free to send us comments or feedback and connect with us on your social network.

Why is it that in certain Delphi applications, minimized windows get lost?

    New here? Read more about why software developers are adopting Thinfinity VirtualUI
    to increase the value of their Windows applications.

 
Thinfinity VirtualUI: Minimized windows get lost when working with Delphi appsWhen the main window is minimized in a Windows application, it is usually replaced by a button on the taskbar.

Minimization in Thinfinity VirtualUI works in a similar fashion, replacing the application window with an icon in the lower left corner of the page. But a problem is found in certain Delphi applications: when minimized, the window is hidden away and the taskbar shows no such icon.

While VirtualUI behaves correctly in this regard, applications developed in this language present the following problem: when the Application.MainFormOnTaskBar property is set to False and an application main window is minimized, this window is in fact hidden but it is not done the proper way.

This is the TApplication.Minimize code:

procedure TApplication.Minimize;
begin
  if not IsIconic(Handle) then
  begin
    NormalizeTopMosts;
    if not MainFormOnTaskBar then
      SetActiveWindow(Handle); // WM_ACTIVATEAPP can set AppIconic to False
      FAppIconic := True;      // Set AppIconic here just to be safe
      DoShowOwnedPopups(False);
      if FMainFormOnTaskBar then
      begin
        if FMainForm <> nil then
          FMainForm.WindowState := wsMinimized
        else
          FInitialMainFormState := wsMinimized;
      end
    else
    begin
      if (FMainForm <> nil) and (ShowMainForm or FMainForm.Visible)
      and IsWindowEnabled(FMainForm.Handle) then
      begin
        SetWindowPos(Handle, FMainForm.Handle, FMainForm.Left, FMainForm.Top,
          FMainForm.Width, 0, SWP_SHOWWINDOW);
        DefWindowProc(Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
      end
      else
        ShowWinNoAnimate(Handle, SW_MINIMIZE);
    end;
    if Assigned(FOnMinimize) then FOnMinimize(Self);
  end;
end;

To fix this problem, the value of this property must be set to True.

program MinimExample;
uses
  Forms,
  VirtualUI_AutoRun,
  MainForm in 'MainForm.pas' {FormMain};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TFormMain, FormMain);
  Application.MainFormOnTaskbar := True;
  Application.Run;
end.

 

With this correction in place, Delphi properly minimizes the application window and the icon is shown on the taskbar as expected.