'students and staff responsible for web administration', 'faculty' => 'faculty members', 'staff' => 'staff members including faculty', 'adjunct' => 'adjunct professors', 'employee' => 'student employees', 'student' => 'current engineering students', 'alumni' => 'graduates of the engineering program', 'user' => 'users who do not fit into any other category', )); // Clear the PageAttributes so that the only page by page attributes are // the externauth ones. This isn't essential, I just don't use the other // ones and they would confuse my users. Yes, my users are pathetic. unset($PageAttributes); // Add some attributes to the page ... // Two attributes for each level, // one for the allowed groups // one for the allowed users foreach(array_keys($ExternAuthAttributes) as $level) { $allowvar = 'externauth_' . $level . '_allow'; $PageAttributes[$allowvar] = '$[' . $level . ' allow:]'; $uservar = 'externauth_' . $level . '_user'; $PageAttributes[$uservar] = '$[' . $level . ' users:]'; $groupvar = 'externauth_' . $level . '_group'; $PageAttributes[$groupvar] = '$[' . $level . ' groups:]'; } // I am adding in a condition to make conditional inclusion easier // Now I can simply say (:if authenticated :) stuff ... (:ifend:) // or (:if authenticated level:) stuff ... (:ifend:) // (where level is one of the ExternAuthAttributes $Conditions['authenticated'] = 'conditional_authenticate(trim($condparm))'; // The conditional_authenticate is used by the Site.PageActions which set's the // tabs that are viewable. This is a bit of a problem. hmmmm. // What I want to know, is not whether or not the Site.PageActions // attributes are // set, but whether or not the attributes are set on the page that is // being displayed. So, I save the referring page being viewed in the // ExternAuthReferrerPage global and used this // for the conditional_authenticate. // This way, whatever conditionals are used on a page // or subsequent included pages, get the value of the referrer page. // To use the referrer page attributes (like the Site.PageActions), // (:if authenticated read referrer:) // (:if authenticated any referrer:) // To do a conditional inclusion based on the attibutes of the present page // (for instance, you want to put some secret stuff in a particular page) // (:if authenticated read:) // (:if authenticated:) - which is the same as (:if authenticated any:) function conditional_authenticate($condparam) { global $ExternAuthReferrerPage; global $ExternAuthCurrentPage; // echo "condparam=$condparam
"; $args = ParseArgs($condparam); $level = $args[''][0]; $type = $args[''][1]; // Give the user a way to do an authenticated on any auth with an referrer // Problem being that (:if authenticated referrer :) will use referrer as the // level and not the type. if ($level == 'any') $level = ''; //echo "level=$level, type = $type
"; // The ExternAuthReferrerPage is set as a global - // when the page is read the first time in, // it is saved so that subsequent calls for authentication can use it. // This is necessary for the Site.PageActions template. // The ExternAuthCurrentPage is the last page that was read in // i.e. the one that spawned this conditional // if ($type == 'referrer') { //echo "Returning the ReferrerPage
"; return extern_authenticate($level, &$ExternAuthReferrerPage); } return extern_authenticate($level, &$ExternAuthCurrentPage); } ///////////////////////////////////////////////////////////////// // The extern_authenticate function assumes that there has // been prior authentication done by some external element. // The results of the authentication are stored in $_SESSION. // // Of interest are the following variables: // $_SESSION['authenticated'] - 1 if the user has authenticated, 0 otherwise // $_SESSION['username'] - The users username - a scalar // $_SESSION['groups'] - an array of the users groups // // The authenticate functions performs the following algorithm: // If there is no level to authenticate, simply return the // users authentication status. // If the level is one of the attributes that we check // and there are no attribute entries, consider the match successful. // Compare the user groups to the authorized group array // Return TRUE if there is a match. // Compare the username to the authorized username array // Return TRUE if there is a match. // If this fails, then return FALSE // // OK - one more problem. Of all of the actions, read doesn't have a default // password. What happens if the page has a read value and we // don't authenticate? // We fail, and it goes back to the general authentication system. // This means that a read failure defaults to the global system read status. // This is generally open. So, what we need to do is go see if there // is a specification on one of the levels that we are checking, and if so, // we need to ensure that the page password is set to something - // if it isn't set, we need to set it to the admin password. function extern_authenticate($level, &$page) { global $ExternAuthAttributes,$DefaultPasswords; global $ExternAuthGroupAttributes; //echo "page (keys)= "; print_r(array_keys($page)); //echo "page (vals)= "; print_r(array_values($page)); //echo "authlevel = $level
"; $pagename = $page['name']; $pagegroup = FmtPageName('$Group',$pagename); //echo "pagegroup = $pagegroup
"; // This variable counts the number of specified elements in // each group If it is nonzero, there is a restriction $allowvar = 'externauth_' . $level . '_allow'; $uservar = 'externauth_' . $level . '_user'; $groupvar = 'externauth_' . $level . '_group'; // Here we are setting the Users and Groups variables from the page // If the page wants to allow the level, allow it. if ($page[$allowvar]) return true; //echo "Checking $uservar which is " . $page[$uservar] . "
"; if ($page[$uservar]) //echo "Found $uservar
"; $usercount = count($Users = explode(',',$page[$uservar])); if ($page[$groupvar]) $groupcount = count($Groups = explode(',',$page[$groupvar])); //echo "Users = " . print_r(array_values($Users)) . "
"; // Now we need to check for any PmWikiGroup variables // This allows the user to set default attribute permissions for an // entire group // Group Variables are NOT checked if the level has page variables // If there are no corresponding page variables, we set the Groups // and Users variables from the Group defaults. $uservar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_user'}; $groupvar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_group'}; $allowvar = $ExternAuthGroupAttributes{$pagegroup}{$level . '_allow'}; // This variable says that there is a restriction // Somewhere in the page settings $SettingsSet = $usercount + $groupcount; // If the page hasn't set anything on this, and the group allowvar is set, // allow it. if ($allowvar && ! $SettingsSet) { return true; } if (! $usercount) { //echo "Page $pagename, Level $level, Checking uservar = $uservar
"; if ($uservar) { $usercount = count($Users = explode(',',$uservar)); //echo "Setting usercount to $usercount
"; } } if (! $groupcount) { //echo "Page $pagename, Level $level, Checking groupvar = $groupvar
"; if ($groupvar) { $groupcount = count($Groups = explode(',',$groupvar)); //echo "Setting groupcount to $groupcount
"; } } // Update the SettingsSet with the Group variable count $SettingsSet = $usercount + $groupcount; //echo "Checking $level
"; //echo "SettingsSet = " . $SettingsSet . "
"; //echo "Groups = "; print_r(array_values($Groups)); echo "
"; //echo "Users = "; print_r(array_values($Users)); echo "
"; if ($_SESSION['authenticated']) { // only return a true if we are authenticated // If we are authenticated and there is no level, call it good if (! $level) { //echo "$level is authenticated (0)
"; return true; } // If there is a * in the user field, return true if the user is authenticated if (strstr(implode(',',$Users),'*')) { //echo "Got the big pig for $level
"; return true; } // If there are no specifications, consider it a match if it is one of // the variables for which we have attributes. if (! $SettingsSet) { if (isset($ExternAuthAttributes[$level])) { //echo "Getting ready to call " . $ExternAuthAttributes[$level] . "
"; return($ExternAuthAttributes[$level]()); } } // If we have specifications, see if they match if ((array_intersect($_SESSION['groups'],$Groups)) || (in_array($_SESSION['username'],$Users))) { //echo "$level is authenticated(2)
"; return true; } } // Before returning the failure, ensure that the appropriate password is set. // If the settings haven't been set, then we just go through and let the // system do its defaults. // However, if we have set something, and we have failed, then we need // to ensure that the system defaults is going to be a deny. We do this // by setting the page password to be the admin password for the wiki. // this means that the wiki admin can get everywhere from the web // without using our authentications. if ($SettingsSet) { if (! $DefaultPasswords[$level]) { //$DefaultPasswords[$level] = $DefaultPasswords['admin']; //echo "DefaultPasswords[$level] = $DefaultPasswords[$level]
"; $page["passwd$level"] = $DefaultPasswords['admin']; //echo "page[passwd$level] = " . $page["passwd$level"] . "
"; //echo "pagename = " . $page[name] . "; "; //echo "page[passwd$level] = " . $page["passwd$level"] . "
"; } } //echo "$level is NOT authenticated
"; return false; } ///////////////////////////////////////////////////////////////// // The ExternAuth function is a copy of PmWikiAuth with a simple // modifications to check for external authorizations. // The only addition are the lines ... /* SDV($ExternAuthReferrerPage,$page); $ExternAuthCurrentPage = $page; if (extern_authenticate($level,&$page)) { return $page; } */ // Which call the extern_authenticate function before passing control to // the standard function. The assumption is that all functions are // nailed down with passwords so that anything beyond what is // allowed by the authenticate function requires a password. // function ExternAuth($pagename, $level, $authprompt=true, $since=0) { //echo "Calling ExternAuth on $pagename, level = $level, authprompt=$authprompt, since = $since
"; global $DefaultPasswords, $AllowPassword, $GroupAttributesFmt, $ExternAuthReferrerPage,$ExternAuthCurrentPage, $AuthCascade, $FmtV, $AuthPromptFmt, $PageStartFmt, $PageEndFmt, $AuthId; static $grouppasswd, $authpw; SDV($GroupAttributesFmt,'$Group/GroupAttributes'); SDV($AllowPassword,'nopass'); $page = ReadPage($pagename, $since); if (!$page) { return false; } ////////////////////////////////////////////////// // I need to save the page when it is found so that the attributes for this // page are available to subsequent authorization checks. // For example, which tabs I put on top (edit, attr) are dependent not on // the attributes of the template page, but on the attributes of this page // The ExternAuthReferrerPage saves the referrer page that started everything // ExternAuthCurrentPage saves the current page (from which this auth call came // These are both used for conditional inclusion SDV($ExternAuthReferrerPage,$page); $ExternAuthCurrentPage = $page; ////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // So, here I authenticate. // If the user is authenticated, return the page //echo "Checking page " . $page[name] . " at level $level"; if (extern_authenticate($level,&$page)) { //echo "- it is AUTHENTICATED
"; return $page; } //echo "- it is NOT AUTHENTICATED "; // But if they aren't, what do we do? // We assume that the site is configured with default passwords on everything // except read - so just pass it on ... /////////////////////////////////////////////////////////////////// $groupattr = FmtPageName($GroupAttributesFmt, $pagename); if (!isset($grouppasswd[$groupattr])) { $grouppasswd[$groupattr] = array(); $gp = ReadPage($groupattr, READPAGE_CURRENT); foreach($DefaultPasswords as $k=>$v) if (isset($gp["passwd$k"])) $grouppasswd[$groupattr][$k] = explode(' ', $gp["passwd$k"]); } foreach ($DefaultPasswords as $k=>$v) { if (isset($page["passwd$k"])) { $passwd[$k] = explode(' ', $page["passwd$k"]); $page['=pwsource'][$k] = 'page'; } else if (isset($grouppasswd[$groupattr][$k])) { $passwd[$k] = $grouppasswd[$groupattr][$k]; $page['=pwsource'][$k] = 'group'; } else { $passwd[$k] = $v; if ($v) $page['=pwsource'][$k] = 'site'; } } $page['=passwd'] = $passwd; foreach($AuthCascade as $k => $t) { if (!$passwd[$k] && $passwd[$t]) { $passwd[$k] = $passwd[$t]; $page['=pwsource'][$k] = "cascade:$t"; } } if (!isset($authpw)) { $sid = session_id(); @session_start(); if (@$_POST['authpw']) @$_SESSION['authpw'][$_POST['authpw']]++; $authpw = array_keys((array)@$_SESSION['authpw']); if (!isset($AuthId)) $AuthId = @$_SESSION['authid']; if (!$sid) session_write_close(); } foreach($passwd as $lv => $a) { if (!$a) { $page['=auth'][$lv]++; continue; } foreach((array)$a as $pwchal) { if ($AuthId && strncmp($pwchal, 'id:', 3) == 0) { $idlist = explode(',', substr($pwchal, 3)); foreach($idlist as $id) { if ($id == $AuthId || $id == '*') { $page['=auth'][$lv]++; continue 3; } if ($id == "-$AuthId") { continue 3; } } } if ($pwchal == '' || crypt($AllowPassword, $pwchal) == $pwchal) { $page['=auth'][$lv]++; continue 2; } foreach ($authpw as $pwresp) if (crypt($pwresp, $pwchal) == $pwchal) { $page['=auth'][$lv]++; continue 3; } } } if ($page['=auth']['admin']) foreach($passwd as $lv=>$a) $page['=auth'][$lv]++; if ($page['=auth'][$level]) { //echo "The page is being allowed
"; return $page; } //echo "The page is NOT being allowed
"; if (!$authprompt) return false; PCache($pagename, $page); $postvars = ''; foreach($_POST as $k=>$v) { if ($k == 'authpw') continue; $v = str_replace('$', '$', htmlspecialchars(stripmagic($v), ENT_COMPAT)); $postvars .= "\n"; } $FmtV['$PostVars'] = $postvars; SDV($AuthPromptFmt,array(&$PageStartFmt, "

