1: <?php
2: /**
3: * This file contains the global authentication class.
4: *
5: * @package Core
6: * @subpackage Authentication
7: * @version SVN Revision $Rev:$
8: *
9: * @author Dominik Ziegler
10: * @copyright four for business AG <www.4fb.de>
11: * @license http://www.contenido.org/license/LIZENZ.txt
12: * @link http://www.4fb.de
13: * @link http://www.contenido.org
14: */
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: /**
19: * This class contains functions for global authentication in CONTENIDO.
20: *
21: * @package Core
22: * @subpackage Authentication
23: */
24: class cAuth {
25:
26: const AUTH_UID_NOBODY = 'nobody';
27:
28: const AUTH_UID_FORM = 'form';
29:
30: /**
31: * Lifetime for authenticated users in minutes.
32: * After that time the authentication expires.
33: * @var integer
34: */
35: protected $_lifetime = 15;
36:
37: /**
38: * The global auth information array.
39: * @var array
40: */
41: public $auth = array();
42:
43: /**
44: * Automatic authentication as nobody.
45: * @var bool
46: */
47: protected $_defaultNobody = false;
48:
49: /**
50: * The "in flag".
51: * Nobody knows, for which reasons it exists.
52: * @var bool
53: */
54: private $_in = false;
55:
56: /**
57: * Magic getter function for outdated variable names.
58: *
59: * @param string $name name of the variable
60: *
61: * @return mixed
62: */
63: public function __get($name) {
64: if ($name == 'lifetime') {
65: return $this->_lifetime;
66: }
67:
68: if ($name == 'persistent_slots') {
69: return array(
70: "auth"
71: );
72: }
73:
74: if ($name == 'classname') {
75: return get_class($this);
76: }
77: }
78:
79: /**
80: * Starts the authentication process.
81: */
82: public function start() {
83: $sess = cRegistry::getSession();
84: if (!$this->_in) {
85: $sess->register('auth');
86: $this->_in = true;
87: }
88:
89: if ($this->isAuthenticated()) {
90: $authInfo = $this->getAuthInfo();
91: $userId = $authInfo['uid'];
92: if ($userId == self::AUTH_UID_FORM) {
93: $userId = $this->validateCredentials();
94: if ($userId !== false) {
95: $this->_setAuthInfo($userId);
96: $this->logSuccessfulAuth();
97: } else {
98: $this->_fetchLoginForm();
99: }
100: } elseif ($userId != self::AUTH_UID_NOBODY) {
101: $this->_setExpiration();
102: }
103: } else {
104: $this->resetAuthInfo();
105:
106: $userId = $this->preAuthorize();
107: if ($userId !== false) {
108: $this->_setAuthInfo($userId);
109:
110: return;
111: }
112:
113: if ($this->_defaultNobody == true) {
114: $this->_setAuthInfo(self::AUTH_UID_NOBODY, 0x7fffffff);
115: } else {
116: $this->_fetchLoginForm();
117: }
118: }
119: }
120:
121: /**
122: * Restarts the authentication process.
123: */
124: public function restart() {
125: $this->resetAuthInfo();
126: $this->_defaultNobody = false;
127: $this->start();
128: }
129:
130: /**
131: * Resets the global authentication information.
132: *
133: * @param bool $nobody If flag set to true, the default authentication is
134: * switched to nobody. (optional, default: false)
135: */
136: public function resetAuthInfo($nobody = false) {
137: $this->auth['uid'] = ($nobody == false ? '' : self::AUTH_UID_NOBODY);
138: $this->auth['perm'] = '';
139:
140: $this->_setExpiration($nobody == false ? 0 : 0x7fffffff);
141: }
142:
143: /**
144: * Logs out the current user, resets the auth information and freezes the
145: * session.
146: *
147: * @param bool $nobody If flag set to true, nobody is recreated as user.
148: *
149: * @return bool true
150: */
151: public function logout($nobody = false) {
152: $sess = cRegistry::getSession();
153:
154: $sess->unregister('auth');
155: unset($this->auth['uname']);
156:
157: $this->resetAuthInfo($nobody == false ? $this->_defaultNobody : $nobody);
158: $sess->freeze();
159:
160: return true;
161: }
162:
163: /**
164: * Getter for the auth information.
165: * @return array auth information
166: */
167: public function getAuthInfo() {
168: return $this->auth;
169: }
170:
171: /**
172: * Checks, if user is authenticated (NOT logged in!).
173: * @return bool
174: */
175: public function isAuthenticated() {
176: $authInfo = $this->getAuthInfo();
177:
178: if (isset($authInfo['uid']) && $authInfo['uid'] && (($this->_lifetime <= 0) || (time() < $authInfo['exp']))) {
179: return $authInfo['uid'];
180: } else {
181: return false;
182: }
183: }
184:
185: /**
186: * Checks, if user is currently in login form mode.
187: * @return bool
188: */
189: public function isLoginForm() {
190: $authInfo = $this->getAuthInfo();
191:
192: return (isset($authInfo['uid']) && $authInfo['uid'] == self::AUTH_UID_FORM);
193: }
194:
195: /**
196: * Sets or refreshs the expiration of the authentication.
197: *
198: * @param int $expiration new expiration (optional, default: null = current
199: * time plus lifetime minutes)
200: */
201: protected function _setExpiration($expiration = NULL) {
202: if ($expiration === NULL) {
203: $expiration = time() + (60 * $this->_lifetime);
204: }
205:
206: $this->auth['exp'] = $expiration;
207: }
208:
209: /**
210: * Sets the authentication info for a user.
211: *
212: * @param string $userId user ID to set
213: * @param int $expiration expiration (optional, default: null)
214: */
215: protected function _setAuthInfo($userId, $expiration = NULL) {
216: $this->auth['uid'] = $userId;
217: $this->_setExpiration($expiration);
218: }
219:
220: /**
221: * Fetches the login form.
222: */
223: protected function _fetchLoginForm() {
224: $sess = cRegistry::getSession();
225:
226: $this->_setAuthInfo(self::AUTH_UID_FORM, 0x7fffffff);
227: $this->displayLoginForm();
228:
229: $sess->freeze();
230: exit();
231: }
232: }
233: