Annotation of perl/modules/CGI/RDFchacl, revision 1.2

1.1       eric        1: #!/usr/bin/perl
                      2: 
                      3: 
                      4: ## W3C chaclCGI - change access control list for a resource
                      5: 
                      6: #Copyright Massachusetts Institute of technology, 1998.
                      7: #Written by Eric Prud'hommeaux
                      8: 
                      9: #things that need to be done:
                     10: #1. purty it up (add icons)
                     11: #2. consider "like $resource%"
                     12: 
                     13: #####
                     14: # What It Does:
                     15: # presents form to edit ACLs for a resource. The form is preloaded with the 
                     16: # current ACLs for that resource. chaclCGI hands its output back to itself.
                     17: 
                     18: #####
                     19: # set up module environment
                     20: 
                     21: use strict;
                     22: BEGIN {unshift@INC,('..');}
                     23: 
                     24: package chacl;
                     25: use CGI;
                     26: use W3C::Util::Exception;
                     27: use W3C::Rnodes::CGIChacl qw(&resourcePrompt &showMySources);
                     28: use W3C::Util::W3CDebugCGI;
                     29: use W3C::Rnodes::UnixPermAgent;
                     30: use W3C::Rnodes::RdfAclAgent;
                     31: use W3C::Rnodes::W3CAclAgent;
                     32: use W3C::Rdf::RdfApp;
                     33: use W3C::Rdf::Atoms;
                     34: use W3C::Rnodes::ACL qw($MACRO_RULENAME $MACRO_RULEICON 
                     35:                        $MACRO_RULES $MACRO_RULE_TYPE $MACRO_RULE_ID $MACRO_RULE_ACCESS
                     36:                        %TEXT_TYPE);
                     37: # W3C-specific ACL layous are kept in a separate module
                     38: use W3C::Rnodes::W3CWebAcls qw(@MACRO_OPTIONS @MACRO_LAYOUT
                     39:                               &getStandardW3CMacro &standardDescToW3CMacro
                     40:                               &standardW3CMacroToDesc &standardW3CMacroToIcon
                     41:                               &standardMatch);
                     42: 
                     43: use vars qw($REVISION $VERSION @ISA);
                     44: $VERSION=0.10;
