From 18b15db0d34b1ff5d08b9a2714d87246bddec62c Mon Sep 17 00:00:00 2001
From: alexhigh <alex@artica.es>
Date: Tue, 8 Apr 2014 16:26:23 +0000
Subject: [PATCH] 2014-04-08  Alejandro Gallardo <alejandro.gallardo@artica.es>

	* include/functions.php: Added the functions
	"get_file_upload_status" and "translate_file_upload_status".

	* extensions/files_repo.php,
	  extensions/files_repo/functions_files_repo.php,
	  extensions/files_repo/files_repo_list.php,
	  extensions/files_repo/files_repo_form.php,
	  extensions/files_repo/sql/files_repo.sql,
	  extensions/files_repo/sql/files_repo.postgreSQL.sql,
	  extensions/files_repo/sql/files_repo.oracle.sql: Added
	new files. New extension "Files repository".




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@9741 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
---
 pandora_console/ChangeLog                     |  14 +
 pandora_console/extensions/files_repo.php     | 205 +++++++++++++
 .../extensions/files_repo/files_repo_form.php |  90 ++++++
 .../extensions/files_repo/files_repo_list.php |  91 ++++++
 .../files_repo/functions_files_repo.php       | 279 ++++++++++++++++++
 .../files_repo/sql/files_repo.oracle.sql      |   6 +
 .../files_repo/sql/files_repo.postgreSQL.sql  |   2 +
 .../extensions/files_repo/sql/files_repo.sql  |   2 +
 pandora_console/include/functions.php         |  46 +++
 9 files changed, 735 insertions(+)
 create mode 100644 pandora_console/extensions/files_repo.php
 create mode 100644 pandora_console/extensions/files_repo/files_repo_form.php
 create mode 100644 pandora_console/extensions/files_repo/files_repo_list.php
 create mode 100644 pandora_console/extensions/files_repo/functions_files_repo.php
 create mode 100644 pandora_console/extensions/files_repo/sql/files_repo.oracle.sql
 create mode 100644 pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql
 create mode 100644 pandora_console/extensions/files_repo/sql/files_repo.sql

diff --git a/pandora_console/ChangeLog b/pandora_console/ChangeLog
index 7ece9fff92..8ffa25c926 100644
--- a/pandora_console/ChangeLog
+++ b/pandora_console/ChangeLog
@@ -1,3 +1,17 @@
+2014-04-08  Alejandro Gallardo <alejandro.gallardo@artica.es>
+	
+	* include/functions.php: Added the functions
+	"get_file_upload_status" and "translate_file_upload_status".
+
+	* extensions/files_repo.php,
+	  extensions/files_repo/functions_files_repo.php,
+	  extensions/files_repo/files_repo_list.php,
+	  extensions/files_repo/files_repo_form.php,
+	  extensions/files_repo/sql/files_repo.sql,
+	  extensions/files_repo/sql/files_repo.postgreSQL.sql,
+	  extensions/files_repo/sql/files_repo.oracle.sql: Added
+	new files. New extension "Files repository".
+
 2014-04-07  Vanessa Gil <vanessa.gil@artica.es>
 	
 	* pandoradb.oracle.sql
