Release 10.1A: OpenEdge Development:
Programming Interfaces

> ## Defining activities-based user authorization

> Applications that you write probably break down into several areas or activities. For example, you may have one set of procedures that handles customer activities, and another set that handles inventory activities. For each set of activities, you may want to establish a valid group of users. To do this, you build a permissions table. To establish and use a permissions table, you must:

> - Create a table that defines the kinds of access different users have to application activities.

> - Include statements in application procedures to check the permissions table at run time.

> - Write a procedure that can modify access permissions.

> ##### Creating an application activity permissions table

> You create a permissions table within the Data Dictionary. This chapter calls the table permissions, but you can use any name you want. Each record in the permissions table contains at least two fields: an `activity` field and a `can–run` field. The `activity` field contains the name of the procedure and the `can–run` field contains a comma-separated list of the user IDs of those users who have permission to run the procedure. (Whether these are database connection or Progress session IDs depends entirely on how you match them with the `CAN-DO` function.) Normally, the primary index is built on the activity field.

> After you create a permissions table, you must add a record for every application activity for which you want to provide security.

> ##### Adding records to the permissions table

> To create records for the permissions table, you must first determine the users and the activities. The users are identified by their user IDs, and the activities by specific procedures or subsystems.

> In the following example, three user IDs—`manager`, `salesrep`, and `inventory`—are given permission to perform the following activities:

> - Add new customers to the database by running `i-adcust.p`, which `manager` and `salesrep` have permission to run.

> - Update records in the database by running `i-chcust.p`, which `manager` and `salesrep` have permission to run.

> - Remove customer records from the database by running `i-delcus.p`, which `manager` has permission to run.

> - The order report and mailing label procedures (`i-itlist.p` and `i-rept6.p`) are grouped into a subsystem called `print`, which `manager` and `inventory` have permission to run.

> To add these application activities as records to the permissions table, you can write a simple Progress procedure:

> i-prmsn.p
>     REPEAT:
>       INSERT permissons.
>     END.

> This procedure lets you add records of activities to the permissions table until you press END–ERROR.

> Figure 2–1 shows records of application activities that you can add to the permissions table.

> Figure 2–1: Sample activity permissions entries

> After you create these records of application activities, you must include statements in your procedures that check them at run time. After that, the security administrator is responsible for maintaining these records.

> ##### Including security checking in procedures

> When the user runs a procedure, you can check the permission for the activity associated with the procedure. Specifically, you:

> - Find the activity record in the permissions table.

> - Compare the permissions for the activity with the user ID (database connection ID or Progress session ID) of the user running the procedure.

> - If there is a match for the user ID, allow access. Otherwise, display a message and exit from the procedure.

> Figure 2–2 shows what happens when the user with user ID `manager` runs the `i-adcust.p` procedure.

> Figure 2–2: User with permission to run a procedure

> When the specified user ID and the permission defined in the `i-adcust.p` record in the permissions table match, the that user can run the procedure. Figure 2–3 shows what happens when the user with user ID `inventory` tries to runs `i-adcust.p`. Because there is no match, the procedure displays a message and the user cannot run the remaining code.

> Figure 2–3: User without permission to run a procedure

> You use the `CAN–DO` function to do security checking in your procedure. The procedure `i-adcus4.p` is a modified version of the `i-adcust.p` procedure that includes activity-based security checking:

> i-adcus4.p

> The first part of this procedure makes sure the user’s single database connection ID is authorized to run the procedure. The `FIND` statement reads the permission record for the `i-adcust.p` procedure. The `CAN–DO` function compares the value of the `can–run` field in the record with the database connection ID of the user running the procedure. If the values do not match, the procedure displays a message and exits. If there is a match, the procedure allows the user to add customer records.

> Progress checks privileges within a `DO FOR` block to ensure that the record read by the `FIND` statement is held only during that block, rather than during the entire procedure. In addition, the `NO–LOCK` option ensures that other users can access or update the permissions table while this procedure is running.

> The part of the `i-adcust.p` procedure that does security checking is standard. For example, you could include the same security checking statements in the procedures `i-chcust.p` and `i-delcus.p`, if you change the name of the activity record being read in the permissions table:

> i-delcs2.p

> The following procedure shows how you can modify a print procedure, such as `i-itlist.p`, and add security checking to it:

> i-itlst2.p

> Here, the `FIND` statement reads the print record from the permissions table. The `CAN–DO` function compares the value of the `can–run` field with the database connection ID of the user running the procedure. If there is no match, the procedure displays a message and exits. If there is a match, the procedure displays order information.

> Remember, there is no separate record in the permissions table for the `i-itlst2.p` procedure. However, you can use the record for the `"print"` activity to handle security for any procedure that you specify as a print activity. You can include the same security checking statements in any other procedure that you consider to be a print activity, such as `i-rept6.p`:

> i-rept6.p
>     OUTPUT TO mail.lst.
>     FOR EACH customer WHERE curr-bal >= 1400 BY zip:
>       PUT contact SKIP
>           name SKIP
>           address SKIP.
>       IF address2 NE "" THEN PUT address2 SKIP.
>       PUT city + ", " + st + "  " + STRING(zip," 99999") FORMAT "X(23)"
>     SKIP(1).
>       IF address2 EQ "" THEN PUT SKIP(1).
>     END.

> For application maintenance purposes, you might want to put security checking statements into an include file. Procedures that require security checking can simply include that file, passing the activity as an argument. The following is an example of a such an include file:

> i-chkprm.i
>     DO for permissions:
>       FIND permissions {1} NO-LOCK.
>       IF NOT CAN-DO (can-run)
>       THEN DO:
>         MESSAGE "You are not authorized to run this procedure".
>         RETURN.
>       END.
>     END.

> ##### Protecting and maintaining the permissions table

> To protect the permissions established in the permissions table, you can provide the security administrator with the following procedures:

> - A procedure that defines who can modify the permissions table. Initially, you can run this procedure and enter the user ID of the security administrator, as well as database connection IDs of those authorized to modify the permissions table.

> - A security update procedure (for example, `i-secupd.p`) that the security administrator or other authorized users can run to modify permissions for specific procedures and functions.

> To do security checking, these procedures require a record in the permissions table associated with the activity of maintaining security. Figure 2–4 shows an example security record in the permissions table.

> Figure 2–4: Sample security record for activity permissions

> When you create the security record, initialize the `can–run` field with an asterisk. This means that, initially, any user can run the security administration procedure (`i-secadm.p`). However, after you run it and enter the authorized user IDs, only the authorized users can change the security record:

> i-secadm.p

> The authorized users can also run the next procedure, `i-secupd.p`, which updates permissions for procedures and activities:

> i-secupd.p

> The first part of `i-secupd.p` checks the security record in the permissions table to make sure that the user is authorized to run the procedure. If the user is not authorized, the procedure displays a message and exits. Otherwise, the second part of `i-secupd.p` permits the user to modify the `can–run` field for a specified activity.

> Figure 2–5 summarizes the security process developed for procedures and functions in an application.

> Figure 2–5: Summary of run-time authorization process

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095