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