1
0
mirror of https://github.com/haiwen/seafile-server.git synced 2025-09-21 02:58:57 +00:00
Files
seafile-server/server/seafile-session.c
feiniks d6f6127641 Add notification server (#535)
* Add notification server of go

Modify path of pkg

Send notification for update-repo event

Delete client pkg and use reflect select to send message

Modify output of log

Add formatter of log

Add jwt authentication

go add get jwt token api

CI support compile libjwt

Get group users from database

* Add ping to test mysql is alive

Co-authored-by: 杨赫然 <heran.yang@seafile.com>
2022-12-16 15:29:01 +08:00

483 lines
15 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include "common.h"
#include <stdint.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include "utils.h"
#include "seafile-session.h"
#include "mq-mgr.h"
#include "seaf-db.h"
#include "seaf-utils.h"
#include "log.h"
#define CONNECT_INTERVAL_MSEC 10 * 1000
#define DEFAULT_THREAD_POOL_SIZE 500
SeafileSession *
seafile_session_new(const char *central_config_dir,
const char *seafile_dir,
const char *ccnet_dir)
{
char *abs_central_config_dir = NULL;
char *abs_seafile_dir;
char *abs_ccnet_dir = NULL;
char *tmp_file_dir;
char *config_file_path;
char *config_file_ccnet;
GKeyFile *config;
GKeyFile *ccnet_config;
SeafileSession *session = NULL;
char *notif_url = NULL;
char *notif_token = NULL;
char *private_key = NULL;
abs_ccnet_dir = ccnet_expand_path (ccnet_dir);
abs_seafile_dir = ccnet_expand_path (seafile_dir);
tmp_file_dir = g_build_filename (abs_seafile_dir, "tmpfiles", NULL);
if (central_config_dir) {
abs_central_config_dir = ccnet_expand_path (central_config_dir);
}
if (checkdir_with_mkdir (abs_seafile_dir) < 0) {
seaf_warning ("Config dir %s does not exist and is unable to create\n",
abs_seafile_dir);
goto onerror;
}
if (checkdir_with_mkdir (tmp_file_dir) < 0) {
seaf_warning ("Temp file dir %s does not exist and is unable to create\n",
tmp_file_dir);
goto onerror;
}
if (checkdir_with_mkdir (abs_ccnet_dir) < 0) {
seaf_warning ("Ccnet config dir %s does not exist and is unable to create\n",
abs_ccnet_dir);
goto onerror;
}
config_file_path = g_build_filename(
abs_central_config_dir ? abs_central_config_dir : abs_seafile_dir,
"seafile.conf", NULL);
config_file_ccnet = g_build_filename(
abs_central_config_dir ? abs_central_config_dir : abs_ccnet_dir,
"ccnet.conf", NULL);
GError *error = NULL;
config = g_key_file_new ();
if (!g_key_file_load_from_file (config, config_file_path,
G_KEY_FILE_NONE, &error)) {
seaf_warning ("Failed to load config file.\n");
g_key_file_free (config);
g_free (config_file_path);
goto onerror;
}
ccnet_config = g_key_file_new ();
g_key_file_set_list_separator (ccnet_config, ',');
if (!g_key_file_load_from_file (ccnet_config, config_file_ccnet,
G_KEY_FILE_KEEP_COMMENTS, NULL))
{
seaf_warning ("Can't load ccnet config file %s.\n", config_file_ccnet);
g_key_file_free (ccnet_config);
g_free (config_file_ccnet);
goto onerror;
}
g_free (config_file_path);
g_free (config_file_ccnet);
session = g_new0(SeafileSession, 1);
session->seaf_dir = abs_seafile_dir;
session->ccnet_dir = abs_ccnet_dir;
session->tmp_file_dir = tmp_file_dir;
session->config = config;
session->ccnet_config = ccnet_config;
session->cloud_mode = g_key_file_get_boolean (config,
"general", "cloud_mode",
NULL);
session->go_fileserver = g_key_file_get_boolean (config,
"fileserver", "use_go_fileserver",
NULL);
if (session->go_fileserver) {
char *type = NULL;
type = g_key_file_get_string (config, "database", "type", NULL);
if (!type || g_strcmp0 (type, "mysql") != 0) {
session->go_fileserver = FALSE;
}
g_free (type);
}
notif_url = g_key_file_get_string (config,
"notification", "notification_url",
NULL);
notif_token = g_key_file_get_string (config,
"notification", "notification_token",
NULL);
private_key = g_key_file_get_string (config,
"notification", "private_key",
NULL);
if (private_key) {
session->private_key = private_key;
}
if (load_database_config (session) < 0) {
seaf_warning ("Failed to load database config.\n");
goto onerror;
}
if (load_ccnet_database_config (session) < 0) {
seaf_warning ("Failed to load ccnet database config.\n");
goto onerror;
}
session->cfg_mgr = seaf_cfg_manager_new (session);
if (!session->cfg_mgr)
goto onerror;
session->fs_mgr = seaf_fs_manager_new (session, abs_seafile_dir);
if (!session->fs_mgr)
goto onerror;
session->block_mgr = seaf_block_manager_new (session, abs_seafile_dir);
if (!session->block_mgr)
goto onerror;
session->commit_mgr = seaf_commit_manager_new (session);
if (!session->commit_mgr)
goto onerror;
session->repo_mgr = seaf_repo_manager_new (session);
if (!session->repo_mgr)
goto onerror;
session->branch_mgr = seaf_branch_manager_new (session);
if (!session->branch_mgr)
goto onerror;
session->share_mgr = seaf_share_manager_new (session);
if (!session->share_mgr)
goto onerror;
session->web_at_mgr = seaf_web_at_manager_new (session);
if (!session->web_at_mgr)
goto onerror;
session->passwd_mgr = seaf_passwd_manager_new (session);
if (!session->passwd_mgr)
goto onerror;
session->quota_mgr = seaf_quota_manager_new (session);
if (!session->quota_mgr)
goto onerror;
session->copy_mgr = seaf_copy_manager_new (session);
if (!session->copy_mgr)
goto onerror;
session->job_mgr = ccnet_job_manager_new (DEFAULT_THREAD_POOL_SIZE);
session->size_sched = size_scheduler_new (session);
session->mq_mgr = seaf_mq_manager_new ();
if (!session->mq_mgr)
goto onerror;
session->http_server = seaf_http_server_new (session);
if (!session->http_server)
goto onerror;
session->zip_download_mgr = zip_download_mgr_new ();
if (!session->zip_download_mgr)
goto onerror;
session->index_blocks_mgr = index_blocks_mgr_new (session);
if (!session->index_blocks_mgr)
goto onerror;
session->user_mgr = ccnet_user_manager_new (session);
if (!session->user_mgr)
goto onerror;
session->group_mgr = ccnet_group_manager_new (session);
if (!session->group_mgr)
goto onerror;
session->org_mgr = ccnet_org_manager_new (session);
if (!session->org_mgr)
goto onerror;
if (notif_url != NULL && notif_token != NULL) {
session->notif_mgr = seaf_notif_manager_new (session, notif_url, notif_token);
if (!session->notif_mgr)
goto onerror;
}
return session;
onerror:
g_free (notif_url);
g_free (notif_token);
g_free (private_key);
free (abs_seafile_dir);
free (abs_ccnet_dir);
g_free (tmp_file_dir);
g_free (session);
return NULL;
}
int
seafile_session_init (SeafileSession *session)
{
if (seaf_commit_manager_init (session->commit_mgr) < 0)
return -1;
if (seaf_fs_manager_init (session->fs_mgr) < 0)
return -1;
if (seaf_branch_manager_init (session->branch_mgr) < 0) {
seaf_warning ("Failed to init branch manager.\n");
return -1;
}
if (seaf_repo_manager_init (session->repo_mgr) < 0) {
seaf_warning ("Failed to init repo manager.\n");
return -1;
}
if (seaf_quota_manager_init (session->quota_mgr) < 0) {
seaf_warning ("Failed to init quota manager.\n");
return -1;
}
if (ccnet_user_manager_prepare (session->user_mgr) < 0) {
seaf_warning ("Failed to init user manager.\n");
return -1;
}
if (ccnet_group_manager_prepare (session->group_mgr) < 0) {
seaf_warning ("Failed to init group manager.\n");
return -1;
}
if (ccnet_org_manager_prepare (session->org_mgr) < 0) {
seaf_warning ("Failed to init org manager.\n");
return -1;
}
if ((session->create_tables || seaf_db_type(session->db) == SEAF_DB_TYPE_PGSQL)
&& seaf_cfg_manager_init (session->cfg_mgr) < 0) {
seaf_warning ("Failed to init config manager.\n");
return -1;
}
return 0;
}
int
seafile_session_start (SeafileSession *session)
{
if (seaf_share_manager_start (session->share_mgr) < 0) {
seaf_warning ("Failed to start share manager.\n");
return -1;
}
if (seaf_web_at_manager_start (session->web_at_mgr) < 0) {
seaf_warning ("Failed to start web access check manager.\n");
return -1;
}
if (seaf_passwd_manager_start (session->passwd_mgr) < 0) {
seaf_warning ("Failed to start password manager.\n");
return -1;
}
if (size_scheduler_start (session->size_sched) < 0) {
seaf_warning ("Failed to start size scheduler.\n");
return -1;
}
if (seaf_copy_manager_start (session->copy_mgr) < 0) {
seaf_warning ("Failed to start copy manager.\n");
return -1;
}
if (!session->go_fileserver) {
if (seaf_http_server_start (session->http_server) < 0) {
seaf_warning ("Failed to start http server thread.\n");
return -1;
}
}
return 0;
}
char *
get_system_default_repo_id (SeafileSession *session)
{
char *sql = "SELECT info_value FROM SystemInfo WHERE info_key='default_repo_id'";
return seaf_db_get_string (session->db, sql);
}
int
set_system_default_repo_id (SeafileSession *session, const char *repo_id)
{
char sql[256];
snprintf (sql, sizeof(sql),
"INSERT INTO SystemInfo (info_key, info_value) VALUES ('default_repo_id', '%s')",
repo_id);
return seaf_db_query (session->db, sql);
}
static int
del_system_default_repo_id (SeafileSession *session)
{
const char *sql = "DELETE FROM SystemInfo WHERE info_key='default_repo_id'";
return seaf_db_query (session->db, sql);
}
#define DEFAULT_TEMPLATE_DIR "library-template"
static void
copy_template_files_recursive (SeafileSession *session,
const char *repo_id,
const char *repo_dir_path,
const char *dir_path)
{
GDir *dir;
const char *name;
char *sub_path, *repo_sub_path;
SeafStat st;
GError *error = NULL;
int rc;
dir = g_dir_open (dir_path, 0, &error);
if (!dir) {
seaf_warning ("Failed to open template dir %s: %s.\n",
dir_path, error->message);
return;
}
while ((name = g_dir_read_name(dir)) != NULL) {
sub_path = g_build_filename (dir_path, name, NULL);
if (seaf_stat (sub_path, &st) < 0) {
seaf_warning ("Failed to stat %s: %s.\n", sub_path, strerror(errno));
g_free (sub_path);
continue;
}
if (S_ISREG(st.st_mode)) {
rc = seaf_repo_manager_post_file (session->repo_mgr,
repo_id,
sub_path,
repo_dir_path,
name,
"System",
NULL);
if (rc < 0)
seaf_warning ("Failed to add template file %s.\n", sub_path);
} else if (S_ISDIR(st.st_mode)) {
rc = seaf_repo_manager_post_dir (session->repo_mgr,
repo_id,
repo_dir_path,
name,
"System",
NULL);
if (rc < 0) {
seaf_warning ("Failed to add template dir %s.\n", sub_path);
g_free (sub_path);
continue;
}
repo_sub_path = g_build_path ("/", repo_dir_path, name, NULL);
copy_template_files_recursive (session, repo_id,
repo_sub_path, sub_path);
g_free (repo_sub_path);
}
g_free (sub_path);
}
g_dir_close (dir);
}
static void *
create_system_default_repo (void *data)
{
SeafileSession *session = data;
char *repo_id;
char *template_path;
/* If default repo is not set or doesn't exist, create a new one. */
repo_id = get_system_default_repo_id (session);
if (repo_id != NULL) {
SeafRepo *repo;
repo = seaf_repo_manager_get_repo (session->repo_mgr, repo_id);
if (!repo) {
seaf_warning ("Failed to get system default repo. Create a new one.\n");
del_system_default_repo_id (session);
seaf_repo_manager_del_repo (session->repo_mgr, repo_id, NULL);
g_free (repo_id);
} else {
seaf_repo_unref (repo);
g_free (repo_id);
return data;
}
}
repo_id = seaf_repo_manager_create_new_repo (session->repo_mgr,
"My Library Template",
"Template for creating 'My Library' for users",
"System",
NULL, -1, NULL);
if (!repo_id) {
seaf_warning ("Failed to create system default repo.\n");
return data;
}
set_system_default_repo_id (session, repo_id);
template_path = g_build_filename (session->seaf_dir, DEFAULT_TEMPLATE_DIR, NULL);
copy_template_files_recursive (session, repo_id, "/", template_path);
g_free (repo_id);
g_free (template_path);
return data;
}
void
schedule_create_system_default_repo (SeafileSession *session)
{
int db_type = seaf_db_type (session->db);
char *sql;
if (db_type == SEAF_DB_TYPE_MYSQL)
sql = "CREATE TABLE IF NOT EXISTS SystemInfo "
"(id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, "
"info_key VARCHAR(256), info_value VARCHAR(1024))";
else
sql = "CREATE TABLE IF NOT EXISTS SystemInfo( "
"info_key VARCHAR(256), info_value VARCHAR(1024))";
if ((session->create_tables || db_type == SEAF_DB_TYPE_PGSQL)
&& seaf_db_query (session->db, sql) < 0)
return;
ccnet_job_manager_schedule_job (session->job_mgr,
create_system_default_repo,
NULL, session);
}