diff --git a/pandora_console/extensions/files_repo.php b/pandora_console/extensions/files_repo.php
new file mode 100644
index 0000000000..c174a2dfb6
--- /dev/null
+++ b/pandora_console/extensions/files_repo.php
@@ -0,0 +1,205 @@
+<?php
+
+// Pandora FMS - http://pandorafms.com
+// ==================================================
+// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
+// Please see http://pandorafms.org for full contribution list
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+
+function pandora_files_repo_install () {
+	global $config;
+	
+	if (isset($config['files_repo_installed'])) {
+		if ($config['files_repo_installed'] == 1) {
+			return;
+		}
+	}
+
+	$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+	$full_sql_dir = $full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."sql".DIRECTORY_SEPARATOR;
+	
+	/* SQL installation */
+	switch ($config['dbtype']) {
+		case 'mysql':
+			$sentences = file ($full_sql_dir.'files_repo.sql');
+			break;
+		case 'postgresql':
+			$sentences = file ($full_sql_dir.'files_repo.postgreSQL.sql');
+			break;
+		case 'oracle':
+			$sentences = file ($full_sql_dir.'files_repo.oracle.sql');
+			break;
+	}
+	
+	foreach ($sentences as $sentence) {
+		if (trim ($sentence) == "")
+			continue;
+		$success = db_process_sql ($sentence);
+		if ($success === false)
+			return;
+	}
+	
+	/* Configuration values */
+	$values = array(
+			"token" => "files_repo_installed",
+			"value" => 1
+		);
+	db_process_sql_insert('tconfig', $values);
+}
+
+function pandora_files_repo_uninstall () {
+	global $config;
+	
+	switch ($config["dbtype"]) {
+		case "mysql":
+			db_process_sql ('DROP TABLE `tfiles_repo_group`');
+			db_process_sql ('DROP TABLE `tfiles_repo`');
+			break;
+		case "postgresql":
+			db_process_sql ('DROP TABLE `tfiles_repo_group`');
+			db_process_sql ('DROP TABLE `tfiles_repo`');
+			break;
+		case "oracle":
+			db_process_sql ('DROP TABLE `tfiles_repo_group`');
+			db_process_sql ('DROP TABLE `tfiles_repo`');
+			break;
+	}
+
+	$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+	delete_dir($full_extensions_dir."files_repo");
+}
+
+function pandora_files_repo_godmode () {
+	global $config;
+
+	if (!isset($config['files_repo_installed']) || !$config['files_repo_installed']) {
+		ui_print_error_message(__('Extension not installed'));
+	}
+
+	// ACL Check
+	check_login ();
+	if (! check_acl ($config['id_user'], 0, "PM")) {
+		db_pandora_audit("ACL Violation", "Trying to access to Files repository");
+		require ("general/noaccess.php");
+		return;
+	}
+
+	// Header tabs
+	$godmode['text'] = '<a href="index.php?sec=gextensions&sec2=extensions/files_repo">'
+			. html_print_image ("images/setup.png", true, array ("title" => __('Administration view')))
+			. "</a>";
+	$godmode['godmode'] = 1;
+	$godmode['active'] = 1;
+		
+	$operation['text'] = '<a href="index.php?sec=extensions&sec2=extensions/files_repo">'
+			. html_print_image ("images/operation.png", true, array ("title" => __('Operation view')))
+			. "</a>";
+	$operation['operation'] = 1;
+			
+	$onheader = array('godmode' => $godmode, 'operation' => $operation);
+	// Header
+	ui_print_page_header (__("Files repository manager"), "images/extensions.png", false, "", true, $onheader);
+
+	$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+	require_once ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."functions_files_repo.php");
+
+	// Directory files_repo check
+	if (!files_repo_check_directory(true)) {
+		return;
+	}
+
+	// GET and POST parameters
+	$file_id = (int) get_parameter ("file_id");
+	$add_file = (bool) get_parameter ("add_file");
+	$update_file = (bool) get_parameter ("update_file");
+	$delete_file = (bool) get_parameter ("delete");
+
+	// File add or update
+	if ( $add_file || ($update_file && $file_id > 0) ) {
+		$groups = get_parameter ("groups", array());
+		$description = io_safe_output((string) get_parameter ("description"));
+		if (mb_strlen($description, "UTF-8") > 200) {
+			$description = mb_substr($description, 0, 200, "UTF-8");
+		}
+		$description = io_safe_input($description);
+
+		if ($add_file) {
+			$result = files_repo_add_file("upfile", $description, $groups);
+		} elseif ($update_file) {
+			$result = files_repo_update_file($file_id, $description, $groups);
+			$file_id = 0;
+		}
+		if ($result['status'] == false) {
+			ui_print_error_message($result['message']);
+		}
+	}
+	// File delete
+	if ($delete_file && $file_id > 0) {
+		$result = files_repo_delete_file($file_id);
+		if ($result !== -1) {
+			ui_print_result_message($result, __('Successfully deleted'), __('Could not be deleted'));
+		}
+		$file_id = 0;
+	}
+
+	// FORM
+	require ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."files_repo_form.php");
+	if (!$file_id) {
+		// LIST
+		$manage = true;
+		require ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."files_repo_list.php");
+	}
+}
+
+function pandora_files_repo_operation () {
+	global $config;
+
+	// Header tabs
+	$onheader = array();
+	if (check_acl($config['id_user'], 0, "PM")) {
+		$godmode['text'] = '<a href="index.php?sec=gextensions&sec2=extensions/files_repo">'
+				. html_print_image ("images/setup.png", true, array ("title" => __('Administration view')))
+				. "</a>";
+		$godmode['godmode'] = 1;
+			
+		$operation['text'] = '<a href="index.php?sec=extensions&sec2=extensions/files_repo">'
+				. html_print_image ("images/operation.png", true, array ("title" => __('Operation view')))
+				. "</a>";
+		$operation['operation'] = 1;
+		$operation['active'] = 1;
+		
+		$onheader = array('godmode' => $godmode, 'operation' => $operation);
+	}
+	// Header
+	ui_print_page_header (__("Files repository"), "images/extensions.png", false, "", false, $onheader);
+
+	$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+	require_once ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."functions_files_repo.php");
+
+	// Directory files_repo check
+	if (!files_repo_check_directory(true)) {
+		return;
+	}
+
+	// LIST
+	$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+	require ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."files_repo_list.php");
+}
+
+extensions_add_operation_menu_option(__('Files repository'), null, null, "v1r1");
+extensions_add_main_function('pandora_files_repo_operation');
+extensions_add_godmode_menu_option(__('Files repository manager'), 'PM', null, null, "v1r1");
+extensions_add_godmode_function('pandora_files_repo_godmode');
+
+pandora_files_repo_install();
+
+?>
diff --git a/pandora_console/extensions/files_repo/files_repo_form.php b/pandora_console/extensions/files_repo/files_repo_form.php
new file mode 100644
index 0000000000..004c34e372
--- /dev/null
+++ b/pandora_console/extensions/files_repo/files_repo_form.php
@@ -0,0 +1,90 @@
+<?php
+
+// Pandora FMS - http://pandorafms.com
+// ==================================================
+// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
+// Please see http://pandorafms.org for full contribution list
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+global $config;
+
+$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+require_once ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."functions_files_repo.php");
+
+$file = array();
+$file['name'] = '';
+$file['description'] = '';
+$file['groups'] = array();
+if (isset($file_id) && $file_id > 0) {
+	$file = files_repo_get_files(array('id' => $file_id));
+	if (empty($file)) {
+		$file_id = 0;
+	} else {
+		$file = $file[$file_id];
+	}
+}
+
+$table = new stdClass();
+$table->width = '99.5%';
+$table->style = array();
+$table->style[0] = "font-weight: bold;";
+$table->style[2] = "text-align: center;";
+$table->colspan = array();
+$table->data = array();
+
+// GROUPS
+$groups = groups_get_all();
+// Add the All group to the beginning to be always the first
+// Use this instead array_unshift to keep the array keys
+$groups = array(0 => __('All')) + $groups;
+$html = "";
+$style = "style=\"vertical-align: middle; min-width: 60px;\"";
+foreach ($groups as $id => $name) {
+	$checked = in_array($id, $file['groups']);
+	$checkbox = html_print_checkbox_extended ('groups[]', $id, $checked, false, '', 'class="chkb_group"', true);
+	$html .= "<span $style>$name&nbsp;$checkbox</span>&nbsp;&nbsp;&nbsp;";
+}
+$row = array();
+$row[0] = __('Groups');
+$row[1] = $html;
+$table->data[] = $row;
+$table->colspan[][1] = 2;
+
+// DESCRIPTION
+$row = array();
+$row[0] = __('Description');
+$row[0] .= ui_print_help_tip(__('Only 200 characters are permitted'), true);
+$row[1] = html_print_textarea('description', 3, 20, $file['description'], 'style="min-height: 40px; max-height: 40px; width: 98%;"', true);
+$table->data[] = $row;
+$table->colspan[][1] = 2;
+
+// FILE and SUBMIT BUTTON
+$row = array();
+$row[0] = __('File');
+if ($file_id > 0) {
+	$row[1] = $file['name'];
+	$row[2] = html_print_submit_button(__('Update'), 'submit', false, 'class="sub upd"', true);
+	$row[2] .= html_print_input_hidden('update_file', 1, true);
+	$row[2] .= html_print_input_hidden('file_id', $file_id, true);
+} else {
+	$row[1] = html_print_input_file('upfile', true);
+	$row[2] = html_print_submit_button(__('Add'), 'submit', false, 'class="sub add"', true);
+	$row[2] .= html_print_input_hidden('add_file', 1, true);
+}
+$table->data[] = $row;
+$table->colspan[][1] = 1;
+
+$url = ui_get_full_url("index.php?sec=gextensions&sec2=extensions/files_repo");
+echo "<form method='post' action='$url' enctype='multipart/form-data'>";
+html_print_table($table);
+echo "</form>";
+
+?>
\ No newline at end of file
diff --git a/pandora_console/extensions/files_repo/files_repo_list.php b/pandora_console/extensions/files_repo/files_repo_list.php
new file mode 100644
index 0000000000..70cbc668cc
--- /dev/null
+++ b/pandora_console/extensions/files_repo/files_repo_list.php
@@ -0,0 +1,91 @@
+<?php
+
+// Pandora FMS - http://pandorafms.com
+// ==================================================
+// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
+// Please see http://pandorafms.org for full contribution list
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+global $config;
+
+$full_extensions_dir = $config['homedir'].DIRECTORY_SEPARATOR.EXTENSIONS_DIR.DIRECTORY_SEPARATOR;
+require_once ($full_extensions_dir."files_repo".DIRECTORY_SEPARATOR."functions_files_repo.php");
+
+$offset = (int) get_parameter('offset');
+$filter = array();
+$filter['limit'] = $config['block_size'];
+$filter['offset'] = $offset;
+$filter['order'] = array('field' => 'id', 'order' => 'DESC');
+$files = files_repo_get_files($filter);
+
+if (!empty($files)) {
+
+	echo "<br>";
+
+	// Pagination
+	if ($manage) {
+		$url = ui_get_full_url("index.php?sec=gextensions&sec2=extensions/files_repo");
+	} else {
+		$url = ui_get_full_url("index.php?sec=extensions&sec2=extensions/files_repo");
+	}
+	$total_files = files_repo_get_files(false, true);
+	ui_pagination($total_files, $url, $offset);
+
+	$table = new stdClass();
+	$table->width = '98%';
+	$table->style = array();
+	$table->style[1] = "max-width: 200px;";
+	$table->style[2] = "text-align: center;";
+	$table->style[3] = "text-align: center;";
+	$table->style[4] = "text-align: center;";
+	$table->head = array();
+	$table->head[0] = __("Name");
+	$table->head[1] = __("Description");
+	$table->head[2] = __("Size");
+	$table->head[3] = __("Last modification");
+	$table->head[4] = "";
+	$table->data = array();
+
+	foreach ($files as $file_id => $file) {
+		$data = array();
+
+		// Prepare the filename for the get_file.php script
+		$relative_path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $file['location']);
+		$file_path = base64_encode($relative_path);
+		$hash = md5($relative_path . $config['dbpass']);
+		$url = ui_get_full_url("include/get_file.php?file=$file_path&hash=$hash");
+
+		$data[0] = "<a href=\"$url\" target=\"_blank\">" . $file['name'] . "</a>"; // Name
+		$data[1] = $file['description']; // Description
+		$data[2] = ui_format_filesize($file['size']); // Size
+		$data[3] = date('F j, Y - H:m', $file['mtime']); // Last modification
+		$data[4] = "<a href=\"$url\" target=\"_blank\">";
+		$data[4] .= html_print_image('images/download.png', true, array('title' => __('Download'))); // Download image
+		$data[4] .= "</a>";
+		if ($manage) {
+			$url = ui_get_full_url("index.php?sec=gextensions&sec2=extensions/files_repo&file_id=$file_id");
+			$data[4] .= " <a href=\"$url\">";
+			$data[4] .= html_print_image('images/config.png', true, array('title' => __('Edit'))); // Edit image
+			$data[4] .= "</a>";
+			$url = ui_get_full_url("index.php?sec=gextensions&sec2=extensions/files_repo&delete=1&file_id=$file_id");
+			$data[4] .= " <a href=\"$url\" onClick=\"if (!confirm('".__('Are you sure?')."')) return false;\">";
+			$data[4] .= html_print_image('images/cross.png', true, array('title' => __('Delete'))); // Delete image
+			$data[4] .= "</a>";
+		}
+		$table->data[] = $data;
+	}
+	html_print_table($table);
+
+} else {
+	ui_print_info_message(__('No items'));
+}
+
+?>
\ No newline at end of file
diff --git a/pandora_console/extensions/files_repo/functions_files_repo.php b/pandora_console/extensions/files_repo/functions_files_repo.php
new file mode 100644
index 0000000000..d621694a6b
--- /dev/null
+++ b/pandora_console/extensions/files_repo/functions_files_repo.php
@@ -0,0 +1,279 @@
+<?php
+
+// Pandora FMS - http://pandorafms.com
+// ==================================================
+// Copyright (c) 2005-2011 Artica Soluciones Tecnologicas
+// Please see http://pandorafms.org for full contribution list
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+
+function files_repo_check_directory ($print_messages = false) {
+	global $config;
+
+	$attachment_path = realpath($config['attachment_store']);
+	$files_repo_path = $attachment_path.DIRECTORY_SEPARATOR."files_repo";
+
+	$result = false;
+	$messages = "";
+
+	// attachment/ check
+	if (!is_writable($attachment_path)) {
+		$messages .= ui_print_error_message(array('message' => __('Attachment directory is not writable by HTTP Server')
+			.'</h3>'.'<p>'.__('Please check that the web server has write rights on the {HOMEDIR}/attachment directory'),
+				'no_close' => true, 'force_style' => 'color: #000000 !important'), '', true);
+	} else {
+		// attachment/agent_packages/ check
+		if (!file_exists($files_repo_path) || !is_writable($files_repo_path)) {
+			// Create the directoty if not exist
+			if (!file_exists($files_repo_path)) {
+				mkdir($files_repo_path);
+			}
+			if (!is_writable($files_repo_path)) {
+				$messages .= ui_print_error_message(array('message' => __('Attachment directory is not writable by HTTP Server')
+					.'</h3>'.'<p>'.__('Please check that the web server has write rights on the {HOMEDIR}/attachment directory'),
+						'no_close' => true, 'force_style' => 'color: #000000 !important'), '', true);
+			} else {
+				$result = true;
+			}
+		} else {
+			$result = true;
+		}
+	}
+
+	if ($print_messages) {
+		echo $messages;
+	}
+	return $result;
+}
+
+function files_repo_check_file_acl ($file_id, $user_id = false, $file_groups = false, $user_groups = false) {
+	global $config;
+
+	$result = false;
+	if (!$user_id) {
+		$user_id = $config['id_user'];
+	}
+	if (is_user_admin($user_id)) {
+		return true;
+	}
+	if (!$file_groups) {
+		$file_groups = files_repo_get_file_groups($file_id);
+		if (empty($file_groups)) {
+			$file_groups = array();
+		}
+	}
+	if (!$user_groups) {
+		$user_groups = users_get_groups ($user_id, false, true);
+		if (empty($user_groups)) {
+			$user_groups = array();
+		}
+	}
+
+	foreach ($file_groups as $group_id) {
+		// $user_groups has the id in the array keys
+		if (in_array($group_id, $user_groups)) {
+			$result = true;
+			break;
+		}
+	}
+	
+	return $result;
+}
+
+function files_repo_get_file_groups ($file_id) {
+
+	$groups = array();
+	$filter = array('id_file' => $file_id);
+	$result = db_get_all_rows_filter("tfiles_repo_group", $filter, "id_group");
+
+	if (!empty($result)) {
+		foreach ($result as $key => $value) {
+			$groups[] = $value['id_group'];
+		}
+	}
+
+	return $groups;
+}
+
+function files_repo_get_user_groups ($user_id) {
+
+	$groups = array();
+	$filter = array('id_usuario' => $user_id);
+	$result = db_get_all_rows_filter("tusuario_perfil", $filter, "id_grupo");
+
+	if (!empty($result)) {
+		foreach ($result as $key => $value) {
+			$groups[] = $value['id_grupo'];
+		}
+	}
+
+	return $groups;
+}
+
+function files_repo_get_files ($filter = false, $count = false) {
+	global $config;
+
+	// Don't use the realpath for the download links!
+	$files_repo_path = $config['attachment_store'].DIRECTORY_SEPARATOR."files_repo";
+
+	$sql = "SELECT * FROM tfiles_repo " . db_format_array_where_clause_sql($filter, "AND", "WHERE");
+	$files = db_get_all_rows_sql($sql);
+
+	if ($files === false)
+		$files = array();
+
+	$user_groups = files_repo_get_user_groups($config['id_user']);
+
+	$files_data = array();
+	foreach ($files as $file) {
+
+		$file_groups = files_repo_get_file_groups($file['id']);
+		$permission = files_repo_check_file_acl ($file['id'], $config['id_user'], $file_groups, $user_groups);
+		if (!$permission) {
+			continue;
+		}
+
+		$data = array();
+		$data['name'] = $file['name'];
+		$data['description'] = $file['description'];
+		$data['location'] = $files_repo_path.DIRECTORY_SEPARATOR.$file['id']."_".$data['name'];
+		// Size in bytes
+		$data['size'] = filesize($data['location']);
+		// Last modification time in unix timestamp
+		$data['mtime'] = filemtime($data['location']);
+		$data['groups'] = $file_groups;
+		$files_data[$file['id']] = $data;
+	}
+
+	if ($count) {
+		$files_data = count($files_data);
+	}
+	
+	return $files_data;
+}
+
+function files_repo_add_file ($file_input_name = "upfile", $description = "", $groups = array()) {
+	global $config;
+
+	$attachment_path = realpath($config['attachment_store']);
+	$files_repo_path = $attachment_path.DIRECTORY_SEPARATOR."files_repo";
+
+	$result = array();
+	$result["status"] = false;
+	$result["message"] = "";
+
+	$upload_status = get_file_upload_status($file_input_name);
+	$upload_result = translate_file_upload_status($upload_status);
+
+	if ($upload_result === true) {
+		$filename = $_FILES[$file_input_name]['name'];
+		// Replace conflictive characters
+		$filename = str_replace (array(" ", "=", "?", "&"), "_", $filename);
+		$filename = filter_var($filename, FILTER_SANITIZE_URL);
+		// The filename should not be larger than 200 characters
+		if (mb_strlen($filename, "UTF-8") > 200) {
+			$filename = mb_substr($filename, 0, 200, "UTF-8");
+		}
+
+		$values = array(
+				'name' => $filename,
+				'description' => $description
+			);
+		$file_id = db_process_sql_insert('tfiles_repo', $values);
+
+		if ($file_id) {
+			
+			$file_tmp = $_FILES[$file_input_name]['tmp_name'];
+			$destination = $files_repo_path.DIRECTORY_SEPARATOR.$file_id."_".$filename;
+			
+			if (move_uploaded_file($file_tmp, $destination)) {
+
+				if (is_array($groups) && !empty($groups)) {
+					db_process_sql_delete('tfiles_repo_group', array('id_file' => $file_id));
+					foreach ($groups as $group) {
+						$values = array(
+								'id_file' => $file_id,
+								'id_group' => $group
+							);
+						db_process_sql_insert('tfiles_repo_group', $values);
+					}
+				}
+				
+				$result["status"] = true;
+			} else {
+				db_process_sql_delete('tfiles_repo', array('id' => $file_id));
+				unlink ($file_tmp);
+				$result["message"] = __('The file could not be copied');
+			}
+			
+		} else {
+			$result["message"] = __('There was an error creating the file');
+		}
+	} else {
+		$result["message"] = $upload_result;
+	}
+
+	return $result;
+}
+
+function files_repo_update_file ($file_id, $description = "", $groups = array()) {
+	global $config;
+
+	$result = array();
+	$result["status"] = false;
+	$result["message"] = "";
+
+	$values = array('description' => $description);
+	$filter = array('id' => $file_id);
+	$res = db_process_sql_update('tfiles_repo', $values, $filter);
+	if ($res !== false) {
+		if (is_array($groups) && !empty($groups)) {
+			db_process_sql_delete('tfiles_repo_group', array('id_file' => $file_id));
+			foreach ($groups as $group) {
+				$values = array(
+						'id_file' => $file_id,
+						'id_group' => $group
+					);
+				db_process_sql_insert('tfiles_repo_group', $values);
+			}
+		}
+		$result["status"] = true;
+	} else {
+		$result["message"] = __('There was an error updating the file');
+	}
+
+	return $result;
+}
+
+function files_repo_delete_file ($file_id) {
+	global $config;
+
+	$result = -1;
+
+	$filename = db_get_value("name", "tfiles_repo", "id", $file_id);
+
+	if ($filename) {
+		$attachment_path = realpath($config['attachment_store']);
+		$files_repo_path = $attachment_path.DIRECTORY_SEPARATOR."files_repo";
+		$location = $files_repo_path.DIRECTORY_SEPARATOR.$file_id."_".$filename;
+
+		if (file_exists($location)) {
+			$result = false;
+			if (unlink($location)) {
+				$result = (bool) db_process_sql_delete('tfiles_repo', array('id' => $file_id));
+			}
+		}
+	}
+	
+	return $result;
+}
+
+?>
\ No newline at end of file
diff --git a/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql b/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql
new file mode 100644
index 0000000000..a3bab6f01d
--- /dev/null
+++ b/pandora_console/extensions/files_repo/sql/files_repo.oracle.sql
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS tfiles_repo (id NUMBER(5, 0) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, description VARCHAR(500) default '');
+CREATE SEQUENCE tfiles_repo_s INCREMENT BY 1 START WITH 1;
+CREATE OR REPLACE TRIGGER tfiles_repo_inc BEFORE INSERT ON tfiles_repo REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tfiles_repo_s.nextval INTO :NEW.ID FROM dual; END;;
+CREATE TABLE IF NOT EXISTS tfiles_repo_group (id NUMBER(10, 0) NOT NULL PRIMARY KEY, id_file NUMBER(5, 0) NOT NULL REFERENCES tfiles_repo(id) ON DELETE CASCADE, id_group NUMBER(4, 0) NOT NULL);
+CREATE SEQUENCE tfiles_repo_profile_s INCREMENT BY 1 START WITH 1;
+CREATE OR REPLACE TRIGGER tfiles_repo_group_inc BEFORE INSERT ON tfiles_repo_group REFERENCING NEW AS NEW FOR EACH ROW BEGIN SELECT tfiles_repo_group_s.nextval INTO :NEW.ID FROM dual; END;;
\ No newline at end of file
diff --git a/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql b/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql
new file mode 100644
index 0000000000..5255a55d82
--- /dev/null
+++ b/pandora_console/extensions/files_repo/sql/files_repo.postgreSQL.sql
@@ -0,0 +1,2 @@
+CREATE TABLE IF NOT EXISTS "tfiles_repo" ("id" SERIAL NOT NULL PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "description" VARCHAR(500) NULL default '');
+CREATE TABLE IF NOT EXISTS "tfiles_repo_group" ("id" SERIAL NOT NULL PRIMARY KEY, "id_file" INTEGER NOT NULL REFERENCES tfiles_repo("id") ON DELETE CASCADE, "id_group" INTEGER NOT NULL);
\ No newline at end of file
diff --git a/pandora_console/extensions/files_repo/sql/files_repo.sql b/pandora_console/extensions/files_repo/sql/files_repo.sql
new file mode 100644
index 0000000000..29b7a6ef8d
--- /dev/null
+++ b/pandora_console/extensions/files_repo/sql/files_repo.sql
@@ -0,0 +1,2 @@
+CREATE TABLE IF NOT EXISTS `tfiles_repo` (`id` int(5) unsigned NOT NULL auto_increment, `name` varchar(255) NOT NULL, `description` varchar(500) NULL default '', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE IF NOT EXISTS `tfiles_repo_group` (`id` int(10) unsigned NOT NULL auto_increment, `id_file` int(5) unsigned NOT NULL, `id_group` int(4) unsigned NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`id_file`) REFERENCES tfiles_repo(`id`) ON DELETE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8;
\ No newline at end of file
diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php
index e0b4f781fc..031ac86a8a 100644
--- a/pandora_console/include/functions.php
+++ b/pandora_console/include/functions.php
@@ -1968,4 +1968,50 @@ function can_user_access_node () {
 		return 1;
 	}
 }
