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: /**
27: * Authentification user ID for nobody.
28: *
29: * @var string
30: */
31: const AUTH_UID_NOBODY = 'nobody';
32:
33: /**
34: * Authentification user ID for calling login form.
35: *
36: * @var string
37: */
38: const AUTH_UID_FORM = 'form';
39:
40: /**
41: * The global auth information array.
42: *
43: * @var array
44: */
45: public $auth = array();
46:
47: /**
48: * Lifetime for authenticated users in minutes.
49: * After that time the authentication expires.
50: *
51: * @var integer
52: */
53: protected $_lifetime = 15;
54:
55: /**
56: * Automatic authentication as nobody.
57: *
58: * @var bool
59: */
60: protected $_defaultNobody = false;
61:
62: /**
63: * The "in flag".
64: * Nobody knows, for which reason it exists.
65: *
66: * @var bool
67: */
68: private $_in = false;
69:
70: /**
71: * Magic getter function for outdated variable names.
72: *
73: * @param string $name name of the variable
74: *
75: * @return mixed
76: */
77: public function __get($name) {
78: if ($name == 'lifetime') {
79: return $this->_lifetime;
80: }
81:
82: if ($name == 'persistent_slots') {
83: return array(
84: "auth"
85: );
86: }
87:
88: if ($name == 'classname') {
89: return get_class($this);
90: }
91: }
92:
93: /**
94: * Starts the authentication process.
95: */
96: public function start() {
97: $sess = cRegistry::getSession();
98: if (!$this->_in) {
99: $sess->register('auth');
100: $this->_in = true;
101: }
102:
103: if ($this->isAuthenticated()) {
104: $authInfo = $this->getAuthInfo();
105: $userId = $authInfo['uid'];
106: if ($userId == self::AUTH_UID_FORM) {
107: $userId = $this->validateCredentials();
108: if ($userId !== false) {
109: $this->_setAuthInfo($userId);
110: $this->logSuccessfulAuth();
111: } else {
112: $this->_fetchLoginForm();
113: }
114: } elseif ($userId != self::AUTH_UID_NOBODY) {
115: $this->_setExpiration();
116: }
117: } else {
118: $this->resetAuthInfo();
119:
120: $userId = $this->preAuthorize();
121: if ($userId !== false) {
122: $this->_setAuthInfo($userId);
123:
124: return;
125: }
126:
127: if ($this->_defaultNobody == true) {
128: $this->_setAuthInfo(self::AUTH_UID_NOBODY, 0x7fffffff);
129: } else {
130: $this->_fetchLoginForm();
131: }
132: }
133: }
134:
135: /**
136: * Restarts the authentication process.
137: */
138: public function restart() {
139: $this->resetAuthInfo();
140: $this->_defaultNobody = false;
141: $this->start();
142: }
143:
144: /**
145: * Resets the global authentication information.
146: *
147: * @param bool $nobody If flag set to true, the default authentication is
148: * switched to nobody. (optional, default: false)
149: */
150: public function resetAuthInfo($nobody = false) {
151: $this->auth['uid'] = ($nobody == false? '' : self::AUTH_UID_NOBODY);
152: $this->auth['perm'] = '';
153:
154: $this->_setExpiration($nobody == false? 0 : 0x7fffffff);
155: }
156:
157: /**
158: * Logs out the current user, resets the auth information and freezes the
159: * session.
160: *
161: * @param bool $nobody If flag set to true, nobody is recreated as user.
162: *
163: * @return bool true
164: */
165: public function logout($nobody = false) {
166: $sess = cRegistry::getSession();
167:
168: $sess->unregister('auth');
169: unset($this->auth['uname']);
170:
171: $this->resetAuthInfo($nobody == false? $this->_defaultNobody : $nobody);
172: $sess->freeze();
173:
174: return true;
175: }
176:
177: /**
178: * Getter for the auth information.
179: *
180: * @return array
181: */
182: public function getAuthInfo() {
183: return $this->auth;
184: }
185:
186: /**
187: * Checks, if user is authenticated (NOT logged in!).
188: *
189: * @return bool
190: */
191: public function isAuthenticated() {
192: $authInfo = $this->getAuthInfo();
193:
194: if (isset($authInfo['uid']) && $authInfo['uid'] && (($this->_lifetime <= 0) || (time() < $authInfo['exp']))) {
195: return $authInfo['uid'];
196: } else {
197: return false;
198: }
199: }
200:
201: /**
202: * Checks, if user is currently in login form mode.
203: *
204: * @return bool
205: */
206: public function isLoginForm() {
207: $authInfo = $this->getAuthInfo();
208:
209: return (isset($authInfo['uid']) && $authInfo['uid'] == self::AUTH_UID_FORM);
210: }
211:
212: /**
213: * Sets or refreshs the expiration of the authentication.
214: *
215: * @param int $expiration new expiration (optional, default: NULL = current
216: * time plus lifetime minutes)
217: */
218: protected function _setExpiration($expiration = NULL) {
219: if ($expiration === NULL) {
220: $expiration = time() + (60 * $this->_lifetime);
221: }
222:
223: $this->auth['exp'] = $expiration;
224: }
225:
226: /**
227: * Fetches the login form.
228: */
229: protected function _fetchLoginForm() {
230: $sess = cRegistry::getSession();
231:
232: $this->_setAuthInfo(self::AUTH_UID_FORM, 0x7fffffff);
233:
234: // TODO Method displayLoginForm() is declared in cAuthHandlerAbstract
235: // which is extending this class! Better declare it in this class and
236: // make it abstract!
237: $this->displayLoginForm();
238:
239: $sess->freeze();
240: exit();
241: }
242:
243: /**
244: * Sets the authentication info for a user.
245: *
246: * @param string $userId user ID to set
247: * @param int $expiration expiration (optional, default: NULL)
248: */
249: protected function _setAuthInfo($userId, $expiration = NULL) {
250: $this->auth['uid'] = $userId;
251: $this->_setExpiration($expiration);
252: }
253: }
254: