CiCMS - Prosty system użytkowników

Teraz zajmiemy się stworzeniem systemu użytkowników i kontroli uprawnień - podstawy wszystkich systemów CMS i podobnych. W system/application/config/database.php ustawiamy dane bazy danych, którą chcemy użyć. Jako prefix tabel podałem cicms_. W autoload.php podałem:
<?php

$autoload['libraries'] = array('database', 'validation');
$autoload['helper'] = array('url', 'form');
Następnie tworzymy w bazie tabelę (kod pod MySQL):
CREATE TABLE cicms_users (
user_id int(10) NOT NULL auto_increment,
user_login varchar(100)  default NULL,
user_password varchar(100) default NULL,
user_email varchar(100) default NULL,
user_active int(1) default '0',
user_last_login_ip varchar(20) default NULL,
user_perms text,
PRIMARY KEY  (user_id));
Tabela cicms_users będzie przechowywała dane o użytkownikach wraz z ich uprawnieniami. Pole user_id zawiera unikatowy numer ID (auto_increment), user_login i user_password przechowują login i hasz sha1/md5 hasła użytkownika. user_active oznacza czy konto jest aktywne (0 - nie, 1 - tak), pole user_last_login_ip zawiera adres IP ostatniego logowania, a user_perms będzie zawierało informacje o uprawnieniach o czym później.

Kontrolery