Please authenticate to view this page

Use the login box on the left


If you are the Wiki administrator, you may the Wiki password here

Password: \$PostVars
", &$PageEndFmt)); PrintFmt($pagename,$AuthPromptFmt); exit; } ///////////////////////////////////////////////////////////////////// // // The following are copies of pmwiki functions with simple changes // ///////////////////////////////////////////////////////////////////// // This is the HandlAuth array from pmwiki.php // I want to change this so that the source action // has the permissions of edit and not read. // There isn't any reason to be looking at the source // if you can't change it. And there may be things // that I want to hide in the source. $HandleAuth = array( 'browse' => 'read', 'source' => 'edit', 'diff' => 'edit','rename' => 'rename', 'edit' => 'edit', 'attr' => 'attr', 'postattr' => 'attr', 'comment' => 'edit', 'logout' => 'read', 'login' => 'login'); // This is the HandlActions array from pmwiki.php // I want to change this so that the it used my ExternAuthHandleAttr function // where I changed the message /* $HandleActions = array( 'browse' => 'HandleBrowse', 'edit' => 'HandleEdit', 'source' => 'HandleSource', 'attr' => 'ExternAuthHandleAttr', 'postattr' => 'ExternAuthHandlePostAttr', 'logout' => 'HandleLogoutA', 'login' => 'HandleLoginA'); */ $HandleActions['attr'] = 'ExternAuthHandleAttr'; $HandleActions['postattr'] = 'ExternAuthHandlePostAttr'; // This is a copy of the function in pmwiki.php. I just wanted to change the message. // function ExternAuthHandleAttr($pagename, $auth = 'attr') { global $PageAttrFmt,$PageStartFmt,$PageEndFmt; $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page) { Abort("?unable to read $pagename"); } PCache($pagename,$page); XLSDV('en', array('EnterAttributes' => "

