Novell is now a part of Micro Focus

IntranetWare Solutions: Using NetBasic to Build a Collaborative Web Site

Articles and Tips: article

PHIL KARREN
Solutions Manager
Novell Vertical Marketing

JIM THATCHER
Software Engineer
Management Products Division

STEVE PIERSON
Product Manager
Developer Services Division

01 Nov 1996


Shows how to build an Intranetware-based custom solution. Introduces a collaboroative Web site which runs on IntranetWare, called Intrasession.

Introduction

This article will show you how you can build an IntranetWare-based custom solution, using a running prototype as an example. We will introduce you to a collaborative Web site which runs on IntranetWare, called Intrasession. We will show you the details of its implementation, and how the pieces of IntranetWare fit together.

If you are developing custom or general-purpose solutions, this article will help you. Whether you are already a seasoned Webmaster, or if you are creating your first Web site, this article will help you create a powerful Web site on IntranetWare.

Intrasession, a collaborative Web site, runs on IntranetWare and demonstrates the power of Net2000.

IntranetWare gives you all the services you need to build a full-service intranet platform: file, print, directory, messaging, Web publishing, security, connectivity and management. Following are some of the components of IntranetWare (for more information, see http://www.novell.com/intranetware):

  • Network OS: NetWare4.11 (OS, network services including NDS, NWAdmin, Novell Application Launcher (NAL) and more).

  • Web access: NetWareWeb Server 2.5, Netscape Navigator

  • Protocols: IP protocol support

  • Development: NetBasic

  • WAN access: NetWare Multiprotocol Router

Net2000, a framework for developing network solutions, has the following goals: enhance NetWare as a development platform; expose the functionality of network services, including NDS; establish NDS as the core service for managing distributed objects; provide interfaces for creating intranetworking solutions; integrate development interfaces to Novell's GroupWise; and provide a consistent set of programming interfaces and documentation.

Net2000 is exposed through four development models: 1) scripting, including NetBasic; 2) Java; 3) Rapid Application Development; 4) C and C++. This article will cover the first item, NetBasic.

NetBasic is a basic runtime environment which ships with and runs on IntranetWare. Novell's partner, HiTechSoft created NetBasic. The NetBasic syntax is compatible with Visual Basic. There is an infinite variety of solutions which developers can create with NetBasic running on IntranetWare. However, in this article, we will cover just one aspect of NetBasic: creating custom, dynamic Web sites.

HitechSoft also provides Visual NetBasic, a Windows-based development environment for creating NetBasic scripts. The environment provides editors, online language documentation, debugging tools, and a client execution environment. HiTechSoft also provides the NetBasic runtime environment for NetWare 3. For more information, refer to http://Hitechsoft.com.

Intrasession: A Collaborative Web Site

Utah Governor Michael Leavitt initiated a project called SmartUTAHTM and told its leaders to find new ways to get government, business, and individuals in the state networked. SmartUTAHTM used the assistance of industry partners (Novell, AT&T, USWest, IBM, and others) to achieve its goals. As a result of its work with SmartUTAHTM, Novell created Intrasession: a collaborative Web site which runs on IntranetWare, implemented in NetBasic. Intrasession provides functionality for discussion forums, group calendar, group survey, and site administration. Intrasession is an example of what Novell calls a "community intranet": a network which allows people in government, business, and the public to work together securely.

Figure 1: Community Intranets.

Figure 2: Intrasession.

Intrasession relies on a number of components from IntranetWare. In addition, it stores its collaborative information in an Oracle database.

Figure 3: Intrasession Components.

Intrasession: Looking Under the Hood

Intrasession is implemented as a collection of NetBasic, HTML, graphic, and map files. In total, there are well over 100 of these. In this article we will walk you through enough of these files to give you the idea of how it works. Here's the order we will cover things:

  1. Building Web pages in HTML

  2. Generating HTML pages with NetBasic. For each script, we will look at the output in the browser, the NetBasic source, and details related to that code. We will look at partor all of three NetBasic scripts: Smtlogin.bas, Smtmain.bas, and Grpmain.bas.

Getting Started: HTML and URLs

Markup languages have been around even longer than word processors, and documentors have used them for years. However, bringing markup language documents, the Internet, document links, and browsers together created an explosive combination: the World Wide Web.

Web browsers, such as the Netscape Navigator, parse, format, and render HTML source on the user's screen. Web servers, such as NetWare Web Server, deliver HTML to the browser in a protocol called HyperText Transfer Protocol (HTTP). Usually, Web servers and browsers communicate their HTTP protocol information over the network via the Transmission Control Protocol/Internet Protocol (TCP/IP).

Most Web servers provide a mechanism which allows custom processes to generate HTML dynamically. This is called the Common Gateway Interface (CGI) and it provides a means of accessing non-HTML information, and also for creating interactive pages. CGIs invoke a separate process which reads information from a data repository and generates HTML documents dynamically. Once the HTML is generated, the Web server can serve that information to the requestor.

It is possible to create an HTML document using any text editor. However, there are a number of authoring tools which will generate HTML output from more sophisticated authoring tools, including most popular word processors. For more details on HTML definition, browse this URL: http://www.ncsa.uiuc.edu/General/Internet/WWW/HTMLPrimerAll.html#GS

One powerful feature of HTML is that it allows for links to other documents. Using links, you can connect all sorts of related information and software. From the browser, users decide what information they want to see by selecting the appropriate links.

