Index: openacs-4/readme.txt
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/readme.txt,v
diff -u -N -r1.3 -r1.4
--- openacs-4/readme.txt 10 Jul 2002 08:45:47 -0000 1.3
+++ openacs-4/readme.txt 30 Nov 2002 17:11:57 -0000 1.4
@@ -31,20 +31,17 @@
--------------
+For installation instructions, please see
+http://openacs.org/doc/openacs-4/acs-admin
+
Documentation for this system is at viewable via your favorite browser
at http://openacs.org/doc
-For installation instructions, please see
-http://openacs.org/4/
-
Once your service is up and running, this same documenation is
-available at
+available at http://yourservicename/doc/
-http://yourservicename/www/doc/
-
The release notes for this release are available at
-packages/acs-core-docs/www/release-notes/.
+packages/acs-core-docs/www/release-notes.html
Please report bugs via http://openacs.org/sdm
-
-
+and any questions and feedback at http://openacs.org/bboard/
Index: openacs-4/contrib/obsolete-packages/acs-content/sql/upgrade/upgrade-4.1-4.1.1.sql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/obsolete-packages/acs-content/sql/upgrade/Attic/upgrade-4.1-4.1.1.sql,v
diff -u -N
--- openacs-4/contrib/obsolete-packages/acs-content/sql/upgrade/upgrade-4.1-4.1.1.sql 13 Mar 2001 22:59:26 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,120 +0,0 @@
-
-------------------------------------------------------------------------------
--- packages/acs-content/sql/upgrade/upgrade-4.1-4.1.1.sql
---
--- @author teeters@arsdigita.com
--- @creation-date 2000-03-06
--- @cvs-id $Id: upgrade-4.1-4.1.1.sql,v 1.1 2001/03/13 22:59:26 ben Exp $
---
-
-
--- upgrade script. Reload package acs_content. Function new changed to procedure.
---
-
-
-create or replace package acs_content
-as
- procedure new (
- content_id in acs_contents.content_id%TYPE ,
- mime_type in acs_contents.mime_type%TYPE default 'text/plain',
- nls_language in acs_contents.nls_language%TYPE default null,
- searchable_p in acs_contents.searchable_p%TYPE default 'f',
- content in acs_contents.content%TYPE default empty_blob()
- );
-
- procedure delete (
- content_id in acs_contents.content_id%TYPE
- );
-
- procedure update_nls_language (
- content_id in acs_contents.content_id%TYPE default null,
- nls_language in acs_contents.nls_language%TYPE
- );
-
- procedure update_mime_type (
- content_id in acs_contents.content_id%TYPE default null,
- mime_type in acs_contents.mime_type%TYPE
- );
-
- procedure update_searchable_p (
- content_id in acs_contents.content_id%TYPE default null,
- searchable_p in acs_contents.searchable_p%TYPE
- );
-
-end acs_content;
-/
-
-create or replace package body acs_content
-as
- procedure new (
- content_id in acs_contents.content_id%TYPE,
- mime_type in acs_contents.mime_type%TYPE default null,
- nls_language in acs_contents.nls_language%TYPE default null,
- searchable_p in acs_contents.searchable_p%TYPE default 't',
- content in acs_contents.content%TYPE default empty_blob()
- )
- is
- v_content_id acs_contents.content_id%TYPE;
- begin
- insert into acs_contents (
- content_id,
- mime_type,
- nls_language,
- searchable_p,
- content
- ) values (
- acs_content.new.content_id,
- acs_content.new.mime_type,
- acs_content.new.nls_language,
- acs_content.new.searchable_p,
- content
- );
- end new;
-
- procedure delete (
- content_id in acs_contents.content_id%TYPE
- )
- is
- begin
- delete from acs_contents
- where content_id = acs_content.delete.content_id;
- end delete;
-
- -- update language column
- procedure update_nls_language (
- content_id in acs_contents.content_id%TYPE,
- nls_language in acs_contents.nls_language%TYPE
- )
- is
- begin
- update acs_contents
- set nls_language = acs_content.update_nls_language.nls_language
- where content_id = acs_content.update_nls_language.content_id;
- end update_nls_language;
-
- -- update mime type column
- procedure update_mime_type (
- content_id in acs_contents.content_id%TYPE,
- mime_type in acs_contents.mime_type%TYPE
- )
- is
- begin
- update acs_contents
- set mime_type = acs_content.update_mime_type.mime_type
- where content_id = acs_content.update_mime_type.content_id;
- end update_mime_type;
-
- -- update searchable p column
- procedure update_searchable_p (
- content_id in acs_contents.content_id%TYPE,
- searchable_p in acs_contents.searchable_p%TYPE
- )
- is
- begin
- update acs_contents
- set searchable_p = acs_content.update_searchable_p.searchable_p
- where content_id = acs_content.update_searchable_p.content_id;
- end update_searchable_p;
-end acs_content;
-/
-
Index: openacs-4/packages/acs-admin/acs-admin.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/acs-admin.info,v
diff -u -N -r1.16 -r1.17
--- openacs-4/packages/acs-admin/acs-admin.info 24 Sep 2002 00:14:39 -0000 1.16
+++ openacs-4/packages/acs-admin/acs-admin.info 30 Nov 2002 17:12:29 -0000 1.17
@@ -120,6 +120,8 @@
Done. You can send the user email or go back. You can send the user email or go back.
+You may return.
+
Index: openacs-4/packages/acs-admin/www/send-email.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/send-email.tcl,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/acs-admin/www/send-email.tcl 30 Nov 2002 17:12:49 -0000 1.2
@@ -0,0 +1,36 @@
+ad_page_contract {
+ email sending page
+
+ @author Hiro Iwashima
"
+ ad_script_abort
+}
+
+if { $show_sent_message_p != "t" } {
+ # Do not show any message. Just go to return url
+ ad_returnredirect $return_url
+ ad_script_abort
+}
Index: openacs-4/packages/acs-admin/www/apm/index.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/acs-admin/www/apm/index.xql,v
diff -u -N -r1.3 -r1.4
--- openacs-4/packages/acs-admin/www/apm/index.xql 13 May 2001 14:30:00 -0000 1.3
+++ openacs-4/packages/acs-admin/www/apm/index.xql 30 Nov 2002 17:13:06 -0000 1.4
@@ -1,16 +1,24 @@
[ad_quotehtml $errmsg]
This procedure is defined in the server but not documented via ad_proc or proc_doc and may be intended as a private interface.
The procedure is defined as:
+proc $proc {[info args $proc]} { +[ad_quotehtml [info body $proc]] +}" + } elseif {![empty_string_p [namespace eval :: [list info commands $proc]]]} { + set error_msg "
The procedure $proc is an available command on the server and might be found in the TCL or AOLServer documentation or in documentation for a loadable module (like ns_cache for example).
" + } else { + set error_msg "The procedure $proc is not defined in the server.
" + } } else { if { $source_p } { Index: openacs-4/packages/acs-api-browser/www/proc/index.vuh =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-api-browser/www/proc/index.vuh,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/acs-api-browser/www/proc/index.vuh 20 Aug 2002 12:41:27 -0000 1.1 +++ openacs-4/packages/acs-api-browser/www/proc/index.vuh 30 Nov 2002 17:13:46 -0000 1.2 @@ -1,3 +1,3 @@ -rp_form_put query_string [string range [ad_conn extra_url] [string length "proc/"] end] -rp_form_put search_type "Feeling Lucky" -rp_internal_redirect "/packages/[ad_conn package_key]/www/proc-search" +set query_string [string range [ad_conn extra_url] [string length "proc/"] end] +set url "[ad_conn package_url]proc-search?[export_vars { query_string { search_type "Feeling Lucky" } }]" +ad_returnredirect $url Index: openacs-4/packages/acs-bootstrap-installer/db-init-checks-postgresql.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-bootstrap-installer/db-init-checks-postgresql.tcl,v diff -u -N -r1.4 -r1.5 --- openacs-4/packages/acs-bootstrap-installer/db-init-checks-postgresql.tcl 5 Sep 2002 05:54:45 -0000 1.4 +++ openacs-4/packages/acs-bootstrap-installer/db-init-checks-postgresql.tcl 30 Nov 2002 17:13:56 -0000 1.5 @@ -46,8 +46,10 @@ } - ## Make sure the function is dropped - catch { ns_db dml $db "drop function __test__();" } + ## Make sure the __test__() function is dropped if it exists + if {![empty_string_p [ns_db 0or1row $db "select proname from pg_proc where proname = '__test__' and pronargs = 0"]]} { + catch { ns_db dml $db "drop function __test__();" } + } if { [catch { ns_db dml $db "create function __test__() returns integer as 'begin end;' language 'plpgsql'" } errmsg] } { append my_errors "\n" Index: openacs-4/packages/acs-bootstrap-installer/installer/create-administrator-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-bootstrap-installer/installer/Attic/create-administrator-2-postgresql.xql,v diff -u -N --- openacs-4/packages/acs-bootstrap-installer/installer/create-administrator-2-postgresql.xql 17 Apr 2001 22:59:51 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,14 +0,0 @@ - -createlang plpgsql your_database_name
Help to the folks keeping an OpenACS installation up and running.
Prev | Home | Next |
OpenACS 4.5 Release Notes | Up | Chapter 2. Installing on Unix/Linux |
Help to the folks keeping an OpenACS installation up and running.
Prev | Home | Next |
OpenACS 4.6 Release Notes | Up | Chapter�2.�Installing on Unix/Linux |
This is the place to look if you want to extend OpenACS and build on top - of what's already here. Here you can find out about the guts of the system.
Table of Contents
Prev | Home | Next |
OpenACS Installation Guide for Windows2000 | Up | Chapter 4. OpenACS Developer's Guide |
This is the place to look if you want to extend OpenACS and build on top + of what's already here. Here you can find out about the guts of the system.
Table of Contents
Prev | Home | Next |
OpenACS Installation Guide for Windows2000 | Up | Chapter�4.�OpenACS Developer's Guide |
+
by Bryan Quinn
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
Tcl API
Tcl API
apm-install-procs.tcl (Supports installation of packages)
20-apm-load-procs.tcl (Bootstraps APM for server startup)
-apm-admin-procs.tcl (Supports APM UI)
PL/SQL file
PL/SQL file
+In general terms, a package is a unit of software that serves a single well-defined purpose. That purpose may be to provide a service directly to one or more classes of end-user, (e.g., discussion forums and file storage for community members, user profiling tools for the site publisher), or it may be to act as a building block for other packages (e.g., an application programming interface (API) for storing and querying access control rules, or an API for scheduling email alerts). Thus, packages fall into one of two categories: -
OpenACS Applications: a "program or group of programs +
OpenACS Applications: a "program or group of programs designed for end users" (the Webopedia definition); also known as modules, for historical reasons. Examples of applications include Bboard and News. -
OpenACS Services: the aforementioned building blocks. +
OpenACS Services: the aforementioned building blocks. Examples of services include the OpenACS Content Repository, the OpenACS Templating -System, and the OpenACS Kernel, which includes +System, and the OpenACS Kernel, which includes APM.
An installation of the OpenACS includes the OpenACS Kernel, some services that extend the kernel's functionality, and some applications intended for end-users. Packages function as individual pieces of subsites. A subsite can contain multiple @@ -89,21 +89,21 @@ packages for other ACS users to download and install.
For a simple illustration of the difference between ACS without APM (pre-3.3) and ACS with APM (3.3 and beyond), consider a hypothetical ACS installation that uses only two of the thirty-odd modules available circa ACS -3.2 (say, bboard and e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS +3.2 (say, bboard and e-commerce):
APM itself is part of a package, the OpenACS Kernel, an OpenACS service that is the only mandatory component of an OpenACS installation.
The OpenACS is a platform for web-based application software, and any software platform has the potential to develop problems like those described above. Fortunately, there are many precedents for systematic solutions, including:
Borrowing from all of the above, OpenACS 3.3 introduces its own package -management system, the OpenACS Package Manager (APM), which consists of:
a standard format for APM packages (also called -"OpenACS packages"), including:
version numbering, independent of any other package and the OpenACS as a -whole
specification of the package interface
specification of dependencies on other packages (if any)
attribution (who wrote it) and ownership (who maintains it)
web-based tools for package management:
obtaining packages from a remote distribution point
installing packages, if and only if:
all prerequisite packages are installed
no conflicts will be created by the installation
configuring packages (obsoleting the monolithic OpenACS configuration -file)
upgrading packages, without clobbering local modifications
uninstalling unwanted packages
a registry of installed packages, database-backed and +management system, the OpenACS Package Manager (APM), which consists of:
a standard format for APM packages (also called +"OpenACS packages"), including:
version numbering, independent of any other package and the OpenACS as a +whole
specification of the package interface
specification of dependencies on other packages (if any)
attribution (who wrote it) and ownership (who maintains it)
web-based tools for package management:
obtaining packages from a remote distribution point
installing packages, if and only if:
all prerequisite packages are installed
no conflicts will be created by the installation
configuring packages (obsoleting the monolithic OpenACS configuration +file)
upgrading packages, without clobbering local modifications
uninstalling unwanted packages
a registry of installed packages, database-backed and integrated with filesystem-based version control -
web-based tools for package development:
creating new packages locally
releasing new versions of locally-created packages
The design chosen for APM was meant to satisfy the following constraints:
The process of authoring a package must be as simple as possible.
Strict conventions must be established that provide a set of canonical locations and names for files and patterns, for OpenACS application @@ -124,7 +124,7 @@ subsites across the system, and be available for distribution to other OpenACS installations without doing a monolithic upgrade or reinstall.
The APM is composed of systems for accomplishing a set of package-related tasks. Each of these tasks comprise a feature area that has an API, data -model, and a UI:
Authoring a Package
Maintaining Multiple Versions of a Package
Creating Instances of the Package
Specifying Configuration Parameters for each Instance
Authoring a Package
Full instructions on how to prepare an OpenACS package are available in Packages. The API here can be invoked manually by a package's data model +model, and a UI:
Authoring a Package
Maintaining Multiple Versions of a Package
Creating Instances of the Package
Specifying Configuration Parameters for each Instance
Authoring a Package
Full instructions on how to prepare an OpenACS package are available in Packages. The API here can be invoked manually by a package's data model creation script, but need not to be used. This API is part of the APM PL/SQL package.
@@ -165,7 +165,7 @@ package_key in apm_package_types.package_key%TYPE ) return integer; -
Maintaining Multiple Versions of a Package
While the package authoring API provides a means for registering a +
Maintaining Multiple Versions of a Package
While the package authoring API provides a means for registering a package, some information about a package is version dependent. For example, between versions, the owner of a package, its vendor, its URI, and its dependency information may change. The API for package versions allows this @@ -245,7 +245,7 @@ );
Files associated with a version can be added and removed. The path is -relative to the package-root which is +relative to the package-root which is acs-server-root/packages/package-key.
-- Add a file to the indicated version. function add_file( @@ -327,7 +327,7 @@ version_name_two in apm_package_versions.version_name%TYPE ) return integer; -
Creating Instances of a Package
Once a package is registered in the system, it is possible to create +
Creating Instances of a Package
Once a package is registered in the system, it is possible to create instances of it. Each instance can maintain its own content and parameters.
@@ -382,7 +382,7 @@ show errors -
Specifying Configuration Parameters for each Instance
A parameter is a setting that can be changed on a package instance basis. +
Specifying Configuration Parameters for each Instance
A parameter is a setting that can be changed on a package instance basis. Parameters are registered on each package_key, and the values are associated with each instance. Parameters can have default values and can be of type 'string' or 'number.' There is support with this @@ -513,14 +513,14 @@ site-wide administration.
APM has two parameters for configuring how it interacts with the UNIX filesystem, accessible via the Site Map admin page. These parameters need not be changed under most circumstances, but may -need to be tweaked for Windows compatibility.
GzipExecutableDirectory +need to be tweaked for Windows compatibility.
GzipExecutableDirectory This directory points to where the gunzip program can be found for uncompressing gzip archives. This is needed for the installation of .apm files which are simply gziped tarballs. Default is /usr/local/bin -
InfoFilePermissionsMode +
InfoFilePermissionsMode This sets the default UNIX permissions used when creating files using the APM. Default is 775.
APM has been in production since OpenACS 3.3, and as of version 4.0 offers a stable set of features. One major feature planned is integration with the OpenACS @@ -542,6 +542,4 @@ all of this functionality in one interface and it can be confusing from a usability perspective.
System creator: Bryan Quinn, Jon Salz, Michael Yoon, Lars Pind, Todd Nightingale.
System owner: Bryan Quinn
Documentation author: Bryan Quinn, building from earlier versions by Jon -Salz, Michael Yoon, and Lars Pind.
Prev | Home | Next |
OpenACS 4.5 Package Manager Requirements | Up | OpenACS 4 Security Requirements |
Prev | Home | Next |
OpenACS 4.6 Package Manager Requirements | Up | OpenACS 4 Security Requirements |
+
by Bryan Quinn and Todd Nightingale
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
The following is a requirements document for the OpenACS Package Manager + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
The following is a requirements document for the OpenACS Package Manager (APM), version 4.0 (APM4). APM4 offers a superset of APM v3.3 functionality with the following specific enhancements:
A public procedural API. (v 3.3 only has web-based UI)
Support for dependency checking.
Support for compound packages (to support installation chaining).
Support for on-line parameter setting.
Support for sub-site level configuration (requires revised ad_parameter and /admin pages at sub-site level; deprecation of site-wide parameter file).
To differentiate these new requirements from the requirements of version 3.3, all requirements new in v4 are prefaced with the number -4.
We gratefully acknowledge the authors of APM 3 for their original design +4.
We gratefully acknowledge the authors of APM 3 for their original design documentation which suggested these features, as well as the influence of the design and open-source implementation of the Red Hat Package manager, the Debian packaging system, and PERL's CPAN in the development of the ideas @@ -29,36 +29,36 @@ packaging, installing, and configuring OpenACS software in a consistent, user-friendly, and subsite-aware manner.
The OpenACS Package Manager (APM) consists of: -
A standard format for APM packages including:
Version numbering, independent of any other package and the OpenACS as a -whole
Specification of the package interface
Specification of dependencies on other packages (if any)
Attribution (who wrote it) and ownership (who maintains it)
Web-based tools for package management:
Obtaining packages from a remote distribution point
Installing packages, if and only if:
All prerequisite packages are installed
No conflicts will be created by the installation
Configuring packages (obsoleting the monolithic OpenACS configuration -file)
Upgrading packages, without clobbering local modifications
Uninstalling unwanted packages
A registry of installed packages, database-backed and +
A standard format for APM packages including:
Version numbering, independent of any other package and the OpenACS as a +whole
Specification of the package interface
Specification of dependencies on other packages (if any)
Attribution (who wrote it) and ownership (who maintains it)
Web-based tools for package management:
Obtaining packages from a remote distribution point
Installing packages, if and only if:
All prerequisite packages are installed
No conflicts will be created by the installation
Configuring packages (obsoleting the monolithic OpenACS configuration +file)
Upgrading packages, without clobbering local modifications
Uninstalling unwanted packages
A registry of installed packages, database-backed and integrated with file system-based version control -
Web-based tools for package development:
Creating new packages locally
Releasing new versions of locally-created packages
Uploading packages to a global package repository on the web
Use of these tools should be safe, i.e. installing or removing a package -should never break an OpenACS installation
Web-based tools for package configuration:
The ability to change package parameter values on-line through a simple +
Web-based tools for package development:
Creating new packages locally
Releasing new versions of locally-created packages
Uploading packages to a global package repository on the web
Use of these tools should be safe, i.e. installing or removing a package +should never break an OpenACS installation
Web-based tools for package configuration:
The ability to change package parameter values on-line through a simple web interface.
A new ad_parameter which does not require a monolithic site-wide parameter's file or server restarts for changes to take effect.
The ability to manage multiple package instances at the sub-site level.
The APM is intended for the following classes of users, which may or may not -overlap:
Developers (referred to as 'the developer') use +overlap:
Developers (referred to as 'the developer') use the APM to create a software package for distribution and use the procedural -API for direct control of the APM system.
Site-wide administrators (referred to as 'the +API for direct control of the APM system.
Site-wide administrators (referred to as 'the administrator') use the APM to install packages for their OpenACS instance, -and optionally make them available to sub-sites.
Sub-site administrators (referred to as 'the +and optionally make them available to sub-sites.
Sub-site administrators (referred to as 'the sub-admin') use an administration interface to configure and enable -packages for their sub-site.
Initial Package Development
David Developer writes a piece of software used to do +packages for their sub-site.
Initial Package Development
David Developer writes a piece of software used to do knowledge management (km) for the OpenACS. He distributes his data model, procedure code, UI pages, and his documentation according to the APM specification. He splits the documentation and the code into sub-packages, and creates a KM installation-chain to install both with the APM developer -UI. Noting that his software was built with Patricia -Programmer's Super Widget toolkit, he specifies that as a +UI. Noting that his software was built with Patricia +Programmer's Super Widget toolkit, he specifies that as a dependency. Moreover, since this package is capable of being used at the sub-site level, David configures this option in the package. When the package development is complete, David uses the APM developer UI to construct a distribution file. He assigns it a version number, 1.0, and makes the package -available for download at the OpenACS package repository.
Initial Package Installation
Annie Admin learns of David's KM system by browsing +available for download at the OpenACS package repository.
Initial Package Installation
Annie Admin learns of David's KM system by browsing the OpenACS package repository. Annie Admin uses the APM administrator UI on her system. She selects to install a package from a URL and types the URL displayed on the system. The APM automatically downloads the package. The @@ -72,16 +72,16 @@ installation was successful, the package is available for use.
Since the package is available for use, its initialization routines are set to run automatically on server startup. Annie is warned that since there are initialization routines, she must restart the server for the package to -be ready for use. Annie restarts the server.
Initial Subsite Use of Package
Annie Admin decides to make the KM module available only to a particular +be ready for use. Annie restarts the server.
Initial Subsite Use of Package
Annie Admin decides to make the KM module available only to a particular sub-site type on her OpenACS system, and not others. She specifies this option -using the Sub-site type UI (not part of APM).
Annie Admin notifies Sally SubAdmin by e-mail that a new +using the Sub-site type UI (not part of APM).
Annie Admin notifies Sally SubAdmin by e-mail that a new package is now available for use. Sally goes to her sub-site /admin page and sees that a new entry, KM, is available. Sally clicks on it and finds links to the installed KM documentation and to the web based configuration utility. Then, Sally configures the package using an automatically generated web interface and enables KM for use on her sub-site. After some initial use of the package, Sally decides to change some parameters using the SubAdmin UI. -These changes take effect immediately, without any server restarts.
Upgrade Process
Sally SubAdmin finds a bug in the KM system and sends a report to David +These changes take effect immediately, without any server restarts.
Upgrade Process
Sally SubAdmin finds a bug in the KM system and sends a report to David Developer. David reads the bug report and verifies that the bugs are present in the current version. Because the bugs are present in the shared procedure file, David assigns a watch to the file. David makes the necessary @@ -92,195 +92,195 @@ repository.
Sally SubAdmin asks Annie Administrator to upgrade the package using the APM UI. This upgrade supersedes the old version of KM at the site-wide level. Once Annie upgrades the package, the new version starts working immediately -in Sally's sub-site.
Procedural API
Danielle Developer wants her software to perform +in Sally's sub-site.
Procedural API
Danielle Developer wants her software to perform different actions depending on what version of another package is installed. She uses the APM procedural API to check if KM version 1.0 is installed or version 1.1. Based on the results of this procedural call, the software -exhibits different behavior.
4.500.0 Package Identification -(All of these items are entered by the developer using the developer UI.)
4.500.1 A human readable package key that is guaranteed +exhibits different behavior.
4.500.0 Package Identification +(All of these items are entered by the developer using the developer UI.)
4.500.1 A human readable package key that is guaranteed to be unique to the local OpenACS site must be maintained by the APM. For -example, "apm."
4.500.5 A package id (primary key) that is guaranteed to +example, "apm."
4.500.5 A package id (primary key) that is guaranteed to be unique to the local site must be maintained by the APM. For example, -"25."
4.500.10 A package URL that is guaranteed to be unique +"25."
4.500.10 A package URL that is guaranteed to be unique across all sites must be maintained by the APM. The package URL should point to a server that allows download of the latest version of the package. For example, "http://openacs.org/software." -
4.505.0 Version Identification - (All of these items are entered by the developer using the developer UI.)
4.505.1 A version id (primary key) that is guaranteed to -be unique to the local site must be maintained by the APM.
4.505.5 A version URL that is guaranteed to be unique +
4.505.0 Version Identification + (All of these items are entered by the developer using the developer UI.)
4.505.1 A version id (primary key) that is guaranteed to +be unique to the local site must be maintained by the APM.
4.505.5 A version URL that is guaranteed to be unique across all sites must be maintained by the APM. The version URL should point to a server that allows download of a specific version of the package.
The API for APM v3 is explicitly a private API. However, it would be useful to obtain information from the APM through a procedural API. Implementing the API specified below is quite easy given that there are pages -that already do all of the below in raw SQL.
4.400.0 Packages Status Predicates
4.400.1 Given defining information such as a package URL, +that already do all of the below in raw SQL.
4.400.0 Packages Status Predicates
4.400.1 Given defining information such as a package URL, the APM API can return the status of the package on the local OpenACS -instance.
4.405.0 Package Information Procedures
4.405.1 The APM API can return information for any +instance.
4.405.0 Package Information Procedures
4.405.1 The APM API can return information for any locally installed packages, including the version number, paths and files, -and package key.
4.410.0 Sub-site Procedures
4.410.1 After a package has been installed at the +and package key.
4.410.0 Sub-site Procedures
4.410.1 After a package has been installed at the site-wide level, the system API will provide means to check for package -presence, creation, enabling, disabling, and destruction on a subsite.
4.415.0 Parameter Values (replaces ad_parameter)
4.415.1 The system API shall allow subsite parameters for +presence, creation, enabling, disabling, and destruction on a subsite.
4.415.0 Parameter Values (replaces ad_parameter)
4.415.1 The system API shall allow subsite parameters for an installed package to be set by either site-wide administrators or sub-site admins. The subsite parameter can be set to be non-persistent (but default is to survive server restarts). The subsite parameter can also be set to only -take effect after a server restart (default is immediate).
4.415.5 Parameters for a given subsite and package can be +take effect after a server restart (default is immediate).
4.415.5 Parameters for a given subsite and package can be returned by the system API.
Provisions will be made to assure that packages are securely -identified.
4.600.1 Each package will have a PGP signature and there +identified.
4.600.1 Each package will have a PGP signature and there will be MD5 time stamps for each file within the package. -
4.600.5 The APM will provide a facility to validate both +
4.600.5 The APM will provide a facility to validate both the PGP signature and MD5 stamps information before a package install.
The user interface is a set of HTML pages that are used to drive the underlying API. It is restricted to site-wide administrators because the actions taken here can dramatically affect the state of the running OpenACS.
The intent of the developer's interface is to enable the developer to construct and maintain APM packages. It will be possible to disable the developer's interface for production sites to help reduce the chance of site failure; much of the functionality here can have cascading effects -throughout the OpenACS and should not be used on a production site.
10.0 Define a package.
The developer must be able to create a new package by specifying some +throughout the OpenACS and should not be used on a production site.
10.0 Define a package.
The developer must be able to create a new package by specifying some identifying information for the package. This includes a package name, a -package key, version information, owner information, and a canonical URL.
10.1 The APM must maintain the state of all locally -generated packages.
10.50 If the developer fails to provide the required -information, the package cannot be created.
10.55 All of the package information should be editable -after creation, except for the package key.
4.10.60 The package creator must specify whether the +package key, version information, owner information, and a canonical URL.
10.1 The APM must maintain the state of all locally +generated packages.
10.50 If the developer fails to provide the required +information, the package cannot be created.
10.55 All of the package information should be editable +after creation, except for the package key.
4.10.60 The package creator must specify whether the package is capable of being used in sub-sites, or if only a single, global -instance of the package is permitted.
4.10.65 If the developer fails to provide unique +instance of the package is permitted.
4.10.65 If the developer fails to provide unique information for unique fields specified in the data model requirements, the -package cannot be created.
20.0 Add files to a package
20.1 The developer must be able to add files to the +package cannot be created.
20.0 Add files to a package
20.1 The developer must be able to add files to the package. This is done by copying the files into the package directory in the host OS's file system. Files can be added at any point after package -creation.
20.3 Once a package has been versioned and distributed, +creation.
20.3 Once a package has been versioned and distributed, no new files should be added to the package without incrementing the version -number.
20.5 The APM's UI should facilitate the process of +number.
20.5 The APM's UI should facilitate the process of adding new files, by scanning the file system for new files automatically, -and allowing the developer to confirm adding them.
20.10 The developer cannot add files to a given package -via the UI that do not exist in the file system already.
20.15 Package file structure must follow a specified -convention. Please see the design -document for what we do currently.
30.0 Remove files from a package
The developer must be able to remove files from a package. This can be -done in two ways.
30.1 Access the APM UI, browse the file list, and remove -files.
30.1.1If a file is removed from the package list, but not -from the file system, an error should be generated at package load time.
30.5 Remove the file from file system.
30.5.1 The APM UI should take note of the fact that the +and allowing the developer to confirm adding them.
20.10 The developer cannot add files to a given package +via the UI that do not exist in the file system already.
20.15 Package file structure must follow a specified +convention. Please see the design +document for what we do currently.
30.0 Remove files from a package
The developer must be able to remove files from a package. This can be +done in two ways.
30.1 Access the APM UI, browse the file list, and remove +files.
30.1.1If a file is removed from the package list, but not +from the file system, an error should be generated at package load time.
30.5 Remove the file from file system.
30.5.1 The APM UI should take note of the fact that the file is gone and offer the developer an option to confirm the file's deletion. -
40.0 Modify files in a package.
40.1 The developer should be able to modify files in the -file system. The APM UI should not interfere with this.
40.5 However, if the developer modifies files containing -procedural definitions, APM UI should allow a means to watch +
40.0 Modify files in a package.
40.1 The developer should be able to modify files in the +file system. The APM UI should not interfere with this.
40.5 However, if the developer modifies files containing +procedural definitions, APM UI should allow a means to watch those files and automatically reload them if changed. See requirement 50.0 -for more detail.
40.10 Also, although a change in files implies that the +for more detail.
40.10 Also, although a change in files implies that the package distribution file is out of date, it is the developer's -responsibility to update it.
4.45.0 Manage Package Dependency Information.
4.45.1 The developer should be able to specify which -interfaces the package requires.
4.45.5 The developer should be able to specify which -interfaces the package provides.
4.45.10 Circular dependencies are not allowed.
50.0 Watch a file
4.50.1 The developer should be able to assign a watch to -any Tcl procedure file, whether in /packages or /tcl.
50.5 If a watched file is locally modified, then it will +responsibility to update it.
4.45.0 Manage Package Dependency Information.
4.45.1 The developer should be able to specify which +interfaces the package requires.
4.45.5 The developer should be able to specify which +interfaces the package provides.
4.45.10 Circular dependencies are not allowed.
50.0 Watch a file
4.50.1 The developer should be able to assign a watch to +any Tcl procedure file, whether in /packages or /tcl.
50.5 If a watched file is locally modified, then it will be automatically reloaded, thus allowing for any changes made to take affect -immediately.
4.50.10 The setting of a watch should be persistent +immediately.
4.50.10 The setting of a watch should be persistent across server restarts. -
60.0 Display an XML package specification
60.1 The developer should be able to view the XML package +
60.0 Display an XML package specification
60.1 The developer should be able to view the XML package specification that encodes all package information. -
70.0 Write an XML package specification to the file -system
70.1 The developer should be able to write an up-to-date -XML specification to disk.
70.5 The developer should be able to request the current -XML specification for all installed, locally generated packages.
130.0 Distribution file generation
130.1 The developer should be able to generate a .APM -distribution file for the package with just one click.
130.5 Generating a distribution file implies doing an +
70.0 Write an XML package specification to the file +system
70.1 The developer should be able to write an up-to-date +XML specification to disk.
70.5 The developer should be able to request the current +XML specification for all installed, locally generated packages.
130.0 Distribution file generation
130.1 The developer should be able to generate a .APM +distribution file for the package with just one click.
130.5 Generating a distribution file implies doing an "up-to-date" check on all of the files. If any of the files have changed since package installation, then a new version of the package is created. -
140.0 Access CVS information
140.1 The developer should be able to determine the CVS +
140.0 Access CVS information
140.1 The developer should be able to determine the CVS status of a package, or all packages, with a single click. -
4.200.0 Compound Package Construction
4.200.1 The developer can include .APM packages +
4.200.0 Compound Package Construction
4.200.1 The developer can include .APM packages (sub-packages) within a package (the compound package) like any other -file.
4.200.5 The recommended usage for this feature is to +file.
4.200.5 The recommended usage for this feature is to allow for separation of optional and required components from the installation as well as better organization of files once installed. For example, all documentation for the community-core can be packages as community-core-doc.apm. It is legal to include sub-packages with dependencies that are not satisfied by the packages in the compound package, but this is discouraged. In such a case, the sub-package should really be a -separate package that is required by the compound package.
4.200.10 If a sub-package is required for the +separate package that is required by the compound package.
4.200.10 If a sub-package is required for the installation of the compound package, the compound package should have a registered dependency on the sub-package.
The requirement of the administrator's interface is to enable the administrator to install, enable, upgrade, disable, deinstall, and delete -packages.
80.0 Package Enable/Disable
4.80.1 The administrator should be able mark an installed +packages.
80.0 Package Enable/Disable
4.80.1 The administrator should be able mark an installed package as enabled. This means that the package is activated and its functionality is delivered through the Request Processor. As of OpenACS 4, this -is done through the sub-site system.
4.80.5 Moreover, the administrator must be able to +is done through the sub-site system.
4.80.5 Moreover, the administrator must be able to disable a package, thereby removing the functionality provided to a sub-site. As of OpenACS 4, this is done through the sub-site system. -
90.0 Package Install
90.1 The administrator must be able to install new -packages either from locally maintained .APM files or from URLs.
90.5 In the case of an URL, the APM transparently +
90.0 Package Install
90.1 The administrator must be able to install new +packages either from locally maintained .APM files or from URLs.
90.5 In the case of an URL, the APM transparently downloads the APM file off the web, proceeds with a file based installation, -and then optionally removes the .APM file just downloaded.
90.10.1 If .APM files are present in a package, then it -is considered a compound package (use 4.210.0).
90.15.0 Installation requires these steps:
90.15.1The package dependencies are scanned. If some +and then optionally removes the .APM file just downloaded.
90.10.1 If .APM files are present in a package, then it +is considered a compound package (use 4.210.0).
90.15.0 Installation requires these steps:
90.15.1The package dependencies are scanned. If some dependencies are not present, the system warns the administrator that -installation cannot proceed until those packages are installed.
90.15.2 Assuming all dependencies are present, APM -extracts the contents of the APM file into the /packages directory.
90.15.3 The administrator is offered the option of -importing directly into CVS.
90.15.4 The administrator is given a list of data model -scripts found in the package and can select which ones to be executed.
90.15.5 If no errors are recorded during this process, -the package is enabled.
4.210.0 Compound package Install
4.210.1 If .APM files are present in a package, then it -is considered a compound package.
4.210.5.0 Installation of a compound package proceeds -according to the following sequence:
4.210.5.1 Identify the set of all sub-packages within -the compound package by scanning for all files with .APM.
4.210.5.2 Identify which sub-packages are required by +installation cannot proceed until those packages are installed.
90.15.2 Assuming all dependencies are present, APM +extracts the contents of the APM file into the /packages directory.
90.15.3 The administrator is offered the option of +importing directly into CVS.
90.15.4 The administrator is given a list of data model +scripts found in the package and can select which ones to be executed.
90.15.5 If no errors are recorded during this process, +the package is enabled.
4.210.0 Compound package Install
4.210.1 If .APM files are present in a package, then it +is considered a compound package.
4.210.5.0 Installation of a compound package proceeds +according to the following sequence:
4.210.5.1 Identify the set of all sub-packages within +the compound package by scanning for all files with .APM.
4.210.5.2 Identify which sub-packages are required by checking the dependencies of the compound package. If there dependencies not satisfied by the current system or the packages included with the compound package, halt installation and inform user to install these packages -first.
4.210.5.3 Present Administrator with the ability to +first.
4.210.5.3 Present Administrator with the ability to choose which sub-packages to install. Required sub-packages must be -installed.
4.210.5.4 Proceed with the installation of each +installed.
4.210.5.4 Proceed with the installation of each sub-package, starting with required packages. If the sub-package is already installed, then do nothing. Else, If the sub-package is a normal package, -proceed according to 90.15.0, otherwise if it is a compound -package, proceed according to 4.210.5.0.
4.210.5.5 If all required sub-packages are installed, +proceed according to 90.15.0, otherwise if it is a compound +package, proceed according to 4.210.5.0.
4.210.5.5 If all required sub-packages are installed, proceed to install non-required sub-packages. If there was a failure during the installation of a required sub-package, then the installation of the -compound package is also a failure.
4.210.5.6 Any attempt to install a compound package in +compound package is also a failure.
4.210.5.6 Any attempt to install a compound package in the future involves a choice presented to the admin of installing any -uninstalled sub-packages.
4.220.0 Recovering from failed package installation
4.220.1 If any error is generated during package +uninstalled sub-packages.
4.220.0 Recovering from failed package installation
4.220.1 If any error is generated during package installation, the package is not considered installed. To recover from this -failure, the package should be selected for installation again.
100.0 Version Upgrade
100.1 The administrator can upgrade to a new version of a -package. This entails
100.1.1 Running any necessary and included upgrade -scripts.
100.1.5 Replacing any old files with new versions.
100.1.10 Marking the old version of the package as -'superseded' and disabling it.
100.1.15 Assuming no errors from above, the new package -is enabled.
110.0 Package Deinstall
110.1 The administrator must be able to deinstall a -package that has already been installed. Deinstallation entails:
110.1.1 Running any data model scripts necessary to drop -the package.
110.1.5 Moving all of the files into a separate location -in the file system from the installed packages.
4.110.1.10 If the package is a compound package, then +failure, the package should be selected for installation again.
100.0 Version Upgrade
100.1 The administrator can upgrade to a new version of a +package. This entails
100.1.1 Running any necessary and included upgrade +scripts.
100.1.5 Replacing any old files with new versions.
100.1.10 Marking the old version of the package as +'superseded' and disabling it.
100.1.15 Assuming no errors from above, the new package +is enabled.
110.0 Package Deinstall
110.1 The administrator must be able to deinstall a +package that has already been installed. Deinstallation entails:
110.1.1 Running any data model scripts necessary to drop +the package.
110.1.5 Moving all of the files into a separate location +in the file system from the installed packages.
4.110.1.10 If the package is a compound package, then the administrator must confirm removing all sub-packages. Optionally, some -sub-packages can be kept.
110.5 Deinstalled packages can be re-installed at a later -date.
4.110.10 If deinstalling a package or any of its +sub-packages can be kept.
110.5 Deinstalled packages can be re-installed at a later +date.
4.110.10 If deinstalling a package or any of its sub-packages breaks a dependency, then deinstallation cannot proceed until -the package registering the dependency is removed.
120.0 Package Deletion
120.1 The administrator should be able to completely +the package registering the dependency is removed.
120.0 Package Deletion
120.1 The administrator should be able to completely erase all records of the package. This involves removing all instances of the -package, all related database tables and content.
120.5 This option can only be used if all package +package, all related database tables and content.
120.5 This option can only be used if all package instances are deleted or marked as disabled. This is purposefully cumbersome because deleting all instances of a package can have far-sweeping -consequences throughout a site and should almost never be done.
150.0 Scan for new or modified packages
150.1 The administrator should be able to scan the file -system for any changes made in any of the installed package files.
150.5 The administrator should be able to scan the file +consequences throughout a site and should almost never be done.
150.0 Scan for new or modified packages
150.1 The administrator should be able to scan the file +system for any changes made in any of the installed package files.
150.5 The administrator should be able to scan the file system for any newly installed packages.
If the developer is in charge of creating packages and the administrator for installing them, then the sub-site administrator is responsible for configuring and enabling packages. In order for a package to be available for a sub-site it must be associated with the sub-site's type specification. This interface is part of the sub-site /admin interface. -
4.300 Creating a package instance.
4.300.1 From the sub-site /admin interface, there should +
4.300 Creating a package instance.
4.300.1 From the sub-site /admin interface, there should be an option to view all packages available in the system as well as an -option to add a package to the subsite.
4.300.5 From the "add" option, the sub-admin +option to add a package to the subsite.
4.300.5 From the "add" option, the sub-admin can select from a list of packages registered as available in the sub-site -type to which the sub-site belongs.
4.300.19 Once a package instance is added, it is -available on the list of the subsite's available packages.
4.305 Configuring a package instance.
4.305.1 An automatic web interface that lists all -parameters with current values must be available.
4.305.5 Changing the values for the parameters is -accomplished simply by submitting an HTML form.
4.310 Enabling a package instance.
4.310.1 The sub-admin should be able to enable a package +type to which the sub-site belongs.
4.300.19 Once a package instance is added, it is +available on the list of the subsite's available packages.
4.305 Configuring a package instance.
4.305.1 An automatic web interface that lists all +parameters with current values must be available.
4.305.5 Changing the values for the parameters is +accomplished simply by submitting an HTML form.
4.310 Enabling a package instance.
4.310.1 The sub-admin should be able to enable a package with a single click. Enabling a package means that the OpenACS will serve its URLs properly. -
4.315 Disabling a package instance.
4.315.1 The sub-admin should be able to disable a package +
4.315 Disabling a package instance.
4.315.1 The sub-admin should be able to disable a package with a single click. Disabling a package means that the OpenACS will no longer -serve those URLs.
4.320 Deleting a package instance.
4.320.1 Deleting a package instance involves deleting not +serve those URLs.
4.320 Deleting a package instance.
4.320.1 Deleting a package instance involves deleting not only the package instance, but any and all content associated with it. It is questionable whether this option should even be available due to its drastic consequences. Reviewer comments appreciated. @@ -293,6 +293,4 @@ are set using the acs_attribute_values table. The automatic web interface for setting package parameters should be one and the same with the interface for setting acs object attribute values. Consequently, the implementation of -these features should be quite straightforward.
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
� | Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Subsites Design Document | Up | OpenACS 4.5 Package Manager Design |
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/10/2000 | Bryan Quinn, Todd Nightingale |
� | Reviewed | 8/11/2000 | John Prevost, Mark Thomas, and Pete Su |
0.2 | Revised and updated | 8/12/2000 | Bryan Quinn |
0.3 | Reviewed, revised, and updated - conforms to requirements template. | 8/18/2000 | Kai Wu |
0.4 | Minor edits before ACS 4 Beta. | 9/30/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Subsites Design Document | Up | OpenACS 4.6 Package Manager Design |
Prev | Home | Next |
Part Part III. For OpenACS Developers | Up | Overview |
Prev | Home | Next |
Part�Part III.�For OpenACS Developers | Up | Overview |
Prev | Home | Next |
Chapter 4. OpenACS Developer's Guide | Up | OpenACS 4.5 Packages |
Prev | Home | Next |
Chapter�4.�OpenACS Developer's Guide | Up | OpenACS 4.6 Packages |
+
By claus@arsdigita.com, with additions by Roberto Mello and the OpenACS Community -
+
ArsDigita created a good documentation ground for us to build upon. Some sections of the documentation, however, lack details and examples; others are simply nonexistant. Our goal is to give OpenACS a superb documentation, so that users, developers and administrators of OpenACS installations can enjoy the system.
- OpenACS™ is a powerful system, with + OpenACS is a powerful system, with incredible possibilities and applications, but with this power comes some complexity and a learning curve that will only be atenuated by good documentation. This is what we are after.
- The documentation for OpenACS™ is + The documentation for OpenACS is written using DocBook XML. The reasons why we are using DocBook are explained in more details in the Why DocBook? section. I will add the reasons why @@ -32,31 +32,31 @@ In order to separate content and presentation, all OpenACS documentation will be marked up to conform to the DocBook XML DTD - + This enables us to publish in a variety of formats and relieves each contributor of the burden of presentation, freeing him to focus on content and sharing knowledge.
Theoretically any strict DTD would have been sufficient - we could even write our own. But DocBook has been around - for a while (since early 90's), + for a while (since early 90's), it's well-tested, it's complete, it's extremely well-suited for technical documents and best of all, it's open-source. A growing community surrounds DocBook (has - mailing lists) + mailing lists) and a number of free and commercial - tools are available + tools are available for editing and publishing DocBook documents.
This primer walks you through the basics, and should cover the needs for 95 percent of the documentation we produce. However, you're always welcome to check out DocBook's - + list of elements and use more exotic features in your documents. The list is made up of SGML-elements but basically - the same elements are valid in the XML DTD as long as you remember to: - + the same elements are valid in the XML DTD as long as you remember to: +
Always close your tags with corresponding end-tags and to - not use other tag minimization + not use other tag minimization
Write all elements and attributes in lowercase
@@ -99,22 +99,22 @@ The documentation for each package will make up a little "book" that is structured like this - examples are emphasized: - +
- book : Docs for one package - templating + book : Docs for one package - templating | - +--chapter : One section - for developers + +--chapter : One section - for developers | ---------+------------------------------------------------------ | - +--sect1 : Single document - requirements + +--sect1 : Single document - requirements | - +--sect2 : Sections - functional requirements + +--sect2 : Sections - functional requirements | - +--sect3 : Subsections - Programmer's API + +--sect3 : Subsections - Programmer's API | - ... : ... + ... : ...
The actual content is split up into documents that start at a sect1-level. These are then tied together in a top-level document that @@ -123,20 +123,20 @@ sources of these DocBook documents to get an idea of how they are tied together.
- + Given that your job starts at the sect1-level, all your documents should open with a <sect1>-tag and end with the corresponding </sect1>.
- + You need to feed every <sect1> two attributes. The first attribute, id, is standard and can be used with all elements. It comes in very handy when interlinking between documents (more about this when talking about links in the section called “Links”). The value of id has to be unique throughout the book you're making since the id's in your sect1's will turn into filenames when the book is parsed into HTML.
- + The other attribute is xreflabel. The value of this is the text that will appear as the link when referring to this sect1.
@@ -151,7 +151,7 @@ </sect1>
- + Inside this container your document will be split up into <sect2>'s, each with the same requirements - id and xreflabel @@ -160,7 +160,7 @@ When it comes to naming your sect2's and below, prefix them with some abbreviation of the id in the sect1 such as requirements-overview.
- + For displaying a snippet of code, a filename or anything else you just want to appear as a part of a sentence, we will use the tag <computeroutput>. @@ -170,12 +170,12 @@ <programlisting> is used. Just wrap your code block in it; mono-spacing, indents and all that stuff is taken care of automatically.
- + Linking falls into two different categories: inside the book you're making and outside: -
+
By having unique id's you can cross-reference any part of your book with a simple tag, regardless of where that part is. -
Check out how I link to a subsection of the Developer's Guide:
+Check out how I link to a subsection of the Developer's Guide:
Put this in your XML: @@ -212,8 +212,8 @@ Note that since I haven't provided an xreflabel for the subsection, packages-looks, the parser will try its best to explain where the link takes you. -
+ If you're hyper-linking out of the documentation, it works almost the same way as HTML - the tag is just a little different @@ -222,19 +222,19 @@
<ulink url="http://www.oracle.com/">Oracle Corporation</ulink>
....will create a hyper-link to Oracle in the HTML-version of the documentation. -
NOTE: Do NOT use ampersands in your hyper links. These are reserved for referencing +
NOTE: Do NOT use ampersands in your hyper links. These are reserved for referencing entities, which is exactly how you'll make an ampersand: &
- NOTE: Currently this section currently only takes HTML-output into consideration - + NOTE: Currently this section currently only takes HTML-output into consideration - not a printed version
- Another Note: Also, it's still not a 100 percent sure that this is how we are going to + Another Note: Also, it's still not a 100 percent sure that this is how we are going to do it, so if you want to start converting your documents right away, start out with the ones without graphics ;)
- + To insert a graphic we use the elements <mediaobject>, <imageobject>, @@ -260,9 +260,9 @@ Put your graphics in a separate directory ("images") and link to them only with relative paths.
- + Here's how you make the DocBook equivalent of the three usual HTML-lists: -
+
Making an unordered list is pretty much like doing the same thing in HTML - if you close your <li>, that is. The only differences are that each list item has to be wrapped in something more, such as <para>, and that the tags are called <itemizedlist> @@ -271,20 +271,20 @@
<itemizedlist> - <listitem><para>Stuff goes here</para><listitem> - <listitem><para>More stuff goes here</para><listitem> + <listitem><para>Stuff goes here</para></listitem> + <listitem><para>More stuff goes here</para></listitem> </itemizedlist> -
+
The ordered list is like the preceding, except that you use <orderedlist> instead:
<orderedlist> - <listitem><para>Stuff goes here</para><listitem> - <listitem><para>More stuff goes here</para><listitem> + <listitem><para>Stuff goes here</para></listitem> + <listitem><para>More stuff goes here</para></listitem> </orderedlist> -
+
This kind of list is called a variablelist and these are the tags you'll need to make it happen: <variablelist>, @@ -295,17 +295,17 @@ <varlistentry> <term>Heading (<dt>) goes here</term> - <listitem><para>And stuff (<dd>)goes here</para><listitem> + <listitem><para>And stuff (<dd>)goes here</para></listitem> </varlistentry> <varlistentry> <term>Another heading goes here</term> - <listitem><para>And more stuff goes here</para><listitem> + <listitem><para>And more stuff goes here</para></listitem> </varlistentry> </variablelist>
- + DocBook supports several types of tables, but in most cases, the <informaltable> is enough: @@ -342,7 +342,7 @@ <table> for an example.
- + Our documentation uses two flavors of emphasis - italics and bold type. DocBook uses one - <emphasis>.
@@ -376,7 +376,7 @@
bash$ xsltproc -o outputfilename.xml /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/html/html.xsl filename.xml
In the process of transforming your HTML into XML, - HTML tidy + HTML tidy can be a a handy tool to make your HTML "regexp'able". Brandoch Calef has made a Perl script @@ -421,6 +421,4 @@
Prev | Home | Next |
Chapter 6. Engineering Standards | Up | Using PSGML mode in Emacs |
Prev | Home | Next |
Chapter�6.�Engineering Standards | Up | Using PSGML mode in Emacs |
Prev | Home | Next |
Programming with AOLserver | Up | OpenACS Documentation Guide |
Prev | Home | Next |
Programming with AOLserver | Up | OpenACS Documentation Guide |
High level information: What is OpenACS?
Table of Contents
Prev | Home | Next |
OpenACS Documentation | Up | Chapter 1. High level information: What is OpenACS? |
High level information: What is OpenACS?
Table of Contents
Prev | Home | Next |
OpenACS Documentation | Up | Chapter�1.�High level information: What is OpenACS? |
Table of Contents
Prev | Home | Next |
Part Part I. OpenACS For Everyone | Up | Overview |
Table of Contents
+
by Rafael H. Schloming and Mark Thomas
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
User directory
Sitewide administrator directory
Subsite administrator directory
TCL script directory
Data model
PL/SQL file
ER diagram
Transaction flow diagram
Almost all database-backed websites have users, and need to model the grouping of users. The OpenACS 4 Parties and Groups system is intended to provide the flexibility needed to model complex real-world organizational structures, @@ -62,16 +62,16 @@
The set of direct membership relationships between a group and a party.
A mapping of a party P to the groups -{Gi}the party is a member of; this mapping +
A mapping of a party P to the groups +{Gi}the party is a member of; this mapping includes the type of relationship by including the appropriaterel_id from the membership_rels table.
The set of direct component relationships between a group and another group.
A mapping of a group Gto the set of groups -{Gi} that G is a component of; +
A mapping of a group Gto the set of groups +{Gi} that G is a component of; this mapping includes the type of relationship by including the appropriaterel_id from the composition_rels table.
New groups are created through the group.new constructor. When a specialized type of group is required, the group type can be extended @@ -116,26 +116,26 @@
A person may appear in the group member map multiple times, for example, by being a member of two different groups that are both components of a third -group. This view is strictly a mapping of approved members +group. This view is strictly a mapping of approved members to groups.
A mapping of a group Gto the set of groups -{Gi} group G is a component of; +
A mapping of a group Gto the set of groups +{Gi} group G is a component of; this mapping includes the type of relationship by including the appropriaterel_id from the composition_rels table.
A mapping of a party P to the set of parties -{Pi} party P is a member +
A mapping of a party P to the set of parties +{Pi} party P is a member of.
A mapping of a party P to the set of parties -{Pi} party P is an -approved member of.
The API consists of tables and views and PL/SQL functions.
The group_types table is used to create new types of groups.
The group_member_map, group_approved_member_map, group_distinct_member_map, group_component_map, party_member_map, and party_approved_member_map views are -used to query group membership and composition.
Person
person.new creates a new person and returns the +used to query group membership and composition.
Person
person.new creates a new person and returns the person_id. The function must be given the full name of the person in two pieces: first_names and last_name. All other fields are optional and default to null except for object_type which defaults @@ -162,7 +162,7 @@ function person.name ( person_id persons.person_id%TYPE ) return varchar; -
User
acs_user.new creates a new user and returns the user_id. +
User
acs_user.new creates a new user and returns the user_id. The function must be given the user's email address and the full name of the user in two pieces: first_names and last_name. All other fields are optional. The interface for this function is:
@@ -204,7 +204,7 @@ procedure acs_user.unapprove_email ( user_id users.user_id%TYPE ); -
Group
acs_group.new creates a new group and returns the +
Group
acs_group.new creates a new group and returns the group_id. All fields are optional and default to null except for object_type which defaults to 'group', creation_date which defaults to sysdate, and @@ -232,7 +232,7 @@ group_id groups.group_id%TYPE, party_id parties.party_id%TYPE, ) return char; -
Membership Relationship
membership_rel.new creates a new membership relationship type +
Membership Relationship
membership_rel.new creates a new membership relationship type between two parties and returns the relationship type's rel_id. All fields are optional and default to null except for rel_type which defaults to membership_rel. The interface for this function is:
@@ -278,7 +278,7 @@ procedure membership_rel.delete ( rel_id membership_rels.rel_id%TYPE ); -
Composition Relationship
composition_rel.new creates a new composition relationship type +
Composition Relationship
composition_rel.new creates a new composition relationship type and returns the relationship's rel_id. All fields are optional and default to null except for rel_type which defaults to composition_rel. The interface for this function is:
@@ -301,6 +301,4 @@
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 08/22/2000 | Rafael H. Schloming |
0.2 | Initial Revision | 08/30/2000 | Mark Thomas |
0.3 | Additional revisions; tried to clarify membership/compostion | 09/08/2000 | Mark Thomas |
Prev | Home | Next |
OpenACS 4 Groups Requirements | Up | OpenACS 4 Subsites Requirements |
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 08/22/2000 | Rafael H. Schloming |
0.2 | Initial Revision | 08/30/2000 | Mark Thomas |
0.3 | Additional revisions; tried to clarify membership/compostion | 09/08/2000 | Mark Thomas |
Prev | Home | Next |
OpenACS 4 Groups Requirements | Up | OpenACS 4 Subsites Requirements |
+
by Rafael H. Schloming, Mark Thomas
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
Almost all database-backed websites have users, and need to model the + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
Almost all database-backed websites have users, and need to model the grouping of users. The OpenACS 4 Parties and Groups system is intended to provide the flexibility needed to model complex real-world organizational structures, particularly to support powerful subsite services; that is, where one OpenACS @@ -16,7 +16,7 @@ person who is employed by (is a member of) a specific department is also a member of the division and the corporation, and works at (is a member of, but in a different sense) a particular office. OpenACS 4's Parties and Groups -system will support such complex relations faithfully.
Historical Motivations
The primary limitation of the OpenACS 3.x user group system is that it +system will support such complex relations faithfully.
Historical Motivations
The primary limitation of the OpenACS 3.x user group system is that it restricts the application developer to representing a "flat group" that contains only users: The user_groups table may contain the group_id of a parent group, but parent-child relationship @@ -33,29 +33,29 @@ (e.g., a row with a scope value of "group" but a null group_id)
perform extra checks in Tcl and PL/SQL functions and procedures to check both the user_id and -group_id values
In sum, the goal of the Parties and Groups system is to +group_id values
In sum, the goal of the Parties and Groups system is to provide OpenACS programmers and site administrators with simple tools that fully describe the complex relationships that exist among groups in the real world.
Pat Developer has a client project and wants to model the company, its offices, its divisions, and its departments as groups and the employees as -users.
We start with Groups, which contain members; the -member can be either a person or another group (i.e. a +users.
We start with Groups, which contain members; the +member can be either a person or another group (i.e. a member is a party).
In addition to membership, the party and groups system defines a -composition relationship that may exist between groups: A -group can be a component of another group. The child group +composition relationship that may exist between groups: A +group can be a component of another group. The child group is called a component group; the parent group is called a -composite group.
A group Gc can be a member and/or a component -of another group Gp; the difference is in the way -the members of Gc are related to -Gp:
If a party P is a member (or a component) of -Gc and if Gc is a -component of Gp, then P is also -a member (or a component) of Gp
If a party P is a member (or a component) of -Gc and if Gc is a -member of Gp, then no -relationship between P and -Gp exists as a result of the relationship between -Gp and Gp.
Consider an example to make this less abstract: Pretend that the Sierra +composite group.
A group Gc can be a member and/or a component +of another group Gp; the difference is in the way +the members of Gc are related to +Gp:
If a party P is a member (or a component) of +Gc and if Gc is a +component of Gp, then P is also +a member (or a component) of Gp
If a party P is a member (or a component) of +Gc and if Gc is a +member of Gp, then no +relationship between P and +Gp exists as a result of the relationship between +Gp and Gp.
Consider an example to make this less abstract: Pretend that the Sierra Club is a member of Greenpeace. The Sierra Club has chapters; each chapter is a component of the Sierra Club. If Eddie Environmentalist is a member of the Massachusetts Chapter of the Sierra Club, Eddie is @@ -68,160 +68,158 @@ Massachusetts chapter), and between the Sierra Club and Greenpeace.
Membership requirements can vary from group to group. The parties and groups system must provide a base type that specifies the bare minimum necessary to join a group.
The parties and groups system must support constraints between a composite -group GP and any of its component groups, -GC. For example, the system should be able to -enforce a rule like: Do not allow a party P to become a -member of GC unless P is already -a member of GP.
The data model for the parties and groups system must provide support for -the following types of entities:
The data model for the parties and groups system must provide support for +the following types of entities:
A party is an entity used to represent either a -group or a person.
The data model should enforce these constraints:
10.10 A party has an email address, which can be -empty.
10.20 A party may have multiple email addresses -associated with it.
10.30 The email address of a party must be unique within -an OpenACS system.
A party is an entity used to represent either a +group or a person.
The data model should enforce these constraints:
10.10 A party has an email address, which can be +empty.
10.20 A party may have multiple email addresses +associated with it.
10.30 The email address of a party must be unique within +an OpenACS system.
A group is a collection of zero or more parties.
20.10 The data model should support the subclassing of -groups via OpenACS Objects.
A group is a collection of zero or more parties.
20.10 The data model should support the subclassing of +groups via OpenACS Objects.
A person represents an actual human being, past or -present.
A person represents an actual human being, past or +present.
A user is a person who has registered with an OpenACS site. A -user may have additional attributes, such as a screen name.
The data model should enforce these constraints:
40.10 A user must have a non-empty email address.
40.20 Two different users may not have the same email +
A user is a person who has registered with an OpenACS site. A +user may have additional attributes, such as a screen name.
The data model should enforce these constraints:
40.10 A user must have a non-empty email address.
40.20 Two different users may not have the same email address on a single OpenACS installation; i.e., an email address identifies a -single user on the system.
40.30 A user may have multiple email addresses; for -example, two or more email addresses may identify a single user.
40.40 A user must have password field which can be +single user on the system.
40.30 A user may have multiple email addresses; for +example, two or more email addresses may identify a single user.
40.40 A user must have password field which can be empty.
The data model for the parties and groups system must provide support for -the following types of relationships between entities:
-A party P is considered a member of a -group G
when a direct membership relationship exists between P -and G
or when there exists a direct membership relationship between -P and some group GC and -GC has a composition relationship (c.f., 60.0) with G.
50.10 A party may be a member of multiple groups.
50.20 A party may be a member of the same group multiple +A party P is considered a member of a +group G
when a direct membership relationship exists between P +and G
or when there exists a direct membership relationship between +P and some group GC and +GC has a composition relationship (c.f., 60.0) with G.
50.10 A party may be a member of multiple groups.
50.20 A party may be a member of the same group multiple times only when all the memberships have different types; for example, Jane may be a member of The Company by being both an Employee and an -Executive.
50.30 A party as a member of itself is not supported.
50.40 The data model must support membership -constraints.
50.50The data model should support the subclassing of +Executive.
50.30 A party as a member of itself is not supported.
50.40 The data model must support membership +constraints.
50.50The data model should support the subclassing of membership via OpenACS Relationships.
A group GC is considered a -component of a second group -GP
when a direct composition relationship exists between -GC and GP
or when there exists a direct composition relationship between -GC and some group Gi -and Gi has a composition relationship with -GP.
60.10A group may be a component of multiple groups.
60.20A group as a component of itself is not -supported.
60.30The data model must support component -constraints.
60.40The data model should support the subclassing of -composition via OpenACS Relationships.
The API should let programmers accomplish the following tasks:
A group GC is considered a +component of a second group +GP
when a direct composition relationship exists between +GC and GP
or when there exists a direct composition relationship between +GC and some group Gi +and Gi has a composition relationship with +GP.
60.10A group may be a component of multiple groups.
60.20A group as a component of itself is not +supported.
60.30The data model must support component +constraints.
60.40The data model should support the subclassing of +composition via OpenACS Relationships.
The API should let programmers accomplish the following tasks:
The parties and groups system provides a well defined API call that creates a new group by running the appropriate transactions on the parties and groups system data model. This API is subject to the constraints laid out -in the data model.
The parties and groups system provides a well defined API call that creates a new person by running the appropriate transactions on the parties and groups system data model. This API is subject to the constraints laid out -in the data model.
The parties and groups system provides a well defined API call that creates a new user by running the appropriate transactions on the parties and groups system data model. This API is subject to the constraints laid out in -the data model.
The parties and groups system provides a well defined API call that creates a new user by running the appropriate transactions on an existing person entity. This API is subject to the constraints laid out in the data -model.
The parties and groups system provides a well defined API call that demotes an existing user entity to a person entity by running the appropriate transactions on the existing user. This API is subject to the constraints -laid out in the data model.
The programmer should be able to modify, add, and delete attributes on any -party. This API is subject to the constraints laid out in the data model.
The programmer should be able to view the attributes on any party. This -API is subject to the constraints laid out in the data model.
The system provides an API for deleting a party. This API is subject to -the constraints laid out in the data model.
100.30 The system may provide a single API call to remove -the party from all groups and then delete the party.
100.40 In the case of a group, the system may provide a +the constraints laid out in the data model.
100.30 The system may provide a single API call to remove +the party from all groups and then delete the party.
100.40 In the case of a group, the system may provide a single API call to remove all parties from a group and then delete the -group.
The parties and groups system provides an API for adding a party as a member of a group. This API is subject to the constraints laid out in the -data model.
The parties and groups system provides an API for adding a group as a component of a second group. This API is subject to the constraints laid out -in the data model.
The parties and groups system provides an API for deleting a party's membership in a group. This API is subject to the constraints laid out in the -data model.
The parties and groups system provides an API for deleting a group's composition in a second group. This API is subject to the constraints laid -out in the data model.
The parties and groups system provides an API for answering the question: -"Is party P a member of group -G?"
The parties and groups system provides an API for answering the question: -"Is group GC a component of group -GP?"
The parties and groups system provides an API for answering the question: -"Which parties are members of group G?"
The parties and groups system provides an API for answering the question: -"Which groups are components of group G?"
The parties and groups system provides an API for answering the question: -"Of which groups is party P a member?"
The parties and groups system provides an API for answering the question: -"Of which groups is group G a component?"
The parties and groups system provides an API for answering the question: -"Is party P allowed to become a member of group -G?"
The parties and groups system provides an API for answering the question: -"Is group GC allowed to become a component -of group GP?"
Since many pages at a site may check membership in a group before serving a page (e.g., as part of a general permissions check), the data model must support the efficient storage and retrieval of party attributes and -membership.
Since many SQL queries will check membership in a group as part of the where clause, whatever mechanism is used to check membership in SQL should be fairly small and simple.
The user interface is a set of HTML pages that are used to drive the -underlying API. The user interface may provide the following functions:
200.0 Create a party
210.0 View the attributes of a party
220.0 Update the attributes of a party
240.0 Delete a party
250.0 Add a party to a group
260.0 Remove a party from a group
270.0 Perform the membership and composition checks -outlined in 130.x to 165.x
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 08/16/2000 | Rafael Schloming |
0.2 | Initial revision | 08/19/2000 | Mark Thomas |
0.3 | Edited and reviewed, conforms to requirements template | 08/23/2000 | Kai Wu |
0.4 | Further revised, added UI requirements | 08/24/2000 | Mark Thomas |
0.5 | Final edits, pending freeze | 08/24/2000 | Kai Wu |
0.6 | More revisions, added composition requirements | 08/30/2000 | Mark Thomas |
0.7 | More revisions, added composition requirements | 09/08/2000 | Mark Thomas |
Prev | Home | Next |
OpenACS 4 Permissions Design | Up | OpenACS 4 Groups Design |
200.0 Create a party
210.0 View the attributes of a party
220.0 Update the attributes of a party
240.0 Delete a party
250.0 Add a party to a group
260.0 Remove a party from a group
270.0 Perform the membership and composition checks +outlined in 130.x to 165.x
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 08/16/2000 | Rafael Schloming |
0.2 | Initial revision | 08/19/2000 | Mark Thomas |
0.3 | Edited and reviewed, conforms to requirements template | 08/23/2000 | Kai Wu |
0.4 | Further revised, added UI requirements | 08/24/2000 | Mark Thomas |
0.5 | Final edits, pending freeze | 08/24/2000 | Kai Wu |
0.6 | More revisions, added composition requirements | 08/30/2000 | Mark Thomas |
0.7 | More revisions, added composition requirements | 09/08/2000 | Mark Thomas |
Prev | Home | Next |
OpenACS 4 Permissions Design | Up | OpenACS 4 Groups Design |
Table of Contents
Table of Contents
Table of Contents
Table of Contents
- Compared to its predecessors, version 4.5 of OpenACS has a much +
+ Compared to its predecessors, version 4.6 of OpenACS has a much more structured organization, i.e. the most significant change is found at the system architecture level, reflected in the following hierarchy: -
The OpenACS 4.5 Kernel, which handles system-wide necessities +
The OpenACS 4.6 Kernel, which handles system-wide necessities such as metadata, security, users and groups, subsites, and package management and deployment. -
The OpenACS 4.5 Core, which comprises all the other packages +
The OpenACS 4.6 Core, which comprises all the other packages that ship with the kernel and are most frequently needed by users, such as templating, bboard, and user registration/management. The packages tend to be developed and distributed with the kernel. -
OpenACS 4.5 Application packages, which typically provide +
OpenACS 4.6 Application packages, which typically provide user-level web services built on top of the Kernel and Core. Such packages include those built by ArsDigita as well as external contributors. Application packages are developed separately from the Kernel, and are typically released independently of it.
This document provides a high level overview of the kernel package. Documentation for the other packages can be found elsewhere. -
Prev | Home | Next |
Chapter 7. Kernel Documentation | Up | OpenACS 4 Object Model Requirements |
Prev | Home | Next |
Chapter�7.�Kernel Documentation | Up | OpenACS 4 Object Model Requirements |
Prev | Home | Next |
Writing OpenACS 4.5 Application Pages | Up | Overview |
Prev | Home | Next |
Writing OpenACS 4.6 Application Pages | Up | Overview |
+
by Pete Su,
Michael Yoon,
Richard Li
and Rafael Schloming
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
The next section will explore these facilities in the context of the the -particular programming idioms that we wish to generalize.
Related Links
This design document should be read along with the design documents for the new groups system, subsites and the permissions system
The motivation for most of the facilities in the OpenACS 4 Object Model can be +particular programming idioms that we wish to generalize.
Related Links
This design document should be read along with the design documents for the new groups system, subsites and the permissions system
The motivation for most of the facilities in the OpenACS 4 Object Model can be understood in the context of the 3.x code base and the kinds of programming idioms that evolved there. These are listed and discussed below.
Object identification is a central mechanism in OpenACS 4. Every application object in OpenACS 4 has a unique ID which is mapped to a row in a central table @@ -77,14 +77,14 @@ make sure every object the system is to manage is associated with a row in acs_objects. More importantly, if they do this, new services like general comments can be created without requiring existing applications -to "hook into" them via new metadata.
Note: Object identifiers are a good example of metadata +to "hook into" them via new metadata.
Note: Object identifiers are a good example of metadata in the new system. Each row in acs_objects stores information about the application object, but not the application object itself. This becomes more clear if you skip ahead and look at the SQL schema code that defines this table.
Until the implementation of the general permissions system, every OpenACS application had to manage access control to its data separately. Later on, a notion of "scoping" was introduced into the core data model.
"Scope" is a term best explained by example. Consider some -hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ...
The first row represents an entry in User 123's personal address book, +hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ...
The first row represents an entry in User 123's personal address book, the second row represents an entry in User Group 456's shared address book, and the third row represents an entry in the site's public address book.
In this way, the scoping columns identify the security context in which a @@ -245,8 +245,8 @@ the more limited domain of the metadata model, this is acceptable since the type hierarchy is fairly small. But the object system data model is not designed to support, for example, a huge type tree like the Java runtime -libraries might define.
This last point cannot be over-stressed: the object model is not -meant to be used for large scale application data storage. It is +libraries might define.
This last point cannot be over-stressed: the object model is not +meant to be used for large scale application data storage. It is meant to represent and store metadata, not application data.
Like most data models, the OpenACS Core data model has two levels:
The knowledge level (i.e. the metadata model)
The operational level (i.e. the concrete data model)
You can browse the data models themselves from here:
Pete Su generated this document from material culled from other documents by Michael Yoon, Richard Li and Rafael Schloming. But, any remaining lies -are his and his alone.
Prev | Home | Next |
OpenACS 4 Object Model Requirements | Up | OpenACS 4 Permissions Requirements |
Prev | Home | Next |
OpenACS 4 Object Model Requirements | Up | OpenACS 4 Permissions Requirements |
+
By Pete Su
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
A major goal in OpenACS 4 is to unify and normalize many of the core services + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
A major goal in OpenACS 4 is to unify and normalize many of the core services of the system into a coherent common data model and API. In the past, these services were provided to applications in an ad-hoc and irregular fashion. Examples of such services include:
General Comments
User/groups
Attribute storage in user/groups
General Permissions
Site wide search
General Auditing
All of these services involve relating extra information and services to @@ -24,7 +24,7 @@ within the OpenACS, and typically corresponds to a single row within the relational database.
The OpenACS 4 Object Model must address five high-level requirements that repeatedly exhibit themselves in the context of existing services in OpenACS 3.x, -as described below.
Object Identifiers for General Services
Generic services require a single unambiguous way of identifying +as described below.
Object Identifiers for General Services
Generic services require a single unambiguous way of identifying application objects that they manage or manipulate. In OpenACS 3.x, there are several different idioms that construct object identifiers from other data. Many modules use a (user_id, group_id, scope) triple combination @@ -46,12 +46,12 @@ that their definition and use is ad-hoc and inconsistent. This makes the construction of generic application-independent services difficult. Therefore, the OpenACS 4 Object Model should provide a centralized and uniform -mechanism for tagging application objects with unique identifiers.
Support for Unified Access Control
Access control should be as transparent as possible to the application +mechanism for tagging application objects with unique identifiers.
Support for Unified Access Control
Access control should be as transparent as possible to the application developer. Until the implementation of the general permissions system, every OpenACS application had to manage access control to its data separately. Later on, a notion of "scoping" was introduced into the core data model.
"Scope" is a term best explained by example. Consider some -hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ...
The first row represents an entry in User 123's personal address book, +hypothetical rows in the address_book table:
... scope user_id group_id ... ... user 123 � ... ... group � 456 ... ... public � � ...
The first row represents an entry in User 123's personal address book, the second row represents an entry in User Group 456's shared address book, and the third row represents an entry in the site's public address book.
In this way, the scoping columns identify the security context in which a @@ -65,7 +65,7 @@ page, a security problem could result.
Thus the OpenACS 4 Object Model must support a more general access control system that allows access control domains to be hierarchical, and specifiable with a single piece of data, instead of the old composite keys described -above.
Extensible Data Models
Another problem with previous OpenACS data models is that many of the central +above.
Extensible Data Models
Another problem with previous OpenACS data models is that many of the central tables in the system became bloated as they were extended to support an increasing number of modules. The users table is the best case in point: it became full of columns that exist for various special @@ -83,10 +83,10 @@ custom extensions to the existing data models, and the OM does the bookkeeping necessary to make this easier, providing a generic API for object creation that automatically keeps track of the location and relationships -between data.
Design Note: While this doesn't really belong in a +between data.
Design Note: While this doesn't really belong in a requirements document, the fact that we are constrained to using relational databases means that certain constraints on the overall design of the object -data model exist, which you can read about in Summary and Design Considerations.
Modifiable Data Models
Another recurring applications problem is how to store a modifiable data +data model exist, which you can read about in Summary and Design Considerations.
Modifiable Data Models
Another recurring applications problem is how to store a modifiable data model, or how to store information that may change extensively between releases or in different client installations. Furthermore, we want to avoid changes to an application's database queries in the face of any custom @@ -103,7 +103,7 @@ store values for those attributes.
Thus the Object Model must provide a general mechanism for applications and developers to modify or extend data models, without requiring changes to the SQL schema of the system. This ensures that all applications use the same -base schema, resulting in a uniform and more maintainable system.
Generic Relations
Many OpenACS applications define simple relationships between application +base schema, resulting in a uniform and more maintainable system.
Generic Relations
Many OpenACS applications define simple relationships between application objects, and tag those relationships with extra data. In OpenACS 3.x, this was done using mapping tables. The user/groups module has the most highly developed data model for this purpose, using a single table called @@ -127,8 +127,8 @@ that store metadata on application objects. The object type system supports subtyping with inheritance, so new object types can be defined in terms of existing object types.
The OM data model forms the main part of the OpenACS 4 Kernel data model. The -other parts of the Kernel data model include:
Parties and Groups
Permissions
Each of these is documented elsewhere at length.
The data model for the object system provides support for the following -kinds of schema patterns that are used by many existing OpenACS modules:
Object identification is a central mechanism in the new metadata system. +other parts of the Kernel data model include:
Parties and Groups
Permissions
Each of these is documented elsewhere at length.
The data model for the object system provides support for the following +kinds of schema patterns that are used by many existing OpenACS modules:
Object identification is a central mechanism in the new metadata system. The fact that every object has a known unique identifier means that the core can deal with all objects in a generic way. Thus the only action required of an application to obtain any general service is to "hook into" the @@ -149,15 +149,15 @@ application data. More importantly, object identifiers will enable developers to readily build and use generic services that work globally across a system.
The object identifiers should be subject to the following -requirements:
10.10 Uniqueness
The object ID should be unique among all the IDs in the entire OpenACS system -in which the object lives.
10.20 Useful as a Reference
Applications should be able to use the unique object ID as a reference, -with which they can fetch any or all of the object's attributes.
10.30 Storable
Object IDs should be storable in tables. e.g. you should be able to use +requirements:
10.10 Uniqueness
The object ID should be unique among all the IDs in the entire OpenACS system +in which the object lives.
10.20 Useful as a Reference
Applications should be able to use the unique object ID as a reference, +with which they can fetch any or all of the object's attributes.
10.30 Storable
Object IDs should be storable in tables. e.g. you should be able to use them to implement mapping tables between objects, to represent -relationships.
10.40 Moveable
Objects should be mobile between databases. That is, information will +relationships.
10.40 Moveable
Objects should be mobile between databases. That is, information will often need to be moved between multiple servers (development, staging, and production), so a mechanism for moving this data is necessary. In addition, a mechanism for tagging these objects in a way similar to CVS would be useful -in determining which objects need to be synchronized.
An object type refers to a specification of one or more +in determining which objects need to be synchronized.
An object type refers to a specification of one or more attributes to be managed along with a piece of application data.
The object system should provide a data model for describing and representing object types. This data model is somewhat analogous to the Oracle data dictionary, which stores information about all user defined @@ -170,33 +170,33 @@ is meant to be a generalization of this mechanism. The data model should allow developers to at least do everything they used to with user/groups, but without its administrative hassles.
Therefore, the data model must be able to represent object types that have -the following characteristics:
20.10 Type Name
A human readable name for the object type.
20.20 Type Attributes
Attributes whose values are shared by all instances of the object -type.
20.30 Object Attributes
Attributes that are specific to each particular object belonging to a -given type.
The data model must also enforce certain constraints on object types:
20.40 Type Uniqueness
Object type names must be unique.
20.50 Attribute Name Uniqueness
Attribute names must be unique in the scope of a single object type and -any of its parent types.
The Object Model must support the definition of object types that are +the following characteristics:
20.10 Type Name
A human readable name for the object type.
20.20 Type Attributes
Attributes whose values are shared by all instances of the object +type.
20.30 Object Attributes
Attributes that are specific to each particular object belonging to a +given type.
The data model must also enforce certain constraints on object types:
20.40 Type Uniqueness
Object type names must be unique.
20.50 Attribute Name Uniqueness
Attribute names must be unique in the scope of a single object type and +any of its parent types.
The Object Model must support the definition of object types that are subtypes of existing types. A subtype inherits all the attributes of its parent type, and defines some attributes of its own. A critical aspect of the OM is parent types may be altered, and any such change must propagate to child subtypes.
The OM data model must enforce constraints on subtypes that are similar to -the ones on general object types.
30.10 Subtype Uniqueness
Subtype names must be unique (this parallels requirement 10.40).
30.20 Subtype Attribute Name Uniqueness
Attribute names must be unique in the scope of a single object -subtype.
30.30 Parent Type Prerequisite
Subtypes must be defined in terms of parent types that, in fact, already -exist.
30.40
The extended attribute names in a subtype must not be the same as those in -its parent type.
35.10 Method and Type Association
The OM data model should define a mechanism for associating procedural +the ones on general object types.
30.10 Subtype Uniqueness
Subtype names must be unique (this parallels requirement 10.40).
30.20 Subtype Attribute Name Uniqueness
Attribute names must be unique in the scope of a single object +subtype.
30.30 Parent Type Prerequisite
Subtypes must be defined in terms of parent types that, in fact, already +exist.
30.40
The extended attribute names in a subtype must not be the same as those in +its parent type.
35.10 Method and Type Association
The OM data model should define a mechanism for associating procedural code, called methods, with objects of a given type. Methods are associated with the each object type - not each object -instance.
35.20 Method Sharing
All instances of a given object type should share the same set of defined -methods for that type.
In addition to information on types, the OM data model provides for the +instance.
35.20 Method Sharing
All instances of a given object type should share the same set of defined +methods for that type.
In addition to information on types, the OM data model provides for the centralized storage of object attribute values. This facility unifies the many ad-hoc attribute/value tables that exist in various OpenACS 3.x data models, such as:
User groups: Each instance of a group type can have custom data.
Photo DB: Users can define their own custom metadata to attach to photograph objects.
Ecommerce: Vendors can attach custom fields to the data model describing -their products.
40.10 Generic Retrieval
Attributes should be stored so that they are retrievable in a way that is +their products.
40.10 Generic Retrieval
Attributes should be stored so that they are retrievable in a way that is independent of the type of the object that they belong to. That is, the only data needed to retrieve an attribute should be the system-wide ID of an -object (see requirement 10.20 above) and the attribute name.
40.20 Inherited Attributes
The system should allow for the automatic retrieval of inherited attribute -values, for an object belonging to a subtype.
40.30. Constraints on Attributes
The system should allow the developer to put down constraints on the +object (see requirement 10.20 above) and the attribute name.
40.20 Inherited Attributes
The system should allow for the automatic retrieval of inherited attribute +values, for an object belonging to a subtype.
40.30. Constraints on Attributes
The system should allow the developer to put down constraints on the values that an attribute may hold, for the purposes of maintaining -application specific integrity rules.
In OpenACS 3.x, there was a notion of "scope" for application +application specific integrity rules.
In OpenACS 3.x, there was a notion of "scope" for application objects. An object could be belong to one of three scopes: public, group or user. This provided a crude way to associate objects with particular scopes in the system, but it was awkward to use and limited in flexibility.
The OpenACS 4 Object Model provides a generalized notion of scope that allows @@ -205,66 +205,64 @@ object has no explicit permissions attached to it, then it inherits permissions from its context.
The context data model also forms the basis of the subsites system, and is a basic part of the permissions system, -described in separate documents.
The context data model should provide the following facilities:
50.10 Unique ID
Every context should have a unique ID in the system.
50.20 Tree Structure
The data model should support a tree structured organization of contexts. +described in separate documents.
The context data model should provide the following facilities:
50.10 Unique ID
Every context should have a unique ID in the system.
50.20 Tree Structure
The data model should support a tree structured organization of contexts. That is, contexts can be logically "contained" within other contexts (i.e. contexts have parents) and contexts can contain other contexts -(i.e. contexts can have children).
50.30 Data Model Constraints
All objects must have a context ID. This ID must refer to an existing +(i.e. contexts can have children).
50.30 Data Model Constraints
All objects must have a context ID. This ID must refer to an existing context or be NULL. The meaning of a NULL context is determined by the -implementation.
Note:
The current system interprets the NULL context as meaning the default +implementation.
Note:
The current system interprets the NULL context as meaning the default "site-wide" context in some sense. I wanted to note this fact for others, but there is no need to make this a requirement of the system. I think it would be reasonable to have a NULL context be an error (psu -8/24/2000).
The data model should include a notion of pair-wise relations between +8/24/2000).
The data model should include a notion of pair-wise relations between objects. Relations should be able to record simple facts of the form "object X is related to object Y by relationship R," and also be -able to attach attributes to these facts.
The API should let programmers accomplish the following actions:
60.10 Create a New Object Type
The object system API should provide a procedure call that creates a new +able to attach attributes to these facts.
The API should let programmers accomplish the following actions:
60.10 Create a New Object Type
The object system API should provide a procedure call that creates a new object type by running the appropriate transactions on the object system data model. This API call is subject to the constraints laid out in the data -model. We call this operation "instantiating" an object.
60.20 Create a New Object Subtype
The object system API should provide a procedure call for creating +model. We call this operation "instantiating" an object.
60.20 Create a New Object Subtype
The object system API should provide a procedure call for creating subtypes of a given type. Operationally, this API is the same as requirement 60.10. Instances of subtypes automatically contain all attributes of the parent type in addition to all attributes of the subtype. This API is subject -to the constraints laid out in the data model.
60.30 Create a New Relation Type
There should be an API call to create a new type of object relation. +to the constraints laid out in the data model.
60.30 Create a New Relation Type
There should be an API call to create a new type of object relation. Relation types can be modeled as object types. The API below for manipulating -attributes can then be used to add attributes to relation types.
The object system API must allow the programmer to modify, add, and delete +attributes can then be used to add attributes to relation types.
The object system API must allow the programmer to modify, add, and delete attributes from any object type. Updates should be propagated to any child subtypes. This API is subject to the constraints laid out in the data -model.
The system provides an API call for deleting an object type.
80.10
Deleting an object type destroys all instances of the type. It should be +model.
The system provides an API call for deleting an object type.
80.10
Deleting an object type destroys all instances of the type. It should be an error to delete types that have dependent subtypes. This API is subject to -the constraints laid out in the data model.
80.10.10
However, the programmer should also be able to specify that all the +the constraints laid out in the data model.
80.10.10
However, the programmer should also be able to specify that all the subtypes and instances of those subtypes be destroyed before destroying the object type. This is similar to a "delete cascade" constraint in -SQL.
The system must provide API calls to manage the creation and destruction -of object instances.
90.10 Create an Instance of an Object Type
The system should provide an API call for creating a new instance of a +SQL.
The system must provide API calls to manage the creation and destruction +of object instances.
90.10 Create an Instance of an Object Type
The system should provide an API call for creating a new instance of a given object type. The new instance should be populated with values for each of the attributes specified in the definition of the type. In addition, it should be possible to create the new instance with an optional context ID -that refers to the default context that the object will live in.
90.20 Delete an Object Instance
The OM should provide an API call for object deletion. Objects can be +that refers to the default context that the object will live in.
90.20 Delete an Object Instance
The OM should provide an API call for object deletion. Objects can be deleted only when no other objects in the system refer to them. Since it might not be practical to provide a mechanism like "delete cascade" here in a reliable way, providing such a facility in the system is -optional.
The system must provide API calls to manage the creation and destruction -of object relations.
The OM must provide an API call to declare that two objects are related to +optional.
The system must provide API calls to manage the creation and destruction +of object relations.
The OM must provide an API call to declare that two objects are related to each other by a given relation type. This API call should also allow -programmers to attach attributes to this object relation.
There should be an API call for destroying object relations and their -attributes.
The system should provide an API to create and destroy object -contexts.
The system should provide an API for updating the attribute values of a -particular instance of an object type.
The system should provide an API for retrieving attribute values from a -particular instance of an object type.
The Object Model must support the efficient storage and retrieval of +programmers to attach attributes to this object relation.
There should be an API call for destroying object relations and their +attributes.
The system should provide an API to create and destroy object +contexts.
The system should provide an API for updating the attribute values of a +particular instance of an object type.
The system should provide an API for retrieving attribute values from a +particular instance of an object type.
The Object Model must support the efficient storage and retrieval of object attributes. Since the OM is intended to form the core of many general services in the OpenACS, and these services will likely make extensive use of the OM tables, queries on these tables must be fast. The major problem here seems to be supporting subtyping and inheritance in a way that does not severely -impact query performance.
Most OpenACS packages will be expected to use the Object Model in one way or +impact query performance.
Most OpenACS packages will be expected to use the Object Model in one way or another. Since it is important that the largest audience of developers possible adopts and uses the OM, it must be easy to incorporate into applications, and it must not impose undue requirements on an application's data model. In other words, it should be easy to "hook into" the object model, and that ability should not have a major impact -on the application data model.
Note: Is the API the only way to obtain values? How does -this integrate with application level SQL queries?
Document Revision # | Action Taken, Notes | When? | By Whom? | ||||||||||||||||||||||||||||||||||||||||||||
0.1 | Creation | 08/10/2000 | Bryan Quinn | ||||||||||||||||||||||||||||||||||||||||||||
0.2 | Major re-write | 08/11/2000 | Pete Su | ||||||||||||||||||||||||||||||||||||||||||||
0.3 | Draft completed after initial reviews | 08/22/2000 | Pete Su | ||||||||||||||||||||||||||||||||||||||||||||
0.4 | Edited, updated to conform to requirements template, pending freeze | 08/23/2000 | Kai Wu | ||||||||||||||||||||||||||||||||||||||||||||
� | Final edits before freeze | 08/24/2000 | Pete Su | ||||||||||||||||||||||||||||||||||||||||||||
0.5 | Edited for consistency | 08/27/2000 | Kai Wu | ||||||||||||||||||||||||||||||||||||||||||||
0.6 | Put Object ID stuff first, because it makes more sense | 08/28/2000 | Pete Su | ||||||||||||||||||||||||||||||||||||||||||||
0.7 | Added requirement that knowledge-level objects must be moveable between
+on the application data model. Note: Is the API the only way to obtain values? How does +this integrate with application level SQL queries?
| 09/06/2000 | Pete Su | ||||||||||||||||||||||||||||||||||||||||||||
0.9 | Edited for ACS 4 Beta release. | 09/30/2000 | Kai Wu |
Prev | Home | Next |
Chapter 1. High level information: What is OpenACS? | Up | OpenACS 4.5 Release Notes |
+ OpenACS (Open Architecture Community System) is an advanced + toolkit for building scalable, community-oriented web applications. + If you're thinking of building an enterprise-level web application, + OpenACS is a solid, proven foundation that will give you a 3-6 month headstart. +
+ OpenACS is also a collection of pre-built applications and services that + you can use to build your web site/application. Through a modular architecture, + OpenACS has packages for user/groups management, content management, e-commerce, + news, FAQ, calendar, forums, bug tracking, full-text searching, and + much more. +
+ OpenACS relies on AOLserver, + the free, multithreaded, scalable, Tcl-enabled, web/application server used by + America On-Line for most of its web sites, and a true acid-compliant + Relational Database Management System (RDBMS). Currently OpenACS supports + PostgreSQL, an open source RDBMS, and Oracle. (read more) +
+ The OpenACS toolkit is based on the ArsDigita Community System. ArsDigita + (now part of Red Hat, Inc.) kindly made their work available under the + GPL, + making all of this possible. +
+ The OpenACS community would like to hear your comments and help you + in your endeavors with the system. Stop by our web site + and feel free to ask a question, post ideas or whatever. +
Prev | Home | Next |
Chapter�1.�High level information: What is OpenACS? | Up | OpenACS 4.6 Release Notes |
Prev | Home | Next |
Chapter 5. Other Developer Resources | Up | Parties in OpenACS 4.5 |
Prev | Home | Next |
Chapter�5.�Other Developer Resources | Up | Parties in OpenACS 4.6 |
+
by John Prevost and Rafael H. Schloming
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
Tcl in packages/acs-kernel
The goal of the Permissions system is to provide generic means to both @@ -48,14 +48,14 @@
The set of all defined privileges.
A relation describing the set of methods directly +
A relation describing the set of methods directly associated with each privilege.
A relation describing which privileges directly +
A relation describing which privileges directly "contain" other privileges.
A table with one (party, object, privilege) -row for every privilege directly granted on any object in +row for every privilege directly granted on any object in the system - this is a denormalization of acs_privilege_method_rules and acs_privilege_hierarchy
There are also a number of views to make it easier to ask specific @@ -78,7 +78,7 @@ a party is a member of a group (at any depth).
Relation with every (object, party, method) -tuple implied by the above trees.
In general, only acs_object_party_method_map +tuple implied by the above trees.
In general, only acs_object_party_method_map should be used for queries from other modules. The other views are intermediate steps in building that query.
The data model also includes two simple PL/SQL procedures (acs_permission.grant_permission and @@ -95,15 +95,15 @@ acs_privilege_hierarchy)
objects get access control from direct grants, or inherit permissions from their context (unless the "don't inherit" flag is set)
There are three essential areas in which all transactions in the -permissions system fall:
Modification of methods and privileges
Modification of permissions
Queries on permissions
"Modification of methods and privileges." This +permissions system fall:
Modification of methods and privileges
Modification of permissions
Queries on permissions
"Modification of methods and privileges." This refers to actions that happen mainly at package installation time - a package will create a number of methods for its own use, then associate them with the system's standard privileges, or new privileges which the package has created. The association step might also happen later, if the site-wide administrator chooses to change permissions policy.
These steps involve directly manipulating the acs_methods, acs_privileges, and acs_privilege_method_rules tables. A web page for manipulating these features should be limited to site-wide -administrators.
"Modification of permissions" - involves fairly +administrators.
"Modification of permissions" - involves fairly common operations. Users are typically able to administer permissions for objects they themselves create. The two basic operations here are "grant" and "revoke". Granting permissions is done via @@ -112,7 +112,7 @@ acs_permissions table.
Web pages for making these changes are available to all users, so they should not be in an admin area. In order to grant and revoke permissions on an object, the user must have the administer_privileges method -permission on that object.
"Queries on permissions" - by far the most +permission on that object.
"Queries on permissions" - by far the most common operation is querying the permissions database. Several kinds of questions are commonly asked: First, and most commonly, "Can this party perform this method on this object?" Two Tcl functions are provided to @@ -127,15 +127,15 @@ for appropriate methods.
Finally, when administering the permissions for an object, a web page needs to know all permissions directly granted on that object. This is done by querying against acs_permissions.
The API to the permissions system consists of a few well-known tables, -plus a pair of PL/SQL procedures and a pair of Tcl functions.
Tables
acs_methods, acs_privileges, and +plus a pair of PL/SQL procedures and a pair of Tcl functions.
Tables
acs_methods, acs_privileges, and acs_privilege_method_rules manage the set of permissions in the system. At installation time, a package will add to these three tables to introduce new permissions into the system.
The main table for queries is acs_object_party_method_map, which contains (object, party, method) triples for all allowed operations in the system.
Also of interest for queries is acs_permissions, which lists directly granted privileges. Neither acs_object_party_method_map (which is a view) nor acs_permissions should be updated -directly.
PL/SQL Procedures
acs_permissions.grant_permission introduces new permissions for +directly.
PL/SQL Procedures
acs_permissions.grant_permission introduces new permissions for an object. It should be given an (object, party, privilege) triple, and will always succeed. If the permission is already in the system, no change occurs. The interface for this procedure @@ -154,7 +154,7 @@ privilege acs_permissions.privilege%TYPE );
These procedures are defined in -permissions-create.sql
Tcl Procedures
Two tcl procedures provide a simple call for the query, "Can this +permissions-create.sql
Tcl Procedures
Two tcl procedures provide a simple call for the query, "Can this user perform this method on this object?" One returns true or false, the other presents an error page.
To receive a true or false value, Tcl code should call:
ad_permission_p $object_id $object_type $method -user_id $user_id @@ -184,6 +184,4 @@
Prev | Home | Next |
OpenACS 4 Permissions Requirements | Up | OpenACS 4 Groups Requirements |
Prev | Home | Next |
OpenACS 4 Permissions Requirements | Up | OpenACS 4 Groups Requirements |
+
by John McClary Prevost
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
This document records requirements for the OpenACS 4 Permissions system, a + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
This document records requirements for the OpenACS 4 Permissions system, a component of the OpenACS 4 Kernel. The Permissions system is meant to unify and centralize the handling of access and control on a given OpenACS 4 system.
Any multi-user software system must address the general problem of permissions, or "who can do what, on what." On web services, which @@ -15,7 +15,7 @@ manner reduces both cost and risk: cost, in that less code has to be written and maintained for dealing with recurring permissions situations; risk, in that we need not rely on any single programmer's diligence to ensure -access control is implemented and enforced correctly.
Historical Motivations
In earlier versions of the OpenACS, permissions and access control was handled +access control is implemented and enforced correctly.
Historical Motivations
In earlier versions of the OpenACS, permissions and access control was handled on a module-by-module basis, often even on a page-by-page basis. For example, a typical module might allow any registered user to access its pages read-only, but only allow members of a certain group to make changes. The way @@ -33,14 +33,14 @@ common administrative interface, and easily deployed and maintained access control. The system must be flexible enough to support every access model required in OpenACS applications, but not so flexible that pieces will go unused -or fall outside the common administrative interfaces.
Terminology
The primary question an access control system must answer is a three-way +or fall outside the common administrative interfaces.
Terminology
The primary question an access control system must answer is a three-way relation, like that between the parts of most simple sentences. A simple sentence generally has three parts, a subject, an object, and a verb - in the context of OpenACS Permissions, our simple sentence is, "Can this party -perform this operation on this target?" Definitions:
The subject of the sentence is "party" - a +perform this operation on this target?" Definitions:
The subject of the sentence is "party" - a distinguishable actor whose access may be controlled, this special word is used because one person may be represented by several parties, and one party -may represent many users (or no users at all).
The object of the sentence is "target" - this +may represent many users (or no users at all).
The object of the sentence is "target" - this is an entity, or object, that the party wishes to perform some action on. An entity/object here is anything that can be put under access control.
The verb of the sentence is "operation" - a behavior on the OpenACS system subject to control, this word is used to represent the fact that a @@ -50,45 +50,43 @@ that operation.
Examples of the essential question addressed by the Permissions system: Can jane@attacker.com delete the web security bboard? Can the Boston office (a party) within the VirtuaCorp intranet/website create its own news -instance?
10.0 Granularity
The system must support access control down to the level of a single +instance?
10.0 Granularity
The system must support access control down to the level of a single entity (this would imply down to the level of a row in the OpenACS Objects data -model).
20.0 Operations
The system itself must be able to answer the essential permissions -question as well as several derived questions.
20.10 Basic Access Check
The system must be able to answer the question, "May party P perform -operation O on target T?"
20.20 Allowed Parties Check
The system must be able to answer the question, "Which parties may -perform operation O on target T?"
20.30 Allowed Operations Check
The system must be able to answer the question, "Which operations may -party P perform on target T?"
20.40 Allowed Targets Check
The system must be able to answer the question, "Upon which targets -may party P perform operation O?"
40.0 Scale of Privileges
Privileges must be designed with appropriate scope for a given OpenACS +model).
20.0 Operations
The system itself must be able to answer the essential permissions +question as well as several derived questions.
20.10 Basic Access Check
The system must be able to answer the question, "May party P perform +operation O on target T?"
20.20 Allowed Parties Check
The system must be able to answer the question, "Which parties may +perform operation O on target T?"
20.30 Allowed Operations Check
The system must be able to answer the question, "Which operations may +party P perform on target T?"
20.40 Allowed Targets Check
The system must be able to answer the question, "Upon which targets +may party P perform operation O?"
40.0 Scale of Privileges
Privileges must be designed with appropriate scope for a given OpenACS package. Some privileges are of general utility (e.g. "read" and "write"). Others are of more limited use (e.g. "moderate" - applies mainly to a package like bboard, where many users are contributing content simultaneously). A package defining its own privileges should do so with moderation, being careful not to overload a privilege like -"read" to mean too many things.
50.0 Aggregation of Operations (Privileges)
For user interface purposes, it can be appropriate to group certain +"read" to mean too many things.
50.0 Aggregation of Operations (Privileges)
For user interface purposes, it can be appropriate to group certain privileges under others. For example, anyone with the "admin" privilege may also automatically receive "read", "write", -"delete", etc. privileges.
60.0 Aggregation of Parties (Groups)
The system must allow aggregation of parties. The exact method used for +"delete", etc. privileges.
60.0 Aggregation of Parties (Groups)
The system must allow aggregation of parties. The exact method used for aggregation will probably be addressed by the OpenACS 4 "Groups" system. Regardless of the exact behavior of aggregate parties, if an aggregate party exists, then access which is granted to the aggregate party -should be available to all members of that aggregate.
70.0 Scope of Access Control
70.10 Context
There must be a method for objects to receive default access control from +should be available to all members of that aggregate.
70.0 Scope of Access Control
70.10 Context
There must be a method for objects to receive default access control from some context. For example, if you do not have read access to a bboard, you -should not have read access to a message in that bboard.
70.20 Overriding
It must be possible to override defaults provided by the context of an -object (as in 70.10), in both a positive and negative manner.
70.20.10 Positive Overriding
It must be possible to allow a party more access to some target than they +should not have read access to a message in that bboard.
70.20 Overriding
It must be possible to override defaults provided by the context of an +object (as in 70.10), in both a positive and negative manner.
70.20.10 Positive Overriding
It must be possible to allow a party more access to some target than they would get by default. (For example, a user does not have the right to edit any message on a bboard. But a user does possibly have the right to edit -their own messages.)
70.20.20 Negative Overriding
It must be possible to deny a party access to some target that their +their own messages.)
70.20.20 Negative Overriding
It must be possible to deny a party access to some target that their inherited privileges would have allowed. (For example, a subdirectory in the file-storage might normally have its parent directory as context. It should -be possible, however, to make a subdirectory private to some group.)
100.0 Efficiency
At least the basic access check (20.10) and the allowed targets check +be possible, however, to make a subdirectory private to some group.)
100.0 Efficiency
At least the basic access check (20.10) and the allowed targets check (20.40) must be efficient enough for general use, i.e. scalable under fairly heavy website traffic. It can be expected that almost every page will contain at least one basic access check, and most pages will contain an allowed targets check (20.40).
In particular, constraining a SELECT to return only rows the current user has access to should not be much slower than the SELECT -on its own.
120.0 Ease of Use
Since most SQL queries will contain an allowed target check in the where +on its own.
120.0 Ease of Use
Since most SQL queries will contain an allowed target check in the where clause, whatever mechanism is used to make checks in SQL should be fairly small and simple.
In particular, constraining a SELECT to return only rows the -current user has access to should not add more than one line to a query.
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/17/2000 | John Prevost |
0.2 | Revised, updated with new terminology | 8/25/2000 | John Prevost |
0.3 | Edited, reformatted to conform to requirements template, pending -freeze. | 8/26/2000 | Kai Wu |
0.4 | Edited for ACS 4 Beta release. | 10/03/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Object Model Design | Up | OpenACS 4 Permissions Design |
Document Revision # | Action Taken, Notes | When? | By Whom? |
0.1 | Creation | 8/17/2000 | John Prevost |
0.2 | Revised, updated with new terminology | 8/25/2000 | John Prevost |
0.3 | Edited, reformatted to conform to requirements template, pending +freeze. | 8/26/2000 | Kai Wu |
0.4 | Edited for ACS 4 Beta release. | 10/03/2000 | Kai Wu |
Prev | Home | Next |
OpenACS 4 Object Model Design | Up | OpenACS 4 Permissions Design |
+ by Vadim Nasardinov. Modified and converted to Docbook XML by Roberto Mello +
+ The general permissions system has a relatively complex data model in OpenACS 4.x. + Developers who haven't had the time to learn the internals of the data model + may end up writing seemingly correct code that crashes their system in + weird ways. This writeup is the result of my running into such a piece + of code and trying to understand exactly what went wrong. + It is geared towards developers who understand the general permissions + system to the extent that is described in the + + OpenACS 4.x Permisisons documentation, + but who haven't had the opportunity to take a long, careful look at the + system internals. +
+ In OpenACS 4.x, most of the interesting tables are expected to extend (subtype) + the acs_objects table, i.e. they are expected to have an integer + primary key column that references the object_id column of + acs_objects. +
+create table acs_objects (
+ object_id integer
+ not null
+ constraint acs_objects_pk primary key,
+ object_type
+ not null
+ constraint acs_objects_object_type_fk references acs_object_types (object_type),
+ context_id
+ constraint acs_objects_context_id_fk references acs_objects(object_id),
+ security_inherit_p char(1) default 't'
+ not null,
+ constraint acs_objects_sec_inherit_p_ck
+ check (security_inherit_p in ('t', 'f')),
+ creation_user integer,
+ creation_date date default sysdate not null,
+ creation_ip varchar2(50),
+ last_modified date default sysdate not null,
+ modifying_user integer,
+ modifying_ip varchar2(50),
+ constraint acs_objects_context_object_un
+ unique (context_id, object_id) disable
+);
+
+ This means that any interesting entity (object) + in the system has an entry in the acs_objects. This + allows developers to define relationships between any two entities A + and B by defining a relationship between their corresponding entries + in the acs_objects table. One of the applications of this + powerful capability is the general permissions system. +
+ At the heart of the permission system are two tables: acs_privileges + and acs_permissions. +
+ create table acs_privileges (
+ privilege varchar2(100) not null
+ constraint acs_privileges_pk primary key,
+ pretty_name varchar2(100),
+ pretty_plural varchar2(100)
+ );
+
+ create table acs_permissions ( + object_id + not null + constraint acs_permissions_on_what_id_fk references acs_objects (object_id), + grantee_id + not null + constraint acs_permissions_grantee_id_fk references parties (party_id), + privilege + not null + constraint acs_permissions_priv_fk references acs_privileges (privilege), + constraint acs_permissions_pk + primary key (object_id, grantee_id, privilege) + ); +
+ The acs_privileges table stores + named privileges like read, + write, delete, create, and + admin. The acs_permissions + table stores assertions of the form: +
+ Who (grantee_id) can do what (privilege) + on which object (object_id). +
+ The naive approach to managing system security would be to require application developers + to store permission information explicitly about every object, i.e. if the system has 100,000 and 1,000 users + who have the read privilege on all objects, then we would need to store 100,000,000 + entries of the form: +
Table�5.1.�
object_id | grantee_id | privilege |
---|---|---|
object_id_1 | user_id_1 | 'read' |
object_id_1 | user_id_2 | 'read' |
... | ||
object_id_1 | user_id_n | 'read' |
object_id_2 | user_id_1 | 'read' |
object_id_2 | user_id_2 | 'read' |
... | ||
object_id_2 | user_id_n | 'read' |
... | ||
... | ||
object_id_m | user_id_1 | 'read' |
object_id_m | user_id_2 | 'read' |
... | ||
object_id_m | user_id_n | 'read' |
+ Although quite feasible, this approach fails to take advantage of the fact + that objects in the system are commonly organized hierarchally, + and permissions usually follow the hierarchical structure, so that if user + X has the read privilege on object A, she typically + also has the read privilege on all objects attached under A. +
+ The general permission system, as implemented in OpenACS 4.x, takes advantage + of the hierarchical organization of objects to unburden developers of the + necessity to explicitly maintain security information for every single + object. There are three kinds of hierarchies involved. + These are discussed in the following sections. +
+ Suppose objects A, B, ..., + and F form the following hierarchy. +
Table�5.2.�
A + object_id=10 + | ||
B + object_id=20 + | C + object_id=30 + | |
D + object_id=40 + | E + object_id=50 + | F + object_id=60 + |
+ This can be represented in the + acs_objects table + by the following entries: +
+ The first entry tells us that object 20 is the descendant of object 10, and + the third entry shows that object 40 is the descendant of object 20. By + running a CONNECT BY query, + we can compute that object 40 is the second-generation descendant of object 10. + With this in mind, if we want to record the fact that user Joe has the read privilege on objects + A, ..., F, we only need to record one entry in the + acs_permissions table. +
+ The fact that Joe can also read B, C, + ..., and F can be derived by ascertaining that these objects + are children of A by traversing the context hierarchy. + As it turns out, hierarchical queries are expensive. As + Rafael Schloming put it so aptly, Oracle can't deal with hierarchies for shit. +
+ One way to solve this problem is to cache a flattened view of the context tree like so: +
+ Note that the number of entries in the flattened view grows exponentially with + respect to the depth of the context tree. For instance, if you have a fully + populated binary tree with a depth of n, then the number of entries + in its flattened view is +
+ 1 + 2*2 + 3*4 + 4*8 + 5*16 + ... + (n+1)*2n = n*2n+1 + 1
+ Despite its potentially great storage costs, maintaining a + flattened representation of the context tree is exactly what OpenACS 4.x + does. The flattened context tree is stored in the + acs_object_context_index table. +
+ create table acs_object_context_index ( + object_id + not null + constraint acs_obj_context_idx_obj_id_fk references acs_objects(object_id), + ancestor_id + not null + constraint acs_obj_context_idx_anc_id_fk references acs_objects(object_id), + n_generations integer + not null + constraint acs_obj_context_idx_n_gen_ck check (n_generations >= 0), + constraint acs_object_context_index_pk + primary key (object_id, ancestor_id) + ) organization index; +
+ A few things to note about this table are these. Number one, it is + an index-organized + table, which means it is substantially optimized for access by primary key. + Number two, as the above computations suggest, the size of the table + grows polynomially + with respect to the average number of descendants that an object + has, and exponentially + with respect to the depth of the context tree. +
+ The acs_object_context_index is kept in sync with the + acs_objects + table by triggers like this: +
+create or replace trigger acs_objects_context_id_in_tr +after insert on acs_objects +for each row +begin + insert into acs_object_context_index + (object_id, ancestor_id, n_generations) + values + (:new.object_id, :new.object_id, 0); + + if :new.context_id is not null and :new.security_inherit_p = 't' then + insert into acs_object_context_index + (object_id, ancestor_id, + n_generations) + select + :new.object_id as object_id, ancestor_id, + n_generations + 1 as n_generations + from acs_object_context_index + where object_id = :new.context_id; + elsif :new.object_id != 0 then + -- 0 is the id of the security context root object + insert into acs_object_context_index + (object_id, ancestor_id, n_generations) + values + (:new.object_id, 0, 1); + end if; +end; +
+ One final note about + acs_objects. By setting + an object's security_inherit_p column to 'f', you can stop permissions + from cascading down the context tree. In the following example, Joe does not have + the read permissions on C and F. +
Table�5.6.�
| ||
|
| |
|
|
|
+ Privileges are also organized hierarchically. In addition to the five main system privileges + defined in the ACS Kernel data model, application developers may define their own. For instance, + the Bboard package defines the following privileges: +
Table�5.7.�
privilege |
---|
create_category |
create_forum |
create_message |
delete_category |
delete_forum |
delete_message |
moderate_forum |
read_category |
read_forum |
read_message |
write_category |
write_forum |
write_message |
+ By defining parent-child relationship between privileges, the OpenACS data model + makes it easier for developers to manage permissions. Instead of granting + a user explicit read, write, delete, + and create + privileges on an object, it is sufficient to grant the user the admin + privilege to which the first four privileges are tied. To give + a more detailed example, the Bboard privileges are structured + as follows. +
Table�5.8.�
admin | ||||||||||||
create | delete | read | write | moderate forum | ||||||||
create category | create forum | create message | delete category | delete forum | delete message | read category | read forum | read message | write category | write forum | write message |
+ The parent-child relationship between privileges is represented in + the acs_privilege_hierarchy table: +
+ create table acs_privilege_hierarchy ( + privilege + not null + constraint acs_priv_hier_priv_fk references acs_privileges (privilege), + child_privilege + not null + constraint acs_priv_hier_child_priv_fk references acs_privileges (privilege), + constraint acs_privilege_hierarchy_pk + primary key (privilege, child_privilege) + ); +
+ As in the case of the context hierarchy, it is convenient to have a flattened representation + of this hierarchal structure. This is accomplished by defining the following view. +
+ create or replace view acs_privilege_descendant_map + as + select + p1.privilege, + p2.privilege as descendant + from + acs_privileges p1, + acs_privileges p2 + where + p2.privilege in + (select + child_privilege + from + acs_privilege_hierarchy + start with + privilege = p1.privilege + connect by + prior child_privilege = privilege + ) + or p2.privilege = p1.privilege; +
+ As the number of different privileges in the system is expected to be + reasonably small, there is no pressing need to cache the flattened ansector-descendant + view of the privilege hierarchy in a specially maintained table like + it is done in the case of the context hierarchy. +
+ Now for the third hierarchy playing a promiment role in the permission system. The party + data model is set up as follows. +
+ create table parties ( + party_id + not null + constraint parties_party_id_fk references acs_objects (object_id) + constraint parties_pk primary key, + email varchar2(100) + constraint parties_email_un unique, + url varchar2(200) + ); +
+ create table persons ( + person_id + not null + constraint persons_person_id_fk references parties (party_id) + constraint persons_pk primary key, + first_names varchar2(100) + not null, + last_name varchar2(100) + not null + ); +
+ create table users ( + user_id + not null + constraint users_user_id_fk references persons (person_id) + constraint users_pk primary key, + password char(40), + -- other attributes + ); +
+ create table groups ( + group_id + not null + constraint groups_group_id_fk references parties (party_id) + constraint groups_pk primary key, + group_name varchar2(100) not null + ); +
+ Recall that the grantee_id column of the + acs_permissions table references + parties.party_id. + This means that you can grant a privilege on an object to a party, person, user, or group. + Groups represent aggregations of parties. The most common scenario that you are likely + to encounter is a group that is a collection of users, although you could also + have collections of persons, groups, parties, or any mix thereof. +
+ Given that the most common use of groups is to partition users, how do you + build groups? One way is to grant membership explicitly. If you have + a group named Pranksters, you can assign membership to Pete, + Poly, and Penelope. The fact that these users are members of the + Pranksters group will be recorded in the + membership_rels and acs_rels tables: +
+ create table acs_rels ( + rel_id + not null + constraint acs_rels_rel_id_fk references acs_objects (object_id) + constraint acs_rels_pk primary key, + rel_type + not null + constraint acs_rels_rel_type_fk references acs_rel_types (rel_type), + object_id_one + not null + constraint acs_object_rels_one_fk references acs_objects (object_id), + object_id_two + not null + constraint acs_object_rels_two_fk references acs_objects (object_id), + constraint acs_object_rels_un + unique (rel_type, object_id_one, object_id_two) + ); +
+ create table membership_rels ( + rel_id + constraint membership_rel_rel_id_fk references acs_rels (rel_id) + constraint membership_rel_rel_id_pk primary key, + -- null means waiting for admin approval + member_state varchar2(20) + constraint membership_rel_mem_ck + check (member_state in ('approved', 'banned', 'rejected', 'deleted')) + ); +
+ The acs_rels + table entries would look like so: +
Table�5.10.�
rel_type | object_one | object_two |
---|---|---|
+ membership_rel + | + Pranksters + | + Pete + |
+ membership_rel + | + Pranksters + | + Poly + |
+ membership_rel + | + Pranksters + | + Penelope + |
+ Another way of building up groups is by adding subgroups. Suppose + we define Merry Pranksters and Sad Pranksters as subgroups + of Pranksters. We say that the Pranksters group + is composed of + groups Merry Pranksters and Sad Pranksters. This + information is stored in the acs_rels + and composition_rels tables. +
+create table composition_rels ( + rel_id + constraint composition_rel_rel_id_fk references acs_rels (rel_id) + constraint composition_rel_rel_id_pk primary key +); +
+ The relevant entries in the + acs_rels look like so. +
Table�5.11.�
rel_type | object_one | object_two |
---|---|---|
+ composition_rel + | + Pranksters + | + Merry Pranksters + |
+ composition_rel + | + Pranksters + | + Sad Pranksters + |
+ The composition relationship means that if I add Matt, Mel, and Mary to the + Merry Pranksters, + they should also automatically become members of the Pranksters group. + The situation we are + facing in trying to determine whether or not a user is member of a group is similar to the one + discussed above in the case of the context hierarchy. Groups can form hierarchies with + respect to the composition relationship. The compositon relationship is transitive. If + G1 is a subgroup of G2, and G2 is a subgroup of G3, then + G1 is a subgroup of G3; that is, any member of G1 is also a member + of G3. +
+ Traversing the group composition hierarchy requires running + hierarchical queries, + which are expensive in Oracle. As we saw in the Context Hierarchy section, one way of + reducing the performance hit incurred by hierarchical queries is to cache query results in + a table maintained by triggers. The OpenACS 4.x data model defines two such tables: +
+ create table group_component_index ( + group_id not null + constraint group_comp_index_group_id_fk + references groups (group_id), + component_id not null + constraint group_comp_index_comp_id_fk + references groups (group_id), + rel_id not null + constraint group_comp_index_rel_id_fk + references composition_rels (rel_id), + container_id not null + constraint group_comp_index_cont_id_ck + references groups (group_id), + constraint group_component_index_ck + check (group_id != component_id), + constraint group_component_index_pk + primary key (group_id, component_id, rel_id) + ) organization index; +
+ create table group_member_index ( + group_id + not null + constraint group_member_index_grp_id_fk references groups (group_id), + member_id + not null + constraint group_member_index_mem_id_fk references parties (party_id), + rel_id + not null + constraint group_member_index_rel_id_fk references membership_rels (rel_id), + container_id + not null + constraint group_member_index_cont_id_fk references groups (group_id), + constraint group_member_index_pk + primary key (member_id, group_id, rel_id) + ) organization index; +
+ The group_component_index table stores a flattened representation of the + group composition hierarchy that is maintained in sync with the acs_rels + and composition_rels tables through triggers. +
+ As far as the group_member_index table goes, I am not sure I understand its + purpose. It maintains group-member relationships that are resolved with respect + to group composition. Note that information stored in + group_member_index can be trivially derived by joining + membership_rels, + acs_rels, + and group_component_index. Here + is a view that does it. (This view is not part of the OpenACS Kernel data model.) +
+create or replace view group_member_view +as +select + gci.group_id, r.object_id_two as member_id +from + ( + select + group_id, group_id as component_id + from + groups + union + select + group_id, component_id + from + group_component_index + ) gci, + membership_rels mr, + acs_rels r +where + mr.rel_id = r.rel_id + and r.object_id_one = gci.component_id; +
+ A heuristic way to verify that group_member_view is essentially identical + to group_member_index is to compute the + symmetric difference between the two: +
+select + group_id, member_id +from + ( + select group_id, member_id from group_member_view + minus + select group_id, member_id from group_member_index + ) +union +select + group_id, member_id +from + ( + select group_id, member_id from group_member_index + minus + select group_id, member_id from group_member_view + ) +
+ The query returns no rows. The important point is, if we + have a flattened view of the composition hierarchy -- like one provided + by the group_component_index table -- + membership relationship resolution can be computed trivially with no hierarchical + queries involved. There is no need to keep the view in a denormalized + table, unless doing so results in substantial performance gains. +
+ Security information is queried by calling the acs_permission.permission_p + function in OpenACS 4.x. +
+ create or replace package body acs_permission + as + -- some stuff removed for the sake of brevity + + function permission_p ( + object_id acs_objects.object_id%TYPE, + party_id parties.party_id%TYPE, + privilege acs_privileges.privilege%TYPE + ) return char + as + exists_p char(1); + begin + -- XXX This must be fixed: -1 shouldn't be hardcoded (it is the public) + select decode(count(*),0,'f','t') into exists_p + from acs_object_party_privilege_map + where object_id = permission_p.object_id + and party_id in (permission_p.party_id, -1) + and privilege = permission_p.privilege; + return exists_p; + end; + + end acs_permission; +
+ The function simply queries + acs_object_party_privilege_map, + which is a humongous view that joins three flattened hierarchies: + the context tree, the privilege hierarchy, + the party composition (and membership) hierarchy. As such, + it contains an extremely large number of rows. About + the only kind of query you can run against it is the one + performed by the acs_permission.permission_p + function. Anything other than that would take forever to + finish or would ultimately result in an Oracle error. +
+ For example, do not try to do things like +
+select count(*) + from acs_object_party_privilege_map; +
+ To give another example of things to avoid, I have seen code like this: +
+ declare + cursor cur is + select + object_id, party_id + from + acs_object_party_privilege_map + where + privilege = 'foo_create'; + begin + -- revoke all 'foo_create' permissions + for rec in cur + loop + acs_permission.revoke_permission ( + object_id => rec.object_id, + grantee_id => rec.party_id, + privilege => 'foo_create' + ); + end loop; + + acs_privilege.remove_child('admin','foo_create'); + acs_privilege.drop_privilege('foo'); + + end; + / +
+ The acs_permission.revoke_permission function merely runs a + delete statement like so: +
+ delete from + acs_permissions + where + object_id = revoke_permission.object_id + and grantee_id = revoke_permission.grantee_id + and privilege = revoke_permission.privilege; +
+ Note that in the above example, acs_permissions had only + one entry that needed to be deleted: +
+ The above script would never get around to deleting this entry because it had + to loop through a gazillion rows in the humongous + acs_object_party_privilege_map view. +
+create or replace view acs_object_party_privilege_map +as +select + ogpm.object_id, + gmm.member_id as party_id, + ogpm.privilege +from + acs_object_grantee_priv_map ogpm, + group_member_map gmm +where + ogpm.grantee_id = gmm.group_id +union +select + object_id, + grantee_id as party_id, + privilege +from + acs_object_grantee_priv_map; +
+create or replace view acs_object_grantee_priv_map +as +select + a.object_id, + a.grantee_id, + m.descendant as privilege +from + acs_permission_all a, + acs_privilege_descendant_map m +where + a.privilege = m.privilege; +
+create or replace view acs_permissions_all +as +select + op.object_id, + p.grantee_id, + p.privilege +from + acs_object_paths op, + acs_permissions p +where + op.ancestor_id = p.object_id; +
+create or replace view acs_object_paths +as +select + object_id, + ancestor_id, + n_generations +from + acs_object_context_index; +
+ +create or replace view group_member_map +as +select + group_id, + member_id, + rel_id, + container_id +from + group_member_index; +
+
by Rafael H. Schloming
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
-pageroot -- Any directory that contains scripts and/or +provides to the browser.
+pageroot -- Any directory that contains scripts and/or static files intended to be served in response to HTTP requests. A typical -OpenACS installation is required to serve files from multiple pageroots.
global pageroot -(/web/servicename/www) -- Files appearing under +OpenACS installation is required to serve files from multiple pageroots.
global pageroot +(/web/servicename/www) -- Files appearing under this pageroot will be served directly off the base url -http://www.servicename.com/
package root -(/web/servicename/packages) -- Each subdirectory of +http://www.servicename.com/
package root +(/web/servicename/packages) -- Each subdirectory of the package root is a package. A typical OpenACS installation will have several -packages.
package pageroot -(/web/servicename/packages/package_key/www) --- This is the pageroot for the package_key package.
request environment (ad_conn) -- This is +packages.
package pageroot +(/web/servicename/packages/package_key/www) +-- This is the pageroot for the package_key package.
request environment (ad_conn) -- This is a global namespace containing variables associated with the current -request.
abstract URL -- A URL with no extension that doesn't -directly correspond to a file in the filesystem.
abstract file or abstract path -- A URL +request.
abstract URL -- A URL with no extension that doesn't +directly correspond to a file in the filesystem.
abstract file or abstract path -- A URL that has been translated into a file system path (probably by prepending the appropriate pageroot), but still doesn't have any extension and so does -not directly correspond to a file in the filesystem.
concrete file or concrete path -- A file -or path that actually references something in the filesystem.
Package Lookup
One of the first things the request processor must do is to determine which package instance a given request references, and based on this information, which pageroot to use when searching for a file to serve. During this process the request processor divides the URL into two pieces. The first portion identifies the package instance. The rest identifies the path into the package pageroot. For example if the news package is mounted on /offices/boston/announcements/, then a request for /offices/boston/announcements/index would be split into the -package_url (/offices/boston/announcements/), and the +package_url (/offices/boston/announcements/), and the abstract (no extension info) file path (index). The request processor must be -able to figure out which package_id is associated with a +able to figure out which package_id is associated with a given package_url, and package mountings must be persistent across server restarts and users must be able to manipulate the mountings on a live site, -therefore this mapping is stored in the database.
Authentication and Authorization
Once the request processor has located both the package_id and concrete +therefore this mapping is stored in the database.
Authentication and Authorization
Once the request processor has located both the package_id and concrete file associated with the request, authentication is performed by the session security system. After authentication has been performed the user is authorized to have read access for the given package by the OpenACS 4 Permissions Design. If authorization succeeds then the request is served, otherwise it is -aborted.
Concrete File Search
To actually serve a file, the request processor generates an ordered list +aborted.
Concrete File Search
To actually serve a file, the request processor generates an ordered list of abstract paths and searches each path for a concrete file. The first path searched is composed of the package pageroot with the extra portion of the URL appended. The second abstract path consists of the global pageroot with @@ -60,16 +60,16 @@ directory. Files take precedence over directory listings, so an index file in the global pageroot will be served instead of a directory listing in the package pageroot, even though the global pageroot is searched later. If a -file is found at any of the searched locations then it is served.
Virtual URL Handlers
If no file is found during the concrete file search, then the request -processor searches the filesystem for a virtual url handler -(.vuh) file. This file contains normal tcl code, and is in +file is found at any of the searched locations then it is served.
Virtual URL Handlers
If no file is found during the concrete file search, then the request +processor searches the filesystem for a virtual url handler +(.vuh) file. This file contains normal tcl code, and is in fact handled by the same extension handling procedure that handles .tcl files. The only way this file is treated differently is in how the request processor searches for it. When a lookup fails, the request processor generates each valid prefix of all the abstract paths considered in the concrete file search, and searches these prefixes in order from most specific to least specific for a matching .vuh file. If a file is found then the -ad_conn variable path_info is set to the portion of the url +ad_conn variable path_info is set to the portion of the url not matched by the .vuh script, and the script is sourced. This facility is intended to replace the concept of registered procs, since no special distinction is required between sitewide procs and package specific @@ -89,16 +89,14 @@ off the rightmost path components until a match is reached. This way the time required to lookup a URL is proportional to the length of the URL, not to the number of entries in the mapping.
The request environment is managed by the procedure -ad_conn. Variables can be set and retrieved through use of +ad_conn. Variables can be set and retrieved through use of the ad_conn procedure. The following variables are available for public use. If the ad_conn procedure doesn't recognize a variable being passed to it for a lookup, it tries to get a value using ns_conn. This guarantees that -ad_conn subsumes the functionality of ns_conn.
Request processor | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn urlv] | A list containing each element of the URL | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn url] | The URL associated with the request. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn file] | The filepath including filename of the file being served | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn request] | The number of requests since the server was last started | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn start_clicks] | The system time when the RP starts handling the request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
� | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Session System Variables: set in
+ad_conn subsumes the functionality of ns_conn.
rmello at fslc.usu.edu - vinod@kurup.com - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
� | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Documentation | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ad_conn api_page_documentation_mode_p] | � |
Prev | Home | Next |
OpenACS 4 Request Processor Requirements | Up | Database Access API |
+
by Rafael H. Schloming
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
The following is a requirements document for the OpenACS 4.0 request + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
The following is a requirements document for the OpenACS 4.0 request processor. The major enhancements in the 4.0 version include a more sophisticated directory mapping system that allows package pageroots to be mounted at arbitrary urls, and tighter integration with the database to allow @@ -19,11 +19,9 @@ for the connecting party. Eventually this may also require determining the capabilities of the connecting browser and choosing the most appropriate form for the delivered content.
It is essential that any errors that occur during the above steps be -reported to developers in an easily decipherable manner.
10.0 Multiple Pageroots
10.10 Pageroots may be combined into one URL space.
10.20 Pageroots may be mounted at more than one location in the URL -space.
20.0 Application Context
20.10 The request processor must be able to determine a primary context +reported to developers in an easily decipherable manner.
10.0 Multiple Pageroots
10.10 Pageroots may be combined into one URL space.
10.20 Pageroots may be mounted at more than one location in the URL +space.
20.0 Application Context
20.10 The request processor must be able to determine a primary context or state associated with a pageroot based on it's location within the URL -space.
30.0 Authentication
30.10 The request processor must be able to verify that the connecting -browser actually represents the party it claims to represent.
40.0 Authorization
40.10 The request processor must be able to verify that the party the -connecting browser represents is allowed to make the request.
50.0 Scalability
Prev | Home | Next |
OpenACS 4 Security Notes | Up | OpenACS 4 Request Processor Design |
30.0 Authentication
30.10 The request processor must be able to verify that the connecting +browser actually represents the party it claims to represent.
40.0 Authorization
40.10 The request processor must be able to verify that the party the +connecting browser represents is allowed to make the request.
50.0 Scalability
Prev | Home | Next |
OpenACS 4 Security Notes | Up | OpenACS 4 Request Processor Design |
+
by Richard Li, Archit Shah
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
+ OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
This document explains security model design for OpenACS 4. The security system with the OpenACS core must authenticate users in both secure and insecure environments. In addition, this subsystem provides sessions on top of the @@ -43,10 +43,10 @@ for a secure authentication token. However, the basic architecture here lays the foundation for a secure system and can be easily adapted to a more secure authentication system by forcing all logins to occur over HTTPS.
The authentication system issues up to four signed cookies (see below), -with each cookie serving a different purpose. These cookies are:
name value max-age secure? ad_session_id session_id,user_id SessionTimeout no ad_user_login user_id Infinity no ad_user_login_secure user_id,random Infinity yes ad_secure_token session_id,user_id,random SessionLifetime yes
ad_session_id
reissued on any hit separated by more than SessionRenew seconds from the -previous hit that received a cookie
is valid only for SessionTimeout seconds
is the canonical source for the session ID in ad_conn
ad_user_login
is used for permanent logins
ad_user_login_secure
is used for permanent secure logins
contains random garbage (ns_time) to prevent attack against the secure +with each cookie serving a different purpose. These cookies are:
name value max-age secure? ad_session_id session_id,user_id SessionTimeout no ad_user_login user_id Infinity no ad_user_login_secure user_id,random Infinity yes ad_secure_token session_id,user_id,random SessionLifetime yes
ad_session_id
reissued on any hit separated by more than SessionRenew seconds from the +previous hit that received a cookie
is valid only for SessionTimeout seconds
is the canonical source for the session ID in ad_conn
ad_user_login
is used for permanent logins
ad_user_login_secure
is used for permanent secure logins
contains random garbage (ns_time) to prevent attack against the secure hash
ad_secure_token -
is a session-level cookie from the browser's standpoint
its signature expires in SessionLifetime seconds
contains random garbage (ns_time) to prevent attack against the secure +
is a session-level cookie from the browser's standpoint
its signature expires in SessionLifetime seconds
contains random garbage (ns_time) to prevent attack against the secure hash
user_id is extraneous
The Tcl function (sec_handler) is called by the request processor to authenticate the user. It first checks the ad_session_id cookie. If there is no valid session in progress, @@ -86,7 +86,7 @@ immediately
nothing: if the cookie is present, it remains
The current state of the permanent login cookies is not taken into account when determining the appropriate action. -
previous login state permanent login requested secure connection action on insecure action on secure other y y set set same y y set set other y n set delete same y n set nothing same n y nothing delete other n y delete delete other n n delete delete same n n delete delete
ad_user_login +
previous login state permanent login requested secure connection action on insecure action on secure other y y set set same y y set set other y n set delete same y n set nothing same n y nothing delete other n y delete delete other n n delete delete same n n delete delete
ad_user_login callssec_setup_session which actually calls sec_generate_session_id_cookie to generate the new cookie with refer to the appropriate user_id. If the connection is secure @@ -206,13 +206,13 @@ token_id is returned out of the entire set of cached token_ids. In addition, a thread-persistent cache called tcl_secret_tokens is maintained on a per-thread basis.
Thus, the L2 ns_cache functions as a server-wide LRU cache that has a -minimum of 100 tokens in it. The cache has a dual purpose:
LRU cache Note that cache misses will only occur in the +minimum of 100 tokens in it. The cache has a dual purpose:
LRU cache Note that cache misses will only occur in the multiple server case, where a user agent may have a signature guaranteed by a -secret token issued by another server in the cluster.
signature cache Since the cache always maintains a +secret token issued by another server in the cluster.
signature cache Since the cache always maintains a minimum of 100 (set by a parameter) tokens populated at startup, it can be used to provide a random token for signature purposes.
The per-thread cache functions as an L1 cache that indiscriminately caches -all secret tokens. Note that this is not an LRU cache +all secret tokens. Note that this is not an LRU cache because there is no cache eviction policy per se -- the cache is cleared when the thread is destroyed by AOLserver.
-ad_user_login user_id Logs the user in as user +ad_user_login user_id Logs the user in as user user_id. Optional forever flag determines whether or not permanent cookies are issued. -
ad_user_logout Logs the user out.
ad_check_password user_id password -returns 0 or 1.
ad_change_password user_id new -password
-ad_sign value Returns the digital signature of this +
ad_user_logout Logs the user out.
ad_check_password user_id password +returns 0 or 1.
ad_change_password user_id new +password
+ad_sign value Returns the digital signature of this value. Optional parameters allow for the specification of the secret used, the token_id used and the max_age for the signature. -ad_verify_signature value signatureReturns +ad_verify_signature value signatureReturns 1 or 0 indicating whether or not the signature matches the value specified. The secret parameter allows for specification of a different secret token to be used.
-ad_set_signed_cookie name data Sets a -signed cookie name with value data.
ad_get_signed_cookie name Gets the signed cookie +ad_set_signed_cookie name data Sets a +signed cookie name with value data.
ad_get_signed_cookie name Gets the signed cookie name. It raises an error if the cookie has been tampered with, or if -its expiration time has passed.
ad_set_client_property module name -data Sets a session property with name to value +its expiration time has passed.
ad_set_client_property module name +data Sets a session property with name to value data for the module module. The optional secure flag specifies the property should only be set if the client is authorized for secure access (ad_secure_conn_p is true). There is also an optional -session_id flag to access data from sessions other than the current one.
ad_get_client_property module name -data Gets a session property with name to for the +session_id flag to access data from sessions other than the current one.
ad_get_client_property module name +data Gets a session property with name to for the module module. The optional secure flag specifies the property should only be retrieved if the client is authorized for secure access (ad_secure_conn_p is true). There is also an optional session_id flag to access data from sessions other than the current one.
-SessionTimeout the maximum time in seconds (default 1200) -between requests that are part of the same session
SessionRenew the time in seconds (default 300) between +SessionTimeout the maximum time in seconds (default 1200) +between requests that are part of the same session
SessionRenew the time in seconds (default 300) between reissue of the session cookie. The minimum time that can pass after a session cookie is issued and before it is rejected is (SessionTimeout - SessionRenew). This parameter is used so that only one session_id cookie is set on a single page even if there are multiple images that are being -downloaded.
SessionLifetime the maximum possible lifetime of a -session in seconds (default 604800 = 7 days)
NumberOfCachedSecretTokens the number of secret tokens to +downloaded.
SessionLifetime the maximum possible lifetime of a +session in seconds (default 604800 = 7 days)
NumberOfCachedSecretTokens the number of secret tokens to cache. (default 100)
The pseudorandom number generator used in the OpenACS is cryptographically weak, and depends primarily on the randomness of the ns_rand function @@ -339,17 +339,15 @@ points for the system; these vulnerabilities are currently theoretical in nature. The major cryptographic vulnerability of the system stems from the pseudorandom nature of the random number generators used in the system. -
Cryptographically weak PRNG see -above.
Dependence on sample -SQL command The list of random token that are placed in the secret +
Cryptographically weak PRNG see +above.
Dependence on sample +SQL command The list of random token that are placed in the secret tokens cache is randomly chosen by the Oracle sample command. This command may not be entirely random, so predicting the contents of the secret tokens cache may not -be as difficult as someone may anticipate.
Dependence on -ns_rand The actual token that is +be as difficult as someone may anticipate.
Dependence on +ns_rand The actual token that is chosen from the cache to be used is chosen by a call to -ns_rand.
ad_secure_conn_p +ns_rand.
ad_secure_conn_p As discussed above, the security of the secure sessions authentication system is -dependent upon this function.
Prev | Home | Next |
OpenACS 4 Security Requirements | Up | OpenACS 4 Security Notes |
Prev | Home | Next |
OpenACS 4 Security Requirements | Up | OpenACS 4 Security Notes |
+
by Richard Li
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
+ OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
Virtually all web sites support personalized content based on user identity. @@ -15,36 +15,34 @@ vendors require that the user identity be securely validated.
The security system consists of a number of subsystems. -
Signed Cookies
+
Signed Cookies
Cookies play a key role in storing user information. However, since they are stored in plaintext on a user's system, the validity of cookies is an important issue in trusting cookie information. Thus, we want to be able to validate a cookie, but we also want to validate the cookie without a database hit. -
10.0 Guaranteed Tamper Detection Any tampering of cookie -data should be easily detectable by the web server.
10.1 Performance and Scalability Validation and +
10.0 Guaranteed Tamper Detection Any tampering of cookie +data should be easily detectable by the web server.
10.1 Performance and Scalability Validation and verification of the cookie should be easily scalable and should not require a -database query on every hit.
Session Properties
+database query on every hit.
Session Properties
Applications should be able to store session-level properties in a database table. -
11.0 Storage API Session-level data should be accessible -via an API.
11.1 Purge Mechanism An efficient pruning mechanism +
11.0 Storage API Session-level data should be accessible +via an API.
11.1 Purge Mechanism An efficient pruning mechanism should be used to prevent old session level properties from filling up the -table.
Login
+table.
Login
The security system should support the concept of persistent user logins. This persistence takes several forms. -
12.0 Permanent Login Users should be able to maintain a -permanent user login so that they never need to type their password.
12.1 Session Login The security system should support +
12.0 Permanent Login Users should be able to maintain a +permanent user login so that they never need to type their password.
12.1 Session Login The security system should support the concept of a session, with authentication tokens that become invalid -after a certain period of time.
12.2 Session Definition A session is a sequence of +after a certain period of time.
12.2 Session Definition A session is a sequence of clicks by one user from one browser in which no two clicks are separated by -more than some constant (the session timeout).
12.3 Stateless The security system should not require +more than some constant (the session timeout).
12.3 Stateless The security system should not require state that is stored in the server. Required state may reside only in the user request (including cookies), and in the database. A single user should be able to log in to the system even if the user is sent to a different -AOLserver for each step of the login process (e.g., by a load balancer).
12.4 Secure The security system should not store -passwords in clear text in the database.
13.0 SSL Hardware The system must work when the SSL +AOLserver for each step of the login process (e.g., by a load balancer).
12.4 Secure The security system should not store +passwords in clear text in the database.
13.0 SSL Hardware The system must work when the SSL processing occurs outside of the web server (in specialized hardware, in a -firewall, etc.).
Prev | Home | Next |
OpenACS 4.5 Package Manager Design | Up | OpenACS 4 Security Design |
Prev | Home | Next |
OpenACS 4.6 Package Manager Design | Up | OpenACS 4 Security Design |
+
by Rafael H. Schloming
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
*Note* This document has not gone through the any of the + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
*Note* This document has not gone through the any of the required QA process yet. It is being tagged as stable due to high demand.
An OpenACS 4 subsite is a managed suite of applications that work together for a particular user community. This definition covers a very broad range of @@ -41,7 +41,7 @@ URLs to operate together. This requirement would cause some packages to have more configuration options than normal since hard-coding the URLs would not be feasible anymore.
This section will cover all the APIs relevant to subsites, and so will -consist of portions of the APIs of several systems.
Packages
The following package is provided for instantiation of packages. The +consist of portions of the APIs of several systems.
Packages
The following package is provided for instantiation of packages. The apm_package.new function can be used to create a package of any type known to the system. The apm_package_types table can be queried for a list of installed packages. (See APM docs for more detail XXX: insert link here)
@@ -101,7 +101,7 @@ show errors -
Site Nodes
This data model keeps track of what packages are being served from what +
Site Nodes
This data model keeps track of what packages are being served from what URLs. You can think of this as a kind of rp_register_directory_map on drugs. This table represents a fully hierarchical site map. The directory_p column indicates whether or not the node is a leaf node. The pattern_p column @@ -182,7 +182,7 @@ show errors -
Request Processor
Once the above APIs are used to create packages and mount them on a +
Request Processor
Once the above APIs are used to create packages and mount them on a specific site node, the following request processor APIs can be used to allow the package to serve content appropriate to the package instance.
@@ -210,6 +210,4 @@ a particular configuration of site nodes/packages. As we build more fundamental applications that can be applied in more general areas, this feature will become more and more in demand since more problems will be -solvable by configuration instead of coding.
Prev | Home | Next |
OpenACS 4 Subsites Requirements | Up | OpenACS 4.5 Package Manager Requirements |
Prev | Home | Next |
OpenACS 4 Subsites Requirements | Up | OpenACS 4.6 Package Manager Requirements |
+
by Rafael H. Schloming and Dennis Gregorovic
- OpenACS docs are written by the named authors, but may be edited
- by OpenACS documentation staff.
-
The following is a requirements document for OpenACS 4 Subsites, part of the + OpenACS docs are written by the named authors, but may be edited + by OpenACS documentation staff. +
The following is a requirements document for OpenACS 4 Subsites, part of the OpenACS 4 Kernel. The Subsites system allows one OpenACS server instance to serve multiple user communities, by enabling the suite of available OpenACS applications to be customized for defined user communities.
Many online communities are also collections of discrete subcommunities, @@ -42,19 +42,17 @@ office. At this point, the Boston and Austin office admins can customize the configurations for each of their bboards, or they can just use the defaults.
Test plan (Not available yet)
A subsite API is required for programmers to ensure their packages are -subsite-aware. The following functions should be sufficient for this:
10.10.0 Package creation
The system must provide an API call to create a package, and it must be -possible for the context (to which the package belongs) to be specified.
10.20.0 Package deletion
The system must provide an API call to delete a package and all related -objects in the subsite's context.
10.30.0 Object's package information
Given an object ID, the system must provide an API call to determine the -package (ID) to which the object belongs.
10.40.0 URL from package
Given a package (ID), the system must provide an API call to return the -canonical URL for that package.
10.50.0 Main subsite's package_id
The system must provide an API call to return a package ID corresponding -to the main subsite's package ID (the degenerate subsite).
The Programmer's User Interface
There is no programmer's UI, other than the API described above.
The Administrator's User Interface
The UI for administrators is a set of HTML pages that are used to drive +subsite-aware. The following functions should be sufficient for this:
10.10.0 Package creation
The system must provide an API call to create a package, and it must be +possible for the context (to which the package belongs) to be specified.
10.20.0 Package deletion
The system must provide an API call to delete a package and all related +objects in the subsite's context.
10.30.0 Object's package information
Given an object ID, the system must provide an API call to determine the +package (ID) to which the object belongs.
10.40.0 URL from package
Given a package (ID), the system must provide an API call to return the +canonical URL for that package.
10.50.0 Main subsite's package_id
The system must provide an API call to return a package ID corresponding +to the main subsite's package ID (the degenerate subsite).
The Programmer's User Interface
There is no programmer's UI, other than the API described above.
The Administrator's User Interface
The UI for administrators is a set of HTML pages that are used to drive the underlying API for package instance management (i.e. adding, removing, or altering packages). It is restricted to administrators of the current subsite such that administrators can only manage their own subsites. Of course, -Site-Wide Administrators can manage all subsites.
20.10.0 Package creation
20.10.1 The administrator should be able to create a -package and make it available at a URL underneath the subsite.
20.20.0 Package deactivation
20.20.1 The administrator should be able to deactivate -any package, causing it to be inaccessible to users.
20.20.5 Deactivating a package makes the package no +Site-Wide Administrators can manage all subsites.
20.10.0 Package creation
20.10.1 The administrator should be able to create a +package and make it available at a URL underneath the subsite.
20.20.0 Package deactivation
20.20.1 The administrator should be able to deactivate +any package, causing it to be inaccessible to users.
20.20.5 Deactivating a package makes the package no longer accessible, but it does not remove data created within the context of -that package.
Prev | Home | Next |
OpenACS 4 Groups Design | Up | OpenACS 4 Subsites Design Document |
Prev | Home | Next |
OpenACS 4 Groups Design | Up | OpenACS 4 Subsites Design Document |
Prev | Home | Next |
Part Part II. For OpenACS Admins | Up | Overview |
Table of Contents
Table of Contents
Prev | Home | Next |
Chapter 3. Installing on Windows | Up | OpenACS Installation Guide for Windows2000 |
Prev | Home | Next |
Chapter�3.�Installing on Windows | Up | OpenACS Installation Guide for Windows2000 |
- |
-
- |
-
- |
-
- |
-
- |
-
- |
-
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+
+ |
+
-
-
+
+