rendering ...

Overview

Triangular uses a server to store data and provide User authentication services.

Section Google App Engine Implementation describes the implementation used by the Apps Examples and the Tutorial Examples

Should another implementation be required, section Building Another Implementation gives untested steps for doing this.

Requirements

At is minimum the server must provide:

Customer Notion

Each application has a unique alphanumeric id such as "deps" that is used to reference the application on the server. This is set with the servGAE.setCust and usually defined in the appname-js file.

It is used to construct the key used to access Data Objects and User Records.

The result of this design is that a single server instance can host many applications each with an independent admin function and pool of Data Objects.

SuperUser Notion

The SuperUser is a special User Record that controls the applications and AdminUser on the server.

Token

The token is an integer created during the servGAE.login process and stored in the User Record on the server and returned to the Triangular infrastructure during the servGAE.login process. All commands except the ajaxLogin command that are sent to the server must include this token.

It is used on the server to validate each request that there is a proper authenticated session established between the User and the server.

Key Structure

The key structure is a 3 part key, each part separated by the "/" character and concatenated into a single string.

The first part defines the application.

The second part defines the record type allowing an application to have several record types.

The third part defines the record or group of records key.

This is defined in more detail in the Record Key Structure

Google App Engine Implementation

The implementation uses a version of the BBB WebServer Framework. (Note: This link is included for reference. At this point there is no need to examine too closely the capabilities of the "BBB WebServer Framework"). One application, namely the CITA application, was added to the BBB standard framework. This CITA application provides the required functionailty given in Requirements and can be used unmodified to host any number of applications.

The Tutorial Examples explains how to obtain and install a version on your own Google App Engine account.

This BBB WebServer Framework implementation has much functionality that is not required for Triangular. However, it was there and in the interest of expediency was used rather than spend development time creating a streamlined version to just support the Triangular required functionailty.

The BBB WebServer Framework has been optimized for the GAE Site environment. Triangular exploits this design during the Login Page Load in doing an asynchronous request that warms up a possibly paged out server. This warming up is done while the user is entering the login information and will give good response to the login request.

The code for the CITA application is purposely omitted from the source code provided for Triangular. The reason is that it contains some code that if divulged would make the server less secure. Should someone be interested in building an alternate server the author can be contacted at Steve P Pritchard.

Node.js Implementation

Included in the download is a file tri-server.js and run-tri.bat. These implement the protocols descibed in the following sections. The first strategy described in Building Another Implementation was utilized. The implementation is described at NodeJS Server. The implementation of the datastore is described in Datastore NodeJS.

Command Set

The method invoked is obtained by passing in the verb name in the ajaxMeth property of the request block (see Request Format). Most often there is a one-to-one correspondence with a servGAE method.

For each command (apart from ajaxLogin) the token is provided in the request block and validated against the one stored for the User on the server. The ajaxLogin actually sets a new token value in the User record.

ajaxLoginUsed to log a user into the system. See servGAE.login.

The user names(s) provided are validated against the Users in the Request Format and a good or fail response is returned. For a good response the new calculated token value is stored in the User record

ajaxValidateTokenUsed to validate whether a token is stale or not. See servGAE.validateToken. A good or fail response is returned.

ajaxChangePasswordUsed by the User to change his/her password. See servGAE.changePassword. The old and new passwords are included in the request block.

Note: Passwords must contain at least one alphabetic character to distinguish them from the encrypted value stored on the server. Internally the server checks the encrypted password stored on file against the value provided that is passed through the same encryption algorithm.

ajaxSendCitaDataUsed to update a record or block of records. If the key record does not exist a new key/data pair is created. See servGAE.putKeyData. A good or fail response is returned.

ajaxFindCitaDataUsed to retrieve the headers for a group of records. It can also be used to return the contents of a specific record. See servGAE.issueFindFile. A good or fail response is returned. It can contain a group of record headers.

ajaxFindUserDataUsed to retrieve the headers for a group of User records. It can also be used to return the contents of a specific User record. It requires that the User have admin authority. See servGAE.issueFindFile. A good or fail response is returned. It can contain a group of record headers.

ajaxDeleteKeyUsed to delete a specific record from the server. See servGAE.dropObj. The request block contains the 'GekID' of the record to be dropped. A good or fail response is returned.

