1
0
mirror of https://github.com/haiwen/ccnet-server.git synced 2025-09-13 05:25:26 +00:00

Support multi-tier groups.

This commit is contained in:
“cuihaikuo”
2017-12-21 17:41:26 +08:00
parent 078d115530
commit 00e3d9eb45
7 changed files with 160 additions and 28 deletions

View File

@@ -47,6 +47,9 @@ public class Group : Object {
public string creator_name { get; set; }
public int64 timestamp { get; set; }
public string source { get; set; }
public int parent_group_id { get; set; }
public bool is_direct { get; set; }
}
public class GroupUser : Object {

View File

@@ -10,6 +10,7 @@ func_table = [
[ "int", ["int", "string"] ],
[ "int", ["int", "string", "int"] ],
[ "int", ["int", "string", "string"] ],
[ "int", ["int", "string", "string", "int"] ],
[ "int", ["int", "string", "int", "int"] ],
[ "int", ["string"] ],
[ "int", ["string", "int"] ],
@@ -18,6 +19,7 @@ func_table = [
[ "int", ["string", "int", "string", "int", "int"] ],
[ "int", ["string", "string"] ],
[ "int", ["string", "string", "string"] ],
[ "int", ["string", "string", "string", "int"] ],
[ "int", ["string", "string", "int"] ],
[ "int", ["string", "string", "int", "int"] ],
[ "int", ["string", "string", "string", "string"] ],

View File

@@ -211,11 +211,11 @@ ccnet_start_rpc(CcnetSession *session)
searpc_server_register_function ("ccnet-threaded-rpcserver",
ccnet_rpc_create_group,
"create_group",
searpc_signature_int__string_string_string());
searpc_signature_int__string_string_string_int());
searpc_server_register_function ("ccnet-threaded-rpcserver",
ccnet_rpc_create_org_group,
"create_org_group",
searpc_signature_int__int_string_string());
searpc_signature_int__int_string_string_int());
searpc_server_register_function ("ccnet-threaded-rpcserver",
ccnet_rpc_remove_group,
"remove_group",
@@ -930,7 +930,7 @@ ccnet_rpc_verify_message (const char *message,
int
ccnet_rpc_create_group (const char *group_name, const char *user_name,
const char *type, GError **error)
const char *type, int parent_group_id, GError **error)
{
CcnetGroupManager *group_mgr =
((CcnetServerSession *)session)->group_mgr;
@@ -942,14 +942,14 @@ ccnet_rpc_create_group (const char *group_name, const char *user_name,
return -1;
}
ret = ccnet_group_manager_create_group (group_mgr, group_name, user_name, error);
ret = ccnet_group_manager_create_group (group_mgr, group_name, user_name, parent_group_id, error);
return ret;
}
int
ccnet_rpc_create_org_group (int org_id, const char *group_name,
const char *user_name, GError **error)
const char *user_name, int parent_group_id, GError **error)
{
CcnetGroupManager *group_mgr =
((CcnetServerSession *)session)->group_mgr;
@@ -961,7 +961,7 @@ ccnet_rpc_create_org_group (int org_id, const char *group_name,
}
ret = ccnet_group_manager_create_org_group (group_mgr, org_id,
group_name, user_name, error);
group_name, user_name, parent_group_id, error);
return ret;
}
@@ -979,7 +979,7 @@ ccnet_rpc_remove_group (int group_id, GError **error)
return -1;
}
ret = ccnet_group_manager_remove_group (group_mgr, group_id, error);
ret = ccnet_group_manager_remove_group (group_mgr, group_id, FALSE, error);
return ret;
@@ -1259,7 +1259,7 @@ ccnet_rpc_remove_org (int org_id, GError **error)
group_ids = ccnet_org_manager_get_org_group_ids (org_mgr, org_id, 0, INT_MAX);
ptr = group_ids;
while (ptr) {
ccnet_group_manager_remove_group (group_mgr, (int)(long)ptr->data, error);
ccnet_group_manager_remove_group (group_mgr, (int)(long)ptr->data, TRUE, error);
ptr = ptr->next;
}
g_list_free (group_ids);

View File