In order to be linked, documents must have names. Web information is identified by its Uniform Resource Locator (URL -- frequently pronounced "Earl"). URLs can refer to just about anything: files, Gopher files, HTTP documents, new servers, databases, and more. For details on the URL syntax, see "A Beginner's Guide to URLs," at: http://www.ncsa.uiuc.edu/demoWeb/url-primer.html

Let's take a look at an HTML file in Intrasession. The Intrasession home page This page allows the user to login, register as a new user, or log in as a guest.

Figure 4: Intrasession Home Page.

The HTML source for this page is defined in the file index.htm, in Figure 5. This is the source which browser is reading and formatting (and which the browser got from the NetWare Web Server). We don't need NetBasic to implement this page because it's always the same-it's a static page.

Figure 5: Index.htm.

<!-- Home page definition document for Intrasession -->
<!-- Copyright 1996 Novell, Inc. All rights reserved --> 
<!-- Document Header --> 
<HTML> 
<HEAD> 
<TITLE> 
Intrasession 
</TITLE> 
</HEAD> 
<!-- Document Body --> 
<BODY bgcolor=#FFFFFF rgb='#ffffff' link='#0000ff' vlink='#0000ff'> 
<CENTER> 
<!-- Logo and login options graphic --> 
<A href="/maps/smtsite.map"><IMG border=0 width=516 height=219 
src="/images/smtsite.gif" ISMAP></A> 
<BR> 
<!-- Alternate links for logging in --> 
[<A HREF="/NetBasic/Smtlogin.bas">Member Login</A>] 
[<A HREF="/NetBasic/guest.bas">Guest Login</A>] 
[<A HREF="/newreg.htm">Register Now</A>]<BR> 
<P>Set your bookmark Here</P> 
</CENTER> 
</BODY> 
</HTML>

A Walk Through Index.htm

HTML, like any other markup language, consists of tags and text. The tags define the portions of a document so that a formatter (such as a browser) can determine how to present the information in the document. To understand index.htm, we need to understand some basics of HTML tags. As we already stated, the tags describe information in the document, and browsers format the information based on the document tags.

There are some basics you should know about HTML tags:

  • Tags are marked by angle brackets: <<.

  • All HTML tags come in pairs, marking the beginning and end of the desired text. Ending tags are marked by a slash:/.

  • Tags pairs can be nested.

  • Tag pairs cannot overlap.

  • There are a few mandatory tags which every HTML document must contain, and there are many more optional tags.

  • Tags come in two flavors: logical and physical. More on this later.

There is a good way to get a better feel for HTML. With the Netscape Navigator, you can select the View menu and the Document Source submenu. This displays the HTML source for the screen. Try it out. Let's walk through index.htm and understand its tags. Here are the first lines in the file:

<!-- Home page definition document for Intrasession --< <
<!-- Copyright 1996 Novell, Inc. All rights reserved --< <
<!-- Document Header --<<

These are comments, which the browser will ignore. Comments are marked as <!-- --<.

The following lines are all mandatory tags:

<HTML> 
<HEAD> 
<TITLE> 
Intrasession 
</TITLE> 
</HEAD>

<HTML< states that this is an HTML document. Note that there is a corresponding </HTML< tag marking the end of the pair at the end of the document. All other tags are nested inside this tag pair. Every HTML document must have a header, marked with the <HEAD<</HEAD< pair. Nested in the header is the title, marked as <TITLE<</TITLE<. The title is "Intrasession," and it will be displayed in the browser title bar.

This line:

<BODY bgcolor=#FFFFFF rgb='#ffffff' link='#0000ff' vlink='#0000ff'>
<CENTER<

marks the beginning of the document body. The parameters indicate color preferences for the background and links, and override the default colors the browser would normally display. The next tag, <CENTER<, is a format tag, and directs the browser to center all information inside the pair on the center of the screen. Now we can place the bitmap:

<A href="/maps/smtsite.map"><IMG border=0 width=516 height=219 
src="/images/smtsite.gif" ISMAP></A> <BR>

This set of tags is a little tougher to follow. The <A< tag indicates a link to another document. If the user clicks on the link, the document corresponding to the link gets served up. Tags can have parameters. The link tag, <A<, has a mandatory parameter (HREF=" ") stating the location of the link. This link refers to a bitmap file, smtsite.map. A bitmap makes it possible to have several links on the same graphic. The bitmap file defines regions of the graphic, and states the links these regions refer to. The browser uses the bitmap to determine what to serve up next. (See Figure 6.)

Nested in the link pair is another tag that refers to a graphic: <IMG<. This tag also has parameters for the size, border preferences, and name of the graphic file. Here, SRC="/images/smtsite.gif" refers to the graphic file.

To add some white space after the graphic, we have added a formatting instruction: <BR<. This tells the browser to insert a blank line. Since the graphic may take a long time to transmit across the network, we have also provided text links to the same locations available from the graphic:

<!-- Alternate links for logging in --> 
[<A HREF="/NetBasic/Smtlogin.bas">Member Login</A>] 
[<A HREF="/NetBasic/guest.bas">Guest Login</A>] 
[<A HREF="/newreg.htm">Register Now</A>]<BR>>

Again, you can see the <A< tag and its HREF parameters which refer to the link locations. Notice that two of these links refer to NetBasic files (Smtlogin.bas, guest.bas) and one refers to an HTML file. Later on, we will look at Smtlogin.bas. Next, we have a simple paragraph:

<P>Set your bookmark Here</P>

This tag pair marks a paragraph. All text inside the pair is formatted and wrapped appropriately. At the end, we terminate all the tag pairs:

</CENTER>
</BODY>
</HTML>