From the attributes pages you can set who has access to various actions that operate on this page. The actions that you can control include who can read the page, who can edit the page, who can rename the page, who can set these attributes, and who can upload files to a WikiGroup from this page. There are Group Defaults for an entire WikiGroup. These are set by the Wiki administrator. Each page can also have its own unique Page Settings. If any value is set in these Page Settings, the Group Defaults for that attribute will be ignored and the Page Settings values will be used instead.


For each of the actions, you can enable specific users or groups of users. To enable a specific user, enter the username in the appropriate text field. If you want to enable multiple users, enter a comma-separated list of usernames (e.g. gehrig,ruth,mantle). To allow any authenticated user, place an asterisk (*) in the field.


Access can also be restricted to groups. Check the appopriate boxes to enable individual groups. The action will be allowed if the authenticated username is explicitly set in the appropriate action OR if the user is in a group that is enabled for the action.


Finally, if you want to simply ensure that ANYONE can perform the action, check the anyone box in the action allow checkbox.



")); SDV($PageAttrFmt,"

$[{\$FullName} Attributes]

$[EnterAttributes]

"); SDV($HandleAttrFmt,array(&$PageStartFmt,&$PageAttrFmt, 'function:EAPrintAttrForm',&$PageEndFmt)); PrintFmt($pagename,$HandleAttrFmt); } function EAPrintAttrForm($pagename) { global $PageAttributes, $PCache, $FmtV, $ExternAuthGroups, $ExternAuthGroupAttributes; $allow_color = '#ffcccc'; $group_color = '#ccccff'; echo ("