@@ -181,11 +181,11 @@ ccnet_rpc_verify_message (const char *message,
int
ccnet_rpc_create_group (const char *group_name, const char *user_name,
const char *type, GError **error);
const char *type, int parent_group_id, GError **error);
int
ccnet_rpc_create_org_group (int org_id, const char *group_name,
const char *user_name, GError **error);
const char *user_name, int parent_group_id, GError **error);
int
ccnet_rpc_remove_group (int group_id, GError **error);

View File

@@ -11,6 +11,8 @@
#include "utils.h"
#include "log.h"
extern CcnetSession *session;
struct _CcnetGroupManagerPriv {
CcnetDB *db;
const char *table_name;
@@ -105,7 +107,7 @@ static int check_db_table (CcnetGroupManager *manager, CcnetDB *db)
"CREATE TABLE IF NOT EXISTS `%s` (`group_id` INTEGER"
" PRIMARY KEY AUTO_INCREMENT, `group_name` VARCHAR(255),"
" `creator_name` VARCHAR(255), `timestamp` BIGINT,"
" `type` VARCHAR(32))"
" `type` VARCHAR(32), `parent_group_id` INTEGER)"
"ENGINE=INNODB", table_name);
if (ccnet_db_query (db, group_sql->str) < 0) {
g_string_free (group_sql, TRUE);
@@ -190,6 +192,7 @@ static int
create_group_common (CcnetGroupManager *mgr,
const char *group_name,
const char *user_name,
int parent_group_id,
GError **error)
{
CcnetDB *db = mgr->priv->db;
@@ -203,15 +206,15 @@ create_group_common (CcnetGroupManager *mgr,
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql,
"INSERT INTO \"%s\"(group_name, "
"creator_name, timestamp) VALUES(?, ?, ?)", table_name);
"creator_name, timestamp, parent_group_id) VALUES(?, ?, ?, ?)", table_name);
else
g_string_printf (sql,
"INSERT INTO `%s`(group_name, "
"creator_name, timestamp) VALUES(?, ?, ?)", table_name);
"creator_name, timestamp, parent_group_id) VALUES(?, ?, ?, ?)", table_name);
if (ccnet_db_statement_query (db, sql->str, 3,
if (ccnet_db_statement_query (db, sql->str, 4,
"string", group_name, "string", user_name_l,
"int64", now) < 0) {
"int64", now, "int", parent_group_id) < 0) {
g_set_error (error, CCNET_DOMAIN, 0, "Failed to create group");
goto out;
}
@@ -259,9 +262,10 @@ out:
int ccnet_group_manager_create_group (CcnetGroupManager *mgr,
const char *group_name,
const char *user_name,
int parent_group_id,
GError **error)
{
return create_group_common (mgr, group_name, user_name, error);
return create_group_common (mgr, group_name, user_name, parent_group_id, error);
}
/* static gboolean */
@@ -300,6 +304,7 @@ int ccnet_group_manager_create_org_group (CcnetGroupManager *mgr,
int org_id,
const char *group_name,
const char *user_name,
int parent_group_id,
GError **error)
{
CcnetOrgManager *org_mgr = ((CcnetServerSession *)(mgr->session))->org_mgr;
@@ -310,7 +315,7 @@ int ccnet_group_manager_create_org_group (CcnetGroupManager *mgr,
/* return -1; */
/* } */
int group_id = create_group_common (mgr, group_name, user_name, error);
int group_id = create_group_common (mgr, group_name, user_name, parent_group_id, error);
if (group_id < 0) {
g_set_error (error, CCNET_DOMAIN, 0, "Failed to create org group.");
return -1;
@@ -336,15 +341,29 @@ check_group_staff (CcnetDB *db, int group_id, const char *user_name)
int ccnet_group_manager_remove_group (CcnetGroupManager *mgr,
int group_id,
gboolean remove_anyway,
GError **error)
{
CcnetDB *db = mgr->priv->db;
GString *sql = g_string_new ("");
gboolean exists;
const char *table_name = mgr->priv->table_name;
/* No permission check here, since both group staff and seahub staff
* can remove group.
*/
if (remove_anyway != TRUE) {
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql, "SELECT 1 FROM \"%s\" WHERE parent_group_id=?", table_name);
else
g_string_printf (sql, "SELECT 1 FROM `%s` WHERE parent_group_id=?", table_name);
exists = ccnet_db_statement_exists (db, sql->str, 1, "int", group_id);
if (exists) {
ccnet_warning ("Failed to remove group [%d] whose child group must be removed first.\n", group_id);
g_string_free (sql, TRUE);
return -1;
}
}
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql, "DELETE FROM \"%s\" WHERE group_id=?", table_name);
@@ -538,7 +557,7 @@ int ccnet_group_manager_quit_group (CcnetGroupManager *mgr,
}
static gboolean
get_user_groups_cb (CcnetDBRow *row, void *data)
get_all_child_groups_cb (CcnetDBRow *row, void *data)
{
GList **plist = data;
CcnetGroup *group;
@@ -547,6 +566,7 @@ get_user_groups_cb (CcnetDBRow *row, void *data)
const char *group_name = ccnet_db_row_get_column_text (row, 1);
const char *creator_name = ccnet_db_row_get_column_text (row, 2);
gint64 ts = ccnet_db_row_get_column_int64 (row, 3);
int parent_group_id = ccnet_db_row_get_column_int (row, 4);
group = g_object_new (CCNET_TYPE_GROUP,
"id", group_id,
@@ -554,9 +574,110 @@ get_user_groups_cb (CcnetDBRow *row, void *data)
"creator_name", creator_name,
"timestamp", ts,
"source", "DB",
"parent_group_id", parent_group_id,
NULL);
*plist = g_list_prepend (*plist, group);
*plist = g_list_append (*plist, group);
return TRUE;
}
GList *
ccnet_group_manager_get_all_child_groups (CcnetGroupManager *mgr,
int group_id)
{
GList *ret = NULL, *tmp_list = NULL, *ptr;
CcnetDB *db = mgr->priv->db;
GString *sql = g_string_new ("");
CcnetGroup *group;
const char *table_name = mgr->priv->table_name;
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql, "SELECT group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"\"%s\" WHERE parent_group_id=?",
table_name);
else
g_string_printf (sql, "SELECT group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"`%s` WHERE parent_group_id=?",
table_name);
if (ccnet_db_statement_foreach_row (db,
sql->str,
get_all_child_groups_cb, &tmp_list,
1, "int", group_id) < 0) {
g_string_free (sql, TRUE);
return NULL;
}
g_string_free (sql, TRUE);
for (ptr = tmp_list; ptr; ptr = ptr->next) {
group = ptr->data;
ret = g_list_append (ret, group);
int tmp_group_id;
g_object_get (group, "id", &tmp_group_id, NULL);
GList *child_list = ccnet_group_manager_get_all_child_groups(mgr, tmp_group_id);
ret = g_list_concat (ret, child_list);
}
return ret;
}
GList *
ccnet_group_manager_get_all_parent_groups (CcnetGroupManager *mgr, int group_id)
{
GList *ret = NULL;
CcnetGroup *group = NULL;
while (group_id > 0) {
group = ccnet_group_manager_get_group (mgr, group_id, NULL);
if (group) {
ret = g_list_prepend (ret, group);
g_object_get(group, "parent_group_id", &group_id, NULL);
} else {
break;
}
}
return ret;
}
static gboolean
get_user_groups_cb (CcnetDBRow *row, void *data)
{
GList **plist = data;
CcnetGroup *group, *end_flag;
CcnetGroupManager *group_mgr = ((CcnetServerSession *)session)->group_mgr;
int group_id = ccnet_db_row_get_column_int (row, 0);
const char *group_name = ccnet_db_row_get_column_text (row, 1);
const char *creator_name = ccnet_db_row_get_column_text (row, 2);
gint64 ts = ccnet_db_row_get_column_int64 (row, 3);
int parent_group_id = ccnet_db_row_get_column_int (row, 4);
group = g_object_new (CCNET_TYPE_GROUP,
"id", group_id,
"group_name", group_name,
"creator_name", creator_name,
"timestamp", ts,
"source", "DB",
"parent_group_id", parent_group_id,
"is_direct", TRUE,
NULL);
/* Get all parent groups */
GList *parent_list = ccnet_group_manager_get_all_parent_groups(group_mgr, parent_group_id);
/* Get all child groups */
GList *child_list = ccnet_group_manager_get_all_child_groups(group_mgr, group_id);
parent_list = g_list_append (parent_list, group);
parent_list = g_list_concat (parent_list, child_list);
end_flag = g_object_new (CCNET_TYPE_GROUP,
"id", -1, NULL);
parent_list = g_list_append (parent_list, end_flag);
*plist = g_list_concat (*plist, parent_list);
return TRUE;
}
@@ -573,12 +694,12 @@ ccnet_group_manager_get_groups_by_user (CcnetGroupManager *mgr,
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql,
"SELECT g.group_id, group_name, creator_name, timestamp FROM "
"SELECT g.group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"\"%s\" g, GroupUser u WHERE g.group_id = u.group_id AND user_name=?",
table_name);
else
g_string_printf (sql,
"SELECT g.group_id, group_name, creator_name, timestamp FROM "
"SELECT g.group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"`%s` g, GroupUser u WHERE g.group_id = u.group_id AND user_name=?",
table_name);
@@ -591,7 +712,7 @@ ccnet_group_manager_get_groups_by_user (CcnetGroupManager *mgr,
}
g_string_free (sql, TRUE);
return g_list_reverse (groups);
return groups;
}
static gboolean
@@ -601,12 +722,14 @@ get_ccnetgroup_cb (CcnetDBRow *row, void *data)
int group_id;
const char *group_name;
const char *creator;
int parent_group_id;
gint64 ts;
group_id = ccnet_db_row_get_column_int (row, 0);
group_name = (const char *)ccnet_db_row_get_column_text (row, 1);
creator = (const char *)ccnet_db_row_get_column_text (row, 2);
ts = ccnet_db_row_get_column_int64 (row, 3);
parent_group_id = ccnet_db_row_get_column_int (row, 4);
char *creator_l = g_ascii_strdown (creator, -1);
*p_group = g_object_new (CCNET_TYPE_GROUP,
@@ -615,6 +738,7 @@ get_ccnetgroup_cb (CcnetDBRow *row, void *data)
"creator_name", creator_l,
"timestamp", ts,
"source", "DB",
"parent_group_id", parent_group_id,
NULL);
g_free (creator_l);
@@ -632,11 +756,11 @@ ccnet_group_manager_get_group (CcnetGroupManager *mgr, int group_id,
if (ccnet_db_type(db) == CCNET_DB_TYPE_PGSQL)
g_string_printf (sql,
"SELECT group_id, group_name, creator_name, timestamp FROM "
"SELECT group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"\"%s\" WHERE group_id = ?", table_name);
else
g_string_printf (sql,
"SELECT group_id, group_name, creator_name, timestamp FROM "
"SELECT group_id, group_name, creator_name, timestamp, parent_group_id FROM "
"`%s` WHERE group_id = ?", table_name);
if (ccnet_db_statement_foreach_row (db, sql->str,
get_ccnetgroup_cb, &ccnetgroup,

View File

@@ -27,16 +27,19 @@ void ccnet_group_manager_start (CcnetGroupManager *manager);
int ccnet_group_manager_create_group (CcnetGroupManager *mgr,
const char *group_name,
const char *user_name,
int parent_group_id,
GError **error);
int ccnet_group_manager_create_org_group (CcnetGroupManager *mgr,
int org_id,
const char *group_name,
const char *user_name,
int parent_group_id,
GError **error);
int ccnet_group_manager_remove_group (CcnetGroupManager *mgr,
int group_id,
gboolean remove_anyway,
GError **error);
int ccnet_group_manager_add_member (CcnetGroupManager *mgr,

View File

@@ -259,12 +259,12 @@ class CcnetThreadedRpcClient(RpcClientBase):
def get_peers_by_email(self, email):
pass
@searpc_func("int", ["string", "string", "string"])
def create_group(self, group_name, user_name, gtype):
@searpc_func("int", ["string", "string", "string", "int"])
def create_group(self, group_name, user_name, gtype, parent_group_id):
pass
@searpc_func("int", ["int", "string", "string"])
def create_org_group(self, org_id, group_name, user_name):
@searpc_func("int", ["int", "string", "string", "int"])
def create_org_group(self, org_id, group_name, user_name, parent_group_id):
pass
@searpc_func("int", ["int"])