static gboolean check_repo_share_permission (SearpcClient *rpc_client, const char *repo_id, const char *user_name) { GList *groups, *pgroup; GList *repos, *prepo; CcnetGroup *group; int group_id; char *shared_repo_id; gboolean ret = FALSE; if (seaf_share_manager_check_permission (seaf->share_mgr, repo_id, user_name) != NULL) return TRUE; groups = ccnet_get_groups_by_user (rpc_client, user_name); for (pgroup = groups; pgroup != NULL; pgroup = pgroup->next) { group = pgroup->data; g_object_get (group, "id", &group_id, NULL); repos = seaf_repo_manager_get_group_repoids (seaf->repo_mgr, group_id, NULL); for (prepo = repos; prepo != NULL; prepo = prepo->next) { shared_repo_id = prepo->data; if (strcmp (shared_repo_id, repo_id) == 0) { ret = TRUE; break; } } for (prepo = repos; prepo != NULL; prepo = prepo->next) g_free (prepo->data); g_list_free (repos); if (ret) break; } for (pgroup = groups; pgroup != NULL; pgroup = pgroup->next) g_object_unref ((GObject *)pgroup->data); g_list_free (groups); return ret; }
/* * Permission priority: owner --> personal share --> group share --> public. * Permission with higher priority overwrites those with lower priority. */ static char * check_repo_share_permission (SeafRepoManager *mgr, const char *repo_id, const char *user_name) { SearpcClient *rpc_client; GList *groups, *p1; GList *group_perms, *p2; CcnetGroup *group; GroupPerm *perm; int group_id; char *permission; permission = seaf_share_manager_check_permission (seaf->share_mgr, repo_id, user_name); if (permission != NULL) return permission; g_free (permission); rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "ccnet-threaded-rpcserver"); if (!rpc_client) return NULL; /* Get the groups this user belongs to. */ groups = ccnet_get_groups_by_user (rpc_client, user_name); ccnet_rpc_client_free (rpc_client); /* Get the groups this repo shared to. */ group_perms = seaf_repo_manager_get_group_perm_by_repo (mgr, repo_id, NULL); permission = NULL; /* Check if any one group overlaps. */ for (p1 = groups; p1 != NULL; p1 = p1->next) { group = p1->data; g_object_get (group, "id", &group_id, NULL); for (p2 = group_perms; p2 != NULL; p2 = p2->next) { perm = p2->data; if (group_id == perm->group_id) { /* If the repo is shared to more than 1 groups, * and user is in more than 1 of these groups, * "rw" permission will overwrite "ro" permission. */ if (g_strcmp0(perm->permission, "rw") == 0) { permission = perm->permission; goto group_out; } else if (g_strcmp0(perm->permission, "r") == 0 && !permission) { permission = perm->permission; } } } } group_out: if (permission != NULL) permission = g_strdup(permission); for (p1 = groups; p1 != NULL; p1 = p1->next) g_object_unref ((GObject *)p1->data); g_list_free (groups); for (p2 = group_perms; p2 != NULL; p2 = p2->next) g_free (p2->data); g_list_free (group_perms); if (permission != NULL) return permission; if (!mgr->seaf->cloud_mode) return seaf_repo_manager_get_inner_pub_repo_perm (mgr, repo_id); return NULL; }