PFC Idle Service
Contributed by Bruce Armstrong
You may have security requirements to suspend a user session if they leave the application inactive for a certain period of time, and to require re-authentication of the user when they attempt to use the application after that period. This service allows you to implement such a requirement with a few lines of code.
When the service is implemented, it minimizes the MDI frame if the application is left idle past a preset amount of time. When the user attempts to reactivate the MDI frame, they are prompted to re-enter the password they used to connect to the database. The dialog that appears also provides the option to terminate the application.
To add the service into the PFC framework (you only do this once):
- Declare a public instance variable of the n_cst_idle class:
- Create a public local external function of_setidle as follows:
// public function integer of_setidle (boolean ab_switch)// Check arguments If IsNull(ab_switch) Then Return -1 End IfIF ab_Switch THEN IF IsNull(inv_idle) Or Not IsValid (inv_idle) THEN inv_idle = CREATE n_cst_idle Return 1 END IF ELSE IF IsValid (inv_idle) THEN DESTROY inv_idle Return 1 END IFReturn 1
- Add code to the pfc_idle event to call the service:
IF IsValid (inv_idle) THENinv_idle.of_deactivate ( )END IF
b. Extend n_cst_platform:
Add a public local external function of_findwidow which takes two arguments, the window name and the window type to look for. Because it takes different arguments than the ancestor function, it overloads rather than overrides that function. (The primary reason we do this is because the current PFC function uses the wrong classname to search for windows in PB6). At this level, we want to make it a 'virtual' function, in that it only returns an error code:
// public function unsignedlong of_findwindow (string as_window_name, // windowtype ae_windowtype)Return -1
c. Extend n_cst_platformwin32:
Add a public local external function of_findwidow which takes two arguments, the window name and the window type to look for. Because it takes the same arguments than the ancestor function, it overrides that function. Use the following code in that function:
// public function unsignedlong of_findwindow (string as_window_name, // windowtype ae_windowtype)ulong lul_whnd string ls_classnameCHOOSE CASE ae_windowtype CASE response! ls_classname="FNWNS360" CASE ELSE ls_classname="FNWND360" END CHOOSElul_whnd = FindWindowA( ls_classname, as_window_name)return lul_whnd
d. Extend w_frame:
i. Declare a custom user event mapped to the pbm_queryopen message ID. The name you give the event is immaterial, however for convenience I suggest naming it "queryopen". This is the event that is called when an MDI application has been minimized to the task bar.
ii. Add the following code to that event:
IF IsValid (gnv_app.inv_idle) THEN message.Processed = gnv_app.inv_idle.event queryopen() END IF
The application minimizes when it suspends the user. This code tells the frame not to allow itself to become unminimized if the user has been suspended and they do not re-authenticate themselves correctly.
iii. Add the following code to the activate event:
IF IsValid (gnv_app.inv_idle) THEN gnv_app.inv_idle.event activate() END IF
An MDI frame does not receive the queryopen event if there is a response window open. This code checks for that situation and deals with it.
OK, that was the tough part. Now for the easy part.
To implement the service for a particular application (you do this on an application by application basis):
Add code to the pfc_open event of the application specific descendant of n_cst_appmanager, after the user has logged in and the MDI fame has been opened, to set up the service:
this.of_SetIdle ( TRUE ) IF IsValid ( inv_idle ) THEN inv_idle.of_Register ( 300 ) END IF
When calling the register function, pass the number of seconds that you allow the application to be inactive before the user is suspended.
Optionally, you may also do the following:
a. To disconnect the user from the database:
By default, the service only minimizes the MDI frame and does not allow it to be reactivated until the user re-authenticates themselves. If you also wish to disconnect the user from the database, make this additional call:inv_idle.of_SetDisconnectDatabase ( TRUE )
The user will be reconnected to the database during the re-authentication process if they re-authenticate correctly.
NOTE: As of this writing ( PB/PFC 6.5 ), disconnecting the user from the database seems to cause problems with the PFC security service once the application is re-activated. It appears to be a PB internal bug in which a datastore will lose its reference to the transaction object assigned to it if you disconnect and reconnect that transaction object. It has been reported to Sybase as issue number 41017889.
b. To make the authentication password case-sensitive:
If database disconnection has been implemented (see above), the service will attempt to re-connect to the database in order to re-authenticate the user. In that case, the case-sensitivity of the password depends on the target database.
If database disconnection has not been implemented, the service performs a case insensitive comparison between the password entered and the password used for the existing database connection. If you want that comparison to be done on a case sensitive basis, make this additional call:
inv_idle.of_SetCaseSenstive ( TRUE )
c. To manually suspend the user:
The users may wish to have an option to manually suspend themselves. For example, the user might know they would be leaving their workstation for a period of time and wish to protect the data they are currently working with from unauthorized access. To provide this option, add a menu/toolbar item that makes this call:inv_idle.of_Deactivate ()
d. To manually reactivate the user:
I actually can not think of an instance where you might want to do this, but in case you do, you can make this call:inv_idle.of_Reactivate ()
This will not reactive the user, it will simply display the dialog box that the user needs to complete in order to re-authenticate.
|Download the||About the extension contributor|
|10/26/1998||Initial Revision||Ver. 1.00|
Interested in contributing material to this web site? Send an email to email@example.com, but don't forget to check the contribution guidelines first.
For information or suggestions about this web site please contact firstname.lastname@example.org
sponsored by Dynamic Technology Group.
The information on this site is provided for advice only and not to be considered a contract or a liability against Dynamic Technology Group.