Map File

This is the map file which defines the regions of the image, and what links correspond to those regions.

Figure 6. Map file: smtsite.map.

default   /lcgi-bin/Web1/Smtlogin.bas
rect   /lcgi-bin/Web1/Smtlogin.bas 224, 104   480 139
rect   /lcgi-bin/Web1/guest.bas     223, 141 479, 168
rect   /newreg.htm  224, 171 480, 207

There are many more tags available in HTML, and each succeeding standard adds more. Other tags define tables, lists, quotations, and more.

As we mentioned earlier, there are two kinds of tags: logical and physical. Logical tags define what text is, and leave the formatting up to the browser. Most of the tags in index.htm are logical tags. In general, logical tags are considered to be preferable. Logical tags are better, the guidelines say, because they are more portable across browsers. This, in turn, makes them easier to maintain.

Physical tags prescribe specific output behavior. In index.htm, <BR<and <CENTER< are the only physical tags. One should use physical tags with care since the results may vary on different browsers and screen sizes.

Summary Information for Index.htm

Index.htm is an HTML file, consisting of tags and text. The server serves the HTML to browsers, which format the text and present it to the user. Here are the HTML tags in index.htm, and their purpose:


Tag
Purpose

<HTML>

Indicatesthat this is an HTML document.

<HEAD>>TITLE>

Thedocument header, which contains informationabout the document. In this case, the only headerinformation is the title. The title text shows up in the browser title bar.

<BODY>

Marksthe beginining of the main portion of the document. The optional parameters overridethebrowser color defaults (for example, browsers default to a grey background).

<CENTER>

All information inside this tag pair will be centered.

<A>

A link to another page. There are four linksin this document: three to other pages, and one link toan image map. The first link isto a map: smtsite.map. The map defines links for specific regions ofthe image. Dependingon where the user clicks, the appropriate link is invoked. The map file is ina figurebelow. Two links invoke other NetBasic scripts, and the last link invokes another HTML file.

<IMG>

There are two of these in the file. IMG pulls in a GIF file image.

<P>

This denotes a paragraph.

<!-- -->

Comments

Here are some of the components index.htm brings together:

  • HTML document: Image.htm is the home page for the Web site. When a user requests the Web site from the browser, the Web server delivers this file. The browser formats it based on the tags in the document.

  • Graphic File: The primary feature of this page is a large graphic. This graphic is contained in file intradev.gif.

  • Map File: Smtsite.map associates regions in the graphic with specific links to other pages. The user can click on different areas of the graphic for different results.

  • Links: There are three links on this page. Two are to NetBasic scripts (Smtlogin.bas and guest.bas). One, newreg.htm, is to a static HTML page.

Moving on-NetBasic Scripts

Now that we have covered the basics, let's get down to some NetBasic code. NetBasic can be used to create a wide variety of server solutions, but this article will focus on how you can use it to create Web pages.

NetBasic scripts provide you with flexibility by allowing your site to generate custom HTML interfaces on demand. Intrasession consists of hundreds of NetBasic scripts, but by examinging three scripts, you will get the idea. The three scripts are Smtlogin.bas, Smtmain.bas, and Grpmain.bas. For each script, we will show the Intrasession screen, the NetBasic script source, and the generated HTML source. We will also enumerate the concepts associated with the code.

Smtlogin.bas-Getting Started

Selecting the "Member Login" button from the home page (see Figure 2) brings up the page shown in Figure 7. The HTML source for this page was generated by the NetBasic script Smtlogin.bas.

Figure 7: Login to Intrasession.

This is a simple NetBasic script, and it could actually be implemented in HTML. However, it's a great way to get a feel for what NetBasic can do before we get more complicated.

NetBasic and the Web Server

Invoking NetBasic Scripts

Smtlogin.bas is invoked when an Intrasession user clicks on the "login" link from the home page, either from the bitmap, or from the text link. The Web Server gets the request, and invokes the script via the CGINMX pair. The script runs, generates more HTML tags, and exits. The Web Server sends the new HTML doc to the Intrasession user. The user's browser formats the new HTML doc on the user's browser screen.

NetBasic Libraries

Using the Net2000 Network Modular eXtension (NMX), NetBasic provides an extensible library interface. Developers can create libraries for network services, user interface control, system interfaces, and more. Libraries are named by uppercase letters, and contain a hierarchy of functions. The syntax for calling these libraries is as follows:

<LIBRARY NAME<:<Function call<[:<function call<]...

For example, the following library call generates an HTML heading tag:

DOC:Heading("Login to Intrasession")

Following are some of the libraries currently available in NetBasic:

System Libraries


FunctionLibrary
Description

COM

Read and write to serial port.

DATE

Get system date and time.

DIR

Enumerateand manipulate directories on the server volumes.

FIO

Performfile operations: open, close, read, write, seek, etc.

INI

Readand write to an INI file.

KEY

Get keyboard input.

LPT

Managethe serverattached printer (network printer calls are part of the NET library)

PORT

Readand write to specific server ports.

RPC

Runan external process. For example, call another NetBasic program.

SYS

Makemiscellaneous system calls-invoke NLMs, getcommand line params, system time, etc.

Web Libraries


FunctionLibrary
Description

DOC

GenerateHTML tags and content.

Data Manipulation Libraries


FunctionLibrary
Description

MATH

Performmathematical functions: absolute value, sin, cos, etc.

STR

Manipulate strings.

Network Libraries


FunctionLibrary
Description

NDS

Call Novell Directory Services.

NET

CallNovell services: Bindery, Broadcast, Connection,Internet, NCP, Queues, Server statistics, trustees,volume information, more.

Database Libraries


FunctionLibrary
Description

ORA

AccessOracle databases.

User Interface Libraries


FunctionLibrary
Description

WIN

Make server-based CWorthy calls.

Generating HTML in NetBasic

There are two ways to generate HTML in NetBasic: using the DOC library, or alternately by just calling the Print() function. For example, the following line of code:

DOC:Heading("Login to Intrasession")

Could also be coded as:

Print("<HTML><HEAD><TITLE>Login to Intrasession</TITLE></HEAD>")

The print statement goes to <stdout<, and when NetBasic is invoked by the Web Server, <stdout< is defined as the current HTML file.

Sometimes the DOC calls are more verbose than the Print calls for generating HTML, and sometimes the opposite is the case. However, the DOC calls are still better for the following reasons:

  • Localization. The DOC calls isolate the actual text from the string content. Thismakes it easier to translate the strings for non-US locales. Translators should not have to see the HTML tags, just the text.

  • Quality. Using DOC calls reduces the chance for error, because the generation of HTML is now more automated, and automating routine tasks reduces the chance of human error. There is less of a chance of missing or mismatched tags. The DOC: calls help alot with making sure all tags come in pairs.

  • Maintainability. DOC calls are more maintainable. It is easier to see what is going on with the calls than it is to have to read each string.

HTML Forms and Fields

HTML does more than just markup text for formatting -- it also allows for input from the user. HTML allows for forms and input fields. There are a number of different fields you can use: Text, Input, Checkbox, Password, Radio buttons, Submit Button, and Reset Button.

You need to write a script to process the results of the form, and take the appropriate action. We will show you a simple form in Smtlogin.bas.

Figure 8: Smtlogin.bas Source.

'Intrasession 1.0 
'Copyright (c) 1996.  Novell, Inc.  All rights reserved.
#include "HTML.H"


Sub main

DOC:Heading("Login to Intrasession")

DOC:Body(DOC_WHITE,DOC_BLACK,DOC_BLUE,DOC_BLUE)

DOC:Address("Copyright 1996, Novell, Inc.  All rights reserved")

DOC:Tag:Begin("H1")

DOC:Image("/images/smtlogo.gif","Login to Intrasession",100,100,0) 
DOC:Print("Login to Intrasession.")

DOC:Tag:End("H1")

DOC:Hr(2,100)

DOC:Form:Begin("/NetBasic/smtmain.bas") 

DOC:Form:Input:Text("login","","Login ID",20,20) 
DOC:Break()

DOC:Form:Input:Password("password","","Password",10,10)

DOC:Break()

DOC:Form:Input:Submit("Login Now") 
DOC:Break()

DOC:Form:End()

Return

End Sub

Now that we have covered some general concepts, let's go over each line in Smtlogin.bas.

Let's start with these lines:

DOC:Heading("Login to Intrasession")"
DOC:Body(DOC_WHITE,DOC_BLACK,DOC_BLUE,DOC_BLUE)

These generate the resulting HTML:

<HTML> 
<HEAD> 
<TITLE> 
Login to Intrasession 
</TITLE> 
</HEAD> 
<BODY BGCOLOR="#FFFFFF" TEXT="#000000"
LINK="#0000FF" 
BACKGROUND="#0000FF">

The parameters of DOC:Body are for the background color, text color, and link colors. The color constants come from the HTML.H include file.

The next lines display a logo and some header text, and draw a line below the header:

Tag:Begin("H1")
DOC:Image("/images/smtlogo.gif","Login to Intrasession",100,100,0)
DOC:Print("Login to Intrasession.")
DOC:Tag:End("H1")
DOC:Hr(2,100)

These lines generate this HTML:

<H1> 
<IMG SRC="/images/smintra.gif" ALT="Login to the Community
Intranet" 
WIDTH=100 SIZE=100 ALIGN=top>
Login to Intrasession.</H1>
<HR SIZE=002 WIDTH=100%>

The DOC:Print call has a useful feature; it is possible to append an HTML tag to it. For example, to generate the text:

<H1>This is a heading</H1>

You can issue the call:

DOC:Print:H1("This is a heading")

Unfortunately, we couldn't use this call here, because we had to embed a graphic in the header. Instead, we used the tag generation calls DOC:Tag:Beginand DOC:Tag:End. Using these calls is still better than using the printf statement to generate HTML.

Now that all that is taken care of, we can show something new: a form and some input fields. The following line gets the form started:

DOC:Form:Begin("/NetBasic/smtmain.bas")

The HTML tag generated from this is:

<FORM METHOD=POST ACTION="/NetBasic/smtmain.bas">

When the user presses the "Login Now" button, the NetBasic script smtmain.bas will be invoked.

Now come the input fields:

DOC:Form:Input:Text("login","","Login ID",20,20)
DOC:Break()

DOC:Form:Input:Password("password","","Password",10,10)
DOC:Break()
DOC:Form:Input:Submit("Login Now") 
DOC:Break()

DOC:Form:End()

The HTML from these statements is:

<FORM METHOD=POST ACTION="/NetBasic/smtmain.bas">
<PRE> 
Login ID: <INPUT TYPE=TEXT NAME="login" VALUE=""
MAXLENGTH=20 SIZE=20>
<BR> 
Password: <INPUT TYPE=PASSWORD NAME="password"
VALUE="" MAXLENGTH=10 SIZE=10>
<BR> 
<INPUT TYPE=SUBMIT VALUE="Login Now"> 
<BR> 
</PRE> 
</FORM>