1.2     ! eric       45: $REVISION = '$Id: RDFchacl,v 1.1 2000/11/06 10:18:37 eric Exp $ ';
1.1       eric       46: @ISA = qw(W3C::Rnodes::CGIChacl);
                     47: 
                     48: # Queries to get a user's prefs from the persistent DB
                     49: use vars qw($PREFS_QUERY_FULL_LAYOUT $PREFS_QUERY_MACRO_SET
                     50:            $PREFS_QUERY_LAYOUT $PREFS_QUERY_OPTIONS $PREFS_QUERY_MACRO);
                     51: 
                     52: # This query would be used to pre-fill a local DB to make the queries more efficient
                     53: $PREFS_QUERY_FULL_LAYOUT = <<EOF
                     54: (ask '((http://www.w3.org/1999/02/22-rdf-syntax-ns#type ?layout http://www.w3.org/schema/chaclv1/Layout)
                     55:        (http://www.w3.org/schema/chaclv1/inRows ?layout ?rowSeq)
                     56:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?rowSeq ?row)
                     57:        (http://www.w3.org/schema/chaclv1/inColumns ?row ?colSeq)
                     58:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?colSeq ?macro)
                     59:        (http://www.w3.org/schema/chaclv1/Title ?macro ?title)
                     60:        (http://www.w3.org/schema/certHTMLv1/acl ?macro ?acl)
                     61:        (http://www.w3.org/schema/certHTMLv1/img ?macro ?img)
                     62:        (http://www.w3.org/schema/certHTMLv1/resourceAccessRule ?macro ?rule)
                     63:        (http://www.w3.org/schema/certHTMLv1/accessor ?rule ?accessor)
                     64:        (http://www.w3.org/schema/certHTMLv1/access ?rule ?access))
                     65:  :collect '(?row ?macro ?title ?acl ?img ?accessor ?access))
                     66: EOF
                     67:     ;
                     68: 
                     69: $PREFS_QUERY_MACRO_SET = <<EOF
                     70: (ask '((http://www.w3.org/1999/02/22-rdf-syntax-ns#type ?macroSet http://www.w3.org/schema/chaclv1/MacroSet)
                     71:        (http://www.w3.org/schema/chaclv1/inOrder ?macroSet ?macroSeq)
                     72:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?macroSeq ?macro)
                     73:        (http://www.w3.org/schema/chaclv1/Title ?macro ?title)
                     74:        (http://www.w3.org/schema/certHTMLv1/acl ?macro ?acl)
                     75:        (http://www.w3.org/schema/certHTMLv1/img ?macro ?img)
                     76:        (http://www.w3.org/schema/certHTMLv1/resourceAccessRule ?macro ?rule)
                     77:        (http://www.w3.org/schema/certHTMLv1/accessor ?rule ?accessor)
                     78:        (http://www.w3.org/schema/certHTMLv1/access ?rule ?access))
                     79:  :collect '(?macro ?title ?acl ?img ?rule ?accessor ?access))
                     80: EOF
                     81:     ;
                     82: 
                     83: $PREFS_QUERY_LAYOUT = <<EOF
                     84: (ask '((http://www.w3.org/1999/02/22-rdf-syntax-ns#type ?layout http://www.w3.org/schema/chaclv1/Layout)
                     85:        (http://www.w3.org/schema/chaclv1/inRows ?layout ?rowSeq)
                     86:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?rowSeq ?row)
                     87:        (http://www.w3.org/schema/chaclv1/inColumns ?row ?colSeq)
                     88:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?colSeq ?macro))
                     89:  :collect '(?row ?macro))
                     90: EOF
                     91:     ;
                     92: 
                     93: $PREFS_QUERY_OPTIONS = <<EOF
                     94: (ask '((http://www.w3.org/1999/02/22-rdf-syntax-ns#type ?layout http://www.w3.org/schema/chaclv1/Options)
                     95:        (http://www.w3.org/schema/chaclv1/inOrder ?layout ?seq)
                     96:        (http://www.w3.org/1999/02/22-rdf-syntax-ns#li ?seq ?option))
                     97:  :collect '(?option))
                     98: EOF
                     99:     ;
                    100: 
                    101: $PREFS_QUERY_MACRO = <<EOF
                    102: (ask '((http://www.w3.org/schema/chaclv1/Title ?macro ?title)
                    103:        (http://www.w3.org/schema/certHTMLv1/acl ?macro ?acl)
                    104:        (http://www.w3.org/schema/certHTMLv1/img ?macro ?img)
                    105:        (http://www.w3.org/schema/certHTMLv1/resourceAccessRule ?macro ?rule)
                    106:        (http://www.w3.org/schema/certHTMLv1/accessor ?rule ?accessor)
                    107:        (http://www.w3.org/schema/certHTMLv1/access ?rule ?access))
                    108:  :collect '(?title ?acl ?img ?accessor ?access))
                    109: EOF
                    110:     ;
                    111: 
                    112: my ($query, $chacl);
                    113: eval {
                    114:     $W3C::Util::W3CDebugCGI::DEBUG_SESSION = $ARGV[1]; # use a session id like 957296047.909868;
                    115:     $query = new W3C::Util::W3CDebugCGI($0, $ARGV[0] eq 'DEBUG', 
                    116:                                        {-storeIn => '/tmp', 
                    117:                                         -dieNoOpen => 1, -logExt => '.log', 
                    118:                                         -rerun => 'w3c_rerun', 
                    119:                                         -reconstruct => 'reconstruct'});
                    120:     my $properties = new W3C::Util::Properties('../Conf/RDFchacl.prop');
                    121: 
                    122:     #####
                    123:     # main - either chaclCGI or show source
                    124:     if ($query->param('w3c_showSource')) {
                    125:        &showMySources($query);
                    126:     } elsif ($query->param('w3c_resource') || $query->param('w3c_rdf_acl')) {
                    127:        $chacl = new chacl($query, $properties);
                    128:        $chacl->execute;
                    129:     } else {
                    130:        &resourcePrompt($query);
                    131:     }
                    132: }; if ($@) {
                    133:     my $sessionId = $query ? $query->getSessionId : undef;
1.2     ! eric      134:     if (my $ex = &catch('W3C::Util::HttpMessageException')) {
1.1       eric      135:        $chacl->{ACL_REPOSITORY}->disconnect if ($chacl && $chacl->{ACL_REPOSITORY});
                    136:        delete $chacl->{ACL_REPOSITORY};
                    137:        $ex->addHeader('Session-Id', $sessionId) if (defined $sessionId);
                    138:        print $ex->toString;
                    139:     } elsif (my $ex = &catch('W3C::Rdf::CGIApp::AppException')) {
                    140:        print $ex->toString($sessionId);
                    141:     } elsif (my $ex = &catch('W3C::Util::Exception')) {
                    142:        print "Status: 500\n\n";
                    143:        print "<pre>".$ex->toString."</pre>\n";
                    144:        if ($sessionId) {
                    145:            print "<p>Session-id: $sessionId</p>\n";
                    146:        }
                    147:     } else {
                    148:        print "Status: 500\n\n";
                    149:        print "died with $@";
                    150:        if ($sessionId) {
                    151:            print "<p>Session-id: $sessionId</p>\n";
                    152:        }
                    153:     }
                    154: }
                    155: 
                    156: sub loadAgents {
                    157:     my ($self) = @_;
                    158:     $self->{ACL_REPOSITORY} = new W3C::Rnodes::RdfAclAgent(-properties => $self->{PROPERTIES}, 
                    159:                                                           -atomDictionary => $self->{-atomDictionary});
                    160:     $self->{ACL_IMPORTERS} = [$self->{ACL_REPOSITORY}];
                    161: }
                    162: 
                    163: sub importAcls {
                    164:     my ($self, $aclDB, $resourceList, $wildcard) = @_;
                    165:     my ($added);
                    166:     eval {
                    167:        foreach my $importer (@{$self->{ACL_IMPORTERS}}) {
                    168:            $added += $importer->getAclsFor($aclDB, $resourceList, $wildcard);
                    169:        }
                    170:     }; if ($@ && !$added) {if (my $ex = &catch('W3C::Rnodes::UnixPermAgent::NeedRedirectException')) {
                    171:        &throw($self->redirect($ex->getTarget, $ex->getUri));
                    172:     } elsif (my $ex = &catch('W3C::Util::NoSuchFileException')) {
                    173:        &throw($self->badResource($ex->getFile));
                    174:     } elsif (my $ex = &catch('W3C::Util::MalformedUriException')) {
                    175:        &throw($self->badResource($ex->getUri));
                    176:     } elsif (my $ex = &catch('W3C::Rnodes::UnixPermAgent::NoMapForResourceException')) {
                    177:        &throw($self->noMapsForURI($ex->getHost, $ex->getUri));
                    178:     } elsif (my $ex = &catch('W3C::Util::Exception')) {
                    179:        &throw($self->unknownException($ex));
                    180:     } else {
                    181:        &throw($self->unknownException($@, ' reading ACLs'));
                    182:     }}
                    183: }
                    184: 
                    185: sub readPrefs {
                    186:     my ($self, $prefs) = @_;
                    187:     my $rdfApp = new W3C::Rdf::RdfApp([], -atomDictionary => $self->{-atomDictionary});
                    188:     # $rdfApp->{ARGS}{-files} = [$prefs];
                    189:     $rdfApp->prepareParser();
                    190:     $rdfApp->parseOne(&W3C::Rdf::RdfApp::getInputSource($prefs));
                    191:     my $queryHandler = $rdfApp->{RDF_DB}->getAlgaeInterface;
                    192:     my $query = $PREFS_QUERY_MACRO_SET;
                    193:     my $sysID = undef; # $rdfApp->{RDF_DB}->getUri($ENV{'SCRIPT_NAME'} ? 'http://'.$ENV{'SERVER_NAME'}.$ENV{'SCRIPT_NAME'} : 'http://www.w3.org/');
                    194:     my ($rows, $selects, $messages) = $queryHandler->algae($query, $sysID, {-uniqueResults => 1});
                    195:     my ($curMacro, $curRule);
                    196:     $self->{MACRO_OPTIONS} = [];
                    197:     foreach my $row (@$rows) {
                    198:        my ($macro, $title, $acl, $img, $rule, $accessor, $access) = 
                    199:            map {$_->isa('W3C::Rdf::String') ? $_->getString : $_->getUri} @$row;
                    200:        # print sprintf ("%s %s %s %s %s %s\n", $option, $title, $acl, $img, $accessor, $access);
                    201:        if ($macro ne $curMacro) {
                    202:            $curMacro = $macro;
                    203:            push (@{$self->{MACRO_OPTIONS}}, []);
                    204:            $curRule = undef;
                    205:        }
                    206:        if ($rule ne $curRule) {
                    207:            $curRule = $rule;
                    208:            push (@{$self->{MACRO_OPTIONS}[-1][$MACRO_RULES]}, []);
                    209:        }
                    210:        my ($type, $id);
                    211:        if ($accessor eq 'http://www.w3.org/1999/02/22-rdf-syntax-ns#NULL') {
                    212:            ($type, $id) = ('U', undef);
                    213:        } else {
                    214:            ($type, $id) = &parseDBRuleId($accessor);
                    215:            $type = $TEXT_TYPE{$type};
                    216:        }
                    217:        $access = &accessBitField($access);
                    218:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULENAME] = $title;
                    219:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULE_ID] = $acl;
                    220:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULEICON] = $img;
                    221:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULES][-1][$MACRO_RULE_TYPE] = $type;
                    222:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULES][-1][$MACRO_RULE_ID] = $id;
                    223:        $self->{MACRO_OPTIONS}[-1][$MACRO_RULES][-1][$MACRO_RULE_ACCESS] = $access;
                    224:     }
                    225: # file://quake.w3.org/usr/local/httpd/WWW/Systems/Code/Conf/chaclPrefs.rdf#row1
                    226: # http://www.w3.org/Icons/toc3off.gif
                    227: # http://www.w3.org/Systems/db/webId
                    228: # chacl,racl,head,get,put,delete,connect,options,trace
                    229: # racl,head,get,options,trace
                    230: 
                    231: #row1 #user   "user"   "4" img:toc5off.gif rdf:NULL               "ALL"
                    232: #row1 #team   "team"   "5" img:toc3off.gif ids:group=w3cteamgroup "ALL"
                    233: #row1 #member "member" "6" img:toc2off.gif ids:group=cabal        "READ"
                    234: #row1 #member "member" "6" img:toc2off.gif ids:group=w3cteamgroup "ALL"
                    235: #row1 #world  "world"  "7" img:toc1off.gif ids:all=all            "READ"
                    236: #row1 #world  "world"  "7" img:toc1off.gif ids:group=w3cteamgroup "ALL"
                    237: #row2 #team   "team"   "5" img:toc3off.gif ids:group=w3cteamgroup "ALL"
                    238: #row2 #world  "world"  "7" img:toc3off.gif ids:all=all            "READ"
                    239: #row2 #world  "world"  "7" img:toc3off.gif ids:group=w3cteamgroup "ALL"
                    240: }
                    241: 
                    242: sub getRuleInfo {
                    243:     my ($self, $aclCheckDB, $user, $byType, $resources) = @_;
                    244:     my ($acl, $diffs, $userMatches) = &standardMatch($aclCheckDB, $user, $byType, $resources);
                    245:     my $ruleName = $MACRO_OPTIONS[$acl][$MACRO_RULENAME];
                    246:     return ($acl, $diffs, $userMatches, $ruleName);
                    247: }
                    248: 
                    249: sub renderLocalMacros {
                    250:     my $ret;
                    251:     foreach my $row (@MACRO_LAYOUT) {
                    252:        $ret .= "  <tr>\n";
                    253:        foreach my $macro (@$row) {
                    254:            $ret .= "    <td align=\"center\">\n";
                    255:            $ret .= "      <input type=\"submit\" name=\"w3c_macro\" value=\"$macro->[$MACRO_RULENAME]\" /></td>\n";
                    256:        }
                    257:        $ret .= "  </tr>\n";
                    258:     }
                    259:     return (@MACRO_LAYOUT, $ret);
                    260: }
                    261: 
                    262: sub getStandardMacro { # static
                    263:     my ($self, $aclDB, $user) = @_;
                    264:     return &getStandardW3CMacro($aclDB, $user);
                    265: }
                    266: 
                    267: sub standardDescToMacro { # static
                    268:     my ($self, $macroName) = @_;
                    269:     return &standardDescToW3CMacro($macroName);
                    270: }
                    271: 
                    272: sub standardMacroToDesc {
                    273:     my ($self, $macroId) = @_;
                    274:     return &standardW3CMacroToDesc($macroId);
                    275: }
                    276: 
                    277: sub standardMacroToIcon {
                    278:     my ($self, $macroId) = @_;
                    279:     return &standardW3CMacroToIcon($macroId);
                    280: }
                    281: 
                    282: __END__
                    283: 
                    284: =head1 NAME chacl
                    285: 
                    286: CGI::chacl - CGI interface for setting access to web resources
                    287: 
                    288: =head1 SYNOPSIS
                    289: 
                    290:   http://<server>/CGI/chacl
                    291: 
                    292: =head1 DESCRIPTION
                    293: 
                    294: The chacl script is called via the CGI interface from a webserver.
                    295: 
                    296: chacl enables the user to browse and set Access Control Lists (henceforth ACLs) via an HTTP CGI interface. With no parameters, chacl prompts the user for the resources for which to browse/change ACLs. With a set of resorces, chacl checks the list of ACL sources and displays the ACLs for those resources.
                    297: 
                    298: This module is used with the W3C::Rnodes CPAN module.
                    299: 
                    300: =head2 Authentication
                    301: 
                    302: Users actions are evaluated prior to execution and are only permitted if the requesting user has access to perform the requested function. For instance, before displaying ACLs for a resource, chacl makes sure that one of the following is true: everyone may see the ACL, the authenticated user may see the resource ACLs, or anyone connecting from the remote address may see the resource ACLs. Smilar check are performed when the user attempts to alter ACLs for a resource. The user may elect to change identity, even when it is not required for the desired action. The "Change Authentication" will cause chacl to require new authentication, which will cause the client to prompt the user for a new identity and password.
                    303: 
                    304: =head2 User Input
                    305: 
                    306: User input comes in four flavors: L<presentation|/"Presentation">, L<state selection|/"State selection">, L<state manipulation|/"State manipulation">, and L<commit|/"Commit">. state manipulation and commit require the user to select when modifying the ACLs for multiple resources at once. Javascript-enabled browsers will have extra buttons for manipulating the resourse selection.
                    307: 
                    308: =head2 User macros
                    309: 
                    310: The system is designed to allow the user to make streamlined ACL selections. These ACLs represent a common configuration that the user will use repleated. Asl the system administrator to create these macros.
                    311: 
                    312: =head2 RDF
                    313: 
                    314: The chacl system is based on RDF assertions of trust. Internal state is maintained by a block of RDF that is optionally hidden or editable depending on whether chacl is in "expert mode". This state is ephemoral and goes away unless the user commits the changes with the "Replace ACLs with RDF below" button.
                    315: 
                    316: =head2 Presentation
                    317: 
                    318: Several buttons control the chacl display. The options inlcude:
                    319: 
                    320:     help - display verbose help interspersed with the
                    321:            user prompts.
                    322:     list / diff - view ACLs as a comprehensive list or
                    323:                   as changes to the closest macro.
                    324:     tabular form - justify resources/ACLs by placing
                    325:                    output in a large table.
                    326:     expert mode - view the extended "expert" options.
                    327: 
                    328: =head2 State selection
                    329: 
                    330: In "expert" mode, the user may get lists of web ids for whom to add or remove ACLs.
                    331: 
                    332: =head2 State manipulation
                    333: 
                    334: Once the user has selected some web ids and ACLs in the "State selection" step, He/she must tell chacl to write these changes back to the RDF. This is done with the "Replace ACLs with RDF below" button.
                    335: 
                    336: =head2 Commit
                    337: 
                    338: Commit actions are ones that specifically write ACLs to the ACL repository. These include the User Macros as well as the Commit RDF Below button.
                    339: 
                    340: =head2 ACL Sources
                    341: 
                    342: chacl can get ACLs from a list of ACL agents, For instance, W3CAclAgent, UnixPermAgent, RdfAclAgent, and maybe, someday, the CVSAclAgent. These agents support the AclImportInterface, mainly, the getAclsFor method. One of these agents will also likely serve as the repository. The AclRepositoryInterface has methods to setAclsFor and deleteAclFor.
                    343: 
                    344: =head2 Architecture
                    345: 
                    346: 
                    347: 
                    348: =head1 AUTHOR
                    349: 
                    350: Eric Prud'hommeaux <eric@w3.org>
                    351: 
                    352: =head1 SEE ALSO
                    353: 
                    354: W3C::Rnodes::ACL(3) W3C::Rnodes::W3CAclAgent(3) W3C::Rnodes::UnixPermAgent(3) W3C::Rnodes::RdfAclAgent(3).
                    355: 
                    356: =cut
                    357: 

Webmaster