[glom/glom-1-20] Add test_selfhosting_new_empty_then_users
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom/glom-1-20] Add test_selfhosting_new_empty_then_users
- Date: Mon, 6 Feb 2012 09:17:08 +0000 (UTC)
commit 87d4d8007fdcec79a8b575f7acdd99998a126f06
Author: Murray Cumming <murrayc murrayc com>
Date: Wed Feb 1 10:42:52 2012 +0100
Add test_selfhosting_new_empty_then_users
* glom/mode_design/users/dialog_groups_list.cc: on_button_group_new():
Move the group creation code to:
* glom/libglom/db_utils.[h|cc]:
* glom/libglom/privs.[h|cc]: set_table_privileges():
Return a bool to report failures.
* Makefile_tests.am:
* tests/test_selfhosting_new_empty_then_users.cc: Add this test to
test simple creation of a group and a user.
Conflicts:
Makefile_tests.am
glom/libglom/db_utils.cc
glom/libglom/db_utils.h
ChangeLog | 14 +++
Makefile_tests.am | 6 +
glom/libglom/db_utils.cc | 115 +++++++++++++++++++++
glom/libglom/db_utils.h | 15 +++
glom/libglom/privs.cc | 29 +++--
glom/libglom/privs.h | 2 +-
glom/mode_design/users/dialog_groups_list.cc | 30 ++----
tests/test_selfhosting_new_empty_then_users.cc | 130 ++++++++++++++++++++++++
8 files changed, 307 insertions(+), 34 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c61f587..405bf40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2012-02-01 Murray Cumming <murrayc murrayc com>
+ Add test_selfhosting_new_empty_then_users
+
+ * glom/mode_design/users/dialog_groups_list.cc: on_button_group_new():
+ Move the group creation code to:
+ * glom/libglom/db_utils.[h|cc]:
+
+ * glom/libglom/privs.[h|cc]: set_table_privileges():
+ Return a bool to report failures.
+ * Makefile_tests.am:
+ * tests/test_selfhosting_new_empty_then_users.cc: Add this test to
+ test simple creation of a group and a user.
+
+2012-02-01 Murray Cumming <murrayc murrayc com>
+
Fix the build.
* glom/mode_design/users/dialog_new_group.cc:
diff --git a/Makefile_tests.am b/Makefile_tests.am
index be8a3e0..35f67f3 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -33,6 +33,7 @@ check_PROGRAMS = \
tests/python/test_python_module \
tests/test_fake_connection \
tests/test_selfhosting_new_empty \
+ tests/test_selfhosting_new_empty_then_users \
tests/test_selfhosting_new_from_example \
tests/test_selfhosting_new_from_example_strangepath \
tests/test_selfhosting_new_then_report \
@@ -61,6 +62,7 @@ TESTS = tests/test_document_load \
tests/python/test_python_module \
tests/test_fake_connection \
tests/test_selfhosting_new_empty \
+ tests/test_selfhosting_new_empty_then_users \
tests/test_selfhosting_new_from_example \
tests/test_selfhosting_new_from_example_in_locales.sh \
tests/test_selfhosting_new_from_example_strangepath \
@@ -182,6 +184,10 @@ tests_test_selfhosting_new_empty_SOURCES = tests/test_selfhosting_new_empty.cc
tests_test_selfhosting_new_empty_LDADD = $(tests_ldadd)
tests_test_selfhosting_new_empty_CPPFLAGS = $(tests_cppflags)
+tests_test_selfhosting_new_empty_then_users_SOURCES = tests/test_selfhosting_new_empty_then_users.cc $(sources_test_selfhosting_utils)
+tests_test_selfhosting_new_empty_then_users_LDADD = $(tests_ldadd)
+tests_test_selfhosting_new_empty_then_users_CPPFLAGS = $(tests_cppflags)
+
tests_test_selfhosting_new_from_example_SOURCES = tests/test_selfhosting_new_from_example.cc $(sources_test_selfhosting_utils)
tests_test_selfhosting_new_from_example_LDADD = $(tests_ldadd)
tests_test_selfhosting_new_from_example_CPPFLAGS = $(tests_cppflags)
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 46c9fd8..9af4813 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -1933,6 +1933,121 @@ Glib::ustring build_query_add_user_to_group(const Glib::ustring& group, const Gl
return "ALTER GROUP " + escape_sql_id(group) + " ADD USER " + escape_sql_id(user);
}
+static Glib::ustring build_query_add_user(const Glib::ustring& user, const Glib::ustring& password, bool superuser)
+{
+ if(user.empty())
+ {
+ std::cerr << G_STRFUNC << ": user is empty" << std::endl;
+ }
+
+ if(password.empty())
+ {
+ std::cerr << G_STRFUNC << ": password is empty" << std::endl;
+ }
+
+ //Note that ' around the user fails, so we use ".
+ Glib::ustring strQuery = "CREATE USER " + DbUtils::escape_sql_id(user) + " PASSWORD '" + password + "'" ; //TODO: Escape the password.
+ if(superuser)
+ strQuery += " SUPERUSER CREATEDB CREATEROLE"; //Because SUPERUSER is not "inherited" from groups to members.
+
+ return strQuery;
+}
+
+bool add_user(const Document* document, const Glib::ustring& user, const Glib::ustring& password, const Glib::ustring& group)
+{
+ if(!document)
+ {
+ std::cerr << G_STRFUNC << ": document is null." << std::endl;
+ return false;
+ }
+
+ if(user.empty() || password.empty() || group.empty())
+ {
+ std::cerr << G_STRFUNC << ": user, password, or group are empty." << std::endl;
+ return false;
+ }
+
+ //Create the user:
+ const bool superuser = (group == GLOM_STANDARD_GROUP_NAME_DEVELOPER);
+ const Glib::ustring query_add = build_query_add_user(user, password, superuser);
+ bool test = DbUtils::query_execute_string(query_add);
+ if(!test)
+ {
+ std::cerr << G_STRFUNC << ": CREATE USER failed." << std::endl;
+ return false;
+ }
+
+ //Add it to the group:
+ const Glib::ustring query_add_to_group = build_query_add_user_to_group(group, user);
+ test = DbUtils::query_execute_string(query_add_to_group);
+ if(!test)
+ {
+ std::cerr << G_STRFUNC << ": ALTER GROUP failed." << std::endl;
+ return false;
+ }
+
+ //Remove any user rights, so that all rights come from the user's presence in the group:
+ Document::type_listTableInfo table_list = document->get_tables();
+
+ for(Document::type_listTableInfo::const_iterator iter = table_list.begin(); iter != table_list.end(); ++iter)
+ {
+ const Glib::ustring table_name = (*iter)->get_name();
+ const Glib::ustring strQuery = "REVOKE ALL PRIVILEGES ON " + DbUtils::escape_sql_id(table_name) + " FROM " + DbUtils::escape_sql_id(user);
+ const bool test = DbUtils::query_execute_string(strQuery);
+ if(!test)
+ std::cerr << G_STRFUNC << ": REVOKE failed." << std::endl;
+ }
+
+ return true;
+}
+
+bool add_group(const Document* document, const Glib::ustring& group)
+{
+ if(!document)
+ {
+ std::cerr << G_STRFUNC << ": document is null." << std::endl;
+ return false;
+ }
+
+ if(group.empty())
+ {
+ std::cerr << G_STRFUNC << ": group is empty." << std::endl;
+ return false;
+ }
+
+ const Glib::ustring strQuery = DbUtils::build_query_create_group(group);
+ const bool test = DbUtils::query_execute_string(strQuery);
+ if(!test)
+ {
+ std::cerr << G_STRFUNC << ": CREATE GROUP failed." << std::endl;
+ return false;
+ }
+
+ //Give the new group some sensible default privileges:
+ Privileges priv;
+ priv.m_view = true;
+ priv.m_edit = true;
+
+ Document::type_listTableInfo table_list = document->get_tables(true /* plus system prefs */);
+ for(Document::type_listTableInfo::const_iterator iter = table_list.begin(); iter != table_list.end(); ++iter)
+ {
+ if(!Privs::set_table_privileges(group, (*iter)->get_name(), priv))
+ {
+ std::cerr << G_STRFUNC << "Privs::set_table_privileges() failed." << std::endl;
+ return false;
+ }
+ }
+
+ //Let them edit the autoincrements too:
+ if(!Privs::set_table_privileges(group, GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME, priv))
+ {
+ std::cerr << G_STRFUNC << "Privs::set_table_privileges() failed." << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
void set_fake_connection()
{
//Allow a fake connection, so sqlbuilder_get_full_query() can work:
diff --git a/glom/libglom/db_utils.h b/glom/libglom/db_utils.h
index 85d8805..3915d6a 100644
--- a/glom/libglom/db_utils.h
+++ b/glom/libglom/db_utils.h
@@ -163,6 +163,21 @@ Glib::ustring build_query_create_group(const Glib::ustring& group, bool superuse
Glib::ustring build_query_add_user_to_group(const Glib::ustring& group, const Glib::ustring& user);
+/** Add a @a user to the database, with the specified @a password, in the specified @a group.
+ * @result true if the addition succeeded.
+ */
+bool add_user(const Document* document, const Glib::ustring& user, const Glib::ustring& password, const Glib::ustring& group);
+
+/** Add a @a group to the database.
+ * @result true if the addition succeeded.
+ */
+bool add_group(const Document* document, const Glib::ustring& group);
+
+
+/** Get the value of the @a source_field from the @a relationship, using the @a key_value.
+ */
+Gnome::Gda::Value get_lookup_value(Document* document, const Glib::ustring& table_name, const sharedptr<const Relationship>& relationship, const sharedptr<const Field>& source_field, const Gnome::Gda::Value & key_value);
+
/** Allow a fake connection, so sqlbuilder_get_full_query() can work.
*/
void set_fake_connection();
diff --git a/glom/libglom/privs.cc b/glom/libglom/privs.cc
index 4e4081c..6d65171 100644
--- a/glom/libglom/privs.cc
+++ b/glom/libglom/privs.cc
@@ -179,10 +179,12 @@ Privs::type_vec_strings Privs::get_database_users(const Glib::ustring& group_nam
return result;
}
-void Privs::set_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name, const Privileges& privs, bool developer_privs)
+bool Privs::set_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name, const Privileges& privs, bool developer_privs)
{
if(group_name.empty() || table_name.empty())
- return;
+ {
+ return false;
+ }
//Change the permission in the database:
@@ -237,19 +239,22 @@ void Privs::set_table_privileges(const Glib::ustring& group_name, const Glib::us
const bool test = DbUtils::query_execute_string(strQuery);
if(!test)
+ {
std::cerr << G_STRFUNC << ": GRANT failed." << std::endl;
- else
+ return false;
+ }
+
+ if( (table_name != GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME) && privs.m_create )
{
- if( (table_name != GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME) && privs.m_create )
- {
- //To create a record, you will usually need write access to the autoincrements table,
- //so grant this too:
- Privileges priv_autoincrements;
- priv_autoincrements.m_view = true;
- priv_autoincrements.m_edit = true;
- set_table_privileges(group_name, GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME, priv_autoincrements);
- }
+ //To create a record, you will usually need write access to the autoincrements table,
+ //so grant this too:
+ Privileges priv_autoincrements;
+ priv_autoincrements.m_view = true;
+ priv_autoincrements.m_edit = true;
+ return set_table_privileges(group_name, GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME, priv_autoincrements);
}
+
+ return true;
}
Privileges Privs::get_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name)
diff --git a/glom/libglom/privs.h b/glom/libglom/privs.h
index 5fec4c8..38d97d7 100644
--- a/glom/libglom/privs.h
+++ b/glom/libglom/privs.h
@@ -70,7 +70,7 @@ public:
static Glib::ustring get_default_developer_user_name(Glib::ustring& password);
static Privileges get_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name);
- static void set_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name, const Privileges& privs, bool developer_privs = false);
+ static bool set_table_privileges(const Glib::ustring& group_name, const Glib::ustring& table_name, const Privileges& privs, bool developer_privs = false);
static Glib::ustring get_user_visible_group_name(const Glib::ustring& group_name);
diff --git a/glom/mode_design/users/dialog_groups_list.cc b/glom/mode_design/users/dialog_groups_list.cc
index dc34bc7..26cd621 100644
--- a/glom/mode_design/users/dialog_groups_list.cc
+++ b/glom/mode_design/users/dialog_groups_list.cc
@@ -253,30 +253,18 @@ void Dialog_GroupsList::on_button_group_new()
if(response != Gtk::RESPONSE_OK)
return;
- if(!group_name.empty())
+ if(group_name.empty())
{
- const Glib::ustring strQuery = DbUtils::build_query_create_group(group_name);
- const bool test = DbUtils::query_execute_string(strQuery);
- if(!test)
- std::cout << "debug: " << G_STRFUNC << ": CREATE GROUP failed." << std::endl;
-
- //Give the new group some sensible default privileges:
- Privileges priv;
- priv.m_view = true;
- priv.m_edit = true;
-
- Document::type_listTableInfo table_list = get_document()->get_tables(true /* plus system prefs */);
-
- for(Document::type_listTableInfo::const_iterator iter = table_list.begin(); iter != table_list.end(); ++iter)
- {
- Privs::set_table_privileges(group_name, (*iter)->get_name(), priv);
- }
-
- //Let them edit the autoincrements too:
- Privs::set_table_privileges(group_name, GLOM_STANDARD_TABLE_AUTOINCREMENTS_TABLE_NAME, priv);
+ std::cerr << ": group_name is empty" << std::endl;
+ return;
+ }
- fill_group_list();
+ if(!DbUtils::add_group(get_document(), group_name))
+ {
+ std::cerr << ": DbUtils::add_group() failed." << std::endl;
}
+
+ fill_group_list();
}
void Dialog_GroupsList::on_button_group_users()
diff --git a/tests/test_selfhosting_new_empty_then_users.cc b/tests/test_selfhosting_new_empty_then_users.cc
new file mode 100644
index 0000000..21ae210
--- /dev/null
+++ b/tests/test_selfhosting_new_empty_then_users.cc
@@ -0,0 +1,130 @@
+/* Glom
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * 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; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+71 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "tests/test_selfhosting_utils.h"
+#include <libglom/init.h>
+#include <libglom/utils.h>
+#include <libglom/db_utils.h>
+#include <libglom/connectionpool.h>
+#include <libglom/privs.h>
+#include <glib.h> //For g_assert()
+#include <iostream>
+#include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
+
+template<typename T_Container, typename T_Value>
+bool contains(const T_Container& container, const T_Value& name)
+{
+ typename T_Container::const_iterator iter =
+ std::find(container.begin(), container.end(), name);
+ return iter != container.end();
+}
+
+static bool test(Glom::Document::HostingMode hosting_mode)
+{
+ //Create and self-host the document:
+ Glom::Document document;
+ if(!(test_create_and_selfhost_new_database(document, hosting_mode, "test_db")))
+ {
+ std::cerr << "test_create_and_selfhost_new_database() failed" << std::endl;
+ return false;
+ }
+
+ //Check that only one group exists (the developer group):
+ const Glom::Privs::type_vec_strings group_list_original = Glom::Privs::get_database_groups();
+ if(group_list_original.empty())
+ {
+ std::cerr << "Privs::get_database_groups() returned an empty list." << std::endl;
+ return false;
+ }
+
+ if(!contains(group_list_original, GLOM_STANDARD_GROUP_NAME_DEVELOPER))
+ {
+ std::cerr << "Privs::get_database_groups() does not contain the developers group." << std::endl;
+ return false;
+ }
+
+ //Add a group:
+ const Glib::ustring group_name = "somegroup";
+ if(!Glom::DbUtils::add_group(&document, group_name))
+ {
+ std::cerr << "DbUtils::add_group() failed." << std::endl;
+ test_selfhosting_cleanup();
+ return false;
+ }
+
+ const Glom::Privs::type_vec_strings group_list_after = Glom::Privs::get_database_groups();
+ if(group_list_after.size() <= group_list_original.size())
+ {
+ std::cerr << "The new group list is not larger than the old group list." << std::endl;
+ return false;
+ }
+
+ const Glom::Privs::type_vec_strings user_list_original = Glom::Privs::get_database_users(group_name);
+ if(!user_list_original.empty())
+ {
+ std::cerr << "The user list is not empty as expected.." << std::endl;
+ return false;
+ }
+
+ //Add an operator user, adding it to the group:
+ if(!Glom::DbUtils::add_user(&document, "someuser", "somepassword", group_name))
+ {
+ std::cerr << "DbUtils::add_user() failed." << std::endl;
+ test_selfhosting_cleanup();
+ return false;
+ }
+
+ const Glom::Privs::type_vec_strings user_list_after = Glom::Privs::get_database_users(group_name);
+ if(user_list_after.size() != 1)
+ {
+ std::cerr << "The user list has an unexpected size: " << user_list_after.size() << std::endl;
+ return false;
+ }
+
+ test_selfhosting_cleanup(false /* do not delete the file. */);
+
+ return true;
+}
+
+int main()
+{
+ Glom::libglom_init();
+
+ if(!test(Glom::Document::HOSTING_MODE_POSTGRES_SELF))
+ {
+ std::cerr << "Failed with PostgreSQL" << std::endl;
+ test_selfhosting_cleanup();
+ return EXIT_FAILURE;
+ }
+
+ /* SQLite does not have user/group access levels,
+ * so the SQL queries woudl fail.
+ if(!test(Glom::Document::HOSTING_MODE_SQLITE))
+ {
+ std::cerr << "Failed with SQLite" << std::endl;
+ test_selfhosting_cleanup();
+ return EXIT_FAILURE;
+ }
+ */
+
+ Glom::libglom_deinit();
+
+ return EXIT_SUCCESS;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]