The first field is a text field, and the second one is a password field. The DOC:break() call puts a space between each field. DOC:Form:Input:Submit()states defines the "submit" button, indicating that the user has entered all the necessary data. DOC:Form:End() closes the form. The tag <PRE< tells the browser not to format this information.

Once the script has generated the tags, it terminates.

When the user pushes the "Login Now" button, the Web server calls Smtmain.bas.

So far, so good. But how do the "login" and "password" values get to Smtmain.bas? We'll take a look at that next.

When your NetBasic script doesn't work as you intended, you can find out a lot by looking at the HTML your script generated. Remember to try the "doc source" item on the browser "view" menu.

Smtmain.bas-Moving on

Smtlogin.bas was simple. The NetBasic had a strong correlation to the resulting HTML tags. As the logic gets more complex, the resulting HTML becomes more dynamic depending on the inputs to the script. We won't go over all of Smtmain.bas, but we will cover some basics. The screen for Smtmain.bas is shown in Figure 2. The only dynamic information in this page is the name of the administrator, which smtmain.bas gets from the database.

In Smtmain.bas we will cover the following concepts:

  • Passing form inputs to the next script

  • Accessing Oracle

  • One piece of dynamic HTML

  • Real Authentication (Intrasession doesn't do it)

Figure 9: Smtmain.bas: getting information.

data = DOC:Var() 
       o 
       o 
       o 
login = data.login 
password = data.password

Let's start by getting the user's ID and password. The first lines of code in smtmain.bas get the login ID and password using the DOC:Var call, which gets CGI environment variables. How did the login and password get in the CGI environment? To understand this, we need to review the form created in Smtlogin.bas.

In the FORM tag created by Smtlogin.bas, the action smtmain.bas was specified as a "POST" method, meaning that the input in the fields would be posted to the Web Server, and stored in the Web Server's CGI environment as a set of value pairs.

There are two ways to get environment data using DOC:Var(). The DOC:Var() call allows the programmer to get a specific value from the environment one at a time, or to get all the values at once. In the first case, the programmer can supply the name of the pair as a parameter to the call. If there are no parameters specified, all of the values come back as an object. The code in Figure 9 could alternatively be written this way:

login = DOC:Var("login")"
password = DOC:Var("password")

Calling Oracle

Now that we have the user's login and password, we are ready to get some information from the Oracle database. Using the ORA library, it is possible to access Oracle.

The section of code in Figure 10 will do the following tasks:

  • Log in to the Oracle DBMS. (We always use the same login and password- a real authentication would take the login ID and password, and log in to Oracle with that).

  • Submit a query to the database to find if there is a user with a matching password.

  • If there is such a user, get the user's ID and group membership.

Figure 10: Smtmain.bas: accessing the Oracle database.

Handle = ORA:Logon("SMTUSER","TEMP")
If (Handle != 0)
   Loginerror("Couldn't login to database.")   
   Return 
EndIf

Q1 = "SELECT LOGIN, USERID, MEMBERSHIP FROM USERS WHERE LOGIN = 
LOWER('" + Login + "') AND PASSWORD = LOWER('" + Password +
"')" 
Success = ORA:Query(Q1) 
If (!Success)
   Loginerror("Query failed:" + DATA:String(Q1))
   Return 
EndIf

ORA:Record:Get 
testlogin = ORA:Field:Get("LOGIN")
userid = ORA:Field:Get("USERID")
member = ORA:Field:Get("MEMBERSHIP")

As already covered, the ORA library provides access to Oracle databases. The first call we make is to log in to Oracle:

Handle = ORA:Logon("SMTUSER","TEMP")

If the login is successful, the variable "Handle" is zero. If the login didn't work, we issue an error and bail out of the script.

Note that we are using the same login and password every time. This implies that Intrasession code is not relying on Oracle authentication for record-level security. Creating a robust authentication scheme is not part of the scope of this article.

Since the login to the database worked, we can now check to see if the user is in the database. This is the only authentication Intrasession performs. If the user ID and matching password are in the database, Intrasession moves ahead.

First we have to build a SQL query to find out if the user is in the database:

Q1 = "SELECT LOGIN, USERID, MEMBERSHIP FROM USERS WHERE LOGIN = LOWER('" + Login + "') AND PASSWORD = LOWER('" + Password + "')"

This SQL SELECT statement says: get the "login," "userid," and "membership" fields from the table "users," and only get records whose login and password fields match the values we got from the user. We have made user ID and password case-insensitive by converting whatever we got from the user to lowercase.

We now submit the SQL string to Oracle:

Success = ORA:Query(Q1)

If the query is successful, we can get the record which came back from the query:

ORA:Record:Get

Now that we have the record, we can read the userid and group membership fields:

testlogin = ORA:Field:Get("LOGIN")"
userid = ORA:Field:Get("USERID")"
member = ORA:Field:Get("MEMBERSHIP")"

So you get the general idea of making Oracle calls: build a SQL statement; give it to Oracle; check results and do appropriate error handling; read specific values.

There is one more item to cover on smtmain.bas before we move on: passing information to the next script.

From Smtlogin.bas to Smtmain.bas we used the CGI environment; between the rest of the scripts, we are going to pass the userid, a session ID, and and additional parameters through the Query portion of the URL. We need to explain why there are two approaches.

It was possible to use the CGI environment to move the user ID and password from Smtlogin.bas to smtmain.bas because smtlogin generated a form, and the content of the form's input fields were passed to the Web server. From Smtmain to the other scripts, there is no form-there are only links. Since links are referred to by a URL, we need to find a way to pass the pertinent information through the URL. A common way to pass parameters between scripts is with the query string.

The standard query syntax for URLs is identified by a question mark followed by a string of value pairs, separated by ampersands:

?<tag1>=<value1>&<tag2>=<value2>...

Since we are going to parse the query string ourselves, we could use our own syntax inside the query. However, Intrasession code uses the standard syntax of a query string.

Smtmain.bas has a subroutine, DspMainPage, which generates the HTML for icons and links to other scripts. We can look at this routine to see how the query strings are built and passed to the next script.

Figure 11: Smtmain.bas:DspMainPage.

Sub DspMainPage


Q1 = "UPDATE USERS SET SESSIONID = '' WHERE ((SYSDATE - LASTACS) >
.4) 
AND (LOGIN != 'guest')" 
ORA:Query(Q1) 
Q1 = "INSERT INTO MAINHITS(USERID,IPADD,BROWSER,HITDATE,REFURL) 
VALUES(" + DATA:String(userid) + ",'" + ipadd + "','" 
Q1 = Q1 + browser + "',SYSDATE,'" + refurl + "')" 
ORA:Query(Q1)


DOC:Heading("Intrasession Main Page") 
DOC:Body("#FFFFFF","#000000","#0000ff","#0000ff")
DOC:Tag:Begin("CENTER")
DOC:Print:H1("Community Intranet") 
lgnsid ="?login="+DATA:String(login)+"&sessionid="+
DATA:String(sessionid) 
DOC:Link:Graphic("/NetBasic/grpmain.bas"+lgnsid,"/IMAGES/SMTGRP1.GIF")
DOC:Link:Graphic("/NetBasic/direct.bas"+lgnsid,"/IMAGES/SMTDIR1.GIF")
DOC:Link:Graphic("/NetBasic/mainsur.bas"+lgnsid,"/IMAGES/SMTSUR1.GIF")
If ((member = 'admin') | (member = 'astadmin'))
  
DOC:Link:Graphic("/NetBasic/admin.bas"+lgnsid,"/IMAGES/SMTADM1.GIF")
EndIf 
DOC:Link:Graphic("/NetBasic/help.bas#general","/IMAGES/SMTHELP1.GIF")
DOC:Tag:End("CENTER") 
DOC:Hr(2,100) 
DOC:Print:Strong("Welcome!")
Q1 = "SELECT INITCAP(FNAME),INITCAP(LNAME),EMAIL FROM USERS
WHERE 
MEMBERSHIP = 'admin' AND ACSLEVEL = (SELECT MAX(ACSLEVEL) FROM
USERS)" 
Success = ORA:Query(Q1) 
If (Success)   
   ORA:Record:Get
   fname = ORA:Field:Get("INITCAP(FNAME)")
   lname = ORA:Field:Get("INITCAP(LNAME)")
   email = ORA:Field:Get("EMAIL")
   If (STR:Length(email) > 0)
      DOC:Print("If you have any questions, comments, or issues regarding 
         passwords, etc., send a message to our site administrator: 
")
      DOC:Link:Text("MAILTO:" + email,"<STRONG>" + fname +
" " + lname + 
         "</STRONG>")
      DOC:Break()   
   EndIf   
   DOC:Tag:Begin("CENTER")
   If (login = 'Guest')     
      DOC:Link:Text("/newreg.htm","Register as a SmartSite user")   
   Else      
      DOC:Link:Text("/NetBasic/userinfo.bas?login=" +  DATA:String(login) 
         + "&sessionid=" + DATA:String(sessionid),"View your account 
         information")
      DOC:Break()     
      DOC:Link:Text("/NetBasic/showinfo.bas?login=" +  DATA:String(login) 
         + "&sessionid=" + DATA:String(sessionid),
         "Set security for your account information")
   EndIf   
   DOC:Tag:End("CENTER")
   Success = ORA:Logoff(Handle)
EndIf 
End Sub

The code in DspMainPage does the following things:

  • Stores the user's session ID in the database.

  • Logs the user id in a log table. Administrators can use this to find out who has been using the site.

  • Displays icons and links to Intrasession functionality.

  • Displays context-sensitive text indicating site administrator and what to do if you are a guest.

Let's take a look at the links, to see how the userid and password are being passed to the next script:

lgnsid="?login="+DATA:String(login)+"&sessionid="+DATA:String(sessioni d) 
DOC:Link:Graphic("/NetBasic/grpmain.bas"+lgnsid,"/IMAGES/SMTGRP1.GIF")
DOC:Link:Graphic("/NetBasic/direct.bas"+lgnsid,"/IMAGES/SMTDIR1.GIF")
DOC:Link:Graphic("/NetBasic/mainsur.bas"+lgnsid,"/IMAGES/SMTSUR1.GIF")
If ((member = 'admin') | (member = 'astadmin'))   GES/SMTADM1.GIF")"
EndIf

These calls generate the resulting HTML:

<A HREF="/NetBasic/grpmain.bas?login=pkarren&sessionid=5378">
<IMG SRC="/IMAGES/SMTGRP1.GIF"
ALIGN="BOTTOM"></A> 
<A HREF="/NetBasic/direct.bas?login=pkarren&sessionid=5378">
<IMG SRC="/IMAGES/SMTDIR1.GIF"
ALIGN="BOTTOM"></A> 
<A HREF="/NetBasic/mainsur.bas?login=pkarren&sessionid=5378">
<IMG SRC="/IMAGES/SMTSUR1.GIF"
ALIGN="BOTTOM"></A> 
<A HREF="/NetBasic/admin.bas?login=pkarren&sessionid=5378">
<IMG SRC="/IMAGES/SMTADM1.GIF"
ALIGN="BOTTOM"></A> 
<A HREF="/NetBasic/help.bas#general">
<IMG SRC="/IMAGES/SMTHELP1.GIF"
ALIGN="BOTTOM"></A>

The session ID 5378 is the one assigned for this particular session. Each time the user logs on, it is different.

The last thing to consider in smtmain.bas is dynamic HTML. There are only a couple of items on this page which are dynamic, but it is useful to look at them. The following code gets the administrator from Oracle, and generates HTML to create an email link to the administrator:

Q1 = "SELECT INITCAP(FNAME),INITCAP(LNAME),EMAIL FROM USERS
WHERE 
MEMBERSHIP = 'admin' AND ACSLEVEL = (SELECT MAX(ACSLEVEL) FROM
USERS)" 
Success = ORA:Query(Q1) 
If (Success)   
   ORA:Record:Get   
   fname = ORA:Field:Get("INITCAP(FNAME)")
   lname = ORA:Field:Get("INITCAP(LNAME)")
   email = ORA:Field:Get("EMAIL")
   If (STR:Length(email) > 0)      
      DOC:Print("If you have any questions, comments, or issues regarding passwords,
      etc., send a message to our site administrator: 
")      
      DOC:Link:Text("MAILTO:" + email,"<STRONG>" + fname +
" " + lname + "
      </STRONG>")      
      DOC:Break()   
   EndIf

You can see the SQL query in the first line. If the query worked, then the code gets the name of the administrator. After that, the code generates the mail link using the DOC:Link:Text call.

The code at the end of the file checks to see if the user is a guest. If she is, then it generates some text encouraging the guest to register.

The HTML for the screen in Figure 2 is this:

Figure 12: HTML from smtmain.bas.

<HTML> 
<HEAD><TITLE>

Intrasession Main Page 
</TITLE></HEAD>

<BODY BGCOLOR="#FFFFFF"
TEXT="#000000" LINK="#0000ff" 
BACKGROUND="#0000ff">

<CENTER> 
<H1>Intrasession</H1>

<A
HREF="/NetBasic/grpmain.bas?login=pkarren&sessionid=26209"><IMG
SRC="/IMAGES/SMTGRP1.GIF" ALIGN="BOTTOM"></A>

<A
HREF="/NetBasic/direct.bas?login=pkarren&sessionid=26209"><IMG
SRC="/IMAGES/SMTDIR1.GIF" ALIGN="BOTTOM"></A>

<A
HREF="/NetBasic/mainsur.bas?login=pkarren&sessionid=26209"><IMG
SRC="/IMAGES/SMTSUR1.GIF" ALIGN="BOTTOM"></A>

<A
HREF="/NetBasic/admin.bas?login=pkarren&sessionid=26209"><IMG
SRC="/IMAGES/SMTADM1.GIF"
ALIGN="BOTTOM"></A>

<A HREF="/NetBasic/help.bas#general"><IMG
SRC="/IMAGES/SMTHELP1.GIF"
ALIGN="BOTTOM"></A>

</CENTER> 
<HR SIZE=002 WIDTH=100%>

<STRONG>Welcome!</STRONG>

If you have any questions, comments, or issues regarding passwords, etc., send a 
message to our site administrator: <A
HREF="MAILTO:pkarren@novell.com"><STRONG>Phil
Karren</STRONG></A> 
<BR> 
<BR> 
<CENTER> 
<A
HREF="/NetBasic/userinfo.bas?login=pkarren&sessionid=26209">View
your account information</A> 
<BR> 
<A
HREF="/NetBasic/showinfo.bas?login=pkarren&sessionid=26209">Set
security for your account information</A> 
</CENTER> 
</BODY></HTML>

The Last NetBasic File: Grpmain.bas

In Grpmain.bas, we will cover the following concepts: getting parameters from the URL query string, reading records from Oracle, and generating tables from database information.

Figure 13: Public and private groups on Intrasession.

The first thing we need to do is get the user and session ID smtmain.bas passed to us. As we discussed previously, smtmain.bas put this information in the URL query string it used to invoke us:

Figure 14: Grpmain.bas: getting parameters from the query string.

SC = STR:Trim:All(DOC:Env:Get('QUERY_STRING'))
Spot = STR:Search("&",SC)
login = STR:Sub(SC,7,Spot - 7) SC = STR:Sub(SC,Spot + 1) 
sessionid = STR:Sub(SC,11)

DOC:Env:Get('QUERY_STRING') gets the query string. STR:Trim:All removes leading and trailing blanks. Now we have the query string, we can parse out the variables by retrieving characters before and after the ampersand.

As was the case for smtmain.bas, grpmain.bas will generate HTML to display the graphics and links to other pages. Once this is taken care of, Smtmain does something new: it reads information from the database and displays it in a table.

The groups page shows what public and private groups are available on the Intrasession site, in two separate tables. The name and description of the groups are displayed in each table.

Let's take a look at the routine ShDiscHead, which is in grpmain.bas. This routine generates a table heading. Grpmain.bas calls this routine twice: once for public groups, and once for private groups.

Figure 15: Grpmain.bas: ShDiscHead.

Sub ShDiscHead

DOC:Tag:Begin("TABLE","BORDER=3 WIDTH=90%") 
DOC:Tag:Begin("TR")
DOC:Tag:Begin("TH","width=30%")
DOC:Print:Strong(param(1))
DOC:Tag:End("TH")
DOC:Tag:Begin("TH")
DOC:Print(param(2)) 
DOC:Tag:End("TH")
DOC:Tag:End("TR")

End Sub

The first call to ShDiscHead is to display the table heading for the public groups table:

ShDiscHead("Public Group","Description")

Before we cover the NetBasic code, let's look at the format for an HTML table. An HTML table consists of the following tag sets:


Table declaration

<TABLE<

BORDER=border_widthWIDTH=percent_of_browser%

Table Row

<TR<

Table heading

<TH<

WIDTH=percent_of_table%

Table Data

<TD<

WIDTH=percent_of_table%

So far, we have generated the tags to begin the table. Let's look at the code which generates the table entries.

Figure 16: Grpmain.bas: ShDiscRow.

Sub ShDiscRow 
DOC:Tag:Begin("TR")
DOC:Tag:Begin("TD","WIDTH=30%")
DOC:Link:Text(param(1),param(2))
DOC:Tag:End("TD")
DOC:Print:TD(param(3)) 
DOC:Tag:End("TR")
End Sub

ShDiscRow is called iteratively for all the records in the Oracle table.

Working together, these two functions generate the HTML tags to create tables. Here is one example of a table generated by these two subroutines.

There is an additional NetBasic detail: parameters in subroutines. The way to get parameters is to use the param(n) construct, in which n is the ordinal for the parameter as it was pased on the call. Since there is no tight parameter checking, you need to make sure you are passing and using the right parameters.

The resulting HTML from these two routines looks like that in the following figure:

Figure 17: Grpmain.bas HTML.

<TABLE BORDER=3 WIDTH=90%>

<TR> 
<TH width=30%> 
<STRONG>Public Group</STRONG>

</TH> 
<TH> 
Description</TH> 
</TR> 
<TR> 
<TD WIDTH=30%> 
<A 
HREF="/NetBasic/grpsel.bas?login=pkarren&sessionid=2530&group=281">Intrasession
Technology</A> 
</TD> 
<TD>This group is for reporting bugs, issues, enhancements requests, praise, 
compliments, and adulatory observations.  Please fill out the survey in this group 
called 'SmartSite Impressions'!</TD> 
</TR> 
<TR> 
<TD WIDTH=30%> 
<A 
HREF="/NetBasic/grpsel.bas?login=pkarren&sessionid=2530&group=300">Main Test</A> 
</TD> 
<TD>This is a public group which you can join to test out the features of the 
SmartSite. Post messages in the discussion forums, create calendar events, and 
take/view surveys which show public opinions.</TD> 
</TR> 
</TABLE>

The correlation between the DOC calls and the HTML tags is reasonably easy to see. The description and group names came from the Oracle database.

We need to look at one final part of grpmain.bas: the Oracle calls. You have seen the two routines which generate the table tags and text. You also need to see the Oracle calls which pass this information to the routines. Let's take a look:

Figure 18: Gprmain.bas: calling Oracle.

loop1 = 0 
Q1 = "SELECT INITCAP(NAME), GROUPID, DESCRIPTION FROM GROUPS,
USERS 
WHERE (GROUPS.USERID = USERS.USERID) AND " 
Q1 = Q1 + "GUESTACS = 'TRUE'" 
Success = ORA:Query(Q1)

If (!Success)   
   GroupError("Database error")   
   Return 
EndIf

ShDiscHead("Public Group","Description")


Do While (ORA:Record:Get)
   name = ORA:Field:Get("INITCAP(NAME)")
   groupid = ORA:Field:Get("GROUPID")
   description = ORA:Field:Get("DESCRIPTION")
   lgnsidgid = lgnsid + "&group=" + DATA:String(groupid)   
   ShDiscRow("/NetBasic/grpsel.bas" + lgnsidgid,name,description)   
   loop1 = loop1 + 1 
EndDo

The first thing this code does is generate an SQL SELECT statement:

Q1 = "SELECT INITCAP(NAME), GROUPID, DESCRIPTION FROM GROUPS, USERS WHERE
(GROUPS.USERID = USERS.USERID) AND GUESTACS = 'TRUE'"

This statement returns the name (with the first letter of the name capitalized), groupid, and description of groups from the groups table. The table join of GROUPS, and USERS (in the WHERE clause) constrains the groups to <what? why?<. Only groups marked as public are viewed in this table.

Once the SELECT statement is built, we can call Oracle:

Success = ORA:Query(Q1)

If this is successful, we keep going and generate the table. In the while loop, we get all the records returned from the SELECT statement, and we can call ShDiscRow to display the results.

Conclusion

IntranetWare is a powerful platform for creating custom Web solutions. Intrasession demonstrates how easy it is to create these solutions. With NetBasic you can quickly and easily build the solution your customers need. IntranetWare provides the core networking components you know and trust, and adds new components which allow you to use it in new ways. Oracle complements the tools available in IntranetWare, and fills out the picture.

Many Novell customers have requested a scripting language on NetWare for years. Most of those who requested it asked for something compatible with Visual Basic. NetBasic meets the needs of developers and network managers, and it enables a broad range of solutions.

We hope this helps you build your own IntranetWare-based solutions. We have shown you portions of Intrasession and shown you how they work. If you would like to use Intrasession as the starting point to building your own solutions, please send email to pkarren@novell.com. This article is only the beginning. Stay tuned for more articles on NetBasic, Java, Rapid App Development, and C/C++.

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates