[php5]authentication manager

Soyez le premier à donner votre avis sur cette source.

Snippet vu 11 891 fois - Téléchargée 18 fois

Contenu du snippet

Quelques classes largement insprirées du framework prado mais taillées pour l'utilisation hors framework (quoique).
Il inclut des notions objet d'Applis et de modules:
j'tez-y un oeil pourvu qu'vous ne l'perdiez pas :).
PS: ce code est encore améliorable. C'est Juste pour le principe.

Source / Exemple :


--Sql
CREATE TABLE `groups` (
  `id` smallint(5) unsigned NOT NULL auto_increment,
  `name` varchar(32) collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;

-- 
-- Contenu de la table `groups`
-- 

INSERT INTO `groups` (`id`, `name`) VALUES 
(3, 'admin');

-- --------------------------------------------------------

-- 
-- Structure de la table `permissions`
-- 

CREATE TABLE `permissions` (
  `id` smallint(5) unsigned NOT NULL auto_increment,
  `page` varchar(64) collate utf8_unicode_ci default NULL,
  `selector` enum('user_id','group_id') collate utf8_unicode_ci default NULL,
  `value` smallint(5) unsigned default NULL,
  `allowed` enum('','1') collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `selector` (`selector`,`value`,`page`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=28 ;

-- 
-- Contenu de la table `permissions`
-- 

INSERT INTO `permissions` (`id`, `page`, `selector`, `value`, `allowed`) VALUES 
(27, 'test.php', 'group_id', 3, '1');

-- --------------------------------------------------------

-- 
-- Structure de la table `users`
-- 

CREATE TABLE `users` (
  `id` smallint(5) unsigned NOT NULL auto_increment,
  `group_id` smallint(5) unsigned NOT NULL,
  `person_id` smallint(5) unsigned default NULL,
  `name` varchar(32) collate utf8_unicode_ci NOT NULL,
  `password` varchar(64) collate utf8_unicode_ci default NULL,
  KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;

<?php
/**
dataSource Path

  • /
$dsPath='../datasource'; /** DataSource File Class Name
  • /
require_once $dsPath.'/CDataSource.php'; class propertyException extends Exception { const MSG_STRING_REQUIRED='type string attendu'; const MSG_INT_REQUIRED='type int attendu'; const MSG_DATASOURCE_REQUIRED='type CDataSource attendu'; const MSG_USERMANAGER_REQUIRED='type userManager attendu'; const MSG_USER_REQUIRED='type user attendu'; const MSG_BOOL_REQUIRED='type booléen attendu'; const MSG_OBJECT_REQUIRED='mauvais type attendu'; } class getsetException extends Exception { const MSG_PORPERTY_NOT_EXIST='Propriété inexistante'; } class propertyChecker { public static function ensureString($data) { if (! is_string($data)) throw new propertyException(propertyException::MSG_STRING_REQUIRED); else return $data; } public static function ensureInt($data) { return (int)$data; } public static function ensureBool($data) { if (! is_bool($data)) throw new propertyException(propertyException::MSG_BOOL_REQUIRED); else return $data; } public static function ensureCDataSource($data) { if (! is_subclass_of(get_class($data),'CDataSource')) throw new propertyException(propertyException::MSG_CDATASOURCE_REQUIRED); else return $data; } public static function ensureUserManager($data) { if (get_class($data) != 'userManager') throw new propertyException(propertyException::MSG_USERMANAGER_REQUIRED); else return $data; } public static function ensureUser($data) { if (get_class($data) != 'user') throw new propertyException(propertyException::MSG_USERMANAGER_REQUIRED); else return $data; } } class application { private static $_app; private static $_curUser = null; private static $_curPage = null; public static function setApp($app) { self::$_application = $application; } public static function getApp($app) { return self::$_application; } public static function setPage($page) { self::$_curPage = propertyChecker::ensureString($page); } public static function getPage($page) { return self::$_curPage; } public static function createComponent($type) { if (is_subclass_of($type,'component')) { if(($n = func_num_args()) > 1) { $args = func_get_args(); $s = '$args[1]'; for($i = 2 ; $i<$n ; ++$i) $s.=",\$args[$i]"; if ($type!='securityApp') eval("\$component=new $type($s);"); else eval("\$component=securityApp::getInstance($s) ;"); return $component; } else return new $type; } else throw new Exception ('La classe '.$type.' est inexistante'); } public static function setCurrentUser($user) { self::$_curUser = propertyChecker::ensureUser($user); } public static function getCurrentUser() { return self::$_curUser; } } class component { public function __set($prop,$value) { $set='set'.$prop; if (!method_exists($this,$set)) throw new propertyException(getsetException::MSG_PORPERTY_NOT_EXIST); return $this->$set($value); } public function __get($prop) { $get='get'.$prop; if (!method_exists($this,$get)) throw new propertyException(getsetException::MSG_PORPERTY_NOT_EXIST); return $this->$get(); } } class securityApp extends component { public static $_instance=null; private $_curUser=null; private $_curPage=null; private $_modules=array(); const MODULE_DBHANDLER = 0; const MODULE_USERMANAGER = 1; const MODULE_AUTHMANAGER = 2; protected function __construct($db,$modules) { $this->_modules[self::MODULE_DBHANDLER] = $db; foreach ($modules as $key=>$subModules) { switch ($key) { case self::MODULE_USERMANAGER : $this->_modules[self::MODULE_USERMANAGER] = new userManager($this->_modules[self::MODULE_DBHANDLER],$subModules[0],$subModules[1]); break; case self::MODULE_AUTHMANAGER: $this->_modules[self::MODULE_AUTHMANAGER] = new authManager($this->_modules[self::MODULE_DBHANDLER],$subModules[0]); break; } } } public function getModule($key) { return $this->_modules[$key]; } public function getCurrentUser() { return application::getCurrentUser(); } public function setCurrentUser($object) { application::setCurrentUser($object); } public static function getInstance($db,$modules) { if (!isset(self::$_instance)) self::$_instance = new self($db,$modules); return self::$_instance; } } class session extends component { private $_sessionId; public function __construct() { } } class userManager extends component { /** property Db ressource instance
  • /
private $_dbInstance; /** property user table
  • /
private $_userTable; /** property group table
  • /
private $_groupTable; public function __construct($dataSource,$userTable,$groupTable) { $this->_dbInstance = propertyChecker::ensureCDataSource($dataSource); $this->_userTable = propertyChecker::ensureString($userTable); $this->_groupTable = propertyChecker::ensureString($groupTable); } public function isValid($name,$password) { if (is_null($password) || $password === '') return false; $this->_dbInstance->query( 'SELECT name, password '. 'FROM '.$this->_userTable.' '. 'WHERE name="'.$name.'" AND password="'.$password.'"' ); if ($row=$this->_dbInstance->fetch_assoc()) { if (is_null($row['password'])) return false; return ($row['name'] == $name && $row['password'] == $password); } return false; } /** return user object
  • /
public function getUser($name) { $users = array(); $this->_dbInstance->query('select u.id,u.group_id,g.name from '.$this->_userTable.' as u, '.$this->_groupTable.' as g where u.group_id=g.id and u.name="'.$name.'"' ); if ($row = $this->_dbInstance->fetch_assoc()) { $user = new user($this); $user->IsAnonymous = false; $user->Name = $name; $user->Group = $row['name']; $user->UserId = $row['id']; $user->GroupId = $row['group_id']; } if($this->_dbInstance->num_rows() === 0) { $user = new user($this); } application::setCurrentUser($user); return $user; } public function setUserTable($usertable) { $this->_userTable = propertyChecker::ensureString($userTable); } public function setGroupTable($groupTable) { $this->_groupTable = propertyChecker::ensureString($groupTable); } public function getUserTable() { return $this->_userTable; } public function getGroupTable() { return $this->_groupTable; } } class user extends component { private $_userManager; private $_userId; private $_name; private $_group; private $_groupId; private $_isAnonymous; public function __construct($userManager) { $this->_userManager = propertyChecker::ensureUserManager($userManager); $this->_isAnonymous = true; $this->_name = 'Anonymous'; $this->_group = 'Anonymous'; } public function setName($value) { $this->_name = propertyChecker::ensureString($value); } public function getName() { return $this->_name; } public function setGroup($value) { $this->_group = propertyChecker::ensureString($value); } public function getGroup() { return $this->_group; } public function setGroupId($value) { $this->_groupId = propertyChecker::ensureInt($value); } public function getGroupId() { return $this->_groupId; } public function setUserId($value) { $this->_userId = propertyChecker::ensureInt($value); } public function getUserId() { return $this->_userId; } public function setIsAnonymous($value) { $this->_isAnonymous = propertyChecker::ensureBool($value); } public function getIsAnonymous() { return $this->_isAnonymous; } } class authManager extends component { private $_permTable; private $_dbInstance; public function __construct($db,$permT) { $this->_permTable = $permT; $this->_dbInstance=$db; } public function isAuthorized($page,$user) { $this->_dbInstance->query('SELECT `allowed` FROM `'.$this->_permTable.'` WHERE ' . '(`page`="'.$page.'" OR `page` IS NULL) ' . 'AND (' . '(`selector`="user_id" AND `value`="'.$user->UserId.'") ' . 'OR (`selector`="group_id" AND `value`="'.$user->GroupId.'") ' . ')' . 'ORDER BY `page` DESC'); $result=$this->_dbInstance->fetch_assoc(); if ($result && $result['allowed']==='1') { return true; } else return false; } } /** Instanciation de la DB
  • /
//Classe perso dispo sur CS $DbClass='CMysql'; $DbHost='localhost'; //Ca c'est affaire de gout, je le conçois, moi, c'est mon idole!! //Au passage désolé pour le dérangement. $DbUser='SiTuAimesBienRaffarinTapesDansTesMains'; $DbPass='SiTuAimesAntoineSeillereTapesParTerre'; $DbName='db_auth'; /** Ou $Db = votre instance de votre propre DB à condition votre Db ait les methodes query et fetch_assoc (voir code)
  • /
$db=CDataSource::add($DbClass,$DbHost,$DbUser,$DbPass,$DbNam); /** Définition des 2 modules de l'application => le nom des tables de la db par module
  • /
$modules=array(securityApp::MODULE_USERMANAGER=>array('users','groups'), securityApp::MODULE_AUTHMANAGER=>array('permissions')); /** Instanciation de l'appli de gestion des droits
  • /
$App=application::createComponent('securityApp',$db,$modules); /** Récupération du module userManager
  • /
$UserManager=$App->getModule(securityApp::MODULE_USERMANAGER); /** Vérification de la validité de l'utilisateur ici sans cryptage pour l'exemple
  • /
$userName='youruser'; $uesrPwd='yourpwd'; if ($UserManager->isValid($userName,$userPwd)) { if (!is_null ($App->CurrentUser)) echo $App->CurrentUser->Name; else echo 'utilsateur indéfini'; $user=$UserManager->getUser($userName); if (!is_null ($App->CurrentUser)) echo $App->CurrentUser->Name; else echo 'utilsateur indéfini'; $testUser= $App->getModule(securityApp::MODULE_USERMANAGER)->getUser($userName)->GroupId; if (!is_null ($App->CurrentUser)) echo $App->CurrentUser->Name; else echo 'utilsateur indéfini'; echo $testUser; // Vérification de la permission $auth=$App->getModule(securityApp::MODULE_AUTHMANAGER)->isAuthorized('test1.php',$App->CurrentUser); if ($auth===true) echo 'Accès autorisé'; else echo 'Accès Non Autorisé'; } else echo 'utilisateur invalide'; ?>

Conclusion :


On peut utiliser n'importe quelle classe de DB :
Il faut juste seulement modifier la methode ensureCDataSource de la classe propertyChecker avec le nom de votre classe utilisée et que votre classe implémente les methodes query et fetch_assoc:
J'essaierai ultérieurement de définir une interface dans ce but.
Manque aussi le cryptage. C'est ceci-dit un bon exercice que de l'ajouter

A voir également

Ajouter un commentaire

Commentaires

khattary
Messages postés
8
Date d'inscription
vendredi 23 octobre 2009
Statut
Membre
Dernière intervention
3 janvier 2010
-
c'est interessant mé ou est CDataSource.php?
franco_se
Messages postés
151
Date d'inscription
samedi 1 novembre 2003
Statut
Membre
Dernière intervention
30 juillet 2018
-
hello

Script interessant mais .... ou est CDataSource.php ? .......
Ca serait quand meme plus simple de tout mettre dans une archive, non ?
guill76
Messages postés
193
Date d'inscription
mercredi 24 août 2005
Statut
Membre
Dernière intervention
3 juin 2016
-
Bonjour,
En tout cas merci pour le 5 :) j'adore.
Pour clarifier:
C'est une appli de gestion de droits utilisateurs incluse dans un contexte de modules objets.
En gros tu passes par la classe application static (sorte de factory)pour instancier le composant applicatif (securityApp) composé lui même de 2 modules usermanager et authManager (autres composants) et d'une instance de DB.

Le module usermanager pilote la gestion utilisateurs sans tenir comptes des perimssions et le module authManager va faire pareil de son coté pour la gestion des permissions associées à ton utilisateur.

Les composants ici utilisent les getter et setter de manière à ce que tu puisses récupérer chaque propriétés privées souhaitée à partir de la méthode getNom_Propriete ainsi tu peux accéder aux propriétés que tu veux par $obj->NomPropriété en lecture(si celle ci à sa fonction getNom_Propriete d'implémentée) et préserver son caractère privé ou le modifier avec plus de sécurité par le biais du setter s'il la fonction setProp est définie:
C'est une manière de coder que je trouve plutôt interressante(et en plus assez universelle en objet)

Donc dans l'exemple ci-dessus c'est pour cela que j'utilise plusieurs appels différents d'objet
par la méthode getProp, ou à partir du composant applicatif principal : Je trouve ça assez puissant et sympa.
Sinon au niveau du fonctionnel, c'est relativement simple:
Cela gére l'accès à différentes pages par groupe d'appartenance de l'utilisateur ou par utilisateur particulier.
A ce niveau on pourrait pousser biensur un peu plus loin mais je voulais juste montrer le principe d'une gestion de droits à la façon Prado:
Voici d'ailleurs un lien à visiter pour vous aider à comprendre le principe :
c'est le tutorial à partir duquel j'ai adapté cette source:
http://www.pradosoft.com/wiki/index.php/Database_authentication_tutorial.
Et encore désolé pour le manque d'explications, j'éspère avoir lever en partie les ambiguités et incompréhensions...
cs_UNi
Messages postés
35
Date d'inscription
vendredi 15 février 2002
Statut
Membre
Dernière intervention
27 avril 2009
-
Ca m'a l'air bien compliqué tout ca !!
bchibicha
Messages postés
19
Date d'inscription
dimanche 18 mars 2007
Statut
Membre
Dernière intervention
29 février 2008
-
bjr
c'est tres bien de penser a creer des codes et de les mettre a la dispositon des autres mais le probleme c'est qu'il faut bien decrire l'application ainsi le code afin de clariser de quoi s'agit il, merci bcp

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.