From 73fb0ded2312b8bea9231f8b16461940c3741c8a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 25 Jul 2017 14:14:15 -0500 Subject: [PATCH] Progress: continue to develop logging and fix other issues Corrected typo in c_base_return_arrray (removing the extra 'r'). Add get_request_headers() function to c_base_http. Fix problems in return value of c_base_http::get_request_uri_relative(). Add get_request_uri_query() function to c_base_http. Incorrect constant name used in p_load_request_accept_datetime(). Add function pr_do_log_user_activity() to c_standard_index to log access logs and responses to the database. --- common/base/classes/base_defaults_global.php | 2 +- common/base/classes/base_http.php | 81 ++++++++++++++++++++++++--- common/standard/classes/standard_database.php | 3 + common/standard/classes/standard_index.php | 55 +++++++++++++++++- common/standard/paths/u/login.php | 1 + 5 files changed, 132 insertions(+), 10 deletions(-) diff --git a/common/base/classes/base_defaults_global.php b/common/base/classes/base_defaults_global.php index 58366e8..adb6271 100644 --- a/common/base/classes/base_defaults_global.php +++ b/common/base/classes/base_defaults_global.php @@ -213,7 +213,7 @@ class c_base_defaults_global { * To ensure proper support for microseconds (and milliseconds), both $string and $format must contain microseconds, even if it is set to 0. * * @param string $string - * The time string to get the timestamp of (relative to $timestamp if specified). + * The time string to get the timestamp of. * @param string $format * (optional) The format the $string is structured as. * diff --git a/common/base/classes/base_http.php b/common/base/classes/base_http.php index ff2d48c..07d990a 100644 --- a/common/base/classes/base_http.php +++ b/common/base/classes/base_http.php @@ -330,7 +330,7 @@ class c_base_http extends c_base_rfc_string { * @see: https://www.w3.org/TR/html5/document-metadata.html#the-meta-element */ public function get_response_headers_for_meta() { - return c_base_return_arrray::s_new(array( + return c_base_return_array::s_new(array( self::RESPONSE_CACHE_CONTROL => self::RESPONSE_CACHE_CONTROL, self::RESPONSE_CONTENT_ENCODING => self::RESPONSE_CONTENT_ENCODING, self::RESPONSE_CONTENT_LANGUAGE => self::RESPONSE_CONTENT_LANGUAGE, @@ -396,6 +396,23 @@ class c_base_http extends c_base_rfc_string { } /** + * Get all provided HTTP request headers exactly as they were provided. + * + * @return c_base_return_array + * This always returns an array. + * An array with all request headers is returned. + * An empty array with the error bit set is returned on error. + */ + public function get_request_headers() { + if (!is_array($this->headers)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{data_name}' => 'request headers', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::NOT_DEFINED); + return c_base_return_error::s_value(array(), 'c_base_return_array', $error); + } + + return c_base_return_array::s_new($this->headers); + } + + /** * Return the relative part of the request URI that is also relative to the base path. * * @param string $base_path @@ -421,7 +438,9 @@ class c_base_http extends c_base_rfc_string { if (is_string($this->request_uri_relative)) { if ($with_query) { - return c_base_return_string::s_new($this->request_uri_relative . '?' . $this->request_uri_query); + if (is_string($this->request_uri_query)) { + return c_base_return_string::s_new($this->request_uri_relative . '?' . $this->request_uri_query); + } } return c_base_return_string::s_new($this->request_uri_relative); @@ -440,14 +459,14 @@ class c_base_http extends c_base_rfc_string { } $this->request_uri_relative = $request_uri['data']['path']; - $this->request_uri_query = ''; + $this->request_uri_query = NULL; - if (is_string($request_uri['data']['query'])) { + if (is_array($request_uri['data']['query']) && !empty($request_uri['data']['query'])) { $this->request_uri_query = http_build_query($request_uri['data']['query']); } unset($request_uri); - if ($with_query) { + if ($with_query && is_string($this->request_uri_query)) { return c_base_return_string::s_new($this->request_uri_relative . '?' . $this->request_uri_query); } @@ -455,6 +474,53 @@ class c_base_http extends c_base_rfc_string { } /** + * Return the query part of the request URI that is also relative to the base path. + * + * This is functionally similar to get_request_uri_relative() except that it returns the request query arguments (if any) instead of the request path. + * + * @param string $base_path + * The base_path to remove from the request uri. + * + * @return c_base_return_string + * A string is always returned. + * A string with error bit set is returned on error. + * + * @see: self::get_request_uri_relative() + */ + public function get_request_uri_query($base_path) { + if (!is_string($base_path)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{argument_name}' => 'base_path', ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); + return c_base_return_error::s_value('', 'c_base_return_string', $error); + } + + if (is_string($this->request_uri_query)) { + return c_base_return_string::s_new($this->request_uri_query); + } + + $request_uri = $this->get_request(c_base_http::REQUEST_URI)->get_value_exact(); + if (!isset($request_uri['defined']) || !$request_uri['defined']) { + unset($request_uri); + return c_base_return_string::s_new(''); + } + + // strip the base path from the requested uri. + if (strlen($base_path) > 0) { + $request_uri['data']['path'] = preg_replace('@^' . preg_quote($base_path, '@') . '@i', '', $request_uri['data']['path']); + $request_uri['data']['path'] = preg_replace('@/$@', '', $request_uri['data']['path']); + } + + $this->request_uri_relative = $request_uri['data']['path']; + $this->request_uri_query = NULL; + + if (is_array($request_uri['data']['query']) && !empty($request_uri['data']['query'])) { + $this->request_uri_query = http_build_query($request_uri['data']['query']); + } + unset($request_uri); + + return c_base_return_string::s_new($this->request_uri_query); + } + + /** * Get the HTTP response array. * * Load the entire HTTP response array or a specific response field. @@ -481,7 +547,6 @@ class c_base_http extends c_base_rfc_string { return c_base_return_error::s_false($error); } - if (is_null($header_name)) { return c_base_return_array::s_new($this->response); } @@ -5551,13 +5616,13 @@ class c_base_http extends c_base_rfc_string { */ private function p_load_request_accept_datetime() { if (p_validate_date_is_valid_rfc($this->headers['accept-datetime']) === FALSE) { - $this->request[self::REQUEST_DATE]['invalid'] = TRUE; + $this->request[self::REQUEST_ACCEPT_DATETIME]['invalid'] = TRUE; return; } $timestamp = strtotime($this->headers['accept-datetime']); if ($timestamp === FALSE) { - $this->request[self::REQUEST_DATE]['invalid'] = TRUE; + $this->request[self::REQUEST_ACCEPT_DATETIME]['invalid'] = TRUE; unset($timestamp); return; } diff --git a/common/standard/classes/standard_database.php b/common/standard/classes/standard_database.php index ddaf253..a50d4d4 100644 --- a/common/standard/classes/standard_database.php +++ b/common/standard/classes/standard_database.php @@ -91,6 +91,8 @@ class c_standard_database extends c_base_database { $last_error = $this->get_last_error()->get_value_exact(); $false = c_base_return_error::s_false($query_result->get_error()); + unset($query_result); + if (!empty($last_error)) { $error = c_base_error::s_log(NULL, array('arguments' => array(':{database_error_message}' => $last_error, ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::POSTGRESQL_ERROR); $false->set_error($error); @@ -99,6 +101,7 @@ class c_standard_database extends c_base_database { return $false; } + unset($query_result); return new c_base_return_true(); } diff --git a/common/standard/classes/standard_index.php b/common/standard/classes/standard_index.php index 76fa98b..dfc8e42 100644 --- a/common/standard/classes/standard_index.php +++ b/common/standard/classes/standard_index.php @@ -599,6 +599,8 @@ class c_standard_index extends c_base_return { $this->processed = $executed->get_output(); unset($executed); + $this->pr_do_log_user_activity(); + $this->pr_do_database_disconnect(); return new c_base_return_true(); @@ -728,7 +730,7 @@ class c_standard_index extends c_base_return { * FALSE with error bit set is returned on error. */ protected function pr_do_unload_database() { - if ($this->database->is_connected()) { + if ($this->database->is_connected() instanceof c_base_return_true) { $this->database->do_disconnect(); } @@ -752,4 +754,55 @@ class c_standard_index extends c_base_return { return new c_base_return_true(); } + + /** + * Add a log entry for the current user in regards to their request. + * + * This is expected to include a log of the intended response code and should be called only after the response has been determined. + * + * @return c_base_return_status + * TRUE on success, FALSE otherwise. + * FALSE with error bit set is returned on error. + */ + protected function pr_do_log_user_activity() { + if ($this->database->is_connected() instanceof c_base_return_false) { + // an active database connection is required. + return new c_base_return_false(); + } + + $query_string = 'insert into v_log_user_activity_self_insert (request_path, request_arguments, request_client, request_headers, response_headers, response_code)'; + $query_string .= ' values ($1, $2, ($3, $4, $5), $6, $7, $8)'; + + $query_parameters = array(); + $query_parameters[0] = $this->http->get_request_uri_relative($this->settings['base_path'])->get_value_exact(); + $query_parameters[1] = $this->http->get_request_uri_query($this->settings['base_path'])->get_value_exact(); + + $query_parameters[2] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; + $query_parameters[3] = isset($_SERVER['REMOTE_PORT']) && is_numeric($_SERVER['REMOTE_PORT']) ? (int) $_SERVER['REMOTE_PORT'] : 0; + $query_parameters[4] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '' ; + + $query_parameters[5] = json_encode($this->http->get_request_headers()->get_value_exact()); + $query_parameters[6] = json_encode($this->http->get_response()->get_value_exact()); + $query_parameters[7] = $this->http->get_response_status()->get_value_exact(); + + $query_result = $this->database->do_query($query_string, $query_parameters); + + if (c_base_return::s_has_error($query_result)) { + $last_error = $this->database->get_last_error()->get_value_exact(); + + $false = c_base_return_error::s_false($query_result->get_error()); + unset($query_result); + + if (!empty($last_error)) { + $error = c_base_error::s_log(NULL, array('arguments' => array(':{database_error_message}' => $last_error, ':{function_name}' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::POSTGRESQL_ERROR); + $false->set_error($error); + } + unset($last_error); + + return $false; + } + unset($query_result); + + return new c_base_return_true(); + } } diff --git a/common/standard/paths/u/login.php b/common/standard/paths/u/login.php index 05e8fde..24f1044 100644 --- a/common/standard/paths/u/login.php +++ b/common/standard/paths/u/login.php @@ -472,6 +472,7 @@ class c_standard_path_user_login extends c_standard_path { // if LDAP is available, make sure the account information exists. $ldap = $this->pr_load_ldap_data($settings, $_POST['login_form-user_name']); + if ($ldap['status']) { $this->pr_update_user_data($database, $ldap); } -- 1.8.3.1