/** * Execute an sql query in the database. The correct database connection * will be chosen and the query will be logged with the success status. * * @param $query query to execute as string */ function exec_query($query) { global $conn, $kga, $errors, $executed_queries; $success = $conn->Query($query); $errorInfo = serialize($conn->Error()); Logger::logfile($query); if (!$success) { Logger::logfile($errorInfo); $errors = true; } }
/** * Execute an sql query in the database. The correct database connection * will be chosen and the query will be logged with the success status. * * @param $query query to execute as string */ function exec_query($query) { global $database, $errors; $conn = $database->getConnectionHandler(); $success = $conn->Query($query); //Logger::logfile($query); if (!$success) { $errorInfo = serialize($conn->Error()); Logger::logfile('[ERROR] in [' . $query . '] => ' . $errorInfo); $errors = true; } }
function expenseAccessAllowed($entry, $action, &$errors) { global $database, $kga; if (!isset($kga['user'])) { $errors[''] = $kga['lang']['errorMessages']['permissionDenied']; return false; } // check if expense is too far in the past to allow editing (or deleting) if (isset($entry['id']) && $kga['conf']['editLimit'] != "-" && time() - $entry['timestamp'] > $kga['conf']['editLimit']) { $errors[''] = $kga['lang']['editLimitError']; return false; } $groups = $database->getGroupMemberships($entry['userID']); if ($entry['userID'] == $kga['user']['userID']) { $permissionName = 'ki_expenses-ownEntry-' . $action; if ($database->global_role_allows($kga['user']['globalRoleID'], $permissionName)) { return true; } else { Logger::logfile("missing global permission {$permissionName} for user " . $kga['user']['name'] . " to access expense"); $errors[''] = $kga['lang']['errorMessages']['permissionDenied']; return false; } } $assignedOwnGroups = array_intersect($groups, $database->getGroupMemberships($kga['user']['userID'])); if (count($assignedOwnGroups) > 0) { $permissionName = 'ki_expenses-otherEntry-ownGroup-' . $action; if ($database->checkMembershipPermission($kga['user']['userID'], $assignedOwnGroups, $permissionName)) { return true; } else { Logger::logfile("missing membership permission {$permissionName} of own group(s) " . implode(", ", $assignedOwnGroups) . " for user " . $kga['user']['name']); $errors[''] = $kga['lang']['errorMessages']['permissionDenied']; return false; } } $permissionName = 'ki_expenses-otherEntry-otherGroup-' . $action; if ($database->global_role_allows($kga['user']['globalRoleID'], $permissionName)) { return true; } else { Logger::logfile("missing global permission {$permissionName} for user " . $kga['user']['name'] . " to access expense"); $errors[''] = $kga['lang']['errorMessages']['permissionDenied']; return false; } }
/** * create exp entry * * @param integer $id ID of record * @param integer $data array with record data * @global array $kga kimai-global-array * @author sl */ function expense_create($userID, $data) { global $kga, $database; $conn = $database->getConnectionHandler(); $data = $database->clean_data($data); $values['projectID'] = MySQL::SQLValue($data['projectID'], MySQL::SQLVALUE_NUMBER); $values['designation'] = MySQL::SQLValue($data['designation']); $values['comment'] = MySQL::SQLValue($data['comment']); $values['commentType'] = MySQL::SQLValue($data['commentType'], MySQL::SQLVALUE_NUMBER); $values['timestamp'] = MySQL::SQLValue($data['timestamp'], MySQL::SQLVALUE_NUMBER); $values['multiplier'] = MySQL::SQLValue($data['multiplier'], MySQL::SQLVALUE_NUMBER); $values['value'] = MySQL::SQLValue($data['value'], MySQL::SQLVALUE_NUMBER); $values['userID'] = MySQL::SQLValue($userID, MySQL::SQLVALUE_NUMBER); $values['refundable'] = MySQL::SQLValue($data['refundable'], MySQL::SQLVALUE_NUMBER); $table = $kga['server_prefix'] . "expenses"; $result = $conn->InsertRow($table, $values); if (!$result) { Logger::logfile('expense_create: ' . $conn->Error()); return false; } return $result; }
/** * check if a parset string matches with the following time-formatting: 20.08.2008-19:00:00 * returns true if string is ok * * @param string $timestring * @return boolean * @author th */ public static function check_time_format($timestring) { if (!preg_match("/([0-9]{1,2})\\.([0-9]{1,2})\\.([0-9]{2,4})-([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/", $timestring)) { return false; // WRONG format } else { $ok = 1; $hours = substr($timestring, 11, 2); $minutes = substr($timestring, 14, 2); $seconds = substr($timestring, 17, 2); if ((int) $hours >= 24) { $ok = 0; } if ((int) $minutes >= 60) { $ok = 0; } if ((int) $seconds >= 60) { $ok = 0; } Logger::logfile("timecheck: " . $ok); $day = substr($timestring, 0, 2); $month = substr($timestring, 3, 2); $year = substr($timestring, 6, 4); if (!checkdate((int) $month, (int) $day, (int) $year)) { $ok = 0; } Logger::logfile("time/datecheck: " . $ok); if ($ok) { return true; } else { return false; } } }
* ================== * * Called via AJAX from the Kimai user interface. Depending on $axAction * actions are performed, e.g. editing preferences or returning a list * of customers. */ // insert KSPI $isCoreProcessor = 1; $dir_templates = "templates/core/"; require "../includes/kspi.php"; switch ($axAction) { /** * Append a new entry to the logfile. */ case 'logfile': Logger::logfile("JavaScript: " . $axValue); break; /** * Remember which project and activity the user has selected for * the quick recording via the buzzer. */ /** * Remember which project and activity the user has selected for * the quick recording via the buzzer. */ case 'saveBuzzerPreselection': if (!isset($kga['user'])) { return; } $data = array(); if (isset($_REQUEST['project'])) {
/** * Execute an sql query in the database. The correct database connection * will be chosen and the query will be logged with the success status. * * As third parameter an alternative query can be passed, which should be * displayed instead of the executed query. This prevents leakage of * confidential information like password salts. The logfile will still * contain the executed query. * * @param $query query to execute as string * @param $errorProcessing true if it's an error when the query fails. */ function exec_query($query,$errorProcessing=true,$displayQuery=null) { global $database, $kga, $errors, $executed_queries; $conn = $database->getConnectionHandler(); $executed_queries++; if ($kga['server_conn'] == "pdo") { $pdo_query = $conn->prepare($query); $success = $pdo_query->execute(array()); } else { $success = $conn->Query($query); } Logger::logfile($query); if ($kga['server_conn'] == "pdo") { $err = $pdo_query->errorInfo(); $err = serialize($err); } else { $err = $conn->Error(); } $query = htmlspecialchars($query); $displayQuery = htmlspecialchars($displayQuery); if ($success) { $level = 'green'; } else { if ($errorProcessing) { $level = 'red'; $errors++; } else { $level = 'orange'; // something went wrong but it's not an error } } printLine($level,($displayQuery==null?$query:$displayQuery),$err); if (!$success) { Logger::logfile("An error has occured in query: $query"); if ($kga['server_conn'] == "pdo") { $err = $pdo_query->errorInfo(); $err = serialize($err); } else { $err = $conn->Error(); } Logger::logfile("Error text: $err"); } }
/** * Check if a global role gives permission for a specific action. * * @param integer $roleID the ID of the global role * @param string $permission name of the action / permission * @return bool true if permissions is granted, false otherwise */ public function global_role_allows($roleID, $permission) { $filter['globalRoleID'] = MySQL::SQLValue($roleID, MySQL::SQLVALUE_NUMBER); $filter[$permission] = 1; $columns[] = "globalRoleID"; $table = $this->kga['server_prefix'] . "globalRoles"; $result = $this->conn->SelectRows($table, $filter, $columns); if ($result === false) { $this->logLastError('global_role_allows'); return false; } $result = $this->conn->RowCount() > 0; Logger::logfile("Global role {$roleID} gave " . ($result ? 'true' : 'false') . " for {$permission}."); return $result; }
} $userData = $database->user_get_data($userId); $keymai = random_code(30); setcookie("kimai_key", $keymai); setcookie("kimai_user", $userData['name']); $database->user_loginSetKey($userId, $keymai); header("Location: core/kimai.php"); } // ================================================================= // = processing login and displaying either login screen or errors = // ================================================================= switch ($_REQUEST['a']) { case "checklogin": $name = htmlspecialchars(trim($name)); $is_customer = $database->is_customer_name($name); Logger::logfile("login: "******" as customer" : " as user")); if ($is_customer) { // perform login of customer $passCrypt = md5($kga['password_salt'] . $password . $kga['password_salt']); $id = $database->customer_nameToID($name); $data = $database->customer_get_data($id); // TODO: add BAN support if ($data['password'] == $passCrypt && $name != '' && $passCrypt != '') { $keymai = random_code(30); setcookie("kimai_key", $keymai); setcookie("kimai_user", 'customer_' . $name); $database->customer_loginSetKey($id, $keymai); header("Location: core/kimai.php"); } else { setcookie("kimai_key", "0"); setcookie("kimai_user", "0");
/** * @brief Check the permission to access an object. * * This method is meant to check permissions for adding, editing and deleting customers, * projects, activities and users. The input is not checked whether it falls within those boundaries since * it can also work with others, if the permissions match the pattern. * * @param $objectTypeName string name of the object type being edited (e.g. Project) * @param $action the action being performed (e.g. add) * @param $oldGroups the old groups of the object (empty array for new objects) * @param $newGroups the new groups of the object (same as oldGroups if nothing should be changed in group assignment) * @return true if the permission is granted, false otherwise */ function checkGroupedObjectPermission($objectTypeName, $action, $oldGroups, $newGroups) { global $database, $kga; if (!isset($kga['user'])) { return false; } $assignedOwnGroups = array_intersect($oldGroups, $database->getGroupMemberships($kga['user']['userID'])); $assignedOtherGroups = array_diff($oldGroups, $database->getGroupMemberships($kga['user']['userID'])); if (count($assignedOtherGroups) > 0) { $permissionName = "core-{$objectTypeName}-otherGroup-{$action}"; if (!$database->global_role_allows($kga['user']['globalRoleID'], $permissionName)) { Logger::logfile("missing global permission {$permissionName} for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } if (count($assignedOwnGroups) > 0) { $permissionName = "core-{$objectTypeName}-{$action}"; if (!$database->checkMembershipPermission($kga['user']['userID'], $assignedOwnGroups, $permissionName)) { Logger::logfile("missing membership permission {$permissionName} of current own group(s) " . implode(", ", $assignedOwnGroups) . " for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } if (count($oldGroups) != array_intersect($oldGroups, $newGroups)) { // group assignment has changed $addToGroups = array_diff($newGroups, $oldGroups); $removeFromGroups = array_diff($oldGroups, $newGroups); $addToOtherGroups = array_diff($addToGroups, $database->getGroupMemberships($kga['user']['userID'])); $addToOwnGroups = array_intersect($addToGroups, $database->getGroupMemberships($kga['user']['userID'])); $removeFromOtherGroups = array_diff($removeFromGroups, $database->getGroupMemberships($kga['user']['userID'])); $removeFromOwnGroups = array_intersect($removeFromGroups, $database->getGroupMemberships($kga['user']['userID'])); $action = 'assign'; if (count($addToOtherGroups) > 0) { $permissionName = "core-{$objectTypeName}-otherGroup-{$action}"; if (!$database->global_role_allows($kga['user']['globalRoleID'], $permissionName)) { Logger::logfile("missing global permission {$permissionName} for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } if (count($addToOwnGroups) > 0) { $permissionName = "core-{$objectTypeName}-{$action}"; if (!$database->checkMembershipPermission($kga['user']['userID'], $addToOwnGroups, $permissionName)) { Logger::logfile("missing membership permission {$permissionName} of new own group(s) " . implode(", ", $addToOwnGroups) . " for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } $action = 'unassign'; if (count($removeFromOtherGroups) > 0) { $permissionName = "core-{$objectTypeName}-otherGroup-{$action}"; if (!$database->global_role_allows($kga['user']['globalRoleID'], $permissionName)) { Logger::logfile("missing global permission {$permissionName} for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } if (count($removeFromOwnGroups) > 0) { $permissionName = "core-{$objectTypeName}-{$action}"; if (!$database->checkMembershipPermission($kga['user']['userID'], $removeFromOwnGroups, $permissionName)) { Logger::logfile("missing membership permission {$permissionName} of old own group(s) " . implode(", ", $removeFromOwnGroups) . " for user " . $kga['user']['name'] . " to access {$objectTypeName}"); return false; } } } return true; }
public static function errorHandler($errno, $errstr, $errfile, $errline) { // If the @ error-control operator is set don't log the error. if (error_reporting() === 0) { return false; } $line = ''; switch ($errno) { case E_WARNING: $line .= 'E_WARNING'; break; case E_NOTICE: $line .= 'E_NOTICE'; break; case E_USER_ERROR: $line .= 'E_USER_ERROR'; break; case E_USER_WARNING: $line .= 'E_USER_WARNING'; break; case E_USER_NOTICE: $line .= 'E_USER_NOTICE'; break; case E_STRICT: $line .= 'E_STRICT'; break; case E_RECOVERABLE_ERROR: $line .= 'E_RECOVERABLE_ERROR'; break; } $line .= ' ' . $errstr; $line .= " @{$errfile} line {$errline}"; Logger::logfile($line); return false; // let PHP do it's error handling as well }
$beginDate = $in; $endDate = $out; $invoiceID = $customer['name'] . "-" . date("y", $in) . "-" . date("m", $in); $today = time(); $dueDate = mktime(0, 0, 0, date("m") + 1, date("d"), date("Y")); $round = 0; // do we have to round the time ? if (isset($_REQUEST['round'])) { $round = $_REQUEST['roundValue']; $time_index = 0; $amount = count($invoiceArray); while ($time_index < $amount) { if ($invoiceArray[$time_index]['type'] == 'timeSheet') { $rounded = RoundValue($invoiceArray[$time_index]['hour'], $round / 10); // Write a logfile entry for each value that is rounded. Logger::logfile("Round " . $invoiceArray[$time_index]['hour'] . " to " . $rounded . " with " . $round); if ($invoiceArray[$time_index]['hour'] == 0) { // make sure we do not raise a "divison by zero" - there might be entries with the zero seconds $rate = 0; } else { $rate = RoundValue($invoiceArray[$time_index]['amount'] / $invoiceArray[$time_index]['hour'], 0.05); } $invoiceArray[$time_index]['hour'] = $rounded; $invoiceArray[$time_index]['amount'] = $invoiceArray[$time_index]['hour'] * $rate; } $time_index++; } } // calculate invoice sums $ttltime = 0; $rawTotalTime = 0;
$logdatei = fopen(WEBROOT . "temporary/logfile.txt", "w"); fwrite($logdatei, ""); fclose($logdatei); echo $kga['lang']['log_delete']; } else { die; } break; /** * Write some message to the logfile. */ /** * Write some message to the logfile. */ case "shoutbox": Logger::logfile("text: " . $axValue); break; /** * Return the $kga variable (Kimai Global Array). Strip out some sensitive * information if not configured otherwise. */ /** * Return the $kga variable (Kimai Global Array). Strip out some sensitive * information if not configured otherwise. */ case "reloadKGA": // read kga --------------------------------------- $output = $kga; // clean out some data that is way too private to be shown in the frontend ... if (!$kga['show_sensible_data']) { $output['server_hostname'] = "xxx";
$commentTypes = array($kga['lang']['ctype0'], $kga['lang']['ctype1'], $kga['lang']['ctype2']); // ================== // = security check = // ================== if (isset($_REQUEST['axAction']) && !is_array($_REQUEST['axAction']) && $_REQUEST['axAction'] != "") { $axAction = strip_tags($_REQUEST['axAction']); } else { $axAction = ''; } $axValue = isset($_REQUEST['axValue']) ? strip_tags($_REQUEST['axValue']) : ''; $id = isset($_REQUEST['id']) ? strip_tags($_REQUEST['id']) : null; // ============================================ // = initialize currently displayed timeframe = // ============================================ $timeframe = get_timeframe(); $in = $timeframe[0]; $out = $timeframe[1]; if (isset($_REQUEST['first_day'])) { $in = (int) $_REQUEST['first_day']; } if (isset($_REQUEST['last_day'])) { $out = mktime(23, 59, 59, date("n", $_REQUEST['last_day']), date("j", $_REQUEST['last_day']), date("Y", $_REQUEST['last_day'])); } if ($axAction != "reloadLogfile") { Logger::logfile("KSPI axAction (" . (array_key_exists('customer', $kga) ? $kga['customer']['name'] : $kga['user']['name']) . "): " . $axAction); } // prevent IE from caching the response header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache");
// = processing login and displaying either login screen or errors = // ================================================================= // $name = htmlspecialchars(trim($name)); $is_customer = $database->is_customer_name($name); if ($is_customer) { $id = $database->customer_nameToID($name); $customer = $database->customer_get_data($id); $keyCorrect = $key == $customer['passwordResetHash']; } else { $id = $database->user_name2id($name); $user = $database->user_get_data($id); $keyCorrect = $key == $user['passwordResetHash']; } switch ($_REQUEST['a']) { case "request": Logger::logfile("password reset: " . $name . ($is_customer ? " as customer" : " as user")); break; // ============================ // = Show password reset page = // ============================ // ============================ // = Show password reset page = // ============================ default: $view->devtimespan = '2006-' . date('y'); $view->keyCorrect = $keyCorrect; $view->requestData = array('key' => $key, 'name' => $name); echo $view->render('login/forgotPassword.php'); break; }