--- /dev/null
+Moodle - FirstClass authentication module\r
+-----------------------------------------\r
+This module uses the FirstClass Flexible Provisining Protocol (FPP) to communicate between the FirstClass server\r
+and the Moodle host. \r
+\r
+Installation\r
+------------\r
+\r
+1. Enable FPP on the FirstClass server\r
+FPP is not doumented in the FirstClass documentation and is not enable by default.\r
+To enable the protocol you need to edit the file \FCPO\Server\Netinfo. Open the file and insert the\r
+following lines. \r
+\r
+// TCP port for Flexible Provisioning Protocol (FPP).\r
+TCPFPPPORT = 3333\r
+\r
+\r
+2. Create an account on the FirstClass server with privilege "Subadministrator".\r
+Using the FPP protocoll this module logs in to the FirstClass server and issuess batch admin commands.\r
+Batch admin command can only be issued in the context of a user with subadministrative privileges.\r
+\r
+Default account name is "fcMoodle".\r
+\r
+\r
+3. Check that the FPP protocoll is working by running a Telnet session. If everyting is working you\r
+should get a "+0" answer from the server. \r
+\r
+> telnet yourhost.domain.com 3333\r
++0\r
+\r
+Check that the "fcMoodle" is working by entering the following sequens of commands:\r
+\r
+> telnet yourhost.domain.com 3333\r
++0\r
+fcMoodle\r
++0\r
+\r
+the_password_you_gave_fcmoodle\r
++0\r
+\r
+Get user some_user_id 1201\r
+\r
+1201 0 some_user_id\r
++0\r
+\r
+\r
+\r
+4. On the Moodle host go to the directory where you have installed Moodle.\r
+Open the folder "auth", where all other authentication modules are installed,\r
+ and create a new directory with the name "fc". \r
+\r
+Copy the files "config.html", "fcFPP.php" and "lib.php" to the "auth" directory.\r
+\r
+Now you need to add som strings to the language file. This distribution contains\r
+string for the English (en) and Swedish (sv) translation.\r
+\r
+Open the file "auth.php" in the folder "lang/sv" and paste the text from the file\r
+"auth.php - sv.txt" at the end of the file above the line "?>"\r
+\r
+Open the file "auth.php" in the folder "lang/en" and paste the text from the file\r
+"auth.php - en.txt" at the end of the file above the line "?>"\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+<?PHP\r
+ if (!isset($config->auth_fchost)) {\r
+ $config->auth_fchost = "127.0.0.1";\r
+ }\r
+ if (!isset($config->auth_fcfppport)) {\r
+ $config->auth_fcfppport = "3333";\r
+ }\r
+ if (!isset($config->auth_fcuserid)) {\r
+ $config->auth_fcuserid = "fcMoodle";\r
+ }\r
+ if (!isset($config->auth_fcpasswd)) {\r
+ $config->auth_fcpasswd = "";\r
+ } \r
+ if (!isset($config->auth_fccreators)) {\r
+ $config->auth_fccreators = "";\r
+ } \r
+?>\r
+\r
+<TR valign="top" BGCOLOR="<?php echo $THEME->cellheading2 ?>">\r
+ <TD ALIGN=RIGHT><P>auth_fchost:</TD>\r
+ <TD>\r
+ <INPUT name=auth_fchost TYPE=text SIZE=30 VALUE="<?php echo $config->auth_fchost?>">\r
+ <?php if (isset($err["auth_fchost"])) formerr($err["auth_fchost"]); ?>\r
+ </TD>\r
+ <TD>\r
+ <?php print_string("auth_fchost","auth") ?>\r
+ </TD>\r
+</TR>\r
+\r
+<TR valign="top" BGCOLOR="<?php echo $THEME->cellheading2 ?>">\r
+ <TD ALIGN=RIGHT><P>auth_fcfppport:</TD>\r
+ <TD>\r
+ <INPUT name=auth_fcfppport TYPE=text SIZE=30 VALUE="<?php echo $config->auth_fcfppport?>">\r
+ <?php if (isset($err["auth_fcfppport"])) formerr($err["auth_fchost"]); ?>\r
+ </TD>\r
+ <TD>\r
+ <?php print_string("auth_fcfppport","auth") ?>\r
+ </TD>\r
+</TR>\r
+\r
+<TR valign="top" BGCOLOR="<?php echo $THEME->cellheading2 ?>">\r
+ <TD ALIGN=RIGHT><P>auth_fcuserid:</TD>\r
+ <TD>\r
+ <INPUT name=auth_fcuserid TYPE=text SIZE=30 MAXLENGTH=15 VALUE="<?php echo $config->auth_fcuserid?>">\r
+ <?php if (isset($err["auth_fcuserid"])) formerr($err["auth_fcuserid"]); ?>\r
+ </TD>\r
+ <TD>\r
+ <?php print_string("auth_fcuserid","auth") ?>\r
+ </TD>\r
+</TR>\r
+\r
+<TR valign="top" BGCOLOR="<?php echo $THEME->cellheading2 ?>">\r
+ <TD ALIGN=RIGHT><P>auth_fcpasswd:</TD>\r
+ <TD>\r
+ <INPUT name=auth_fcpasswd TYPE=password SIZE=30 MAXLENGTH=12 VALUE="<?php echo $config->auth_fcpasswd?>">\r
+ <?php if (isset($err["auth_fcpasswd"])) formerr($err["auth_fcpasswd"]); ?>\r
+ </TD>\r
+ <TD>\r
+ <?php print_string("auth_fcpasswd","auth") ?>\r
+ </TD>\r
+</TR>\r
+\r
+<TR valign="top" BGCOLOR="<?php echo $THEME->cellheading2 ?>">\r
+ <TD ALIGN=RIGHT><P>auth_fccreators:</TD>\r
+ <TD>\r
+ <INPUT name=auth_fccreators TYPE=text SIZE=30 VALUE="<?php echo $config->auth_fccreators?>">\r
+ <?php if (isset($err["auth_fccreators"])) formerr($err["auth_fccreators"]); ?>\r
+ </TD>\r
+ <TD>\r
+ <?php print_string("auth_fccreators","auth") ?>\r
+ </TD>\r
+</TR>\r
+\r
+\r
+<TR VALIGN=TOP>\r
+ <TD ALIGN=RIGHT><P><?php print_string("instructions", "auth") ?>:</TD>\r
+ <TD>\r
+ <TEXTAREA NAME=auth_instructions COLS=30 ROWS=10 WRAP=virtual><?php p($config->auth_instructions) ?></TEXTAREA> \r
+ </TD>\r
+ <TD>\r
+ <?php print_string("authinstructions","auth") ?>\r
+ <?php helpbutton("text", get_string("helptext")) ?>\r
+ </TD>\r
+</TR>\r
--- /dev/null
+<?php\r
+/************************************************************************/\r
+/* fcFPP: Php class for FirstClass Flexible Provisining Protocol */\r
+/* ============================================================= */\r
+/* */\r
+/* Copyright (c) 2004 SKERIA Utveckling, Teknous */\r
+/* http://skeria.skelleftea.se */\r
+/* */\r
+/* Flexible Provisioning Protocol is a real-time, IP based protocol */\r
+/* which provides direct access to the scriptable remote administration */\r
+/* subsystem of the core FirstClass Server. Using FPP, it is possible to*/\r
+/* implement automated provisioning and administration systems for */\r
+/* FirstClass, avoiding the need for a point and click GUI. FPP can also*/\r
+/* be used to integrate FirstClass components into a larger unified */\r
+/* system. */\r
+/* */\r
+/* This program is free software. You can redistribute it and/or modify */\r
+/* it under the terms of the GNU General Public License as published by */\r
+/* the Free Software Foundation; either version 2 of the License. */\r
+/************************************************************************/\r
+/* Author: Torsten Anderson, torsten.anderson@skeria.skelleftea.se\r
+ */\r
+\r
+class fcFPP\r
+{ \r
+ var $_hostname; // hostname of FirstClass server we are connection to\r
+ var $_port; // port on which fpp is running\r
+ var $_conn = 0; // socket we are connecting on\r
+ var $_debug = FALSE; // set to true to see some debug info\r
+ \r
+ // class constructor\r
+ function fcFPP($host="localhost", $port="3333")\r
+ {\r
+ $this->_hostname = $host;\r
+ $this->_port = $port;\r
+ $this->_user = "";\r
+ $this->_pwd = ""; \r
+ }\r
+ \r
+ // open a connection to the FirstClass server\r
+ function open()\r
+ {\r
+ if($this->_debug) echo "Connecting to host ";\r
+ $host = $this->_hostname;\r
+ $port = $this->_port;\r
+\r
+ if($this->_debug) echo "[$host:$port]..";\r
+\r
+ // open the connection to the FirstClass server\r
+ $conn = fsockopen($host, $port, $errno, $errstr, 5);\r
+ if(!$conn)\r
+ {\r
+ echo "connection failed!".$errno. $errstr;\r
+ return false;\r
+ }\r
+ \r
+ // We are connected\r
+ if($this->_debug) echo "connected!";\r
+ \r
+ // Read connection message.\r
+ $line = fgets ($conn); //+0\r
+ $line = fgets ($conn); //new line\r
+\r
+ // store the connection in this class, so we can use it later\r
+ $this->_conn = & $conn;\r
+\r
+ return true;\r
+ }\r
+\r
+ // close any open connections\r
+ function close()\r
+ { \r
+ // get the current connection\r
+ $conn = &$this->_conn;\r
+\r
+ // close it if it's open\r
+ if($conn)\r
+ {\r
+ fclose($conn);\r
+\r
+ // cleanup the variable\r
+ unset($this->_conn);\r
+ return true;\r
+ }\r
+ return;\r
+ }\r
+ \r
+ \r
+ // Authenticate to the FirstClass server\r
+ function login($userid, $passwd)\r
+ {\r
+ // we did have a connection right?!\r
+ if($this->_conn)\r
+ {\r
+ # Send username\r
+ fputs($this->_conn,"$userid\r\n");\r
+\r
+ $line = fgets ($this->_conn); //new line\r
+ $line = fgets ($this->_conn); //+0\r
+ $line = fgets ($this->_conn); //new line\r
+ \r
+ # Send password\r
+ fputs($this->_conn,"$passwd\r\n");\r
+ $line = fgets ($this->_conn); //new line\r
+ $line = fgets ($this->_conn); //+0\r
+ $line = fgets ($this->_conn); //+0 or message\r
+ \r
+ if($this->_debug) echo $line;\r
+ \r
+ if (preg_match ("/^\+0/", $line)) { //+0, user with subadmin privileges\r
+ $this->_user = $userid;\r
+ $this->_pwd = $passwd; \r
+ return TRUE; \r
+ } elseif (preg_match ("/^\Sorry/",$line)){ //Denied access but a valid user and password\r
+ return TRUE;\r
+ } else { //Invalid user or password\r
+ return FALSE;\r
+ }\r
+ \r
+\r
+ }\r
+ return FALSE;\r
+ }\r
+\r
+ // Get the list of groups the user is a member of \r
+ function getGroups($userid){\r
+ \r
+ $groups = array();\r
+ \r
+ // we must be logged in as a user with subadmin privileges \r
+ if($this->_conn AND $this->_user) {\r
+ # Send BA-command to get groups\r
+ fputs($this->_conn,"GET USER '" . $userid . "' 4 -1\r");\r
+ $line = "";\r
+ while (!$line) {\r
+ $line = trim(fgets ($this->_conn));\r
+ }\r
+ $n = 0;\r
+ while ($line AND !preg_match("/^\+0/", $line) AND $line != "-1003") {\r
+ list( , , $groups[$n++]) = explode(" ",$line,3);\r
+ $line = trim(fgets ($this->_conn));\r
+ }\r
+ if($this->_debug) echo "getGroups:" . implode(",",$groups);\r
+ }\r
+ \r
+ return $groups;\r
+ }\r
+\r
+ // Check if the user is member of any of the groups.\r
+ // Return the list of groups the user is member of.\r
+ function isMemberOf($userid, $groups){\r
+ \r
+ $usergroups = array_map("strtolower",$this->getGroups($userid));\r
+ $groups = array_map("strtolower",$groups);\r
+ \r
+ $result = array_intersect($groups,$usergroups);\r
+ \r
+ if($this->_debug) echo "isMemberOf:" . implode(",",$result);\r
+ \r
+ return $result;\r
+\r
+ }\r
+ \r
+ function getUserInfo($userid, $field){\r
+ \r
+ $userinfo = "";\r
+ \r
+ if($this->_conn AND $this->_user) {\r
+ # Send BA-command to get data\r
+ fputs($this->_conn,"GET USER '" . $userid . "' " . $field . "\r");\r
+ $line = "";\r
+ while (!$line) {\r
+ $line = trim(fgets ($this->_conn));\r
+ }\r
+ $n = 0;\r
+ while ($line AND !preg_match("/^\+0/", $line)) {\r
+ list( , , $userinfo) = explode(" ",$line,3);\r
+ $line = trim(fgets ($this->_conn));\r
+ }\r
+ if($this->_debug) echo "getUserInfo:" . $userinfo;\r
+ }\r
+ \r
+ return str_replace('\r',' ',trim($userinfo,'"'));\r
+\r
+ }\r
+\r
+ function getResume($userid){\r
+ \r
+ $resume = "";\r
+\r
+ $pattern = "/\[.+:.+\..+\]/"; // Remove references to pictures in resumes\r
+ \r
+ if($this->_conn AND $this->_user) {\r
+ # Send BA-command to get data\r
+ fputs($this->_conn,"GET RESUME '" . $userid . "' 6\r");\r
+ $line = "";\r
+ while (!$line) {\r
+ $line = trim(fgets ($this->_conn));\r
+ }\r
+ $n = 0;\r
+ while ($line AND !preg_match("/^\+0/", $line)) {\r
+ $resume .= preg_replace($pattern,"",str_replace('\r',"\n",trim($line,'6 ')));\r
+ $line = trim(fgets ($this->_conn));\r
+ //print $line;\r
+ \r
+ }\r
+ if($this->_debug) echo "getResume:" . $resume;\r
+ }\r
+ \r
+ return $resume;\r
+\r
+ }\r
+ \r
+ \r
+}\r
+ \r
+\r
+?>
\ No newline at end of file
--- /dev/null
+<?php // $Id$\r
+ \r
+// FirstClass authentication using FirstClass Flexible Provisining Protocol\r
+\r
+/* Author: Torsten Anderson, torsten.anderson@skeria.skelleftea.se\r
+\r
+CHANGELOG\r
+\r
+README\r
+ Module will authenticate user against FirstClass server and check if user belongs to any of\r
+ the defined creator groups.\r
+ User authenticates using their existing FirstClass username and password.\r
+ Where possible userdata is copied from the FirstClass directory to Moodle. You may\r
+ want to modify this.\r
+ Module requires the fcFPP class to do it's jobb.\r
+ */\r
+ \r
+\r
+require('fcFPP.php');\r
+ \r
+\r
+function auth_user_login ($username, $password) {\r
+/// Returns true if the username and password work\r
+/// and false if they don't\r
+\r
+ global $CFG;\r
+\r
+ $hostname = $CFG->auth_fchost;\r
+ $port = $CFG->auth_fcfppport;\r
+\r
+ $retval = FALSE;\r
+\r
+ if (!$username or !$password) { // Don't allow blank usernames or passwords\r
+ return $retval;\r
+ }\r
+\r
+\r
+ $fpp = new fcFPP($hostname,$port);\r
+ if ($fpp->open()) {\r
+ if ($fpp->login($username,$password)){\r
+ $retval = TRUE;\r
+ }\r
+ }\r
+ $fpp->close();\r
+\r
+ return $retval;\r
+ \r
+\r
+}\r
+\r
+function auth_get_userinfo($username){\r
+// Get user information from FirstCLass server and return it in an array.\r
+// Localize this routine to fit your needs. \r
+\r
+/*\r
+Moodle FirstCLass fieldID in UserInfo form\r
+------ -----------------------------------\r
+firstname 1202\r
+lastname 1204\r
+email 1252\r
+icq -\r
+phone1 1206\r
+phone2 1207 (Fax)\r
+institution - \r
+department - \r
+address 1205\r
+city - \r
+country -\r
+lang -\r
+timezone 8030 (Not used yet. Need to figure out how FC codes timezones)\r
+\r
+description Get data from users resume. Pictures will be removed.\r
+\r
+*/\r
+\r
+ global $CFG;\r
+ \r
+ $hostname = $CFG->auth_fchost;\r
+ $port = $CFG->auth_fcfppport;\r
+ $userid = $CFG->auth_fcuserid;\r
+ $passwd = $CFG->auth_fcpasswd; \r
+\r
+ $userinfo = array();\r
+\r
+ $fpp = new fcFPP($hostname,$port);\r
+ if ($fpp->open()) {\r
+ if ($fpp->login($userid,$passwd)){\r
+\r
+ $userinfo['firstname'] = $fpp->getUserInfo($username,"1202");\r
+ $userinfo['lastname'] = $fpp->getUserInfo($username,"1204");\r
+ $userinfo['email'] = strtok($fpp->getUserInfo($username,"1252"),',');\r
+ $userinfo['phone1'] = $fpp->getUserInfo($username,"1206");\r
+ $userinfo['phone2'] = $fpp->getUserInfo($username,"1207");\r
+ $userinfo['description'] = $fpp->getResume($username);\r
+\r
+ }\r
+ }\r
+\r
+ $fpp->close();\r
+\r
+ foreach($userinfo as $key => $value) {\r
+ if (!$value) {\r
+ unset($userinfo[$key]);\r
+ }\r
+ }\r
+ \r
+ return $userinfo;\r
+\r
+}\r
+\r
+\r
+function auth_iscreator($username=0) {\r
+//Get users group membership from the FirstClass server user and check if\r
+// user is member of one of the groups of creators.\r
+\r
+ global $CFG, $USER;\r
+\r
+ if (! $CFG->auth_fccreators) {\r
+ return false;\r
+ }\r
+\r
+ if (! $username) {\r
+ $username=$USER->username;\r
+ }\r
+\r
+ $fcgroups = array();\r
+\r
+ $hostname = $CFG->auth_fchost;\r
+ $port = $CFG->auth_fcfppport;\r
+ $userid = $CFG->auth_fcuserid;\r
+ $passwd = $CFG->auth_fcpasswd; \r
+\r
+ $fpp = new fcFPP($hostname,$port);\r
+ if ($fpp->open()) {\r
+ if ($fpp->login($userid,$passwd)){\r
+ $fcgroups = $fpp->getGroups($username);\r
+ }\r
+ }\r
+ $fpp->close();\r
+\r
+ \r
+ if ((! $fcgroups)) {\r
+ return false;\r
+ }\r
+\r
+ $creators = explode(";",$CFG->auth_fccreators);\r
+ \r
+ foreach($creators as $creator) {\r
+ If (in_array($creator, $fcgroups)) return true;\r
+ }\r
+ \r
+ return false;\r
+}\r
+
\ No newline at end of file