more organization of autoloaded files (#424)
[openemr.git] / library / auth.inc
bloba7858a8cbb33c734f1606d961e84fa466ce703e8
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@sparmy.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']))
37     $clearPass=$_POST['clearPass'];
38     // set the language
39     if (!empty($_POST['languageChoice'])) {
40         $_SESSION['language_choice'] = $_POST['languageChoice'];
41     }
42     else {
43         $_SESSION['language_choice'] = 1;
44     }
45     // set language direction according to language choice. Later in globals.php we'll override main theme name if needed.
46     $_SESSION['language_direction'] = getLanguageDir($_SESSION['language_choice']  );
48     if(!validate_user_password($_POST['authUser'],$clearPass,$_POST['authProvider']) ||  !verify_user_gacl_group($_POST['authUser']))
49     {
50         $_SESSION['loginfailure'] = 1;
51         authLoginScreen();
52     }
53 //If password expiration option is enabled call authCheckExpired() to check whether login user password is expired or not
55     if($GLOBALS['password_expiration_days'] != 0){
56         if(authCheckExpired($_POST['authUser']))
57         {
58             authLoginScreen();
59         }
60     }
61     $ip=$_SERVER['REMOTE_ADDR'];
62     $_SESSION['loginfailure'] = null;
63     unset($_SESSION['loginfailure']);
64     //store the very first initial timestamp for timeout errors
65     $_SESSION["last_update"] = time();
67 else if ( (isset($_GET['auth'])) && ($_GET['auth'] == "logout") )
69     newEvent("logout", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "success");
70     authCloseSession();
71     authLoginScreen(true);
73 else
75     if (authCheckSession())
76     {
77         if (isset($_SESSION['pid']) && empty($GLOBALS['DAEMON_FLAG']))
78         {
79             require_once("{$GLOBALS['srcdir']}/patient.inc");
80             /**
81             $logpatient = getPatientData($_SESSION['pid'], "lname, fname, mname");
82             newEvent("view", $_SESSION['authUser'], $_SESSION['authProvider'],
83                 "{$logpatient['lname']}, {$logpatient['fname']} {$logpatient['mname']} :: encounter " .
84                 $_SESSION['encounter']);
85             **/
86         }
87         //LOG EVERYTHING
88         //newEvent("view", $_SESSION['authUser'], $_SESSION['authProvider'], $_SERVER['REQUEST_URI']);
89     }
90     else {
91         newEvent("login",$_POST['authUser'], $_POST['authProvider'], 0, "insufficient data sent");
92         authLoginScreen();
93     }
96 if (!isset($_SESSION["last_update"])) {
97     authLoginScreen();
98 } else {
99      //if page has not been updated in a given period of time, we call login screen
100      //--Note can't perform nice logout if skip_timeout_reset is set since these are called
101      //via ajax scripts where this output is not getting sent to browser.
102      //--Note DAEMON_FLAG is ok because it is run from a frame in the browser.
103     if ( ((time() - $_SESSION["last_update"]) > $timeout) && empty($_REQUEST['skip_timeout_reset']) ) {
104         newEvent("logout", $_SESSION['authUser'], $_SESSION['authProvider'], 0, "timeout");
105         authCloseSession();
106         authLoginScreen(true);
107     } else {
108         // Have a mechanism to skip the timeout reset mechanism if a skip_timeout_reset parameter exists. This
109         //  can be used by scripts that continually request information from the server; for example the Messages
110         //  and Reminders automated intermittent requests that happen in the Messages Center script and in
111         //  the left navigation menu script.
112         if (empty($GLOBALS['DAEMON_FLAG']) && empty($_REQUEST['skip_timeout_reset'])) $_SESSION["last_update"] = time();
113     }
118 //----------THINGS WE DO IF WE STILL LIKE YOU
120 function authCheckSession ()
122     if (isset($_SESSION['authId'])) {
123         $authDB = privQuery("select ".implode(",",array(TBL_USERS.".".COL_ID,
124                                                         TBL_USERS.".".COL_UNM,
125                                                         TBL_USERS_SECURE.".".COL_PWD,
126                                                         TBL_USERS_SECURE.".".COL_ID))
127                 . " FROM ". implode(",",array(TBL_USERS,TBL_USERS_SECURE))
128                 . " WHERE ". TBL_USERS.".".COL_ID." = ? "
129                 . " AND ". TBL_USERS.".".COL_UNM . "=" . TBL_USERS_SECURE.".".COL_UNM
130                 . " AND ". TBL_USERS.".".COL_ACTIVE . "=1"
131                 ,array($_SESSION['authId']));
132         if ($_SESSION['authUser'] == $authDB['username']
133             && $_SESSION['authPass'] == $authDB['password'] )
134         {
135             return true;
136         }
137         else {
138             return false;
139         }
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   {
189     $pwd_expires = $row['pwd_expiration_date'];
190   }
191   $current_date = date("Y-m-d");
192   if($pwd_expires != "0000-00-00")
193   {
194     $grace_time1 = date("Y-m-d", strtotime($pwd_expires . "+".$GLOBALS['password_grace_time'] ."days"));
195   }
196   if(($grace_time1 != "") && strtotime($current_date) > strtotime($grace_time1))
197   {
198     sqlStatement("update users set active=0 where username = ?",array($user));
199     $_SESSION['loginfailure'] = 1;
200     return true;
201   }
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     for ($iter = 0; $row = sqlFetchArray($rez); $iter++)
212         $tbl[$iter] = $row;
213     return $tbl;
216 function getProviderList ($cols = '*', $limit= 'all', $start = '0')
218     if ($limit = "all")
219         $rez = sqlStatement("select $cols from groups order by date DESC");
220     else
221         $rez = sqlStatement("select $cols from groups order by date DESC limit $limit, $start");
222     for ($iter = 0; $row = sqlFetchArray($rez); $iter++)
223         $tbl[$iter] = $row;
224     return $tbl;
227 function addGroup ($groupname)
229     return sqlInsert("insert into groups (name) values (?)", array($groupname));
232 function delGroup ($group_id)
234     return sqlQuery("delete from groups where id = ? limit 0,1", array($group_id));
237 /***************************************************************
238 //pennfirm
239 //Function currently user by new post calendar code to determine
240 //if a given user is in a group with another user
241 //and if so to allow editing of that users events
243 //*************************************************************/
245 function validateGroupStatus ($user_to_be_checked, $group_user) {
246     if (isset($user_to_be_checked) && isset($group_user)) {
247         if ($user_to_be_checked == $group_user) {
249             return true;
250         }
251         elseif ($_SESSION['authorizeduser'] == 1)
252             return true;
254         $query = "SELECT groups.name FROM users,groups WHERE users.username = ? " .
255                  "AND users.username = groups.user group by groups.name";
256         $result = sqlStatement($query, array($user_to_be_checked));
258         $usertbcGroups = array();
260         while ($row = sqlFetchArray($result)) {
261             $usertbcGroups[] = $row[0];
262         }
264         $query = "SELECT groups.name FROM users,groups WHERE users.username =  ? " .
265                  "AND users.username = groups.user group by groups.name";
266         $result = sqlStatement($query, array($group_user));
268         $usergGroups = array();
270         while ($row = sqlFetchArray($result)) {
271             $usergGroups[] = $row[0];
272         }
273         foreach ($usertbcGroups as $group) {
274               if(in_array($group,$usergGroups)) {
275               return true;
276             }
277         }
279     }
281     return false;
285 // Attempt to update the user's password, password history, and password expiration.
286 // Verify that the new password does not match the last three passwords used.
287 // Return true if successfull, false on failure
288 function UpdatePasswordHistory($userid,$pwd)
290     $result = sqlStatement("select password, pwd_history1, pwd_history2 from users where id = ?",array($userid));
291     if ($row = sqlFetchArray($result)) {
292         $previous_pwd1=$row['password'];
293         $previous_pwd2=$row['pwd_history1'];
294         $previous_pwd3=$row['pwd_history2'];
295     }
296     if (($pwd != $previous_pwd1) && ($pwd != $previous_pwd2) && ($pwd != $previous_pwd3)) {
297         sqlStatement("update users set pwd_history2=?, pwd_history1=?,password=? where id=?",array($previous_pwd2,$previous_pwd1,$pwd,$userid));
298         if($GLOBALS['password_expiration_days'] != 0){
299         $exp_days=$GLOBALS['password_expiration_days'];
300         $exp_date = date('Y-m-d', strtotime("+$exp_days days"));
301         sqlStatement("update users set pwd_expiration_date=? where id=?",array($exp_date,$userid));
302         }
303         return true;
304     }
305     else {
306         return false;
307     }