920576ec7000641e63db41e39891e824a9b0d2a5
[atutor.git] / mods / mahara / new_account_admin.php
1 <?php\r
2 \r
3 /*\r
4     This belongs to the ATutor+Mahara module. It is called from index_admin.php when\r
5     the admin user does not have a Mahara account associated with ATutor.  This script\r
6     automatically creates a new Mahara admin account for the user and saves the login\r
7     information with ATutor.  If the user already has an admin Mahara account, the script\r
8     simply adds the login information to ATutor and reassigns an automatically\r
9     generated password for Mahara.\r
10 \r
11     Most of the necessary code is copied and modified from init.php and\r
12     register.php of Mahara.\r
13 \r
14     This script very similar to new_account.php except it deals with admin only\r
15     (ie. authenticates session for admin, reads from 'admins' table, and sets\r
16          'admin' value to 1 in the 'usr' table of Mahara)\r
17 \r
18     by: Boon-Hau Teh\r
19 */\r
20 \r
21 $_user_location = 'public';\r
22 \r
23 if (!defined('new_admin_account')) { exit; }\r
24 if (!defined('AT_INCLUDE_PATH')) { exit; }\r
25 if (!function_exists('admin_authenticate')) { exit; }\r
26 \r
27 admin_authenticate(AT_ADMIN_PRIV_MAHARA);\r
28 \r
29 $sql = 'SELECT * FROM '.TABLE_PREFIX.'admins WHERE login="'.$_SESSION['login'].'"';\r
30 $result = mysql_query($sql, $db);\r
31 $row = mysql_fetch_assoc($result);\r
32 \r
33 $registration->username     = $row['login'];\r
34 if (isset($row['real_name']) && $row['real_name'] != '')\r
35     $registration->firstname    = $row['real_name'];\r
36 else\r
37     $registration->firstname    = $row['login'];\r
38 $registration->lastname     = ' ';           // mahara also requires lastname so enter a space char.\r
39 $registration->password     = $row['password'];\r
40 $registration->email        = $row['email'];\r
41 \r
42 define (MAHARA_PATH, $_config['mahara']);\r
43 \r
44 /******************from init.php*************************/\r
45 define('INTERNAL', 1);\r
46 define('PUBLIC', 1);\r
47 define('SECTION_PLUGINTYPE', 'core');\r
48 define('SECTION_PLUGINNAME', 'site');\r
49 define('SECTION_PAGE', 'register');\r
50 \r
51 $CFG = new StdClass;\r
52 $CFG->docroot = MAHARA_PATH;\r
53 \r
54 // Figure out our include path\r
55 if (!empty($_SERVER['MAHARA_LIBDIR'])) {\r
56     $CFG->libroot = $_SERVER['MAHARA_LIBDIR'];\r
57 } else {\r
58     $CFG->libroot = MAHARA_PATH. 'lib/';\r
59 }\r
60 set_include_path($CFG->libroot . PATH_SEPARATOR . $CFG->libroot . 'pear/' . PATH_SEPARATOR . get_include_path());\r
61 \r
62 // Set up error handling\r
63 require(MAHARA_PATH.'lib/errors.php');\r
64 \r
65 if (!is_readable($CFG->docroot . 'config.php')) {\r
66     // @todo Later, this will redirect to the installer script. For now, we\r
67     // just log and exit.\r
68     log_environ(_AT('MAHARA_ERROR_INSTALL'));\r
69     header('Location: '.AT_BASE_HREF);\r
70 }\r
71 \r
72 require(MAHARA_PATH.'config.php');\r
73 $CFG = (object)array_merge((array)$cfg, (array)$CFG);\r
74 \r
75 // Fix up paths in $CFG\r
76 foreach (array('docroot', 'dataroot') as $path) {\r
77     $CFG->{$path} = (substr($CFG->{$path}, -1) != DIRECTORY_SEPARATOR) ? $CFG->{$path} . DIRECTORY_SEPARATOR : $CFG->{$path};\r
78 }\r
79 \r
80 // xmldb stuff\r
81 $CFG->xmldbdisablenextprevchecking = true;\r
82 $CFG->xmldbdisablecommentchecking = true;\r
83 \r
84 // ensure directorypermissions is set\r
85 if (empty($CFG->directorypermissions)) {\r
86     $CFG->directorypermissions = 0700;\r
87 }\r
88 \r
89 // core libraries\r
90 require(MAHARA_PATH.'lib/mahara.php');\r
91 ensure_sanity();\r
92 require(MAHARA_PATH.'auth/internal/lib.php');\r
93 require(MAHARA_PATH.'lib/dml.php');\r
94 require(MAHARA_PATH.'lib/ddl.php');\r
95 require(MAHARA_PATH.'lib/activity.php');\r
96 require(MAHARA_PATH.'lib/user.php');\r
97 require(MAHARA_PATH.'lib/web.php');\r
98 \r
99 // Database access functions\r
100 require(MAHARA_PATH.'lib/adodb/adodb-exceptions.inc.php');\r
101 require(MAHARA_PATH.'lib/adodb/adodb.inc.php');\r
102 \r
103 try {\r
104     // ADODB does not provide the raw driver error message if the connection\r
105     // fails for some reason, so we use output buffering to catch whatever\r
106     // the error is instead.\r
107     ob_start();\r
108     \r
109     $db = &ADONewConnection($CFG->dbtype);\r
110     $dbgenerator = null;\r
111     if (empty($CFG->dbhost)) {\r
112         $CFG->dbhost = '';\r
113     }\r
114     else if (!empty($CFG->dbport)) {\r
115         $CFG->dbhost .= ':'.$CFG->dbport;\r
116     }\r
117     if (!empty($CFG->dbpersist)) {    // Use persistent connection (default)\r
118         $dbconnected = $db->PConnect($CFG->dbhost,$CFG->dbuser,$CFG->dbpass,$CFG->dbname);\r
119     } \r
120     else {                                                     // Use single connection\r
121         $dbconnected = $db->Connect($CFG->dbhost,$CFG->dbuser,$CFG->dbpass,$CFG->dbname);\r
122     }\r
123 \r
124     $db->SetFetchMode(ADODB_FETCH_ASSOC);\r
125     configure_dbconnection();\r
126     ensure_internal_plugins_exist();\r
127 \r
128     ob_end_clean();\r
129 }\r
130 catch (Exception $e) {\r
131     $errormessage = ob_get_contents();\r
132     if (!$errormessage) {\r
133         $errormessage = $e->getMessage();\r
134     }\r
135     ob_end_clean();\r
136     $errormessage = get_string('dbconnfailed', 'error') . $errormessage;\r
137     throw new ConfigSanityException($errormessage);\r
138 }\r
139 try {\r
140     db_ignore_sql_exceptions(true);\r
141     load_config();\r
142     db_ignore_sql_exceptions(false);\r
143\r
144 catch (SQLException $e) {\r
145     db_ignore_sql_exceptions(false);\r
146 }\r
147 \r
148 \r
149 // Only do authentication once we know the page theme, so that the login form\r
150 // can have the correct theming.\r
151 require_once(MAHARA_PATH.'auth/lib.php');\r
152 $USER    = new LiveUser();\r
153 /***************end from init.php*************************/\r
154 \r
155 \r
156 /*~~~~~~~~~modified from register.php~~~~~~~~~~*/\r
157 $random_password = substr(md5($registration->password.rand(100000, 999999)), 2, 8);\r
158 \r
159 /*-- from register_submit function --*/\r
160 $registration->salt         = substr(md5(rand(1000000, 9999999)), 2, 8);\r
161 $registration->password     = AuthInternal::encrypt_password($random_password, $registration->salt);\r
162 $registration->expiry       = NULL;\r
163 /*-----------------------------------*/\r
164 \r
165 \r
166 check_create_admin();\r
167 \r
168 \r
169  /**\r
170  * Uses global variable $registration and checks if the user\r
171  * is registered in Mahara as an admin.  If so, the record is\r
172  * updated.  If not, a new Mahara is created using the login name\r
173  * or the login name appended by random characters (if the username\r
174  * exists in Mahara but not as an admin).  This function recursively\r
175  * calls itself until a Mahara account is created/updated.\r
176  * @param   void\r
177  * @access  private\r
178  * @return  void\r
179  * @author  Boon-Hau Teh\r
180  */\r
181 function check_create_admin() {\r
182     global $registration;\r
183 \r
184     // Check if user already exists in Mahara\r
185     if ($data_record = get_record('usr', 'username', $registration->username)) {\r
186         // Check if user is an admin on Mahara as well\r
187         if ($data_record -> admin == 1) {\r
188             $registration -> id = $data_record -> id;\r
189             update_record('usr', $registration, 'username');\r
190         } else {\r
191             // create a new admin account with a different name\r
192             $registration->username = $_SESSION['login'].substr(md5(rand(100, 999)), 2, 5);\r
193             check_create_admin();   // Send register info to create a new account\r
194         }\r
195     } else {\r
196         create_admin_user();   // Send register info to create a new account\r
197     }\r
198 }\r
199 \r
200 // Reconnect to ATutor Database\r
201 $db_atutor = @mysql_connect(DB_HOST . ':' . DB_PORT, DB_USER, DB_PASSWORD);\r
202 if (!$db_atutor) {\r
203     /* AT_ERROR_NO_DB_CONNECT */\r
204     require_once(AT_INCLUDE_PATH . 'classes/ErrorHandler/ErrorHandler.class.php');\r
205     $err =& new ErrorHandler();\r
206     trigger_error('VITAL#Unable to connect to db.', E_USER_ERROR);\r
207     exit;\r
208 }\r
209 if (!@mysql_select_db(DB_NAME, $db_atutor)) {\r
210     require_once(AT_INCLUDE_PATH . 'classes/ErrorHandler/ErrorHandler.class.php');\r
211     $err =& new ErrorHandler();\r
212     trigger_error('VITAL#DB connection established, but database "'.DB_NAME.'" cannot be selected.',\r
213                     E_USER_ERROR);\r
214     exit;\r
215 }\r
216 \r
217 // Store data into ATutor Databse\r
218 $sql = "INSERT INTO ".TABLE_PREFIX."mahara SET at_login='".$_SESSION['login']."', username='".$registration->username."', password='".$random_password."'";\r
219 if (!mysql_query($sql, $db_atutor))\r
220     exit;                    // in case there's some external error; prevent being caught in an infinite loop\r
221 \r
222 \r
223 /**\r
224  * This function is copied and modified from register.php of Mahara to create an admin account\r
225  *\r
226  * @param array profilefields    Array of values from registration form. In this module, we're not using a form so we don't pass anything\r
227  * @return boolean               Returns true if function exits without any problems\r
228  */\r
229 function create_admin_user($profilefields=array()) {\r
230     global $registration, $USER;\r
231 \r
232     db_begin();\r
233 \r
234     // Move the user record to the usr table from the registration table\r
235     $registrationid = $registration->id;\r
236     unset($registration->id);\r
237     unset($registration->expiry);\r
238     if ($expirytime = get_config('defaultaccountlifetime')) {\r
239         $registration->expiry = db_format_timestamp(time() + $expirytime);\r
240     }\r
241     $registration->lastlogin = db_format_timestamp(time());\r
242 \r
243     $user = new User();\r
244     $user->username         = $registration->username;\r
245     $user->password         = $registration->password;\r
246     $user->salt             = $registration->salt;\r
247     $user->passwordchange   = 0;\r
248     $user->active           = 1;\r
249     $user->authinstance     = $authinstance->id;\r
250     $user->firstname        = $registration->firstname;\r
251     $user->lastname         = $registration->lastname;\r
252     $user->email            = $registration->email;\r
253     $user->admin            = 1;\r
254     $user->commit();\r
255 \r
256     $registration->id = $user->id;\r
257 \r
258     // Insert standard stuff as artefacts\r
259     set_profile_field($user->id, 'email', $registration->email);\r
260     set_profile_field($user->id, 'firstname', $registration->firstname);\r
261     set_profile_field($user->id, 'lastname', $registration->lastname);\r
262     if (!empty($registration->lang) && $registration->lang != 'default') {\r
263         set_account_preference($user->id, 'lang', $registration->lang);\r
264     }\r
265 \r
266     // Set mandatory profile fields \r
267     foreach(ArtefactTypeProfile::get_mandatory_fields() as $field => $type) {\r
268         // @todo here and above, use the method for getting "always mandatory" fields\r
269         if (in_array($field, array('firstname', 'lastname', 'email'))) {\r
270             continue;\r
271         }\r
272         set_profile_field($user->id, $field, $profilefields[$field]);\r
273     }\r
274 \r
275     db_commit();\r
276     handle_event('createuser', $registration);\r
277 \r
278     return true;\r
279 }\r
280 \r
281 ?>