mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-09-02 16:04:26 +00:00
Get nickname use seahub API (#670)
* Get nickname use seahub API * Add parse site_root * Use regex to match SECRET_KEY --------- Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
@@ -27,13 +27,12 @@ get_nickname_by_modifier (GHashTable *email_to_nickname, const char *modifier)
|
|||||||
return nickname;
|
return nickname;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *sql = "SELECT nickname from profile_profile WHERE user = ?";
|
nickname = http_tx_manager_get_nickname (modifier);
|
||||||
nickname = seaf_db_statement_get_string(seaf->seahub_db, sql, 1, "string", modifier);
|
|
||||||
|
|
||||||
if (!nickname) {
|
if (!nickname) {
|
||||||
nickname = modifier;
|
nickname = g_strdup (modifier);
|
||||||
}
|
}
|
||||||
g_hash_table_insert (email_to_nickname, g_strdup(modifier), g_strdup(nickname));
|
g_hash_table_insert (email_to_nickname, g_strdup(modifier), nickname);
|
||||||
|
|
||||||
return nickname;
|
return nickname;
|
||||||
}
|
}
|
||||||
@@ -73,7 +72,7 @@ merge_conflict_filename (const char *store_id, int version,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nickname = modifier;
|
nickname = modifier;
|
||||||
if (seaf->seahub_db)
|
if (seaf->seahub_pk)
|
||||||
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);
|
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);
|
||||||
|
|
||||||
conflict_name = gen_conflict_path (filename, nickname, mtime);
|
conflict_name = gen_conflict_path (filename, nickname, mtime);
|
||||||
@@ -106,7 +105,7 @@ merge_conflict_dirname (const char *store_id, int version,
|
|||||||
seaf_commit_unref (commit);
|
seaf_commit_unref (commit);
|
||||||
|
|
||||||
nickname = modifier;
|
nickname = modifier;
|
||||||
if (seaf->seahub_db)
|
if (seaf->seahub_pk)
|
||||||
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);
|
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);
|
||||||
|
|
||||||
conflict_name = gen_conflict_path (dirname, nickname, (gint64)time(NULL));
|
conflict_name = gen_conflict_path (dirname, nickname, (gint64)time(NULL));
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
char *
|
char *
|
||||||
seafile_session_get_tmp_file_path (SeafileSession *session,
|
seafile_session_get_tmp_file_path (SeafileSession *session,
|
||||||
@@ -380,128 +381,64 @@ load_ccnet_database_config (SeafileSession *session)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
#ifdef FULL_FEATURE
|
||||||
parse_seahub_db_config ()
|
|
||||||
|
void
|
||||||
|
load_seahub_private_key (SeafileSession *session, const char *conf_dir)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char *conf_path = g_build_filename(conf_dir, "seahub_settings.py", NULL);
|
||||||
|
char *data = NULL;
|
||||||
|
GRegex *secret_key_regex = NULL;
|
||||||
|
GRegex *site_root_regex = NULL;
|
||||||
GError *error = NULL;
|
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");
|
FILE *file = fopen(conf_path, "r");
|
||||||
|
if (!file) {
|
||||||
|
seaf_warning ("Failed to open seahub_settings.py: %s\n", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf (buf,
|
secret_key_regex = g_regex_new ("SECRET_KEY\\s*=\\s*'(.+)'", 0, 0, &error);
|
||||||
sizeof(buf),
|
if (error) {
|
||||||
"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);
|
g_clear_error (&error);
|
||||||
return NULL;
|
seaf_warning ("Failed to create secret key regex: %s\n", error->message);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
g_spawn_check_exit_status (retcode, &error);
|
|
||||||
if (error != NULL) {
|
site_root_regex = g_regex_new ("SITE_ROOT\\s*=\\s*'(.+)'", 0, 0, &error);
|
||||||
seaf_warning ("Failed to run python parse_seahub_db.py: %s\n", error->message);
|
if (error) {
|
||||||
g_free (binary_path);
|
|
||||||
g_free (child_stdout);
|
|
||||||
g_free (child_stderr);
|
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
return NULL;
|
seaf_warning ("Failed to create site root regex: %s\n", error->message);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
object = json_loadb (json_str, strlen(json_str), 0, &err);
|
char line[256];
|
||||||
if (!object) {
|
char *site_root = NULL;
|
||||||
seaf_warning ("Failed to load seahub db json: %s: %s\n", json_str, err.text);
|
while (fgets(line, sizeof(line), file)) {
|
||||||
ret = -1;
|
GMatchInfo *match_info;
|
||||||
goto out;
|
if (g_regex_match (secret_key_regex, line, 0, &match_info)) {
|
||||||
|
char *sk = g_match_info_fetch (match_info, 1);
|
||||||
|
session->seahub_pk = sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine = json_object_get_string_member (object, "ENGINE");
|
if (g_regex_match (site_root_regex, line, 0, &match_info)) {
|
||||||
name = json_object_get_string_member (object, "NAME");
|
site_root = g_match_info_fetch (match_info, 1);
|
||||||
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) {
|
if (session->seahub_pk) {
|
||||||
goto out;
|
if (site_root) {
|
||||||
|
session->seahub_url = g_strdup_printf("http://127.0.0.1:8000%sapi/v2.1/internal/user-list/", site_root);
|
||||||
|
} else {
|
||||||
|
session->seahub_url = g_strdup("http://127.0.0.1:8000/api/v2.1/internal/user-list/");
|
||||||
}
|
}
|
||||||
#ifdef HAVE_MYSQL
|
session->seahub_conn_pool = connection_pool_new ();
|
||||||
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);
|
|
||||||
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:
|
out:
|
||||||
if (object)
|
g_regex_unref (secret_key_regex);
|
||||||
json_decref (object);
|
g_regex_unref (site_root_regex);
|
||||||
g_free (json_str);
|
g_free (conf_path);
|
||||||
return ret;
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@@ -16,7 +16,9 @@ load_database_config (struct _SeafileSession *session);
|
|||||||
int
|
int
|
||||||
load_ccnet_database_config (struct _SeafileSession *session);
|
load_ccnet_database_config (struct _SeafileSession *session);
|
||||||
|
|
||||||
int
|
#ifdef FULL_FEATURE
|
||||||
load_seahub_database_config (SeafileSession *session);
|
void
|
||||||
|
load_seahub_private_key (SeafileSession *session, const char *conf_dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2,21 +2,20 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
@@ -44,7 +43,8 @@ var pidFilePath string
|
|||||||
var logFp *os.File
|
var logFp *os.File
|
||||||
|
|
||||||
var dbType string
|
var dbType string
|
||||||
var seafileDB, ccnetDB, seahubDB *sql.DB
|
var seafileDB, ccnetDB *sql.DB
|
||||||
|
var seahubURL, seahubPK string
|
||||||
|
|
||||||
// when SQLite is used, user and group db are separated.
|
// when SQLite is used, user and group db are separated.
|
||||||
var userDB, groupDB *sql.DB
|
var userDB, groupDB *sql.DB
|
||||||
@@ -272,66 +272,45 @@ func loadSeafileDB() {
|
|||||||
dbType = dbEngine
|
dbType = dbEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSeahubDB() {
|
func loadSeahubPK() {
|
||||||
scriptPath, err := exec.LookPath("parse_seahub_db.py")
|
confPath := filepath.Join(centralDir, "seahub_settings.py")
|
||||||
|
|
||||||
|
file, err := os.Open(confPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Failed to find script of parse_seahub_db.py: %v", err)
|
log.Warnf("Failed to open seahub_settings.py: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd := exec.Command("python3", scriptPath)
|
defer file.Close()
|
||||||
dbData, err := cmd.CombinedOutput()
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
|
||||||
|
pkRe, err := regexp.Compile("SECRET_KEY\\s*=\\s*'([^']*)'")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Failed to run python parse_seahub_db.py: %v", err)
|
log.Warnf("Failed to compile regex: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
siteRootRe, err := regexp.Compile("SITE_ROOT\\s*=\\s*'([^']*)'")
|
||||||
dbConfig := make(map[string]string)
|
|
||||||
|
|
||||||
err = json.Unmarshal(dbData, &dbConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Failed to decode seahub database json file: %v", err)
|
log.Warnf("Failed to compile regex: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dbEngine := dbConfig["ENGINE"]
|
siteRoot := ""
|
||||||
dbName := dbConfig["NAME"]
|
for scanner.Scan() {
|
||||||
user := dbConfig["USER"]
|
line := scanner.Text()
|
||||||
password := dbConfig["PASSWORD"]
|
matches := pkRe.FindStringSubmatch(line)
|
||||||
host := dbConfig["HOST"]
|
if matches != nil {
|
||||||
portStr := dbConfig["PORT"]
|
seahubPK = matches[1]
|
||||||
|
|
||||||
if strings.Index(dbEngine, "mysql") >= 0 {
|
|
||||||
port, err := strconv.ParseInt(portStr, 10, 64)
|
|
||||||
if err != nil || port <= 0 {
|
|
||||||
port = 3306
|
|
||||||
}
|
}
|
||||||
if dbName == "" {
|
matches = siteRootRe.FindStringSubmatch(line)
|
||||||
log.Warnf("Seahub DB name not set in config")
|
if matches != nil {
|
||||||
return
|
siteRoot = matches[1]
|
||||||
}
|
}
|
||||||
if user == "" {
|
|
||||||
log.Warnf("Seahub DB user not set in config")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if password == "" {
|
if siteRoot != "" {
|
||||||
log.Warnf("Seahub DB password not set in config")
|
seahubURL = fmt.Sprintf("http://127.0.0.1:8000%sapi/v2.1/internal/user-list/", siteRoot)
|
||||||
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)
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
log.Warnf("Unsupported database %s.", dbEngine)
|
seahubURL = ("http://127.0.0.1:8000/api/v2.1/internal/user-list/")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,7 +412,7 @@ func main() {
|
|||||||
fp.Close()
|
fp.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSeahubDB()
|
loadSeahubPK()
|
||||||
|
|
||||||
repomgr.Init(seafileDB)
|
repomgr.Init(seafileDB)
|
||||||
|
|
||||||
|
@@ -1,14 +1,19 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
"github.com/haiwen/seafile-server/fileserver/commitmgr"
|
"github.com/haiwen/seafile-server/fileserver/commitmgr"
|
||||||
"github.com/haiwen/seafile-server/fileserver/fsmgr"
|
"github.com/haiwen/seafile-server/fileserver/fsmgr"
|
||||||
|
"github.com/haiwen/seafile-server/fileserver/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mergeOptions struct {
|
type mergeOptions struct {
|
||||||
@@ -379,10 +384,8 @@ func getNickNameByModifier(emailToNickname map[string]string, modifier string) s
|
|||||||
if ok {
|
if ok {
|
||||||
return nickname
|
return nickname
|
||||||
}
|
}
|
||||||
if seahubDB != nil {
|
if seahubPK != "" {
|
||||||
sqlStr := "SELECT nickname from profile_profile WHERE user = ?"
|
nickname = postGetNickName(modifier)
|
||||||
row := seahubDB.QueryRow(sqlStr, modifier)
|
|
||||||
row.Scan(&nickname)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if nickname == "" {
|
if nickname == "" {
|
||||||
@@ -394,6 +397,72 @@ func getNickNameByModifier(emailToNickname map[string]string, modifier string) s
|
|||||||
return nickname
|
return nickname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SeahubClaims struct {
|
||||||
|
Exp int64
|
||||||
|
IsInternal bool `json:"is_internal"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SeahubClaims) Valid() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postGetNickName(modifier string) string {
|
||||||
|
claims := SeahubClaims{
|
||||||
|
time.Now().Add(time.Second * 300).Unix(),
|
||||||
|
true,
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &claims)
|
||||||
|
tokenString, err := token.SignedString([]byte(seahubPK))
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
header := map[string][]string{
|
||||||
|
"Authorization": {"Token " + tokenString},
|
||||||
|
"Content-Type": {"application/json"},
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(map[string]interface{}{
|
||||||
|
"user_id_list": []string{modifier},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
status, body, err := utils.HttpCommon("POST", seahubURL, header, bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(body, &results)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
userList, ok := results["user_list"].([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
nickname := ""
|
||||||
|
for _, element := range userList {
|
||||||
|
list, ok := element.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nickname, _ = list["name"].(string)
|
||||||
|
if nickname != "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nickname
|
||||||
|
}
|
||||||
|
|
||||||
func getFileModifierMtime(repoID, storeID, head, filePath string) (string, int64, error) {
|
func getFileModifierMtime(repoID, storeID, head, filePath string) (string, int64, error) {
|
||||||
commit, err := commitmgr.Load(repoID, head)
|
commit, err := commitmgr.Load(repoID, head)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
34
fileserver/utils/http.go
Normal file
34
fileserver/utils/http.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var HttpReqContext, HttpReqCancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
func HttpCommon(method, url string, header map[string][]string, reader io.Reader) (int, []byte, error) {
|
||||||
|
req, err := http.NewRequestWithContext(HttpReqContext, method, url, reader)
|
||||||
|
if err != nil {
|
||||||
|
return -1, nil, err
|
||||||
|
}
|
||||||
|
req.Header = header
|
||||||
|
|
||||||
|
rsp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return -1, nil, err
|
||||||
|
}
|
||||||
|
defer rsp.Body.Close()
|
||||||
|
|
||||||
|
if rsp.StatusCode == http.StatusNotFound {
|
||||||
|
return rsp.StatusCode, nil, fmt.Errorf("url %s not found", url)
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(rsp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return rsp.StatusCode, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rsp.StatusCode, body, nil
|
||||||
|
}
|
@@ -24,7 +24,7 @@ struct _SeafileSession {
|
|||||||
GKeyFile *ccnet_config;
|
GKeyFile *ccnet_config;
|
||||||
SeafDB *db;
|
SeafDB *db;
|
||||||
SeafDB *ccnet_db;
|
SeafDB *ccnet_db;
|
||||||
SeafDB *seahub_db;
|
char *seahub_pk;
|
||||||
|
|
||||||
SeafBlockManager *block_mgr;
|
SeafBlockManager *block_mgr;
|
||||||
SeafFSManager *fs_mgr;
|
SeafFSManager *fs_mgr;
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
#include <jwt.h>
|
||||||
|
|
||||||
#include "seafile-session.h"
|
#include "seafile-session.h"
|
||||||
#include "http-tx-mgr.h"
|
#include "http-tx-mgr.h"
|
||||||
@@ -289,29 +290,13 @@ send_request (void *ptr, size_t size, size_t nmemb, void *userp)
|
|||||||
return copy_size;
|
return copy_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
http_post (Connection *conn, const char *url, const char *token,
|
http_post_common (CURL *curl, const char *url, const char *token,
|
||||||
const char *req_content, gint64 req_size,
|
const char *req_content, gint64 req_size,
|
||||||
int *rsp_status, char **rsp_content, gint64 *rsp_size,
|
int *rsp_status, char **rsp_content, gint64 *rsp_size,
|
||||||
gboolean timeout, int timeout_sec)
|
gboolean timeout, int timeout_sec)
|
||||||
{
|
{
|
||||||
char *token_header;
|
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
CURL *curl;
|
|
||||||
|
|
||||||
curl = conn->curl;
|
|
||||||
|
|
||||||
g_return_val_if_fail (req_content != NULL, -1);
|
|
||||||
|
|
||||||
headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")");
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
token_header = g_strdup_printf ("Seafile-Repo-Token: %s", token);
|
|
||||||
headers = curl_slist_append (headers, token_header);
|
|
||||||
g_free (token_header);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||||
@@ -378,9 +363,190 @@ http_post (Connection *conn, const char *url, const char *token,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
conn->release = TRUE;
|
|
||||||
g_free (rsp.content);
|
g_free (rsp.content);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
http_post (Connection *conn, const char *url, const char *token,
|
||||||
|
const char *req_content, gint64 req_size,
|
||||||
|
int *rsp_status, char **rsp_content, gint64 *rsp_size,
|
||||||
|
gboolean timeout, int timeout_sec)
|
||||||
|
{
|
||||||
|
char *token_header;
|
||||||
|
struct curl_slist *headers = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
CURL *curl;
|
||||||
|
|
||||||
|
curl = conn->curl;
|
||||||
|
|
||||||
|
headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")");
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
token_header = g_strdup_printf ("Seafile-Repo-Token: %s", token);
|
||||||
|
headers = curl_slist_append (headers, token_header);
|
||||||
|
g_free (token_header);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_return_val_if_fail (req_content != NULL, -1);
|
||||||
|
|
||||||
|
ret = http_post_common (curl, url, token, req_content, req_size,
|
||||||
|
rsp_status, rsp_content, rsp_size, timeout, timeout_sec);
|
||||||
|
if (ret < 0) {
|
||||||
|
conn->release = TRUE;
|
||||||
|
}
|
||||||
curl_slist_free_all (headers);
|
curl_slist_free_all (headers);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
parse_nickname (const char *rsp_content, int rsp_size)
|
||||||
|
{
|
||||||
|
json_t *array = NULL, *object, *member;
|
||||||
|
json_error_t jerror;
|
||||||
|
size_t n;
|
||||||
|
int i;
|
||||||
|
char *nickname = NULL;
|
||||||
|
|
||||||
|
object = json_loadb (rsp_content, rsp_size, 0, &jerror);
|
||||||
|
if (!object) {
|
||||||
|
seaf_warning ("Parse response failed: %s.\n", jerror.text);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
array = json_object_get (object, "user_list");
|
||||||
|
if (!array) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = json_array_size (array);
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
json_t *obj = json_array_get (array, i);
|
||||||
|
|
||||||
|
member = json_object_get (obj, "name");
|
||||||
|
if (!member) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nickname = g_strdup (json_string_value(member));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
json_decref (object);
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
gen_jwt_token ()
|
||||||
|
{
|
||||||
|
char *jwt_token = NULL;
|
||||||
|
gint64 now = (gint64)time(NULL);
|
||||||
|
|
||||||
|
jwt_t *jwt = NULL;
|
||||||
|
|
||||||
|
if (!seaf->seahub_pk) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = jwt_new (&jwt);
|
||||||
|
if (ret != 0 || jwt == NULL) {
|
||||||
|
seaf_warning ("Failed to create jwt\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = jwt_add_grant_bool (jwt, "is_internal", TRUE);
|
||||||
|
if (ret != 0) {
|
||||||
|
seaf_warning ("Failed to add is_internal to jwt\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = jwt_add_grant_int (jwt, "exp", now + 300);
|
||||||
|
if (ret != 0) {
|
||||||
|
seaf_warning ("Failed to add expire time to jwt\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = jwt_set_alg (jwt, JWT_ALG_HS256, (unsigned char *)seaf->seahub_pk, strlen(seaf->seahub_pk));
|
||||||
|
if (ret != 0) {
|
||||||
|
seaf_warning ("Failed to set alg\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
jwt_token = jwt_encode_str (jwt);
|
||||||
|
|
||||||
|
out:
|
||||||
|
jwt_free (jwt);
|
||||||
|
return jwt_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
http_tx_manager_get_nickname (const char *modifier)
|
||||||
|
{
|
||||||
|
Connection *conn = NULL;
|
||||||
|
char *token_header;
|
||||||
|
struct curl_slist *headers = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
CURL *curl;
|
||||||
|
json_t *content = NULL;
|
||||||
|
json_t *array = NULL;
|
||||||
|
int rsp_status;
|
||||||
|
char *req_content = NULL;
|
||||||
|
char *jwt_token = NULL;
|
||||||
|
char *rsp_content = NULL;
|
||||||
|
char *nickname = NULL;
|
||||||
|
gint64 rsp_size;
|
||||||
|
|
||||||
|
jwt_token = gen_jwt_token ();
|
||||||
|
if (!jwt_token) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = connection_pool_get_connection (seaf->seahub_conn_pool);
|
||||||
|
if (!conn) {
|
||||||
|
g_free (jwt_token);
|
||||||
|
seaf_warning ("Failed to get connection: out of memory.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = json_object ();
|
||||||
|
array = json_array ();
|
||||||
|
json_array_append_new (array, json_string (modifier));
|
||||||
|
json_object_set_new (content, "user_id_list", array);
|
||||||
|
req_content = json_dumps (content, JSON_COMPACT);
|
||||||
|
if (!req_content) {
|
||||||
|
json_decref (content);
|
||||||
|
seaf_warning ("Failed to dump json request.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
json_decref (content);
|
||||||
|
|
||||||
|
curl = conn->curl;
|
||||||
|
headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")");
|
||||||
|
token_header = g_strdup_printf ("Authorization: Token %s", jwt_token);
|
||||||
|
headers = curl_slist_append (headers, token_header);
|
||||||
|
headers = curl_slist_append (headers, "Content-Type: application/json");
|
||||||
|
g_free (token_header);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||||
|
|
||||||
|
ret = http_post_common (curl, seaf->seahub_url, jwt_token, req_content, strlen(req_content),
|
||||||
|
&rsp_status, &rsp_content, &rsp_size, TRUE, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
conn->release = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsp_status != HTTP_OK) {
|
||||||
|
seaf_warning ("Failed to get user list from seahub %d.\n",
|
||||||
|
rsp_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
nickname = parse_nickname (rsp_content, rsp_size);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (jwt_token);
|
||||||
|
g_free (req_content);
|
||||||
|
g_free (rsp_content);
|
||||||
|
connection_pool_return_connection (seaf->seahub_conn_pool, conn);
|
||||||
|
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
@@ -45,4 +45,7 @@ http_post (Connection *conn, const char *url, const char *token,
|
|||||||
|
|
||||||
void
|
void
|
||||||
http_tx_manager_init ();
|
http_tx_manager_init ();
|
||||||
|
|
||||||
|
char *
|
||||||
|
http_tx_manager_get_nickname (const char *modifier);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -218,7 +218,7 @@ seafile_session_new(const char *central_config_dir,
|
|||||||
goto onerror;
|
goto onerror;
|
||||||
}
|
}
|
||||||
|
|
||||||
load_seahub_database_config (session);
|
load_seahub_private_key (session, abs_central_config_dir ? abs_central_config_dir : abs_seafile_dir);
|
||||||
|
|
||||||
session->cfg_mgr = seaf_cfg_manager_new (session);
|
session->cfg_mgr = seaf_cfg_manager_new (session);
|
||||||
if (!session->cfg_mgr)
|
if (!session->cfg_mgr)
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "zip-download-mgr.h"
|
#include "zip-download-mgr.h"
|
||||||
#include "index-blocks-mgr.h"
|
#include "index-blocks-mgr.h"
|
||||||
#include "notif-mgr.h"
|
#include "notif-mgr.h"
|
||||||
|
#include "http-tx-mgr.h"
|
||||||
|
|
||||||
#include <searpc-client.h>
|
#include <searpc-client.h>
|
||||||
|
|
||||||
@@ -47,7 +48,9 @@ struct _SeafileSession {
|
|||||||
GKeyFile *ccnet_config;
|
GKeyFile *ccnet_config;
|
||||||
SeafDB *db;
|
SeafDB *db;
|
||||||
CcnetDB *ccnet_db;
|
CcnetDB *ccnet_db;
|
||||||
SeafDB *seahub_db;
|
char *seahub_pk;
|
||||||
|
char *seahub_url;
|
||||||
|
ConnectionPool *seahub_conn_pool;
|
||||||
|
|
||||||
SeafBlockManager *block_mgr;
|
SeafBlockManager *block_mgr;
|
||||||
SeafFSManager *fs_mgr;
|
SeafFSManager *fs_mgr;
|
||||||
|
Reference in New Issue
Block a user