ajaxReadCitaData Used to retrieve the data for a record or block of records based on the key of the record. See servGAE.getKeyData. A good or fail response is returned.

SuperUser Command Set

Note that for this command set the SuperUser ID and password must be provided in the auth section of the Request.

This command set is used by the WAKS Utility Program.

ajaxWaksFindCitaDataUsed to retrieve the headers for a group of records. See servGAE.issueFindFile. A good or fail response is returned. It can contain a group of record headers.

ajaxWaksSendCitaDataUsed to update a record or block of records. If the key record does not exist a new key/data pair is created. A good or fail response is returned.

ajaxWaksReadCitaData Used to retrieve the data for a record or block of records based on the key of the record. A good or fail response is returned.

This command set requires a gems/boot/ajax.ajax URL request signature. The first does not require a SuperUser ID or password. They are used by the Prime.htm system file used to initialize the server Datastore.

ajaxValidateStoreUsed to test the presence of the Datastore control record indicating it has been primed. If found a GOOD Response is returned. Otherwise a FAIL Response is returned.

ajaxPrimeStoreIf the server is not primed a control record is created and SuperUser created using the provided SuperUser ID and password in the Request. A GOOD Response is returned.

Otherwise a FAIL Response is returned.

ajaxSuperLoginIf the provided SuperUser ID and password in the Request match the existing SuperUser record a GOOD Response is returned.

Otherwise a FAIL Response is returned.

ajaxAddAdminUserIf the provided SuperUser ID and password in the Request match the existing SuperUser record an AdminUser is created with the information in the Request. A GOOD Response is returned.

Otherwise a FAIL Response is returned.

ajaxListAppsIf the provided SuperUser ID and password in the Request match the existing SuperUser record a GOOD Response is returned. In addition the response returns a list of applications and their AdminUser IDs.

Otherwise a FAIL Response is returned.

Request Format

The Request Object is constructed as properties within a Javascript Object and sent as a JSON stringified rendition of that object. On the server a Java JSONObject is created from the JSON stringified rendition and used to process the command request. The browser console.log may be examined to see the fine details of each request block. It is recognized with a 'AJAX.AJAX.AJAX' string in the browser console window.

An example structure is:

   AjaxID: "AngJS.100"              // An id used for debugging to correlate server side
                                    // and browser side requests
   EXEC: {                          // The 'EXEC' block
     ajaxMeth: "ValidateToken"      // The command to invoke less the 'ajax' prefix
     auth: {                        // The authorization block
       cust: "deps"                 // The application (customer) the request is for.
       token: "3104379893"          // The current token
       user: "user_name"            // The User name
     }
     payload: {                     // Specific data such as the data to write
       ...
     }
   }

For the cust: value refer to See cust and key

For the token: value refer token

For the user: value refer User name

Response Formats

The Response Object Format is constructed on the server as properties within a Java JSONObject. It is transmitted as a JSON stringified rendition of that object. In the browser the Triangular response handler renders this into a Javascript object.

The browser console.log may be examined to see the fine details of each response block. It is recognized as a log output statement that follows the initiating 'AJAX.AJAX.AJAX' statement. Since these are run asynchronously care must be taken to correlate the correct response.

The following example give the general structure of the response:

  RESULT: {                                    // result block
    DataStat: {                                // Data block
      CODE: "found"                            // indicator of command success
      RECORD: [...]                            // The record or array of records
      STATUS: "OK"                             // command status
    }
    PROFILE: {...}                             // For 'ajaxLogin' and `ajaxValidateToken'
                                               // the user profile for local customization
    STATUS: "OK"                               // command status
    status: "GOOD"                             // success or failure indicator
    status-message: "validate OK"              // processing message
    status-ts: "2013-09-29 09:46:28 0.031ms"   // processing timestamp
  }

Building Another Implementation

This section presents the high level strategy that could be used to build another server implementation. This has not been done and is therefore hypothetical.

One of two strategies could be used.

  1. Direct the servGAE to a site that implements the same Request Format/Response Formats and internally implements the same Command Set.

  2. Replace servGAE with a new protocol and command structure directed at a server with an entirely different protocol. This could be achieved by replacing the servGAE function call handlers with a new set. See the oFuncs object.