From: Kevin Day Date: Thu, 23 Mar 2017 04:54:24 +0000 (-0500) Subject: Progress: major database work and other changes X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=46400274d7a33ee76ee4c777993a2176f8da4a5b;p=koopa Progress: major database work and other changes --- diff --git a/common/base/classes/base_cookie.php b/common/base/classes/base_cookie.php index 91f20a8..c751e0b 100644 --- a/common/base/classes/base_cookie.php +++ b/common/base/classes/base_cookie.php @@ -19,7 +19,7 @@ require_once('common/base/classes/base_return.php'); * @todo: there seems to be a non-standard cookie flag called 'storeid'. * I cannot find any decent documentation, so I will not implement it at this time. * - * @see: http://us.php.net/manual/en/features.cookies.php + * @see: http://php.net/manual/en/features.cookies.php * @see: https://tools.ietf.org/html/rfc6265 * @see: https://tools.ietf.org/html/draft-west-first-party-cookies * @see: setcookie() diff --git a/common/base/classes/base_database.php b/common/base/classes/base_database.php index 2d66eeb..d250e06 100644 --- a/common/base/classes/base_database.php +++ b/common/base/classes/base_database.php @@ -24,17 +24,18 @@ * - A reason against persistent connections is the inability to directly close them. * - This is a major weakness and may prevent me from using this persistent connection design (much testing is required). * - * @see: http://us.php.net/manual/en/features.persistent-connections.php + * @see: http://php.net/manual/en/features.persistent-connections.php */ // include required files. +require_once('common/base/classes/base_warning.php'); require_once('common/base/classes/base_error.php'); require_once('common/base/classes/base_return.php'); /** * A generic class for storing and creating a database connection string. * - * @see: http://us.php.net/manual/en/function.pg-pconnect.php + * @see: http://php.net/manual/en/function.pg-pconnect.php */ class c_base_connection_string extends c_base_return_string { const DATA_CLEAR_TEXT_LENGTH = 4096; @@ -50,8 +51,6 @@ class c_base_connection_string extends c_base_return_string { private $ssl_mode; private $service; - private $error; - /** * Class destructor. */ @@ -68,8 +67,6 @@ class c_base_connection_string extends c_base_return_string { $this->options = NULL; $this->ssl_mode = NULL; $this->service = NULL; - - $this->error = NULL; } /** @@ -89,8 +86,6 @@ class c_base_connection_string extends c_base_return_string { unset($this->ssl_mode); unset($this->service); - unset($this->error); - parent::__destruct(); } @@ -854,6 +849,13 @@ class c_base_database extends c_base_return { // make sure the connection string is built before using. $this->connection_string->build(); + // PHP's default error handle does not handle warnings. + // postgresql does not return the connection failure errors and instead prints a warning. + // the warning has to be caught by temporarily implementing a custom error handler that can catch warnings. + // the custom error handle then has to be reset back to the original PHP handler. + $handle_warnings = new c_base_warning_handler(); + $handle_warnings->do_handle(); + // Both pg_connect() and pg_pconnect() throw errors and the functions do not support try {} .. catch { statements. // the only way to prevent unwanted error reporting (allowing the caller to the reporting) is to use @. // The @ is considered bad practice, but there is no alternative in this case. @@ -868,9 +870,23 @@ class c_base_database extends c_base_return { if ($database === FALSE) { unset($database); - $error = c_base_error::s_log(NULL, array('arguments' => array(':database_name' => $this->connection_string->get_database()->get_value_exact(), ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::POSTGRESQL_CONNECTION_FAILURE); + // postgresql returns connection errors as warnings. + $warnings = $handle_warnings->get_warnings(); + unset($handle_warnings); + + $failure_reasons = array(); + if ($warnings instanceof c_base_return_array) { + $failure_reasons = $warnings->get_value_exact(); + } + unset($warnings); + + $error = c_base_error::s_log(NULL, array('arguments' => array(':database_name' => $this->connection_string->get_database()->get_value_exact(), ':failure_reasons' => $failure_reasons, ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::POSTGRESQL_CONNECTION_FAILURE); + unset($failure_reasons); + return c_base_return_error::s_false($error); } + unset($handle_warnings); + unset($warnings); $this->database = $database; unset($database); @@ -1865,7 +1881,7 @@ class c_base_database extends c_base_return { * This is confusing and a return value of an array makes the most sense. * * @see: pg_select() - * @see: http://us.php.net/manual/en/function.pg-select.php + * @see: http://php.net/manual/en/function.pg-select.php */ function do_select($table, $conditions, $options = NULL) { if (!is_string($table) || empty($table)) { diff --git a/common/base/classes/base_defaults_global.php b/common/base/classes/base_defaults_global.php new file mode 100644 index 0000000..381819d --- /dev/null +++ b/common/base/classes/base_defaults_global.php @@ -0,0 +1,24 @@ +set_field($field_name); + if (c_base_return::s_has_error($result)) { + $problem->set_error($result->get_error()); + unset($result); + + return $problem; + } + unset($result); + + $result = $problem->set_value($message); + if (c_base_return::s_has_error($result)) { + $problem->set_error($result->get_error()); + unset($result); + + return $problem; + } + unset($result); + + return $problem; + } + + /** * Associations a field via the field name with this problem. * * @param string $field_name @@ -75,7 +113,7 @@ class c_base_form_problem extends c_base_return_string { * @see: c_base_session::save() */ public function set_field($field_name) { - if (!is_string($field_name) && !empty($field_name)) { + if (!is_string($field_name) || empty($field_name)) { $error = c_base_error::s_log(NULL, array('arguments' => array(':argument_name' => 'field_name', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); return c_base_return_error::s_false($error); } diff --git a/common/base/classes/base_http.php b/common/base/classes/base_http.php index 1b87310..96d3efc 100644 --- a/common/base/classes/base_http.php +++ b/common/base/classes/base_http.php @@ -2667,10 +2667,10 @@ class c_base_http extends c_base_rfc_string { $this->response[self::RESPONSE_SET_COOKIE] = array(); } - $this->response[self::RESPONSE_SET_COOKIE][$cookie_name] = $cookie; + $this->response[self::RESPONSE_SET_COOKIE][$cookie_name] = clone($cookie); } else { - $this->response[self::RESPONSE_SET_COOKIE] = array($cookie_name => $cookie); + $this->response[self::RESPONSE_SET_COOKIE] = array($cookie_name => clone($cookie)); } unset($cookie_name); @@ -4455,6 +4455,7 @@ class c_base_http extends c_base_rfc_string { * @param bool $shuffle * (optional) When TRUE, this will randomize the order in which header fields are defined, except for the status header (which is always first). * This helps resist fingerprinting techniques thereby helping increase security. + * Some web-servers, namely Apache, will alter the headers, causing the order to not be completely shuffled. * * @return c_base_return_status * TRUE is returned when headers are sent. @@ -4578,10 +4579,21 @@ class c_base_http extends c_base_rfc_string { foreach ($headers as $header_id => $header_name) { if (array_key_exists($header_id, $header_output)) { if (is_array($header_output[$header_id])) { - foreach ($header_output[$header_id] as $sub_header) { - header($sub_header); + // the very first header should be a replacement, all others should be an appendment. + $headers_copy = $header_output[$header_id]; + reset($headers_copy); + $key = key($headers_copy); + $sub_header = $headers_copy[$key]; + + header($sub_header); + unset($headers_copy[$key]); + unset($key); + + foreach ($headers_copy as $sub_header) { + header($sub_header, FALSE); } unset($sub_header); + unset($headers_copy); } else { header($header_output[$header_id]); @@ -9569,11 +9581,22 @@ class c_base_http extends c_base_rfc_string { $encoding = $key; break 2; } + + if ($key == self::ENCODING_BZIP) { + $encoding = $key; + break 2; + } + + if ($key == self::ENCODING_LZO) { + $encoding = $key; + break 2; + } } unset($key); unset($choice); } unset($weight); + unset($choices); return $encoding; diff --git a/common/base/classes/base_mime.php b/common/base/classes/base_mime.php index e9971ac..ad15919 100644 --- a/common/base/classes/base_mime.php +++ b/common/base/classes/base_mime.php @@ -8,23 +8,26 @@ * A generic class for managing mime-type information. */ class c_base_mime { - const CATEGORY_UNKNOWN = 0; - const CATEGORY_PROVIDED = 1; - const CATEGORY_STREAM = 2; - const CATEGORY_TEXT = 1000; - const CATEGORY_IMAGE = 2000; - const CATEGORY_AUDIO = 3000; - const CATEGORY_VIDEO = 4000; - const CATEGORY_DOCUMENT = 5000; - const CATEGORY_CONTAINER = 6000; - const CATEGORY_APPLICATION = 7000; // only for application/* that values not covered by any other category. - - - const TYPE_UNKNOWN = 0; - const TYPE_PROVIDED = 1; - const TYPE_STREAM = 2; - const TYPE_MULTIPART = 3; - + const CATEGORY_NONE = 0; + const CATEGORY_UNKNOWN = 1; + const CATEGORY_PROVIDED = 2; + const CATEGORY_STREAM = 3; + const CATEGORY_MULTIPART = 4; + const CATEGORY_TEXT = 5; + const CATEGORY_IMAGE = 6; + const CATEGORY_AUDIO = 7; + const CATEGORY_VIDEO = 8; + const CATEGORY_DOCUMENT = 9; + const CATEGORY_CONTAINER = 10; + const CATEGORY_APPLICATION = 11; // only for application/* that values not covered by any other category. + + const TYPE_NONE = 0; + const TYPE_UNKNOWN = 1; + const TYPE_PROVIDED = 2; + const TYPE_STREAM = 3; + const TYPE_FORM_DATA = 4; + + const TYPE_TEXT = 1000; const TYPE_TEXT_PLAIN = 1001; const TYPE_TEXT_HTML = 1002; const TYPE_TEXT_RSS = 1003; @@ -37,7 +40,9 @@ class c_base_mime { const TYPE_TEXT_RICH = 1010; const TYPE_TEXT_XHTML = 1011; const TYPE_TEXT_PS = 1012; + const TYPE_TEXT_FSS = 1013; + const TYPE_IMAGE = 2000; const TYPE_IMAGE_PNG = 2001; const TYPE_IMAGE_GIF = 2002; const TYPE_IMAGE_JPEG = 2003; @@ -45,12 +50,17 @@ class c_base_mime { const TYPE_IMAGE_SVG = 2005; const TYPE_IMAGE_TIFF = 2006; - const TYPE_AUDIO_WAV = 3001; - const TYPE_AUDIO_OGG = 3002; - const TYPE_AUDIO_MP3 = 3003; - const TYPE_AUDIO_MP4 = 3004; - const TYPE_AUDIO_MIDI = 3005; - + const TYPE_AUDIO = 3000; + const TYPE_AUDIO_WAV = 3001; + const TYPE_AUDIO_OGG = 3002; + const TYPE_AUDIO_SPEEX = 3003; + const TYPE_AUDIO_FLAC = 3004; + const TYPE_AUDIO_MP3 = 3005; + const TYPE_AUDIO_MP4 = 3006; + const TYPE_AUDIO_MIDI = 3007; + const TYPE_AUDIO_BASIC = 3008; + + const TYPE_VIDEO = 4000; const TYPE_VIDEO_MPEG = 4001; const TYPE_VIDEO_OGG = 4002; const TYPE_VIDEO_H264 = 4003; @@ -59,34 +69,41 @@ class c_base_mime { const TYPE_VIDEO_JPEG = 4006; const TYPE_VIDEO_WEBM = 4007; - const TYPE_DOCUMENT_LIBRECHART = 5001; - const TYPE_DOCUMENT_LIBREFORMULA = 5002; - const TYPE_DOCUMENT_LIBREGRAPHIC = 5003; - const TYPE_DOCUMENT_LIBREPRESENTATION = 5004; - const TYPE_DOCUMENT_LIBRESPREADSHEET = 5005; - const TYPE_DOCUMENT_LIBRETEXT = 5006; - const TYPE_DOCUMENT_LIBREHTML = 5007; - const TYPE_DOCUMENT_PDF = 5008; + const TYPE_DOCUMENT = 5000; + const TYPE_DOCUMENT_PDF = 5001; + const TYPE_DOCUMENT_LIBRECHART = 5002; + const TYPE_DOCUMENT_LIBREFORMULA = 5003; + const TYPE_DOCUMENT_LIBREGRAPHIC = 5004; + const TYPE_DOCUMENT_LIBREPRESENTATION = 5005; + const TYPE_DOCUMENT_LIBRESPREADSHEET = 5006; + const TYPE_DOCUMENT_LIBRETEXT = 5007; + const TYPE_DOCUMENT_LIBREHTML = 5008; const TYPE_DOCUMENT_ABIWORD = 5009; const TYPE_DOCUMENT_MSWORD = 5010; const TYPE_DOCUMENT_MSEXCEL = 5011; const TYPE_DOCUMENT_MSPOWERPOINT = 5012; + const TYPE_CONTAINER = 6000; const TYPE_CONTAINER_TAR = 6001; const TYPE_CONTAINER_CPIO = 6002; const TYPE_CONTAINER_JAVA = 6003; + const TYPE_APPLICATION = 7000; + const TYPE_APPLICATION_OCSP_REQUEST = 7001; + const TYPE_APPLICATION_OCSP_RESPONSE = 7002; + private static $s_names_provided = array( self::TYPE_PROVIDED => array('*/*', 'text/*', 'image/*', 'audio/*', 'video/*', 'application/*'), self::TYPE_STREAM => array('application/octet-stream'), - self::TYPE_MULTIPART => array('multipart/form-data'), + self::TYPE_FORM_DATA => array('multipart/form-data'), ); private static $s_names_text = array( + self::TYPE_TEXT => array('text/*'), self::TYPE_TEXT_PLAIN => array('text/plain'), self::TYPE_TEXT_HTML => array('text/html'), - self::TYPE_TEXT_RSS => array('application/rss', 'application/rss+xml', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml'), + self::TYPE_TEXT_RSS => array('application/rss', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml'), self::TYPE_TEXT_ICAL => array('text/calendar'), self::TYPE_TEXT_CSV => array('text/csv'), self::TYPE_TEXT_XML => array('application/xml'), @@ -96,9 +113,11 @@ class c_base_mime { self::TYPE_TEXT_RICH => array('text/rtf'), self::TYPE_TEXT_XHTML => array('application/xhtml', 'application/xhtml+xml'), self::TYPE_TEXT_PS => array('text/ps'), + self::TYPE_TEXT_FSS => array('text/fss'), ); private static $s_names_image = array( + self::TYPE_IMAGE => array('image/*'), self::TYPE_IMAGE_PNG => array('image/png'), self::TYPE_IMAGE_GIF => array('image/gif'), self::TYPE_IMAGE_JPEG => array('image/jpeg', 'image/jpg', 'image/jpx'), @@ -108,17 +127,22 @@ class c_base_mime { ); private static $s_names_audio = array( - self::TYPE_AUDIO_WAV => array('audio/wav'), - self::TYPE_AUDIO_OGG => array('audio/ogg'), - self::TYPE_AUDIO_MP3 => array('audio/mpeg'), - self::TYPE_AUDIO_MP4 => array('audio/mp4'), - self::TYPE_AUDIO_MIDI => array('audio/midi'), + self::TYPE_AUDIO => array('audio/*'), + self::TYPE_AUDIO_WAV => array('audio/wav'), + self::TYPE_AUDIO_OGG => array('audio/ogg'), + self::TYPE_AUDIO_SPEEX => array('audio/speex'), + self::TYPE_AUDIO_FLAC => array('audio/flac'), + self::TYPE_AUDIO_MP3 => array('audio/mpeg'), + self::TYPE_AUDIO_MP4 => array('audio/mp4'), + self::TYPE_AUDIO_MIDI => array('audio/midi'), + self::TYPE_AUDIO_BASIC => array('audio/au', 'audio/snd'), ); private static $s_names_video = array( + self::TYPE_VIDEO => array('video/*'), self::TYPE_VIDEO_MPEG => array('video/mp4', 'video/mpeg'), - self::TYPE_VIDEO_OGG => array('video/ogg'), - self::TYPE_VIDEO_H264 => array('video/h264'), + self::TYPE_VIDEO_OGG => array('video/ogv'), + self::TYPE_VIDEO_H264 => array('video/h264', 'video/x264'), self::TYPE_VIDEO_QUICKTIME => array('video/qt'), self::TYPE_VIDEO_DV => array('video/dv'), self::TYPE_VIDEO_JPEG => array('video/jpeg', 'video/jpeg2000'), @@ -126,6 +150,7 @@ class c_base_mime { ); private static $s_names_document = array( + self::TYPE_DOCUMENT => array('application/*'), self::TYPE_DOCUMENT_PDF => array('application/pdf'), self::TYPE_DOCUMENT_LIBRECHART => array('application/vnd.oasis.opendocument.chart'), self::TYPE_DOCUMENT_LIBREFORMULA => array('application/vnd.oasis.opendocument.formula'), @@ -141,12 +166,96 @@ class c_base_mime { ); private static $s_names_container = array( + self::TYPE_CONTAINER => array('application/*'), self::TYPE_CONTAINER_TAR => array('application/tar'), self::TYPE_CONTAINER_CPIO => array('application/cpio'), self::TYPE_CONTAINER_JAVA => array('application/java'), ); private static $s_names_application = array( + self::TYPE_APPLICATION => array('application/*'), + self::TYPE_APPLICATION_OCSP_REQUEST => array('application/ocsp-request'), + self::TYPE_APPLICATION_OCSP_RESPONSE => array('application/ocsp-response'), + ); + + private static $s_extensions_text = array( + self::TYPE_TEXT => array(), + self::TYPE_TEXT_PLAIN => array('txt'), + self::TYPE_TEXT_HTML => array('html'), + self::TYPE_TEXT_RSS => array('rss', 'rdf'), + self::TYPE_TEXT_ICAL => array('ics'), + self::TYPE_TEXT_CSV => array('csv'), + self::TYPE_TEXT_XML => array('xml'), + self::TYPE_TEXT_CSS => array('css'), + self::TYPE_TEXT_JS => array('js'), + self::TYPE_TEXT_JSON => array('json'), + self::TYPE_TEXT_RICH => array('rtf'), + self::TYPE_TEXT_XHTML => array('xhtml'), + self::TYPE_TEXT_PS => array('ps'), + self::TYPE_TEXT_FSS => array('setting'), + ); + + private static $s_extensions_image = array( + self::TYPE_IMAGE => array(), + self::TYPE_IMAGE_PNG => array('png'), + self::TYPE_IMAGE_GIF => array('gif'), + self::TYPE_IMAGE_JPEG => array('jpg', 'jpeg'), + self::TYPE_IMAGE_BMP => array('bmp'), + self::TYPE_IMAGE_SVG => array('svg'), + self::TYPE_IMAGE_TIFF => array('tiff'), + ); + + private static $s_extensions_audio = array( + self::TYPE_AUDIO => array(), + self::TYPE_AUDIO_WAV => array('wav'), + self::TYPE_AUDIO_OGG => array('ogg'), + self::TYPE_AUDIO_OPUS => array('opus', 'ogg'), + self::TYPE_AUDIO_SPEEX => array('spx'), + self::TYPE_AUDIO_FLAC => array('flac'), + self::TYPE_AUDIO_MP3 => array('mp3', 'mp2', 'mp1'), + self::TYPE_AUDIO_MP4 => array('mp4', 'mpeg'), + self::TYPE_AUDIO_MIDI => array('midi'), + self::TYPE_AUDIO_BASIC => array('au', 'snd'), + ); + + private static $s_extensions_video = array( + self::TYPE_VIDEO => array(), + self::TYPE_VIDEO_MPEG => array('mp4', 'video/mpeg'), + self::TYPE_VIDEO_OGG => array('video/ogv'), + self::TYPE_VIDEO_H264 => array('video/h264'), + self::TYPE_VIDEO_QUICKTIME => array('video/qt'), + self::TYPE_VIDEO_DV => array('video/dv'), + self::TYPE_VIDEO_JPEG => array('video/jpeg', 'video/jpeg2000'), + self::TYPE_VIDEO_WEBM => array('video/webm'), + ); + + private static $s_extensions_document = array( + self::TYPE_DOCUMENT => array('application/*'), + self::TYPE_DOCUMENT_PDF => array('application/pdf'), + self::TYPE_DOCUMENT_LIBRECHART => array('application/vnd.oasis.opendocument.chart'), + self::TYPE_DOCUMENT_LIBREFORMULA => array('application/vnd.oasis.opendocument.formula'), + self::TYPE_DOCUMENT_LIBREGRAPHIC => array('application/vnd.oasis.opendocument.graphics'), + self::TYPE_DOCUMENT_LIBREPRESENTATION => array('application/vnd.oasis.opendocument.presentation'), + self::TYPE_DOCUMENT_LIBRESPREADSHEET => array('application/vnd.oasis.opendocument.spreadsheet'), + self::TYPE_DOCUMENT_LIBRETEXT => array('application/vnd.oasis.opendocument.text'), + self::TYPE_DOCUMENT_LIBREHTML => array('application/vnd.oasis.opendocument.text-web'), + self::TYPE_DOCUMENT_ABIWORD => array('application/abiword', 'application/abiword-compressed'), + self::TYPE_DOCUMENT_MSWORD => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/msword'), + self::TYPE_DOCUMENT_MSEXCEL => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/ms-excel'), + self::TYPE_DOCUMENT_MSPOWERPOINT => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/ms-powerpoint'), + ); + + private static $s_extensions_container = array( + self::TYPE_CONTAINER => array('application/*'), + self::TYPE_CONTAINER_TAR => array('application/tar'), + self::TYPE_CONTAINER_CPIO => array('application/cpio'), + self::TYPE_CONTAINER_JAVA => array('application/java'), + ); + + private static $s_extensions_application = array( + self::TYPE_APPLICATION => array('application/*'), + self::TYPE_APPLICATION_OCSP_REQUEST => array('application/ocsp-request'), + self::TYPE_APPLICATION_OCSP_RESPONSE => array('application/ocsp-response'), ); @@ -440,6 +549,14 @@ class c_base_mime { $information['id_category'] = self::CATEGORY_CONTAINER; $information['id_type'] = self::TYPE_CONTAINER_JAVA; } + elseif ($parts[1] == 'ocsp-request') { + $information['id_category'] = self::CATEGORY_APPLICATION; + $information['id_type'] = self::TYPE_PACKET_OCSP_REQUEST; + } + elseif ($parts[1] == 'ocsp-response') { + $information['id_category'] = self::CATEGORY_APPLICATION; + $information['id_type'] = self::TYPE_PACKET_OCSP_RESPONSE; + } else { $information['id_type'] = self::TYPE_UNKNOWN; } diff --git a/common/base/classes/base_return.php b/common/base/classes/base_return.php index b2997ea..645d70b 100644 --- a/common/base/classes/base_return.php +++ b/common/base/classes/base_return.php @@ -1152,19 +1152,23 @@ class c_base_return_object extends c_base_return_value { /** * Assign the value. * + * This calls PHP's clone() function to prevent potential security/integrirty issues. + * * @param object $value * Any value so long as it is an object. * NULL is not allowed. * * @return bool * TRUE on success, FALSE otherwise. + * + * @see: clone() */ public function set_value($value) { if (!is_object($value)) { return FALSE; } - $this->value = $value; + $this->value = clone($value); return TRUE; } diff --git a/common/base/classes/base_session.php b/common/base/classes/base_session.php index a3e0186..93537b6 100644 --- a/common/base/classes/base_session.php +++ b/common/base/classes/base_session.php @@ -34,7 +34,6 @@ class c_base_session extends c_base_return { private $cookie; private $name; - private $id_user; private $host; private $password; private $session_id; @@ -63,7 +62,6 @@ class c_base_session extends c_base_return { $this->system_name = NULL; $this->name = NULL; - $this->id_user = NULL; $this->host = NULL; $this->password = NULL; $this->session_id = NULL; @@ -96,7 +94,6 @@ class c_base_session extends c_base_return { unset($this->system_name); unset($this->name); - unset($this->id_user); unset($this->host); unset($this->password); unset($this->session_id); @@ -236,11 +233,6 @@ class c_base_session extends c_base_return { return c_base_return_error::s_false($error); } - if (is_null($this->socket_directory)) { - $this->socket_directory = NULL; - return new c_base_return_true(); - } - $this->system_name = basename($system_name); $this->socket_path = $this->socket_directory . $this->system_name . self::SOCKET_PATH_SUFFIX; @@ -309,44 +301,6 @@ class c_base_session extends c_base_return { } /** - * Assigns the user id associated with the session. - * - * @param int|null $id_user - * The user id. - * This must be greater than or equal to 0. - * Set to NULL to remove any existing values. - * - * @return c_base_return_status - * TRUE on success, FALSE otherwise. - * FALSE with the error bit set is returned on error. - */ - public function set_id_user($id_user) { - if (!is_null($id_user) && ((is_int($id_user) && $id_user < 0))) { - $error = c_base_error::s_log(NULL, array('arguments' => array(':argument_name' => 'id_user', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_ARGUMENT); - return c_base_return_error::s_false($error); - } - - $this->id_user = $id_user; - - return new c_base_return_true(); - } - - /** - * Returns the stored user id. - * - * @return c_base_return_int|c_base_return_null - * The user id_user integer or NULL if undefined. - * FALSE with the error bit set is returned on error. - */ - public function get_id_user() { - if (is_null($this->id_user)) { - return new c_base_return_null(); - } - - return c_base_return_int::s_new($this->id_user); - } - - /** * Assigns the host ip address associated with the session. * * @param string|null $host @@ -871,6 +825,7 @@ class c_base_session extends c_base_return { return c_base_return_error::s_false($error); } + $this->socket = @socket_create(AF_UNIX, SOCK_STREAM, 0); if (!is_resource($this->socket)) { $this->socket = NULL; @@ -990,11 +945,6 @@ class c_base_session extends c_base_return { $this->name = $response['result']['name']; } - $this->id_user = NULL; - if (isset($response['result']['id_user']) && is_int($response['result']['id_user'])) { - $this->id_user = $response['result']['id_user']; - } - if (!is_null($this->password)) { $this->password = str_repeat(' ', self::PASSWORD_CLEAR_TEXT_LENGTH); } @@ -1050,11 +1000,6 @@ class c_base_session extends c_base_return { return c_base_return_error::s_false($error); } - if (is_null($this->id_user)) { - $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->id_user', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE); - return c_base_return_error::s_false($error); - } - if (is_null($this->host)) { $error = c_base_error::s_log(NULL, array('arguments' => array(':variable_name' => 'this->host', ':function_name' => __CLASS__ . '->' . __FUNCTION__)), i_base_error_messages::INVALID_VARIABLE); return c_base_return_error::s_false($error); @@ -1085,7 +1030,7 @@ class c_base_session extends c_base_return { $this->settings = array(); } - $response = $this->p_transfer(array('name' => $this->name, 'id_user' => $this->id_user, 'ip' => $this->host, 'password' => $this->password, 'expire' => $interval_expire, 'max' => $interval_max, 'settings' => $this->settings)); + $response = $this->p_transfer(array('name' => $this->name, 'ip' => $this->host, 'password' => $this->password, 'expire' => $interval_expire, 'max' => $interval_max, 'settings' => $this->settings)); if (c_base_return::s_has_error($response)) { return c_base_return_error::s_false($response->get_error(0)); } diff --git a/common/base/classes/base_warning.php b/common/base/classes/base_warning.php new file mode 100644 index 0000000..9dc9c5e --- /dev/null +++ b/common/base/classes/base_warning.php @@ -0,0 +1,146 @@ +warnings = FALSE; + $this->handler = NULL; + } + + /** + * Class destructor. + */ + public function __destruct() { + // restore previous handler on destruction. + if (!is_null($this->handler)) { + set_error_handler($this->handler, E_WARNING | E_USER_WARNING); + } + + unset($this->warnings); + unset($this->handler); + } + + /** + * Setup the PHP default error handler to catch warnings. + * + * @return c_base_return_status + * TRUE on success, FALSE otherwise. + * The error bit is not set on error. + */ + public function do_handle() { + if (is_array($this->warnings) || $this->warnings === TRUE) { + return new c_base_return_true(); + } + + $this->handler = set_error_handler(array($this, 'warning_handler'), E_WARNING | E_USER_WARNING); + if (!is_null($this->handler)) { + $this->warnings = TRUE; + return new c_base_return_true(); + } + + return new c_base_return_false(); + } + + /** + * Reset the PHP default error handler behavior. + * + * @return c_base_return_status + * TRUE on success, FALSE otherwise. + * The error bit is not set on error. + */ + public function do_restore() { + if (is_null($this->warnings) || $this->warnings === FALSE) { + return new c_base_return_false(); + } + + if (is_null($this->handler)) { + return new c_base_return_true(); + } + + // reset to previous error handler. + set_error_handler($this->handler, E_WARNING | E_USER_WARNING); + + $this->warnings = FALSE; + $this->handler = NULL; + return new c_base_return_true(); + } + + /** + * Returns any detected warnings. + * + * @return c_base_return_status|c_base_return_array + * TRUE is returned when the warning handler is active but no errors have been detected. + * FALSE is returned when the warning handler is inactive. + */ + public function get_warnings() { + if (is_array($this->warnings)) { + return c_base_return_array::s_new($this->warnings); + } + + if (is_bool($this->warnings) && $this->warnings) { + return new c_base_return_true(); + } + + return new c_base_return_false(); + } + + /** + * Handle PHP's warnings. + * + * @param int $code + * The error level. + * @param string $message + * The error message. + * @param string|null $file_name + * (optional) The name of the file, if provided. + * @param string|null $line_number + * (optional) The line number in the file, if provided. + * @param array|null $context + * (optional) An array of variables that exist during the scope of the error, if provided. + * + * @see: set_error_handler() + */ + public function warning_handler($code, $message, $file_name = NULL, $line_number = NULL, $context = NULL) { + if ($code !== E_WARNING && $code !== E_USER_WARNING) { + // shouldn't happen, but just in case, add a failsafe to catch any errors that PHP's error handler should still handle. + return FALSE; + } + + if (!is_array($this->warnings)) { + $this->warnings = array(); + } + + $this->warnings[] = array( + 'code' => (int) $code, + 'message' => (string) $message, + 'file_name' => (is_null($file_name) ? NULL : (string) $file_name), + 'line_number' => (is_null($line_number) ? NULL : (int) $line_number), + 'context' => (is_null($context) ? NULL : (array) $context), + ); + + return TRUE; + } +} diff --git a/database/sql/reservation/base-associations.sql b/database/sql/reservation/base-associations.sql deleted file mode 100644 index e71961a..0000000 --- a/database/sql/reservation/base-associations.sql +++ /dev/null @@ -1,93 +0,0 @@ -/** Standardized SQL Structure - Content **/ -/** This depends on: base-fields.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** Associations ***/ -create table managers.t_associations ( - id bigint not null, - id_manager bigint not null, - id_group bigint, - id_coordinator bigint not null, - - name_machine varchar(128) not null, - name_machine_manager varchar(128) not null, - name_machine_coordinator varchar(128) not null, - name_human varchar(256) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - field_affiliation bigint not null, - field_classification bigint not null, - - constraint cu_associations_id unique (id), - constraint cu_associations_name_machine unique (name_machine), - - constraint cc_associations_id check (id > 0), - - constraint cf_associations_id_manager foreign key (id_manager, name_machine_manager) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_associations_id_coordinator foreign key (id_coordinator, name_machine_coordinator) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_associations_group foreign key (id_group) references managers.t_groups (id) on delete restrict on update cascade, - constraint cf_associations_field_affiliation foreign key (field_affiliation) references managers.t_field_affiliations (id) on delete restrict on update cascade, - constraint cf_associations_field_classification foreign key (field_classification) references managers.t_field_classifications (id) on delete restrict on update cascade -); - -create sequence managers.s_associations_id owned by managers.t_associations.id; -alter table managers.t_associations alter column id set default nextval('managers.s_associations_id'::regclass); - -grant select,insert,update on managers.t_associations to reservation_users_administer; -grant select,insert,update on managers.t_associations to reservation_users_manager; -grant select on managers.t_associations to reservation_users_auditor; -grant select,usage on managers.s_associations_id to reservation_users_administer; -grant select,usage on managers.s_associations_id to reservation_users_manager; -grant usage on managers.s_associations_id to reservation_users; - - -/*** provide current user access to their own information ***/ -create view users.v_associations_self with (security_barrier=true) as - with allowed_groups as (select id from users.v_groups_self) - select id, id_manager, id_group, id_coordinator, name_machine, name_machine_manager, name_machine_coordinator, name_human, date_created, date_changed, field_affiliation, field_classification from managers.t_associations - where is_deleted is not true and ((id_group is null and (name_machine_manager)::text = (current_user)::text) or id_group in (select * from allowed_groups)); - -grant select on users.v_associations_self to reservation_users; - - -/*** provide current user access to associations who they are assigned as the coordinator of ***/ -create view users.v_associations_coordinator_self with (security_barrier=true) as - with allowed_groups as (select id from users.v_groups_self) - select id, id_manager, id_group, id_coordinator, name_machine, name_machine_manager, name_machine_coordinator, name_human, date_created, date_changed, field_affiliation, field_classification from managers.t_associations - where is_deleted is not true and (name_machine_coordinator)::text = (current_user)::text; - -grant select on users.v_associations_coordinator_self to reservation_users; - - -/** provide current user access to insert their own associations **/ -create view users.v_associations_self_insert with (security_barrier=true) as - select id, id_manager, id_group, id_coordinator, name_machine, name_machine_manager, name_machine_coordinator, name_human, field_affiliation, field_classification from managers.t_associations - where is_deleted is not true and (id_group is null or id_group in (select id from users.v_groups_self)) and (name_machine_manager)::text = (current_user)::text - with check option; - -grant insert on users.v_associations_self_insert to reservation_users; - - -/** provide current user access to update their own associations **/ -create view users.v_associations_self_update with (security_barrier=true) as - select id, id_group, id_coordinator, name_machine, name_machine_coordinator, name_human, date_changed, field_affiliation, field_classification from managers.t_associations - where is_deleted is not true and (id_group is null or id_group in (select id from users.v_groups_self)) and date_changed = localtimestamp and (name_machine_manager)::text = (current_user)::text - with check option; - -grant insert on users.v_associations_self_update to reservation_users; - -commit transaction; diff --git a/database/sql/reservation/base-dates.sql b/database/sql/reservation/base-dates.sql deleted file mode 100644 index 5708bae..0000000 --- a/database/sql/reservation/base-dates.sql +++ /dev/null @@ -1,59 +0,0 @@ -/** Standardized SQL Structure - Dates **/ -/** This depends on: base-main.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** Dates: Contexts ***/ -create table managers.t_date_contexts ( - id bigint not null, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cu_date_contexts_id unique (id), - constraint cu_date_contexts_name_machine unique (name_machine), - - constraint cc_date_contexts_id check (id >= 0) -); - -create sequence managers.s_date_contexts_id owned by managers.t_date_contexts.id; -alter table managers.t_date_contexts alter column id set default nextval('managers.s_date_contexts_id'::regclass); - -grant select,insert,update on managers.t_date_contexts to reservation_users_administer; -grant select,insert,update on managers.t_date_contexts to reservation_users_manager; -grant select on managers.t_date_contexts to reservation_users_auditor; -grant select,usage on managers.s_date_contexts_id to reservation_users_administer; -grant select,usage on managers.s_date_contexts_id to reservation_users_manager; - -create index ci_date_contexts_deleted_not on managers.t_date_contexts (id) - where is_deleted is not true; - -create index ci_date_contexts_public on managers.t_date_contexts (id) - where is_deleted is not true and is_locked is not true; - - -create view requesters.v_date_contexts with (security_barrier=true) as - select id, name_machine, name_human from managers.t_date_contexts - where is_deleted is not true and is_locked is not true; - -grant select on requesters.v_date_contexts to reservation_users_requester; - -insert into managers.t_date_contexts (id, name_machine, name_human) values (0, 'none', 'None'); -insert into managers.t_date_contexts (name_machine, name_human) values ('rehearsal', 'Rehearsal / Setup'); -insert into managers.t_date_contexts (name_machine, name_human) values ('event', 'Event / Meeting'); -insert into managers.t_date_contexts (name_machine, name_human) values ('cleanup', 'Cleanup / Breakdown'); diff --git a/database/sql/reservation/base-fields.sql b/database/sql/reservation/base-fields.sql deleted file mode 100644 index 6f85710..0000000 --- a/database/sql/reservation/base-fields.sql +++ /dev/null @@ -1,88 +0,0 @@ -/** Standardized SQL Structure - Content **/ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** Field: Affiliations ***/ -create table managers.t_field_affiliations ( - id bigint not null, - id_external bigint, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cu_field_affiliations_id unique (id), - constraint cu_field_affiliations_name_machine unique (name_machine), - - constraint cc_field_affiliations_id check (id > 0) -); - -create sequence managers.s_field_affiliations_id owned by managers.t_field_affiliations.id; -alter table managers.t_field_affiliations alter column id set default nextval('managers.s_field_affiliations_id'::regclass); - -grant select,insert,update on managers.t_field_affiliations to reservation_users_administer; -grant select,insert,update on managers.t_field_affiliations to reservation_users_manager; -grant select on managers.t_field_affiliations to reservation_users_auditor; -grant select,usage on managers.s_field_affiliations_id to reservation_users_administer; -grant select,usage on managers.s_field_affiliations_id to reservation_users_manager; - -create view users.v_field_affiliations with (security_barrier=true) as - select id, id_external, name_machine, name_human, date_created, date_changed from managers.t_field_affiliations - where is_deleted is false; - -grant select on users.v_field_affiliations to reservation_users; - - - -/*** Field: Classifications ***/ -create table managers.t_field_classifications ( - id bigint not null, - id_external bigint, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cu_field_classifications_id unique (id), - constraint cu_field_classifications_name_machine unique (name_machine), - - constraint cc_field_classifications_id check (id > 0) -); - -create sequence managers.s_field_classifications_id owned by managers.t_field_classifications.id; -alter table managers.t_field_classifications alter column id set default nextval('managers.s_field_classifications_id'::regclass); - -grant select,insert,update on managers.t_field_classifications to reservation_users_administer; -grant select,insert,update on managers.t_field_classifications to reservation_users_manager; -grant select on managers.t_field_classifications to reservation_users_auditor; -grant select,usage on managers.s_field_classifications_id to reservation_users_administer; -grant select,usage on managers.s_field_classifications_id to reservation_users_manager; - -create view users.v_field_classifications with (security_barrier=true) as - select id, id_external, name_machine, name_human, date_created, date_changed from managers.t_field_classifications - where is_deleted is false; - -grant select on users.v_field_classifications to reservation_users; - -/** @todo: create all field types needed for f_requests fields **/ - -commit transaction; diff --git a/database/sql/reservation/base-first.sql b/database/sql/reservation/base-first.sql deleted file mode 100644 index 84f29f6..0000000 --- a/database/sql/reservation/base-first.sql +++ /dev/null @@ -1,70 +0,0 @@ -/** First time or one time execution stuff **/ -/** Things here must be run first and cannot be run a second time due to their nature. **/ -/** For example, tablespaces need only be created 1x and then any database on the system can use them **/ -/** Be sure to replace reservation_ and reservation- with the prefix that is specific to your database. **/ - - - -/** Create the roles (note: public_user and public_users are expected to have already been created. Users and not roles should be created with noinherit) **/ -create role reservation_users inherit nologin; -create role reservation_users_administer inherit nologin; -create role reservation_users_manager inherit nologin; -create role reservation_users_auditor inherit nologin; -create role reservation_users_publisher inherit nologin; -create role reservation_users_insurer inherit nologin; -create role reservation_users_financer inherit nologin; -create role reservation_users_reviewer inherit nologin; -create role reservation_users_editor inherit nologin; -create role reservation_users_drafter inherit nologin; -create role reservation_users_requester inherit nologin; - -grant reservation_users to reservation_users_administer with admin option; -grant reservation_users to reservation_users_manager with admin option; -grant reservation_users to reservation_users_auditor; -grant reservation_users to reservation_users_publisher; -grant reservation_users to reservation_users_insurer; -grant reservation_users to reservation_users_financer; -grant reservation_users to reservation_users_reviewer; -grant reservation_users to reservation_users_editor; -grant reservation_users to reservation_users_drafter; -grant reservation_users to reservation_users_requester; - -grant reservation_users_manager to reservation_users_administer with admin option; - -grant reservation_users_auditor to reservation_users_administer with admin option; -grant reservation_users_auditor to reservation_users_manager with admin option; - -grant reservation_users_publisher to reservation_users_administer with admin option; -grant reservation_users_publisher to reservation_users_manager with admin option; - -grant reservation_users_insurer to reservation_users_administer with admin option; -grant reservation_users_insurer to reservation_users_manager with admin option; - -grant reservation_users_financer to reservation_users_administer with admin option; -grant reservation_users_financer to reservation_users_manager with admin option; - -grant reservation_users_reviewer to reservation_users_administer with admin option; -grant reservation_users_reviewer to reservation_users_manager with admin option; - -grant reservation_users_editor to reservation_users_administer with admin option; -grant reservation_users_editor to reservation_users_manager with admin option; - -grant reservation_users_drafter to reservation_users_administer with admin option; -grant reservation_users_drafter to reservation_users_manager with admin option; - -grant reservation_users_requester to reservation_users_administer with admin option; -grant reservation_users_requester to reservation_users_manager with admin option; - -/** This is the role the database should use to connect to to perform system activity **/ -create role reservation_user; - -grant reservation_users to reservation_user; - - -/** This is the role and role group the database should use for anonymous traffic. I further suggest setting up pg_hba.conf to allow non-ssl connections (increase performance as public information is still public). **/ -/** If the data is meant to be private, then have the public account use the system user with ssl connections **/ -create role public_users; -create role public_user; - -grant public_users to public_user; - diff --git a/database/sql/reservation/base-groups.sql b/database/sql/reservation/base-groups.sql deleted file mode 100644 index 0d0b020..0000000 --- a/database/sql/reservation/base-groups.sql +++ /dev/null @@ -1,172 +0,0 @@ -/** Standardized SQL Structure - Groups */ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - -/* Note about composite groups (is_composite) - Instead of having an array of multiple groups assigned to one entity or having a table of group and entity associates, use a group that logically represents multiple groups. - For example, if I want to add both group_1 and group_2 to entity_a, then I can create group_3 and put all users from group_1 and group_2 in it. - @todo: I will likely need to create a composite groups table to manage the relations between a composite group and its non-composites for management purposes. - - @todo: with this composite groups design, I can get rid of the user to groups table and need users only to be assigned to a single (composite) group. - the current flaw with this design may be with access control in creating or auto-creating composite groups. -*/ - -/** Groups **/ -create table managers.t_groups ( - id bigint not null, - id_sort smallint not null default 0, - id_external bigint, - id_manager bigint, - - name_machine varchar(128) not null, - name_machine_creator varchar(128) not null, - name_machine_manager varchar(128) not null, - name_human varchar(256) not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_synced timestamp default localtimestamp not null, - date_deleted timestamp, - - is_deleted boolean default false not null, - is_locked boolean default false not null, - is_composite boolean default false not null, - - can_manage_paths boolean default false not null, - - settings json, - - constraint cp_groups_id primary key (id), - - constraint cc_groups_id check (id > 0), - constraint cc_groups_id_external check (id_external > 0), - - constraint cu_groups_id_external unique (id_external), - constraint cu_groups_name_machine unique (name_machine), - constraint cu_groups_user unique (id, name_machine), - - constraint cf_t_groups_manager foreign key (id_manager, name_machine_manager) references administers.t_users (id, name_machine) on delete restrict on update cascade -); - -create sequence managers.s_groups_id owned by managers.t_groups.id; -alter table managers.t_groups alter column id set default nextval('managers.s_groups_id'::regclass); - -grant select,insert,update on managers.t_groups to reservation_users_administer; -grant select,insert,update on managers.t_groups to reservation_users_manager; -grant select on managers.t_groups to reservation_users_auditor; -grant select,usage on managers.s_groups_id to reservation_users_administer; -grant select,usage on managers.s_groups_id to reservation_users_manager; -grant usage on managers.s_groups_id to reservation_users; - -create index ci_groups_id_sort_a on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 97; -create index ci_groups_id_sort_b on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 98; -create index ci_groups_id_sort_c on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 99; -create index ci_groups_id_sort_d on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 100; -create index ci_groups_id_sort_e on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 101; -create index ci_groups_id_sort_f on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 102; -create index ci_groups_id_sort_g on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 103; -create index ci_groups_id_sort_h on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 104; -create index ci_groups_id_sort_i on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 105; -create index ci_groups_id_sort_j on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 106; -create index ci_groups_id_sort_k on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 107; -create index ci_groups_id_sort_l on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 108; -create index ci_groups_id_sort_m on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 109; -create index ci_groups_id_sort_n on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 110; -create index ci_groups_id_sort_o on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 111; -create index ci_groups_id_sort_p on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 112; -create index ci_groups_id_sort_q on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 113; -create index ci_groups_id_sort_r on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 114; -create index ci_groups_id_sort_s on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 115; -create index ci_groups_id_sort_t on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 116; -create index ci_groups_id_sort_u on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 117; -create index ci_groups_id_sort_v on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 118; -create index ci_groups_id_sort_w on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 119; -create index ci_groups_id_sort_x on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 120; -create index ci_groups_id_sort_y on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 121; -create index ci_groups_id_sort_z on managers.t_groups (id_sort) with (fillfactor = 100) where id_sort = 122; - - - - -/** Groups to Users Association **/ -create table managers.t_group_users ( - id_user bigint not null, - id_group bigint not null, - - name_machine_user varchar(128) not null, - - constraint cu_groups_id unique (id_user, id_group), - - constraint cf_t_group_users_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete cascade on update cascade, - constraint cf_t_group_users_group foreign key (id_group) references managers.t_groups (id) on delete cascade on update cascade -); - -grant select,insert,update on managers.t_groups to reservation_users_administer; -grant select,insert,update on managers.t_groups to reservation_users_manager; -grant select on managers.t_groups to reservation_users_auditor; - - -/*** provide group manages access to manage users assigned to their groups ***/ -create view users.v_group_users_manage with (security_barrier=true) as - select gu.id_user, gu.id_group from managers.t_group_users gu - inner join managers.t_groups g on g.id = gu.id_group - where g.is_deleted is not true and (g.name_machine_manager)::text = (current_user)::text; - -grant select, insert, update, delete on users.v_group_users_manage to reservation_users; - - -/*** provide current user access to their own information ***/ -create view users.v_groups_self with (security_barrier=true) as - select g.id, g.id_sort, g.id_external, g.id_manager, g.name_machine, g.name_human, g.is_locked, g.is_composite, g.date_created, g.date_changed, g.date_synced, g.can_manage_paths, g.settings from managers.t_groups g - inner join managers.t_group_users gu on g.id = gu.id_group - where g.is_deleted is not true and (gu.name_machine_user)::text = (current_user)::text; - -grant select on users.v_groups_self to reservation_users; - - -/*** provide group manages access to manage users their groups ***/ -create view users.v_groups_manage with (security_barrier=true) as - select g.id, g.id_sort, g.id_external, g.name_machine, g.name_human, g.is_locked, g.is_composite, g.date_changed, g.date_synced, g.can_manage_paths, g.settings from managers.t_groups g - inner join managers.t_group_users gu on g.id = gu.id_group - where g.is_deleted is not true and (date_changed is null or date_changed = localtimestamp) and (date_synced is null or date_synced = localtimestamp) and (gu.name_machine_user)::text = (current_user)::text; - -grant select, insert, update on users.v_groups_manage to reservation_users; - - - - -/** Groups Composites **/ -create table managers.t_group_composites ( - id_composite bigint not null, - id_group bigint not null, - - constraint cu_group_composites_id unique (id_composite, id_group), - - constraint cf_t_group_composites_composite foreign key (id_composite) references managers.t_groups (id) on delete cascade on update cascade, - constraint cf_t_group_composites_group foreign key (id_group) references managers.t_groups (id) on delete cascade on update cascade -); - -grant select,insert,update on managers.t_groups to reservation_users_administer; -grant select,insert,update on managers.t_groups to reservation_users_manager; -grant select on managers.t_groups to reservation_users_auditor; - - -/*** provide group manages access to composite groups containing groups they belong to. ***/ -create view users.v_group_composites with (security_barrier=true) as - with allowed_groups as (select id from users.v_groups_self) - select gc.id_composite, gc.id_group from managers.t_group_composites gc - inner join managers.t_groups g on g.id = gc.id_group - where g.is_deleted is not true and (g.is_locked is not true or (g.name_machine_manager)::text = (current_user)::text) and ((g.name_machine_manager)::text = (current_user)::text or gc.id_group in (select * from allowed_groups)); - -grant select on users.v_group_composites to reservation_users; - - -commit transaction; diff --git a/database/sql/reservation/base-legal.sql b/database/sql/reservation/base-legal.sql deleted file mode 100644 index ac01c05..0000000 --- a/database/sql/reservation/base-legal.sql +++ /dev/null @@ -1,123 +0,0 @@ -/** Standardized SQL Structure - Legal */ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** Legal Types ***/ -create table managers.t_legal_types ( - id bigint not null, - id_external bigint, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cu_legal_types_id unique (id), - constraint cu_legal_types_name_machine unique (name_machine), - - constraint cc_legal_types_id check (id >= 0) -); - -create sequence managers.s_legal_types_id owned by managers.t_legal_types.id; -alter table managers.t_legal_types alter column id set default nextval('managers.s_legal_types_id'::regclass); - -grant select,insert,update on managers.t_legal_types to reservation_users_administer; -grant select,insert,update on managers.t_legal_types to reservation_users_manager; -grant select on managers.t_legal_types to reservation_users_auditor; -grant select,usage on managers.s_legal_types_id to reservation_users_administer; -grant select,usage on managers.s_legal_types_id to reservation_users_manager; - -create index ci_legal_types_deleted_not on managers.t_legal_types (id) - where is_deleted is not true; - -create index ci_legal_types_public on managers.t_legal_types (id) - where is_deleted is not true and is_locked is not true; - - -create view users.v_legal_types with (security_barrier=true) as - select id, id_external, name_machine, name_human from managers.t_legal_types - where is_deleted is not true and is_locked is not true; - -grant select on users.v_legal_types to reservation_users_requester; - - -insert into managers.t_legal_types (id, name_machine, name_human) values (0, 'none', 'None'); - - - -/*** Legal / Digital Signatures ***/ -create table managers.t_signatures ( - id bigint not null, - id_type bigint not null, - id_signer bigint not null, - id_request bigint, - - name_machine_signer varchar(128) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_deleted timestamp, - - /* @todo: PGP/GPG based signatures are planned but not currently implemented, the columns (fingerprint and signature) are created but are subject to major change. */ - fingerprint varchar(64), - signature text, - - constraint cu_signatures_id unique (id), - - constraint cc_signatures_id check (id > 0), - - constraint cf_signatures_id_creator foreign key (id_signer, name_machine_signer) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_signatures_id_type foreign key (id_type) references managers.t_legal_types (id) on delete restrict on update cascade, - constraint cf_signatures_id_request foreign key (id_request) references managers.t_requests (id) on delete restrict on update cascade -); - -create sequence managers.s_signatures_id owned by managers.t_signatures.id; -alter table managers.t_signatures alter column id set default nextval('managers.s_signatures_id'::regclass); - -grant select,insert,update on managers.t_signatures to reservation_users_administer; -grant select,insert,update on managers.t_signatures to reservation_users_manager; -grant select on managers.t_signatures to reservation_users_auditor; -grant select,usage on managers.s_signatures_id to reservation_users_administer; -grant select,usage on managers.s_signatures_id to reservation_users_manager; -grant usage on managers.s_signatures_id to reservation_users; - -create index ci_signatures_deleted_not on managers.t_signatures (id) - where is_deleted is not true; - -create index ci_signatures_approved on managers.t_signatures (id) - where is_deleted is not true and is_cancelled is not true and is_approved is true; - -create index ci_signatures_approved_cancelled on managers.t_signatures (id) - where is_deleted is not true and is_cancelled is true and is_approved is true; - - -/*** provide current user access to their own information ***/ -create view users.v_signatures_self with (security_barrier=true) as - select id, id_type, id_request, date_created, fingerprint, signature from managers.t_signatures - where is_deleted is not true and (name_machine_signer)::text = (current_user)::text; - -grant select on users.v_signatures_self to reservation_users; - - -/** provide current user access to insert their own associations **/ -create view users.v_signatures_self_insert with (security_barrier=true) as - select id, id_type, id_signer, name_machine_signer, id_request, fingerprint, signature from managers.t_signatures - where is_deleted is not true and (name_machine_signer)::text = (current_user)::text - with check option; - -grant insert on users.v_signatures_self_insert to reservation_users; diff --git a/database/sql/reservation/base-log_groups.sql b/database/sql/reservation/base-log_groups.sql deleted file mode 100644 index 61dfb60..0000000 --- a/database/sql/reservation/base-log_groups.sql +++ /dev/null @@ -1,107 +0,0 @@ -/** Standardized SQL Structure - Logs - Groups */ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** provide group activity logging ***/ -create table managers.t_log_groups ( - id bigint not null, - id_user bigint default 1 not null, - id_group bigint not null, - - name_machine_user varchar(128) not null, - - log_type bigint not null, - log_details json, - log_date timestamp default localtimestamp not null, - - constraint cp_log_groups_id primary key (id), - - constraint cc_log_groups_id check (id > 0), - - constraint cf_log_groups_id_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_log_groups_id_group foreign key (id_group) references managers.t_groups (id) on delete restrict on update cascade, - constraint cf_log_groups_log_type foreign key (log_type) references managers.t_log_types (id) on delete restrict on update cascade -); - -create sequence managers.s_log_groups_id owned by managers.t_log_groups.id; -alter table managers.t_log_groups alter column id set default nextval('managers.s_log_groups_id'::regclass); - -grant select on managers.t_log_groups to reservation_users_administer; -grant select on managers.t_log_groups to reservation_users_manager; -grant select on managers.t_log_groups to reservation_users_auditor; -grant select,usage on managers.s_log_groups_id to reservation_users_administer; -grant usage on managers.s_log_groups_id to reservation_users; - - -/** only allow select and insert for users when user id is current user **/ -create view users.v_log_groups_self with (security_barrier=true) as - select id, id_user, id_group, log_type, log_details, log_date from managers.t_log_groups - where (name_machine_user)::text = (current_user)::text; - -grant select on users.v_log_groups_self to reservation_users; - -create view users.v_log_groups_self_insert with (security_barrier=true) as - select id_user, id_group, name_machine_user, log_type, log_details from managers.t_log_groups - where (name_machine_user)::text = (current_user)::text - with check option; - -grant insert on users.v_log_groups_self_insert to reservation_users; - - - -/*** provide group user activity logging ***/ -create table managers.t_log_group_users ( - id bigint not null, - id_user bigint default 1 not null, - id_group bigint not null, - - name_machine_user varchar(128) not null, - - log_type bigint not null, - log_date timestamp default localtimestamp not null, - - constraint cp_log_group_users_id primary key (id), - - constraint cc_log_group_users_id check (id > 0), - - constraint cf_log_group_users_id_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_log_group_users_id_group foreign key (id_group) references managers.t_groups (id) on delete restrict on update cascade, - constraint cf_log_group_users_log_type foreign key (log_type) references managers.t_log_types (id) on delete restrict on update cascade -); - -create sequence managers.s_log_group_users_id owned by managers.t_log_group_users.id; -alter table managers.t_log_group_users alter column id set default nextval('managers.s_log_group_users_id'::regclass); - -grant select on managers.t_log_group_users to reservation_users_administer; -grant select on managers.t_log_group_users to reservation_users_manager; -grant select on managers.t_log_group_users to reservation_users_auditor; -grant select,usage on managers.s_log_group_users_id to reservation_users_administer; -grant usage on managers.s_log_group_users_id to reservation_users; - - -/** only allow select and insert for users when user id is current user **/ -create view users.v_log_group_users_self with (security_barrier=true) as - select id, id_user, id_group, log_type, log_date from managers.t_log_group_users - where (name_machine_user)::text = (current_user)::text; - -grant select on users.v_log_group_users_self to reservation_users; - -create view users.v_log_group_users_self_insert with (security_barrier=true) as - select id_user, id_group, name_machine_user, log_type from managers.t_log_group_users - where (name_machine_user)::text = (current_user)::text - with check option; - -grant insert on users.v_log_group_users_self_insert to reservation_users; - - - -commit transaction; diff --git a/database/sql/reservation/base-log_problems.sql b/database/sql/reservation/base-log_problems.sql deleted file mode 100644 index 16439b3..0000000 --- a/database/sql/reservation/base-log_problems.sql +++ /dev/null @@ -1,107 +0,0 @@ -/** Standardized SQL Structure - Logs - Problems */ -/** This depends on: base-users.sql **/ -/* The problem logs are intended for temporary reporting of problems and are meant to allow permanent deletion. */ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/** Provide a log of problems, which are defined by the software. **/ -/* @todo: shouldnt there be a problem type code? */ -create table managers.t_log_problems ( - id bigint not null, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - - constraint cp_log_problems_id primary key (id), - - constraint cc_log_problems_id check (id > 0), - - constraint cu_log_problems_name_machine unique (name_machine) -); - -grant select,insert,update,delete on managers.t_log_problems to reservation_users_administer; -grant select,insert,update,delete on managers.t_log_problems to reservation_users_manager; -grant select on managers.t_log_problems to reservation_users_auditor; - -/* @todo: it seems the views for allowing users to insert/delete problems needs to be created. */ - - - -/** Provide a log of problems, associated with a given user. **/ -create table managers.t_log_problems_users ( - id_problem bigint not null, - id_user bigint not null, - - name_machine_user varchar(128) not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - - log_details json, - - constraint cp_log_problems_users_id primary key (id_problem, id_user), - - constraint cu_log_problems_users_name_machine unique (name_machine_user), - - constraint cf_log_problems_users_id_problem foreign key (id_problem) references managers.t_log_problems (id) on delete restrict on update cascade, - constraint cf_log_problems_users_id_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete restrict on update cascade -); - -grant select,delete on managers.t_log_problems_users to reservation_users_administer; -grant select,delete on managers.t_log_problems_users to reservation_users_manager; -grant select on managers.t_log_problems_users to reservation_users_auditor; - - -/** only allow select, insert, and delete for users when user id is current user **/ -create view users.v_log_problems_users_self with (security_barrier=true) as - select id_problem, id_user, date_created, date_changed, log_details from managers.t_log_problems_users - where (name_machine_user)::text = (current_user)::text; - -grant select on users.v_log_problems_users_self to reservation_users; - - -create view users.v_log_problems_users_self_insert with (security_barrier=true) as - select id_problem, id_user, name_machine_user, date_changed, log_details from managers.t_log_problems_users - where (name_machine_user)::text = (current_user)::text - with check option; - -grant insert on users.v_log_problems_users_self_insert to reservation_users; - - -create view users.v_log_problems_users_self_delete with (security_barrier=true) as - select id_problem, id_user from managers.t_log_problems_users - where (name_machine_user)::text = (current_user)::text - with check option; - -grant delete on users.v_log_problems_users_self_delete to reservation_users; - - -/** automatically delete problems deleted from the table managers.t_log_problems_users **/ -create function managers.f_log_problems_users_delete() returns trigger security definer as $$ - begin - if (tg_op = 'DELETE') then - delete from managers.t_log_problems where id = old.id_problem; - return old; - end if; - - return null; - end; -$$ language plpgsql; - -create trigger tr_log_problems_users_delete - after delete on managers.t_log_problems_users - for each row execute procedure managers.f_log_problems_users_delete(); - - -commit transaction; diff --git a/database/sql/reservation/base-log_types.sql b/database/sql/reservation/base-log_types.sql deleted file mode 100644 index ab4d906..0000000 --- a/database/sql/reservation/base-log_types.sql +++ /dev/null @@ -1,269 +0,0 @@ -/** Standardized SQL Structure - Logs - Types */ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** provide log type id and names ***/ -create table managers.t_log_types ( - id bigint not null, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_log_types_id primary key (id), - - constraint cu_log_types_user unique (name_machine), - - constraint cc_log_types_id check (id >= 0) -); - -create sequence managers.s_log_types_id owned by managers.t_log_types.id; -alter table managers.t_log_types alter column id set default nextval('managers.s_log_types_id'::regclass); - -grant select,insert,update on managers.t_log_types to reservation_users_administer; -grant select on managers.t_log_types to reservation_users_manager; -grant select on managers.t_log_types to reservation_users_auditor; -grant select,usage on managers.s_log_types_id to reservation_users_administer; - -create index ci_log_types_deleted_not on managers.t_log_types (id) - where is_deleted is not true; - -create index ci_log_types_public on managers.t_log_types (id) - where is_deleted is not true and is_locked is not true; - -create view public.v_log_types with (security_barrier=true) as - select id, name_machine, name_human from managers.t_log_types - where is_deleted is not true and is_locked is not true; - -grant select on public.v_log_types to reservation_users; -grant select on public.v_log_types to public_users; - - -/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ -alter sequence managers.s_log_types_id start 1000; -alter sequence managers.s_log_types_id restart; - - -/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ -insert into managers.t_log_types (id, name_machine, name_human) values (0, 'none', 'None'); -insert into managers.t_log_types (id, name_machine, name_human) values (1, 'php', 'PHP'); -insert into managers.t_log_types (id, name_machine, name_human) values (2, 'theme', 'Theme'); -insert into managers.t_log_types (id, name_machine, name_human) values (3, 'cache', 'Cache'); -insert into managers.t_log_types (id, name_machine, name_human) values (4, 'javascript', 'Javascript'); -insert into managers.t_log_types (id, name_machine, name_human) values (5, 'ajax', 'AJAX'); -insert into managers.t_log_types (id, name_machine, name_human) values (6, 'sql', 'SQL'); -insert into managers.t_log_types (id, name_machine, name_human) values (7, 'form', 'Form'); -insert into managers.t_log_types (id, name_machine, name_human) values (8, 'form_validate', 'Form Validation'); -insert into managers.t_log_types (id, name_machine, name_human) values (9, 'form_submit', 'Form Submit'); -insert into managers.t_log_types (id, name_machine, name_human) values (10, 'load', 'Load'); -insert into managers.t_log_types (id, name_machine, name_human) values (11, 'save', 'Save'); -insert into managers.t_log_types (id, name_machine, name_human) values (12, 'render', 'Render'); -insert into managers.t_log_types (id, name_machine, name_human) values (13, 'client', 'Client'); -insert into managers.t_log_types (id, name_machine, name_human) values (14, 'add', 'Add'); -insert into managers.t_log_types (id, name_machine, name_human) values (15, 'create', 'Create'); -insert into managers.t_log_types (id, name_machine, name_human) values (16, 'change', 'Change'); -insert into managers.t_log_types (id, name_machine, name_human) values (17, 'delete', 'Delete'); -insert into managers.t_log_types (id, name_machine, name_human) values (18, 'redirect', 'Redirect'); -insert into managers.t_log_types (id, name_machine, name_human) values (19, 'login', 'Login'); -insert into managers.t_log_types (id, name_machine, name_human) values (20, 'logout', 'Logout'); -insert into managers.t_log_types (id, name_machine, name_human) values (21, 'session', 'Session'); -insert into managers.t_log_types (id, name_machine, name_human) values (22, 'database', 'Database'); -insert into managers.t_log_types (id, name_machine, name_human) values (23, 'not_found', 'Not Found'); -insert into managers.t_log_types (id, name_machine, name_human) values (24, 'access_denied', 'Access Denied'); -insert into managers.t_log_types (id, name_machine, name_human) values (25, 'removed', 'Removed'); -insert into managers.t_log_types (id, name_machine, name_human) values (26, 'locked', 'Locked'); -insert into managers.t_log_types (id, name_machine, name_human) values (27, 'timeout', 'Timeout'); -insert into managers.t_log_types (id, name_machine, name_human) values (28, 'expire', 'Expiration'); -insert into managers.t_log_types (id, name_machine, name_human) values (29, 'user', 'User'); -insert into managers.t_log_types (id, name_machine, name_human) values (30, 'error', 'Error'); -insert into managers.t_log_types (id, name_machine, name_human) values (31, 'content', 'Content'); -insert into managers.t_log_types (id, name_machine, name_human) values (32, 'workflow', 'Workflow'); -insert into managers.t_log_types (id, name_machine, name_human) values (33, 'draft', 'Draft'); -insert into managers.t_log_types (id, name_machine, name_human) values (34, 'clone', 'Clone'); -insert into managers.t_log_types (id, name_machine, name_human) values (35, 'publish', 'Publish'); -insert into managers.t_log_types (id, name_machine, name_human) values (36, 'revert', 'Revert'); -insert into managers.t_log_types (id, name_machine, name_human) values (37, 'validate', 'Validate'); -insert into managers.t_log_types (id, name_machine, name_human) values (38, 'approve', 'Approve'); -insert into managers.t_log_types (id, name_machine, name_human) values (39, 'password', 'Password'); -insert into managers.t_log_types (id, name_machine, name_human) values (40, 'revision', 'Revision'); -insert into managers.t_log_types (id, name_machine, name_human) values (41, 'search', 'Search'); -insert into managers.t_log_types (id, name_machine, name_human) values (42, 'access', 'Access'); -insert into managers.t_log_types (id, name_machine, name_human) values (43, 'unknown', 'Unknown'); - - - -/*** provide HTTP status codes ***/ -create table managers.t_log_http_status_codes ( - id smallint not null, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_log_http_status_codes_id primary key (id), - - constraint cu_log_http_status_codes_user unique (name_machine), - - constraint cc_log_http_status_codes_id check (id >= 0 and id < 600) -); - -create sequence managers.s_log_http_status_codes_id owned by managers.t_log_http_status_codes.id; -alter table managers.t_log_http_status_codes alter column id set default nextval('managers.s_log_http_status_codes_id'::regclass); - -grant select,insert,update on managers.t_log_http_status_codes to reservation_users_administer; -grant select on managers.t_log_http_status_codes to reservation_users_manager; -grant select on managers.t_log_http_status_codes to reservation_users_auditor; -grant select,usage on managers.s_log_http_status_codes_id to reservation_users_administer; - -create view public.v_log_http_status_codes with (security_barrier=true) as - select id, name_machine, name_human from managers.t_log_http_status_codes; - -grant select on public.v_log_http_status_codes to reservation_users; -grant select on public.v_log_http_status_codes to public_users; - - -/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (0, '0', 'Undefined'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (1, '1', 'Invalid'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (2, '2', 'Unknown'); - -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (100, '100', 'Continue'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (101, '101', 'Switching Protocols'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (102, '102', 'Processing'); - -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (200, '200', 'OK'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (201, '201', 'Created'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (202, '202', 'Accepted'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (203, '203', 'Non-Authoritative Information'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (204, '204', 'No Content'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (205, '205', 'Reset Content'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (206, '206', 'Partial Content'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (207, '207', 'Multi-Status'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (208, '208', 'Already Reported'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (226, '226', 'IM used'); - -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (300, '300', 'Multiple Choices'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (301, '301', 'Moved Permanently'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (302, '302', 'Found'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (303, '303', 'See Other'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (304, '304', 'Not Modified'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (305, '305', 'Use Proxy'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (306, '306', 'Switch Proxy'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (307, '307', 'Temporary Redirect'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (308, '308', 'Permanent Redirect'); - -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (400, '400', 'Bad Request'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (401, '401', 'Unauthorized'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (402, '402', 'Payment Required'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (403, '403', 'Forbidden'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (404, '404', 'Not Found'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (405, '405', 'Method Not Allowed'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (406, '406', 'Not Acceptable'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (407, '407', 'Proxy Authentication Required'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (408, '408', 'Request Timeout'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (409, '409', 'Conflict'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (410, '410', 'Gone'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (411, '411', 'Length Required'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (412, '412', 'Precondition Failed'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (413, '413', 'Payload Too Large'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (414, '414', 'Request-URI Too Long'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (415, '415', 'Unsupported Media Type'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (416, '416', 'Requested Range Not Satisfiable'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (417, '417', 'Expectation Failed'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (422, '422', 'Misdirected Request'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (423, '423', 'Locked'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (424, '424', 'Failed Dependency'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (426, '426', 'Upgrade Required'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (428, '428', 'Precondition Required'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (429, '429', 'Too Many Requests'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (431, '431', 'Request Header Fields Too Large'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (451, '451', 'Unavailable For Legal Reasons'); - -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (500, '500', 'Internal Server Error'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (501, '501', 'Not Implemented'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (502, '502', 'Bad Gateway'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (503, '503', 'Service Unavailable'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (504, '504', 'Gateway Timeout'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (505, '505', 'HTTP Version Not Supported'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (506, '506', 'Variant Also Negotiates'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (507, '507', 'Insufficient Storage'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (508, '508', 'Loop Detected'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (510, '510', 'Not Extended'); -insert into managers.t_log_http_status_codes (id, name_machine, name_human) values (511, '511', 'Network Authentication Required'); - - - -/*** provide log severity level id and names ***/ -create table managers.t_log_severity_levels ( - id bigint not null, - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_log_severity_levels_id primary key (id), - - constraint cu_log_severity_levels_user unique (name_machine), - - constraint cc_log_severity_levels_id check (id >= 0) -); - -create sequence managers.s_log_severity_levels_id owned by managers.t_log_severity_levels.id; -alter table managers.t_log_severity_levels alter column id set default nextval('managers.s_log_severity_levels_id'::regclass); - -grant select,insert,update on managers.t_log_severity_levels to reservation_users_administer; -grant select on managers.t_log_severity_levels to reservation_users_manager; -grant select on managers.t_log_severity_levels to reservation_users_auditor; -grant select,usage on managers.s_log_severity_levels_id to reservation_users_administer; - -create view users.v_log_severity_levels with (security_barrier=true) as - select id, name_machine, name_human from managers.t_log_severity_levels - where is_deleted is false; - -grant select on users.v_log_severity_levels to reservation_users; -grant select on users.v_log_severity_levels to public_users; - - -/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ -alter sequence managers.s_log_severity_levels_id start 1000; -alter sequence managers.s_log_severity_levels_id restart; - - -/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (0, 'none', 'None'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (1, 'information', 'Information'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (2, 'notice', 'Notice'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (3, 'debug', 'Debug'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (4, 'warning', 'Warning'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (5, 'error', 'Error'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (6, 'alert', 'Alert'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (7, 'critical', 'Critical'); -insert into managers.t_log_severity_levels (id, name_machine, name_human) values (8, 'emergency', 'Emergency'); - - - -commit transaction; diff --git a/database/sql/reservation/base-log_users.sql b/database/sql/reservation/base-log_users.sql deleted file mode 100644 index d3996ab..0000000 --- a/database/sql/reservation/base-log_users.sql +++ /dev/null @@ -1,249 +0,0 @@ -/** Standardized SQL Structure - Logs */ -/** This depends on: base-users.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** provide user activity logging ***/ -create table managers.t_log_users ( - id bigint not null, - id_user bigint default 1 not null, - - name_machine_user varchar(128) not null, - - log_title varchar(512) not null, - log_type bigint not null, - log_severity bigint not null, - log_details json, - log_date timestamp default localtimestamp not null, - - request_client public.ct_client not null, - response_code smallint not null default 0, - - constraint cp_log_users_id primary key (id), - - constraint cc_log_users_id check (id > 0), - constraint cc_log_users_log_severity check (log_severity > 0), - - constraint cf_log_users_id_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_log_users_log_type foreign key (log_type) references managers.t_log_types (id) on delete restrict on update cascade, - constraint cf_log_users_log_severity foreign key (log_severity) references managers.t_log_severity_levels (id) on delete restrict on update cascade, - constraint cf_log_users_response_code foreign key (response_code) references managers.t_log_http_status_codes (id) on delete restrict on update cascade -); - -create sequence managers.s_log_users_id owned by managers.t_log_users.id; -alter table managers.t_log_users alter column id set default nextval('managers.s_log_users_id'::regclass); - -grant select on managers.t_log_users to reservation_users_administer; -grant select on managers.t_log_users to reservation_users_manager; -grant select on managers.t_log_users to reservation_users_auditor; -grant select,usage on managers.s_log_users_id to reservation_users_administer; -grant usage on managers.s_log_users_id to reservation_users; -grant usage on managers.s_log_users_id to public_users; - -create index ci_log_users_type_php on managers.t_log_users (id) - where log_type = 1; - -create index ci_log_users_type_theme on managers.t_log_users (id) - where log_type = 2; - -create index ci_log_users_type_cache on managers.t_log_users (id) - where log_type = 3; - -create index ci_log_users_type_javascript on managers.t_log_users (id) - where log_type = 4; - -create index ci_log_users_type_ajax on managers.t_log_users (id) - where log_type = 5; - -create index ci_log_users_type_sql on managers.t_log_users (id) - where log_type = 6; - -create index ci_log_users_type_redirect on managers.t_log_users (id) - where log_type = 16; - -create index ci_log_users_type_login on managers.t_log_users (id) - where log_type = 17; - -create index ci_log_users_type_logout on managers.t_log_users (id) - where log_type = 18; - -create index ci_log_users_type_user on managers.t_log_users (id) - where log_type = 27; - -create index ci_log_users_type_error on managers.t_log_users (id) - where log_type = 28; - -create index ci_log_users_type_content on managers.t_log_users (id) - where log_type = 29; - -create index ci_log_users_type_workflow on managers.t_log_users (id) - where log_type = 30; - -create index ci_log_users_type_search on managers.t_log_users (id) - where log_type = 39; - -create index ci_log_users_response_code_200 on managers.t_log_users (id) - where response_code = 200; - -create index ci_log_users_response_code_403 on managers.t_log_users (id) - where response_code = 403; - -create index ci_log_users_response_code_404 on managers.t_log_users (id) - where response_code = 404; - -create index ci_log_users_response_code_410 on managers.t_log_users (id) - where response_code = 410; - -create index ci_log_users_response_code_500 on managers.t_log_users (id) - where response_code = 500; - -create index ci_log_users_response_code_503 on managers.t_log_users (id) - where response_code = 503; - -create index ci_log_users_response_code_normal on managers.t_log_users (id) - where response_code in (200, 201, 202, 304); - -create index ci_log_users_response_code_redirects on managers.t_log_users (id) - where response_code in (301, 302, 303, 307, 308); - -create index ci_log_users_response_code_notable on managers.t_log_users (id) - where response_code in (400, 403, 404, 410, 500, 503); - - -/** only allow select and insert for users when user id is current user **/ -create view users.v_log_users_self with (security_barrier=true) as - select id, id_user, log_title, log_type, log_severity, log_details, log_date, request_client, response_code from managers.t_log_users - where (name_machine_user)::text = (current_user)::text; - -grant select on users.v_log_users_self to reservation_users; - -create view users.v_log_users_self_insert with (security_barrier=true) as - select id_user, name_machine_user, log_title, log_type, log_severity, log_details, request_client, response_code from managers.t_log_users - where (name_machine_user)::text = (current_user)::text - with check option; - -grant insert on users.v_log_users_self_insert to reservation_users; - - -/** only allow insert for the public user **/ -create view public.v_log_users_self_insert with (security_barrier=true) as - select id_user, name_machine_user, log_title, log_type, log_severity, log_details, request_client, response_code from managers.t_log_users - where id_user = 1 and name_machine_user = 'unknown' - with check option; - -grant insert on public.v_log_users_self_insert to public_users; - - -/** only allow insert for the system user **/ -create view system.v_log_users_self_insert with (security_barrier=true) as - select id_user, name_machine_user, log_title, log_type, log_severity, log_details, request_client, response_code from managers.t_log_users - where id_user = 2 and name_machine_user = 'system' - with check option; - -grant insert on system.v_log_users_self_insert to reservation_users; - - - -/*** provide access activity logging ***/ -create table managers.t_log_activity ( - id bigint not null, - id_user bigint default 1 not null, - - name_machine_user varchar(128) not null, - - request_path varchar(512) not null, - request_arguments varchar(512) not null, - request_date timestamp default localtimestamp not null, - request_client public.ct_client not null, - request_headers json, - - response_headers json, - response_code smallint not null default 0, - - constraint cp_log_activity_id primary key (id), - - constraint cc_log_activity_id check (id > 0), - - constraint cf_log_activity_id_user foreign key (id_user, name_machine_user) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_log_activity_response_code foreign key (response_code) references managers.t_log_http_status_codes (id) on delete restrict on update cascade -); - -create sequence managers.s_log_activity_id owned by managers.t_log_activity.id; -alter table managers.t_log_activity alter column id set default nextval('managers.s_log_activity_id'::regclass); - -grant select on managers.t_log_activity to reservation_users_administer; -grant select on managers.t_log_activity to reservation_users_manager; -grant select on managers.t_log_activity to reservation_users_auditor; -grant select,usage on managers.s_log_activity_id to reservation_users_administer; -grant usage on managers.s_log_activity_id to reservation_users; -grant usage on managers.s_log_activity_id to public_users; - -create index ci_log_activity_response_code_4xx on managers.t_log_activity (id) - where response_code >= 400 and response_code < 500; - -create index ci_log_activity_response_code_403 on managers.t_log_activity (id) - where response_code = 403; - -create index ci_log_activity_response_code_404 on managers.t_log_activity (id) - where response_code = 404; - -create index ci_log_activity_response_code_410 on managers.t_log_activity (id) - where response_code = 410; - -create index ci_log_activity_response_code_5xx on managers.t_log_activity (id) - where response_code >= 500 and response_code < 600; - -create index ci_log_activity_response_code_500 on managers.t_log_activity (id) - where response_code = 500; - -create index ci_log_activity_response_code_503 on managers.t_log_activity (id) - where response_code = 503; - -create index ci_log_activity_response_code_notable on managers.t_log_activity (id) - where response_code in (403, 404, 410, 500, 503); - - - -/** only allow select and insert for users when user id is current user **/ -create view users.v_log_activity_self with (security_barrier=true) as - select id, id_user, request_path, request_arguments, request_date, request_client, request_headers, response_headers, response_code from managers.t_log_activity - where (name_machine_user)::text = (current_user)::text; - -grant select on users.v_log_activity_self to reservation_users; - -create view users.v_log_activity_self_insert with (security_barrier=true) as - select id_user, name_machine_user, request_path, request_arguments, request_client, request_headers, response_headers, response_code from managers.t_log_activity - where (name_machine_user)::text = (current_user)::text - with check option; - -grant insert on users.v_log_activity_self_insert to reservation_users; - - -/** only allow insert for the public user **/ -create view public.v_log_activity_self_insert with (security_barrier=true) as - select id_user, name_machine_user, request_path, request_arguments, request_client, request_headers, response_headers, response_code from managers.t_log_activity - where id_user = 1 and name_machine_user = 'unknown' - with check option; - -grant insert on public.v_log_activity_self_insert to public_users; - - -/** only allow insert for the system user **/ -create view system.v_log_activity_self_insert with (security_barrier=true) as - select id_user, name_machine_user, request_path, request_arguments, request_client, request_headers, response_headers, response_code from managers.t_log_activity - where id_user = 2 and name_machine_user = 'system' - with check option; - -grant insert on system.v_log_activity_self_insert to reservation_users; - - - -commit transaction; diff --git a/database/sql/reservation/base-main.sql b/database/sql/reservation/base-main.sql deleted file mode 100644 index 266af79..0000000 --- a/database/sql/reservation/base-main.sql +++ /dev/null @@ -1,205 +0,0 @@ -/** Standardized SQL Structure - Main */ -/** This depends on: base-first.sql **/ -/** users will be called 'reservation_user_X' where X is the name, so that regex can be used on this script at a later time and mass rename these as necessary. - @todo: prepare for Row Level Security Policies as defined here: https://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.5 and here: http://www.depesz.com/2014/10/02/waiting-for-9-5-row-level-security-policies-rls/ - All roles associated with a user can be determined with: "select pr.rolname from pg_auth_members pam inner join pg_roles pr on (pam.roleid = pr.oid) inner join pg_roles pr_u on (pam.member = pr_u.oid) where pr_u.rolname = user;" - For performance reasons, name_machine is not directly assigned as a foreign key, only the id_user is. This can result in out of sync issues if the name_machine is ever changed. To avoid this, prediodically run a cron job to analyze all the entries and fix conflicts. (name_human may also fall into this situation in certain circumstances.) - @todo: investigate and compare use of btree and gist for indexes used. This will require populating the data and comparing 'explain analyze' performance results. btree is the default and gist can be added by inserting 'using gist' for the index after the 'on name' part. - Example of date selection format: select to_char('now'::timestamp, 'YYYY/MM/DD HH12:MI:SS am '); (see: http://www.postgresql.org/docs/9.4/static/functions-formatting.html) - @todo: use http://www.postgresql.org/docs/9.4/static/functions-formatting.html and daterange for calendar dates and times (GiST is good for indexing ranges) (consider 'overlaps') (see: http://www.postgresql.org/docs/9.4/interactive/rangetypes.html#RANGETYPES-GIST). - @todo: use BRIN (pg 9.5) indexing for indexes used to optimize specific table views or for tables expected to get very large (content, logs, files, etc..) (see: https://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.5) -*/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/** Schemas **/ -create schema system authorization reservation_user; -create schema administers authorization reservation_users_administer; -create schema managers authorization reservation_users_manager; -create schema auditors authorization reservation_users_auditor; -create schema publishers authorization reservation_users_publisher; -create schema insurer authorization reservation_users_insurer; -create schema financer authorization reservation_users_financer; -create schema reviewers authorization reservation_users_reviewer; -create schema editors authorization reservation_users_editor; -create schema drafters authorization reservation_users_drafter; -create schema requesters authorization reservation_users_requester; -create schema users authorization reservation_users; - -revoke create on schema system from reservation_user; -revoke create on schema administers from reservation_users_administer; -revoke create on schema auditors from reservation_users_auditor; -revoke create on schema managers from reservation_users_manager; -revoke create on schema publishers from reservation_users_publisher; -revoke create on schema insurer from reservation_users_insurer; -revoke create on schema financer from reservation_users_financer; -revoke create on schema reviewers from reservation_users_reviewer; -revoke create on schema editors from reservation_users_editor; -revoke create on schema drafters from reservation_users_drafter; -revoke create on schema requesters from reservation_users_requester; -revoke create on schema users from reservation_users; - -grant usage on schema system to reservation_user; -grant usage on schema administers to reservation_users_administer; -grant usage on schema managers to reservation_users_manager; -grant usage on schema auditors to reservation_users_auditor; -grant usage on schema publishers to reservation_users_publisher; -grant usage on schema insurer to reservation_users_insurer; -grant usage on schema financer to reservation_users_financer; -grant usage on schema reviewers to reservation_users_reviewer; -grant usage on schema editors to reservation_users_editor; -grant usage on schema drafters to reservation_users_drafter; -grant usage on schema requesters to reservation_users_requester; -grant usage on schema users to reservation_users; - -grant create,usage on schema system to postgres; -grant create,usage on schema administers to postgres; -grant create,usage on schema managers to postgres; -grant create,usage on schema auditors to postgres; -grant create,usage on schema publishers to postgres; -grant create,usage on schema insurer to postgres; -grant create,usage on schema financer to postgres; -grant create,usage on schema reviewers to postgres; -grant create,usage on schema editors to postgres; -grant create,usage on schema drafters to postgres; -grant create,usage on schema requesters to postgres; -grant create,usage on schema users to postgres; - - -/** Composite Types **/ -create type public.ct_name_person as ( - prefix varchar(32), - first varchar(64), - middle varchar(64), - last varchar(64), - suffix varchar(32), - complete varchar(256) -); - -create type public.ct_client as ( - ip inet, - port int, - agent varchar(256) -); - -create type public.ct_email as ( - name varchar(128), - domain varchar(128), - private boolean -); - -create type public.ct_text as ( - content text, - context bigint -); - -create type public.ct_location as ( - building bigint, - room bigint[] -); - -create type public.ct_date as ( - date timestamp, - time_start timestamp, - time_stop timestamp -); - -create type public.ct_date_context as ( - date timestamp, - time_start timestamp, - time_stop timestamp, - context bigint -); - -create type public.ct_phone_number as ( - country smallint, - area smallint, - number smallint, - extension smallint -); - -create type public.ct_phone_number_context as ( - country smallint, - area smallint, - number smallint, - extension smallint, - context bigint -); - -create type public.ct_money_context as ( - money money, - context bigint -); - -create type public.ct_field_fees as ( - needed bool, - quantity bigint, - days bigint, - hours bigint, - amount money -); - -create type public.ct_field_used_with_contact as ( - used bool, - email text, - name text, - phone public.ct_phone_number -); - -create type public.ct_field_needed_with_total as ( - needed bool, - total bigint -); - -create type public.ct_field_needed_with_details as ( - needed bool, - details text -); - -create type public.ct_field_used_with_details as ( - used bool, - details text -); - -create type public.ct_field_used_with_designer as ( - used bool, - designer text -); - -create type public.ct_field_served_with_caterer as ( - served bool, - caterer text -); - -create type public.ct_field_generated_with_types as ( - generated bool, - types bigint[] -); - -create type public.ct_field_needed_with_types as ( - needed bool, - types bigint[] -); - -create type public.ct_field_needed_with_types_and_microphone as ( - needed bool, - types bigint[], - microphone bigint -); - -create type public.ct_field_insurance as ( - needed bool, - provided bool -); - - - -commit transaction; diff --git a/database/sql/reservation/base-paths.sql b/database/sql/reservation/base-paths.sql deleted file mode 100644 index 0dde698..0000000 --- a/database/sql/reservation/base-paths.sql +++ /dev/null @@ -1,123 +0,0 @@ -/** Standardized SQL Structure - Content **/ -/** This depends on: base-groups.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,publishers,insurers,financers,reviewers,drafters,users,public; -set datestyle to us; - - - -/*** provide path type id and names ***/ -create table managers.t_path_types ( - id bigint not null, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_path_types_id primary key (id), - - constraint cu_path_types_user unique (name_machine), - - constraint cc_path_types_id check (id > 0) -); - -create sequence managers.s_path_types_id owned by managers.t_path_types.id; -alter table managers.t_path_types alter column id set default nextval('managers.s_path_types_id'::regclass); - -grant select,insert,update on managers.t_path_types to reservation_users_administer; -grant select on managers.t_path_types to reservation_users_manager; -grant select on managers.t_path_types to reservation_users_auditor; -grant select,usage on managers.s_path_types_id to reservation_users_administer; - -create index ci_path_types_deleted_not on managers.t_path_types (id) - where is_deleted is not true; - -create index ci_path_types_public on managers.t_path_types (id) - where is_deleted is not true and is_locked is not true; - -create view public.v_path_types with (security_barrier=true) as - select id, name_machine, name_human from managers.t_path_types - where is_deleted is not true and is_locked is not true; - -grant select on public.v_path_types to reservation_users; -grant select on public.v_path_types to public_users; - - -/* @todo: pre-populate the path types. */ - - -/* @todo: with its current design, the id_access field needs a trigger to maintain its up to date status if/when group ids change. */ -/* @todo: come up with a design for dynamic path management via users/managers (as opposed to hardcoded paths in source). */ -/*** provide paths table (@todo: this is added as a stub and needs to be finished) ***/ -create table managers.t_paths ( - id bigint not null, - id_type bigint not null, - id_group bigint, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_private boolean default true not null, - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_paths_id primary key (id), - - constraint cu_paths_name_machine unique (name_machine), - - constraint cc_paths_id check (id > 0), - - constraint cf_paths_id_type foreign key (id_type) references managers.t_path_types (id) on delete restrict on update cascade, - constraint cf_paths_id_group foreign key (id_group) references managers.t_groups (id) on delete restrict on update cascade -); - -create sequence managers.s_paths_id owned by managers.t_paths.id; -alter table managers.t_paths alter column id set default nextval('managers.s_paths_id'::regclass); - -grant select on managers.t_paths to reservation_users_administer; -grant select on managers.t_paths to reservation_users_manager; -grant select on managers.t_paths to reservation_users_auditor; -grant select,usage on managers.s_paths_id to reservation_users_administer; -grant usage on managers.s_paths_id to reservation_users; - -create index ci_paths_deleted_not on managers.t_paths (id) - where is_deleted is not true; - -create index ci_paths_private_not on managers.t_paths (id) - where is_deleted is not true and is_private is not true; - -create index ci_paths_locked_not on managers.t_paths (id) - where is_deleted is not true and is_locked is not true; - -create index ci_paths_public on managers.t_paths (id) - where is_deleted is not true and is_locked is not true and is_private is not true; - -create view users.v_paths with (security_barrier=true) as - with allowed_groups as (select id from users.v_groups_self) - select id, id_type, id_group, name_machine, name_human, is_private, date_created, date_changed from managers.t_paths - where is_deleted is not true and (is_locked is not true or id_group in (select * from allowed_groups)) and (is_private is not true or (is_private is true and id_group in (select * from allowed_groups))); - -grant select on users.v_paths to reservation_users; - -create view public.v_paths with (security_barrier=true) as - select id, id_type, name_machine, name_human from managers.t_paths - where is_deleted is not true and is_locked is not true and is_private is not true; - -grant select on public.v_path_types to public_users; - -commit transaction; diff --git a/database/sql/reservation/base-requests.sql b/database/sql/reservation/base-requests.sql deleted file mode 100644 index 0c07325..0000000 --- a/database/sql/reservation/base-requests.sql +++ /dev/null @@ -1,199 +0,0 @@ -/** Standardized SQL Structure - Content **/ -/** This depends on: base-fields.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/*** Request: Type ***/ -create table managers.t_request_types ( - id bigint not null, - id_external bigint, - - name_machine varchar(128) not null, - name_human varchar(256) not null, - - is_locked boolean default false not null, - is_deleted boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cu_request_types_id unique (id), - constraint cu_request_types_name_machine unique (name_machine), - - constraint cc_request_types_id check (id >= 0) -); - -create sequence managers.s_request_types_id owned by managers.t_request_types.id; -alter table managers.t_request_types alter column id set default nextval('managers.s_request_types_id'::regclass); - -grant select,insert,update on managers.t_request_types to reservation_users_administer; -grant select,insert,update on managers.t_request_types to reservation_users_manager; -grant select on managers.t_request_types to reservation_users_auditor; -grant select,usage on managers.s_request_types_id to reservation_users_administer; -grant select,usage on managers.s_request_types_id to reservation_users_manager; - -create index ci_request_types_deleted_not on managers.t_request_types (id) - where is_deleted is not true; - -create index ci_request_types_public on managers.t_request_types (id) - where is_deleted is not true and is_locked is not true; - - -create view requesters.v_request_types with (security_barrier=true) as - select id, id_external, name_machine, name_human from managers.t_request_types - where is_deleted is not true and is_locked is not true; - -grant select on requesters.v_request_types to reservation_users_requester; - -/** @todo: consider creating default request types **/ -insert into managers.t_request_types (id, name_machine, name_human) values (0, 'none', 'None'); - - - -/*** Requests ***/ -create table managers.t_requests ( - id bigint not null, - id_revision bigint not null, - id_type bigint not null, - id_association bigint not null, - id_creator bigint not null, - - name_machine varchar(128) not null, - name_machine_creator varchar(128) not null, - name_human varchar(256) not null, - - is_approved boolean default false not null, - is_cancelled boolean default false not null, - is_deleted boolean default false not null, - is_denied boolean default false not null, - is_troubled boolean default false not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_synced timestamp default localtimestamp not null, - date_deleted timestamp, - - field_additional text not null, - field_dates public.ct_date_context[] not null, - field_fees_custodial public.ct_field_fees[] not null, - field_fees_equipment public.ct_field_fees[] not null, - field_fees_facilities public.ct_field_fees[] not null, - field_fees_grounds public.ct_field_fees[] not null, - field_fees_maintenance public.ct_field_fees[] not null, - field_fees_other public.ct_field_fees[] not null, - field_fees_security public.ct_field_fees[] not null, - field_fees_university public.ct_field_fees[] not null, - field_location public.ct_location[] not null, - field_information_attendance bigint not null, - field_information_organization bigint not null, - field_information_adviser_approval bool not null, - field_insurance_affiliated public.ct_field_insurance not null, - field_insurance_contractor public.ct_field_insurance not null, - field_insurance_unaffiliated public.ct_field_insurance not null, - field_plans_activities text not null, - field_plans_audience bigint not null, - field_plans_description text not null, - field_presentation_designing_material public.ct_field_used_with_contact not null, - field_presentation_external_audio_person public.ct_field_used_with_contact not null, - field_presentation_production public.ct_field_used_with_contact not null, - field_presentation_printed_material public.ct_field_used_with_details not null, - field_presentation_publicity public.ct_field_needed_with_types not null, - field_presentation_technical_equipment public.ct_field_needed_with_types_and_microphone not null, - field_presentation_university_logo public.ct_field_used_with_designer not null, - field_registration_revenue public.ct_field_generated_with_types not null, - field_registration_phone public.ct_phone_number not null, - field_registration_required bool not null, - field_registration_ticket_dates public.ct_date_context[] not null, - field_registration_ticket_phone public.ct_phone_number_context not null, - field_registration_ticket_price public.ct_money_context[] not null, - field_registration_ticket_website text not null, - field_registration_website text not null, - field_setup_other_tables public.ct_field_needed_with_details not null, - field_setup_parking_assistance public.ct_field_needed_with_details not null, - field_setup_podium public.ct_field_needed_with_details not null, - field_setup_portable_stage public.ct_field_needed_with_details not null, - field_setup_rectangular_tables_8ft public.ct_field_needed_with_total not null, - field_setup_road_closures public.ct_field_needed_with_details not null, - field_setup_round_tables_8ft public.ct_field_needed_with_total not null, - field_setup_security public.ct_field_needed_with_details not null, - field_setup_special_requests public.ct_field_needed_with_details not null, - field_setup_standard_blue_chairs public.ct_field_needed_with_total not null, - field_services_alcohol_served public.ct_field_served_with_caterer not null, - field_services_food public.ct_field_served_with_caterer not null, - field_services_open_flames public.ct_field_used_with_details not null, - field_title text not null, - - in_state bigint not null, - in_step bigint not null, - - constraint cu_requests_id unique (id), - constraint cu_requests_name_machine unique (name_machine), - - constraint cc_requests_id check (id > 0), - constraint cc_requests_approved check ((is_approved is true and is_denied is not true) or (is_approved is not true and is_denied is true)), - - constraint cf_requests_id_creator foreign key (id_creator, name_machine_creator) references administers.t_users (id, name_machine) on delete restrict on update cascade, - constraint cf_requests_request_type foreign key (id_type) references managers.t_request_types (id) on delete restrict on update cascade, - constraint cf_requests_association foreign key (id_association) references managers.t_associations (id) on delete restrict on update cascade -); - -create sequence managers.s_requests_id owned by managers.t_requests.id; -alter table managers.t_requests alter column id set default nextval('managers.s_requests_id'::regclass); - -grant select,insert,update on managers.t_requests to reservation_users_administer; -grant select,insert,update on managers.t_requests to reservation_users_manager; -grant select on managers.t_requests to reservation_users_auditor; -grant select,usage on managers.s_requests_id to reservation_users_administer; -grant select,usage on managers.s_requests_id to reservation_users_manager; -grant usage on managers.s_requests_id to reservation_users; - - -/** @todo: create all appropriate views (and indexes), including individual views for is_cancelled, is_deleted, is_published, is_unpublished, is_denied, and is_troubled **/ -create index ci_requests_deleted_not on managers.t_requests (id) - where is_deleted is not true; - -create index ci_requests_approved on managers.t_requests (id) - where is_deleted is not true and is_cancelled is not true and is_approved is true; - -create index ci_requests_approved_cancelled on managers.t_requests (id) - where is_deleted is not true and is_cancelled is true and is_approved is true; - - -/*** approved requests (but not cancelled) ***/ -create view users.v_requests_approved with (security_barrier=true) as - select id, id_revision, id_type, id_association, name_machine, name_human, is_troubled, date_created, date_changed, field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, in_state, in_step from managers.t_requests - where is_deleted is not true and is_cancelled is not true and is_approved is true; - -grant select on users.v_requests_approved to reservation_users; - - -/*** approved requests (only cancelled) ***/ -create view users.v_requests_approved_cancelled with (security_barrier=true) as - select id, id_revision, id_type, id_association, name_machine, name_human, is_troubled, date_created, date_changed, field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, in_state, in_step from managers.t_requests - where is_deleted is not true and is_cancelled is true and is_approved is true; - -grant select on users.v_requests_approved to reservation_users; - - -/*** requests the current user can manage (do determine this, the associations table is join and because it is already joined, add the additional fields provided by assocation). ***/ -/* @todo: review this to see if I can come up with a better way than doing an inner join on associations. */ -create view users.v_requests_self with (security_barrier=true) as - select r.id, r.id_revision, r.id_type, r.id_association, a.id_group, a.id_coordinator, r.name_machine, a.name_machine_coordinator, r.name_human, a.name_human as name_human_association, r.is_troubled, r.date_created, r.date_changed, r.field_additional, r.field_dates, r.field_fees_custodial, r.field_fees_equipment, r.field_fees_facilities, r.field_fees_grounds, r.field_fees_maintenance, r.field_fees_other, r.field_fees_security, r.field_fees_university, r.field_location, r.field_information_attendance, r.field_information_organization, r.field_information_adviser_approval, r.field_insurance_affiliated, r.field_insurance_contractor, r.field_insurance_unaffiliated, r.field_plans_activities, r.field_plans_audience, r.field_plans_description, r.field_presentation_designing_material, r.field_presentation_external_audio_person, r.field_presentation_production, r.field_presentation_printed_material, r.field_presentation_publicity, r.field_presentation_technical_equipment, r.field_presentation_university_logo, r.field_registration_revenue, r.field_registration_phone, r.field_registration_required, r.field_registration_ticket_dates, r.field_registration_ticket_phone, r.field_registration_ticket_price, r.field_registration_ticket_website, r.field_registration_website, r.field_setup_other_tables, r.field_setup_parking_assistance, r.field_setup_podium, r.field_setup_portable_stage, r.field_setup_rectangular_tables_8ft, r.field_setup_road_closures, r.field_setup_round_tables_8ft, r.field_setup_security, r.field_setup_special_requests, r.field_setup_standard_blue_chairs, r.field_services_alcohol_served, r.field_services_food, r.field_services_open_flames, r.field_title, a.field_affiliation, a.field_classification, r.in_state, r.in_step from managers.t_requests r - inner join managers.t_associations a on r.id_association = a.id - where r.is_deleted is not true and a.is_deleted is not true and ((id_group is null and (a.name_machine_manager)::text = (current_user)::text) or a.id in (select id from users.v_associations_self)); - -grant select on users.v_requests_self to reservation_users; - - -/** @todo: create "managers.t_requests_revision" that is identical to "managers.t_requests" with all the columns allowed to be null. **/ - -commit transaction; diff --git a/database/sql/reservation/base-statistics.sql b/database/sql/reservation/base-statistics.sql deleted file mode 100644 index 2b2751c..0000000 --- a/database/sql/reservation/base-statistics.sql +++ /dev/null @@ -1,192 +0,0 @@ -/** Standardized SQL Structure - Statistics **/ -/** This depends on: base-logs.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - -/** Provide status code statistics **/ -create table managers.t_statistics_http_status_codes ( - code smallint not null, - count bigint not null default 0, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_statistics_http_status_codes_code primary key (code), - - constraint cc_statistics_http_status_codes_count check (count >= 0), - - constraint cf_statistics_http_status_codes_code foreign key (code) references managers.t_log_http_status_codes (id) on delete restrict on update cascade -); - -grant select,insert,update on managers.t_statistics_http_status_codes to reservation_users_administer; -grant select,insert,update on managers.t_statistics_http_status_codes to reservation_users_manager; -grant select on managers.t_statistics_http_status_codes to reservation_users_auditor; - - -/** create an auto-update trigger. set the role to reservation_users_manager so that the function runs as that role when using "SECURITY DEFINER". The reservation_users_manager must also have the appropriate create privileges. **/ -grant create on schema managers to reservation_users_manager; -set role reservation_users_manager; - -create function managers.f_statistics_http_status_codes_insert() returns trigger security definer as $$ - begin - if (tg_op = 'INSERT') then - update managers.t_statistics_http_status_codes set count = (select count + 1 as count from managers.t_statistics_http_status_codes where code = new.response_code) where code = new.response_code; - if not found then - insert into managers.t_statistics_http_status_codes (code, count) values (new.response_code, 1); - if not found then return null; end if; - end if; - - return new; - end if; - - return null; - end; -$$ language plpgsql; - -create trigger tr_log_activity_insert_statistics_http_status_codes - after insert on managers.t_log_activity - for each row execute procedure managers.f_statistics_http_status_codes_insert(); - -create trigger tr_log_users_insert_statistics_http_status_codes - after insert on managers.t_log_users - for each row execute procedure managers.f_statistics_http_status_codes_insert(); - - -/** create all of the known codes, initializing them to 0. **/ -insert into managers.t_statistics_http_status_codes (code) values (0); -insert into managers.t_statistics_http_status_codes (code) values (1); -insert into managers.t_statistics_http_status_codes (code) values (2); - -insert into managers.t_statistics_http_status_codes (code) values (100); -insert into managers.t_statistics_http_status_codes (code) values (101); -insert into managers.t_statistics_http_status_codes (code) values (102); - -insert into managers.t_statistics_http_status_codes (code) values (200); -insert into managers.t_statistics_http_status_codes (code) values (201); -insert into managers.t_statistics_http_status_codes (code) values (202); -insert into managers.t_statistics_http_status_codes (code) values (203); -insert into managers.t_statistics_http_status_codes (code) values (204); -insert into managers.t_statistics_http_status_codes (code) values (205); -insert into managers.t_statistics_http_status_codes (code) values (206); -insert into managers.t_statistics_http_status_codes (code) values (207); -insert into managers.t_statistics_http_status_codes (code) values (208); -insert into managers.t_statistics_http_status_codes (code) values (226); - -insert into managers.t_statistics_http_status_codes (code) values (300); -insert into managers.t_statistics_http_status_codes (code) values (301); -insert into managers.t_statistics_http_status_codes (code) values (302); -insert into managers.t_statistics_http_status_codes (code) values (303); -insert into managers.t_statistics_http_status_codes (code) values (304); -insert into managers.t_statistics_http_status_codes (code) values (305); -insert into managers.t_statistics_http_status_codes (code) values (306); -insert into managers.t_statistics_http_status_codes (code) values (307); -insert into managers.t_statistics_http_status_codes (code) values (308); - -insert into managers.t_statistics_http_status_codes (code) values (400); -insert into managers.t_statistics_http_status_codes (code) values (401); -insert into managers.t_statistics_http_status_codes (code) values (402); -insert into managers.t_statistics_http_status_codes (code) values (403); -insert into managers.t_statistics_http_status_codes (code) values (404); -insert into managers.t_statistics_http_status_codes (code) values (405); -insert into managers.t_statistics_http_status_codes (code) values (406); -insert into managers.t_statistics_http_status_codes (code) values (407); -insert into managers.t_statistics_http_status_codes (code) values (408); -insert into managers.t_statistics_http_status_codes (code) values (409); -insert into managers.t_statistics_http_status_codes (code) values (410); -insert into managers.t_statistics_http_status_codes (code) values (411); -insert into managers.t_statistics_http_status_codes (code) values (412); -insert into managers.t_statistics_http_status_codes (code) values (413); -insert into managers.t_statistics_http_status_codes (code) values (414); -insert into managers.t_statistics_http_status_codes (code) values (415); -insert into managers.t_statistics_http_status_codes (code) values (416); -insert into managers.t_statistics_http_status_codes (code) values (417); -insert into managers.t_statistics_http_status_codes (code) values (422); -insert into managers.t_statistics_http_status_codes (code) values (423); -insert into managers.t_statistics_http_status_codes (code) values (424); -insert into managers.t_statistics_http_status_codes (code) values (426); -insert into managers.t_statistics_http_status_codes (code) values (428); -insert into managers.t_statistics_http_status_codes (code) values (429); -insert into managers.t_statistics_http_status_codes (code) values (431); -insert into managers.t_statistics_http_status_codes (code) values (451); - -insert into managers.t_statistics_http_status_codes (code) values (500); -insert into managers.t_statistics_http_status_codes (code) values (501); -insert into managers.t_statistics_http_status_codes (code) values (502); -insert into managers.t_statistics_http_status_codes (code) values (503); -insert into managers.t_statistics_http_status_codes (code) values (504); -insert into managers.t_statistics_http_status_codes (code) values (505); -insert into managers.t_statistics_http_status_codes (code) values (506); -insert into managers.t_statistics_http_status_codes (code) values (507); -insert into managers.t_statistics_http_status_codes (code) values (508); -insert into managers.t_statistics_http_status_codes (code) values (510); -insert into managers.t_statistics_http_status_codes (code) values (511); - - - -/** Provide request path statistics **/ -create table managers.t_statistics_request_path ( - path varchar(512) not null, - count bigint not null default 0, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_deleted timestamp, - - constraint cp_statistics_request_path_code primary key (path), - - constraint cc_statistics_request_path_count check (count >= 0) -); - -grant select on managers.t_statistics_request_path to reservation_users_administer; -grant select on managers.t_statistics_request_path to reservation_users_manager; -grant select on managers.t_statistics_request_path to reservation_users_auditor; - - -/** permissions prevent this from working as desired, so for now open up these stats to the following users (via a view) **/ -create view users.v_statistics_request_path with (security_barrier=true) as - select path, count from managers.t_statistics_request_path - with check option; - -grant select,insert,update on users.v_statistics_request_path to reservation_users; - - -create view public.v_statistics_request_path with (security_barrier=true) as - select path, count from managers.t_statistics_request_path - with check option; - -grant select,insert,update on public.v_statistics_request_path to public_users; - - -/** create an auto-update trigger **/ -create function managers.f_statistics_request_path_insert() returns trigger as $$ - begin - if (tg_op = 'INSERT') then - update v_statistics_request_path set count = (select count + 1 as count from v_statistics_request_path where path = new.request_path) where path = new.request_path; - if not found then - insert into v_statistics_request_path (path, count) values (new.request_path, 1); - if not found then return null; end if; - end if; - - return new; - end if; - - return null; - end; -$$ language plpgsql; - -create trigger tr_statistics_request_path_insert - after insert on managers.t_log_activity - for each row execute procedure managers.f_statistics_request_path_insert(); - - - -commit transaction; diff --git a/database/sql/reservation/base-users.sql b/database/sql/reservation/base-users.sql deleted file mode 100644 index 80d4c1a..0000000 --- a/database/sql/reservation/base-users.sql +++ /dev/null @@ -1,226 +0,0 @@ -/** Standardized SQL Structure - Users */ -/** This depends on: base-main.sql **/ -start transaction; - - - -/** Custom database specific settings (do this on every connection made) **/ -set bytea_output to hex; -set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public; -set datestyle to us; - - - - -/** Users **/ -create table administers.t_users ( - id bigint not null, - id_sort smallint not null default 0, - id_external bigint, - - name_machine varchar(128) not null, - name_human public.ct_name_person default (null, null, null, null, null, null) not null, - - address_email public.ct_email default (null, null, true) not null, - - is_coordinator boolean default false not null, - is_deleted boolean default false not null, - is_locked boolean default false not null, - is_private boolean default true not null, - - date_created timestamp default localtimestamp not null, - date_changed timestamp default localtimestamp not null, - date_synced timestamp default localtimestamp not null, - date_deleted timestamp, - - settings json, - - constraint cp_users_id primary key (id), - - constraint cc_users_id check (id > 0), - constraint cc_users_id_external check (id_external > 0), - - constraint cu_users_id_external unique (id_external), - constraint cu_users_name_machine unique (name_machine), - constraint cu_users_user unique (id, name_machine) -); - -create sequence administers.s_users_id owned by administers.t_users.id; -alter table administers.t_users alter column id set default nextval('administers.s_users_id'::regclass); - -grant select,insert,update on administers.t_users to reservation_users_administer; -grant select on administers.t_users to reservation_users_auditor; -grant select,usage on administers.s_users_id to reservation_users_administer; -grant usage on administers.s_users_id to reservation_users; - -create index ci_users_deleted_not on administers.t_users (id) - where is_deleted is not true; - -create index ci_users_private_not on administers.t_users (id) - where is_deleted is not true and is_private is not true; - -create index ci_users_private_email_not on administers.t_users (id) - where is_deleted is not true and is_private is not true and (address_email).private is not true; - -create index ci_users_id_sort_a on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 97; -create index ci_users_id_sort_b on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 98; -create index ci_users_id_sort_c on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 99; -create index ci_users_id_sort_d on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 100; -create index ci_users_id_sort_e on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 101; -create index ci_users_id_sort_f on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 102; -create index ci_users_id_sort_g on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 103; -create index ci_users_id_sort_h on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 104; -create index ci_users_id_sort_i on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 105; -create index ci_users_id_sort_j on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 106; -create index ci_users_id_sort_k on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 107; -create index ci_users_id_sort_l on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 108; -create index ci_users_id_sort_m on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 109; -create index ci_users_id_sort_n on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 110; -create index ci_users_id_sort_o on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 111; -create index ci_users_id_sort_p on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 112; -create index ci_users_id_sort_q on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 113; -create index ci_users_id_sort_r on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 114; -create index ci_users_id_sort_s on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 115; -create index ci_users_id_sort_t on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 116; -create index ci_users_id_sort_u on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 117; -create index ci_users_id_sort_v on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 118; -create index ci_users_id_sort_w on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 119; -create index ci_users_id_sort_x on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 120; -create index ci_users_id_sort_y on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 121; -create index ci_users_id_sort_z on administers.t_users (id_sort) with (fillfactor = 100) where id_sort = 122; - - -/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ -alter sequence administers.s_users_id start 1000; -alter sequence administers.s_users_id restart; - - -/*** create hard-coded user ids ***/ -insert into administers.t_users (id, name_machine, name_human, is_private) values (1, 'unknown', (null, 'Unknown', null, null, null, 'Unknown'), false); -insert into administers.t_users (id, name_machine, name_human, is_private) values (2, 'system', (null, 'System', null, null, null, 'System'), false); -insert into administers.t_users (id, name_machine, name_human, is_private) values (3, 'console', (null, 'Console', null, null, null, 'Console'), false); -insert into administers.t_users (id, name_machine, name_human, is_private) values (4, 'cron', (null, 'Cron', null, null, null, 'Cron'), false); - - -/*** provide current user access to their own information ***/ -create view users.v_users_self with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users - where (name_machine)::text = (current_user)::text; - -grant select on users.v_users_self to reservation_users; - -create view users.v_users_self_insert with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, settings from administers.t_users - where (name_machine)::text = (current_user)::text - with check option; - -grant insert on users.v_users_self_insert to reservation_users; - -create view users.v_users_self_update with (security_barrier=true) as - select address_email, is_private, date_changed, date_synced, settings from administers.t_users - where date_changed = localtimestamp and (date_synced is null or date_synced = localtimestamp) and (name_machine)::text = (current_user)::text - with check option; - -grant update on users.v_users_self_update to reservation_users; - - -/**** anonymous user has uid = 1 ****/ -create view public.v_users_self with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users - where id = 1 and id_sort = 0; - -grant select on public.v_users_self to public_users; - - -/**** system user has uid = 2 ****/ -create view system.v_users_self with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users - where id = 2 and id_sort = 0; - -grant select on system.v_users_self to reservation_user; - - -/*** provide public user information ***/ -create view public.v_users with (security_barrier=true) as - select id, id_sort, name_machine, name_human from administers.t_users - where (is_deleted is not true and is_private is not true) or (is_deleted is not true and (name_machine)::text = (current_user)::text); - -grant select on public.v_users to reservation_users; -grant select on public.v_users to public_users; - - -/*** provide e-mail address as public information only if it is explicitly allowed ***/ -create view public.v_users_email with (security_barrier=true) as - select id, id_sort, name_machine, name_human, address_email from administers.t_users - where (is_deleted is not true and is_private is not true and (address_email).private is not true) or (is_deleted is not true and (name_machine)::text = (current_user)::text); - -grant select on public.v_users_email to reservation_users; -grant select on public.v_users_email to public_users; - - -/*** provide managers with the ability to modify accounts ***/ -create view managers.v_users with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_created, date_changed, date_synced, settings from administers.t_users - where is_deleted is not true; - -grant select on managers.v_users to reservation_users_manager; - -create view managers.v_users_insert with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, settings from administers.t_users - with check option; - -grant insert on managers.v_users_insert to reservation_users_manager; - -create view managers.v_users_update with (security_barrier=true) as - select id, id_sort, id_external, name_machine, name_human, address_email, is_private, is_locked, is_coordinator, date_changed, date_synced, settings from administers.t_users - where is_deleted is not true and date_changed = localtimestamp and (date_synced is null or date_synced = localtimestamp) - with check option; - -grant update on managers.v_users_update to reservation_users_manager; - - -/** Create Materialized views for table based on history **/ -create materialized view administers.vm_users_date_created_this_day as select * from administers.t_users where date_trunc('day', date_created) = date_trunc('day', current_timestamp); -create materialized view administers.vm_users_date_created_previous_day as select * from administers.t_users where date_trunc('day', date_created) = date_trunc('day', current_timestamp) - interval '1 day'; -create materialized view administers.vm_users_date_created_previous_month as select * from administers.t_users where date_trunc('month', date_created) = date_trunc('month', current_timestamp) - interval '1 month'; -create materialized view administers.vm_users_date_created_previous_year as select * from administers.t_users where date_trunc('year', date_created) = date_trunc('year', current_timestamp) - interval '1 year'; - -create materialized view administers.vm_users_date_changed_this_day as select * from administers.t_users where date_trunc('day', date_changed) = date_trunc('day', current_timestamp); -create materialized view administers.vm_users_date_changed_previous_day as select * from administers.t_users where date_trunc('day', date_changed) = date_trunc('day', current_timestamp) - interval '1 day'; -create materialized view administers.vm_users_date_changed_previous_month as select * from administers.t_users where date_trunc('month', date_changed) = date_trunc('month', current_timestamp) - interval '1 month'; -create materialized view administers.vm_users_date_changed_previous_year as select * from administers.t_users where date_trunc('year', date_changed) = date_trunc('year', current_timestamp) - interval '1 year'; - -create materialized view administers.vm_users_date_synced_this_day as select * from administers.t_users where date_trunc('day', date_synced) = date_trunc('day', current_timestamp); -create materialized view administers.vm_users_date_synced_previous_day as select * from administers.t_users where date_trunc('day', date_synced) = date_trunc('day', current_timestamp) - interval '1 day'; -create materialized view administers.vm_users_date_synced_previous_month as select * from administers.t_users where date_trunc('month', date_synced) = date_trunc('month', current_timestamp) - interval '1 month'; -create materialized view administers.vm_users_date_synced_previous_year as select * from administers.t_users where date_trunc('year', date_synced) = date_trunc('year', current_timestamp) - interval '1 year'; - -grant select on administers.vm_users_date_created_this_day to reservation_users_administer; -grant select on administers.vm_users_date_created_this_day to reservation_users_manager; -grant select on administers.vm_users_date_created_previous_day to reservation_users_administer; -grant select on administers.vm_users_date_created_previous_day to reservation_users_manager; -grant select on administers.vm_users_date_created_previous_month to reservation_users_administer; -grant select on administers.vm_users_date_created_previous_month to reservation_users_manager; -grant select on administers.vm_users_date_created_previous_year to reservation_users_administer; -grant select on administers.vm_users_date_created_previous_year to reservation_users_manager; - -grant select on administers.vm_users_date_changed_this_day to reservation_users_administer; -grant select on administers.vm_users_date_changed_this_day to reservation_users_manager; -grant select on administers.vm_users_date_changed_previous_day to reservation_users_administer; -grant select on administers.vm_users_date_changed_previous_day to reservation_users_manager; -grant select on administers.vm_users_date_changed_previous_month to reservation_users_administer; -grant select on administers.vm_users_date_changed_previous_month to reservation_users_manager; -grant select on administers.vm_users_date_changed_previous_year to reservation_users_administer; -grant select on administers.vm_users_date_changed_previous_year to reservation_users_manager; - -grant select on administers.vm_users_date_synced_this_day to reservation_users_administer; -grant select on administers.vm_users_date_synced_this_day to reservation_users_manager; -grant select on administers.vm_users_date_synced_previous_day to reservation_users_administer; -grant select on administers.vm_users_date_synced_previous_day to reservation_users_manager; -grant select on administers.vm_users_date_synced_previous_month to reservation_users_administer; -grant select on administers.vm_users_date_synced_previous_month to reservation_users_manager; -grant select on administers.vm_users_date_synced_previous_year to reservation_users_administer; -grant select on administers.vm_users_date_synced_previous_year to reservation_users_manager; - - -commit transaction; diff --git a/database/sql/reservation/order.install b/database/sql/reservation/order.install new file mode 100644 index 0000000..7e3d828 --- /dev/null +++ b/database/sql/reservation/order.install @@ -0,0 +1,18 @@ +reservation-first +reservation-main +reservation-users +reservation-groups +reservation-paths +reservation-types +reservation-log_types +reservation-log_groups +reservation-log_problems +reservation-log_users +reservation-dates +reservation-fields +reservation-associations +reservation-requests +reservation-workflow +reservation-statistics +reservation-legal +reservation-last diff --git a/database/sql/reservation/reservation-associations.sql b/database/sql/reservation/reservation-associations.sql new file mode 100644 index 0000000..2109ddb --- /dev/null +++ b/database/sql/reservation/reservation-associations.sql @@ -0,0 +1,126 @@ +/** Standardized SQL Structure - Associations **/ +/** This depends on: base-fields.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** Associations ***/ +create table s_tables.t_associations ( + id bigint not null, + id_creator bigint not null, + id_creator_session bigint not null, + id_manager bigint not null, + id_coordinator bigint not null, + id_group bigint, + id_sort smallint not null default 0, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_approved boolean default false not null, + is_cancelled boolean default false not null, + is_denied boolean default false not null, + is_troubled boolean default false not null, + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_synced timestamp default localtimestamp not null, + date_approved timestamp, + date_cancelled timestamp, + date_denied timestamp, + date_troubled timestamp, + date_locked timestamp, + date_deleted timestamp, + + field_affiliation bigint, + field_classification bigint, + + constraint cu_associations_id unique (id), + constraint cu_associations_name_machine unique (name_machine), + + constraint cc_associations_id check (id > 0), + + constraint cf_associations_manager foreign key (id_manager) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_associations_creator foreign key (id_creator) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_associations_creator_session foreign key (id_creator_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_associations_coordinator foreign key (id_coordinator) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_associations_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade, + constraint cf_associations_field_affiliation foreign key (field_affiliation) references s_tables.t_field_affiliations (id) on delete restrict on update cascade, + constraint cf_associations_field_classification foreign key (field_classification) references s_tables.t_field_classifications (id) on delete restrict on update cascade +); + +create sequence s_tables.se_associations_id owned by s_tables.t_associations.id; +alter table s_tables.t_associations alter column id set default nextval('s_tables.se_associations_id'::regclass); + +grant select,insert,update on s_tables.t_associations to r_reservation_manager; +grant select on s_tables.t_associations to r_reservation_auditor; +grant select,usage on s_tables.se_associations_id to r_reservation_manager; +grant usage on s_tables.se_associations_id to r_reservation_requester, r_reservation_reviewer; + + +/*** provide current user access to their own information ***/ +create view s_users.v_associations_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self), + allowed_groups as (select id from s_users.v_groups_self) + select id, id_manager, id_coordinator, id_group, id_sort, name_machine, name_human, is_approved, is_cancelled, is_denied, is_troubled, is_locked, date_created, date_changed, date_synced, date_approved, date_cancelled, date_denied, date_troubled, date_locked, field_affiliation, field_classification from s_tables.t_associations + where is_deleted is not true and (id_manager in (select * from this_user) or id_group in (select * from allowed_groups)); + +grant select on s_users.v_associations_self to r_reservation_requester, r_reservation_reviewer; + + +/*** provide current user access to associations who they are assigned as the manager of ***/ +create view s_users.v_associations_manage with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_creator, id_coordinator, id_group, id_sort, name_machine, name_human, is_approved, is_cancelled, is_denied, is_troubled, is_locked, date_created, date_changed, date_synced, date_approved, date_cancelled, date_denied, date_troubled, date_locked, field_affiliation, field_classification from s_tables.t_associations + where is_deleted is not true and id_manager in (select * from this_user); + +grant select on s_users.v_associations_manage to r_reservation_requester, r_reservation_reviewer; + + +/*** provide current user access to associations who they are assigned as the coordinator of ***/ +create view s_users.v_associations_coordinate with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_creator, id_manager, id_group, id_sort, name_machine, name_human, is_approved, is_cancelled, is_denied, is_troubled, is_locked, date_created, date_changed, date_synced, date_approved, date_cancelled, date_denied, date_troubled, date_locked, field_affiliation, field_classification from s_tables.t_associations + where is_deleted is not true and id_coordinator in (select * from this_user); + +grant select on s_users.v_associations_coordinate to r_reservation_requester, r_reservation_reviewer; + + +/** provide current user access to insert their own associations (with them as the manager) **/ +create view s_users.v_associations_self_insert with (security_barrier=true) as + select id_manager, id_group, id_coordinator, name_machine, name_human, field_affiliation, field_classification from s_tables.t_associations + where is_deleted is not true and id_manager in (select id from s_users.v_users_locked_not_self) + with check option; + +grant insert on s_users.v_associations_self_insert to r_reservation_requester, r_reservation_reviewer; + + +/** provide current user access to update associations they manager **/ +create view s_users.v_associations_self_update with (security_barrier=true) as + select id_manager, id_group, id_coordinator, name_machine, name_human, date_changed, field_affiliation, field_classification from s_tables.t_associations + where is_deleted is not true and id_manager in (select id from s_users.v_users_locked_not_self) + with check option; + +grant update on s_users.v_associations_self_update to r_reservation_requester, r_reservation_reviewer; + + +create trigger tr_associations_update_date_changed_deleted_or_locked + before update on s_tables.t_associations + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +create trigger tr_associations_enforce_creator_and_session_ids + before insert on s_tables.t_associations + for each row execute procedure s_administers.f_common_enforce_creator_and_session_ids(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-dates.sql b/database/sql/reservation/reservation-dates.sql new file mode 100644 index 0000000..fe14fb5 --- /dev/null +++ b/database/sql/reservation/reservation-dates.sql @@ -0,0 +1,63 @@ +/** Standardized SQL Structure - Dates **/ +/** This depends on: base-main.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** Dates: Contexts ***/ +create table s_tables.t_date_contexts ( + id bigint not null, + id_external bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cu_date_contexts_id unique (id), + constraint cu_date_contexts_name_machine unique (name_machine), + + constraint cc_date_contexts_id check (id >= 0) +); + +create sequence s_tables.se_date_contexts_id owned by s_tables.t_date_contexts.id; +alter table s_tables.t_date_contexts alter column id set default nextval('s_tables.se_date_contexts_id'::regclass); + +grant select,insert,update on s_tables.t_date_contexts to r_reservation_manager; +grant select on s_tables.t_date_contexts to r_reservation_auditor; +grant select,usage on s_tables.se_date_contexts_id to r_reservation_manager; + +create index i_date_contexts_deleted_not on s_tables.t_date_contexts (id) + where is_deleted is not true; + +create index i_date_contexts_locked_not on s_tables.t_date_contexts (id) + where is_deleted is not true and is_locked is not true; + + +create view s_requesters.v_date_contexts with (security_barrier=true) as + select id, id_external, name_machine, name_human, is_locked from s_tables.t_date_contexts + where is_deleted is not true; + +grant select on s_requesters.v_date_contexts to r_reservation_requester, r_reservation_reviewer; + + +create trigger tr_date_contexts_update_date_changed_deleted_or_locked + before update on s_tables.t_date_contexts + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-fields.sql b/database/sql/reservation/reservation-fields.sql new file mode 100644 index 0000000..8bbef1b --- /dev/null +++ b/database/sql/reservation/reservation-fields.sql @@ -0,0 +1,111 @@ +/** Standardized SQL Structure - Fields **/ +/** This depends on: base-users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** Field: Affiliations ***/ +create table s_tables.t_field_affiliations ( + id bigint not null, + id_external bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cu_field_affiliations_id unique (id), + constraint cu_field_affiliations_name_machine unique (name_machine), + + constraint cc_field_affiliations_id check (id > 0) +); + +create sequence s_tables.se_field_affiliations_id owned by s_tables.t_field_affiliations.id; +alter table s_tables.t_field_affiliations alter column id set default nextval('s_tables.se_field_affiliations_id'::regclass); + +grant select,insert,update on s_tables.t_field_affiliations to r_reservation_manager; +grant select on s_tables.t_field_affiliations to r_reservation_auditor; +grant select,usage on s_tables.se_field_affiliations_id to r_reservation_manager; + +create index i_field_affiliations_deleted_not on s_tables.t_field_affiliations (id) + where is_deleted is not true; + +create index i_field_affiliations_locked_not on s_tables.t_field_affiliations (id) + where is_deleted is not true and is_locked is not true; + +create view s_users.v_field_affiliations with (security_barrier=true) as + select id, id_external, name_machine, name_human, is_locked from s_tables.t_field_affiliations + where is_deleted is not true; + +grant select on s_users.v_field_affiliations to r_reservation, r_reservation_system; + + +create trigger tr_field_affiliations_update_date_changed_deleted_or_locked + before update on s_tables.t_field_affiliations + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** Field: Classifications ***/ +create table s_tables.t_field_classifications ( + id bigint not null, + id_external bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cu_field_classifications_id unique (id), + constraint cu_field_classifications_name_machine unique (name_machine), + + constraint cc_field_classifications_id check (id > 0) +); + +create sequence s_tables.se_field_classifications_id owned by s_tables.t_field_classifications.id; +alter table s_tables.t_field_classifications alter column id set default nextval('s_tables.se_field_classifications_id'::regclass); + +grant select,insert,update on s_tables.t_field_classifications to r_reservation_manager; +grant select on s_tables.t_field_classifications to r_reservation_auditor; +grant select,usage on s_tables.se_field_classifications_id to r_reservation_manager; + +create index i_field_classifications_deleted_not on s_tables.t_field_classifications (id) + where is_deleted is not true; + +create index i_field_classifications_locked_not on s_tables.t_field_classifications (id) + where is_deleted is not true and is_locked is not true; + + +create view s_users.v_field_classifications with (security_barrier=true) as + select id, id_external, name_machine, name_human, is_locked from s_tables.t_field_classifications + where is_deleted is not true; + +grant select on s_users.v_field_classifications to r_reservation, r_reservation_system; + + +create trigger tr_field_classifications_update_date_changed_deleted_or_locked + before update on s_tables.t_field_classifications + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +/** @todo: create all field types needed for f_requests fields **/ + +commit transaction; diff --git a/database/sql/reservation/reservation-first.sql b/database/sql/reservation/reservation-first.sql new file mode 100644 index 0000000..437d780 --- /dev/null +++ b/database/sql/reservation/reservation-first.sql @@ -0,0 +1,120 @@ +/** First time or one time execution stuff **/ +/** Things here must be run first and cannot be run a second time due to their nature. **/ +/** For example, tablespaces need only be created 1x and then any database on the system can use them **/ +/** Be sure to replace reservation_ and reservation- with the prefix that is specific to your database. **/ +/** This script creates the database at the bottom. **/ + + + +/** Create the roles**/ +create role r_reservation inherit nologin; +create role r_reservation_administer inherit nologin; +create role r_reservation_manager inherit nologin; +create role r_reservation_auditor inherit nologin; +create role r_reservation_publisher inherit nologin; +create role r_reservation_insurer inherit nologin; +create role r_reservation_financer inherit nologin; +create role r_reservation_reviewer inherit nologin; +create role r_reservation_editor inherit nologin; +create role r_reservation_drafter inherit nologin; +create role r_reservation_requester inherit nologin; +create role r_reservation_system inherit nologin; +create role r_reservation_revision_requests inherit nologin; +create role r_reservation_statistics_update inherit nologin; +create role r_reservation_logger inherit nologin; + + +grant r_reservation to r_reservation_administer with admin option; +grant r_reservation to r_reservation_manager with admin option; + +grant r_reservation_manager to r_reservation_administer with admin option; + +grant r_reservation_auditor to r_reservation_administer with admin option; +grant r_reservation_auditor to r_reservation_manager with admin option; + +grant r_reservation_publisher to r_reservation_administer with admin option; +grant r_reservation_publisher to r_reservation_manager with admin option; + +grant r_reservation_insurer to r_reservation_administer with admin option; +grant r_reservation_insurer to r_reservation_manager with admin option; + +grant r_reservation_financer to r_reservation_administer with admin option; +grant r_reservation_financer to r_reservation_manager with admin option; + +grant r_reservation_reviewer to r_reservation_administer with admin option; +grant r_reservation_reviewer to r_reservation_manager with admin option; + +grant r_reservation_editor to r_reservation_administer with admin option; +grant r_reservation_editor to r_reservation_manager with admin option; + +grant r_reservation_drafter to r_reservation_administer with admin option; +grant r_reservation_drafter to r_reservation_manager with admin option; + +grant r_reservation_requester to r_reservation_administer with admin option; +grant r_reservation_requester to r_reservation_manager with admin option; + +/** This is the role the database should use to connect to to perform system activity **/ +create role u_reservation inherit login; + +grant r_reservation to u_reservation; + + +/** This is the role and role group the database should use for anonymous traffic. I further suggest setting up pg_hba.conf to allow non-ssl connections (increase performance as public information is still public). **/ +/** If the data is meant to be private, then have the public account use the system user with ssl connections **/ +create role r_public inherit nologin; +create role u_public inherit login; + +grant r_public to u_public; + +/** These are the roles and role group the database should use for system activity (such as executing cron-jobs). **/ +create role u_reservation_system_administer inherit login; +create role u_reservation_system_manager inherit login; +create role u_reservation_system_auditor inherit login; +create role u_reservation_system_publisher inherit login; +create role u_reservation_system_insurer inherit login; +create role u_reservation_system_financer inherit login; +create role u_reservation_system_reviewer inherit login; +create role u_reservation_system_editor inherit login; +create role u_reservation_system_drafter inherit login; +create role u_reservation_system_requester inherit login; +create role u_reservation_system_public inherit login; + +grant r_reservation_system to u_reservation_system_administer; +grant r_reservation_system to u_reservation_system_manager; +grant r_reservation_system to u_reservation_system_auditor; +grant r_reservation_system to u_reservation_system_publisher; +grant r_reservation_system to u_reservation_system_insurer; +grant r_reservation_system to u_reservation_system_financer; +grant r_reservation_system to u_reservation_system_reviewer; +grant r_reservation_system to u_reservation_system_editor; +grant r_reservation_system to u_reservation_system_drafter; +grant r_reservation_system to u_reservation_system_requester; +grant r_reservation_system to u_reservation_system_public; + +grant r_reservation_administer to u_reservation_system_administer; +grant r_reservation_manager to u_reservation_system_manager; +grant r_reservation_auditor to u_reservation_system_auditor; +grant r_reservation_publisher to u_reservation_system_publisher; +grant r_reservation_insurer to u_reservation_system_insurer; +grant r_reservation_financer to u_reservation_system_financer; +grant r_reservation_reviewer to u_reservation_system_reviewer; +grant r_reservation_editor to u_reservation_system_editor; +grant r_reservation_drafter to u_reservation_system_drafter; +grant r_reservation_requester to u_reservation_system_requester; + + + +/** Create and connect to the database **/ +create database reservation; + +\c reservation ; + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + +/* Make sure public is never allowed to create tables! */ +revoke create on schema public from public; diff --git a/database/sql/reservation/reservation-groups.sql b/database/sql/reservation/reservation-groups.sql new file mode 100644 index 0000000..0ccb6a6 --- /dev/null +++ b/database/sql/reservation/reservation-groups.sql @@ -0,0 +1,232 @@ +/** Standardized SQL Structure - Groups */ +/** This depends on: base-users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + +/* Note about composite groups (is_composite) + Instead of having an array of multiple groups assigned to one entity or having a table of group and entity associates, use a group that logically represents multiple groups. + For example, if I want to add both group_1 and group_2 to entity_a, then I can create group_3 and put all users from group_1 and group_2 in it. + @todo: I will likely need to create a composite groups table to manage the relations between a composite group and its non-composites for management purposes. + + @todo: with this composite groups design, I can get rid of the user to groups table and need users only to be assigned to a single (composite) group. + the current flaw with this design may be with access control in creating or auto-creating composite groups. +*/ + +/** Groups **/ +create table s_tables.t_groups ( + id bigint not null, + id_external bigint, + id_manager bigint, + + id_sort smallint not null default 0, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + is_composite boolean default false not null, + + can_manage_paths boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_synced timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + settings json, + + constraint cp_groups primary key (id), + + constraint cc_groups_id check (id > 0), + constraint cc_groups_id_external check (id_external >= -1), + + constraint cu_groups_id_external unique (id_external), + constraint cu_groups_name_machine unique (name_machine), + + constraint cf_groups_manager foreign key (id_manager) references s_tables.t_users (id) on delete restrict on update cascade +); + +create sequence s_tables.se_groups_id owned by s_tables.t_groups.id; +alter table s_tables.t_groups alter column id set default nextval('s_tables.se_groups_id'::regclass); + +grant select,insert,update on s_tables.t_groups to r_reservation_manager; +grant select on s_tables.t_groups to r_reservation_auditor; +grant select,usage on s_tables.se_groups_id to r_reservation_manager; +grant usage on s_tables.se_groups_id to r_reservation, r_reservation_system; + +/* Note: id_sort is only needed when directly validating against id or name_machine because both of those are already an index. */ +create index i_groups_id_sort_a on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 97; +create index i_groups_id_sort_b on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 98; +create index i_groups_id_sort_c on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 99; +create index i_groups_id_sort_d on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 100; +create index i_groups_id_sort_e on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 101; +create index i_groups_id_sort_f on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 102; +create index i_groups_id_sort_g on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 103; +create index i_groups_id_sort_h on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 104; +create index i_groups_id_sort_i on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 105; +create index i_groups_id_sort_j on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 106; +create index i_groups_id_sort_k on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 107; +create index i_groups_id_sort_l on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 108; +create index i_groups_id_sort_m on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 109; +create index i_groups_id_sort_n on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 110; +create index i_groups_id_sort_o on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 111; +create index i_groups_id_sort_p on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 112; +create index i_groups_id_sort_q on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 113; +create index i_groups_id_sort_r on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 114; +create index i_groups_id_sort_s on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 115; +create index i_groups_id_sort_t on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 116; +create index i_groups_id_sort_u on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 117; +create index i_groups_id_sort_v on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 118; +create index i_groups_id_sort_w on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 119; +create index i_groups_id_sort_x on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 120; +create index i_groups_id_sort_y on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 121; +create index i_groups_id_sort_z on s_tables.t_groups (id_sort) with (fillfactor = 100) where id_sort = 122; + + +/*** provide group managers access to manage their groups ***/ +create view s_users.v_groups_manage_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_external, name_machine, name_human, is_locked, is_composite, can_manage_paths, settings from s_tables.t_groups + where is_deleted is not true and id_manager in (select * from this_user); + +grant select on s_users.v_groups_manage_self to r_reservation, r_reservation_system; + +create view s_users.v_groups_manage_update with (security_barrier=true) as + select id, id_external, name_machine, name_human, is_locked, is_composite, can_manage_paths, settings from s_tables.t_groups + where is_deleted is not true and id_manager in (select id from s_users.v_users_locked_not_self) + with check option; + +grant update on s_users.v_groups_manage_update to r_reservation, r_reservation_system; + + +create trigger tr_groups_date_changed_deleted_or_locked + before update on s_tables.t_groups + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/** Groups to Users Association **/ +create table s_tables.t_group_users ( + id_user bigint not null, + id_group bigint not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + constraint cp_group_users unique (id_user, id_group), + + constraint cf_group_users_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + + constraint cf_group_users_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade +); + +grant select,insert,update on s_tables.t_groups to r_reservation_manager; +grant select on s_tables.t_groups to r_reservation_auditor; + + +/*** provide current user access to their own information ***/ +create view s_users.v_groups_self with (security_barrier=true) as + with allowed_groups as (select id_group from s_tables.t_group_users where is_deleted is not true and is_locked is not true and id_user in (select id from s_users.v_users_locked_not_self)) + select id, id_external, id_manager, name_machine, name_human, is_locked, is_composite, date_created, date_changed, date_synced, can_manage_paths, settings from s_tables.t_groups + where is_deleted is not true and id in (select * from allowed_groups); + +grant select on s_users.v_groups_self to r_reservation, r_reservation_system; + +/*** provide group managers access to manage users assigned to their groups (any user id less than 1000 is reserved/special case, prohibit those). ***/ +create view s_users.v_group_users_manage with (security_barrier=true) as + with managed_groups as (select id from s_tables.t_groups where is_deleted is not true and id_manager in (select id from s_users.v_users_locked_not_self)), + available_users as (select id from s_tables.t_users where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true) + select id_user, id_group, is_locked from s_tables.t_group_users + where is_deleted is not true and id_group in (select * from managed_groups) and id_user in (select * from available_users); + +grant select on s_users.v_group_users_manage to r_reservation, r_reservation_system; + +create view s_users.v_group_users_manage_insert with (security_barrier=true) as + select id_user, id_group from s_tables.t_group_users + where is_deleted is not true and id_group in (select id from s_users.v_groups_manage_self) and id_group in (select id_group from s_tables.t_group_users where is_deleted is not true and is_locked is not true and id_user in (select id from s_users.v_users_locked_not_self)) and id_user in (select id from s_tables.t_users where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true) + with check option; + +grant insert on s_users.v_group_users_manage_insert to r_reservation, r_reservation_system; + +create view s_users.v_group_users_manage_update with (security_barrier=true) as + select id_user, id_group from s_tables.t_group_users + where is_deleted is not true and id_group in (select id from s_users.v_groups_manage_self) and id_group in (select id_group from s_tables.t_group_users where is_deleted is not true and is_locked is not true and id_user in (select id from s_users.v_users_locked_not_self)) and id_user in (select id from s_tables.t_users where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true) + with check option; + +grant update on s_users.v_group_users_manage_update to r_reservation, r_reservation_system; + + +create trigger tr_groups_users_date_changed_deleted_or_locked + before update on s_tables.t_group_users + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/** Groups Composites **/ +create table s_tables.t_group_composites ( + id_composite bigint not null, + id_group bigint not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + constraint cu_group_composites_id unique (id_composite, id_group), + + constraint cf_group_composites_composite foreign key (id_composite) references s_tables.t_groups (id) on delete restrict on update cascade, + constraint cf_group_composites_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade +); + +grant select,insert,update,delete on s_tables.t_groups to r_reservation_manager; +grant select on s_tables.t_groups to r_reservation_auditor; + + +/*** provide group managers access to manage composite groups. ***/ +create view s_users.v_group_composites with (security_barrier=true) as + with allowed_groups as (select id from s_users.v_groups_self where is_locked is not true), + managed_groups as (select id from s_users.v_groups_manage_self where is_locked is not true) + select id_composite, id_group, is_locked from s_tables.t_group_composites + where is_deleted is not true and id_group in (select * from managed_groups) or id_group in (select * from allowed_groups); + +grant select on s_users.v_group_composites to r_reservation, r_reservation_system; + +create view s_users.v_group_composites_manage_insert with (security_barrier=true) as + select id_user, id_group from s_tables.t_group_users + where is_deleted is not true and id_group in (select id_group from s_users.v_group_users_manage where is_locked is not true) + with check option; + +grant insert on s_users.v_group_composites_manage_insert to r_reservation, r_reservation_system; + +create view s_users.v_group_composites_manage_update with (security_barrier=true) as + select id_user, id_group from s_tables.t_group_users + where is_deleted is not true and id_group in (select id_group from s_users.v_group_users_manage where is_locked is not true) + with check option; + +grant update on s_users.v_group_composites_manage_update to r_reservation, r_reservation_system; + + +create trigger tr_groups_date_changed_deleted_or_locked + before update on s_tables.t_group_composites + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-last.sql b/database/sql/reservation/reservation-last.sql new file mode 100644 index 0000000..2c219a3 --- /dev/null +++ b/database/sql/reservation/reservation-last.sql @@ -0,0 +1,371 @@ +/** Standardized SQL Structure - Last */ +/** This depends on: everything (run this absolutely last) **/ + +/** The purpose of this is to add all initial data after all appropriate triggers are defined. ***/ +start transaction; + + + +insert into s_tables.t_date_contexts (id, name_machine, name_human) values (0, 'none', 'None'); +insert into s_tables.t_date_contexts (name_machine, name_human) values ('rehearsal', 'Rehearsal / Setup'); +insert into s_tables.t_date_contexts (name_machine, name_human) values ('event', 'Event / Meeting'); +insert into s_tables.t_date_contexts (name_machine, name_human) values ('cleanup', 'Cleanup / Breakdown'); + + + +insert into s_tables.t_legal_types (id, name_machine, name_human) values (0, 'none', 'None'); + + + +/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ +alter sequence s_tables.se_log_types_id start 1000; +alter sequence s_tables.se_log_types_id restart; + + +/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ +insert into s_tables.t_log_types (id, name_machine, name_human) values (0, 'none', 'None'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (1, 'php', 'PHP'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (2, 'theme', 'Theme'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (3, 'cache', 'Cache'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (4, 'javascript', 'Javascript'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (5, 'ajax', 'AJAX'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (6, 'sql', 'SQL'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (7, 'form', 'Form'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (8, 'form_validate', 'Form Validation'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (9, 'form_submit', 'Form Submit'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (10, 'load', 'Load'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (11, 'save', 'Save'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (12, 'render', 'Render'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (13, 'client', 'Client'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (14, 'add', 'Add'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (15, 'create', 'Create'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (16, 'change', 'Change'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (17, 'delete', 'Delete'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (18, 'redirect', 'Redirect'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (19, 'login', 'Login'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (20, 'logout', 'Logout'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (21, 'session', 'Session'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (22, 'database', 'Database'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (23, 'not_found', 'Not Found'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (24, 'access_denied', 'Access Denied'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (25, 'removed', 'Removed'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (26, 'locked', 'Locked'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (27, 'timeout', 'Timeout'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (28, 'expire', 'Expiration'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (29, 'user', 'User'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (30, 'error', 'Error'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (31, 'content', 'Content'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (32, 'workflow', 'Workflow'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (33, 'draft', 'Draft'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (34, 'clone', 'Clone'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (35, 'publish', 'Publish'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (36, 'revert', 'Revert'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (37, 'validate', 'Validate'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (38, 'approve', 'Approve'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (39, 'password', 'Password'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (40, 'revision', 'Revision'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (41, 'search', 'Search'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (42, 'access', 'Access'); +insert into s_tables.t_log_types (id, name_machine, name_human) values (43, 'unknown', 'Unknown'); + + + +/* pre-populate the path types (note: this may be redesigned later once I have more type names). */ +insert into s_tables.t_path_types (id, name_machine, name_human) values (0, 'none', 'None'); +insert into s_tables.t_path_types (id, name_machine, name_human) values (1, 'system', 'System'); +insert into s_tables.t_path_types (id, name_machine, name_human) values (2, 'user', 'User'); + + +/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (0, '0', 'Undefined'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (1, '1', 'Invalid'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (2, '2', 'Unknown'); + +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (100, '100', 'Continue'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (101, '101', 'Switching Protocols'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (102, '102', 'Processing'); + +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (200, '200', 'OK'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (201, '201', 'Created'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (202, '202', 'Accepted'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (203, '203', 'Non-Authoritative Information'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (204, '204', 'No Content'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (205, '205', 'Reset Content'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (206, '206', 'Partial Content'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (207, '207', 'Multi-Status'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (208, '208', 'Already Reported'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (226, '226', 'IM used'); + +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (300, '300', 'Multiple Choices'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (301, '301', 'Moved Permanently'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (302, '302', 'Found'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (303, '303', 'See Other'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (304, '304', 'Not Modified'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (305, '305', 'Use Proxy'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (306, '306', 'Switch Proxy'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (307, '307', 'Temporary Redirect'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (308, '308', 'Permanent Redirect'); + +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (400, '400', 'Bad Request'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (401, '401', 'Unauthorized'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (402, '402', 'Payment Required'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (403, '403', 'Forbidden'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (404, '404', 'Not Found'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (405, '405', 'Method Not Allowed'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (406, '406', 'Not Acceptable'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (407, '407', 'Proxy Authentication Required'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (408, '408', 'Request Timeout'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (409, '409', 'Conflict'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (410, '410', 'Gone'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (411, '411', 'Length Required'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (412, '412', 'Precondition Failed'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (413, '413', 'Payload Too Large'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (414, '414', 'Request-URI Too Long'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (415, '415', 'Unsupported Media Type'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (416, '416', 'Requested Range Not Satisfiable'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (417, '417', 'Expectation Failed'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (422, '422', 'Misdirected Request'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (423, '423', 'Locked'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (424, '424', 'Failed Dependency'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (426, '426', 'Upgrade Required'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (428, '428', 'Precondition Required'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (429, '429', 'Too Many Requests'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (431, '431', 'Request Header Fields Too Large'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (451, '451', 'Unavailable For Legal Reasons'); + +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (500, '500', 'Internal Server Error'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (501, '501', 'Not Implemented'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (502, '502', 'Bad Gateway'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (503, '503', 'Service Unavailable'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (504, '504', 'Gateway Timeout'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (505, '505', 'HTTP Version Not Supported'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (506, '506', 'Variant Also Negotiates'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (507, '507', 'Insufficient Storage'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (508, '508', 'Loop Detected'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (510, '510', 'Not Extended'); +insert into s_tables.t_log_http_status_codes (id, name_machine, name_human) values (511, '511', 'Network Authentication Required'); + + +/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ +alter sequence s_tables.se_log_severity_levels_id start 1000; +alter sequence s_tables.se_log_severity_levels_id restart; + + +/** create well known types that can then be user for indexes (all new types added should be considered for custom indexing). **/ +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (0, 'none', 'None'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (1, 'information', 'Information'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (2, 'notice', 'Notice'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (3, 'debug', 'Debug'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (4, 'warning', 'Warning'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (5, 'error', 'Error'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (6, 'alert', 'Alert'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (7, 'critical', 'Critical'); +insert into s_tables.t_log_severity_levels (id, name_machine, name_human) values (8, 'emergency', 'Emergency'); + + + +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human) values (0, 'none', 'None'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human) values (1, 'unknown', 'Unknown'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (2, 'provided', 'Provided', '*'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (3, 'stream', 'Stream', 'application'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (4, 'multipart', 'Multipart', 'multipart'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (5, 'text', 'Text', 'text'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (6, 'image', 'Image', 'image'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (7, 'audio', 'Audio', 'audio'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (8, 'video', 'Video', 'video'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (9, 'document', 'Document', 'application'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (10, 'container', 'Container', 'application'); +insert into s_tables.t_types_mime_categorys (id, name_machine, name_human, field_category) values (11, 'application', 'Application', 'application'); + + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human) values (0, 0, 'none', 'None'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human) values (1, 1, 'unknown', 'Unknown'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided', 'Provided', NULL, '*/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided_text', 'Provided Text', NULL, 'text/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided_image', 'Provided Image', NULL, 'image/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided_audio', 'Provided Audio', NULL, 'audio/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided_video', 'Provided Video', NULL, 'video/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2, 2, 'provided_application', 'Provided Application', NULL, 'application/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3, 3, 'stream', 'Stream', 'octect-stream', 'application/octect-stream'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4, 4, 'multipart', 'Form Data', 'form-data', 'multipart/form-data'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1000, 5, 'text', 'Text', NULL, 'text/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1001, 5, 'text_plain', 'Plain Text', 'txt', 'text/plain'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1002, 5, 'text_html', 'HTML', 'html', 'text/html'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1003, 5, 'text_rss', 'RSS', 'rss', 'text/rss'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1003, 5, 'text_rss_xml', 'RSS+XML', 'rss', 'text/rss+xml'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1003, 5, 'text_rdf_xml', 'RDF+XML', 'rss', 'text/rdf+xml'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1003, 5, 'text_atom_xml', 'ATOM+XML', 'rss', 'text/atom+xml'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1004, 5, 'text_ical', 'iCalendar', 'ics', 'text/calendar'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1005, 5, 'text_csv', 'CSV', 'csv', 'text/csv'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1006, 5, 'text_xml', 'XML', 'xml', 'text/xml'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1007, 5, 'text_css', 'CSS', 'css', 'text/css'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1008, 5, 'text_js', 'Javascript', 'js', 'text/js'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1008, 5, 'text_js', 'Javascript', 'js', 'application/js'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1009, 5, 'text_json', 'JSON', 'json', 'text/json'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1010, 5, 'text_rich', 'Rich Text', 'rtf', 'text/rich'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1011, 5, 'text_xhtml', 'XHTML', 'xhtml', 'text/xhtml'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1012, 5, 'text_ps', 'Postscript', 'ps', 'text/ps'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (1013, 5, 'text_fss', 'FSS', 'setting', 'text/fss'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2000, 6, 'image', 'Image', NULL, 'image/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2001, 6, 'image_png', 'PNG', 'png', 'image/png'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2002, 6, 'image_gif', 'GIF', 'gif', 'image/gif'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2003, 6, 'image_jpg', 'JPEG', 'jpg', 'image/jpg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2003, 6, 'image_jpg', 'JPEG', 'jpeg', 'image/jpg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2003, 6, 'image_jpg', 'JPEG', 'jpx', 'image/jpg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2004, 6, 'image_bmp', 'Bitmap', 'bmp', 'image/bmp'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2005, 6, 'image_svg', 'SVG', 'svg', 'image/svg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2006, 6, 'image_tiff', 'Tiff', 'tiff', 'image/tiff'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (2006, 6, 'image_tiff', 'Tiff', 'tiff', 'image/tiff-fx'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3000, 7, 'audio', 'Audio', NULL, 'audio/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3001, 7, 'audio_wav', 'Wave', 'wav', 'audio/wav'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3002, 7, 'audio_ogg', 'OGG', 'ogg', 'audio/ogg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3003, 7, 'audio_speex', 'Speex', 'spx', 'audio/speex'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3004, 7, 'audio_flac', 'FLAC', 'flac', 'audio/flac'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3005, 7, 'audio_mp3', 'MP3', 'mp3', 'audio/mpeg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3005, 7, 'audio_mp1', 'MP1', 'mp1', 'audio/mpeg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3005, 7, 'audio_mp2', 'MP2', 'mp2', 'audio/mpeg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3006, 7, 'audio_mp4', 'MP4', 'mp4', 'audio/mp4'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3007, 7, 'audio_midi', 'SVG', 'svg', 'audio/svg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3008, 7, 'audio_basic', 'Audio', 'au', 'audio/basic'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (3008, 7, 'audio_basic', 'Audio', 'snd', 'audio/basic'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4000, 8, 'video', 'Video', NULL, 'video/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4001, 8, 'video_mpeg', 'MPEG', 'mp4', 'video/mp4'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4001, 8, 'video_mpeg', 'MPEG', 'mpg', 'video/mp4'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4002, 8, 'video_ogg', 'OGG', 'ogg', 'video/ogg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4003, 8, 'video_h264', 'H264', 'h264', 'video/h264'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4003, 8, 'video_x264', 'X264', 'x264', 'video/x264'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4004, 8, 'video_quicktine', 'Quicktime', 'qt', 'video/qt'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4005, 8, 'video_dv', 'Digital Video', 'dv', 'video/dv'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4006, 8, 'video_jpeg', 'Motion JPEG', 'jpg', 'video/jpeg'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (4006, 8, 'video_webm', 'Tiff', 'tiff', 'video/tiff-fx'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5000, 9, 'document', 'Document', NULL, 'application/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5001, 9, 'document_libre_chart', 'LibreOffice Chart', 'odc', 'application/vnd.oasis.opendocument.chart'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5002, 9, 'document_libre_formula', 'LibreOffice Formula', 'odf', 'application/vnd.oasis.opendocument.formula'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5003, 9, 'document_libre_graphic', 'LibreOffice Graphic', 'odg', 'application/vnd.oasis.opendocument.graphics'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5004, 9, 'document_libre_presentation', 'LibreOffice Presentation', 'odp', 'application/vnd.oasis.opendocument.presentation'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5005, 9, 'document_libre_spreadsheet', 'LibreOffice Spreadsheet', 'ods', 'application/vnd.oasis.opendocument.spreadsheet'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5006, 9, 'document_libre_text', 'LibreOffice Text', 'odt', 'application/vnd.oasis.opendocument.text'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5007, 9, 'document_libre_html', 'LibreOffice HTML', 'odh', 'application/vnd.oasis.opendocument.text-web'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5008, 9, 'document_pdf', 'PDF', 'pdf', 'application/pdf'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5009, 9, 'document_abi_word', 'Abiword Text', 'abw', 'application/abiword-compressed'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5010, 9, 'document_ms_word', 'Microsoft Word', 'docx', 'application/msword'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5010, 9, 'document_ms_word', 'Microsoft Word', 'doc', 'application/msword'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5011, 9, 'document_ms_excel', 'Microsoft Excel', 'xlsx', 'application/ms-excel'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5011, 9, 'document_ms_excel', 'Microsoft Excel', 'xls', 'application/ms-excel'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5012, 9, 'document_ms_powerpoint', 'Microsoft Powerpoint', 'pptx', 'application/ms-powerpoint'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (5012, 9, 'document_ms_powerpoint', 'Microsoft Powerpoint', 'ppt', 'application/ms-powerpoint'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (6000, 10, 'container', 'Container', NULL, 'application/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (6001, 10, 'container_tar', 'Tar', 'tar', 'application/tar'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (6002, 10, 'container_cpio', 'CPIO', 'cpio', 'application/cpio'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (6003, 10, 'container_java', 'Java', 'jar', 'application/java'); + +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (7000, 11, 'application', 'Application', NULL, 'application/*'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (7001, 11, 'application_ocsp_request', 'OCSP Request', NULL, 'application/ocsp-request'); +insert into s_tables.t_types_mime_types (id, id_category, name_machine, name_human, field_extension, field_mime) values (7002, 11, 'application_ocsp_response', 'OCSP Response', NULL, 'application/ocsp-response'); + + + +/** create all of the known codes, initializing them to 0. **/ +insert into s_tables.t_statistics_http_status_codes (code) values (0); +insert into s_tables.t_statistics_http_status_codes (code) values (1); +insert into s_tables.t_statistics_http_status_codes (code) values (2); + +insert into s_tables.t_statistics_http_status_codes (code) values (100); +insert into s_tables.t_statistics_http_status_codes (code) values (101); +insert into s_tables.t_statistics_http_status_codes (code) values (102); + +insert into s_tables.t_statistics_http_status_codes (code) values (200); +insert into s_tables.t_statistics_http_status_codes (code) values (201); +insert into s_tables.t_statistics_http_status_codes (code) values (202); +insert into s_tables.t_statistics_http_status_codes (code) values (203); +insert into s_tables.t_statistics_http_status_codes (code) values (204); +insert into s_tables.t_statistics_http_status_codes (code) values (205); +insert into s_tables.t_statistics_http_status_codes (code) values (206); +insert into s_tables.t_statistics_http_status_codes (code) values (207); +insert into s_tables.t_statistics_http_status_codes (code) values (208); +insert into s_tables.t_statistics_http_status_codes (code) values (226); + +insert into s_tables.t_statistics_http_status_codes (code) values (300); +insert into s_tables.t_statistics_http_status_codes (code) values (301); +insert into s_tables.t_statistics_http_status_codes (code) values (302); +insert into s_tables.t_statistics_http_status_codes (code) values (303); +insert into s_tables.t_statistics_http_status_codes (code) values (304); +insert into s_tables.t_statistics_http_status_codes (code) values (305); +insert into s_tables.t_statistics_http_status_codes (code) values (306); +insert into s_tables.t_statistics_http_status_codes (code) values (307); +insert into s_tables.t_statistics_http_status_codes (code) values (308); + +insert into s_tables.t_statistics_http_status_codes (code) values (400); +insert into s_tables.t_statistics_http_status_codes (code) values (401); +insert into s_tables.t_statistics_http_status_codes (code) values (402); +insert into s_tables.t_statistics_http_status_codes (code) values (403); +insert into s_tables.t_statistics_http_status_codes (code) values (404); +insert into s_tables.t_statistics_http_status_codes (code) values (405); +insert into s_tables.t_statistics_http_status_codes (code) values (406); +insert into s_tables.t_statistics_http_status_codes (code) values (407); +insert into s_tables.t_statistics_http_status_codes (code) values (408); +insert into s_tables.t_statistics_http_status_codes (code) values (409); +insert into s_tables.t_statistics_http_status_codes (code) values (410); +insert into s_tables.t_statistics_http_status_codes (code) values (411); +insert into s_tables.t_statistics_http_status_codes (code) values (412); +insert into s_tables.t_statistics_http_status_codes (code) values (413); +insert into s_tables.t_statistics_http_status_codes (code) values (414); +insert into s_tables.t_statistics_http_status_codes (code) values (415); +insert into s_tables.t_statistics_http_status_codes (code) values (416); +insert into s_tables.t_statistics_http_status_codes (code) values (417); +insert into s_tables.t_statistics_http_status_codes (code) values (422); +insert into s_tables.t_statistics_http_status_codes (code) values (423); +insert into s_tables.t_statistics_http_status_codes (code) values (424); +insert into s_tables.t_statistics_http_status_codes (code) values (426); +insert into s_tables.t_statistics_http_status_codes (code) values (428); +insert into s_tables.t_statistics_http_status_codes (code) values (429); +insert into s_tables.t_statistics_http_status_codes (code) values (431); +insert into s_tables.t_statistics_http_status_codes (code) values (451); + +insert into s_tables.t_statistics_http_status_codes (code) values (500); +insert into s_tables.t_statistics_http_status_codes (code) values (501); +insert into s_tables.t_statistics_http_status_codes (code) values (502); +insert into s_tables.t_statistics_http_status_codes (code) values (503); +insert into s_tables.t_statistics_http_status_codes (code) values (504); +insert into s_tables.t_statistics_http_status_codes (code) values (505); +insert into s_tables.t_statistics_http_status_codes (code) values (506); +insert into s_tables.t_statistics_http_status_codes (code) values (507); +insert into s_tables.t_statistics_http_status_codes (code) values (508); +insert into s_tables.t_statistics_http_status_codes (code) values (510); +insert into s_tables.t_statistics_http_status_codes (code) values (511); + + + +/* @todo: consider creating default request types */ +insert into s_tables.t_request_types (id, name_machine, name_human) values (0, 'none', 'None'); + + + + +/*** start the sequence count at 1000 to allow for < 1000 to be reserved for special uses ***/ +alter sequence s_tables.se_users_id start 1000; +alter sequence s_tables.se_users_id restart; + + +/*** create hard-coded/internal user ids ***/ +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (3, 'u_system_administer', (null, 'System', null, 'Administer', null, 'System (Administer)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (4, 'u_system_manager', (null, 'System', null, 'Manager', null, 'System (Manager)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (5, 'u_system_auditor', (null, 'System', null, 'Auditor', null, 'System (Auditor)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (6, 'u_system_publisher', (null, 'System', null, 'Publisher', null, 'System (Publisher)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (7, 'u_system_insurer', (null, 'System', null, 'Insurer', null, 'System (Insurer)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (8, 'u_system_financer', (null, 'System', null, 'Financer', null, 'System (Financer)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (9, 'u_system_reviewer', (null, 'System', null, 'Reviewer', null, 'System (Reviewer)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (10, 'u_system_editor', (null, 'System', null, 'Editor', null, 'System (Editor)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (11, 'u_system_drafter', (null, 'System', null, 'Drafter', null, 'System (Drafter)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (12, 'u_system_requester', (null, 'System', null, 'Requester', null, 'System (Requester)'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system, is_public) values (13, 'u_system_public', (null, 'System', null, 'Public', null, 'System (Public)'), false, true, true); + + + +commit; diff --git a/database/sql/reservation/reservation-legal.sql b/database/sql/reservation/reservation-legal.sql new file mode 100644 index 0000000..5a3fbfe --- /dev/null +++ b/database/sql/reservation/reservation-legal.sql @@ -0,0 +1,126 @@ +/** Standardized SQL Structure - Legal */ +/** This depends on: base-users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** Legal Types ***/ +create table s_tables.t_legal_types ( + id bigint not null, + id_external bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cu_legal_types_id unique (id), + constraint cu_legal_types_name_machine unique (name_machine), + + constraint cc_legal_types_id check (id > -1) +); + +create sequence s_tables.se_legal_types_id owned by s_tables.t_legal_types.id; +alter table s_tables.t_legal_types alter column id set default nextval('s_tables.se_legal_types_id'::regclass); + +grant select,insert,update on s_tables.t_legal_types to r_reservation_manager; +grant select on s_tables.t_legal_types to r_reservation_auditor; +grant select,usage on s_tables.se_legal_types_id to r_reservation_manager; + +create index i_legal_types_deleted_not on s_tables.t_legal_types (id) + where is_deleted is not true; + +create index i_legal_type_locked_not on s_tables.t_legal_types (id) + where is_deleted is not true and is_locked is not true; + + +create view s_users.v_legal_types with (security_barrier=true) as + select id, id_external, name_machine, name_human, is_locked from s_tables.t_legal_types + where is_deleted is not true and is_locked is not true; + +grant select on s_users.v_legal_types to r_reservation_auditor, r_reservation_requester; + + +create trigger tr_legal_types_date_changed_deleted_or_locked + before update on s_tables.t_legal_types + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** Legal / Digital Signatures ***/ +create table s_tables.t_signatures ( + id bigint not null, + id_creator bigint not null, + id_creator_session bigint not null, + id_type bigint not null, + id_request bigint, + + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_deleted timestamp, + + /* @todo: PGP/GPG based signatures are planned but not currently implemented, the columns (fingerprint and signature) are created but are subject to major change. */ + field_fingerprint varchar(64), + field_signature text, + + constraint cp_signatures unique (id), + + constraint cc_signatures_id check (id > 0), + + constraint cf_signatures_user foreign key (id_creator) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_signatures_user_session foreign key (id_creator_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_signatures_id_type foreign key (id_type) references s_tables.t_legal_types (id) on delete restrict on update cascade, + constraint cf_signatures_id_request foreign key (id_request) references s_tables.t_requests (id) on delete restrict on update cascade +); + +create sequence s_tables.se_signatures_id owned by s_tables.t_signatures.id; +alter table s_tables.t_signatures alter column id set default nextval('s_tables.se_signatures_id'::regclass); + +grant select,insert,update on s_tables.t_signatures to r_reservation_manager; +grant select on s_tables.t_signatures to r_reservation_auditor; +grant select,usage on s_tables.se_signatures_id to r_reservation_manager; +grant usage on s_tables.se_signatures_id to r_reservation, r_reservation_system; + +create index i_signatures_deleted_not on s_tables.t_signatures (id) + where is_deleted is not true; + + +/*** provide current user access to their own information ***/ +create view s_users.v_signatures_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_type, id_request, date_created, field_fingerprint, field_signature from s_tables.t_signatures + where is_deleted is not true and id_creator in (select * from this_user); + +grant select on s_users.v_signatures_self to r_reservation, r_reservation_system; + + +/** provide current user access to insert their own associations **/ +create view s_users.v_signatures_self_insert with (security_barrier=true) as + select id, id_type, id_creator, id_request, field_fingerprint, field_signature from s_tables.t_signatures + where is_deleted is not true and id_creator in (select id from s_users.v_users_locked_not_self) + with check option; + +grant insert on s_users.v_signatures_self_insert to r_reservation, r_reservation_system; + + +create trigger tr_signatures_date_deleted + before update on s_tables.t_signatures + for each row execute procedure s_administers.f_common_update_date_deleted(); + + + +commit; diff --git a/database/sql/reservation/reservation-log_groups.sql b/database/sql/reservation/reservation-log_groups.sql new file mode 100644 index 0000000..647f2fe --- /dev/null +++ b/database/sql/reservation/reservation-log_groups.sql @@ -0,0 +1,122 @@ +/** Standardized SQL Structure - Logs - Groups */ +/** This depends on: base-groups.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** provide group activity logging ***/ +create table s_tables.t_log_groups ( + id bigint not null, + id_user bigint not null, + id_user_session bigint not null, + id_group bigint not null, + + log_type bigint not null, + log_details json, + log_date timestamp default localtimestamp not null, + + constraint cp_log_groups primary key (id), + + constraint cc_log_groups_id check (id > 0), + + constraint cf_log_groups_id_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_groups_id_user_session foreign key (id_user_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_groups_id_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade, + constraint cf_log_groups_log_type foreign key (log_type) references s_tables.t_log_types (id) on delete restrict on update cascade +); + +create sequence s_tables.se_log_groups_id owned by s_tables.t_log_groups.id; +alter table s_tables.t_log_groups alter column id set default nextval('s_tables.se_log_groups_id'::regclass); + +grant select,usage on s_tables.se_log_groups_id to r_reservation_manager, r_reservation_auditor; +grant usage on s_tables.se_log_groups_id to r_reservation, r_reservation_system; + + +/** only allow select and insert for users when user id is current user **/ +create view s_users.v_log_groups_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_user, id_group, log_type, log_details, log_date from s_tables.t_log_groups + where id_user in (select * from this_user); + +grant select on s_users.v_log_groups_self to r_reservation, r_reservation_system; + +create view s_users.v_log_groups_self_insert with (security_barrier=true) as + select id_group, log_type, log_details from s_tables.t_log_groups + where id_user in (select id from s_users.v_users_locked_not_self) and id_group in (select id from s_users.v_groups_self where is_locked is not true) + with check option; + +grant insert on s_users.v_log_groups_self_insert to r_reservation, r_reservation_system; + + +create trigger tr_log_groups_date_changed_deleted_or_locked + before update on s_tables.t_log_groups + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +create trigger tr_log_groups_enforce_user_and_session_ids + before insert on s_tables.t_log_groups + for each row execute procedure s_administers.f_common_enforce_user_and_session_ids(); + + + +/*** provide group user activity logging ***/ +create table s_tables.t_log_group_users ( + id bigint not null, + id_user bigint not null, + id_user_session bigint not null, + id_group bigint not null, + + log_type bigint not null, + log_date timestamp default localtimestamp not null, + + constraint cp_log_group_users primary key (id), + + constraint cc_log_group_users_id check (id > 0), + + constraint cf_log_group_users_id_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_group_users_id_user_session foreign key (id_user_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_group_users_id_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade, + constraint cf_log_group_users_log_type foreign key (log_type) references s_tables.t_log_types (id) on delete restrict on update cascade +); + +create sequence s_tables.se_log_group_users_id owned by s_tables.t_log_group_users.id; +alter table s_tables.t_log_group_users alter column id set default nextval('s_tables.se_log_group_users_id'::regclass); + +grant select,usage on s_tables.se_log_group_users_id to r_reservation_manager, r_reservation_auditor; +grant usage on s_tables.se_log_group_users_id to r_reservation, r_reservation_system; + + +/** only allow select and insert for users when user id is current user **/ +create view s_users.v_log_group_users_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self), + allowed_groups as (select id from s_users.v_groups_self where is_locked is not true) + select id, id_user, id_group, log_type, log_date from s_tables.t_log_group_users + where id_user in (select * from this_user) or id_group in (select * from allowed_groups); + +grant select on s_users.v_log_group_users_self to r_reservation, r_reservation_system; + +create view s_users.v_log_group_users_self_insert with (security_barrier=true) as + select id_group, log_type from s_tables.t_log_group_users + where id_user in (select id from s_users.v_users_locked_not_self) and id_group in (select id from s_users.v_groups_self where is_locked is not true) + with check option; + +grant insert on s_users.v_log_group_users_self_insert to r_reservation, r_reservation_system; + + +create trigger tr_log_group_users_date_changed_deleted_or_locked + before update on s_tables.t_log_group_users + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +create trigger tr_log_group_users_enforce_user_and_session_ids + before insert on s_tables.t_log_group_users + for each row execute procedure s_administers.f_common_enforce_user_and_session_ids(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-log_problems.sql b/database/sql/reservation/reservation-log_problems.sql new file mode 100644 index 0000000..58e6867 --- /dev/null +++ b/database/sql/reservation/reservation-log_problems.sql @@ -0,0 +1,117 @@ +/** Standardized SQL Structure - Logs - Problems */ +/** This depends on: base-users.sql **/ +/* The problem logs are intended for temporary reporting of problems and are meant to allow permanent deletion. */ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/** Provide a log of problems, which are defined by the software. **/ +/* @todo: shouldnt there be a problem type code? */ +create table s_tables.t_log_problems ( + id bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + + constraint cp_log_problems primary key (id), + + constraint cc_log_problems_id check (id > 0), + + constraint cu_log_problems_name_machine unique (name_machine) +); + +create sequence s_tables.se_log_problems_id owned by s_tables.t_log_problems.id; +alter table s_tables.t_log_problems alter column id set default nextval('s_tables.se_log_problems_id'::regclass); + +grant select,insert,update,delete on s_tables.t_log_problems to r_reservation_manager; +grant select on s_tables.t_log_problems to r_reservation_auditor; +grant select,usage on s_tables.se_log_problems_id to r_reservation_manager, r_reservation_auditor; +grant usage on s_tables.se_log_problems_id to r_reservation, r_reservation_system; + +/* @todo: it seems the views for allowing users to insert/delete problems needs to be created. */ + + + +/** Provide a log of problems, associated with a given user. **/ +create table s_tables.t_log_problems_users ( + id_problem bigint not null, + id_user bigint not null, + id_user_session bigint not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + + log_details json, + + constraint cp_log_problems_users primary key (id_problem, id_user), + + constraint cf_log_problems_users_id_problem foreign key (id_problem) references s_tables.t_log_problems (id) on delete restrict on update cascade, + constraint cf_log_problems_users_id_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_problems_users_id_user_session foreign key (id_user_session) references s_tables.t_users (id) on delete restrict on update cascade +); + +grant select,insert,update,delete on s_tables.t_log_problems_users to r_reservation_manager; +grant select on s_tables.t_log_problems_users to r_reservation_auditor; + + +/** only allow select, insert, and delete for users when user id is current user **/ +create view s_users.v_log_problems_users_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id_problem, date_created, date_changed, log_details from s_tables.t_log_problems_users + where id_user in (select * from this_user); + +grant select on s_users.v_log_problems_users_self to r_reservation, r_reservation_system; + + +create view s_users.v_log_problems_users_self_insert with (security_barrier=true) as + select id_problem, date_changed, log_details from s_tables.t_log_problems_users + where id_user in (select id from s_users.v_users_locked_not_self) + with check option; + +grant insert on s_users.v_log_problems_users_self_insert to r_reservation, r_reservation_system; + + +create view s_users.v_log_problems_users_self_delete with (security_barrier=true) as + select id_problem from s_tables.t_log_problems_users + where id_user in (select id from s_users.v_users_locked_not_self) + with check option; + +grant delete on s_users.v_log_problems_users_self_delete to r_reservation, r_reservation_system; + + +/** automatically delete problems deleted from the table s_tables.t_log_problems_users **/ +create function s_tables.f_log_problems_users_delete() returns trigger security definer as $$ + begin + if (tg_op = 'DELETE') then + delete from s_tables.t_log_problems where id = old.id_problem; + return old; + end if; + + return null; + end; +$$ language plpgsql; + +reset role; + +alter function s_tables.f_log_problems_users_delete () owner to r_reservation_logger; + +create trigger tr_log_problems_users_delete + after delete on s_tables.t_log_problems_users + for each row execute procedure s_tables.f_log_problems_users_delete(); + +create trigger tr_log_problems_enforce_user_and_session_ids + before insert on s_tables.t_log_problems + for each row execute procedure s_administers.f_common_enforce_user_and_session_ids(); + + +commit transaction; diff --git a/database/sql/reservation/reservation-log_types.sql b/database/sql/reservation/reservation-log_types.sql new file mode 100644 index 0000000..906c1ed --- /dev/null +++ b/database/sql/reservation/reservation-log_types.sql @@ -0,0 +1,144 @@ +/** Standardized SQL Structure - Logs - Types */ +/** This depends on: base-users.sql **/ +/* @todo: consider prepending t_log_types_ to all tables (except t_log_types itself). */ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** provide log type id and names ***/ +create table s_tables.t_log_types ( + id bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_deleted timestamp, + + constraint cp_log_types primary key (id), + + constraint cu_log_types_user unique (name_machine), + + constraint cc_log_types_id check (id >= 0) +); + +create sequence s_tables.se_log_types_id owned by s_tables.t_log_types.id; +alter table s_tables.t_log_types alter column id set default nextval('s_tables.se_log_types_id'::regclass); + +grant select,insert,update on s_tables.t_log_types to r_reservation_administer; +grant select on s_tables.t_log_types to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_log_types_id to r_reservation_administer; + +create index i_log_types_deleted_not on s_tables.t_log_types (id) + where is_deleted is not true; + +create index i_log_types_public on s_tables.t_log_types (id) + where is_deleted is not true and is_locked is not true; + +create view public.v_log_types with (security_barrier=true) as + select id, name_machine, name_human from s_tables.t_log_types + where is_deleted is not true and is_locked is not true; + +grant select on public.v_log_types to r_reservation, r_public, r_reservation_system; + + +create trigger tr_log_types_date_changed_deleted_or_locked + before update on s_tables.t_log_types + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** provide HTTP status codes ***/ +create table s_tables.t_log_http_status_codes ( + id smallint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cp_log_http_status_codes primary key (id), + + constraint cu_log_http_status_codes_user unique (name_machine), + + constraint cc_log_http_status_codes_id check (id >= 0 and id < 600) +); + +create sequence s_tables.se_log_http_status_codes_id owned by s_tables.t_log_http_status_codes.id; +alter table s_tables.t_log_http_status_codes alter column id set default nextval('s_tables.se_log_http_status_codes_id'::regclass); + +grant select,insert,update on s_tables.t_log_http_status_codes to r_reservation_administer; +grant select on s_tables.t_log_http_status_codes to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_log_http_status_codes_id to r_reservation_administer; + +create view public.v_log_http_status_codes with (security_barrier=true) as + select id, name_machine, name_human from s_tables.t_log_http_status_codes; + +grant select on public.v_log_http_status_codes to r_reservation, r_public, r_reservation_system; + + +create trigger tr_log_http_status_codes_date_changed_deleted_or_locked + before update on s_tables.t_log_http_status_codes + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** provide log severity level id and names ***/ +create table s_tables.t_log_severity_levels ( + id bigint not null, + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cp_log_severity_levels primary key (id), + + constraint cu_log_severity_levels_user unique (name_machine), + + constraint cc_log_severity_levels_id check (id >= 0) +); + +create sequence s_tables.se_log_severity_levels_id owned by s_tables.t_log_severity_levels.id; +alter table s_tables.t_log_severity_levels alter column id set default nextval('s_tables.se_log_severity_levels_id'::regclass); + +grant select,insert,update on s_tables.t_log_severity_levels to r_reservation_administer; +grant select on s_tables.t_log_severity_levels to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_log_severity_levels_id to r_reservation_administer; + +create view s_users.v_log_severity_levels with (security_barrier=true) as + select id, name_machine, name_human from s_tables.t_log_severity_levels + where is_deleted is not true; + +grant select on s_users.v_log_severity_levels to r_reservation, r_public, r_reservation_system; + + +create trigger tr_log_severity_levels_date_changed_deleted_or_locked + before update on s_tables.t_log_severity_levels + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-log_users.sql b/database/sql/reservation/reservation-log_users.sql new file mode 100644 index 0000000..4976034 --- /dev/null +++ b/database/sql/reservation/reservation-log_users.sql @@ -0,0 +1,237 @@ +/** Standardized SQL Structure - Logs */ +/** This depends on: base-users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** provide user activity logging ***/ +create table s_tables.t_log_users ( + id bigint not null, + id_user bigint not null, + id_user_session bigint not null, + + log_title varchar(512) not null, + log_type bigint not null, + log_severity bigint not null, + log_details json, + log_date timestamp default localtimestamp not null, + + request_client public.ct_client not null, + response_code smallint not null default 0, + + constraint cp_log_users primary key (id), + + constraint cc_log_users_id check (id > 0), + constraint cc_log_users_log_severity check (log_severity > 0), + + constraint cf_log_users_id_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_users_id_user_session foreign key (id_user_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_users_log_type foreign key (log_type) references s_tables.t_log_types (id) on delete restrict on update cascade, + constraint cf_log_users_log_severity foreign key (log_severity) references s_tables.t_log_severity_levels (id) on delete restrict on update cascade, + constraint cf_log_users_response_code foreign key (response_code) references s_tables.t_log_http_status_codes (id) on delete restrict on update cascade +); + +create sequence s_tables.se_log_users_id owned by s_tables.t_log_users.id; +alter table s_tables.t_log_users alter column id set default nextval('s_tables.se_log_users_id'::regclass); + +grant select on s_tables.t_log_users to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_log_users_id to r_reservation_administer; +grant usage on s_tables.se_log_users_id to r_reservation, r_public, r_reservation_system; + +create index i_log_users_type_php on s_tables.t_log_users (id) + where log_type = 1; + +create index i_log_users_type_theme on s_tables.t_log_users (id) + where log_type = 2; + +create index i_log_users_type_cache on s_tables.t_log_users (id) + where log_type = 3; + +create index i_log_users_type_javascript on s_tables.t_log_users (id) + where log_type = 4; + +create index i_log_users_type_ajax on s_tables.t_log_users (id) + where log_type = 5; + +create index i_log_users_type_sql on s_tables.t_log_users (id) + where log_type = 6; + +create index i_log_users_type_redirect on s_tables.t_log_users (id) + where log_type = 16; + +create index i_log_users_type_login on s_tables.t_log_users (id) + where log_type = 17; + +create index i_log_users_type_logout on s_tables.t_log_users (id) + where log_type = 18; + +create index i_log_users_type_user on s_tables.t_log_users (id) + where log_type = 27; + +create index i_log_users_type_error on s_tables.t_log_users (id) + where log_type = 28; + +create index i_log_users_type_content on s_tables.t_log_users (id) + where log_type = 29; + +create index i_log_users_type_workflow on s_tables.t_log_users (id) + where log_type = 30; + +create index i_log_users_type_search on s_tables.t_log_users (id) + where log_type = 39; + +create index i_log_users_response_code_200 on s_tables.t_log_users (id) + where response_code = 200; + +create index i_log_users_response_code_403 on s_tables.t_log_users (id) + where response_code = 403; + +create index i_log_users_response_code_404 on s_tables.t_log_users (id) + where response_code = 404; + +create index i_log_users_response_code_410 on s_tables.t_log_users (id) + where response_code = 410; + +create index i_log_users_response_code_500 on s_tables.t_log_users (id) + where response_code = 500; + +create index i_log_users_response_code_503 on s_tables.t_log_users (id) + where response_code = 503; + +create index i_log_users_response_code_normal on s_tables.t_log_users (id) + where response_code in (200, 201, 202, 304); + +create index i_log_users_response_code_redirects on s_tables.t_log_users (id) + where response_code in (301, 302, 303, 307, 308); + +create index i_log_users_response_code_notable on s_tables.t_log_users (id) + where response_code in (400, 403, 404, 410, 500, 503); + + +/** only allow select and insert for users when user id is current user **/ +create view s_users.v_log_users_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_user, log_title, log_type, log_severity, log_details, log_date, request_client, response_code from s_tables.t_log_users + where id_user in (select * from this_user); + +grant select on s_users.v_log_users_self to r_reservation, r_reservation_system; + +create view s_users.v_log_users_self_insert with (security_barrier=true) as + select log_title, log_type, log_severity, log_details, request_client, response_code from s_tables.t_log_users + where id_user in (select id from s_users.v_users_locked_not_self) + with check option; + +grant insert on s_users.v_log_users_self_insert to r_reservation, r_reservation_system; + + +/** only allow insert for the public user **/ +create view public.v_log_users_self_insert with (security_barrier=true) as + select log_title, log_type, log_severity, log_details, request_client, response_code from s_tables.t_log_users + where id_user = 1 + with check option; + +grant insert on public.v_log_users_self_insert to r_public; + + +create trigger tr_log_users_enforce_user_and_session_ids + before insert on s_tables.t_log_users + for each row execute procedure s_administers.f_common_enforce_user_and_session_ids(); + + + +/*** provide access activity logging ***/ +create table s_tables.t_log_user_activity ( + id bigint not null, + id_user bigint not null, + id_user_session bigint not null, + + request_path varchar(512) not null, + request_arguments varchar(512) not null, + request_date timestamp default localtimestamp not null, + request_client public.ct_client not null, + request_headers json, + + response_headers json, + response_code smallint not null default 0, + + constraint cp_log_user_activity primary key (id), + + constraint cc_log_user_activity_id check (id > 0), + + constraint cf_log_user_activity_id_user foreign key (id_user) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_user_activity_id_user_session foreign key (id_user_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_log_user_activity_response_code foreign key (response_code) references s_tables.t_log_http_status_codes (id) on delete restrict on update cascade +); + +create sequence s_tables.se_log_user_activity_id owned by s_tables.t_log_user_activity.id; +alter table s_tables.t_log_user_activity alter column id set default nextval('s_tables.se_log_user_activity_id'::regclass); + +grant select on s_tables.t_log_user_activity to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_log_user_activity_id to r_reservation_administer; +grant usage on s_tables.se_log_user_activity_id to r_reservation, r_public, r_reservation_system; + +create index i_log_user_activity_response_code_4xx on s_tables.t_log_user_activity (id) + where response_code >= 400 and response_code < 500; + +create index i_log_user_activity_response_code_403 on s_tables.t_log_user_activity (id) + where response_code = 403; + +create index i_log_user_activity_response_code_404 on s_tables.t_log_user_activity (id) + where response_code = 404; + +create index i_log_user_activity_response_code_410 on s_tables.t_log_user_activity (id) + where response_code = 410; + +create index i_log_user_activity_response_code_5xx on s_tables.t_log_user_activity (id) + where response_code >= 500 and response_code < 600; + +create index i_log_user_activity_response_code_500 on s_tables.t_log_user_activity (id) + where response_code = 500; + +create index i_log_user_activity_response_code_503 on s_tables.t_log_user_activity (id) + where response_code = 503; + +create index i_log_user_activity_response_code_notable on s_tables.t_log_user_activity (id) + where response_code in (403, 404, 410, 500, 503); + + + +/** only allow select and insert for users when user id is current user **/ +create view s_users.v_log_user_activity_self with (security_barrier=true) as + with this_user as (select id from s_users.v_users_locked_not_self) + select id, id_user, request_path, request_arguments, request_date, request_client, request_headers, response_headers, response_code from s_tables.t_log_user_activity + where id_user in (select * from this_user); + +grant select on s_users.v_log_user_activity_self to r_reservation, r_reservation_system; + +create view s_users.v_log_user_activity_self_insert with (security_barrier=true) as + select request_path, request_arguments, request_client, request_headers, response_headers, response_code from s_tables.t_log_user_activity + where id_user in (select id from s_users.v_users_locked_not_self) + with check option; + +grant insert on s_users.v_log_user_activity_self_insert to r_reservation, r_reservation_system; + + +/** only allow insert for the public user **/ +create view public.v_log_user_activity_self_insert with (security_barrier=true) as + select request_path, request_arguments, request_client, request_headers, response_headers, response_code from s_tables.t_log_user_activity + where id_user = 1 + with check option; + +grant insert on public.v_log_user_activity_self_insert to r_public; + + +create trigger tr_log_user_activity_enforce_user_and_session_ids + before insert on s_tables.t_log_user_activity + for each row execute procedure s_administers.f_common_enforce_user_and_session_ids(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-main.sql b/database/sql/reservation/reservation-main.sql new file mode 100644 index 0000000..850f256 --- /dev/null +++ b/database/sql/reservation/reservation-main.sql @@ -0,0 +1,328 @@ +/** Standardized SQL Structure - Main */ +/** This depends on: base-first.sql **/ +/* @todo: add restrictions to even managers and administers so that ALL users access via views to allow for disabling any account (even an admin). + only the postgresql/root account may access tables directly. + This requires changing permissions and adding the appropriate s_administers and s_managers tables. +*/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/** Schemas **/ +create schema s_administers authorization postgres; +create schema s_managers authorization postgres; +create schema s_auditors authorization postgres; +create schema s_publishers authorization postgres; +create schema s_insurers authorization postgres; +create schema s_financers authorization postgres; +create schema s_reviewers authorization postgres; +create schema s_editors authorization postgres; +create schema s_drafters authorization postgres; +create schema s_requesters authorization postgres; +create schema s_users authorization postgres; +create schema s_tables authorization postgres; + +grant usage on schema s_administers to r_reservation_administer; +grant usage on schema s_managers to r_reservation_manager; +grant usage on schema s_auditors to r_reservation_auditor; +grant usage on schema s_publishers to r_reservation_publisher; +grant usage on schema s_insurers to r_reservation_insurer; +grant usage on schema s_financers to r_reservation_financer; +grant usage on schema s_reviewers to r_reservation_reviewer; +grant usage on schema s_editors to r_reservation_editor; +grant usage on schema s_drafters to r_reservation_drafter; +grant usage on schema s_requesters to r_reservation_requester; +grant usage on schema s_users to r_reservation; + +grant usage on schema s_tables to r_reservation_revision_requests, r_reservation_statistics_update, r_reservation_logger; + + +/** Composite Types **/ +create type public.ct_name_person as ( + prefix varchar(32), + first varchar(64), + middle varchar(64), + last varchar(64), + suffix varchar(32), + complete varchar(256) +); + +create type public.ct_client as ( + ip inet, + port int, + agent varchar(256) +); + +create type public.ct_email as ( + name varchar(128), + domain varchar(128), + private boolean +); + +create type public.ct_text as ( + content text, + context bigint +); + +create type public.ct_location as ( + building bigint, + room bigint[] +); + +create type public.ct_date as ( + date timestamp, + time_start timestamp, + time_stop timestamp +); + +create type public.ct_date_context as ( + date timestamp, + time_start timestamp, + time_stop timestamp, + context bigint +); + +create type public.ct_phone_number as ( + country smallint, + area smallint, + number smallint, + extension smallint +); + +create type public.ct_phone_number_context as ( + country smallint, + area smallint, + number smallint, + extension smallint, + context bigint +); + +create type public.ct_money_context as ( + money money, + context bigint +); + +create type public.ct_field_fees as ( + needed bool, + quantity bigint, + days bigint, + hours bigint, + amount money +); + +create type public.ct_field_used_with_contact as ( + used bool, + email text, + name text, + phone public.ct_phone_number +); + +create type public.ct_field_needed_with_total as ( + needed bool, + total bigint +); + +create type public.ct_field_needed_with_details as ( + needed bool, + details text +); + +create type public.ct_field_used_with_details as ( + used bool, + details text +); + +create type public.ct_field_used_with_designer as ( + used bool, + designer text +); + +create type public.ct_field_served_with_caterer as ( + served bool, + caterer text +); + +create type public.ct_field_generated_with_types as ( + generated bool, + types bigint[] +); + +create type public.ct_field_needed_with_types as ( + needed bool, + types bigint[] +); + +create type public.ct_field_needed_with_types_and_microphone as ( + needed bool, + types bigint[], + microphone bigint +); + +create type public.ct_field_insurance as ( + needed bool, + provided bool +); + + + +/** Common Functions **/ +/* User ID and Session User ID Functions */ +create function s_administers.f_common_enforce_user_and_session_ids() returns trigger as $$ + begin + new.id_user = coalesce((select id from v_users_self), 1); + new.id_user_session = coalesce((select id from v_users_self_session), 1); + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_enforce_creator_and_session_ids() returns trigger as $$ + begin + new.id_creator = coalesce((select id from v_users_self), 1); + new.id_creator_session = coalesce((select id from v_users_self_session), 1); + return new; + end; +$$ language plpgsql; + + +/* Date Change Functions */ +create function s_administers.f_common_update_date_deleted() returns trigger as $$ + begin + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_update_date_changed_or_deleted() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_update_date_changed_or_locked() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_locked = false and new.is_locked = true) then + new.date_locked = localtimestamp; + elseif (old.is_locked = true and new.is_locked = false) then + new.date_locked = localtimestamp; + end if; + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_update_date_changed_deleted_or_locked() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + if (old.is_locked = false and new.is_locked = true) then + new.date_locked = localtimestamp; + elseif (old.is_locked = true and new.is_locked = false) then + new.date_locked = localtimestamp; + end if; + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_update_date_changed_deleted_cancelled_or_locked() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + if (old.is_locked = false and new.is_locked = true) then + new.date_locked = localtimestamp; + elseif (old.is_locked = true and new.is_locked = false) then + new.date_locked = localtimestamp; + end if; + + if (old.is_cancelled = false and new.is_cancelled = true) then + new.date_cancelled = localtimestamp; + elseif (old.is_cancelled = true and new.is_cancelled = false) then + new.date_cancelled = localtimestamp; + end if; + + return new; + end; +$$ language plpgsql; + + +/* Revision Increment Functions */ +create function s_administers.f_common_increment_revision() returns trigger as $$ + begin + new.id_revision = old.id_revision + 1; + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_increment_revision_update_date_changed_or_deleted() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + new.id_revision = old.id_revision + 1; + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_common_increment_revision_update_date_changed_deleted_or_locked() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + if (old.is_locked = false and new.is_locked = true) then + new.date_locked = localtimestamp; + elseif (old.is_locked = true and new.is_locked = false) then + new.date_locked = localtimestamp; + end if; + + new.id_revision = old.id_revision + 1; + + return new; + end; +$$ language plpgsql; + +commit transaction; diff --git a/database/sql/reservation/reservation-paths.sql b/database/sql/reservation/reservation-paths.sql new file mode 100644 index 0000000..da9e6b2 --- /dev/null +++ b/database/sql/reservation/reservation-paths.sql @@ -0,0 +1,152 @@ +/** Standardized SQL Structure - Content **/ +/** This depends on: base-groups.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** provide path type id and names ***/ +create table s_tables.t_path_types ( + id bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_deleted timestamp, + date_locked timestamp, + + constraint cp_path_types primary key (id), + + constraint cu_path_types_name_machine unique (name_machine), + + constraint cc_path_types_id check (id > -1) +); + +create sequence s_tables.se_path_types_id owned by s_tables.t_path_types.id; +alter table s_tables.t_path_types alter column id set default nextval('s_tables.se_path_types_id'::regclass); + +grant select,insert,update on s_tables.t_path_types to r_reservation_administer; +grant select on s_tables.t_path_types to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_path_types_id to r_reservation_administer; + +create index i_path_types_deleted_not on s_tables.t_path_types (id) + where is_deleted is not true; + +create index i_path_types_public on s_tables.t_path_types (id) + where is_deleted is not true and is_locked is not true; + + +create view s_managers.v_path_types with (security_barrier=true) as + select id, name_machine, name_human, is_locked, date_created, date_changed from s_tables.t_path_types + where is_deleted is not true and is_locked is not true; + +grant select on s_managers.v_path_types to r_reservation_manager; + + +create view public.v_path_types with (security_barrier=true) as + select id, name_machine, name_human, FALSE as is_locked, NULL::timestamp as date_created, NULL::timestamp as date_changed from s_tables.t_path_types + where is_deleted is not true and is_locked is not true; + +grant select on public.v_path_types to r_reservation, r_public, r_reservation_system; + + +create trigger tr_path_types_date_changed_deleted_or_locked + before update on s_tables.t_path_types + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + +/* @todo: come up with a design for dynamic path management via users/managers (as opposed to hardcoded paths in source). */ +/*** provide paths table (@todo: this is added as a stub and needs to be finished) ***/ +create table s_tables.t_paths ( + id bigint not null, + id_creator bigint not null, + id_creator_session bigint not null, + id_type bigint not null, + id_group bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_private boolean default true not null, + is_locked boolean default false not null, + is_deleted boolean default false not null, + is_system boolean default false not null, + is_user boolean default false not null, + + field_path varchar(256) not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cp_paths primary key (id), + + constraint cu_paths_name_machine unique (name_machine), + constraint cu_paths_field_path unique (field_path), + + constraint cc_paths_id check (id > 0), + + constraint cf_paths_id_creator foreign key (id_creator) references s_tables.t_users (id) on delete cascade on update cascade, + constraint cf_paths_id_creator_session foreign key (id_creator_session) references s_tables.t_users (id) on delete cascade on update cascade, + constraint cf_paths_id_type foreign key (id_type) references s_tables.t_path_types (id) on delete restrict on update cascade, + constraint cf_paths_id_group foreign key (id_group) references s_tables.t_groups (id) on delete restrict on update cascade +); + +create sequence s_tables.se_paths_id owned by s_tables.t_paths.id; +alter table s_tables.t_paths alter column id set default nextval('s_tables.se_paths_id'::regclass); + +grant select,insert,update on s_tables.t_path_types to r_reservation_administer; +grant select on s_tables.t_paths to r_reservation_manager, r_reservation_auditor; +grant select,usage on s_tables.se_paths_id to r_reservation_administer; +grant usage on s_tables.se_paths_id to r_reservation, r_reservation_system; + +create index i_paths_deleted_not on s_tables.t_paths (id) + where is_deleted is not true; + +create index i_paths_private_not on s_tables.t_paths (id) + where is_deleted is not true and is_private is not true; + +create index i_paths_locked_not on s_tables.t_paths (id) + where is_deleted is not true and is_locked is not true; + +create index i_paths_public on s_tables.t_paths (id) + where is_deleted is not true and is_locked is not true and is_private is not true; + + +create view s_users.v_paths with (security_barrier=true) as + with allowed_groups as (select id from s_users.v_groups_self) + select id, id_type, id_group, name_machine, name_human, is_private, date_created, date_changed from s_tables.t_paths + where is_deleted is not true and (is_locked is not true or id_group in (select * from allowed_groups)) and (is_private is not true or (is_private is true and id_group in (select * from allowed_groups))); + +grant select on s_users.v_paths to r_reservation, r_reservation_system; + +create view public.v_paths with (security_barrier=true) as + select id, id_type, NULL::bigint as id_group, name_machine, name_human, NULL::bool as is_private, NULL::bool as date_created, NULL::bool as date_changed from s_tables.t_paths + where is_deleted is not true and is_locked is not true and is_private is not true; + +grant select on public.v_path_types to r_reservation, r_public, r_reservation_system; + + +create trigger tr_paths_date_changed_deleted_or_locked + before update on s_tables.t_paths + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +create trigger tr_paths_enforce_creator_and_session_ids + before insert on s_tables.t_paths + for each row execute procedure s_administers.f_common_enforce_creator_and_session_ids(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-requests.sql b/database/sql/reservation/reservation-requests.sql new file mode 100644 index 0000000..59f4b9d --- /dev/null +++ b/database/sql/reservation/reservation-requests.sql @@ -0,0 +1,861 @@ +/** Standardized SQL Structure - Requests **/ +/** This depends on: base-fields.sql, base-workflow.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** Request: Type ***/ +create table s_tables.t_request_types ( + id bigint not null, + id_external bigint, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + constraint cu_request_types_id unique (id), + constraint cu_request_types_name_machine unique (name_machine), + + constraint cc_request_types_id check (id >= 0) +); + +create sequence s_tables.se_request_types_id owned by s_tables.t_request_types.id; +alter table s_tables.t_request_types alter column id set default nextval('s_tables.se_request_types_id'::regclass); + +grant select,insert,update on s_tables.t_request_types to r_reservation_manager; +grant select on s_tables.t_request_types to r_reservation_auditor; +grant select,usage on s_tables.se_request_types_id to r_reservation_manager; + +create index i_request_types_deleted_not on s_tables.t_request_types (id) + where is_deleted is not true; + +create index i_request_types_public on s_tables.t_request_types (id) + where is_deleted is not true and is_locked is not true; + + +create view s_requesters.v_request_types with (security_barrier=true) as + select id, id_external, name_machine, name_human from s_tables.t_request_types + where is_deleted is not true and is_locked is not true; + +grant select on s_requesters.v_request_types to r_reservation_auditor, r_reservation_requester; + + +create trigger tr_request_types_update_date_changed_deleted_or_locked + before update on s_tables.t_request_types + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** Requests ***/ +create table s_tables.t_requests ( + id bigint not null, + id_revision bigint not null default 0, + id_type bigint not null, + id_association bigint not null, + id_creator bigint not null, + id_creator_session bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_approved boolean default false not null, + is_denied boolean default false not null, + is_troubled boolean default false not null, + is_cancelled boolean default false not null, + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_synced timestamp default localtimestamp not null, + date_approved timestamp, + date_denied timestamp, + date_troubled timestamp, + date_cancelled timestamp, + date_locked timestamp, + date_deleted timestamp, + + field_additional text not null, + field_dates public.ct_date_context[] not null, + field_fees_custodial public.ct_field_fees[] not null, + field_fees_equipment public.ct_field_fees[] not null, + field_fees_facilities public.ct_field_fees[] not null, + field_fees_grounds public.ct_field_fees[] not null, + field_fees_maintenance public.ct_field_fees[] not null, + field_fees_other public.ct_field_fees[] not null, + field_fees_security public.ct_field_fees[] not null, + field_fees_university public.ct_field_fees[] not null, + field_location public.ct_location[] not null, + field_information_attendance bigint not null, + field_information_organization bigint not null, + field_information_adviser_approval bool not null, + field_insurance_affiliated public.ct_field_insurance not null, + field_insurance_contractor public.ct_field_insurance not null, + field_insurance_unaffiliated public.ct_field_insurance not null, + field_plans_activities text not null, + field_plans_audience bigint not null, + field_plans_description text not null, + field_presentation_designing_material public.ct_field_used_with_contact not null, + field_presentation_external_audio_person public.ct_field_used_with_contact not null, + field_presentation_production public.ct_field_used_with_contact not null, + field_presentation_printed_material public.ct_field_used_with_details not null, + field_presentation_publicity public.ct_field_needed_with_types not null, + field_presentation_technical_equipment public.ct_field_needed_with_types_and_microphone not null, + field_presentation_university_logo public.ct_field_used_with_designer not null, + field_registration_revenue public.ct_field_generated_with_types not null, + field_registration_phone public.ct_phone_number not null, + field_registration_required bool not null, + field_registration_ticket_dates public.ct_date_context[] not null, + field_registration_ticket_phone public.ct_phone_number_context not null, + field_registration_ticket_price public.ct_money_context[] not null, + field_registration_ticket_website text not null, + field_registration_website text not null, + field_setup_other_tables public.ct_field_needed_with_details not null, + field_setup_parking_assistance public.ct_field_needed_with_details not null, + field_setup_podium public.ct_field_needed_with_details not null, + field_setup_portable_stage public.ct_field_needed_with_details not null, + field_setup_rectangular_tables_8ft public.ct_field_needed_with_total not null, + field_setup_road_closures public.ct_field_needed_with_details not null, + field_setup_round_tables_8ft public.ct_field_needed_with_total not null, + field_setup_security public.ct_field_needed_with_details not null, + field_setup_special_requests public.ct_field_needed_with_details not null, + field_setup_standard_blue_chairs public.ct_field_needed_with_total not null, + field_services_alcohol_served public.ct_field_served_with_caterer not null, + field_services_food public.ct_field_served_with_caterer not null, + field_services_open_flames public.ct_field_used_with_details not null, + field_title text not null, + + in_state bigint not null, + in_step bigint not null, + + constraint cp_requests primary key (id), + constraint cu_requests_name_machine unique (name_machine), + + constraint cc_requests_id check (id > 0), + constraint cc_requests_id_revision check (id_revision > -1), + constraint cc_requests_approved check ((is_approved is true and is_denied is not true) or (is_approved is not true and is_denied is true)), + + constraint cf_requests_id_creator foreign key (id_creator) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_requests_id_creator_session foreign key (id_creator_session) references s_tables.t_users (id) on delete restrict on update cascade, + constraint cf_requests_request_type foreign key (id_type) references s_tables.t_request_types (id) on delete restrict on update cascade, + constraint cf_requests_association foreign key (id_association) references s_tables.t_associations (id) on delete restrict on update cascade +); + +create sequence s_tables.se_requests_id owned by s_tables.t_requests.id; +alter table s_tables.t_requests alter column id set default nextval('s_tables.se_requests_id'::regclass); + +grant select,insert,update on s_tables.t_requests to r_reservation_manager; +grant select on s_tables.t_requests to r_reservation_auditor; +grant select,usage on s_tables.se_requests_id to r_reservation_manager; +grant usage on s_tables.se_requests_id to r_reservation, r_reservation_system; + +create index i_requests_deleted_not on s_tables.t_requests (id) + where is_deleted is not true; + +create index i_requests_locked_not on s_tables.t_requests (id) + where is_deleted is not true and is_locked is not true; + +create index i_requests_approved on s_tables.t_requests (id) + where is_deleted is not true and is_cancelled is not true and is_approved is true; + +create index i_requests_approved_cancelled on s_tables.t_requests (id) + where is_deleted is not true and is_cancelled is true and is_approved is true; + +create index i_requests_denied on s_tables.t_requests (id) + where is_deleted is not true and is_cancelled is not true and is_denied is true; + +create index i_requests_troubled on s_tables.t_requests (id) + where is_deleted is not true and is_cancelled is not true and is_troubled is true; + +create index i_requests_cancelled on s_tables.t_requests (id) + where is_deleted is not true and is_cancelled is true; + +create index i_requests_locked on s_tables.t_requests (id) + where is_deleted is not true and is_locked is true; + + +/*** approved requests (but not cancelled) ***/ +create view s_users.v_requests_approved with (security_barrier=true) as + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_troubled, + date_created, date_changed, date_synced, date_approved, date_troubled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and is_cancelled is not true and is_approved is true; + +grant select on s_users.v_requests_approved to r_reservation, r_reservation_system; + + +/*** approved requests (only cancelled) ***/ +create view s_users.v_requests_approved_cancelled with (security_barrier=true) as + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_troubled, + date_created, date_changed, date_synced, date_approved, date_troubled, date_cancelled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and is_cancelled is true and is_approved is true; + +grant select on s_users.v_requests_approved_cancelled to r_reservation, r_reservation_system; + + +/*** denied requests (but not cancelled) ***/ +create view s_users.v_requests_denied with (security_barrier=true) as + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_troubled, + date_created, date_changed, date_synced, date_denied, date_troubled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and is_cancelled is not true and is_denied is true; + +grant select on s_users.v_requests_denied to r_reservation, r_reservation_system; + + +/*** troubled requests (but not cancelled) ***/ +create view s_users.v_requests_troubled with (security_barrier=true) as + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, + date_created, date_changed, date_synced, date_approved, date_denied, date_troubled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and is_cancelled is not true and is_troubled is true; + +grant select on s_users.v_requests_troubled to r_reservation, r_reservation_system; + + +/*** cancelled requests ***/ +create view s_users.v_requests_cancelled with (security_barrier=true) as + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, + date_created, date_changed, date_synced, date_approved, date_denied, date_troubled, date_cancelled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and is_cancelled is true; + +grant select on s_users.v_requests_cancelled to r_reservation, r_reservation_system; + + +/*** requests the current user belongs to or can manage. ***/ +create view s_users.v_requests_self with (security_barrier=true) as + with associations as (select id from s_users.v_associations_self) + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, is_cancelled, + date_created, date_changed, date_synced, date_approved, date_denied, date_troubled, date_cancelled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and id_association in (select id from associations); + +grant select on s_users.v_requests_self to r_reservation, r_reservation_system; + + +/*** requests the current user belongs to or can manage. ***/ +create view s_users.v_requests_manage with (security_barrier=true) as + with associations as (select id from s_users.v_associations_manage) + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, is_cancelled, + date_created, date_changed, date_synced, date_approved, date_denied, date_troubled, date_cancelled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and id_association in (select id from associations); + +grant select on s_users.v_requests_self to r_reservation, r_reservation_system; + + +/*** requests the current user belongs to or can coordinate. ***/ +create view s_users.v_requests_coordinate with (security_barrier=true) as + with associations as (select id from s_users.v_associations_coordinate) + select id, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, is_cancelled, + date_created, date_changed, date_synced, date_approved, date_denied, date_troubled, date_cancelled, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + from s_tables.t_requests + where is_deleted is not true and id_association in (select id from associations); + +grant select on s_users.v_requests_self to r_reservation, r_reservation_system; + + +create trigger tr_requests_update_date_changed_deleted_or_locked + before update on s_tables.t_requests + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + +create trigger tr_requests_enforce_creator_and_session_ids + before insert on s_tables.t_requests + for each row execute procedure s_administers.f_common_enforce_creator_and_session_ids(); + + + +/*** Request Original Version (store the first/initial revision) ***/ +create table s_tables.t_request_revisions_original ( + id_request bigint not null, + id_type bigint, + id_association bigint, + + name_machine varchar(128), + name_human varchar(256), + + is_approved boolean, + is_denied boolean, + is_troubled boolean, + is_cancelled boolean, + is_locked boolean, + is_deleted boolean, + + field_additional text, + field_dates public.ct_date_context[], + field_fees_custodial public.ct_field_fees[], + field_fees_equipment public.ct_field_fees[], + field_fees_facilities public.ct_field_fees[], + field_fees_grounds public.ct_field_fees[], + field_fees_maintenance public.ct_field_fees[], + field_fees_other public.ct_field_fees[], + field_fees_security public.ct_field_fees[], + field_fees_university public.ct_field_fees[], + field_location public.ct_location[], + field_information_attendance bigint, + field_information_organization bigint, + field_information_adviser_approval bool, + field_insurance_affiliated public.ct_field_insurance, + field_insurance_contractor public.ct_field_insurance, + field_insurance_unaffiliated public.ct_field_insurance, + field_plans_activities text, + field_plans_audience bigint, + field_plans_description text, + field_presentation_designing_material public.ct_field_used_with_contact, + field_presentation_external_audio_person public.ct_field_used_with_contact, + field_presentation_production public.ct_field_used_with_contact, + field_presentation_printed_material public.ct_field_used_with_details, + field_presentation_publicity public.ct_field_needed_with_types, + field_presentation_technical_equipment public.ct_field_needed_with_types_and_microphone, + field_presentation_university_logo public.ct_field_used_with_designer, + field_registration_revenue public.ct_field_generated_with_types, + field_registration_phone public.ct_phone_number, + field_registration_required bool, + field_registration_ticket_dates public.ct_date_context[], + field_registration_ticket_phone public.ct_phone_number_context, + field_registration_ticket_price public.ct_money_context[], + field_registration_ticket_website text, + field_registration_website text, + field_setup_other_tables public.ct_field_needed_with_details, + field_setup_parking_assistance public.ct_field_needed_with_details, + field_setup_podium public.ct_field_needed_with_details, + field_setup_portable_stage public.ct_field_needed_with_details, + field_setup_rectangular_tables_8ft public.ct_field_needed_with_total, + field_setup_road_closures public.ct_field_needed_with_details, + field_setup_round_tables_8ft public.ct_field_needed_with_total, + field_setup_security public.ct_field_needed_with_details, + field_setup_special_requests public.ct_field_needed_with_details, + field_setup_standard_blue_chairs public.ct_field_needed_with_total, + field_services_alcohol_served public.ct_field_served_with_caterer, + field_services_food public.ct_field_served_with_caterer, + field_services_open_flames public.ct_field_used_with_details, + field_title text, + + in_state bigint, + in_step bigint, + + constraint cp_request_revisions_original primary key (id_request), + + constraint cc_request_revisions_original_approved check ((is_approved is true and is_denied is not true) or (is_approved is not true and is_denied is true)), + + constraint cf_request_revisions_original_id_request foreign key (id_request) references s_tables.t_requests (id) on delete restrict on update cascade, + constraint cf_request_revisions_original_request_type foreign key (id_type) references s_tables.t_request_types (id) on delete restrict on update cascade, + constraint cf_request_revisions_original_association foreign key (id_association) references s_tables.t_associations (id) on delete restrict on update cascade +); + +grant select,insert on s_tables.t_request_revisions_original to r_reservation_administer, r_reservation_revision_requests; +grant select on s_tables.t_request_revisions_original to r_reservation_manager, r_reservation_auditor; + + +/** automatically insert the original request into the original requests table. **/ +create function s_tables.f_request_revisions_original_record_revision() returns trigger security definer as $$ + begin + insert into s_tables.t_request_revisions + ( + id_request, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, is_cancelled, is_locked, is_deleted, + date_created, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + ) + values + ( + new.id, new.id_type, new.id_association, + new.name_machine, new.name_human, + new.is_approved, new.is_denied, new.is_troubled, new.is_cancelled, new.is_locked, new.is_deleted, + new.date_created, + new.field_additional, new.field_dates, new.field_fees_custodial, new.field_fees_equipment, new.field_fees_facilities, new.field_fees_grounds, new.field_fees_maintenance, new.field_fees_other, new.field_fees_security, new.field_fees_university, new.field_location, new.field_information_attendance, new.field_information_organization, new.field_information_adviser_approval, new.field_insurance_affiliated, new.field_insurance_contractor, new.field_insurance_unaffiliated, new.field_plans_activities, new.field_plans_audience, new.field_plans_description, new.field_presentation_designing_material, new.field_presentation_external_audio_person, new.field_presentation_production, new.field_presentation_printed_material, new.field_presentation_publicity, new.field_presentation_technical_equipment, new.field_presentation_university_logo, new.field_registration_revenue, new.field_registration_phone, new.field_registration_required, new.field_registration_ticket_dates, new.field_registration_ticket_phone, new.field_registration_ticket_price, new.field_registration_ticket_website, new.field_registration_website, new.field_setup_other_tables, new.field_setup_parking_assistance, new.field_setup_podium, new.field_setup_portable_stage, new.field_setup_rectangular_tables_8ft, new.field_setup_road_closures, new.field_setup_round_tables_8ft, new.field_setup_security, new.field_setup_special_requests, new.field_setup_standard_blue_chairs, new.field_services_alcohol_served, new.field_services_food, new.field_services_open_flames, new.field_title, + new.in_state, new.in_step + ); + end; +$$ language plpgsql; + +alter function s_tables.f_request_revisions_original_record_revision () owner to r_reservation_revision_requests; + +create trigger tr_requests_save_original_revision + after insert on s_tables.t_requests + for each row execute procedure s_tables.f_request_revisions_original_record_revision(); + + +/*** Request Revisions ***/ +create table s_tables.t_request_revisions ( + id_request bigint not null, + id_revision bigint not null, + id_type bigint, + id_association bigint, + + name_machine varchar(128), + name_human varchar(256), + + is_approved boolean, + is_denied boolean, + is_troubled boolean, + is_cancelled boolean, + is_locked boolean, + is_deleted boolean, + + date_changed timestamp default localtimestamp not null, + + field_additional text, + field_dates public.ct_date_context[], + field_fees_custodial public.ct_field_fees[], + field_fees_equipment public.ct_field_fees[], + field_fees_facilities public.ct_field_fees[], + field_fees_grounds public.ct_field_fees[], + field_fees_maintenance public.ct_field_fees[], + field_fees_other public.ct_field_fees[], + field_fees_security public.ct_field_fees[], + field_fees_university public.ct_field_fees[], + field_location public.ct_location[], + field_information_attendance bigint, + field_information_organization bigint, + field_information_adviser_approval bool, + field_insurance_affiliated public.ct_field_insurance, + field_insurance_contractor public.ct_field_insurance, + field_insurance_unaffiliated public.ct_field_insurance, + field_plans_activities text, + field_plans_audience bigint, + field_plans_description text, + field_presentation_designing_material public.ct_field_used_with_contact, + field_presentation_external_audio_person public.ct_field_used_with_contact, + field_presentation_production public.ct_field_used_with_contact, + field_presentation_printed_material public.ct_field_used_with_details, + field_presentation_publicity public.ct_field_needed_with_types, + field_presentation_technical_equipment public.ct_field_needed_with_types_and_microphone, + field_presentation_university_logo public.ct_field_used_with_designer, + field_registration_revenue public.ct_field_generated_with_types, + field_registration_phone public.ct_phone_number, + field_registration_required bool, + field_registration_ticket_dates public.ct_date_context[], + field_registration_ticket_phone public.ct_phone_number_context, + field_registration_ticket_price public.ct_money_context[], + field_registration_ticket_website text, + field_registration_website text, + field_setup_other_tables public.ct_field_needed_with_details, + field_setup_parking_assistance public.ct_field_needed_with_details, + field_setup_podium public.ct_field_needed_with_details, + field_setup_portable_stage public.ct_field_needed_with_details, + field_setup_rectangular_tables_8ft public.ct_field_needed_with_total, + field_setup_road_closures public.ct_field_needed_with_details, + field_setup_round_tables_8ft public.ct_field_needed_with_total, + field_setup_security public.ct_field_needed_with_details, + field_setup_special_requests public.ct_field_needed_with_details, + field_setup_standard_blue_chairs public.ct_field_needed_with_total, + field_services_alcohol_served public.ct_field_served_with_caterer, + field_services_food public.ct_field_served_with_caterer, + field_services_open_flames public.ct_field_used_with_details, + field_title text, + + in_state bigint, + in_step bigint, + + constraint cp_request_revisions primary key (id_request, id_revision), + + constraint cc_request_revisions_id_request check (id_request > 0), + constraint cc_request_revisions_approved check ((is_approved is true and is_denied is not true) or (is_approved is not true and is_denied is true)), + + constraint cf_request_revisions_id_request foreign key (id_request) references s_tables.t_requests (id) on delete restrict on update cascade, + constraint cf_request_revisions_request_type foreign key (id_type) references s_tables.t_request_types (id) on delete restrict on update cascade, + constraint cf_request_revisions_association foreign key (id_association) references s_tables.t_associations (id) on delete restrict on update cascade +); + +grant select,insert on s_tables.t_request_revisions to r_reservation_administer, r_reservation_revision_requests; +grant select on s_tables.t_request_revisions to r_reservation_manager, r_reservation_auditor; + + +/** automatically update the request revision table. **/ +create function s_tables.f_request_revisions_record_revision() returns trigger security definer as $$ + declare + tmp_id_type bigint; + tmp_id_association bigint; + + tmp_name_machine varchar(128); + tmp_name_human varchar(256); + + tmp_is_approved boolean; + tmp_is_denied boolean; + tmp_is_troubled boolean; + tmp_is_cancelled boolean; + tmp_is_locked boolean; + tmp_is_deleted boolean; + + tmp_field_additional text; + tmp_field_dates public.ct_date_context[]; + tmp_field_fees_custodial public.ct_field_fees[]; + tmp_field_fees_equipment public.ct_field_fees[]; + tmp_field_fees_facilities public.ct_field_fees[]; + tmp_field_fees_grounds public.ct_field_fees[]; + tmp_field_fees_maintenance public.ct_field_fees[]; + tmp_field_fees_other public.ct_field_fees[]; + tmp_field_fees_security public.ct_field_fees[]; + tmp_field_fees_university public.ct_field_fees[]; + tmp_field_location public.ct_location[]; + tmp_field_information_attendance bigint; + tmp_field_information_organization bigint; + tmp_field_information_adviser_approval bool; + tmp_field_insurance_affiliated public.ct_field_insurance; + tmp_field_insurance_contractor public.ct_field_insurance; + tmp_field_insurance_unaffiliated public.ct_field_insurance; + tmp_field_plans_activities text; + tmp_field_plans_audience bigint; + tmp_field_plans_description text; + tmp_field_presentation_designing_material public.ct_field_used_with_contact; + tmp_field_presentation_external_audio_person public.ct_field_used_with_contact; + tmp_field_presentation_production public.ct_field_used_with_contact; + tmp_field_presentation_printed_material public.ct_field_used_with_details; + tmp_field_presentation_publicity public.ct_field_needed_with_types; + tmp_field_presentation_technical_equipment public.ct_field_needed_with_types_and_microphone; + tmp_field_presentation_university_logo public.ct_field_used_with_designer; + tmp_field_registration_revenue public.ct_field_generated_with_types; + tmp_field_registration_phone public.ct_phone_number; + tmp_field_registration_required bool; + tmp_field_registration_ticket_dates public.ct_date_context[]; + tmp_field_registration_ticket_phone public.ct_phone_number_context; + tmp_field_registration_ticket_price public.ct_money_context[]; + tmp_field_registration_ticket_website text; + tmp_field_registration_website text; + tmp_field_setup_other_tables public.ct_field_needed_with_details; + tmp_field_setup_parking_assistance public.ct_field_needed_with_details; + tmp_field_setup_podium public.ct_field_needed_with_details; + tmp_field_setup_portable_stage public.ct_field_needed_with_details; + tmp_field_setup_rectangular_tables_8ft public.ct_field_needed_with_total; + tmp_field_setup_road_closures public.ct_field_needed_with_details; + tmp_field_setup_round_tables_8ft public.ct_field_needed_with_total; + tmp_field_setup_security public.ct_field_needed_with_details; + tmp_field_setup_special_requests public.ct_field_needed_with_details; + tmp_field_setup_standard_blue_chairs public.ct_field_needed_with_total; + tmp_field_services_alcohol_served public.ct_field_served_with_caterer; + tmp_field_services_food public.ct_field_served_with_caterer; + tmp_field_services_open_flames public.ct_field_used_with_details; + tmp_field_title text; + + tmp_in_state bigint; + tmp_in_step bigint; + + begin + if (old.id_type != new.id_type) then + tmp_id_type = new.id_type; + end if; + + if (old.id_association != new.id_association) then + tmp_id_association = new.id_association; + end if; + + if (old.name_machine != new.name_machine) then + tmp_name_machine = new.name_machine; + end if; + + if (old.name_human != new.name_human) then + tmp_name_human = new.name_human; + end if; + + if (old.is_approved != new.is_approved) then + tmp_is_approved = new.is_approved; + end if; + + if (old.is_denied != new.is_denied) then + tmp_is_denied = new.is_denied; + end if; + + if (old.is_troubled != new.is_troubled) then + tmp_is_troubled = new.is_troubled; + end if; + + if (old.is_cancelled != new.is_cancelled) then + tmp_is_cancelled = new.is_cancelled; + end if; + + if (old.is_locked != new.is_locked) then + tmp_is_locked = new.is_locked; + end if; + + if (old.is_deleted != new.is_deleted) then + tmp_is_deleted = new.is_deleted; + end if; + + if (old.field_additional != new.field_additional) then + tmp_field_additional = new.field_additional; + end if; + + if (old.field_dates != new.field_dates) then + tmp_field_dates = new.field_dates; + end if; + + if (old.field_fees_custodial != new.field_fees_custodial) then + tmp_field_fees_custodial = new.field_fees_custodial; + end if; + + if (old.field_fees_equipment != new.field_fees_equipment) then + tmp_field_fees_equipment = new.field_fees_equipment; + end if; + + if (old.field_fees_facilities != new.field_fees_facilities) then + tmp_field_fees_facilities = new.field_fees_facilities; + end if; + + if (old.field_fees_grounds != new.field_fees_grounds) then + tmp_field_fees_grounds = new.field_fees_grounds; + end if; + + if (old.field_fees_maintenance != new.field_fees_maintenance) then + tmp_field_fees_maintenance = new.field_fees_maintenance; + end if; + + if (old.field_fees_other != new.field_fees_other) then + tmp_field_fees_other = new.field_fees_other; + end if; + + if (old.field_fees_security != new.field_fees_security) then + tmp_field_fees_security = new.field_fees_security; + end if; + + if (old.field_fees_university != new.field_fees_university) then + tmp_field_fees_university = new.field_fees_university; + end if; + + if (old.field_location != new.field_location) then + tmp_field_location = new.field_location; + end if; + + if (old.field_information_attendance != new.field_information_attendance) then + tmp_field_information_attendance = new.field_information_attendance; + end if; + + if (old.field_information_organization != new.field_information_organization) then + tmp_field_information_organization = new.field_information_organization; + end if; + + if (old.field_information_adviser_approval != new.field_information_adviser_approval) then + tmp_field_information_adviser_approval = new.field_information_adviser_approval; + end if; + + if (old.field_insurance_affiliated != new.field_insurance_affiliated) then + tmp_field_insurance_affiliated = new.field_insurance_affiliated; + end if; + + if (old.field_insurance_contractor != new.field_insurance_contractor) then + tmp_field_insurance_contractor = new.field_insurance_contractor; + end if; + + if (old.field_insurance_unaffiliated != new.field_insurance_unaffiliated) then + tmp_field_insurance_unaffiliated = new.field_insurance_unaffiliated; + end if; + + if (old.field_plans_activities != new.field_plans_activities) then + tmp_field_plans_activities = new.field_plans_activities; + end if; + + if (old.field_plans_audience != new.field_plans_audience) then + tmp_field_plans_audience = new.field_plans_audience; + end if; + + if (old.field_plans_description != new.field_plans_description) then + tmp_field_plans_description = new.field_plans_description; + end if; + + if (old.field_presentation_designing_material != new.field_presentation_designing_material) then + tmp_field_presentation_designing_material = new.field_presentation_designing_material; + end if; + + if (old.field_presentation_external_audio_person != new.field_presentation_external_audio_person) then + tmp_field_presentation_external_audio_person = new.field_presentation_external_audio_person; + end if; + + if (old.field_presentation_production != new.field_presentation_production) then + tmp_field_presentation_production = new.field_presentation_production; + end if; + + if (old.field_presentation_printed_material != new.field_presentation_printed_material) then + tmp_field_presentation_printed_material = new.field_presentation_printed_material; + end if; + + if (old.field_presentation_publicity != new.field_presentation_publicity) then + tmp_field_presentation_publicity = new.field_presentation_publicity; + end if; + + if (old.field_presentation_technical_equipment != new.field_presentation_technical_equipment) then + tmp_field_presentation_technical_equipment = new.field_presentation_technical_equipment; + end if; + + if (old.field_presentation_university_logo != new.field_presentation_university_logo) then + tmp_field_presentation_university_logo = new.field_presentation_university_logo; + end if; + + if (old.field_registration_revenue != new.field_registration_revenue) then + tmp_field_registration_revenue = new.field_registration_revenue; + end if; + + if (old.field_registration_phone != new.field_registration_phone) then + tmp_field_registration_phone = new.field_registration_phone; + end if; + + if (old.field_registration_required != new.field_registration_required) then + tmp_field_registration_required = new.field_registration_required; + end if; + + if (old.field_registration_required != new.field_registration_required) then + tmp_field_registration_required = new.field_registration_required; + end if; + + if (old.field_registration_ticket_dates != new.field_registration_ticket_dates) then + tmp_field_registration_ticket_dates = new.field_registration_ticket_dates; + end if; + + if (old.field_registration_ticket_phone != new.field_registration_ticket_phone) then + tmp_field_registration_ticket_phone = new.field_registration_ticket_phone; + end if; + + if (old.field_registration_ticket_price != new.field_registration_ticket_price) then + tmp_field_registration_ticket_price = new.field_registration_ticket_price; + end if; + + if (old.field_registration_ticket_website != new.field_registration_ticket_website) then + tmp_field_registration_ticket_website = new.field_registration_ticket_website; + end if; + + if (old.field_registration_website != new.field_registration_website) then + tmp_field_registration_website = new.field_registration_website; + end if; + + if (old.field_setup_other_tables != new.field_setup_other_tables) then + tmp_field_setup_other_tables = new.field_setup_other_tables; + end if; + + if (old.field_setup_parking_assistance != new.field_setup_parking_assistance) then + tmp_field_setup_parking_assistance = new.field_setup_parking_assistance; + end if; + + if (old.field_setup_podium != new.field_setup_podium) then + tmp_field_setup_podium = new.field_setup_podium; + end if; + + if (old.field_setup_portable_stage != new.field_setup_portable_stage) then + tmp_field_setup_portable_stage = new.field_setup_portable_stage; + end if; + + if (old.field_setup_rectangular_tables_8ft != new.field_setup_rectangular_tables_8ft) then + tmp_field_setup_rectangular_tables_8ft = new.field_setup_rectangular_tables_8ft; + end if; + + if (old.field_setup_road_closures != new.field_setup_road_closures) then + tmp_field_setup_road_closures = new.field_setup_road_closures; + end if; + + if (old.field_setup_round_tables_8ft != new.field_setup_round_tables_8ft) then + tmp_field_setup_round_tables_8ft = new.field_setup_round_tables_8ft; + end if; + + if (old.field_setup_security != new.field_setup_security) then + tmp_field_setup_security = new.field_setup_security; + end if; + + if (old.field_setup_special_requests != new.field_setup_special_requests) then + tmp_field_setup_special_requests = new.field_setup_special_requests; + end if; + + if (old.field_setup_standard_blue_chairs != new.field_setup_standard_blue_chairs) then + tmp_field_setup_standard_blue_chairs = new.field_setup_standard_blue_chairs; + end if; + + if (old.field_services_alcohol_served != new.field_services_alcohol_served) then + tmp_field_services_alcohol_served = new.field_services_alcohol_served; + end if; + + if (old.field_services_food != new.field_services_food) then + tmp_field_services_food = new.field_services_food; + end if; + + if (old.field_services_open_flames != new.field_services_open_flames) then + tmp_field_services_open_flames = new.field_services_open_flames; + end if; + + if (old.field_title != new.field_title) then + tmp_field_title = new.field_title; + end if; + + if (old.in_state != new.in_state) then + tmp_in_state = new.in_state; + end if; + + if (old.in_step != new.in_step) then + tmp_in_step = new.in_step; + end if; + + insert into s_tables.t_request_revisions + ( + id_request, id_revision, id_type, id_association, + name_machine, name_human, + is_approved, is_denied, is_troubled, is_cancelled, is_locked, is_deleted, + date_changed, + field_additional, field_dates, field_fees_custodial, field_fees_equipment, field_fees_facilities, field_fees_grounds, field_fees_maintenance, field_fees_other, field_fees_security, field_fees_university, field_location, field_information_attendance, field_information_organization, field_information_adviser_approval, field_insurance_affiliated, field_insurance_contractor, field_insurance_unaffiliated, field_plans_activities, field_plans_audience, field_plans_description, field_presentation_designing_material, field_presentation_external_audio_person, field_presentation_production, field_presentation_printed_material, field_presentation_publicity, field_presentation_technical_equipment, field_presentation_university_logo, field_registration_revenue, field_registration_phone, field_registration_required, field_registration_ticket_dates, field_registration_ticket_phone, field_registration_ticket_price, field_registration_ticket_website, field_registration_website, field_setup_other_tables, field_setup_parking_assistance, field_setup_podium, field_setup_portable_stage, field_setup_rectangular_tables_8ft, field_setup_road_closures, field_setup_round_tables_8ft, field_setup_security, field_setup_special_requests, field_setup_standard_blue_chairs, field_services_alcohol_served, field_services_food, field_services_open_flames, field_title, + in_state, in_step + ) + values + ( + old.id, new.id_revision, tmp_id_type, tmp_id_association, + tmp_name_machine, tmp_name_human, + tmp_is_approved, tmp_is_denied, tmp_is_troubled, tmp_is_cancelled, tmp_is_locked, tmp_is_deleted, + new.date_changed, + tmp_field_additional, tmp_field_dates, tmp_field_fees_custodial, tmp_field_fees_equipment, tmp_field_fees_facilities, tmp_field_fees_grounds, tmp_field_fees_maintenance, tmp_field_fees_other, tmp_field_fees_security, tmp_field_fees_university, tmp_field_location, tmp_field_information_attendance, tmp_field_information_organization, tmp_field_information_adviser_approval, tmp_field_insurance_affiliated, tmp_field_insurance_contractor, tmp_field_insurance_unaffiliated, tmp_field_plans_activities, tmp_field_plans_audience, tmp_field_plans_description, tmp_field_presentation_designing_material, tmp_field_presentation_external_audio_person, tmp_field_presentation_production, tmp_field_presentation_printed_material, tmp_field_presentation_publicity, tmp_field_presentation_technical_equipment, tmp_field_presentation_university_logo, tmp_field_registration_revenue, tmp_field_registration_phone, tmp_field_registration_required, tmp_field_registration_ticket_dates, tmp_field_registration_ticket_phone, tmp_field_registration_ticket_price, tmp_field_registration_ticket_website, tmp_field_registration_website, tmp_field_setup_other_tables, tmp_field_setup_parking_assistance, tmp_field_setup_podium, tmp_field_setup_portable_stage, tmp_field_setup_rectangular_tables_8ft, tmp_field_setup_road_closures, tmp_field_setup_round_tables_8ft, tmp_field_setup_security, tmp_field_setup_special_requests, tmp_field_setup_standard_blue_chairs, tmp_field_services_alcohol_served, tmp_field_services_food, tmp_field_services_open_flames, tmp_field_title, + tmp_in_state, tmp_in_step + ); + end; +$$ language plpgsql; + +alter function s_tables.f_request_revisions_record_revision () owner to r_reservation_revision_requests; + +create trigger tr_requests_save_revision + after insert on s_tables.t_request_revisions + for each row execute procedure s_tables.f_request_revisions_record_revision(); + + +commit transaction; diff --git a/database/sql/reservation/reservation-statistics.sql b/database/sql/reservation/reservation-statistics.sql new file mode 100644 index 0000000..f9a8451 --- /dev/null +++ b/database/sql/reservation/reservation-statistics.sql @@ -0,0 +1,131 @@ +/** Standardized SQL Structure - Statistics **/ +/** This depends on: base-log_users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/** Provide status code statistics **/ +create table s_tables.t_statistics_http_status_codes ( + code smallint not null, + count bigint not null default 0, + + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_deleted timestamp, + + constraint cp_statistics_http_status_codes primary key (code), + + constraint cc_statistics_http_status_codes_count check (count >= 0), + + constraint cf_statistics_http_status_codes_code foreign key (code) references s_tables.t_log_http_status_codes (id) on delete restrict on update cascade +); + +grant select,insert,update on s_tables.t_statistics_http_status_codes to r_reservation_manager, r_reservation_statistics_update; +grant select on s_tables.t_statistics_http_status_codes to r_reservation_auditor; + + +/** create an auto-update trigger. set the role to r_reservation_manager so that the function runs as that role when using "SECURITY DEFINER". The r_reservation_manager must also have the appropriate create privileges. **/ +create function s_tables.f_statistics_http_status_codes_insert() returns trigger security definer as $$ + begin + if (tg_op = 'INSERT') then + update s_tables.t_statistics_http_status_codes set count = (select count + 1 as count from s_tables.t_statistics_http_status_codes where code = new.response_code) where code = new.response_code; + if not found then + insert into s_tables.t_statistics_http_status_codes (code, count) values (new.response_code, 1); + if not found then return null; end if; + end if; + + return new; + end if; + + return null; + end; +$$ language plpgsql; + +alter function s_tables.f_statistics_http_status_codes_insert () owner to r_reservation_statistics_update; + +create trigger tr_log_user_activity_insert_statistics_http_status_codes + after insert on s_tables.t_log_user_activity + for each row execute procedure s_tables.f_statistics_http_status_codes_insert(); + +create trigger tr_log_users_insert_statistics_http_status_codes + after insert on s_tables.t_log_users + for each row execute procedure s_tables.f_statistics_http_status_codes_insert(); + +create trigger tr_statistics_http_status_codes_date_deleted + before update on s_tables.t_statistics_http_status_codes + for each row execute procedure s_administers.f_common_update_date_deleted(); + + + +/** Provide request path statistics **/ +create table s_tables.t_statistics_request_path ( + path varchar(512) not null, + count bigint not null default 0, + + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_deleted timestamp, + + constraint cp_statistics_request_path primary key (path), + + constraint cc_statistics_request_path_count check (count >= 0) +); + +grant select on s_tables.t_statistics_request_path to r_reservation_manager, r_reservation_auditor; + + +/** permissions prevent this from working as desired, so for now open up these stats to the following users (via a view) **/ +/* @todo: review this and try to restrict what accounts can access and set request_path in the same way s_tables.f_statistics_http_status_codes_insert() is handled. */ +create view s_users.v_statistics_request_path with (security_barrier=true) as + select path, count from s_tables.t_statistics_request_path + with check option; + +grant select,insert,update on s_users.v_statistics_request_path to r_reservation, r_reservation_system; + + +create view public.v_statistics_request_path with (security_barrier=true) as + select path, count from s_tables.t_statistics_request_path + with check option; + +grant select,insert,update on public.v_statistics_request_path to r_public; + + +/** create an auto-update trigger **/ +create function s_tables.f_statistics_request_path_insert() returns trigger as $$ + begin + if (tg_op = 'INSERT') then + update v_statistics_request_path set count = (select count + 1 as count from v_statistics_request_path where path = new.request_path) where path = new.request_path; + if not found then + insert into v_statistics_request_path (path, count) values (new.request_path, 1); + if not found then return null; end if; + end if; + + return new; + end if; + + return null; + end; +$$ language plpgsql; + +create trigger tr_statistics_request_path_insert + after insert on s_tables.t_statistics_request_path + for each row execute procedure s_tables.f_statistics_request_path_insert(); + +create trigger tr_statistics_request_path_date_deleted + before update on s_tables.t_statistics_request_path + for each row execute procedure s_administers.f_common_update_date_deleted(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-types.sql b/database/sql/reservation/reservation-types.sql new file mode 100644 index 0000000..6b2bd71 --- /dev/null +++ b/database/sql/reservation/reservation-types.sql @@ -0,0 +1,109 @@ +/** Standardized SQL Structure - Logs - Types */ +/** This depends on: base-main.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/*** provide mime type category id and names ***/ +create table s_tables.t_types_mime_categorys ( + id bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + field_category varchar(64), + + constraint cp_types_mime_categorys primary key (id), + + constraint cu_types_mime_categorys_name_machine unique (name_machine), + + constraint cc_types_mime_categorys_id check (id > -1) +); + +grant select,insert,update on s_tables.t_types_mime_categorys to r_reservation_administer; + +create view public.v_types_mime_categorys with (security_barrier=true) as + select id, name_machine, name_human, is_locked from s_tables.t_types_mime_categorys + where is_deleted is not true; + +grant select on public.v_types_mime_categorys to r_reservation, r_public, r_reservation_system; + +grant select,insert,update on s_tables.t_types_mime_categorys to r_reservation_administer; + + +create view public.v_types_mime_categorys_locked_not with (security_barrier=true) as + select id, name_machine, name_human, field_category from s_tables.t_types_mime_categorys + where is_deleted is not true and is_locked is not true; + +grant select on public.v_types_mime_categorys_locked_not to r_reservation, r_public, r_reservation_system; + + +create trigger tr_types_mime_categorys_date_changed_deleted_or_locked + before update on s_tables.t_types_mime_categorys + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +/*** provide mime type ids and names ***/ +create table s_tables.t_types_mime_types ( + id bigint not null, + id_category bigint not null, + + name_machine varchar(128) not null, + name_human varchar(256) not null, + + is_locked boolean default false not null, + is_deleted boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + field_extension varchar(64), + field_mime varchar(128), + + constraint cc_types_mime_types_id check (id > -1), + + constraint cu_types_mime_types_mime_type unique (id, id_category, field_extension, field_mime), + + constraint cf_types_mime_types_id foreign key (id_category) references s_tables.t_types_mime_categorys (id) on delete restrict on update cascade +); + +grant select,insert,update on s_tables.t_types_mime_types to r_reservation_administer; + +create view public.v_types_mime_types with (security_barrier=true) as + select id, id_category, name_machine, name_human, field_extension, field_mime, is_locked from s_tables.t_types_mime_types + where is_deleted is not true; + +grant select on public.v_types_mime_types to r_reservation, r_public, r_reservation_system; + +create view public.v_types_mime_types_locked_not with (security_barrier=true) as + select id, id_category, name_machine, name_human, field_extension, field_mime, is_locked from s_tables.t_types_mime_types + where is_deleted is not true and is_locked is not true; + +grant select on public.v_types_mime_types to r_reservation, r_public, r_reservation_system; + + +create trigger tr_types_mime_types_date_changed_deleted_or_locked + before update on s_tables.t_types_mime_types + for each row execute procedure s_administers.f_common_update_date_changed_deleted_or_locked(); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-users.sql b/database/sql/reservation/reservation-users.sql new file mode 100644 index 0000000..2d1264e --- /dev/null +++ b/database/sql/reservation/reservation-users.sql @@ -0,0 +1,323 @@ +/** Standardized SQL Structure - Users */ +/** This depends on: base-main.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + + + +/** Users **/ +create table s_tables.t_users ( + id bigint not null, + id_external bigint, + + id_sort smallint not null default 0, + + name_machine varchar(128) not null, + name_human public.ct_name_person default (null, null, null, null, null, null) not null, + + address_email public.ct_email default (null, null, true) not null, + + is_administer boolean default false not null, + is_manager boolean default false not null, + is_auditor boolean default false not null, + is_publisher boolean default false not null, + is_insurer boolean default false not null, + is_financer boolean default false not null, + is_reviewer boolean default false not null, + is_editor boolean default false not null, + is_drafter boolean default false not null, + is_requester boolean default false not null, + is_system boolean default false not null, + is_public boolean default false not null, + is_locked boolean default false not null, + is_private boolean default true not null, + is_deleted boolean default false not null, + + can_manage_roles boolean default false not null, + + date_created timestamp default localtimestamp not null, + date_changed timestamp default localtimestamp not null, + date_synced timestamp default localtimestamp not null, + date_locked timestamp, + date_deleted timestamp, + + settings json, + + constraint cp_users primary key (id), + + constraint cc_users_id check (id > 0), + constraint cc_users_id_external check (id_external >= -1), + + constraint cu_users_id_external unique (id_external), + constraint cu_users_name_machine unique (name_machine) +); + +create sequence s_tables.se_users_id owned by s_tables.t_users.id; +alter table s_tables.t_users alter column id set default nextval('s_tables.se_users_id'::regclass); + +grant select,insert,update on s_tables.t_users to r_reservation_administer; +grant select on s_tables.t_users to r_reservation_auditor; +grant select,usage on s_tables.se_users_id to r_reservation_administer; +grant usage on s_tables.se_users_id to r_reservation, r_reservation_system; + +create index i_users_deleted_not on s_tables.t_users (id) + where is_deleted is not true; + +create index i_users_private_not on s_tables.t_users (id) + where is_deleted is not true and is_private is not true; + +create index i_users_locked_not on s_tables.t_users (id) + where is_deleted is not true and is_locked is not true; + +create index i_users_private_email_not on s_tables.t_users (id) + where is_deleted is not true and is_private is not true and (address_email).private is not true; + + +/* Note: id_sort is only needed when directly validating against id or name_machine because both of those are already an index. */ +create index i_users_id_sort_a on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 97; +create index i_users_id_sort_b on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 98; +create index i_users_id_sort_c on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 99; +create index i_users_id_sort_d on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 100; +create index i_users_id_sort_e on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 101; +create index i_users_id_sort_f on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 102; +create index i_users_id_sort_g on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 103; +create index i_users_id_sort_h on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 104; +create index i_users_id_sort_i on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 105; +create index i_users_id_sort_j on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 106; +create index i_users_id_sort_k on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 107; +create index i_users_id_sort_l on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 108; +create index i_users_id_sort_m on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 109; +create index i_users_id_sort_n on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 110; +create index i_users_id_sort_o on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 111; +create index i_users_id_sort_p on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 112; +create index i_users_id_sort_q on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 113; +create index i_users_id_sort_r on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 114; +create index i_users_id_sort_s on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 115; +create index i_users_id_sort_t on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 116; +create index i_users_id_sort_u on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 117; +create index i_users_id_sort_v on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 118; +create index i_users_id_sort_w on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 119; +create index i_users_id_sort_x on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 120; +create index i_users_id_sort_y on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 121; +create index i_users_id_sort_z on s_tables.t_users (id_sort) with (fillfactor = 100) where id_sort = 122; + + + +/*** provide current user access to their own information (system users are not allowed to update their account) ***/ +create view s_users.v_users_self with (security_barrier=true) as + select id, id_external, id_sort, name_machine, name_human, address_email, is_administer, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_system, is_public, is_locked, is_private, can_manage_roles, date_created, date_changed, date_synced, date_locked, settings from s_tables.t_users + where is_deleted is not true and (name_machine)::text = (current_user)::text; + +grant select on s_users.v_users_self to r_reservation, r_reservation_system; + +create view s_users.v_users_self_session with (security_barrier=true) as + select id, id_external, id_sort, name_machine, name_human, address_email, is_administer, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_system, is_public, is_locked, is_private, can_manage_roles, date_created, date_changed, date_synced, date_locked, settings from s_tables.t_users + where is_deleted is not true and (name_machine)::text = (session_user)::text; + +grant select on s_users.v_users_self_session to r_reservation, r_reservation_system; + +create view s_users.v_users_locked_not_self with (security_barrier=true) as + select id, id_external, id_sort, name_machine, name_human, address_email, is_administer, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_system, is_public, is_locked, is_private, can_manage_roles, date_created, date_changed, date_synced, date_locked, settings from s_tables.t_users + where is_deleted is not true and is_locked is not true and (name_machine)::text = (current_user)::text; + +grant select on s_users.v_users_locked_not_self to r_reservation, r_reservation_system; + +create view s_users.v_users_can_manage_roles with (security_barrier=true) as + with this_user_can_manage_roles as (select id from s_users.v_users_locked_not_self where can_manage_roles is true) + select id_sort, name_human, address_email from s_tables.t_users + where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true and (name_machine)::text = (current_user)::text and id in (select * from this_user_can_manage_roles); + +grant select on s_users.v_users_can_manage_roles to r_reservation, r_reservation_system; + +create view s_users.v_users_self_insert with (security_barrier=true) as + select id_external, name_human, address_email, is_private, settings from s_tables.t_users + where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true and (name_machine)::text = (current_user)::text + with check option; + +grant insert on s_users.v_users_self_insert to r_reservation, r_reservation_system; + +create view s_users.v_users_self_update with (security_barrier=true) as + select address_email, is_private, settings from s_tables.t_users + where is_deleted is not true and is_locked is not true and is_system is not true and is_public is not true and (name_machine)::text = (current_user)::text + with check option; + +grant update on s_users.v_users_self_update to r_reservation, r_reservation_system; + + +/**** anonymous user has uid = 1 ****/ +create view public.v_users_self with (security_barrier=true) as + select id, id_external, id_sort, name_machine, name_human, address_email, is_administer, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_system, is_public, is_locked, is_private, date_created, date_changed, date_synced, date_locked, settings from s_tables.t_users + where is_deleted is not true and id = 1; + +grant select on public.v_users_self to r_public, r_reservation, r_reservation_system; + + +/*** provide public user information ***/ +create view public.v_users with (security_barrier=true) as + select id, null::bigint as id_external, id_sort, name_machine, name_human, null::public.ct_email as address_email, null::bool as is_administer, null::bool as is_manager, null::bool as is_auditor, null::bool as is_publisher, null::bool as is_insurer, null::bool as is_financer, null::bool as is_reviewer, null::bool as is_editor, null::bool as is_drafter, null::bool as is_requester, is_system, is_public, null::bool as is_locked, null::bool as is_private, null::bool as can_manage_roles, null::timestamp as date_created, null::timestamp as date_changed, null::timestamp as date_synced, null::timestamp as date_locked, null::json as settings from s_tables.t_users + where (is_deleted is not true and is_private is not true) or (is_deleted is not true and (name_machine)::text = (current_user)::text); + +grant select on public.v_users to r_reservation, r_public, r_reservation_system; + + +/*** provide e-mail address as public information only if it is explicitly allowed ***/ +create view public.v_users_email with (security_barrier=true) as + select id, null::bigint as id_external, id_sort, name_machine, name_human, address_email, null::bool as is_administer, null::bool as is_manager, null::bool as is_auditor, null::bool as is_publisher, null::bool as is_insurer, null::bool as is_financer, null::bool as is_reviewer, null::bool as is_editor, null::bool as is_drafter, null::bool as is_requester, is_system, is_public, null::bool as is_locked, null::bool as is_private, null::bool as can_manage_roles, null::timestamp as date_created, null::timestamp as date_changed, null::timestamp as date_synced, null::timestamp as date_locked, null::json as settings from s_tables.t_users + where (is_deleted is not true and is_private is not true and (address_email).private is not true) or (is_deleted is not true and (name_machine)::text = (current_user)::text); + +grant select on public.v_users_email to r_reservation, r_public, r_reservation_system; + + +/*** provide managers with the ability to modify accounts ***/ +create view s_managers.v_users with (security_barrier=true) as + select * from s_tables.t_users + where is_deleted is not true; + +grant select on s_managers.v_users to r_reservation_manager; + +create view s_managers.v_users_insert with (security_barrier=true) as + select id, id_external, name_machine, name_human, address_email, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_locked, is_private, can_manage_roles, settings from s_tables.t_users + with check option; + +grant insert on s_managers.v_users_insert to r_reservation_manager; + +create view s_managers.v_users_update with (security_barrier=true) as + select id, id_external, name_machine, name_human, address_email, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_locked, is_private, can_manage_roles, settings from s_tables.t_users + where is_deleted is not true + with check option; + +grant update on s_managers.v_users_update to r_reservation_manager; + +create view s_managers.v_users_deleted with (security_barrier=true) as + select id, id_external, name_machine, name_human, address_email, is_administer, is_manager, is_auditor, is_publisher, is_insurer, is_financer, is_reviewer, is_editor, is_drafter, is_requester, is_locked, is_private, can_manage_roles, date_created, date_changed, date_synced, date_locked, settings from s_tables.t_users + where is_deleted is true; + +grant select on s_managers.v_users to r_reservation_manager; + + +/** Create Materialized views for table based on history (maybe current day should be a view and previous days should be a materialized view that is updated by cron?) **/ +create materialized view s_administers.m_users_date_created_this_day as select * from s_tables.t_users where date_trunc('day', date_created) = date_trunc('day', current_timestamp); +create materialized view s_administers.m_users_date_created_previous_day as select * from s_tables.t_users where date_trunc('day', date_created) = date_trunc('day', current_timestamp) - interval '1 day'; +create materialized view s_administers.m_users_date_created_previous_month as select * from s_tables.t_users where date_trunc('month', date_created) = date_trunc('month', current_timestamp) - interval '1 month'; +create materialized view s_administers.m_users_date_created_previous_year as select * from s_tables.t_users where date_trunc('year', date_created) = date_trunc('year', current_timestamp) - interval '1 year'; + +create materialized view s_administers.m_users_date_changed_this_day as select * from s_tables.t_users where date_trunc('day', date_changed) = date_trunc('day', current_timestamp); +create materialized view s_administers.m_users_date_changed_previous_day as select * from s_tables.t_users where date_trunc('day', date_changed) = date_trunc('day', current_timestamp) - interval '1 day'; +create materialized view s_administers.m_users_date_changed_previous_month as select * from s_tables.t_users where date_trunc('month', date_changed) = date_trunc('month', current_timestamp) - interval '1 month'; +create materialized view s_administers.m_users_date_changed_previous_year as select * from s_tables.t_users where date_trunc('year', date_changed) = date_trunc('year', current_timestamp) - interval '1 year'; + +create materialized view s_administers.m_users_date_synced_this_day as select * from s_tables.t_users where date_trunc('day', date_synced) = date_trunc('day', current_timestamp); +create materialized view s_administers.m_users_date_synced_previous_day as select * from s_tables.t_users where date_trunc('day', date_synced) = date_trunc('day', current_timestamp) - interval '1 day'; +create materialized view s_administers.m_users_date_synced_previous_month as select * from s_tables.t_users where date_trunc('month', date_synced) = date_trunc('month', current_timestamp) - interval '1 month'; +create materialized view s_administers.m_users_date_synced_previous_year as select * from s_tables.t_users where date_trunc('year', date_synced) = date_trunc('year', current_timestamp) - interval '1 year'; + +alter materialized view s_administers.m_users_date_created_this_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_created_previous_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_created_previous_month owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_created_previous_year owner to r_reservation_administer; + +alter materialized view s_administers.m_users_date_changed_this_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_changed_previous_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_changed_previous_month owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_changed_previous_year owner to r_reservation_administer; + +alter materialized view s_administers.m_users_date_synced_this_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_synced_previous_day owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_synced_previous_month owner to r_reservation_administer; +alter materialized view s_administers.m_users_date_synced_previous_year owner to r_reservation_administer; + +grant select on s_administers.m_users_date_created_this_day to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_day to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_month to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_year to r_reservation_manager; + +grant select on s_administers.m_users_date_changed_this_day to r_reservation_manager; +grant select on s_administers.m_users_date_changed_previous_day to r_reservation_manager; +grant select on s_administers.m_users_date_changed_previous_month to r_reservation_manager; +grant select on s_administers.m_users_date_changed_previous_year to r_reservation_manager; + +grant select on s_administers.m_users_date_synced_this_day to r_reservation_manager; +grant select on s_administers.m_users_date_synced_previous_day to r_reservation_manager; +grant select on s_administers.m_users_date_synced_previous_month to r_reservation_manager; +grant select on s_administers.m_users_date_synced_previous_year to r_reservation_manager; + +grant select on s_administers.m_users_date_created_this_day to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_day to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_month to r_reservation_manager; +grant select on s_administers.m_users_date_created_previous_year to r_reservation_manager; + + +create function s_administers.f_users_insert_actions() returns trigger as $$ + begin + if (new.name_machine = null) then + new.name_machine = current_user; + end if; + + new.id_sort = ascii(new.name_machine); + + return new; + end; +$$ language plpgsql; + +create function s_administers.f_users_update_actions() returns trigger as $$ + begin + new.date_changed = localtimestamp; + + if (old.is_deleted = false and new.is_deleted = true) then + new.date_deleted = localtimestamp; + elseif (old.is_deleted = true and new.is_deleted = false) then + new.date_deleted = localtimestamp; + end if; + + if (old.is_locked = false and new.is_locked = true) then + new.date_locked = localtimestamp; + elseif (old.is_locked = true and new.is_locked = false) then + new.date_locked = localtimestamp; + end if; + + if (new.id_sort <> ascii(new.name_machine)) then + new.id_sort = ascii(new.name_machine); + end if; + + return new; + end; +$$ language plpgsql; + + +create function s_administers.f_users_update_materialized_views() returns trigger security definer as $$ + begin + refresh materialized view s_administers.m_users_date_created_this_day; + refresh materialized view s_administers.m_users_date_changed_this_day; + refresh materialized view s_administers.m_users_date_synced_this_day; + + return null; + end; +$$ language plpgsql; + +alter function s_administers.f_users_update_materialized_views() owner to r_reservation_administer; + +create trigger tr_users_insert_actions + before insert on s_tables.t_users + for each row execute procedure s_administers.f_users_insert_actions(); + +create trigger tr_users_update_actions + before update on s_tables.t_users + for each row execute procedure s_administers.f_users_update_actions(); + +create trigger tr_users_update_materialized_views + after insert or update on s_tables.t_users + for each statement execute procedure s_administers.f_users_update_materialized_views(); + +/** Special Cases: manually add the postgresql and public users first before any logging triggers are defined (because some of them depend on this table recursively! **/ +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_public) values (1, 'u_public', (null, 'Unknown', null, null, null, 'Unknown'), false, true); +insert into s_tables.t_users (id, name_machine, name_human, is_private, is_system) values (2, 'postgres', (null, 'Database', null, 'Administer', null, 'Database (Administer)'), false, true); + + + +commit transaction; diff --git a/database/sql/reservation/reservation-workflow.sql b/database/sql/reservation/reservation-workflow.sql new file mode 100644 index 0000000..c39b66f --- /dev/null +++ b/database/sql/reservation/reservation-workflow.sql @@ -0,0 +1,12 @@ +/** Standardized SQL Structure - Workflow **/ +/** This depends on: base-users.sql **/ +start transaction; + + + +/** Custom database specific settings (do this on every connection made) **/ +set bytea_output to hex; +set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public; +set datestyle to us; + +/* @todo: implement this and add appropriate foreign keys to the t_requests and related tables. */ diff --git a/documentation/access_roles.txt b/documentation/access_roles.txt index e69f746..46fe6d7 100644 --- a/documentation/access_roles.txt +++ b/documentation/access_roles.txt @@ -47,14 +47,14 @@ The roles: - This role is intended for users who need to make a request. - With the reservation system example. thos would be a request for a reservation. -- (system)_users: - - Replace (system) with the appropriate name for the system, generally the database name (for example, the reservation system, this would be reservation_users). +- r_(system): + - Replace (system) with the appropriate name for the system, generally the database name (for example, the reservation system, this would be r_reservation). - Provides basic access to the database, such as ldap integration. - All other roles should be a sub-set of this role. - - Do not confuse this with "(system)_user" (described below), which is considered a special-case user account. + - Do not confuse this with "r_(system)_user" (described below), which is considered a special-case user account. - All users should be part of this role. -- public_users: +- r_public: - Provides access to the database but only for information that should be made available to the world. - This role has the least amount of access. - Should not be assigned to any user with the (system)_users role or any such subset. @@ -75,22 +75,31 @@ There are five groups: - These are for accounts that are non-administrative but have additional access to the database beyond basic user access. - Basic Group: - - (system)_users + - r_(system)_user - These are for accounts that need login access and are granted access that every user on the system should have access to. - Public Group: - - public_users + - r_public - These are for anonymous accounts and other public access entities. - Everything this should be able to access is generally considered public information. There are also special user accounts: -- public_user: +- u_public: - This account should not require a password to login and essentially represent a public web user. - - Some systems are designed to be private and require login, these systems generally provided almost no access for public_user. + - Some systems are designed to be private and require login, these systems generally provided almost no access for u_public. - Because there is no password and all data is considered public, ssl is not needed and access to/from the database should have higher performance than other user accounts. -- (system)_user: - - Replace (system) with the appropriate name for the system, generally the database name (for example, the reservation system, this would be reservation_user). +- r_(system): + - Replace (system) with the appropriate name for the system, generally the database name (for example, the reservation system, this would be r_reservation). - This is the account the system uses for general cron jobs and other automated tasks. - The access provided here is dependent to the particular system and therefore this may also have or not have a password. + +- r_(system)_(????): + - Replace (system) with the appropriate name for the system, generally the database name (for example, the reservation system, this would be r_reservation). + - Replace (????) with a custom name specific to the limitation or purpose of the role. + - Custom database-specific accounts are created to act as a restricted/jailed account to perform certain tasks. + - These roles are used to prevent users from having direct access to some tables without having to switch to a root user. + - Postgresql allows views to run as 'security definer', which then grants all such priveleges. + - By using a restricted/jailed role, any potential damage from accidents or security breaches are reduced. + - Example: 'r_reservation_statistics_update' is a role that performs updates on statistics tables in the reservation system database. diff --git a/documentation/database.txt b/documentation/database.txt index ac8b43f..fbdd867 100644 --- a/documentation/database.txt +++ b/documentation/database.txt @@ -28,10 +28,10 @@ As for order of operations, postgresql provides a database environment variable This search_path provides an order in which schemas may be searched. Because of a users access control, some schemas may not be available. This has the convenient effect of allowing multiple identically named tables to be used, but provide different content based on access restrictions. -For example, there are at least two views filtering the user account infomration: managers.v_users and public.v_users. +For example, there are at least two views filtering the user account infomration: s_managers.v_users and public.v_users. Users without access to the managers will at least see the public.v_users view. The view public.v_users provides a limited subset of user rows based on criteria such as if the account is not marked private and then only a limited set of columns are made visible. -The view managers.v_users provides access to far more accounts and many more columns. +The view s_managers.v_users provides access to far more accounts and many more columns. This then allows the client software, such as PHP, to not need to understand the access control situation and to only need to select v_users to access user data. Postgresql materialized views are experimentally being used to provide a sort of live cache of information. @@ -46,3 +46,20 @@ This can then slow down site response time, directly affecting the user experien This id_sort column is used, in conjunction with custom indexing, to provide a sub-set of the arbitrarily large users table. The id_sort is simply an ordinal integer (as returned by PHPs ord() function) for the first (lower-cased) letter of the username. This is obviously not an optimal solution, in part because some alphabets will have more names than others, but I believe it is a good enough solution. + +For database names, the following naming scheme is used: + - t_: This represents a table. + - v_: This represents a view. + - m_: This represents a materialized view. + - cp_: This represents a primary key constraint. + - cu_: This represents a unique constraint. + - cc_: This represents a check constraint. + - cf_: This represents a foreign key constraint. + - i_: This represents an index. + - f_: This represents a function. + - tr_: This represents a trigger. + - ct_: This represents a composite type. + - s_: This represents a schema. + - r_: This represents a role. + - u_: This represents a user (except for ldap users, whose names are exactly as defined in ldap, and the root postgresql user, usually postgres). + - se_: This represents a sequence. diff --git a/examples/http.php b/examples/http.php index 3b6e79a..93f910d 100644 --- a/examples/http.php +++ b/examples/http.php @@ -5,6 +5,8 @@ $root_path = 'common/base/classes/'; require_once($root_path . 'base_http.php'); + require_once($root_path . 'base_database.php'); + require_once($root_path . 'base_cookie.php'); class_alias('c_base_return', 'c_return'); class_alias('c_base_return_status', 'c_status'); @@ -72,11 +74,98 @@ ini_set('output_buffering', FALSE); } + function program_load_session(&$data_program) { + $database = new c_base_database(); + + $remote_address = '127.0.0.1'; + if (!empty($_SERVER['REMOTE_ADDR'])) { + $remote_address = $_SERVER['REMOTE_ADDR']; + } + + // cookie is used to determine whether or not the user is logged in. + $cookie = new c_base_cookie(); + $cookie->set_name("localhost"); + $cookie->set_path('/'); + $cookie->set_domain('.localhost'); + $cookie->set_secure(TRUE); + + $logged_in = FALSE; + $failure = FALSE; + + $result = $cookie->do_pull(); + if ($result instanceof c_base_return_true) { + $value = $cookie->get_value_exact(); + + if ($cookie->validate() instanceof c_base_return_true && !empty($value['session_id'])) { + $session = new c_base_session(); + $session->set_socket_directory('/programs/sockets/sessionize_accounts/'); + $session->set_system_name('example'); + $session->set_host($remote_address); + $session->set_session_id($value['session_id']); + $result = $session->do_connect(); + $failure = c_base_return::s_has_error($result); + if (!$failure) { + $result = $session->do_pull(); + $session->do_disconnect(); + $data_program['session'] = $result; + } + unset($failure); + + $connected = FALSE; + if ($result instanceof c_base_return_true) { + $name = $session->get_name()->get_value(); + $password = $session->get_name()->get_value(); + program_assign_database_string($database, $name, $password, $session); + unset($name); + unset($password); + + $connected = program_connect_database($database); + } + unset($result); + + if ($connected) { + // check to see if the session timeout has been extended and if so, then update the cookie. + $session_expire = cbri::s_value_exact($session->get_timeout_expire()); + $session_seconds = $session_expire - time(); + if ($session_seconds == 0) { + $session_seconds = -1; + } + if ($session_expire > $value['expire']) { + $value['expire'] = gmdate("D, d-M-Y H:i:s T", $session_expire); + $cookie->set_value($value); + $cookie->set_expires($session_expire); + } + unset($session_expire); + unset($session_seconds); + } + unset($connected); + unset($session); + } + } + else { + program_assign_database_string($database, 'example_user', NULL, NULL); + $connected = program_connect_database($database); + + if ($connected) { + $data_program['http']->set_response_content('Connected: success
.'); + $database->do_disconnect(); + } + unset($connected); + } + unset($value); + unset($cookie); + unset($database); + unset($remote_address); + unset($logged_in); + } + function program_receive_request(&$data_program) { $data_program['http'] = new c_base_http(); $data_program['http']->do_load_request(); $data_program['http']->set_response_content(""); + + program_load_session($data_program); } function program_process_request(&$data_program) { @@ -312,4 +401,35 @@ unset($data_program['debug']); } + function program_assign_database_string(&$database, $username, $password, $session) { + if (!is_null($session)) { + $database->set_session($session); + } + + $connection_string = new c_base_connection_string(); + $connection_string->set_host('127.0.0.1'); + $connection_string->set_port(5432); + $connection_string->set_database('example'); + $connection_string->set_user($username); + if (!is_null($password)) { + $connection_string->set_password($password); + } + $connection_string->set_ssl_mode('require'); + $connection_string->set_connect_timeout(4); + $database->set_connection_string($connection_string); + unset($connection_string); + } + + function program_connect_database(&$database) { + if (!($database->do_connect() instanceof c_base_return_true)) { + return FALSE; + } + + $database->do_query('set bytea_output to hex;'); + $database->do_query('set datestyle to us;'); + + return TRUE; + } + + program(); diff --git a/examples/test.php b/examples/test.php index c935ce0..08bb633 100755 --- a/examples/test.php +++ b/examples/test.php @@ -2,6 +2,10 @@ // make sure the class files can be loaded (be sure to customize this as necessary). set_include_path('/var/www/koopa'); + // load the global defaults file (this file is not included by default but is required by all). + // replace this with your own as you see fit. + require_once('common/base/classes/base_defaults_global.php'); + require_once('common/base/classes/base_error.php'); require_once('common/base/classes/base_return.php'); require_once('common/base/classes/base_session.php'); @@ -352,11 +356,10 @@ $user_data = get_user_data($database, $session->get_name()->get_value_exact()); $stuff['login'] .= ' - You are logged in as: ' . $session->get_name()->get_value_exact() . '
' . "\n"; - $stuff['login'] .= ' - Your user id is: ' . $session->get_id_user()->get_value_exact() . '
' . "\n"; #$stuff['login'] .= ' - Your password is: ' . $session->get_password()->get_value_exact() . '
' . "\n"; $stuff['login'] .= ' - You will be auto-logged out at: ' . $data['expire'] . '
' . "\n"; $stuff['login'] .= '
' . "\n"; - $stuff['login'] .= 'Your user data is:
' . "\n"; + $stuff['login'] .= 'Your session user data is:
' . "\n"; $stuff['login'] .= print_r($user_data, TRUE) . "
"; $stuff['login'] .= '
' . "\n"; $logged_in = TRUE; @@ -365,7 +368,7 @@ set_log_activity($database); get_database_data($database, $stuff); - if ($session->get_id_user()->get_value_exact() > 0) { + if (!empty($session->get_name()->get_value_exact())) { $log = get_log_activity($database); $table = build_log_activity_table($log); $stuff['login'] .= "
" . $table . "
"; @@ -374,7 +377,7 @@ unset($table); } - if ($session->get_id_user()->get_value_exact() > 0) { + if (!empty($session->get_name()->get_value_exact())) { $log = get_log_users($database); $table = build_log_users_table($log); $stuff['login'] .= "
" . $table . "
"; @@ -414,7 +417,7 @@ $account_exists = check_login_access($stuff, $database, $_POST['login_name'], $_POST['login_password'], $session); if (!$account_exists) { $user_id = 1; - $session->set_name('public_user'); + $session->set_name('u_public'); $session->set_password(NULL); if (!isset($stuff['login'])) { $stuff['login'] = ''; @@ -423,14 +426,14 @@ $database->set_session($session); #$database->set_persistent(TRUE); - assign_database_string($database, 'public_user', NULL, $session); + assign_database_string($database, 'u_public', NULL, $session); $connected = connect_database($database); if ($connected) { set_log_user($database, 'login_failure', $_POST['login_name'], NULL, 401); set_log_activity($database, 401); - $stuff['login'] .= ' - Accessing database as: public_user' . '
' . "\n"; + $stuff['login'] .= ' - Accessing database as: u_public' . '
' . "\n"; $stuff['login'] .= ' - Your user id is: 1 ' . '
' . "\n"; $stuff['login'] .= '
' . "\n"; $logged_in = TRUE; @@ -465,8 +468,7 @@ $failure = c_base_return::s_has_error($result); } - // added '$user_id > 999' to ensure that anonymous and other system users do not generate a session cookie. - if (!$failure && $user_id > 999) { + if (!$failure) { $result = $session->do_push(600, 1800); // (10 minutes, 30 minutes) $session->do_disconnect(); @@ -491,11 +493,10 @@ } $stuff['login'] .= ' - You are logged in as: ' . $session->get_name()->get_value_exact() . '
' . "\n"; - $stuff['login'] .= ' - Your user id is: ' . $session->get_id_user()->get_value_exact() . '
' . "\n"; #$stuff['login'] .= ' - Your password is: ' . $session->get_password()->get_value_exact() . '
' . "\n"; $stuff['login'] .= ' - You will be auto-logged out at: ' . $expire_string . ' (' . $session_expire . ')' . '
' . "\n"; $stuff['login'] .= '
' . "\n"; - $stuff['login'] .= 'Your user data is:
' . "\n"; + $stuff['login'] .= 'Your session user data is:
' . "\n"; $stuff['login'] .= print_r($user_data, TRUE) . "
"; $stuff['login'] .= '
' . "\n"; $logged_in = TRUE; @@ -507,7 +508,7 @@ set_log_activity($database); get_database_data($database, $stuff); - if ($session->get_id_user()->get_value_exact() > 0) { + if (!empty($session->get_name()->get_value_exact())) { $log = get_log_activity($database); $table = build_log_activity_table($log); $stuff['login'] .= "
" . $table . "
"; @@ -516,7 +517,7 @@ unset($table); } - if ($session->get_id_user()->get_value_exact() > 0) { + if (!empty($session->get_name()->get_value_exact())) { $log = get_log_users($database); $table = build_log_users_table($log); $stuff['login'] .= "
" . $table . "
"; @@ -578,8 +579,8 @@ } function get_database_data(&$database, &$stuff) { - $stuff['login'] .= 'query: "select * from v_users;"
' . "\n"; - $query_result = $database->do_query('select * from v_users'); + $stuff['login'] .= 'query: "select * from v_users where is_system is not true and is_public is not true limit 20;"
' . "\n"; + $query_result = $database->do_query(' where is_system is not true and is_public is not true limit 20'); if ($query_result instanceof c_base_database_result) { $all = $query_result->fetch_all(); $stuff['login'] .= "
    "; @@ -609,7 +610,7 @@ } function check_login_access(&$stuff, &$database, $username, $password, $session) { - if ($username == 'public_user') return FALSE; + if ($username == 'u_public') return FALSE; $database->set_session($session); assign_database_string($database, $username, $password, $session); @@ -670,7 +671,7 @@ } $database->do_query('set bytea_output to hex;'); - $database->do_query('set search_path to system,administers,managers,publishers,reviewers,drafters,users,public;'); + $database->do_query('set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public;'); $database->do_query('set datestyle to us;'); return TRUE; @@ -681,8 +682,8 @@ $extra_values = ''; $query_string = ''; - $query_string .= 'insert into v_log_users_self_insert (id_user, name_machine_user, log_title, log_type, log_severity, request_client, response_code, log_details)'; - $query_string .= ' values (coalesce((select id from v_users_self), 1), coalesce((select name_machine from v_users_self), \'unknown\'), $1, $2, $3, ($4, $5, $6), $7, $8); '; + $query_string .= 'insert into v_log_users_self_insert (log_title, log_type, log_severity, request_client, response_code, log_details)'; + $query_string .= ' values ($1, $2, $3, ($4, $5, $6), $7, $8); '; $query_parameters = array(); $query_parameters[3] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; @@ -752,7 +753,7 @@ if ($connected) { $query_string = ''; - $query_string .= 'insert into v_log_activity_self_insert (id_user, name_machine_user, request_path, request_arguments, request_client, response_code) values (coalesce((select id from v_users_self), 1), coalesce((select name_machine from v_users_self), \'unknown\'), $1, $2, ($3, $4, $5), $6); '; + $query_string .= 'insert into v_log_user_activity_self_insert (request_path, request_arguments, request_client, response_code) values ($1, $2, ($3, $4, $5), $6); '; $query_parameters = array(); $query_parameters[] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; @@ -791,14 +792,10 @@ } function get_user_data(&$database, $user_name, $ldap_data = NULL) { - $id_sort = (int) ord($user_name[0]); - $sort_string = ' where id_sort = ' . $id_sort; - $user_data = array( 'id_user' => NULL, - 'id_sort' => $id_sort, ); - $query_result = $database->do_query('select id, id_external, name_human, address_email, is_private, is_locked, date_created, date_changed, settings from v_users_self' . $sort_string); + $query_result = $database->do_query('select id, id_external, name_human, address_email, is_private, is_locked, is_system, is_public, date_created, date_changed, settings from v_users_self'); if ($query_result instanceof c_base_database_result) { if ($query_result->number_of_rows()->get_value_exact() > 0) { $result = $query_result->fetch_row(); @@ -811,9 +808,11 @@ $user_data['address_email'] = $result_array[3]; $user_data['is_private'] = $result_array[4]; $user_data['is_locked'] = $result_array[5]; - $user_data['date_created'] = $result_array[6]; - $user_data['date_changed'] = $result_array[7]; - $user_data['settings'] = json_decode($result_array[8], TRUE); + $user_data['is_system'] = $result_array[6]; + $user_data['is_public'] = $result_array[7]; + $user_data['date_created'] = $result_array[8]; + $user_data['date_changed'] = $result_array[9]; + $user_data['settings'] = json_decode($result_array[10], TRUE); } } } @@ -829,7 +828,7 @@ if (is_null($user_data['id_user'])) { if (is_null($ldap_data)) { - $query_result = $database->do_query('insert into v_users_self_insert (id_sort, name_machine) values (' . $id_sort . ', user)'); + $query_result = $database->do_query('insert into v_users_self_insert (name_human.first, name_human.last, name_human.complete, address_email, id_external) values (null, null, null, null, null)'); if ($query_result instanceof c_base_return_false) { if (!isset($stuff['errors'])) { $stuff['errors'] = ''; @@ -850,7 +849,7 @@ $ldap_data['employeenumber'], ); - $query_result = $database->do_query('insert into v_users_self_insert (id_sort, name_machine, name_human.first, name_human.last, name_human.complete, address_email, id_external) values (' . $id_sort . ', user, $1, $2, $3, ($4, $5, TRUE), $6)', $parameters); + $query_result = $database->do_query('insert into v_users_self_insert (name_human.first, name_human.last, name_human.complete, address_email, id_external) values ($1, $2, $3, ($4, $5, TRUE), $6)', $parameters); if ($query_result instanceof c_base_return_false) { if (!isset($stuff['errors'])) { $stuff['errors'] = ''; @@ -861,8 +860,8 @@ unset($query_result); } - $user_data['id_user'] = 1; - $query_result = $database->do_query('select id, id_external, name_human, address_email, is_private, is_locked, date_created, date_changed, settings from v_users_self' . $sort_string); + $user_data['id_user'] = NULL; + $query_result = $database->do_query('select id, id_external, name_human, address_email, is_private, is_locked, is_system, is_public, date_created, date_changed, settings from v_users_self'); if ($query_result instanceof c_base_database_result) { if ($query_result->number_of_rows()->get_value_exact() > 0) { $result = $query_result->fetch_row(); @@ -874,9 +873,11 @@ $user_data['address_email'] = $result_array[3]; $user_data['is_private'] = $result_array[4]; $user_data['is_locked'] = $result_array[5]; - $user_data['date_created'] = $result_array[6]; - $user_data['date_changed'] = $result_array[7]; - $user_data['settings'] = json_decode($result_array[8], TRUE); + $user_data['is_system'] = $result_array[6]; + $user_data['is_public'] = $result_array[7]; + $user_data['date_created'] = $result_array[8]; + $user_data['date_changed'] = $result_array[9]; + $user_data['settings'] = json_decode($result_array[10], TRUE); } } } @@ -897,7 +898,7 @@ $values = array(); $user_id = NULL; - $query_result = $database->do_query('select id, request_path, request_date, request_client, response_code from v_log_activity_self order by request_date desc limit 20;'); + $query_result = $database->do_query('select id, request_path, request_date, request_client, response_code from v_log_user_activity_self order by request_date desc limit 20;'); if ($query_result instanceof c_base_database_result) { $total_rows = $query_result->number_of_rows()->get_value_exact(); diff --git a/program/reservation/index.php b/program/reservation/index.php index d1d5b25..3b2f000 100644 --- a/program/reservation/index.php +++ b/program/reservation/index.php @@ -2,24 +2,23 @@ // assign custom include path. set_include_path('/var/www/git/koopa'); - $root_path = 'common/base/classes/'; - require_once($root_path . 'base_http.php'); - require_once($root_path . 'base_cookie.php'); - require_once($root_path . 'base_ldap.php'); - require_once($root_path . 'base_markup.php'); - require_once($root_path . 'base_html.php'); - require_once($root_path . 'base_charset.php'); - require_once($root_path . 'base_database.php'); + // load the global defaults file (this file is not included by default but is required by all). + // replace this with your own as you see fit. + require_once('common/base/classes/base_defaults_global.php'); - $root_path = 'common/theme/classes/'; - require_once($root_path . 'theme_html.php'); + require_once('common/base/classes/base_http.php'); + require_once('common/base/classes/base_cookie.php'); + require_once('common/base/classes/base_ldap.php'); + require_once('common/base/classes/base_markup.php'); + require_once('common/base/classes/base_html.php'); + require_once('common/base/classes/base_charset.php'); + require_once('common/base/classes/base_database.php'); - $root_path = 'program/reservation/'; - require_once($root_path . 'reservation_database.php'); - require_once($root_path . 'reservation_session.php'); - require_once($root_path . 'reservation_paths.php'); + require_once('common/theme/classes/theme_html.php'); - unset($root_path); + require_once('program/reservation/reservation_database.php'); + require_once('program/reservation/reservation_session.php'); + require_once('program/reservation/reservation_paths.php'); /** * Load all custom settings. @@ -40,7 +39,7 @@ $settings['database_host'] = '127.0.0.1'; $settings['database_port'] = 5432; $settings['database_name'] = 'reservation'; - $settings['database_user'] = 'public_user'; + $settings['database_user'] = 'u_public'; $settings['database_password'] = NULL; $settings['database_timeout'] = 4; $settings['database_ssl_mode'] = 'require'; @@ -97,10 +96,11 @@ $http->set_response_pragma('no-cache'); $http->set_response_vary('Host'); $http->set_response_vary('User-Agent'); + $http->set_response_vary('Accept'); + $http->set_response_vary('Accept-Language'); #$http->set_response_warning('1234 This site is under active development.'); // finalize the content prior to sending headers to ensure header accuracy. - $http->set_response_content_length(NULL, TRUE); $http->encode_response_content(); @@ -110,7 +110,7 @@ // when the headers are sent, checksums are created, so at this point all error output should be stored and not sent. - $http->send_response_headers(); + $http->send_response_headers(TRUE); flush(); @@ -251,8 +251,8 @@ if (!isset($_SERVER["HTTPS"])) { reservation_build_page_require_https($html, $settings, $session); } - elseif ($settings['database_user'] == 'public_user') { - // if the session cookie exists, but the user is still public_user, then the cookie is no longer valid. + elseif ($settings['database_user'] == 'u_public') { + // if the session cookie exists, but the user is still u_public, then the cookie is no longer valid. if (empty($session->get_session_id()->get_value_exact())) { // check to see if user has filled out the login form. if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['form_id']) && $_POST['form_id'] == 'login_form') { @@ -264,7 +264,7 @@ } else { // store the problems in the session object (because session as a subclass of c_base_return). - $session->set_problems($problems); + $session->set_problems($problems->get_value_exact()); // @todo: render login failure. reservation_process_path_public($html, $settings, $session); diff --git a/program/reservation/reservation_database.php b/program/reservation/reservation_database.php index 4132a80..249f4e4 100644 --- a/program/reservation/reservation_database.php +++ b/program/reservation/reservation_database.php @@ -75,7 +75,7 @@ // configure default settings. $database->do_query('set bytea_output to hex;'); - $database->do_query('set search_path to system,administers,managers,auditors,publishers,insurers,financers,reviewers,editors,drafters,requesters,users,public;'); + $database->do_query('set search_path to s_administers,s_managers,s_auditors,s_publishers,s_insurers,s_financers,s_reviewers,s_editors,s_drafters,s_requesters,s_users,public;'); $database->do_query('set datestyle to us;'); return new c_base_return_true(); diff --git a/program/reservation/reservation_paths.php b/program/reservation/reservation_paths.php index b75ca78..0c0ad49 100644 --- a/program/reservation/reservation_paths.php +++ b/program/reservation/reservation_paths.php @@ -29,18 +29,20 @@ function reservation_build_login_page(&$html, $settings, $session) { // @fixme: create a form problems array in session and use that. $problems = $session->get_problems(); - if (is_array($problems)) { + if ($problems instanceof c_base_return_array) { + $problems = $problems->get_value_exact(); + foreach ($problems as $problem) { - if (!empty($problem['fields']) && is_array($problem['fields'])) { - foreach ($problem['fields'] as $problem_field) { - $problem_fields[$problem_field] = $problem_field; + $fields = $problem->get_fields(); + if ($fields instanceof c_base_return_array) { + foreach ($fields->get_value_exact() as $field) { + $problem_fields[] = $field; } - unset($problem_field); + unset($field); } + unset($fields); - if (!empty($problem['messages']) && is_string($problem['messages'])) { - $problem_messages[] = $problem['messages']; - } + $problem_messages[] = $problem->get_value_exact(); } unset($problem); } @@ -174,31 +176,16 @@ function reservation_build_login_page(&$html, $settings, $session) { function reservation_attempt_login(&$database, &$settings, &$session) { $problems = array(); if (empty($_POST['login_form-username'])) { - $problem = new c_base_form_problem(); - $problem->set_field('login_form-username'); - $problem->set_value('No valid username has been supplied.'); - - $problems[] = $problem; - unset($problem); + $problems[] = c_base_form_problem::s_create_error('login_form-username', 'No valid username has been supplied.'); } if (empty($_POST['login_form-password'])) { - $problem = new c_base_form_problem(); - $problem->set_field('login_form-password'); - $problem->set_value('No valid password has been supplied.'); - - $problems[] = $problem; - unset($problem); + $problems[] = c_base_form_problem::s_create_error('login_form-password', 'No valid password has been supplied.'); } // explicitly deny access to internal user accounts - if ($_POST['login_form-username'] == 'public_user') { - $problem = new c_base_form_problem(); - $problem->set_field('login_form-username'); - $problem->set_value('Unable to login, an incorrect user name or password has been specified.'); - - $problems[] = $problem; - unset($problem); + if ($_POST['login_form-username'] == 'u_public') { + $problems[] = c_base_form_problem::s_create_error('login_form-username', 'Unable to login, an incorrect user name or password has been specified.'); } // return current list of problems before continuing to login attempt with credentials. @@ -214,40 +201,123 @@ function reservation_attempt_login(&$database, &$settings, &$session) { // the database string must be rebuilt using the new username and password. reservation_database_string($database, $settings); + $access_denied = FALSE; + $error_messages = array(); $connected = reservation_database_connect($database); if (!($connected instanceof c_base_return_true)) { - // it is possible the user name might not exist, so try to auto-create the username if the username does not exist. - $ensure_result = reservation_ensure_user_account($settings, $_POST['login_form-username']); - // @todo: process the $ensure_result return codes. - - if ($ensure_result instanceof c_base_return_int) { - $ensure_result = $ensure_result->get_value_exact(); - - $connected = new c_base_return_false(); - if ($ensure_result === 0) { - // try again now that the system has attempted to ensure the user account exists. - $connected = reservation_database_connect($database); - if ($connected instanceof c_base_return_true) { - // @todo: add log entry. - #set_log_user($database, 'create_user'); - } + // try to determine what the warning is. + // this is not very accurate/efficient, but scanning the string appears to be the only way to identify the error. + $errors = $connected->get_error(); + + $error = reset($errors); + unset($errors); + + $details = $error->get_details(); + unset($error); + + if (isset($details['arguments'][':failure_reasons'][0]['message'])) { + // in the case where the database cannot be connected to, do not attempt to ensure user account. + if (preg_match('/could not connect to server: connection refused/i', $details['arguments'][':failure_reasons'][0]['message']) > 0) { + // @todo: separate messages for admin users and public users. + #foreach ($details['arguments'][':failure_reasons'] as $error_message) { + # $error_messages[] = $error_message; + #} + #unset($error_message); + unset($details); + + $problems[] = c_base_form_problem::s_create_error(NULL, 'Unable to login, cannot connect to the database.'); + return c_base_return_array::s_new($problems); } - else { - // @todo: possibly handle errors resulting from not being able to auto-create account. + elseif (preg_match('/no pg_hba\.conf entry for host/i', $details['arguments'][':failure_reasons'][0]['message']) > 0) { + // the account either does note exist or is not authorized. + // it is a pity that postgresql doesn't differentiate the two. + $access_denied = TRUE; + } + } + unset($details); + + if ($access_denied) { + // it is possible the user name might not exist, so try to auto-create the username if the username does not exist. + $ensure_result = reservation_ensure_user_account($settings, $_POST['login_form-username']); + if ($ensure_result instanceof c_base_return_int) { + $ensure_result = $ensure_result->get_value_exact(); + + $connected = new c_base_return_false(); + if ($ensure_result === 0) { + // try again now that the system has attempted to ensure the user account exists. + $connected = reservation_database_connect($database); + if ($connected instanceof c_base_return_true) { + // @todo: add log entry. + #set_log_user($database, 'create_user'); + } + } + elseif ($ensure_result === 1) { + // invalid user name, bad characters, or name too long. + } + elseif ($ensure_result === 2) { + // failed to connect to the ldap server and could not query the ldap name. + } + elseif ($ensure_result === 3) { + // user name not found in ldap database. + } + elseif ($ensure_result === 4) { + // 4 = failed to connect to the database. + } + elseif ($ensure_result === 5) { + // 5 = error returned while executing the SQL command. + } + elseif ($ensure_result === 6) { + // 6 = error occured while reading input from the user (such as via recv()). + } + elseif ($ensure_result === 7) { + // 7 = error occured while writing input from the user (such as via send()). + } + elseif ($ensure_result === 8) { + // 8 = the received packet is invalid, such as wrong length. + } + elseif ($ensure_result === 9) { + // 10 = connection timed out when reading or writing. + } + elseif ($ensure_result === 10) { + // 10 = the connection is being forced closed. + } + elseif ($ensure_result === 11) { + // 11 = the connection is closing because the service is quitting. + } } + unset($ensure_result); } - unset($ensure_result); } if ($connected instanceof c_base_return_false) { - $problem = new c_base_form_problem(); - $problem->set_field('login_form-username'); - $problem->set_value('Unable to login, an incorrect user or password has been specified.'); + if ($access_denied) { + $problems[] = c_base_form_problem::s_create_error('login_form-username', 'Unable to login, an incorrect user or password has been specified.'); + } + else { + $errors = $connected->get_error(); - $problems[] = $problem; - unset($problem); + $error = reset($errors); + unset($errors); + + $details = $error->get_details(); + unset($error); + + // @todo: not just database errors, but also session create errors need to be checked. + if (isset($details['arguments'][':failure_reasons'][0]['message']) && is_string($details['arguments'][':failure_reasons'][0]['message'])) { + $problems[] = c_base_form_problem::s_create_error(NULL, 'Unable to login, ' . $details['arguments'][':failure_reasons'][0]['message']); + } + else { + // here the reason for failure is unknown. + $problems[] = c_base_form_problem::s_create_error(NULL, 'Unable to login,'); + } + unset($details); + } + + unset($access_denied); } else { + unset($access_denied); + // @todo: add log entry. #set_log_user($database, 'login'); @@ -258,20 +328,14 @@ function reservation_attempt_login(&$database, &$settings, &$session) { // the session needs to be opened and the data needs to be saved on successful login. $result = $session->do_connect(); if (c_base_return::s_has_error($result)) { - // @todo: process each error message. - $problem = new c_base_form_problem(); - - $socket_error = $session->get_socket_error()->get_value(); + $socket_error = $session->get_error_socket(); if ($socket_error instanceof c_base_return_int) { - $problem->set_value('Failed to load session, due to socket error (' . $socket_error . '): ' . @socket_strerror($socket_error) . '.'); + $problems[] = c_base_form_problem::s_create_error(NULL, 'Failed to load session, due to socket error (' . $socket_error->get_value_exact() . '): ' . @socket_strerror($socket_error->get_value_exact()) . '.'); } else { - $problem->set_value('Failed to load session.'); + $problems[] = c_base_form_problem::s_create_error(NULL, 'Failed to load session.'); } unset($socket_error); - - $problems[] = $problem; - unset($problem); } else { $ldap = reservation_database_load_ldap_data($settings, $_POST['login_form-username'])->get_value(); @@ -282,13 +346,9 @@ function reservation_attempt_login(&$database, &$settings, &$session) { } if (isset($ldap['status']) && $ldap['status'] instanceof c_base_return_false) { - // @todo: handle error situation. - $problem = new c_base_form_problem(); - $problem->set_field('login_form-username'); - $problem->set_value('Failed to retrieve ldap information for specified user.'); + $problems[] = c_base_form_problem::s_create_error('login_form-username', 'Failed to retrieve ldap information for specified user.'); - $problems[] = $problem; - unset($problem); + // @todo: handle error situation. } $user_data = reservation_database_get_user_data($database, $_POST['login_form-username'], $ldap['data'])->get_value(); @@ -302,23 +362,20 @@ function reservation_attempt_login(&$database, &$settings, &$session) { $pushed = $session->do_push($settings['session_expire'], $settings['session_max']); $session->do_disconnect(); - $session_expire = $session->get_timeout_expire()->get_value_exact(); - $cookie_login = $session->get_cookie(); - + $cookie_login = NULL; if (c_base_return::s_has_error($pushed)) { - $problem = new c_base_form_problem(); - - $socket_error = $session->get_socket_error()->get_value(); + $socket_error = $session->get_error_socket(); if ($socket_error instanceof c_base_return_int) { - $problem->set_value('Failed to push session, due to socket error (' . $socket_error . '): ' . @socket_strerror($socket_error) . '.'); + $problems = c_base_form_problem::s_create_error(NULL, 'Failed to push session, due to socket error (' . $socket_error->get_value_exact() . '): ' . @socket_strerror($socket_error->get_value_exact()) . '.'); } else { - $problem->set_value('Failed to push session.'); + $problems[] = c_base_form_problem::s_create_error(NULL, 'Failed to push session.'); } unset($socket_error); - - $problems[] = $problem; - unset($problem); + } + else { + $session_expire = $session->get_timeout_expire()->get_value_exact(); + $cookie_login = $session->get_cookie(); } if ($cookie_login instanceof c_base_cookie) { @@ -484,6 +541,17 @@ function reservation_process_forms(&$html, $settings, &$session) { $tag->set_text('This function is called to process specific forms.'); $html->set_tag($tag); unset($tag); + + if (!empty($_POST['form_id'])) { + $tag = c_theme_html::s_create_tag(c_base_markup_tag::TYPE_BREAK); + $html->set_tag($tag); + unset($tag); + + $tag = c_theme_html::s_create_tag(c_base_markup_tag::TYPE_DIVIDER); + $tag->set_text('The form has the id: ' . $_POST['form_id'] . '.'); + $html->set_tag($tag); + unset($tag); + } } /** diff --git a/program/reservation/reservation_session.php b/program/reservation/reservation_session.php index bac1943..2c5fd90 100644 --- a/program/reservation/reservation_session.php +++ b/program/reservation/reservation_session.php @@ -268,8 +268,8 @@ // 6 = error occured while reading input from the user (such as via recv()). // 7 = error occured while writing input from the user (such as via send()). // 8 = the received packet is invalid, such as wrong length. - // 10 = connection timed out when reading or writing. - // 11 = the connection is being forced closed. - // 12 = the connection is closing because the service is quitting. + // 9 = connection timed out when reading or writing. + // 10 = the connection is being forced closed. + // 11 = the connection is closing because the service is quitting. return c_base_return_int::s_new($response_value); }