PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/app/controllers/components/auth.php

https://github.com/rogerwu99/randomizr
PHP | 571 lines | 422 code | 51 blank | 98 comment | 93 complexity | 79fcacffa774a6debe7849ebbd5f66d7 MD5 | raw file
Possible License(s): MIT, LGPL-3.0
  1. <?php
  2. class AuthComponent extends Object {
  3. //user model name
  4. var $user_model_name = 'User';
  5. //user model fields for user and password.
  6. var $user_name_field = 'email';
  7. var $user_pass_field = 'password';
  8. //do you want to case fold the username before verifying? either 'lower','upper','none', to change case to lower/upper/leave it alone before matching.
  9. var $user_name_case_folding = 'lower';
  10. //surely you have a field in you users table to show whether the user is active or not? set to null if not.
  11. var $user_live_field = 'live';
  12. var $user_live_value = 1;
  13. //Group for access control if used, and the field for matching the name.
  14. var $group_model_name = 'Group';
  15. var $group_name_field = 'name';
  16. //set to false if you don use a HABTM group relationship.
  17. var $HABTM = true;
  18. //if you want a single group to have automatically granted access to any restriction.
  19. var $superuser_group = 'Root';
  20. //this is the login and deny views (I usually suggest keeping this in the root of your views folder)
  21. var $login_view = '/login';
  22. var $deny_view = '/deny';
  23. // NB this is were to **redirect** AFTER logout by default
  24. var $logout_page = '/';
  25. //This message is setFlash()'d on failed login.
  26. var $login_failed_message = '<div class="bodycopy" style="color:red;">Login Failed, Please check your details and try again.</div>';
  27. //Message to setFlash after logout.
  28. var $logout_message = '<p class="success">You have been succesfully logged out.</p>';
  29. //Allow use of cookies to remember authenticated sessions.
  30. var $allow_cookie = true;
  31. //how long until cookies expire (by default). format is "strtotime()" based (http://php.net/strtotime).
  32. var $cookie_expiry = '+1 week';
  33. //some random stuff that someone is unlikey to guess.
  34. var $session_secure_key = 't8rewf897sdfaNf12HXsqw6Flpf9';
  35. /**
  36. * You can edit this function to explain how you want to hash your passwords.
  37. * Also you can use it as a static function in your controller to hash passwords beforeSave
  38. */
  39. function hasher($plain_text)
  40. {
  41. $hashed = sha1('dudes'.$plain_text.'ladies');
  42. return $hashed;
  43. }
  44. ##########################################################################
  45. /*
  46. * DON'T EDIT THESE OR ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING
  47. */
  48. var $controller;
  49. var $here;
  50. var $components=array('Session');
  51. var $uses = array('User','Merchant');
  52. var $current_user;
  53. var $from_session;
  54. var $from_post;
  55. var $from_cookie;
  56. var $from_oauth;
  57. function startup(&$controller){
  58. //Let's check they have changed the secure key from the default.
  59. if($this->session_secure_key == 'sRmtVStkedAdlxBy'){
  60. die('<p>Please change the Auth::session_secure_key value from it default.</p>');
  61. }
  62. $this->controller = $controller;
  63. if (get_class($this->controller) == "MerchantsController"){
  64. $this->user_model_name="Merchant";
  65. }
  66. $this->here = substr($this->controller->here,strlen($this->controller->base));
  67. $this->controller->_login();
  68. //now check session/cookie info.
  69. $this->getUserInfoFromSessionOrCookie();
  70. //now see if the calling controller wants auth
  71. if( array_key_exists('_Auth', $this->controller) ){
  72. // We want Auth for any action here
  73. if(!empty($this->controller->_Auth['onDeny'])){
  74. $deny = $this->controller->_Auth['onDeny'];
  75. }else{
  76. $deny = null;
  77. }
  78. if(!empty($this->controller->_Auth['required'])){
  79. $this->requiresAuth($this->controller->_Auth['required'],$deny);
  80. }else{
  81. $this->requiresAuth(null,$deny);
  82. }
  83. }
  84. //finally give the view access to the data
  85. $this->_giveViewData();
  86. /* if ($this->controller->name == 'Twitter'){
  87. echo 'twitter';
  88. var_dump($this->controller->TwitterUserData);
  89. if (!empty($this->controller->TwitterUserData){
  90. $this->controller->set('_Auth', $this->controller->TwitterUserData)
  91. }
  92. else {
  93. echo 'hoe';
  94. }
  95. }
  96. */
  97. }
  98. function _giveViewData(){
  99. // echo 'first';
  100. $DA = array(
  101. 'User'=>$this->getUserInfo(),
  102. // 'Access'=>$this->getAccessList()
  103. );
  104. $this->controller->set('_Auth',$DA);
  105. }
  106. function giveViewData($data){
  107. // echo '2nd';
  108. // var_dump($data);
  109. $this->controller->set('_Auth',$data);
  110. //return true;
  111. //}
  112. }
  113. function secure_key(){
  114. static $key;
  115. if(!$key){
  116. $key = md5(Configure::read('Security.salt').'!Auth!'.$this->session_secure_key);
  117. }
  118. return $key;
  119. }
  120. function requiresAuth($groups=array(),$deny_redirect=null){
  121. if( empty($this->current_user) ){
  122. // Still no info! render login page!
  123. if($this->from_post){
  124. $this->Session->setFlash($this->login_failed_message);
  125. }
  126. echo $this->controller->render($this->login_view);
  127. exit();
  128. }else{
  129. if($this->from_post){
  130. // user just authed, so redirect to avoid post data refresh.
  131. $this->controller->redirect($this->here,null,null,true);
  132. exit();
  133. }
  134. // User is authenticated, so we just need to check against the groups.
  135. if( empty($groups) ){
  136. // No Groups specified so we are good to go!
  137. $deny = false;
  138. }else{
  139. $deny = !$this->isAllowed($groups);
  140. }
  141. if($deny){
  142. // Current User Doesn't Have Access! DENY
  143. if($deny_redirect){
  144. $this->controller->redirect($deny_redirect);
  145. exit();
  146. }else{
  147. // $this->_giveViewData(); // so this view has it, otherwise the exit stopps it being set.
  148. // $this->giveViewData();
  149. echo $this->controller->render($this->deny_view);
  150. exit();
  151. }
  152. }
  153. }
  154. return true;
  155. }
  156. function isAllowed($groups=array()){
  157. if( empty($this->current_user) ){
  158. // No information about the user! FALSE
  159. return false;
  160. }else{
  161. // User is authenticated, so we just need to check against the groups.
  162. if( empty($groups) ){
  163. // No Groups specified so we are good to go! TRUE
  164. return true;
  165. }
  166. if(!is_array($groups)){
  167. //if a string passed, turn to an array with one element
  168. $groups = array(0 => $groups);
  169. }
  170. $access = $this->getAccessList();
  171. foreach($groups as $g){
  172. if(array_key_exists($g,$access) && $access[$g]){
  173. return true;
  174. }
  175. }
  176. }
  177. }
  178. function getCookieInfo(){
  179. if(!array_key_exists('Auth',$_COOKIE)){
  180. //No cookie
  181. return false;
  182. }
  183. list($hash,$data) = explode("|||",$_COOKIE['Auth']);
  184. if($hash != md5($data.$this->secure_key())){
  185. //Cookie has been tampered with
  186. return false;
  187. }
  188. $crumbs = unserialize(base64_decode($data));
  189. if(!array_key_exists('username',$crumbs) ||
  190. !array_key_exists('password',$crumbs) ||
  191. !array_key_exists('expiry' ,$crumbs)){
  192. //Cookie doesn't contain the correct info.
  193. return false;
  194. }
  195. if(!isset($crumbs['expiry']) || $crumbs['expiry'] <= time()){
  196. //Cookie is out of date!
  197. return false;
  198. }
  199. //All checks passed, cookie is genuine. remove expiry time and return
  200. unset($crumbs['expiry']);
  201. return $crumbs;
  202. }
  203. function setCookieInfo($data,$expiry=0)
  204. {
  205. if($data === false)
  206. {
  207. //remove cookie!
  208. $cookie = false;
  209. $expiry = 100; //should be in the past enough!
  210. }
  211. else
  212. {
  213. $serial = base64_encode(serialize($data));
  214. $hash = md5($serial.$this->secure_key());
  215. $cookie = $hash."|||".$serial;
  216. }
  217. if($_SERVER['SERVER_NAME']=='localhost')
  218. {
  219. $domain = null;
  220. }
  221. else
  222. {
  223. $domain = '.'.$_SERVER['SERVER_NAME'];
  224. }
  225. if (empty($this->controller->base))
  226. {
  227. $base='/';
  228. }
  229. else
  230. {
  231. $base=$this->controller->base;
  232. }
  233. return setcookie('Auth', $cookie, $expiry, $base, $domain);
  234. }
  235. function authenticate_from_post($data){
  236. $this->from_post = true;
  237. return $this->authenticate($data);
  238. }
  239. function authenticate_from_session($data){
  240. $this->from_session = true;
  241. return $this->authenticate($data);
  242. }
  243. function authenticate_from_cookie(){
  244. $this->from_cookie = true;
  245. return $this->authenticate($this->getCookieInfo());
  246. }
  247. function authenticate_from_oauth($data){
  248. $this->from_oauth = true;
  249. return $this->authenticate($data);
  250. }
  251. function authenticate($data){
  252. if($data === false){
  253. $this->destroyData();
  254. return false;
  255. }
  256. if($this->from_session || $this->from_cookie || $this->from_oauth)
  257. {
  258. $hashed_password = $data['password'];
  259. }
  260. else
  261. {
  262. $hashed_password = $this->hasher($data['password']);
  263. }
  264. switch($this->user_name_case_folding)
  265. {
  266. case 'lower':
  267. $data['username'] = strtolower($data['username']);
  268. break;
  269. case 'upper';
  270. $data['username'] = strtoupper($data['username']);
  271. break;
  272. default: break;
  273. }
  274. $conditions = array(
  275. $this->user_model_name.".".$this->user_name_field => $data['username'],
  276. $this->user_model_name.".".$this->user_pass_field => $hashed_password
  277. );
  278. if($this->user_live_field){
  279. $field = $this->user_model_name.".".$this->user_live_field;
  280. $conditions[$field] = $this->user_live_value;
  281. };
  282. //$check = $this->controller->{$this->user_model_name}->find($conditions);
  283. // echo 'pre';
  284. if ($this->user_model_name == 'User'):
  285. $check = $this->controller->{$this->user_model_name}->find('first', array('conditions' => (array('User.email'=>$data['username'], 'User.password'=>$hashed_password))));
  286. //elseif ($this->user_model_name == 'Merchant'):
  287. //$check = $this->controller->{$this->user_model_name}->find('first', array('conditions' => (array('Merchant.email'=>$data['username'], 'Merchant.password'=>$hashed_password))));
  288. endif;
  289. //echo $this->user_model_name;
  290. //endif;
  291. //$db_results=$this->User->findByEmail($data['username']);
  292. //echo $this->user_model_name;
  293. //$db_results = $this->controller->{$this->user_model_name}->find(array('conditions' => (array('User.email'=>'info@klickable.tv', 'User.password'=>'ll1WmmFM8JkJ2uYPtQ7S'))));
  294. //var_dump($check);
  295. if($check){
  296. // echo 'in here';
  297. $this->Session->write($this->secure_key(),$check);
  298. if(
  299. $this->allow_cookie && //check we're allowing cookies
  300. $this->from_post && //check this was a posted login attempt.
  301. array_key_exists('remember_me',$data) && //check they where given the option!
  302. $data['remember_me'] == true //check they WANT a cookie set
  303. ){
  304. // set our cookie!
  305. if(array_key_exists('cookie_expiry',$data)){
  306. $this->cookie_expiry = $data['cookie_expiry'];
  307. }else{
  308. $this->cookie_expiry;
  309. }
  310. if(strtotime($this->cookie_expiry) <= time()){
  311. // Session cookie? might as well not set at all...
  312. }else{
  313. $expiry = strtotime($this->cookie_expiry);
  314. $this->setCookieInfo(array('username'=>$data['username'], 'password'=>$hashed_password, 'expiry'=>$expiry), $expiry);
  315. }
  316. }
  317. $this->current_user = $check;
  318. return true;
  319. }else{
  320. if($this->from_post){
  321. $this->Session->setFlash($this->login_failed_message);
  322. }
  323. $this->destroyData();
  324. return false;
  325. }
  326. }
  327. function getUserInfo(){
  328. return $this->current_user[$this->user_model_name];
  329. }
  330. function getUserId(){
  331. return $this->current_user[$this->user_model_name]['id'];
  332. }
  333. function getAllUserInfo(){
  334. return $this->current_user;
  335. }
  336. function getAccessList(){
  337. static $access_list = false;
  338. if(!$access_list){
  339. $access_list = $this->_generateAccessList();
  340. }
  341. return $access_list;
  342. }
  343. function _generateAccessList(){
  344. if(!$this->group_model_name){
  345. return array();
  346. }
  347. $all_groups = $this->controller->{$this->user_model_name}->{$this->group_model_name}->find('list');
  348. if(!count($all_groups)){ return array(); }
  349. $access = array_combine($all_groups,array_fill(0,count($all_groups),0)); //create empty array.
  350. if(empty($this->current_user)){
  351. // NO AUTHENTICATION, SO EMTPY ARRAY!
  352. return $access;
  353. }
  354. if($this->HABTM){
  355. // could be many groups
  356. $ugroups = Set::combine($this->current_user[$this->group_model_name],'{n}.id','{n}.'.$this->group_name_field);
  357. foreach($all_groups as $id => $role){
  358. if(in_array($role,$ugroups)){
  359. $access[$role] = 1;
  360. }else{
  361. $access[$role] = 0;
  362. }
  363. }
  364. }else{
  365. // single group assoc, id = user.group_id
  366. $foreign_key = $this->controller{$this->user_model_name}->belongsTo[$this->group_model_name]['foreignKey'];
  367. foreach($all_groups as $id => $role){
  368. if($this->current_user[$this->user_model_name][$foreign_key] == $id){
  369. $access[$role] = 1;
  370. }else{
  371. $access[$role] = 0;
  372. }
  373. }
  374. }
  375. if($this->superuser_group && $access[$this->superuser_group]){
  376. return array_combine($all_groups,array_fill(0,count($all_groups),1));
  377. }else{
  378. return $access;
  379. }
  380. }
  381. function destroyData(){
  382. $this->Session->delete($this->secure_key());
  383. if($this->allow_cookie){
  384. $this->setCookieInfo(false);
  385. }
  386. $this->current_user = null;
  387. }
  388. function logout($redirect=false){
  389. $this->destroyData();
  390. if(!$redirect){
  391. $redirect = $this->logout_page;
  392. }
  393. //$this->Session->setFlash($this->logout_message);
  394. $this->controller->redirect($redirect,null,true);
  395. exit();
  396. }
  397. function getUserInfoFromSessionOrCookie(){
  398. if( !empty($this->current_user) ){
  399. return false;
  400. }
  401. if($this->Session->valid() && $this->Session->check($this->secure_key()) ){
  402. $this->current_user = $this->Session->read($this->secure_key());
  403. return $this->authenticate_from_session(array(
  404. 'username' => $this->current_user[$this->user_model_name][$this->user_name_field],
  405. 'password' => $this->current_user[$this->user_model_name][$this->user_pass_field],
  406. ));
  407. }elseif($this->allow_cookie){
  408. return $this->authenticate_from_cookie();
  409. }
  410. }
  411. function redirectLoggedIn($where_to=null) {
  412. if (!empty($this->current_user))
  413. {
  414. if (!empty($where_to))
  415. {
  416. $this->controller->redirect($where_to);
  417. }
  418. $this->controller->redirect('/users/home');
  419. }
  420. }
  421. /* function user_in_group($name)
  422. {
  423. $Group = ClassRegistry::init('Group');
  424. $user = $this->current_user[$this->user_model_name];
  425. foreach($gu as $key=>$value)
  426. {
  427. $groups[] = $all[$key]['Group']['name'];
  428. }
  429. if(in_array($name, $groups))
  430. {
  431. return true;
  432. }
  433. else
  434. {
  435. return false;
  436. }
  437. }*/
  438. function login($data = null) {
  439. $this->__setDefaults();
  440. $this->_loggedIn = false;
  441. if (empty($data)) {
  442. $data = $this->data;
  443. }
  444. if ($user = $this->identify($data)) {
  445. $this->Session->write($this->sessionKey, $user);
  446. $this->_loggedIn = true;
  447. }
  448. return $this->_loggedIn;
  449. }
  450. function identify($user = null, $conditions = null) {
  451. if ($conditions === false) {
  452. $conditions = null;
  453. } elseif (is_array($conditions)) {
  454. $conditions = array_merge((array)$this->userScope, $conditions);
  455. } else {
  456. $conditions = $this->userScope;
  457. }
  458. $model =& $this->getModel();
  459. if (empty($user)) {
  460. $user = $this->user();
  461. if (empty($user)) {
  462. return null;
  463. }
  464. } elseif (is_object($user) && is_a($user, 'Model')) {
  465. if (!$user->exists()) {
  466. return null;
  467. }
  468. $user = $user->read();
  469. $user = $user[$model->alias];
  470. } elseif (is_array($user) && isset($user[$model->alias])) {
  471. $user = $user[$model->alias];
  472. }
  473. if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$model->alias . '.' . $this->fields['username']]))) {
  474. if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']]) && !empty($user[$this->fields['password']])) {
  475. if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
  476. return false;
  477. }
  478. $find = array(
  479. $model->alias.'.'.$this->fields['username'] => $user[$this->fields['username']],
  480. $model->alias.'.'.$this->fields['password'] => $user[$this->fields['password']]
  481. );
  482. } elseif (isset($user[$model->alias . '.' . $this->fields['username']]) && !empty($user[$model->alias . '.' . $this->fields['username']])) {
  483. if (trim($user[$model->alias . '.' . $this->fields['username']]) == '=' || trim($user[$model->alias . '.' . $this->fields['password']]) == '=') {
  484. return false;
  485. }
  486. $find = array(
  487. $model->alias.'.'.$this->fields['username'] => $user[$model->alias . '.' . $this->fields['username']],
  488. $model->alias.'.'.$this->fields['password'] => $user[$model->alias . '.' . $this->fields['password']]
  489. );
  490. } else {
  491. return false;
  492. }
  493. $data = $model->find('first', array(
  494. 'conditions' => array_merge($find, $conditions),
  495. 'recursive' => 0
  496. ));
  497. if (empty($data) || empty($data[$model->alias])) {
  498. return null;
  499. }
  500. } elseif (!empty($user) && is_string($user)) {
  501. $data = $model->find('first', array(
  502. 'conditions' => array_merge(array($model->escapeField() => $user), $conditions),
  503. ));
  504. if (empty($data) || empty($data[$model->alias])) {
  505. return null;
  506. }
  507. }
  508. if (!empty($data)) {
  509. if (!empty($data[$model->alias][$this->fields['password']])) {
  510. unset($data[$model->alias][$this->fields['password']]);
  511. }
  512. return $data[$model->alias];
  513. }
  514. return null;
  515. }
  516. }
  517. ?>