source: trunk/www/identity.php @ 1184

Revision 1164, 6.6 KB checked in by bogdan2412, 4 months ago (diff)

Make infoarena compatible with HPHP.

  • Implemented APC caching support since eaccelerator is not compatible with HPHP and although we support memcached, we do not use it on live.
  • Replaced instances of create_function_cached with php anonymous functions. This bumps the PHP version requirement to 5.3, but it allows the code to work with HPHP, since dynamic function generation is replaced with staticly analyzable functions. This also removes a horrible, terrible hack in Textile.php which was storing the current instance of the Textile class being processed as a static variable so that it could be accessed by anonymous functions.
  • Replaced occurrences of assert with log_assert.
  • When running under HPHP, IA_HPHP_ENV is defined and is used to bypass some incompatible code (redundant ini configuration checks).
  • Fixed some includes that were dependent on the working directory being www/
  • Included a sample HPHP configuration file and a Makefile with compilation commands.

REVIEW URL: http://reviewboard.infoarena.ro/r/182/

  • Property svn:eol-style set to native
Line 
1<?php
2
3require_once(IA_ROOT_DIR."common/db/user.php");
4require_once(IA_ROOT_DIR."common/security.php");
5
6// This module helps access and manage information about the current remote
7// user, whether it is a visitor (anonymous) or an authenticated user.
8//
9// Additionally, you can perform permission queries to check remote
10// user's permissions to perform actions against some resources.
11
12// ABOUT AUTHENTICATION
13//
14// There are 2 entry points for user authentication
15//  * identity_from_session()   -- restores identity from cookie based session
16//  * identity_from_http()      -- restores identity from HTTP AUTH headers
17//
18// Start a cookie-based sessions via:   identity_start_session(...)
19// End a cookie-based session via:      identity_end_session()
20
21// current remote user, globally accessible
22$identity_user = null;
23
24// Returns whether current user is anonymous
25function identity_is_anonymous() {
26    global $identity_user;
27    return is_null($identity_user);
28}
29
30// Get current user, or null if anonymous.
31function identity_get_user() {
32    global $identity_user;
33    return $identity_user;
34}
35
36// Get user_id for current user, or null if anonymous
37function identity_get_user_id() {
38    global $identity_user;
39    if (is_null($identity_user)) {
40        return null;
41    } else {
42        return $identity_user['id'];
43    }
44}
45
46// Returns remote user's username or NULL if anonymous
47function identity_get_username() {
48    global $identity_user;
49    if (is_null($identity_user)) {
50        return null;
51    } else {
52        return $identity_user['username'];
53    }
54}
55
56// Check whether current user (or any other arbitrary user) can perform
57// a given action (onto an object)
58// This is a wrapper for the more-generic, session-independent permission
59// module.
60function identity_can($action, $object = null) {
61    global $identity_user;
62    return security_query($identity_user, $action, $object);
63}
64
65// Require login first.
66// It makes a lot of sense to separate this from security. No matter what
67// dumb little security.php might say, some things absolutely require login.
68function identity_require_login() {
69    if (identity_is_anonymous()) {
70        flash_error("Mai intai trebuie sa te autentifici.");
71
72        // save current URL. We redirect to here right after logging in
73        $_SESSION['_ia_redirect'] = $_SERVER['REQUEST_URI'];
74        redirect(url_login());
75    }
76}
77
78// This function is similar to identity_can(), except that it automatically
79// redirects to the login page and displays a generic message when faced
80// with insufficient privileges.
81function identity_require($action, $object = null) {
82    $can = identity_can($action, $object);
83    if (!$can) {
84        if (identity_is_anonymous()) {
85            // when user is anonymous, send it to login page
86            // and redirect it back after login
87
88            flash_error("Mai intai trebuie sa te autentifici.");
89            // save current URL. We redirect to here right after logging in
90            $_SESSION['_ia_redirect'] = IA_URL_HOST.$_SERVER['REQUEST_URI'];
91            redirect(url_login());
92        } else {
93            // User doesn't have enough priviledges, tell him to fuck off.
94            flash_error('Nu ai permisiuni suficiente pentru a executa aceasta '
95                        .'actiune! Te redirectez ...');
96            redirect(url_home());
97        }
98    }
99    return $can;
100}
101
102// Initializes long-lived PHP session.
103// When remember user is `true`, it will persist session for
104// IA_SESSION_LIFETIME_SECONDS seconds.
105//
106// Here's a good example why PHP sucks.
107function init_php_session($remember_user = false) {
108    session_name('infoarena_session');
109    ini_set('session.gc_maxlifetime', IA_SESSION_LIFETIME_SECONDS);
110    if ($remember_user) {
111        session_cache_limiter('private');
112        session_cache_expire(IA_SESSION_LIFETIME_SECONDS / 60);
113        session_set_cookie_params(IA_SESSION_LIFETIME_SECONDS, '/', IA_COOKIE_DOMAIN);
114    } else {
115        session_set_cookie_params(0, '/', IA_COOKIE_DOMAIN);
116    }
117    if (defined('IA_HPHP_ENV')) {
118        // FIXME: Raises PHP Warning: Constant SID already defined when
119        // init_php_session is called a second time.
120        @session_start();
121    } else {
122        session_start();
123    }
124}
125
126// identity information from cookie-based session
127// Returns identity (user) object instance
128function identity_from_session() {
129    init_php_session();
130
131    if (isset($_SESSION['_ia_identity'])) {
132        // log_print('Restoring identity from PHP session');
133        $username = $_SESSION['_ia_identity'];
134
135        $identity = user_get_by_username($username);
136        if (!$identity) {
137            log_warn("Closing broken session");
138            identity_end_session();
139        }
140    } else {
141        $identity = null;
142    }
143
144    return $identity;
145}
146
147// Obtain identity information from HTTP AUTH headers
148// Returns identity (user) object instance
149function identity_from_http() {
150    $user = getattr($_SERVER, 'PHP_AUTH_USER');
151    $pass = getattr($_SERVER, 'PHP_AUTH_PW');
152
153    if (!defined("IA_FROM_SMF") && ($user || $pass)) {
154        // somebody is trying to authenticate via HTTP
155        // log_print('Restoring identity from HTTP AUTH headers');
156        $user = user_test_password($user, $pass);
157
158        if (!$user) {
159            log_warn("Invalid HTTP AUTH username/password");
160        }
161
162        return $user;
163    } else {
164        // nobody is trying to authenticate via HTTP
165        return null;
166    }
167}
168
169// Wraps all authentication entry points
170// Return identity_user.
171function identity_restore() {
172    global $identity_user;
173
174    if (!$identity_user) {
175        $identity_user = identity_from_session();
176    }
177
178    if (!$identity_user) {
179        $identity_user = identity_from_http();
180    }
181
182    if ($identity_user) {
183        log_assert(is_array($identity_user) && getattr($identity_user, 'id'),
184                   'Invalid user object, identity code broke!');
185    }
186
187    return $identity_user;
188}
189
190
191// Persists $user to session. This is used when logging in.
192// When $remember_user is true, it will persist session for
193// IA_SESSION_LIFETIME_SECONDS seconds.
194function identity_start_session($user, $remember_user = false) {
195    session_write_close();
196    init_php_session($remember_user);
197    $_SESSION['_ia_identity'] = $user['username'];
198}
199
200// Update session information. Use this if you change data of current
201// remote user.
202function identity_update_session($user) {
203    $_SESSION['_ia_identity'] = $user['username'];
204}
205
206// Terminate session for current user.
207function identity_end_session() {
208    if (isset($_SESSION['_ia_identity'])) {
209        unset($_SESSION['_ia_identity']);
210    }
211    session_write_close();
212    init_php_session();
213}
214
215?>
Note: See TracBrowser for help on using the repository browser.