integration of simple OpenID logging in facility almost ready
[living-lab-site.git] / application / controllers / user.php
1 <?php
2
3 /**
4  * Class User controls video hierarchy and searching
5  *
6  * @category    Controller
7  * @author              Călin-Andrei Burloiu
8  */
9 class User extends CI_Controller {
10
11         private $import = FALSE;
12         private $activated_account = TRUE;
13         private $user_id = NULL;
14
15         public function __construct()
16         {
17                 parent::__construct();
18
19                 $this->lang->load('user');
20                 $this->load->model('users_model');
21         }
22
23         public function index()
24         {
25         }
26         
27         public function test($user_id = 1)
28         {
29
30         }
31
32         /**
33         * Login a user and then redirect it to the last page which must be encoded
34         * in $redirect.
35         *
36         * @param string $redirect       contains the last page URI segments encoded
37         * with helper url_encode_segments.
38         */
39         public function login($redirect = '')
40         {
41                 $this->load->library('form_validation');
42                 $this->form_validation->set_error_delimiters('<span class="error">',
43                         '</span>');
44                 
45                 // Normal or OpenID login?
46                 if ($this->input->post('openid') !== FALSE)
47                         $b_openid = TRUE;
48                 else
49                         $b_openid = FALSE;
50                 // Validate the correct form.
51                 $res_form_validation = FALSE;
52                 if (!$b_openid)
53                         $res_form_validation = $this->form_validation->run('login');
54                 else
55                         $res_form_validation = $this->form_validation->run('login_openid');
56
57                 if ($res_form_validation === FALSE)
58                 {
59                         $params = array(        'title' =>
60                                                                         $this->lang->line('ui_nav_menu_login')
61                                                                                 .' &ndash; '
62                                                                                 . $this->config->item('site_name'),
63                                                                 //'metas' => array('description'=>'')
64                         );
65                         $this->load->library('html_head_params', $params);
66                                 
67                         // **
68                         // ** LOADING VIEWS
69                         // **
70                         $this->load->view('html_begin', $this->html_head_params);
71                         $this->load->view('header', array('selected_menu' => 'login'));
72
73                         $main_params['content'] = $this->load->view('user/login_view',
74                                 array('redirect'=> $redirect), TRUE);
75                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
76                         $this->load->view('main', $main_params);
77                                 
78                         $this->load->view('footer');
79                         $this->load->view('html_end');
80                 }
81                 else
82                 {
83                         if ($b_openid)
84                         {
85                                 $this->lang->load('openid');
86                                 $this->load->library('openid');
87                                 $this->config->load('openid');
88                                 $request_to = site_url('user/check_openid_login');
89                                 $req = $this->config->item('openid_required');
90                                 $opt = $this->config->item('openid_optional');
91                                 $policy = site_url('user/openid_policy');
92                                 $pape_policy_uris = $this->config->item('openid_papa_policies');
93                                 
94                                 $this->openid->set_request_to($request_to);
95                                 $this->openid->set_trust_root(base_url());
96                                 $this->openid->set_args(null);
97                                 $this->openid->set_sreg(true, $req, $opt, $policy);
98                                 if (!empty($pape_policy_uris))
99                                         $this->openid->set_pape(true, $pape_policy_uris);
100                                 
101                                 // Redirection to OP site will follow.
102                                 $this->openid->authenticate($this->input->post('openid'));
103                                 return;
104                         }
105                         
106                         // Without OpenID
107                         if (! $this->activated_account)
108                                 header('Location: '
109                                         . site_url("user/activate/{$this->user_id}"));
110                         else if (! $this->import)
111                         {
112                                 // Redirect to last page before login. 
113                                 header('Location: '. site_url(urldecode_segments($redirect)));
114                         }
115                         else
116                         {
117                                 // Redirect to account page because an user authenticates here
118                                 // for the first time with external authentication. The page
119                                 // will display imported data.
120                                 header('Location: '. site_url('user/account'));
121                         }
122                 }
123         }
124         
125         public function check_openid_login()
126         {
127                 $this->lang->load('openid');
128                 $this->load->library('openid');
129                 $this->config->load('openid');
130                 $request_to = site_url('user/check_openid_login');
131
132                 $this->openid->set_request_to($request_to);
133                 $response = $this->openid->get_response();
134
135                 switch ($response->status)
136                 {
137                 case Auth_OpenID_CANCEL:
138                         $this->load->helper('message');
139                         show_info_msg_page($this, $this->lang->line('openid_cancel'));
140                         break;
141                 case Auth_OpenID_FAILURE:
142                         $this->load->helper('message');
143                         show_error_msg_page($this,
144                                         $this->_format_message('openid_failure',
145                                                         $response->message));
146                         break;
147                 case Auth_OpenID_SUCCESS:
148                         $openid = $response->getDisplayIdentifier();
149                         $esc_identity = htmlspecialchars($openid, ENT_QUOTES);
150
151                         $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
152                         $sreg = $sreg_resp->contents();
153                         
154                         // Get registration informations
155                     $ax = new Auth_OpenID_AX_FetchResponse();
156                         $obj = $ax->fromSuccessResponse($response);
157
158                         //echo 'nickname('. $sreg_resp->get('nickname'). ')';
159                         echo var_dump($obj->data);
160 //                      foreach ($sreg as $key => $value)
161 //                      {
162 //                              $data['success'] .= $this->_set_message('openid_content', array($key, $value), array('%s', '%t'));
163 //                      }
164
165                         break;
166                 }
167         }
168         
169         public function openid_policy()
170         {
171                 $this->load->view('openid_policy_view');
172         }
173         
174         /**
175          * Logout user and then redirect it to the last page which must be encoded
176          * in $redirect.
177          * 
178          * @param string $redirect      contains the last page URI segments encoded
179          * with helper url_encode_segments.
180          */
181         public function logout($redirect = '')
182         {
183                 $this->session->unset_userdata('user_id');
184                 $this->session->unset_userdata('username');
185                 $this->session->unset_userdata('auth_src');
186                 $this->session->unset_userdata('time_zone');
187                 
188                 header('Location: '. site_url(urldecode_segments($redirect)));
189         }
190         
191         public function register($redirect = '')
192         {
193                 $this->load->library('form_validation');
194                 $this->load->helper('localization');
195                 $this->load->helper('date');
196                         
197                 $this->form_validation->set_error_delimiters('<span class="error">',
198                                         '</span>');
199                 $error_upload = '';
200
201                 if ($this->form_validation->run('register'))
202                 {
203                         $b_validation = TRUE;
204                         
205                         if ($_FILES['picture']['tmp_name'])
206                         {
207                                 // Upload library
208                                 $config_upload['upload_path'] = './data/user_pictures';
209                                 $config_upload['file_name'] = 
210                                         str_replace('.', '-', $this->input->post('username')) .'-';
211                                 $config_upload['allowed_types'] = 'gif|jpg|png';
212                                 $config_upload['max_size'] = '10240';
213                                 $this->load->library('upload', $config_upload);
214                                 
215                                 $b_validation = $this->upload->do_upload('picture');
216                                 $error_upload = 
217                                         $this->upload->display_errors('<span class="error">',
218                                                         '</span>');
219                         }
220                 }
221                 else
222                         $b_validation = FALSE;
223                 
224                 if (! $b_validation)
225                 {
226                         // Edit account data if logged in, otherwise register.
227                         if ($user_id = $this->session->userdata('user_id'))
228                         {
229                                 $userdata = $this->users_model->get_userdata(intval($user_id));
230                                 $selected_menu = 'account';
231                         }
232                         else
233                         {
234                                 $userdata = FALSE;
235                                 $selected_menu = 'register';
236                         }
237                         
238                         $params = array('title' =>
239                                                                 $this->lang->line('ui_nav_menu_register')
240                                                                         .' &ndash; '
241                                                                         . $this->config->item('site_name'),
242                                                         //'metas' => array('description'=>'')
243                         );
244                         $this->load->library('html_head_params', $params);
245                 
246                         // **
247                         // ** LOADING VIEWS
248                         // **
249                         $this->load->view('html_begin', $this->html_head_params);
250                         $this->load->view('header', 
251                                 array('selected_menu' => $selected_menu));
252                         
253                         $main_params['content'] = $this->load->view('user/register_view', 
254                                 array('userdata'=> $userdata, 'redirect'=> $redirect,
255                                         'error_upload'=> $error_upload),
256                                 TRUE);
257                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
258                         $this->load->view('main', $main_params);
259                 
260                         $this->load->view('footer');
261                         $this->load->view('html_end');
262                 }
263                 else
264                 {
265                         $user_id = $this->input->post('user-id');
266                         $data['email'] = $this->input->post('email');
267                         $data['first_name'] = $this->input->post('first-name');
268                         $data['last_name'] = $this->input->post('last-name');
269                         $data['birth_date'] = $this->input->post('birth-date');
270                         $data['country'] = $this->input->post('country');
271                         $data['locality'] = $this->input->post('locality');
272                         $data['ui_lang'] = $this->input->post('ui-lang');
273                         $data['time_zone'] = $this->input->post('time-zone');
274                         
275                         // Handle picture if one was uploaded.
276                         if ($_FILES['picture']['tmp_name'])
277                         {
278                                 $upload_data = $this->upload->data();
279                                 $this->load->library('image');
280                                 $this->image->load($upload_data['full_path']);
281                                 // Resize original to a maximum size.
282                                 if ($this->image->get_width() * $this->image->get_height()
283                                                 > 640*480)
284                                 {
285                                         $this->image->save_thumbnail(
286                                                 $upload_data['full_path'],
287                                                 640, 480, IMAGETYPE_AUTO);
288                                 }
289                                 // Create thumbnail.
290                                 $data['picture'] = $upload_data['file_name'];
291                                 $this->image->save_thumbnail($upload_data['file_path']
292                                                 . $upload_data['file_name']. '-thumb.jpg', 120, 90);
293                         }
294                         
295                         // Update session user data.
296                         $this->_update_session_userdata($data);
297                         
298                         // Edit account data
299                         if ($user_id)
300                         {
301                                 $password = $this->input->post('new-password');
302                                 if ($password)
303                                         $data['password'] = $this->input->post('new-password');
304                                 
305                                 $this->users_model->set_userdata($user_id, $data);
306                                 
307                                 // Redirect to last page before login.
308                                 header('Location: '. site_url(urldecode_segments($redirect)));
309                         }
310                         // Registration
311                         else
312                         {
313                                 $data['username'] = $this->input->post('username');
314                                 $data['password'] = $this->input->post('password');
315                                 
316                                 $this->users_model->register($data);
317                                 $user_id = $this->users_model->get_userdata($data['username'],
318                                                 "id");
319                                 $user_id = $user_id['id'];
320                                 
321                                 // Redirect account activation page.
322                                 header('Location: '. site_url("user/activate/$user_id"));
323                         }
324                 }
325         }
326         
327         public function account($redirect = '')
328         {
329                 $this->register($redirect);
330         }
331         
332         public function profile($username, $videos_offset = 0)
333         {
334                 // TODO handle user not found
335                 
336                 $this->load->config('localization');
337                 $this->load->helper('date');
338                 $this->lang->load('date');
339                 
340                 // **
341                 // ** LOADING MODEL
342                 // **
343                 // Logged in user time zone
344                 $time_zone = $this->session->userdata('time_zone');
345                 
346                 // User data
347                 $userdata = $this->users_model->get_userdata($username);
348                 $userdata['roles'] = Users_model::roles_to_string($userdata['roles']);
349                 $country_list = $this->config->item('country_list');
350                 $userdata['country_name'] = $country_list[ $userdata['country'] ];
351                 $userdata['last_login'] = human_gmt_to_human_local(
352                         $userdata['last_login'], $time_zone); 
353                 $userdata['time_zone'] = $this->lang->line($userdata['time_zone']);
354                 
355                 // User's videos
356                 $this->load->model('videos_model');
357                 $vs_data['videos'] = $this->videos_model->get_videos_summary(
358                         NULL, $username, intval($videos_offset),
359                         $this->config->item('videos_per_page'));
360                 
361                 // Pagination
362                 $this->load->library('pagination');
363                 $pg_config['base_url'] = site_url("user/profile/$username/");
364                 $pg_config['uri_segment'] = 4;
365                 $pg_config['total_rows'] = $this->videos_model->get_videos_count(
366                         NULL, $username);
367                 $pg_config['per_page'] = $this->config->item('videos_per_page');
368                 $this->pagination->initialize($pg_config);
369                 $vs_data['pagination'] = $this->pagination->create_links();
370                 $vs_data['title'] = NULL;
371                 $vs_data['category_name'] = ''; // TODO videos_summary with AJAX
372                 
373                 $params = array(
374                         'title'=> $this->lang->line('user_appelation').' '.$username
375                                 .' &ndash; '
376                                 . $this->config->item('site_name'),
377                         'css'=> array('catalog.css')
378                         //'metas' => array('description'=>'')
379                 );
380                 $this->load->library('html_head_params', $params);
381                 
382                 // Current user profile tab
383                 $tab = (! $videos_offset ? 0 : 1);
384                 
385                 // **
386                 // ** LOADING VIEWS
387                 // **
388                 $this->load->view('html_begin', $this->html_head_params);
389                 $this->load->view('header', array());
390                 
391                 $vs = $this->load->view('catalog/videos_summary_view', $vs_data, TRUE);
392                 
393                 $main_params['content'] = $this->load->view('user/profile_view',
394                         array('userdata'=> $userdata, 'videos_summary'=> $vs, 'tab'=>$tab),
395                         TRUE);
396                 $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
397                 $this->load->view('main', $main_params);
398                 
399                 $this->load->view('footer');
400                 $this->load->view('html_end');
401         }
402         
403         public function activate($user_id, $method='', $activation_code='')
404         {
405                 $user_id = intval($user_id);            
406                 $res_form_validation = FALSE;
407                 
408                 if ($method == 'code')
409                 {
410                         if (! $activation_code)
411                                 $res_form_validation = $this->form_validation->run('activate');
412                         // Activation code is provided in URL.
413                         else
414                         {
415                                 if ($this->_valid_activation_code($activation_code)
416                                                 && $this->users_model->activate_account($user_id,
417                                                         $activation_code))
418                                 {
419                                         $this->load->helper('message');
420                                         show_info_msg_page($this, sprintf(
421                                                 $this->lang->line('user_msg_activated_account'), 
422                                                 site_url('user/login')));
423                                         return;
424                                 }
425                                 else
426                                 {
427                                         $this->load->helper('message');
428                                         show_error_msg_page($this, 
429                                                         $this->lang->line(
430                                                                         'user_msg_wrong_activation_code'));
431                                         return;
432                                 }
433                         }
434                 }
435                 else if ($method == 'resend')
436                 {
437                         $res_form_validation =
438                                 $this->form_validation->run('resend_activation');
439                 }
440                 
441                 $userdata = $this->users_model->get_userdata($user_id,
442                                 'email, a.activation_code');
443                 $email = $userdata['email'];
444                 $activated_account = ($userdata['activation_code'] == NULL);
445                 
446                 if ($activated_account)
447                 {
448                         $this->load->helper('message');
449                         show_info_msg_page($this, sprintf(
450                                 $this->lang->line('user_msg_activated_account'), 
451                                 site_url('user/login')));
452                         return;
453                 }
454                 
455                 $this->load->library('form_validation');
456                         
457                 $this->form_validation->set_error_delimiters('<span class="error">',
458                                         '</span>');
459                 
460                 if ($res_form_validation === FALSE)
461                 {
462                         $params = array(
463                                 'title'=> $this->lang->line('user_title_activation')
464                                         .' &ndash; '
465                                         . $this->config->item('site_name'),
466                                 //'metas' => array('description'=>'')
467                         );
468                         $this->load->library('html_head_params', $params);
469                 
470                         // **
471                         // ** LOADING VIEWS
472                         // **
473                         $this->load->view('html_begin', $this->html_head_params);
474                         $this->load->view('header', array());
475
476                         // Show form
477                         $main_params['content'] = 
478                                 $this->load->view('user/activate_view',
479                                 array(  'user_id'=> $user_id,
480                                                 'email'=> $userdata['email']),
481                                 TRUE);
482                         
483                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
484                         $this->load->view('main', $main_params);
485                 
486                         $this->load->view('footer');
487                         $this->load->view('html_end');
488                 }
489                 else
490                 {
491                         if ($method == 'code')
492                         {
493                                 // A message which tells the user that the
494                                 // activation was successful.
495                                 $this->load->helper('message');
496                                 show_info_msg_page($this, sprintf(
497                                         $this->lang->line('user_msg_activated_account'), 
498                                         site_url('user/login')));
499                                 return;
500                         }
501                         else if ($method == 'resend')
502                         {
503                                 // Redirect to resent message
504                                 $this->load->helper('message');
505                                 show_info_msg_page($this, sprintf(
506                                                 $this->lang->line('user_msg_activation_resent'),
507                                                 $this->input->post('email')));
508                                 return;
509                         }
510                 }
511         }
512         
513         public function recover_password()
514         {
515                 $this->load->library('form_validation');
516                         
517                 $this->form_validation->set_error_delimiters('<span class="error">',
518                         '</span>');
519
520                 if ($this->form_validation->run('recover_password') === FALSE)
521                 {
522                         $params = array(        'title' =>
523                                                                         $this->lang->line(
524                                                                                 'user_title_password_recovery')
525                                                                                 .' &ndash; '
526                                                                                 . $this->config->item('site_name'),
527                                                                 //'metas' => array('description'=>'')
528                         );
529                         $this->load->library('html_head_params', $params);
530                                 
531                         // **
532                         // ** LOADING VIEWS
533                         // **
534                         $this->load->view('html_begin', $this->html_head_params);
535                         $this->load->view('header', array('selected_menu' => 
536                                         'recover_password'));
537
538                         $main_params['content'] = $this->load->view(
539                                 'user/recover_password_view', array(),
540                                 TRUE);
541                         
542                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
543                         $this->load->view('main', $main_params);
544                                 
545                         $this->load->view('footer');
546                         $this->load->view('html_end');
547                 }
548                 else
549                 {
550                         // Resent message
551                         $this->load->helper('message');
552                         show_info_msg_page($this, sprintf(
553                                         $this->lang->line('user_msg_password_recovery_email_sent'),
554                                         $this->input->post('username'),
555                                         $this->input->post('email')));
556                         return;
557                 }
558         }
559         
560         public function _format_message($msg, $val = '', $sub = '%s')
561         {
562                 return str_replace($sub, $val, $this->lang->line($msg));
563         }
564         
565         public function _update_session_userdata($data)
566         {
567                 foreach ($data as $key=> $val)
568                         $this->session->set_userdata($key, $val);
569         }
570         
571         public function _valid_username($username)
572         {
573                 return (preg_match('/^[a-z0-9\._]+$/', $username) === 1);
574         }
575
576         public function _valid_username_or_email($username)
577         {
578                 $this->load->helper('email');
579
580                 if (valid_email($username))
581                         return TRUE;
582                 else
583                         return $this->_valid_username($username);
584         }
585         
586         public function _valid_date($date)
587         {
588                 if (! $date)
589                         return TRUE;
590                 
591                 return (preg_match('/[\d]{4}-[\d]{2}-[\d]{2}/', $date) === 1);
592         }
593         
594         public function _postprocess_birth_date($date)
595         {
596                 // If the user entered no birth date NULL needs to be inserted into DB.
597                 if (! $date)
598                         return NULL;
599                 
600                 return $date;
601         }
602         
603         public function _valid_old_password($old_password, $field_username)
604         {
605                 if (! $old_password)
606                         return TRUE;
607                 
608                 $username= $this->input->post($field_username);
609                 
610                 if ($this->users_model->login($username, $old_password))
611                         return TRUE;
612                 
613                 return FALSE;
614         }
615         
616         public function _change_password_cond($param)
617         {
618                 $old = $this->input->post('old-password');
619                 $new = $this->input->post('new-password');
620                 $newc = $this->input->post('new-password-confirmation');
621                 
622                 return (!$old && !$new && !$newc)
623                         || ($old && $new && $newc);
624         }
625         
626         public function _required_by_register($param)
627         {
628                 $user_id = $this->input->post('user-id');
629                 
630                 if (! $user_id && ! $param)
631                         return FALSE;
632                 
633                 return TRUE;
634         }
635         
636         public function _valid_activation_code($activation_code)
637         {
638                 return (preg_match('/^[a-fA-F0-9]{16}$/', $activation_code) == 1);
639         }
640
641         public function _do_login($username, $field_password)
642         {
643                 $password = $this->input->post($field_password);
644
645                 $user = $this->users_model->login($username, $password);
646
647                 // Authentication failed.
648                 if ($user === FALSE)
649                         return FALSE;
650                 
651                 // User has not activated the account.
652                 if ($user['activation_code'] !== NULL)
653                 {
654                         $this->activated_account = FALSE;
655                         $this->user_id = $user['id'];
656                         return TRUE;
657                 }
658                 
659                 // Authentication successful: set session with user data.
660                 $this->session->set_userdata(array(
661                         'user_id'=> $user['id'],
662                         'username'=> $user['username'],
663                         'auth_src'=> $user['auth_src'],
664                         'time_zone'=> $user['time_zone']
665                 ));
666                 $this->import = (isset($user['import']) ? $user['import'] : FALSE);
667                 return TRUE;
668         }
669         
670         public function _do_activate($activation_code)
671         {
672                 $user_id = $this->input->post('user-id');
673                 if ($user_id === FALSE)
674                         return FALSE;
675                 $user_id = intval($user_id);
676                 
677                 return $this->users_model->activate_account($user_id,
678                                 $activation_code);
679         }
680         
681         public function _do_resend_activation($email)
682         {
683                 $user_id = $this->input->post('user-id');
684                 if ($user_id === FALSE)
685                         return FALSE;
686                 $user_id = intval($user_id);
687                 
688                 $this->users_model->set_userdata($user_id,
689                         array('email'=> $email));
690                 
691                 return $this->users_model->send_activation_email($user_id, $email);
692         }
693         
694         public function _username_exists($username)
695         {
696                 $userdata = $this->users_model->get_userdata($username);
697                 
698                 if (! $userdata)
699                         return FALSE;
700                 
701                 return TRUE;
702         }
703         
704         public function _internal_account($username)
705         {
706                 $userdata = $this->users_model->get_userdata($username, 'auth_src');
707                 if (! $userdata)
708                         return FALSE;
709
710                 if ($userdata['auth_src'] != 'internal')
711                         return FALSE;
712                 
713                 return TRUE;
714         }
715         
716         public function _do_recover_password($username)
717         {
718                 $email = $this->input->post('email');
719                 if (! $email)
720                         return FALSE;
721                 
722                 return $this->users_model->recover_password($username, $email);
723         }
724 }
725
726 /* End of file user.php */
727 /* Location: ./application/controllers/user.php */