A re-work of guest handling in .LRN was committed to the dotlrn-2-0 branch on February 20, 2004. Here's a summary of what was changed and why.
In the US (and more so elsewhere), privacy laws govern what sorts of information educational institutions may share and with whom. The first versions of .LRN shipped with something called "Guest status" and an OpenACS permissions system privilege called "read_private_data". Historically guest status hasn't been well understood nor much applied. Over time, changes in OpenACS started to break the initial implementation, revealing it's weaknesses. This prompted the changes we describe here.
read_private_data
is the OpenACS permissions
system privilege that is required to view data designated by various
packages as private data. At the time of this writing (February,
2004) this privilege is little used and inconsistently used, but we
believe this was in part due to the limitations that this upgrade aims
to remove. Prior to .LRN 2.0.2, guest status was handled in the following way:
read_private_data
privilege on the dotlrn instance mounted at "/dotlrn", as returned by
dotlrn::get_package_id
.
read_private_data
.read_private_data
on an appropriate object.acs-tcl/tcl/acs-private-data-procs.tcl
or dotlrn/tcl/dotlrn-security-procs.tcl
which allowed ad-parameter-based overriding for backwards compatibility.
There are a few problems with this design. The first stems from
initial confusion about how the permissions inheritance hierarchy
should be set up. In early versions of .LRN, all communities
inherited permissions from the main .LRN instance. Thus if a user was
granted read_private_data
on the main .LRN instance, they
would automatically get read_private_data
on every object
under dotlrn. Unfortunately, this also meant that other privileges
cascaded down from the main .LRN instance. This includes
read
, which all users are granted so that they can view
shared, .LRN-wide pages such the "join communities" page. Because cascading
read
permission would have allowed users to view data in
communities to which they didn't belong, permissions inheritance was
turned off between the main .LRN instance and the communities below
it.
But turning off permissions inheritance also meant that
read_private_data
did not cascade as originally
envisioned. This led to bugs in areas where private data was
protected, notably bug #1549 ("Regular
users cannot post to forums").
Another limitation was revealed by a SloanSpace requirement that, in specific communities, it should be possible allow guests to view private data about members. Because a user's guest status is determined by whether or not they have a specific permission, there was no straightforward way to say "this person is a guest, but they should be able see private data in Community X." Sloan evolved some custom code to handle this case, which added wrappers to allow disabling of the permission check on a community-by-community basis.
packages/dotlrn/sql/db/privacy-init.sql
packages/dotlrn/sql/db/privacy-package-create.sql
packages/dotlrn/tcl/privacy-procs.tcl
The new implementation separates the storage of Guest/Non-guest status
from specific permission grants. Two new relationship types are
created, dotlrn_guest_rel
for Guests and
dotlrn_non_guest_rel
for Non-guests. A user's guest
status is determined by which of these two relationships the user has
with the Registered Users group, the "magic object" corresponding to
registered_users
. Two new relational segments are also
created: "Registered .LRN Guests" for users having a
dotlrn_guest_rel
with Registered Users and "Registered
.LRN Non-guests" for users having a dotlrn_non_guest_rel
with Registered Users.
Permissions are selectively granted to these relational segments on a
community by community basis. read_private_data
is
granted to Non-Guests on each community when the community is created.
read_private_data
may be granted to Non-guests by the
.LRN site administrator for specific communities, from the community
admin screen. This ability to open up private data is restricted to
site administrators because of the legal implications.
Once granted, read_private_data
permissions will
cascade to all objects in the community which have permissions
inheritance turned on (most or all objects). Permissions are checked
with the standard OpenACS calls in
packages/acs-tcl/tcl/acs-private-data-procs.tcl
. These
calls will bypass the permission check if the kernel parameter
PrivacyControlEnabledP
is set to 0. Thus it is safe to
put permission checks in generic packages such as forums, which should
protect private data when run in .LRN but not in a regular OpenACS
site. Privacy control should be enabled on .LRN sites and disabled on
regular OpenACS sites.