+
+/**
+ *  Get the upload status code
+ */
+function get_file_upload_status ($file_input_name) {
+	return $_FILES[$file_input_name]['error'];
+}
+
+/**
+ *  Get a human readable message with the upload status code
+ */
+function translate_file_upload_status ($status_code) {
+	switch ($status_code) {
+		case UPLOAD_ERR_OK:
+			$message = true;
+			break;
+		case UPLOAD_ERR_INI_SIZE:
+			$message = __('The file exceeds the maximum size');
+			break;
+		case UPLOAD_ERR_FORM_SIZE:
+			$message = __('The file exceeds the maximum size');
+			break;
+		case UPLOAD_ERR_PARTIAL:
+			$message = __('The uploaded file was only partially uploaded');
+			break;
+		case UPLOAD_ERR_NO_FILE:
+			$message = __('No file was uploaded');
+			break;
+		case UPLOAD_ERR_NO_TMP_DIR:
+			$message = __('Missing a temporary folder');
+			break;
+		case UPLOAD_ERR_CANT_WRITE:
+			$message = __('Failed to write file to disk');
+			break;
+		case UPLOAD_ERR_EXTENSION:
+			$message = __('File upload stopped by extension');
+			break;
+		
+		default:
+			$message = __('Unknown upload error');
+			break;
+	}
+	
+	return $message;
+}
+
 ?>