Document-ID: 30860.1
Subject: CUSTOMIZING LOGON BEHAVIOR
Author: RNIX
Last Modified Date: 04 December 1995
Customizing Logon Behavior
Introduction
============
By default, Oracle Forms will attempt to establish a connection to a
database when starting up a Runform session. If the connect
information (username, password, connect string) is not specified as
parameters to the Runform executable, Oracle Forms will pop up a logon
window.
This bulletin details methods of commonly-asked-for customization of
this logon behavior, including running a form without logging onto a
database, defaulting the connect string, and creating a custom logon
window.
Objective
=========
This bulletin will primarily focus on the On-Logon trigger and the
LOGON built-in. The On-Logon trigger, if defined, replaces the
default logon behavior of Oracle Forms. Within that trigger, the
LOGON built-in actually establishes the connection. If called from
outside the On-Logon trigger, the LOGON built-in calls the On-Logon
trigger.
Running Without a Connection
============================
Forms that do not access any data do not require connections to the
database. By telling Forms not to establish a connection, startup
time is reduced and the operator will not be prompted for connect
information. The following On-Logon trigger eliminates logon
entirely:
On-Logon (Form Level)
NULL;
Small Changes to Default Behavior
=================================
Here is an On-Logon trigger which mimics the default behavior of
Oracle Forms when it performs a connect.
On-Logon (Form Level)
DECLARE
un VARCHAR2(30);
pw VARCHAR2(30);
cs VARCHAR2(30);
upc VARCHAR2(200);
connected BOOLEAN := FALSE;
tries NUMBER := 3;
PROCEDURE get_connect_info IS
BEGIN
un := GET_APPLICATION_PROPERTY(USERNAME);
pw := GET_APPLICATION_PROPERTY(PASSWORD);
cs := GET_APPLICATION_PROPERTY(CONNECT_STRING);
END;
BEGIN
get_connect_info;
IF un IS NOT NULL THEN
LOGON(un, pw||'@'||cs, FALSE);
IF FORM_SUCCESS THEN /* Successful logon */
connected := TRUE;
END IF;
END IF;
WHILE connected = FALSE and tries > 0 LOOP
upc := un||pw||cs;
LOGON_SCREEN;
get_connect_info;
IF upc = un||pw||cs THEN
EXIT;
END IF;
LOGON(un, pw||'@'||cs, FALSE);
IF FORM_SUCCESS THEN /* Successful logon */
connected := TRUE;
END IF;
tries := tries - 1;
END LOOP;
IF NOT connected THEN
RAISE FORM_TRIGGER_FAILURE;
END IF;
END;
Note that the GET_APPLICATION_PROPERTY(CONNECT_STRING) will not work
in versions prior to 4.0.13 of Oracle Forms. In prior versions, the
connect string is part of the password.
Small deviations from the default connect behavior can be accomplished
by modifying this code:
* To allow more or fewer logon attempts, increase the initial value of
the counter variable, tries.
* To default the connect string, change the calls to LOGON from:
LOGON(un, pw||'@'||cs, FALSE);
to use a hard-coded connect string:
LOGON(un, pw||'@<connect string>', FALSE);
* These lines can also be modified to hardcode username or password.
Hiding the Logon Information
============================
For security reasons, many customers do not want their users to be
able to access the database except through the forms. One way to do
this is to have the form handle connecting to the database, which
keeps passwords away from the users. In V7, the best way to do this
is to have the form set role to a privileged role. However, a quick
and dirty way to do it is to have the form connect to a privileged,
secret ORACLE account.
The following On-Logon trigger establishes a connection using
hard-coded values for username and password. Users will be able to
connect to the database without knowing the account or password:
On-Logon (Form Level)
LOGON('SCOTT','TIGER@T:MYHOST:V716');
Deferring Logon
===============
Connection can be deferred until later in the Forms processing.
On-Logon (Form level)
DECLARE
un CHAR(30);
pw CHAR(30);
cs CHAR(30);
BEGIN
DEFAULT_VALUE('N','global.logon_now');
IF :global.logon_now = 'Y' THEN
LOGON_SCREEN;
un := GET_APPLICATION_PROPERTY(USERNAME);
pw := GET_APPLICATION_PROPERTY(PASSWORD);
cs := GET_APPLICATION_PROPERTY(CONNECT_STRING);
LOGON(un, pw||'@'||cs);
END IF;
END;
When the form starts up, it will not try to log on since the flag
logon_now will be defaulted to N. When you do wish to log onto the
database, use the syntax:
:global.logon_now := 'Y';
LOGON(NULL, NULL);
This sets the flag to Y and causes the On-Logon trigger to fire, so
the form connects to the database.
Customizing the Logon Screen
============================
The built-in LOGON_SCREEN calls up the default Forms logon screen to
capture the username, password, and connect string. However, you can
also use a customized logon screen. The following tutorial creates a
form which can be used as a replacement logon screen from any form.
NOTE: Coordinate System is assumed to be pixel.
1. Create a new forms module and change only the following properties:
Name: LOGON
Title: LOGON (v4.5)
2. Modify only the following properties for WINDOW0
(v4.0, Create this window):
Name: LOGON_WINDOW
Width: 126
Height: 108
Title: Logon
Style: Dialog
Modal: TRUE
Fixed Size: TRUE
Iconifiable: FALSE
Inherit Menu: FALSE
Zoomable: FALSE
3. Create a new canvas (v4.0, Modify CANVAS0) and modify only the following
properties:
Name: LOGON_CANVAS
Window: LOGON_WINDOW
Width: 126
Height: 108
4. Modify only the following properties for LOGON_WINDOW:
View: LOGON_CANVAS
5. Create a new block and modify only the following properties:
Block Name: LOGON_BLOCK
6. Create three text items on canvas LOGON_CANVAS for block LOGON_BLOCK
with properties as follows:
Name: USERNAME
X Position: 12
Y Position: 8
Width: 102
Height: 18
Name: PASSWORD
X Position: 12
Y Position: 31
Width: 102
Height: 18
Secure: TRUE
Name: CONNECT
X Position: 12
Y Position: 54
Width: 102
Height: 18
7. Create two push buttons on canvas LOGON_CANVAS for block LOGON_BLOCK
with properties as follows:
Name: LOGON
X Position: 12
Y Position: 84
Width: 52
Height: 18
Label: Logon
Mouse Navigate: FALSE
Default Button: TRUE
Name: CANCEL
X Position: 72
Y Position: 84
Width: 52
Height: 18
Label: Cancel
Mouse Navigate: FALSE
8. Code the following program units:
PROCEDURE leave(status BOOLEAN DEFAULT TRUE) IS
BEGIN
IF status THEN
:global.logged_on := 'TRUE';
ELSE
:global.logged_on := 'FALSE';
END IF;
EXIT_FORM;
END;
PROCEDURE initialize_form IS
un VARCHAR2(30) := GET_APPLICATION_PROPERTY(USERNAME);
pw VARCHAR2(30) := GET_APPLICATION_PROPERTY(PASSWORD);
cs VARCHAR2(30) := GET_APPLICATION_PROPERTY(CONNECT_STRING);
BEGIN
DEFAULT_VALUE('3', 'global.logon_tries');
DEFAULT_VALUE(un, 'global.username');
DEFAULT_VALUE(pw, 'global.password');
DEFAULT_VALUE(cs, 'global.connect_string');
:logon_block.username := :global.username;
:logon_block.password := :global.password;
:logon_block.connect := :global.connect_string;
END;
FUNCTION connect_to RETURN BOOLEAN IS
BEGIN
IF :logon_block.username IS NULL THEN
BELL;
END IF;
LOGON(:logon_block.username,
:logon_block.password||'@'||:logon_block.connect, FALSE);
IF FORM_SUCCESS THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END;
9. Code the following triggers:
On-Logon (Form Level)
LOGON(:logon_block.username,
:logon_block.password||'@'||:logon_block.connect,
FALSE);
When-New-Form-Instance (Form Level)
initialize_form;
When-Button-Pressed (Item Level, on LOGON_BLOCK.CANCEL)
leave(FALSE);
When-Button-Pressed (Item Level, on LOGON_BLOCK.LOGON)
BEGIN
IF connect_to THEN
leave(TRUE);
END IF;
:global.logon_tries := TO_NUMBER(:global.logon_tries) - 1;
IF TO_NUMBER(:global.logon_tries) = '0' THEN
leave(FALSE);
END IF;
END;
When-Window-Activated (Form Level)
DECLARE
screen_height NUMBER;
screen_width NUMBER;
window_height NUMBER;
window_width NUMBER;
BEGIN
IF :SYSTEM.EVENT_WINDOW = 'LOGON_WINDOW' THEN
screen_height := GET_APPLICATION_PROPERTY(DISPLAY_HEIGHT);
screen_width := GET_APPLICATION_PROPERTY(DISPLAY_WIDTH);
window_height := GET_WINDOW_PROPERTY(:SYSTEM.EVENT_WINDOW, HEIGHT);
window_width := GET_WINDOW_PROPERTY(:SYSTEM.EVENT_WINDOW, WIDTH);
SET_WINDOW_PROPERTY('LOGON_WINDOW', X_POS,
(screen_width - window_width)/2);
SET_WINDOW_PROPERTY('LOGON_WINDOW', Y_POS,
screen_height/2 - window_height);
END IF;
END;
10. Generate and save this form.
11. Create a new form. This form is an example of how to use the
logon form that has just been created.
12. Create a default block, giving this form some items.
13. Code the On-Logon trigger as follows:
On-Logon (Form Level)
CALL_FORM('logon', NO_HIDE);
IF :global.logged_on != 'TRUE' THEN
RAISE FORM_TRIGGER_FAILURE;
END IF;
This will complete the coding for the main form. When the form now
requires a connection to the database, it will use this customized
logon screen instead of the Forms default one.