Group Defaults


"); echo "In the abscence of group defaults or page specific settings, the read action will be allowed for any visitor to the website. The edit and action is restricted to authenticated users, and the upload, rename and attribute actions are restricted to members of the faculty, staff, and webadmin groups."; echo (""); $page = $PCache[$pagename]; $groupname = FmtPageName('$Group',$pagename); $group_columns = 8; // Let's print out the group defaults foreach($ExternAuthGroupAttributes[$groupname] as $attr=>$p) { $setting = $p; $value = $p; $prompt = ereg_replace('_',' ',$attr) . 's:'; $colcount = 0; if (strstr($attr, 'group')) { echo ""; foreach($ExternAuthGroups as $group=>$descr) { //echo "group=$group, descr=$descr
"; $cbox_value=''; //echo "Looking for $group in $setting
"; if (strstr($setting,$group)) { $cbox_value='checked'; } $name = $attr . '_' . $group . 'jojo'; //echo "Setting the name to $name with cbox_value $cbox_value
"; if ($colcount >= $group_columns) { $colcount = 0; echo ""; } echo ""; $colcount = $colcount + 1; } echo ""; } else { $spansize = count($ExternAuthGroups); echo ""; } } echo FmtPageName("
$prompt
$group
$prompt $setting


", $pagename); echo ("

