Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get nickname from seahub database #663

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ endif

MAKE_SERVER = server tools $(MAKE_CONTROLLER) $(MAKE_FUSE)

SUBDIRS = include lib common python $(MAKE_SERVER) doc
SUBDIRS = include lib common python $(MAKE_SERVER) doc scripts

DIST_SUBDIRS = include lib common python server tools controller fuse doc
DIST_SUBDIRS = include lib common python server tools controller fuse doc scripts

INTLTOOL = \
intltool-extract.in \
Expand Down
46 changes: 44 additions & 2 deletions common/merge-new.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,39 @@ merge_trees_recursive (const char *store_id, int version,
const char *basedir,
MergeOptions *opt);

static const char *
get_nickname_by_modifier (GHashTable *email_to_nickname, const char *modifier)
{
const char *nickname = NULL;

if (!modifier) {
return NULL;
}

nickname = g_hash_table_lookup (email_to_nickname, modifier);
if (nickname) {
return nickname;
}

char *sql = "SELECT nickname from profile_profile WHERE user = ?";
nickname = seaf_db_statement_get_string(seaf->seahub_db, sql, 1, "string", modifier);

if (!nickname) {
nickname = modifier;
}
g_hash_table_insert (email_to_nickname, g_strdup(modifier), g_strdup(nickname));

return nickname;
}

static char *
merge_conflict_filename (const char *store_id, int version,
MergeOptions *opt,
const char *basedir,
const char *filename)
{
char *path = NULL, *modifier = NULL, *conflict_name = NULL;
const char *nickname = NULL;
gint64 mtime;
SeafCommit *commit;

Expand All @@ -46,7 +72,11 @@ merge_conflict_filename (const char *store_id, int version,
seaf_commit_unref (commit);
}

conflict_name = gen_conflict_path (filename, modifier, mtime);
nickname = modifier;
if (seaf->seahub_db)
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);

conflict_name = gen_conflict_path (filename, nickname, mtime);

