07b9885d6ec3a7b6dbdc22b02e5be13bf622de1c
[plewww.git] / planetlab / sites / join_request.php
1 <?php
2 // $Id$
3 //
4 // page for administration of pending site registration requests
5 //
6
7 // Require login
8 require_once 'plc_login.php';
9
10 // Get session and API handles
11 require_once 'plc_session.php';
12 global $plc, $api;
13
14 // Print header
15 require_once 'plc_drupal.php';
16 include 'plc_header.php';
17
18 // Common functions
19 require_once 'plc_functions.php';
20 require_once 'details.php';
21 require_once 'nifty.php';
22 require_once 'table.php';
23 require_once 'nifty.php';
24
25 include 'site_form.php';
26
27 ////////////////////////////////////////
28 function render_all_join_requests($api) {
29   global $PENDING_CONSORTIUM_ID;
30   $filter = array("peer_id" => NULL, "ext_consortium_id" => $PENDING_CONSORTIUM_ID);
31   $columns=array('site_id','name','enabled','date_created');
32   $sites = $api->GetSites( $filter, $columns);
33   if (empty($sites)) {
34     print("<p> No open join requests </p>");
35     return;
36   }
37   $headers = array();
38   $headers['id']='int';
39   $headers['Site Name']='string';
40   # trying the sortEnglishDateTime stuff - not too lucky so far
41   # http://www.frequency-decoder.com/demo/table-sort-revisited/custom-sort-functions/
42   $headers['submitted']='sortEnglishDateTime';
43   $headers['enabled']='string';
44   
45   $nifty=new PlekitNifty ('pending','sites-pending','medium');
46   $nifty->start();
47   $table=new PlekitTable ('pending',$headers,2,
48                           array('pagesize_area'=>FALSE,'pagesize'=>10000));
49   $table->start();
50   foreach($sites as $site) {
51     $site_id=$site['site_id'];
52     $link = $site['enabled'] ? l_site($site_id) : l_site_review_pending($site_id);
53     $table->row_start();
54     $table->cell(href($link,$site['site_id']));
55     $table->cell(href($link,$site['name']));
56     $table->cell(date("dS F Y",$site['date_created']) . " at " . date("G:i",$site['date_created']));
57     $table->cell( $site['enabled'] ? plc_warning_html('yes') : 'no');
58     $table->row_end();
59   }
60   $table->end();
61   $nifty->end();
62 }
63
64 function render_join_request_review($api, $site_id) {
65   $sites = $api->GetSites( array(intval($site_id)) );
66   if (empty($sites)) {
67       print("<p class='plc-warning'> Invalid request with site_id=$site_id</p> ");
68       return;
69   }
70   $site = $sites[0];
71   if ($site['enabled'] && $site['ext_consortium_id'] === $PENDING_CONSORTIUM_ID) {
72     print("<p class='plc-warning'> This site is already enabled </p>");
73     return;
74   }
75   $addresses = $api->GetAddresses ($site['address_ids']);
76   if (empty ($addresses)) {
77     drupal_set_message("Site $site_id has no address - never mind");
78     $address=array('line1'=>'');
79     $address_id=0;
80   } else {
81     $address = $addresses[0];
82     $address_id=$address['address_id'];
83   }
84 # just in case there is no person attached yet
85   if (empty ($site['person_ids'])) {
86     $persons=array();
87   } else {
88     $person_ids = $site['person_ids'];
89     $persons = $api->GetPersons( $person_ids, array( "person_id", "role_ids", "first_name", "last_name", "title", "email" , "phone") );
90   }
91   $tech = Null;
92   $pi = Null;
93   foreach($persons as $person) {
94     if ( in_array('20',  $person['role_ids']) ) {
95       $pi = $person;
96     }
97     if ( in_array('40',  $person['role_ids']) ) {
98       $tech = $person;
99     }
100   }
101   $pi_id = $pi['person_id'];
102   $tech_id = $tech['person_id'];
103
104   print <<< EOF
105 <p> Please review the join request below.</p>
106     <p> <b> Warning:</b> the PI email address that was provided in this form will <b> not be checked</b> automatically. We expect that as part of the handshake with the site, the support team has had an opportunity to use this address so it can be considered safe. Please check it manually if this is not the case.</p>
107 <form name="join_request" method="post" action="/db/sites/join_request.php">
108 <input type="hidden" name="pi_id" value="$pi_id">
109 <input type="hidden" name="address_id" value="$address_id">
110 <input type="hidden" name="tech_id" value="$tech_id">
111 <input type="hidden" name="site_id" value="$site_id">
112 EOF;
113
114   // don't render the tech part if that was the same as the pi
115   $site_form = build_site_form(FALSE);
116   $input = array ('site' => $site, 'address'=> $address, 'pi' => $pi, 'tech' => $tech);
117   
118   $nifty=new PlekitNifty ('pending','site-pending','medium');
119
120   $nifty->start();
121   $details = new PlekitDetails(TRUE);
122   $details->start();
123
124   // display the buttons 
125   $buttons_row =<<<EOF
126     <table width="100%" border=0 cellspacing="0" cellpadding="5"> <tr> 
127     <td align=center><input type="submit" name="submitted" value="Delete"></td>
128     <td align=center><input type="submit" name="submitted" value="Update"></td>
129     <td align=center><input type="submit" name="submitted" value="Approve"></td>
130     </tr> </table>
131 EOF;
132
133   $details->tr($buttons_row,'center');
134   // render the form - not supposed to be empty
135   form_render_details ($details,$site_form, $input, TRUE);
136
137   // display the buttons again
138   $details->tr($buttons_row,'center');
139
140   $details->end();
141   $nifty->end();
142
143 }
144
145 function notify_enabled_pi ($api, $pi_id, $pi, $site_id, $site) {
146   // notify the PI
147   $template= <<<EOF
148 You have filed a site registration with the %s platform.
149
150 This registration has been approved, and your account was enabled
151 You were granted a PI role, meaning that you will be responsible 
152 for managing personal accounts and slices for your site
153
154 You can now enter the system at
155 https://%s:%d/
156 with %s as a login, 
157 and the password that you provided at registration-time
158
159 You can directly access your site information at
160 https://%s:%d/db/sites/index.php?id=%d
161
162 Please start with adding nodes for this site with
163 https://%s:%d/db/nodes/node_add.php
164
165 Our support team will be glad to answer any question that you might have
166 They are reachable at mailto:%s
167 EOF;
168  
169  $body=sprintf($template,
170                PLC_NAME,
171                PLC_WWW_HOST,PLC_WWW_SSL_PORT,
172                $pi['email'],
173                PLC_WWW_HOST,PLC_WWW_SSL_PORT,$site_id,
174                PLC_WWW_HOST,PLC_WWW_SSL_PORT,
175                PLC_MAIL_SUPPORT_ADDRESS);
176    
177  $subject="Site registration for " . $site['name'] . " has been approved by " . PLC_NAME;
178  $api->NotifyPersons(array($pi_id),$subject,$body);
179 }
180
181
182 // find person roles
183 $_person= $plc->person;
184 $_roles= $_person['role_ids'];
185
186 // only admins are allowed to view this page
187 if( !in_array( '10', $_roles ) ) {
188
189     print("<p> not allowed to view this page </p>");
190 }
191 else if ($_GET['review'])
192 {
193
194     //print review page
195     drupal_set_title('Join Request - Review');
196     render_join_request_review($api, $_GET['site_id']);
197         
198 }
199 else if ($_POST['submitted'] )
200 {
201
202   // parse the form
203   $site_form = build_site_form(FALSE);
204   $input = parse_form ($site_form, $_REQUEST, $input);
205   // xxx should not happen ?
206   $empty_form = $input['is_empty'];
207   $error = "";
208   $messages= array();
209   if ( $empty_form ) {
210     $error .= '<div class-"plc-warning">Internal error - empty form !?!</div>';
211   }
212   if (empty ($error)) {
213     $site=$input['site'];
214     $address=$input['address'];
215     $pi=$input['pi'];
216     $tech=$input['tech'];
217
218     // Look for missing/blank entries
219     $error .= form_check_required ($site_form, $input);
220   }
221
222   if (empty($error)) {
223     // get objects id from the request
224     $site_id = intval(trim($_POST['site_id']));
225     $address_id = intval(trim($_POST['address_id']));
226     $pi_id = intval(trim($_POST['pi_id']));
227     $tech_id = intval(trim($_POST['tech_id']));
228
229     switch ($_POST['submitted']) {
230     case 'Delete': {
231       $api->DeleteSite ($site_id);
232       $api_error=$api->error();
233       if (!empty($api_error)) {
234         $error .= $api->error();
235       } else {
236         $messages [] = "Site " . $site['name'] . " deleted";
237       }
238       break;
239     }
240     case 'Update': {
241       $api->begin();
242       $api->UpdateSite($site_id,$site);
243       if ($address_id) $api->UpdateAddress($address_id,$address);
244       else if(!empty($address)) $api->AddSiteAddress($site_id,$address);
245       $api->UpdatePerson($pi_id,$pi);
246       if ($tech_id != $pi_id) $api->UpdatePerson($tech_id,$tech);
247       $api->commit();
248       $api_error=$api->error();
249       if (!empty($api_error)) {
250         $error .= $api->error();
251       } else {
252         $messages [] = "Join request updated for site " . $site['name'] ;
253       }
254       
255       break;
256     }
257     case 'Approve': {
258       // Thierry - august 22 2007
259       // keep it simple - the admin who approves is now supposed to check 
260       // the PI's email address, which makes the whole thing *a lot* simpler
261       // enable the site, enable the PI, and VerifyPerson the thec if different from the PI
262       $site['enabled'] = True;
263       global $APPROVED_CONSORTIUM_ID;
264       $site['ext_consortium_id'] = $APPROVED_CONSORTIUM_ID;
265       $api->UpdateSite ($site_id,$site);
266       $api_error=$api->error();
267       if (!empty($api_error)) {
268         $error .= $api->error();
269         $messages [] = "Could not enable site";
270       } else {
271         $messages[] = l_site_t ($site_id,"Site '" . $site['name'] . "' enabled");
272       }
273       
274       if (empty ($error) && $address_id) {
275         // Update Address
276         $api->UpdateAddress($address_id,$address);
277         $api_error=$api->error();
278         if ( ! empty($api_error)) {
279           $error .= $api->error();
280           $messages [] = "Could not update address";
281         }
282         
283         foreach ( array("Billing","Shipping") as $address_type) {
284           $api->AddAddressTypeToAddress($address_type,$address_id);
285           $api_error=$api->error();
286           if ( ! empty($api_error)) {
287             $error .= $api->error();
288             $messages [] = "Could not add address type " . $address_type;
289           }
290         }
291           
292         // Update pi, and enable him
293         $api->UpdatePerson ($pi_id,$pi);
294         if ( $pi ['enabled' ] ) {
295           $messages [] = "PI already enabled";
296         } else {
297           $api->UpdatePerson ($pi_id,array("enabled"=>True));
298           $api_error=$api->error();
299           if (empty($api_error)) {
300             $messages[] = "Enabled PI as " . $pi['email'] ;
301             notify_enabled_pi ($api, $pi_id,$pi,$site_id, $site);
302             $messages[] = "Notified PI by email";
303           } else {
304             $error .= $api->error();
305             $messages [] = "Could not update PI";
306           }
307         }
308
309         if ($pi_id != $tech_id) {
310           // Update tech, and VerifyPerson him if needed
311           $api->UpdatePerson ($tech_id,$tech);
312           if ( $tech [ 'enabled' ] ) {
313             $messages [] = "Tech already enabled";
314           } else {
315             $api->VerifyPerson($tech_id);
316             $api_error=$api->error();
317             if (empty($api_error)) {
318               $messages[] = "Created account registration for Tech as " . $tech['email'];
319             } else {
320               $error .= $api->error();
321               $messages [] = "Could not verify Tech";
322             }
323           }
324         }
325       }
326
327       break;
328     }
329     default: {
330       $error .= '<div class-"plc-warning">Internal error - unexpected request</div>';
331       break;
332     }
333
334     } // end switch
335   }
336
337   // Show messages
338   if (!empty($messages)) {
339     print '<div class="messages status"><ul>';
340     foreach ($messages as $line) {
341       print "<li> $line";
342     }
343     print "</ul></div>";
344   }
345         
346   // Show errors if any
347   if (!empty($error)) {
348     print '<div class="messages error">' . $error . '</div>';
349     drupal_set_title('Join Request - Review');
350     render_join_request_review($api, $_POST['site_id']);    
351   } else {
352     drupal_set_title('All currently pending join requests');
353     render_all_join_requests($api);
354   }
355
356  }
357  else // list all pending requests
358 {
359
360     drupal_set_title('All currently pending join requests');
361     render_all_join_requests($api);
362 }
363
364 // Print footer
365 include 'plc_footer.php';
366
367 ?>