fix js error that broke client side validation
[openemr.git] / library / auth.inc
blob3889a7b3cf795c1a889235a1e0eae73ea4467632
1 <?php
2 /**
3  * Authorization functions.
4  *
5  * LICENSE: This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
15  *
16  * @package OpenEMR
17  * @author  Rod Roark <rod@sunsetsystems.com>
18  * @author  Brady Miller <brady.g.miller@gmail.com>
19  * @author  Kevin Yeh <kevin.y@integralemr.com>
20  * @author  ViCarePlus <visolve_emr@visolve.com>
21  * @author  cfapress
22  * @link    http://www.open-emr.org
23  */
25 //----------THINGS WE ALWAYS DO
27 require_once("{$GLOBALS['srcdir']}/log.inc");
28 // added for the phpGACL group check -- JRM
29 require_once("{$GLOBALS['srcdir']}/acl.inc");
30 require_once("$srcdir/authentication/login_operations.php");
32 $incoming_site_id = '';
34 if (isset($_GET['auth']) && ($_GET['auth'] == "login") && isset($_POST['authUser']) &&
35     isset($_POST['clearPass']) && isset($_POST['authProvider'])) {
36     $clearPass=$_POST['clearPass'];
37     // set the language
38     if (!empty($_POST['languageChoice'])) {
39         $_SESSION['language_choice'] = $_POST['languageChoice'];
40     } else {
41         $_SESSION['language_choice'] = 1;
42     }
44     // set language direction according to language choice. Later in globals.php we'll override main theme name if needed.
45     $_SESSION['language_direction'] = getLanguageDir($_SESSION['language_choice']);
47     if (!validate_user_password($_POST['authUser'], $clearPass, $_POST['authProvider']) ||  !verify_user_gacl_group($_POST['authUser'])) {
48         $_SESSION['loginfailure'] = 1;
49         authLoginScreen();
50     }
52 //If password expiration option is enabled call authCheckExpired() to check whether login user password is expired or not
54     if ($GLOBALS['password_expiration_days'] != 0) {
55         if (authCheckExpired($_POST['authUser'])) {
56             authLoginScreen();
57         }
58     }
60     $ip=$_SERVER['REMOTE_ADDR'];
61     $_SESSION['loginfailure'] = null;
62     unset($_SESSION['loginfailure']);
63     //store the very first initial timestamp for timeout errors
64     $_SESSION["last_update"] = time();
65 } else if ((isset($_GET['auth'])) && ($_GET['auth'] == "logout")) {
66     newEvent("logout", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "success");
67     authCloseSession();
68     authLoginScreen(true);
69 } else {
70     if (authCheckSession()) {
71         if (isset($_SESSION['pid']) && empty($GLOBALS['DAEMON_FLAG'])) {
72             require_once("{$GLOBALS['srcdir']}/patient.inc");
73             /**
74             $logpatient = getPatientData($_SESSION['pid'], "lname, fname, mname");
75             newEvent("view", $_SESSION['authUser'], $_SESSION['authProvider'],
76                 "{$logpatient['lname']}, {$logpatient['fname']} {$logpatient['mname']} :: encounter " .
77                 $_SESSION['encounter']);
78             **/
79         }
81         //LOG EVERYTHING
82         //newEvent("view", $_SESSION['authUser'], $_SESSION['authProvider'], $_SERVER['REQUEST_URI']);
83     } else {
84         newEvent("login", $_POST['authUser'], $_POST['authProvider'], 0, "insufficient data sent");
85         authLoginScreen();
86     }
89 if (!isset($_SESSION["last_update"])) {
90     authLoginScreen();
91 } else {
92      //if page has not been updated in a given period of time, we call login screen
93      //--Note can't perform nice logout if skip_timeout_reset is set since these are called
94      //via ajax scripts where this output is not getting sent to browser.
95      //--Note DAEMON_FLAG is ok because it is run from a frame in the browser.
96     if (((time() - $_SESSION["last_update"]) > $timeout) && empty($_REQUEST['skip_timeout_reset'])) {
97         newEvent("logout", $_SESSION['authUser'], $_SESSION['authProvider'], 0, "timeout");
98         authCloseSession();
99         authLoginScreen(true);
100     } else {
101         // Have a mechanism to skip the timeout reset mechanism if a skip_timeout_reset parameter exists. This
102         //  can be used by scripts that continually request information from the server; for example the Messages
103         //  and Reminders automated intermittent requests that happen in the Messages Center script and in
104         //  the left navigation menu script.
105         if (empty($GLOBALS['DAEMON_FLAG']) && empty($_REQUEST['skip_timeout_reset'])) {
106             $_SESSION["last_update"] = time();
107         }
108     }
113 //----------THINGS WE DO IF WE STILL LIKE YOU
115 function authCheckSession()
117     if (isset($_SESSION['authId'])) {
118          // If active directory was used, check a different session variable (as there is no password in database).
119         if ($GLOBALS['use_active_directory']) {
120             if ($_SESSION['active_directory_auth']) {
121                 return true;
122             } else {
123                 return false;
124             }
125         }
127         $authDB = privQuery("select ".implode(",", array(TBL_USERS.".".COL_ID,
128                                                         TBL_USERS.".".COL_UNM,
129                                                         TBL_USERS_SECURE.".".COL_PWD,
130                                                         TBL_USERS_SECURE.".".COL_ID))
131                 . " FROM ". implode(",", array(TBL_USERS,TBL_USERS_SECURE))
132                 . " WHERE ". TBL_USERS.".".COL_ID." = ? "
133                 . " AND ". TBL_USERS.".".COL_UNM . "=" . TBL_USERS_SECURE.".".COL_UNM
134                 . " AND ". TBL_USERS.".".COL_ACTIVE . "=1", array($_SESSION['authId']));
135         if ($_SESSION['authUser'] == $authDB['username']
136             && $_SESSION['authPass'] == $authDB['password'] ) {
137             return true;
138         } else {
139             return false;
140         }
141     } else {
142         return false;
143     }
146 function authCloseSession()
148   // Before destroying the session, save its site_id so that the next
149   // login will default to that same site.
150     global $incoming_site_id;
151     $incoming_site_id = $_SESSION['site_id'];
152     ob_start();
153     session_unset();
154     session_destroy();
155     unset($_COOKIE[session_name()]);
158 function authLoginScreen($timed_out = false)
160   // See comment in authCloseSession().
161     global $incoming_site_id;
163 <script>
164  // Find the top level window for this instance of OpenEMR, set a flag indicating
165  // session timeout has occurred, and reload the login page into it.  This is so
166  // that beforeunload event handlers will not obstruct the process in this case.
167  var w = window;
168  while (w.opener) { // in case we are in a dialog window
169   var wtmp = w;
170   w = w.opener;
171   wtmp.close();
173 <?php if ($timed_out) { ?>
174  w.top.timed_out = true;
175 <?php } ?>
176  w.top.location.href = '<?php echo "{$GLOBALS['login_screen']}?error=1&site=$incoming_site_id"; ?>';
177 </script>
178 <?php
179   exit;
182 // Check if the user's password has expired beyond the grace limit.
183 // If so, deactivate the user
184 function authCheckExpired($user)
186     $result = sqlStatement("select pwd_expiration_date from users where username = ?", array($user));
187     if ($row = sqlFetchArray($result)) {
188         $pwd_expires = $row['pwd_expiration_date'];
189     }
191     $current_date = date("Y-m-d");
192     if ($pwd_expires != "0000-00-00") {
193         $grace_time1 = date("Y-m-d", strtotime($pwd_expires . "+".$GLOBALS['password_grace_time'] ."days"));
194     }
196     if (($grace_time1 != "") && strtotime($current_date) > strtotime($grace_time1)) {
197         sqlStatement("update users set active=0 where username = ?", array($user));
198         $_SESSION['loginfailure'] = 1;
199         return true;
200     }
202     return false;
205 function getUserList($cols = '*', $limit = 'all', $start = '0')
207     if ($limit = "all") {
208         $rez = sqlStatement("select $cols from users where username != '' order by date DESC");
209     } else {
210         $rez = sqlStatement("select $cols from users where username != '' order by date DESC limit $limit, $start");
211     }
213     for ($iter = 0; $row = sqlFetchArray($rez); $iter++) {
214         $tbl[$iter] = $row;
215     }
217     return $tbl;
220 function getProviderList($cols = '*', $limit = 'all', $start = '0')
222     if ($limit = "all") {
223         $rez = sqlStatement("select $cols from groups order by date DESC");
224     } else {
225         $rez = sqlStatement("select $cols from groups order by date DESC limit $limit, $start");
226     }
228     for ($iter = 0; $row = sqlFetchArray($rez); $iter++) {
229         $tbl[$iter] = $row;
230     }
232     return $tbl;
235 function addGroup($groupname)
237     return sqlInsert("insert into groups (name) values (?)", array($groupname));
240 function delGroup($group_id)
242     return sqlQuery("delete from groups where id = ? limit 0,1", array($group_id));
245 /***************************************************************
246 //pennfirm
247 //Function currently user by new post calendar code to determine
248 //if a given user is in a group with another user
249 //and if so to allow editing of that users events
251 //*************************************************************/
253 function validateGroupStatus($user_to_be_checked, $group_user)
255     if (isset($user_to_be_checked) && isset($group_user)) {
256         if ($user_to_be_checked == $group_user) {
257             return true;
258         } elseif ($_SESSION['authorizeduser'] == 1) {
259             return true;
260         }
262         $query = "SELECT groups.name FROM users,groups WHERE users.username = ? " .
263                  "AND users.username = groups.user group by groups.name";
264         $result = sqlStatement($query, array($user_to_be_checked));
266         $usertbcGroups = array();
268         while ($row = sqlFetchArray($result)) {
269             $usertbcGroups[] = $row[0];
270         }
272         $query = "SELECT groups.name FROM users,groups WHERE users.username =  ? " .
273                  "AND users.username = groups.user group by groups.name";
274         $result = sqlStatement($query, array($group_user));
276         $usergGroups = array();
278         while ($row = sqlFetchArray($result)) {
279             $usergGroups[] = $row[0];
280         }
282         foreach ($usertbcGroups as $group) {
283             if (in_array($group, $usergGroups)) {
284                 return true;
285             }
286         }
287     }
289     return false;
293 // Attempt to update the user's password, password history, and password expiration.
294 // Verify that the new password does not match the last three passwords used.
295 // Return true if successfull, false on failure
296 function UpdatePasswordHistory($userid, $pwd)
298     $result = sqlStatement("select password, pwd_history1, pwd_history2 from users where id = ?", array($userid));
299     if ($row = sqlFetchArray($result)) {
300         $previous_pwd1=$row['password'];
301         $previous_pwd2=$row['pwd_history1'];
302         $previous_pwd3=$row['pwd_history2'];
303     }
305     if (($pwd != $previous_pwd1) && ($pwd != $previous_pwd2) && ($pwd != $previous_pwd3)) {
306         sqlStatement("update users set pwd_history2=?, pwd_history1=?,password=? where id=?", array($previous_pwd2,$previous_pwd1,$pwd,$userid));
307         if ($GLOBALS['password_expiration_days'] != 0) {
308             $exp_days=$GLOBALS['password_expiration_days'];
309             $exp_date = date('Y-m-d', strtotime("+$exp_days days"));
310             sqlStatement("update users set pwd_expiration_date=? where id=?", array($exp_date,$userid));
311         }
313         return true;
314     } else {
315         return false;
316     }