out:
g_free (path);
Expand All @@ -61,6 +91,7 @@ merge_conflict_dirname (const char *store_id, int version,
const char *dirname)
{
char *modifier = NULL, *conflict_name = NULL;
const char *nickname = NULL;
SeafCommit *commit;

commit = seaf_commit_manager_get_commit (seaf->commit_mgr,
Expand All @@ -74,7 +105,11 @@ merge_conflict_dirname (const char *store_id, int version,
modifier = g_strdup(commit->creator_name);
seaf_commit_unref (commit);

conflict_name = gen_conflict_path (dirname, modifier, (gint64)time(NULL));
nickname = modifier;
if (seaf->seahub_db)
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);

conflict_name = gen_conflict_path (dirname, nickname, (gint64)time(NULL));

out:
g_free (modifier);
Expand Down Expand Up @@ -687,6 +722,11 @@ seaf_merge_trees (const char *store_id, int version,

g_return_val_if_fail (n == 2 || n == 3, -1);

opt->email_to_nickname = g_hash_table_new_full(g_str_hash,
g_str_equal,
g_free,
g_free);

trees = g_new0 (SeafDir *, n);
for (i = 0; i < n; ++i) {
root = seaf_fs_manager_get_seafdir (seaf->fs_mgr, store_id, version, roots[i]);
Expand All @@ -704,5 +744,7 @@ seaf_merge_trees (const char *store_id, int version,
seaf_dir_free (trees[i]);
g_free (trees);

g_hash_table_destroy (opt->email_to_nickname);

return ret;
}
2 changes: 2 additions & 0 deletions common/merge-new.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ typedef struct MergeOptions {
char merged_tree_root[41]; /* merge result */
int visit_dirs;
gboolean conflict;

GHashTable *email_to_nickname;
} MergeOptions;

int
Expand Down
126 changes: 126 additions & 0 deletions common/seaf-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,129 @@ load_ccnet_database_config (SeafileSession *session)
g_free (engine);
return ret;
}

static char *
parse_seahub_db_config ()
{
char buf[1024];
GError *error = NULL;
int retcode = 0;
char *child_stdout = NULL;
char *child_stderr = NULL;

char *binary_path = g_find_program_in_path ("parse_seahub_db.py");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个字符串要释放一下吧。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

怎样保证能找到这个脚本呢?需要把脚本放在 bin 目录下面的话,需要记录一个任务告诉马宇航处理一下。


snprintf (buf,
sizeof(buf),
"python3 %s",
binary_path);
g_spawn_command_line_sync (buf,
&child_stdout,
&child_stderr,
&retcode,
&error);

if (error != NULL) {
seaf_warning ("Failed to run python parse_seahub_db.py: %s\n", error->message);
g_free (binary_path);
g_free (child_stdout);
g_free (child_stderr);
g_clear_error (&error);
return NULL;
}
g_spawn_check_exit_status (retcode, &error);
if (error != NULL) {
seaf_warning ("Failed to run python parse_seahub_db.py: %s\n", error->message);
g_free (binary_path);
g_free (child_stdout);
g_free (child_stderr);
g_clear_error (&error);
return NULL;
}

g_free (binary_path);
g_free (child_stderr);
return child_stdout;
}

int
load_seahub_database_config (SeafileSession *session)
{
int ret = 0;
json_t *object = NULL;
json_error_t err;
const char *engine = NULL, *name = NULL, *user = NULL, *password = NULL, *host = NULL, *charset = NULL;
int port;
char *json_str = NULL;

json_str = parse_seahub_db_config ();
if (!json_str){
seaf_warning ("Failed to parse seahub database config.\n");
ret = -1;
goto out;
}

object = json_loadb (json_str, strlen(json_str), 0, &err);
if (!object) {
seaf_warning ("Failed to load seahub db json: %s: %s\n", json_str, err.text);
ret = -1;
goto out;
}

engine = json_object_get_string_member (object, "ENGINE");
name = json_object_get_string_member (object, "NAME");
user = json_object_get_string_member (object, "USER");
password = json_object_get_string_member (object, "PASSWORD");
host = json_object_get_string_member (object, "HOST");
charset = json_object_get_string_member (object, "CHARSET");
port = json_object_get_int_member (object, "PORT");
if (port <= 0) {
port = MYSQL_DEFAULT_PORT;
}

if (!engine || strstr (engine, "sqlite") != NULL) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sqlite 是不能支持多进程同时打开的吧,而且11版本之后 sqlite 已经不支持了。所以这里如果检测到 sqlite 就不用做 username 的转换了。

goto out;
}
#ifdef HAVE_MYSQL
else if (strstr (engine, "mysql") != NULL) {
seaf_message("Use database Mysql\n");
if (!host) {
seaf_warning ("Seahub DB host not set in config.\n");
ret = -1;
goto out;
}
if (!user) {
seaf_warning ("Seahub DB user not set in config.\n");
ret = -1;
goto out;
}
if (!password) {
seaf_warning ("Seahub DB password not set in config.\n");
ret = -1;
goto out;
}
if (!name) {
seaf_warning ("Seahub DB name not set in config.\n");
ret = -1;
goto out;
}

session->seahub_db = seaf_db_new_mysql (host, port, user, password, name, NULL, FALSE, FALSE, NULL, charset, DEFAULT_MAX_CONNECTIONS);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要检查必要的参数是否已经设置了。

if (!session->seahub_db) {
seaf_warning ("Failed to open seahub database.\n");
ret = -1;
goto out;
}
}
#endif
else {
seaf_warning ("Unknown database type: %s.\n", engine);
ret = -1;
}

out:
if (object)
json_decref (object);
g_free (json_str);
return ret;
}
3 changes: 3 additions & 0 deletions common/seaf-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ load_database_config (struct _SeafileSession *session);
int
load_ccnet_database_config (struct _SeafileSession *session);

int
load_seahub_database_config (SeafileSession *session);

#endif
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ AC_CONFIG_FILES(
controller/Makefile
tools/Makefile
doc/Makefile
scripts/Makefile
)

AC_OUTPUT
70 changes: 69 additions & 1 deletion fileserver/fileserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import (
"crypto/tls"
"crypto/x509"
"database/sql"
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"os/signal"
"path/filepath"
"runtime/debug"
"strconv"
"strings"
"syscall"

Expand Down Expand Up @@ -41,7 +44,7 @@ var pidFilePath string
var logFp *os.File

var dbType string
var seafileDB, ccnetDB *sql.DB
var seafileDB, ccnetDB, seahubDB *sql.DB

// when SQLite is used, user and group db are separated.
var userDB, groupDB *sql.DB
Expand Down Expand Up @@ -269,6 +272,69 @@ func loadSeafileDB() {
dbType = dbEngine
}

func loadSeahubDB() {
scriptPath, err := exec.LookPath("parse_seahub_db.py")
if err != nil {
log.Warnf("Failed to find script of parse_seahub_db.py: %v", err)
return
}
cmd := exec.Command("python3", scriptPath)
dbData, err := cmd.CombinedOutput()
if err != nil {
log.Warnf("Failed to run python parse_seahub_db.py: %v", err)
return
}

dbConfig := make(map[string]string)

err = json.Unmarshal(dbData, &dbConfig)
if err != nil {
log.Warnf("Failed to decode seahub database json file: %v", err)
return
}

dbEngine := dbConfig["ENGINE"]
dbName := dbConfig["NAME"]
user := dbConfig["USER"]
password := dbConfig["PASSWORD"]
host := dbConfig["HOST"]
portStr := dbConfig["PORT"]

if strings.Index(dbEngine, "mysql") >= 0 {
port, err := strconv.ParseInt(portStr, 10, 64)
if err != nil || port <= 0 {
port = 3306
}
if dbName == "" {
log.Warnf("Seahub DB name not set in config")
return
}
if user == "" {
log.Warnf("Seahub DB user not set in config")
return
}
if password == "" {
log.Warnf("Seahub DB password not set in config")
return
}
if host == "" {
log.Warnf("Seahub DB host not set in config")
return
}

dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里也需要类似 C 部分改一下。

另外,怎样保证在 go fileserver 运行之前 seaf-server 已经解析好了 seahub_db.json 呢?而且把数据库密码这些敏感信息写入到 tmp 下面也有安全问题的,应该改为 seaf-server 和 go fileserver 都直接把 python 脚本的输出读取到内存里面,不需要临时文件。


seahubDB, err = sql.Open("mysql", dsn)
if err != nil {
log.Warnf("Failed to open database: %v", err)
}
} else if strings.Index(dbEngine, "sqlite") >= 0 {
return
} else {
log.Warnf("Unsupported database %s.", dbEngine)
}
}

func writePidFile(pid_file_path string) error {
file, err := os.OpenFile(pid_file_path, os.O_CREATE|os.O_WRONLY, 0664)
if err != nil {
Expand Down Expand Up @@ -367,6 +433,8 @@ func main() {
fp.Close()
}

loadSeahubDB()

repomgr.Init(seafileDB)

fsmgr.Init(centralDir, dataDir, option.FsCacheLimit)
Expand Down
Loading
Loading