Page Settings


"); echo FmtPageName("
",$pagename); $page = $PCache[$pagename]; /* This goes through the PageAttributes vars to build up stuff */ $colcount=0; foreach($PageAttributes as $attr=>$p) { if (!$p) continue; $setting = @$page[$attr]; $value = @$page[$attr]; $prompt = FmtPageName($p,$pagename); $colcount = 0; if (strstr($attr, 'group')) { echo ""; foreach($ExternAuthGroups as $group=>$descr) { //echo "group=$group, descr=$descr
"; $cbox_value=''; //echo "Looking for $group in $setting
"; if (strstr($setting,$group)) { $cbox_value='checked'; } $name = $attr . '_' . $group; //echo "Setting the name to $name with cbox_value $cbox_value
"; if ($colcount >= $group_columns) { $colcount = 0; echo ""; } echo ""; $colcount = $colcount + 1; } echo ""; } elseif (strstr($attr, 'allow')) { $prompt = ereg_replace('_',' ',$attr) ; $prompt = ereg_replace('externauth ','',$prompt) ; echo ""; $setting = @$page[$attr]; $cbox_value=''; if ($setting) { $cbox_value='checked'; } $name = $attr; //echo "Setting the name to $name with cbox_value $cbox_value
"; echo ""; echo ""; } else { $spansize = count($ExternAuthGroups); echo ""; } } echo FmtPageName("
$prompt
$group
$promptanyone
$prompt $setting

", $pagename); echo "
"; } function ExternAuthHandlePostAttr($pagename, $auth = 'attr') { global $PageAttributes, $EnablePostAttrClearSession, $ExternAuthGroups; Lock(2); $page = RetrieveAuthPage($pagename, $auth, true); if (!$page) { Abort("?unable to read $pagename"); } // We are going to have to do more than get the page attributes here, // we need to also get the tacked on group attributes. // maybe we should do that first, turn it into a page attribute, // and then go from there ... // For each of the page attributes foreach($PageAttributes as $attr=>$p) { //echo "Looking for group in $attr
"; if (strstr($attr,'group')) { // Clear the group array $group_array = array(); // For each of the groups foreach($ExternAuthGroups as $group=>$desc) { //Form the groupvar $groupvar = $attr . '_' . $group; //See if the groupvar is set if ($_POST[$groupvar] != '') { //if so, push it onto an array array_push($group_array,$group); } } // Set the POST attribute as though I had done it via a string $_POST[$attr] = implode(',',$group_array); } } foreach($PageAttributes as $attr=>$p) { //echo "Looking at $attr = $p
"; // Clear any of the group Page Attributes as we will set them from the post //if (strstr($attr,'group')) { unset($page[$attr]); //} $v = stripmagic(@$_POST[$attr]); //echo "V = $v
"; if ($v == '') continue; //if ($v=='clear') unset($page[$attr]); else if (strncmp($attr, 'passwd', 6) != 0) $page[$attr] = $v; else { $a = array(); preg_match_all('/"[^"]*"|\'[^\']*\'|\\S+/', $v, $match); foreach($match[0] as $pw) $a[] = preg_match('/^(@|\\w+:)/', $pw) ? $pw : crypt(preg_replace('/^([\'"])(.*)\\1$/', '$2', $pw)); if ($a) $page[$attr] = implode(' ',$a); } } WritePage($pagename,$page); Lock(0); if (IsEnabled($EnablePostAttrClearSession, 1)) { @session_start(); unset($_SESSION['authid']); unset($_SESSION['authlist']); $_SESSION['authpw'] = array(); } Redirect($pagename); exit; } ?>