source: trunk/lib/Auth_Simple.inc.php @ 693

Last change on this file since 693 was 690, checked in by anonymous, 5 years ago

Remove App's 'ssl_domain' and 'ssl_enabled' parameters; determine SSL usage by detecting the presence of HTTPS env var (or HTTP_X_FORWARDED_PROTO). Update Session parameters for greater logevity and security. Add 'session_dir' to store site-specific sess_* files with a longer gc_maxlifetime duration.

File size: 9.3 KB
Line 
1<?php
2/*
3* Auth_Simple.inc
4* Code by Strangecode :: www.strangecode.com :: This document contains copyrighted information.
5* @author   Quinn Comendant <quinn@strangecode.com>
6* @version  1.0
7* @since    04 Mar 2009 21:59:03
8*/
9
10class Auth_Simple {
11
12    // Namespace of this auth object.
13    var $_ns;
14
15    // Parameters to be configured by setParam.
16    var $_params = array();
17    var $_default_params = array(
18
19        // The URL to the login script.
20        'login_url' => '/',
21
22        // The maximum amount of time a user is allowed to be logged in. They will be forced to login again if they expire.
23        // In seconds. 21600 seconds = 6 hours.
24        'login_timeout' => 21600,
25
26        // The maximum amount of time a user is allowed to be idle before their session expires. They will be forced to login again if they expire.
27        // In seconds. 3600 seconds = 1 hour.
28        'idle_timeout' => 3600,
29    );
30
31    /**
32     * Constructs a new authentication object.
33     *
34     * @access public
35     * @param optional array $params  A hash containing parameters.
36     */
37    function Auth_Simple($namespace='')
38    {
39        $app =& App::getInstance();
40
41        $this->_ns = $namespace;
42
43        // Initialize default parameters.
44        $this->setParam($this->_default_params);
45
46        // Get create tables config from global context.
47        if (!is_null($app->getParam('db_create_tables'))) {
48            $this->setParam(array('create_table' => $app->getParam('db_create_tables')));
49        }
50
51        if (!isset($_SESSION['_auth_simple'][$this->_ns])) {
52            $this->clear();
53        }
54    }
55
56    /**
57     * Set the params of an auth object.
58     *
59     * @param  array $params   Array of parameter keys and value to set.
60     * @return bool true on success, false on failure
61     */
62    function setParam($params)
63    {
64        if (isset($params) && is_array($params)) {
65            // Merge new parameters with old overriding only those passed.
66            $this->_params = array_merge($this->_params, $params);
67        }
68    }
69
70    /**
71     * Return the value of a parameter, if it exists.
72     *
73     * @access public
74     * @param string $param        Which parameter to return.
75     * @return mixed               Configured parameter value.
76     */
77    function getParam($param)
78    {
79        $app =& App::getInstance();
80
81        if (isset($this->_params[$param])) {
82            return $this->_params[$param];
83        } else {
84            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
85            return null;
86        }
87    }
88
89    /**
90     * Sets a variable into a registered auth session.
91     *
92     * @access public
93     * @param mixed $key      Which value to set.
94     * @param mixed $val      Value to set variable to.
95     */
96    function set($key, $val)
97    {
98        if (!isset($_SESSION['_auth_simple'][$this->_ns]['user_data'])) {
99            $_SESSION['_auth_simple'][$this->_ns]['user_data'] = array();
100        }
101        $_SESSION['_auth_simple'][$this->_ns]['user_data'][$key] = $val;
102    }
103
104    /**
105     * Returns a specified value from a registered auth session.
106     *
107     * @access public
108     * @param mixed $key      Which value to return.
109     * @param mixed $default  Value to return if key not found in user_data.
110     * @return mixed          Value stored in session.
111     */
112    function get($key, $default='')
113    {
114        if (isset($_SESSION['_auth_simple'][$this->_ns][$key])) {
115            return $_SESSION['_auth_simple'][$this->_ns][$key];
116        } else if (isset($_SESSION['_auth_simple'][$this->_ns]['user_data'][$key])) {
117            return $_SESSION['_auth_simple'][$this->_ns]['user_data'][$key];
118        } else {
119            return $default;
120        }
121    }
122
123    /**
124     * Clear any authentication tokens in the current session. A.K.A. logout.
125     *
126     * @access public
127     */
128    function clear()
129    {
130        $_SESSION['_auth_simple'][$this->_ns] = array('authenticated' => false);
131    }
132
133    /*
134    * Runs a full login sequence: clear old session, validate auth, create session.
135    *
136    * @access   public
137    * @param    int     $user_id     User ID.
138    * @return   mixed                   False on failure, true on success.
139    * @author   Quinn Comendant <quinn@strangecode.com>
140    * @version  1.0
141    * @since    04 Mar 2009 21:07:33
142    */
143    function login($user_id, $password, $callback)
144    {
145        global $acct;
146
147        $app =& App::getInstance();
148
149        $this->clear();
150
151        if (!is_callable($callback)) {
152            $app->logMsg(sprintf('Not callable: %s', getDump($callable)), LOG_ERR, __FILE__, __LINE__);
153            return false;
154        }
155
156        if (!call_user_func($callback, $user_id, $password)) {
157            $app->logMsg(sprintf('Authentication failed for user_id: %s', $user_id), LOG_NOTICE, __FILE__, __LINE__);
158            return false;
159        }
160
161        $app->logMsg(sprintf('Authentication successful for user_id: %s', $user_id), LOG_INFO, __FILE__, __LINE__);
162        return $this->createSession($user_id);
163    }
164
165
166    /*
167    *
168    *
169    * @access   public
170    * @param
171    * @return
172    * @author   Quinn Comendant <quinn@strangecode.com>
173    * @version  1.0
174    * @since    04 Mar 2009 21:07:33
175    */
176    function createSession($user_id)
177    {
178        $app =& App::getInstance();
179
180        // Register authenticated session.
181        $_SESSION['_auth_simple'][$this->_ns] = array(
182            'authenticated'         => true,
183            'user_id'               => $user_id,
184            'login_datetime'        => date('Y-m-d H:i:s'),
185            'last_access_datetime'  => date('Y-m-d H:i:s'),
186            'remote_ip'             => getRemoteAddr(),
187        );
188
189        return true;
190    }
191
192    /*
193    *
194    *
195    * @access   public
196    * @param
197    * @return
198    * @author   Quinn Comendant <quinn@strangecode.com>
199    * @version  1.0
200    * @since    04 Mar 2009 21:10:41
201    */
202    function isLoggedIn()
203    {
204        $app =& App::getInstance();
205
206        // Test login with information stored in session. Skip IP matching for users from trusted networks.
207        if (isset($_SESSION['_auth_simple'][$this->_ns]['authenticated'])
208            && true === $_SESSION['_auth_simple'][$this->_ns]['authenticated']
209            && !empty($_SESSION['_auth_simple'][$this->_ns]['user_id'])
210            && strtotime($_SESSION['_auth_simple'][$this->_ns]['login_datetime']) > time() - $this->_params['login_timeout']
211            && strtotime($_SESSION['_auth_simple'][$this->_ns]['last_access_datetime']) > time() - $this->_params['idle_timeout']
212        ) {
213            // User is authenticated!
214            $_SESSION['_auth_simple'][$this->_ns]['last_access_datetime'] = date('Y-m-d H:i:s');
215            return true;
216        } else if (isset($_SESSION['_auth_simple'][$this->_ns]['authenticated']) && true === $_SESSION['_auth_simple'][$this->_ns]['authenticated']) {
217            // User is authenticated, but login has expired.
218            if (strtotime($_SESSION['_auth_simple'][$this->_ns]['last_access_datetime']) > time() - 43200) {
219                // Only raise message if last session is less than 12 hours old.
220                // TODO: Can we move this message to requireLogin() so it doesn't display unless the user expects it to?
221                // $app->raiseMsg(_("Your session has expired. You need to log-in again."), MSG_NOTICE, __FILE__, __LINE__);
222            }
223            // Log the reason for login expiration.
224            $expire_reasons = array();
225            if (empty($_SESSION['_auth_simple'][$this->_ns]['user_id'])) {
226                $expire_reasons[] = 'user_id not found';
227            }
228            if (strtotime($_SESSION['_auth_simple'][$this->_ns]['login_datetime']) <= time() - $this->_params['login_timeout']) {
229                $expire_reasons[] = 'login_timeout expired';
230            }
231            if (strtotime($_SESSION['_auth_simple'][$this->_ns]['last_access_datetime']) <= time() - $this->_params['idle_timeout']) {
232                $expire_reasons[] = 'idle_timeout expired';
233            }
234            $app->logMsg(sprintf('user_id %s session expired: %s', $this->get('user_id'), join(', ', $expire_reasons)), LOG_INFO, __FILE__, __LINE__);
235        }
236
237        // User is not authenticated.
238        $this->clear();
239        return false;
240    }
241
242    /**
243     * Redirect user to login page if they are not logged in.
244     *
245     * @param string $message The text description of a message to raise.
246     * @param int    $type    The type of message: MSG_NOTICE,
247     *                        MSG_SUCCESS, MSG_WARNING, or MSG_ERR.
248     * @param string $file    __FILE__.
249     * @param string $line    __LINE__.
250     * @access public
251     */
252    function requireLogin($message='', $type=MSG_NOTICE, $file=null, $line=null)
253    {
254        $app =& App::getInstance();
255
256        if (!$this->isLoggedIn()) {
257            // Display message for requiring login. (RaiseMsg will ignore empty strings.)
258            if ('' != $message) {
259                $app->raiseMsg($message, $type, $file, $line);
260            }
261
262            // Login scripts must have the same 'login' tag for boomerangURL verification/manipulation.
263            $app->setBoomerangURL(getenv('REQUEST_URI'), 'login');
264            $app->dieURL($this->_params['login_url']);
265        }
266    }
267
268    /**
269     * Stub method to fulfill requirements by Version()
270     *
271     * @param  string   $null
272     * @return string   Empty string
273     */
274    function getUsername($null=null)
275    {
276        return '';
277    }
278}
279
280?>
Note: See TracBrowser for help on using the repository browser.