Musimy stworzyć kontrolery - dodaniwa, edycji i usunięcia konta użytkownika. Oprócz tego kontroler logowania i wylogowania użytkownika. Poniżej pełen kod kontrolera site ustawionego jako główny. Funkcje dodaj/usuń to kopiuj/wkelej kodu newsów z bloga, metody logowania i wylogowania także z bloga (z modyfikacjami):
<?php
class Site extends Controller
{
function Site()
	{
	parent::Controller();
	$this->load->model('User');
	$this->response = array();
	}
// bazowy kontroler
function index()
	{
	$users = $this->User->get_users()->result_array();
	if (isset($users[0]))
		{
		$this->response['content'] = $this->load->view('user_list', array('users' => $users), True);
		}
	else
		{
		$this->response['content'] = 'Brak użytkowników<br /><div style="text-align:center;"><h2><a href="'.site_url('site/user_add/').'">Dodaj Użytkownika</a></h2></div>';
		}
	IF(Site::_check_login())
		{
		$this->response['content'] .= '<br /><div style="text-align:center;"><h2><a href="'.site_url('site/logout/').'">Wyloguj</a></h2></div>';
		}
	else
		{
		$this->response['content'] .= '<br /><div style="text-align:center;"><h2><a href="'.site_url('site/login/').'">Zaloguj</a></h2></div>';
		}
	$this->load->view('index', $this->response);
	}
// dodanie użytkownika
function user_add()
	{
	$data["login"] = array('name' => 'login');
	$data['haslo'] = array('name' => 'haslo');
	$data['email'] = array('name' => 'email');
	
	$rules['login'] = "required|max_length[100]|xss_clean";
	$rules['haslo'] = "required|max_length[100]|xss_clean";
	$rules['email'] = "required|max_length[100]|xss_clean|valid_email";
	$this->validation->set_rules($rules);
	$ar = $this->User->get_user_by_login($this->input->post('login'))->result_array();
	if ($this->validation->run() == FALSE)
		{
		$data['login']['value'] = $this->input->post('login');
		$data['haslo']['value'] = $this->input->post('haslo');
		$data['email']['value'] = $this->input->post('email');
		$this->response['content'] = $this->load->view('user_add', $data, True);
		}
	else IF(!isset($ar[0]))
		{
		$this->User->add_user(array('user_login' => $this->input->post('login'), 'user_email' => $this->input->post('email'), 'user_password' => sha1(md5($this->input->post('haslo'))), 'user_active' => '1'));
		$this->response['content'] = '<h1>Dane zapisane</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('site').'">';
		}
	else
		{
		$this->response['content'] = '<h1>Użytkownik już istnieje w bazie danych</h1>';
		}
	$this->load->view('index', $this->response);
	}
//edycja konta
function user_edit()
	{
	$id = $this->uri->segment(3);
	IF(isset($id) and is_numeric($id))
		{
		$ar = $this->User->get_user_by_id($id)->result_array();
		
		$data["login"] = array('name' => 'login');
		$data['haslo'] = array('name' => 'haslo');
		$data['email'] = array('name' => 'email');
		$data['perms'] = array('name' => 'perms');
		
		$rules['login'] = "required|max_length[100]|xss_clean";
		$rules['perms'] = "xss_clean";
		$rules['haslo'] = "max_length[100]|xss_clean";
		$rules['email'] = "required|max_length[100]|xss_clean|valid_email";
		$this->validation->set_rules($rules);
		
		if ($this->validation->run() == FALSE)
			{
			IF(strlen($this->input->post('tytul')) > 0)
				{
				$data['login']['value'] = $this->input->post('login');
				$data['haslo']['value'] = $this->input->post('haslo');
				$data['email']['value'] = $this->input->post('email');
				$data['perms']['value'] = $this->input->post('perms');
				}
			else
				{
				$data['login']['value'] = $ar[0]['user_login'];
				$data['email']['value'] = $ar[0]['user_email'];
				$data['perms']['value'] = $ar[0]['user_perms'];
				}
			$this->response['content'] = $this->load->view('user_edit', $data, True);
			}
		else
			{
			IF(strlen($this->input->post('haslo')) > 0)
				{
				$this->User->update_user($id, array('user_login' => $this->input->post('login'), 'user_email' => $this->input->post('email'), 'user_perms' => $this->input->post('perms'), 'user_password' => sha1(md5($this->input->post('haslo')))));
				}
			else
				{
				$this->User->update_user($id, array('user_login' => $this->input->post('login'), 'user_email' => $this->input->post('email'), 'user_perms' => $this->input->post('perms')));
				}
			$this->response['content'] = '<h1>Zmiany zapisane</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('site').'">';
			}
		}
	else
		{
		$this->response['content'] = '<h1>Niepoprawny URL</h1>';
		}
	$this->load->view('index', $this->response);
	}

// usunięcie usera
function user_delete()
	{
	$id = $this->uri->segment(3);
	IF(isset($id) and is_numeric($id))
		{
		$this->User->delete_user($this->uri->segment(3));
		$this->response['content'] = '<h1>User skasowany</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('site').'">';
		$this->load->view('index', $this->response);
		}
	}
################################################################
// czy jestem zalogowany
function _check_login()
	{
	IF($cookie = $this->input->cookie('cicookie', True))
		{
		$dane = unserialize(base64_decode($cookie));
		IF(is_array($dane))
			{
			$ar = $this->User->get_user_by_login($dane['user'])->result_array();
			IF(isset($ar[0]) and $ar[0]['user_last_login_ip'] == $this->input->ip_address() and sha1(md5($ar[0]['user_login'].$ar[0]['user_password'])) == $dane['pass'])
				{
				return true;
				}
			else
				{
				return false;
				}
			}
		else
			{
			return false;
			}
		}
	else
		{
		return false;
		}
	}
// czy mam uprawnienie $perm
function _check_perm($perm)
	{
	IF($cookie = $this->input->cookie('cicookie', True))
		{
		$dane = unserialize(base64_decode($cookie));
		IF(is_array($dane))
			{
			$ar = $this->User->get_user_by_login($dane['user'])->result_array();
			IF(isset($ar[0]) and $ar[0]['user_last_login_ip'] == $this->input->ip_address() and sha1(md5($ar[0]['user_login'].$ar[0]['user_password'])) == $dane['pass'])
				{
				IF(strpos($ar[0]['user_perms'], $perm))
					{
					return true;
					}
				else
					{
					return false;
					}
				}
			else
				{
				return false;
				}
			}
		else
			{
			return false;
			}
		}
	else
		{
		return false;
		}
	}
// logowanie
function login()
	{
	$data["login"] = array('name' => 'login');
	$data['pass'] = array('name' => 'pass');
	
	$rules['login'] = "required|max_length[100]|xss_clean";
	$rules['pass'] = "required|max_length[100]|xss_clean";
	$this->validation->set_rules($rules);
	
	if ($this->validation->run() == FALSE)
		{
		$data['login']['value'] = $this->input->post('login');
		$data['pass']['value'] = $this->input->post('pass');
		$this->response['content'] = $this->load->view('login', $data, True);
		}
	else
		{
		$ar = $this->User->get_user_by_login($this->input->post('login'))->result_array();
		IF(isset($ar[0]) and $ar[0]['user_password'] == sha1(md5($this->input->post('pass'))))
			{
			$a = array('user' => $this->input->post('login'), 'pass' => sha1(md5($this->input->post('login').$ar[0]['user_password'])));
			setcookie("cicookie", base64_encode(serialize($a)), time()+172800, '/', '', '0');
			$this->User->update_login_ip($this->input->post('login'), $this->input->ip_address());
			$this->response['content'] = '<h1>Zalogowany</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('site').'">';
			}
		else
			{
			$this->response['content'] = '<h1>Błąd logowania</h1><META HTTP-EQUIV="Refresh" CONTENT="1; URL='.site_url('site').'">';
			}
		}
	$this->load->view('index', $this->response);
	}
//wylogowanie
function logout()
	{
	setcookie("cicookie", NULL, time()-172800, '/', '', '0');
	header('Location: '.site_url('site'));
	}
}
Do tego model user:
<?php
class User extends Model
{
function User()
	{
	parent::Model();
	}
function get_users()
	{
	return $this->db->get('users');
	}
function get_user_by_id($id)
	{
	// Pobiera określonego usera
	$this->db->where('user_id', $id);
	return $this->db->get('users');
	}
function get_user_by_login($login)
	{
	// Pobiera określonego usera
	$this->db->where('user_login', $login);
	$this->db->where('user_active', '1');
	return $this->db->get('users');
	}
function add_user($data)
	{
	// dodanie usera
	return $this->db->insert('users', $data);
	}
function update_user($id, $data)
	{
	// edycja danych usera o podanym numerze user_id
	$this->db->where('user_id', $id);
	return $this->db->update('users', $data);
	}
function delete_user($id)
	{
	// skasowanie usera o podanym user_id
	$this->db->where('user_id', $id);
	return $this->db->delete('users');
	}
function update_login_ip($login, $ip)
	{
	// edycja danych usera o podanym numerze user_id
	$this->db->where('user_login', $login);
	return $this->db->update('users', array('user_last_login_ip' => $ip));
	}

 }
Widoki są tak samo zaplanowane jak w poprzednich projektach - Widok index wyświetla zawartość zmiennej $content, która to zazwyczaj zawiera wykonany inny widok. Widok user_list:
<h1>Lista Użytkowników</h1>
<?PHP
foreach($users as $val)
{
echo '<b>'.$val['user_login'].'</b> - [<a href="'.site_url('site/user_edit/'.$val['user_id']).'">Edytuj</a>] |  [<a href="'.site_url('site/user_delete/'.$val['user_id']).'">Kasuj</a>]<br />';
}
?>
<br /><br />
<div style="text-align:center;"><h2><a href="<?PHP echo site_url('site/user_add/'); ?>">Dodaj Użytkownika</a></h2></div>
login:
<h1>Logowanie</h1>
<center><?=$this->validation->error_string; ?></center>

<?php echo form_open('site/login'); ?>
<table width="90%" border="0" cellspacing="3" cellpadding="3">
<tr><td width="180"><B>Login</B></td><td><?php echo form_input($login); ?></td></tr>
<tr><td width="180"><B>Hasło</B></td><td><?php echo form_password($pass); ?></td></tr>
<tr><td> </td><td><?php echo form_submit('submit', 'Zaloguj'); ?></td></tr>
</table>
<?php echo form_close(); ?>
user_add:
<h1>Dodaj użytkownika</h1>
<center><?=$this->validation->error_string; ?></center>

<?php echo form_open('site/user_add'); ?>
<table width="90%" border="0" cellspacing="3" cellpadding="3">
<tr><td width="180"><B>Login</B></td><td><?php echo form_input($login); ?></td></tr>
<tr><td width="180"><B>Hasło</B></td><td><?php echo form_password($haslo); ?></td></tr>
<tr><td width="180"><B>Adres Email</B></td><td><?php echo form_input($email); ?></td></tr>
<tr><td> </td><td><?php echo form_submit('submit', 'Zapisz'); ?></td></tr>
</table>
<?php echo form_close(); ?>
I user_edit:
<h1>Edytuj użytkownika</h1>
<center><?=$this->validation->error_string; ?></center>

<?php echo form_open('site/user_edit/'.$this->uri->segment(3)); ?>
<table width="90%" border="0" cellspacing="3" cellpadding="3">
<tr><td width="180"><B>Login</B></td><td><?php echo form_input($login); ?></td></tr>
<tr><td width="180"><B>Hasło</B></td><td><?php echo form_password($haslo); ?></td></tr>
<tr><td width="180"><B>Adres Email</B></td><td><?php echo form_input($email); ?></td></tr>
<tr><td width="180"><B>Uprawnienia</B></td><td><?php echo form_input($perms); ?></td></tr>
<tr><td> </td><td><?php echo form_submit('submit', 'Zapisz'); ?></td></tr>
</table>
<?php echo form_close(); ?>
Powyższy kod implementuje podstawowy system użytkowników i uprawnień. Metody dodawania i edycji kont użytkowników przeznaczone są dla "adminów" niż dla użytkowników, gdyż oferują edycję m.in. uprawnień - by udostępnić opcję edycji użytkownikowi wystarczy usunąć edycję uprawnień i upewnić się że zalogowany użytkownik edytuje swoje konto. Uprawnienia - w polu uprawnień podajemy frazy uprawnień oddzielone jakimś znakiem specjalnym np:
news_edit|news_add
I w naszych kontrolerach używamy _check_perm($perm) gdzie $perm zawiera ustaloną dla danej akcji frazę.
RkBlog

Kurs Code Igniter, 14 July 2008

Comment article
Comment article RkBlog main page Search RSS Contact