Skip to main content

Notes.Net Exposed: Registering users on your Domino Web site

Barbara Burch, Content Editor, Iris Associates
Barbara was "Content Editor" for the award-winning Notes.net webzine, Iris Today. During her two years with Iris, she contributed her editing and writing talents to numerous articles published in Iris Today. Barbara left Iris in August 1999 to pursue other career opportunites.
Murray Hurvitz, Application Developer, Iris Associates
Murray was one of the original "founders" of the Notes.net Web site. He began working on the site as both an application developer and a system administrator. Murray no longer works on Notes.net, but has taken his web development and Domino development skills into another development group at Iris.

Summary:  This article dissects the Notes.net registration database and its forms and agents and discusses the challenges of the clustered environment. (For changes since R5, see What's new in the Registration template and download the new template.)

Date:  02 Feb 1998
Level:  Intermediate
Activity:  576 views

Since this article was first published, the Notes.net team has updated our registration process and template. Read our new article, What's new in the Registration template, and download the new template from the Iris Sandbox.

[Editor's Note: This article is the next in our series exposing how the Notes.Net site is run. This time, learn how you can set up registration and authentication on your Domino Web site.]

Overview

Anonymity has had a long history on the Web, but it can only get you so far on your Domino Web site. Sure, you can publish great marketing and product information, wrapped up in a nice design. But by adding registration to your site, you can add a whole new dimension. You can use Domino authentication to open new doors -- to allow users to go where they have never gone before.

Anytime a user tries to open a database where "Anonymous" has no access in the access control list (ACL), Domino automatically requests a user name and password. Once the user enters something, Domino then searches for a matching Person document in the Public Address Book (names.nsf), and a matching password in the Internet Password field. These won't exist unless you've actually created an entry for the user in the Public Address Book -- that is, if you've registered the user.

One of the easiest ways to register users for your Web site is by setting up a Registration database, which allows users to create a login name and password for themselves. Then, you can develop an agent to create the actual entry in the Public Address Book. You can create a Registration database by customizing the sample Registration database (siregw46.nsf) that is shipped with Domino 4.6. The Registration database includes a sample agent, and its Help - Using document contains specific instructions for how to customize the database. In this article, we'll show you how we customized the database to work for our registration needs here at Notes.Net.

You'll see how our Registration database allows us to:

  • Provide real-time registration, so users can automatically download software or participate in discussions immediately after they register.
  • Enable users to update their passwords, while maintaining the security of our Public Address Book. (Users can only make changes to the Registration database, and are never allowed direct access to the Public Address Book.)
  • Manage registration across the servers in our Web site cluster, so users can register on one server, and then authenticate on a different server. (This involves registering users in a "master" group document in the Public Address Book, which is made up of "subgroups" for the separate servers.)
  • Make sure that all user names are unique, and that they include both a first and last name.

In the rest of this article, we'll walk through the forms and agents that drive the Notes.Net registration process. Just like the sample 4.6 Registration database, you can customize our database to fit your own needs. Our Registration database works with both Domino 4.5 and 4.6 servers, and is designed to work in a clustered environment. You can submit feedback about the Registration database by using the Feedback link at the bottom of any page on the Notes.Net site, and choosing "Notes.Net Design Feedback."

Note: The Notes.Net site is set up in its own domain, so our Registration database is designed to register all users in one central Public Address Book. If your site uses cascading address books or the Master Address Book, refer to the sample Registration database's Using document for the appropriate instructions.


Notes.Net registration: Opening the doors

Adding registration to your Web site is not a decision to be taken lightly. Some users may view registration as a roadblock or as unnecessary red tape. This means your challenge is to put registration in a favorable light -- to use it only where necessary and to keep it quick and painless.

To meet this challenge, we've designed most of Notes.Net to be accessible by anonymous users. And where we do require registration -- to download software and/or to participate in the discussions in the Iris Cafe -- we make it real-time registration, so users can immediately participate in the site right after they register.

The primary reason we require registration for downloads is a legal one. That is, we are legally required to verify that only North American residents actually download the North American version of Domino/Notes. The encryption for the North American version is stronger than the encryption in the International version. As you'll see, a lot of the code in our registration database revolves around verifying the user's registration type.

As for the Iris Cafe, any user can read the discussions. However, we require users to register to participate in the discussions for three reasons:

  1. Without authentication (and therefore, some form of user name/password registration) we cannot give users the ability to edit or delete their postings.
  2. We have found that people usually show greater respect for those individuals willing to put their name on their comments.
  3. The developers at Iris would like to have a way to follow up with users.

Since we do require registration, let's look closer at how we try to make it easier on users by providing "real time" registration.


The cluster challenge

An important part of Notes.Net registration is that users can immediately download software or participate in discussions right after they register. This "real time" nature of registration really has to do more with authentication than with the Registration database itself. That is, the Registration database gathers the users' information and gets it into the Public Address Book (and we'll walk through how this works in a moment). But, the key point for the user is that the Public Address Book's views get updated, so the user can immediately enter a name and password, and Domino recognizes it.

In fact, the Registration database also takes care of updating the Public Address Book views, but only on the particular server on which the user registered. If the user stays within the context of this same server, the authentication will be successful. The challenge is that we use several servers in a Domino cluster to host Notes.Net, and it's possible that the user could navigate to another server for the site that does not yet contain the latest registration information. Although our cluster replication (scheduled to run every 1 minute) can replicate the new Person document, each server's Indexer task must update the views in its own Public Address Book. (The $Users view does have priority for indexing, so it will be updated first when the Indexer runs.) So, you'll notice that when the Notes.Net registration completes, we provide a link back to the site so users stay within the context of the server on which they registered.

Another aspect of using clusters is that you need to handle groups a little differently. The standard way to register users is to add them to a group, so you can then use the group name in your ACLs. (All user rights and roles are assigned to the group, and the group has rights quicker than the individual.) As users register on a particular server, they are added to the Group document in the Public Address Book for that server. This time, the challenge with clusters is that as the Group documents replicated around the cluster, we ran into replication conflicts and were unable to merge the conflicts. Our solution is that we register all users into one "master" group in the Public Address Book. This master group is made up of several subgroups. For example, the following screen shows our "master" group, DownloadNA, with its subgroup members.


Figure 1. DownloadNA group
DownloadNA group

Users are registered in a subgroup, based on the server that they actually register on. Since the membership of the master group never changes -- only the membership in the subgroups -- we can avoid replication conflicts on the different servers in our Web site cluster. As shown below, when User 1 registers on the Web 1 server, he joins the subgroup on Web 1. And, when User 2 registers on Web 2, she instead joins the Web 2 subgroup.


Figure 3. Notes.net registration diagram
Notes.net registration diagram

How registration works at Notes.Net

Now, that you understand the challenges of setting up registration, let's get to the point of actually registering users. The heart of Notes.Net registration is driven by two key forms and two key agents in our registration database. There's a form and agent for the initial registration, and a separate form and agent for updating the account later. In each case, the form gathers the information, and the agent gets it into the Public Address Book. Let's first look at the initial registration.


Gathering the initial information

As you may already know, you can access our Registration database from anywhere on Notes.Net. Domino then displays the following page, which prompts you to choose your type of registration -- either North American or International. You can also update an existing account from this page.


Figure 4. Notes.net registration Welcome page
Notes.net registration Welcome page

The main difference between the registration types is that we ask more questions of North American users. As stated earlier, we must verify that only North American users actually download the North American version of Domino/Notes. Domino displays the following form for North American users.


Figure 5. North American Registration form
North American Registration form

In addition to the name and address fields, we include three key questions to verify your status as a North American user:

  • Are you an existing Notes user?
  • Are you a United States or Canadian citizen or permanent resident?
  • Are you obtaining the Lotus Software for end-use in the United States or Canada?

The registration agent then verifies the values in these fields, which we'll discuss later. If you're registering to just participate in the Iris Cafe, it doesn't really matter to us whether you're a North American or International user. So, when you use either form to register for a download, you're automatically set up to participate in the forums.


Taking a closer look at the registration form

The registration form itself includes three key areas: a registration fields subform, a marketing information subform, and a grouping of hidden fields. (We'll specifically look at the North American form, but the International form works essentially the same.)

Here's what the registration fields subform looks like.


Figure 6. Registration fields subform
Registration fields subform

Because all the fields are required on this subform, each field has an input validation formula that verifies that the field is not blank. If a field is blank, the user receives a message requesting a value for the field. The user can then click the browser's Back button to finish filling out the form. For example, here's the validation formula for the First Name field:

@If(FirstName= ""; @Failure("All fields are required, please provide us with a value for the First Name field."); @Success)

The NewPassword field is a shared field, because it's also used when users want to update their account. This field generates a random password that users may change. Also, the field checks that the password is at least three characters long, and that the password is not blank.

The marketing information subform collects information for the Lotus marketing team, and just contains editable keyword fields. (The fields aren't required, so they don't use the input validation formula.)

Now, let's look at the hidden fields.


Figure 7. Reg46NA form, hidden fields
Reg46NA form, hidden fields

When the user submits the registration form, the $$QuerySaveAgent fires off the "Handle New Account Request" agent, which we'll discuss in the next section. (The $$QuerySaveAgent field works in our mixed environment of Domino 4.5 and 4.6 servers. If you're running a pure 4.6 environment, you could instead use the new WebQuerySave form event to implement your Web agents.)

The FullName field computes the user's name with the following formula:

FirstName + @If(MiddleInitial = ""; ""; " " + MiddleInitial) + " " + LastName

The "Author_Names" and "Reader_Names" fields control future access to the document. Only the user (FullName) has author access for editing the document in the future. However, we allow our admin group, server groups, and the user to read the document.

The AgentStatus subform contains hidden fields (AgentState, WhenHandled and AgentStatus), into which the Handle New Account Requests agent can write bookkeeping information. This information leaves a trail that can help you to diagnose any problems that might occur. The default value for the AgentState field is "P" for "pending," and the default value for the AgentStatus field is "Not run yet." When the agent begins running, it writes "Agent running" into the AgentStatus field. Then, when the agent is finished running, it writes "Successful" into the AgentStatus field, "D" for "done" into the AgentState field, and the date/time it finished running into the WhenHandled field.

Finally, we use the CGI variables to confirm where users are connecting from.


Getting the information into the Public Address Book

When the user successfully submits the registration form, the $$QuerySaveAgent field triggers the "Handle New Account Request" agent. This agent is the "middle man" for actually getting the user information into the Public Address Book. Our code differs from the sample Registration database in that we only have one Public Address Book, but we need to also check the registration type and place users in subgroups according to the server on which they're registering.

Here's a breakdown of what our agent does:

  1. Checks that the registration type is correct. That is, it checks that North American users have entered a valid e-mail domain, and have answered "Yes" to the three additional questions for North American users.
  2. Checks for duplicate names.
  3. Creates a Person document in the Public Address Book.
  4. Adds the person to the appropriate groups, according to the registration type and server.
  5. Checks that the views in the Public Address Book are up-to-date, so the user can immediately authenticate successfully.
  6. Thanks the users for registering, and provides a link back to the Notes.Net home page.

Step 1. Checking the registration type

Before we even deal with the Public Address Book, the agent first needs to verify the user's registration type. (We do this in the Initialize event.) We mainly want to check that North American users answered "Yes" to all three questions, and that they are connecting from a valid domain. We first set the valid North American domains as: edu, net, org, com, gov, mil, .us and .ca. The registration fails if the North American user answered "No" to the citizen or existing Notes user questions, if the Remote_Host lookup failed, or if the user entered an invalid domain. Otherwise, we call the "HandleNewAccount" subroutine.

If (doc.RegType(0) <> "Intl46")Then

    'Test For North American
        If (doc.CitzenNA(0) <> "No") And (doc.useNA(0) <> "No") Then
            If doc.Remote_Host(0) <> "" Then
                HostDomain = Lcase(Right(doc.Remote_Host(0), 3))
                Forall vd In ValidDomains
                    If vd = HostDomain Then
                        DomainMatchFlag = True
                        Exit Forall
                              
                    End If
                End Forall
                If DomainMatchFlag  Then
    ' Handle New Account Request
                    If (( doc.Form(0)="Reg46NA") And doc.AgentState(0) = "P" ) Then
                        Call doc.ReplaceItemValue("Form", "Request")
                        Call HandleNewAccount( doc )
                    End If 
                Else
                    Call doc.REPLACEITEMVALUE("Form","Failure")
                    Call doc.REPLACEITEMVALUE("FailureType",
                    "Domain or Country invalid")
                    Print "[/downnote.nsf/lookup/ValidateFailure?OpenDocument]"
                End If
            Else
                Call doc.REPLACEITEMVALUE("Form","Failure")
                Call doc.REPLACEITEMVALUE("FailureType","Reverse Lookup Failed")
                Print "[/downnote.nsf/lookup/ValidateFailure?OpenDocument]"
            End If
        Else
            Call doc.REPLACEITEMVALUE("Form","Failure")
            Call doc.REPLACEITEMVALUE("FailureType","No Answer to 
            Citzen or Usage questions")
            Print "[/downnote.nsf/lookup/ValidateFailure?OpenDocument]"
        End If
    Else
        ' Handle New Account Request
            If (( doc.Form(0)="Reg46Intl") And doc.AgentState(0) = "P" ) Then
                Call doc.ReplaceItemValue("Form", "Request")
                Call HandleNewAccount( doc )
            End If 
    End If

Step 2. Checking for duplicate names

The rest of the steps take place in the HandleNewAccount subroutine. Before we register the user, we want to make sure that the user doesn't already exist in our Public Address Book. Notice that we ask users to try registering again if they entered a name that's already in use.

(The "Modifiable Constants" script library contains the path to our primary Public Address Book for creating both the new Person documents and new Group documents. The GetPersonDocument subroutine is in the "Request Utilities" script library, and finds the Person document in the Public Address Book for the person named in the argument.)

Dim docPerson As NotesDocument
Set docPerson = GetPersonDocument( req.FullName(0), nabPeople )

If Not (docPerson Is Nothing) Then
    req.AgentStatus = "Duplicate name"
 
    Print "<h2>Registration not completed:</h2>"
    Print "<br>The name " + req.FullName(0) + " is already in use.  
    Please try registering again with a different name."
    Print "<br>To try again, go back to the previous page 
    and re-enter the name fields."
    Print "<br><br><a href=""/welcome.nsf"">
    Notes.Net Home Page</a>"
          
    Goto Done
End If

Step 3. Creating a Person document in the Public Address Book

The following code creates the new Person document.

Set docPerson = New NotesDocument( nabPeople )
     
     docPerson.Form = "Person"
     docPerson.Type = "Person"
     docPerson.LastName = req.LastName
     docPerson.FirstName = req.FirstName
     docPerson.FullName = req.FullName
     docPerson.OfficePhoneNumber = req.Phone
     docPerson.MailAddress = req.EMail
     docPerson.HTTPPassword = req.NewPassword
     Call docPerson.ComputeWithForm( False, False )
     Call docPerson.Save( False, True )

Step 4. Adding the person to appropriate groups

Now, we add the user to a subgroup according to the registration type and the corresponding server. For example, for a North American user who happens to be registering on the Web1 server, we place the user in the subgroup "DownloadNAWeb1." The code below specifically works with the naming scheme for our Notes.Net servers, which all have the same common name (Web) with a different server number. You could instead use a Case statement to switch between specific server names.

ServerNum = Right$(sName.common, 1)
     
If (req.RegType(0) <> "Intl46") Then
    group = "DownloadNAWeb" & ServerNum
Else
    group = "DownloadIntlWeb" & ServerNum
End If
     
Call AddUserToGroup( req.FullName(0), group, nabGroups )

The AddUserToGroup call goes to the Request Utilities script library. We "borrowed" the AddUserToGroup code directly from the sample Registration database. Basically, it adds a user to a group, but does it in a way that allows very large groups.

Step 5. Checking that the Public Address Book views are up-to-date

This is another place where our agent calls the Request Utilities script library. This time, we use EnsureUserInNAB:

Call EnsureUserInNAB(req.FullName(0) )

The EnsureUserInNAB function updates the $Users and $ServerAccess views in the Public Address Book so that the user can immediately gain access to the server. (Adding the user to an existing group has a real-time effect, so no additional update of the Groups view is necessary.) Under normal circumstances, these view updates occur automatically, but perhaps not quite as fast as the user could navigate to a secured database on the site. So, we use LotusScript DLL callbacks to call the Notes API to cause the view to be updated immediately. (We use separate DLLs according to the platform of the server.)

Note: The sample registration database uses a pure script implementation that does not require any platform-specific customization. In addition, it includes the DLL code that we use with detailed comments.

Step 6. Thanking the user, and redirecting to the home page

One of the last components of the Handle New Account Requests agent is to let the user know that the registration was successful, and to direct them to the proper home page URL. As we explained earlier, the reason we provide the link is that we want to control the server context.

If req.RegType(0) = "NA46" Then
    Print "<h2>Thank you " + req.FirstName(0) + ", 
    for registering with the Notes.Net site!</h2>"
    Print "<br>You can now access the North American 
    Downloads and the Iris Cafe Forums."
    Print "<br>Your user name is: " + req.FullName(0)
    Print "<br><br><a href=""http://" & sName.common & 
    ".notes.net"">Click here to return to the Notes.Net home page</a>" 
Else
    Print "<h2>Thank you " + req.FirstName(0) + ", for registering 
    with the Notes.Net site!</h2>"
    Print "<br>You can now access the International English 
    Downloads and the Iris Cafe Forums."
    Print "<br>Your user name is: " + req.FullName(0)
    Print "<br><br><a href=""http://" & sName.common & 
    ".notes.net"">Click here to return to the Notes.Net home page</a>" 
End If


Updating account information

Another feature of the Notes.Net registration is that we allow users to update their passwords anytime after their initial registration. To do this, you just click "Update existing account" on either the Iris Cafe page or the initial Registration page. After you authenticate with the server, Domino displays the following Change Password form.


Figure 8. Change Password form
Change Password form

The FullName field simply uses an @UserName command to display the user's name. The OldPassword field is where the user enters the old password, which is then verified in the corresponding Change Password agent. NewPassword is the same shared field used for the initial registration -- it again checks that the password is at least three characters long, and that it's not blank.

The hidden fields on this form work about the same as for the registration forms. This time when the user submits the form, the $$QuerySaveAgent field runs the "Handle Change Password Request" agent. Again, the AgentStatus subform records the agent bookkeeping information, and the CGI variables record where users are connecting from. The Readers field allows users to see the correct registration document(s) in the view when updating their account.


Getting the updated information into the Public Address Book

When the user successfully submits the registration form, the $$QuerySaveAgent field triggers the Change Password agent. This agent works essentially the same as the one in the sample registration database. The Initialize event calls the HandleChangePassword subroutine to handle any Change Password requests.

First, we check that the user name in the request matches the name in the Registration database. (Remember that the GetPersonDocument call goes to the Request Utilities script library.)

Dim docPerson As NotesDocument
Dim dbNab As New NotesDatabase("", "names.nsf")
Set docPerson = GetPersonDocument( req.FullName(0), req.ParentDatabase )

Then, we check that the old password matches the user's current password in the Registration database.

Temp = Evaluate("@Password(OldPassword)", Req)
If Temp(0) <> docPerson.HTTPPassword(0) Then
    req.AgentStatus = "Old password is incorrect"
    Print "<b>Your old password does not match your current password.</b>"
    Print "<br>Please go back and correct your password."
    Goto Done
End If   

Once we've verified information in the Registration database, we can move on to the Public Address Book. We check that the user name and old password matches, and then set the new password.

Dim nabPerson As NotesDocument
    Set nabPerson = GetPersonDocument( req.FullName(0), nabPeople)
    If nabPerson Is Nothing Then
        req.AgentStatus = "No such user"
        Goto Done
    End If
     
    ' Check that the old password matches.
     
    If req.OldPassword(0) <> nabPerson.HTTPPassword(0) Then
        req.AgentStatus = "Old password is incorrect"
        Print "<b>Your old password does not match your current password.</b>"
        Print "<br>Please go back and correct your password."
        Goto Done
    End If
     
    ' OK: Set the new password in the NAB
     
    Call nabPerson.ReplaceItemValue( "HTTPPassword", req.NewPassword(0) )
    Call nabPerson.Save( False, True )

Then, we update the Person document in this Registration database, call EnsureUserInNAB to get the views up-to-date again, and let the user know that their request was successful.

' Update the person document in this database.
Call docPerson.ReplaceItemValue( "HTTPPassword", req.NewPassword(0) )
Call docPerson.ComputeWithForm(False, False)
Call docPerson.Save( False, True )

Call EnsureUserInNAB( req.FullName(0) )

req.AgentStatus = "Successful"
Print "<b>Thank you " &  docPerson.FirstName(0)  & ".  
Your password has been changed.</b>"
Print "<br><br><a href=""http://notes.net"">Notes.Net Home Page</a>" 


Security settings for the Registration database

Although users are never directly accessing your Public Address Book, you still need to be aware of the security considerations when using a Registration database. For one thing, default access to the database needs to be at least Author (with "Create documents" rights), because the anonymous Web users must be able to run the registration agent. The ACL should also include the group name that users are registered into, and the group should have Author access (so registered users can update their accounts). In addition, the "Maximum Internet name and password" setting on the Advanced panel of the ACL should be set to Author.

In fact, while the registration agent runs with the permissions of the Web user for all operations in the Registration database, the agent runs with the permissions of the user whose signature is on the agent for all operations in the Public Address Book. (You can sign an existing agent with your ID by opening the agent, typing a single space into the code, and then saving the agent.) When you enable an agent to run on a server, the agent records your identity and uses that identity when running. This means that the agent can only do what you are allowed to do. So, in the ACL for the Public Address Book, you must be able to create and edit Person documents and Group documents.

Your name must also appear in the Agent Manager section of the Server document, in the "Run restricted LotusScript agents" and "Run unrestricted LotusScript agents" fields.

You should note that the Registration database was designed and tested to work properly on servers in a domain whose Public Address Book contains no Notes users. This should be the most common (and safest) configuration for Domino servers that allow Web users to register themselves.


Future enhancements

We're striving at Notes.Net to make registration as easy as possible for users -- with "real time" registration, the ability to update passwords, and more. But, we know that there's always room for improvement. Some ideas for the future include: adding a Notes registration model, perhaps using cross-certification; doing more checking for valid names, like not allowing numbers in names; and allowing users to update more of their account information.

In addition, we plan to put our experience at Notes.Net to work for 5.0, as we update the next version of the sample Registration database. We want registration to be a welcome addition, so users can gain even more value from your Web site.


Resources

About the authors

Barbara was "Content Editor" for the award-winning Notes.net webzine, Iris Today. During her two years with Iris, she contributed her editing and writing talents to numerous articles published in Iris Today. Barbara left Iris in August 1999 to pursue other career opportunites.

Murray was one of the original "founders" of the Notes.net Web site. He began working on the site as both an application developer and a system administrator. Murray no longer works on Notes.net, but has taken his web development and Domino development skills into another development group at Iris.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=12645
ArticleTitle=Notes.Net Exposed: Registering users on your Domino Web site
publish-date=02021998
author1-email=
author1-email-cc=
author2-email=
author2-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers