diff --git a/fileserver/fileop.go b/fileserver/fileop.go index e896fc17..ec1893dd 100644 --- a/fileserver/fileop.go +++ b/fileserver/fileop.go @@ -30,7 +30,6 @@ import ( "sort" "syscall" - jwt "github.com/golang-jwt/jwt/v5" "github.com/gorilla/mux" "github.com/haiwen/seafile-server/fileserver/blockmgr" "github.com/haiwen/seafile-server/fileserver/commitmgr" @@ -324,19 +323,12 @@ type UserInfo struct { } func checkFileAccess(repoID, token, cookie, filePath, op string) (string, *appError) { - claims := SeahubClaims{ - time.Now().Add(time.Second * 300).Unix(), - true, - jwt.RegisteredClaims{}, - } - - jwtToken := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &claims) - tokenString, err := jwtToken.SignedString([]byte(seahubPK)) + tokenString, err := utils.GenJWTToken("", "", true) if err != nil { err := fmt.Errorf("failed to sign jwt token: %v", err) return "", &appError{err, "", http.StatusInternalServerError} } - url := fmt.Sprintf("%s/repos/%s/check-access/?path=%s", seahubURL, repoID, filePath) + url := fmt.Sprintf("%s/repos/%s/check-access/?path=%s", option.SeahubURL, repoID, filePath) header := map[string][]string{ "Authorization": {"Token " + tokenString}, } @@ -2097,7 +2089,7 @@ func notifRepoUpdate(repoID string, commitID string) error { } url := fmt.Sprintf("http://%s/events", option.NotificationURL) - token, err := genJWTToken(repoID, "") + token, err := utils.GenJWTToken(repoID, "", false) if err != nil { log.Printf("failed to generate jwt token: %v", err) return err @@ -3631,19 +3623,12 @@ type ShareLinkInfo struct { } func queryShareLinkInfo(token, cookie, opType string) (*ShareLinkInfo, *appError) { - claims := SeahubClaims{ - time.Now().Add(time.Second * 300).Unix(), - true, - jwt.RegisteredClaims{}, - } - - jwtToken := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &claims) - tokenString, err := jwtToken.SignedString([]byte(seahubPK)) + tokenString, err := utils.GenJWTToken("", "", true) if err != nil { err := fmt.Errorf("failed to sign jwt token: %v", err) return nil, &appError{err, "", http.StatusInternalServerError} } - url := fmt.Sprintf("%s?token=%s&type=%s", seahubURL+"/check-share-link-access/", token, opType) + url := fmt.Sprintf("%s?token=%s&type=%s", option.SeahubURL+"/check-share-link-access/", token, opType) header := map[string][]string{ "Authorization": {"Token " + tokenString}, } @@ -3671,7 +3656,7 @@ func queryShareLinkInfo(token, cookie, opType string) (*ShareLinkInfo, *appError } func accessLinkCB(rsp http.ResponseWriter, r *http.Request) *appError { - if seahubPK == "" { + if option.PrivateKey == "" { err := fmt.Errorf("no seahub private key is configured") return &appError{err, "", http.StatusNotFound} } diff --git a/fileserver/fileserver.go b/fileserver/fileserver.go index bbd589dc..d2929d8d 100644 --- a/fileserver/fileserver.go +++ b/fileserver/fileserver.go @@ -43,7 +43,6 @@ var logFp *os.File var dbType string var seafileDB, ccnetDB *sql.DB -var seahubURL, seahubPK string func init() { flag.StringVar(¢ralDir, "F", "", "central config directory") @@ -264,22 +263,6 @@ func loadSeafileDB() { dbType = dbEngine } -func loadSeahubConfig() error { - seahubPK = os.Getenv("JWT_PRIVATE_KEY") - if seahubPK == "" { - return fmt.Errorf("failed to read JWT_PRIVATE_KEY") - } - - siteRoot := os.Getenv("SITE_ROOT") - if siteRoot != "" { - seahubURL = fmt.Sprintf("http://127.0.0.1:8000%sapi/v2.1/internal", siteRoot) - } else { - seahubURL = "http://127.0.0.1:8000/api/v2.1/internal" - } - - return nil -} - func writePidFile(pid_file_path string) error { file, err := os.OpenFile(pid_file_path, os.O_CREATE|os.O_WRONLY, 0664) if err != nil { @@ -378,7 +361,7 @@ func main() { fp.Close() } - if err := loadSeahubConfig(); err != nil { + if err := option.LoadSeahubConfig(); err != nil { log.Fatalf("Failed to read seahub config: %v", err) } diff --git a/fileserver/merge.go b/fileserver/merge.go index dcd6b488..022dc894 100644 --- a/fileserver/merge.go +++ b/fileserver/merge.go @@ -10,9 +10,9 @@ import ( "strings" "time" - jwt "github.com/golang-jwt/jwt/v5" "github.com/haiwen/seafile-server/fileserver/commitmgr" "github.com/haiwen/seafile-server/fileserver/fsmgr" + "github.com/haiwen/seafile-server/fileserver/option" "github.com/haiwen/seafile-server/fileserver/utils" ) @@ -381,7 +381,7 @@ func getNickNameByModifier(emailToNickname map[string]string, modifier string) s if ok { return nickname } - if seahubPK != "" { + if option.PrivateKey != "" { nickname = postGetNickName(modifier) } @@ -394,25 +394,8 @@ func getNickNameByModifier(emailToNickname map[string]string, modifier string) s return nickname } -type SeahubClaims struct { - Exp int64 - IsInternal bool `json:"is_internal"` - jwt.RegisteredClaims -} - -func (*SeahubClaims) Valid() error { - return nil -} - func postGetNickName(modifier string) string { - claims := SeahubClaims{ - time.Now().Add(time.Second * 300).Unix(), - true, - jwt.RegisteredClaims{}, - } - - token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &claims) - tokenString, err := token.SignedString([]byte(seahubPK)) + tokenString, err := utils.GenJWTToken("", "", true) if err != nil { return "" } @@ -428,7 +411,7 @@ func postGetNickName(modifier string) string { return "" } - url := seahubURL + "/user-list/" + url := option.SeahubURL + "/user-list/" status, body, err := utils.HttpCommon("POST", url, header, bytes.NewReader(data)) if err != nil { return "" diff --git a/fileserver/option/option.go b/fileserver/option/option.go index 9c7ba0bd..aa2892b0 100644 --- a/fileserver/option/option.go +++ b/fileserver/option/option.go @@ -3,6 +3,7 @@ package option import ( "fmt" "log" + "os" "path/filepath" "strconv" "strings" @@ -62,6 +63,10 @@ var ( // DB default timeout DBOpTimeout time.Duration + + // seahub + SeahubURL string + PrivateKey string ) func initDefaultOptions() { @@ -256,3 +261,19 @@ func parseQuota(quotaStr string) int64 { return quota } + +func LoadSeahubConfig() error { + PrivateKey = os.Getenv("JWT_PRIVATE_KEY") + if PrivateKey == "" { + return fmt.Errorf("failed to read JWT_PRIVATE_KEY") + } + + siteRoot := os.Getenv("SITE_ROOT") + if siteRoot != "" { + SeahubURL = fmt.Sprintf("http://127.0.0.1:8000%sapi/v2.1/internal", siteRoot) + } else { + SeahubURL = "http://127.0.0.1:8000/api/v2.1/internal" + } + + return nil +} diff --git a/fileserver/sync_api.go b/fileserver/sync_api.go index c1ef70be..fd533d68 100644 --- a/fileserver/sync_api.go +++ b/fileserver/sync_api.go @@ -17,7 +17,6 @@ import ( "sync" "time" - jwt "github.com/golang-jwt/jwt/v5" "github.com/gorilla/mux" "github.com/haiwen/seafile-server/fileserver/blockmgr" "github.com/haiwen/seafile-server/fileserver/commitmgr" @@ -726,17 +725,6 @@ func getCheckQuotaCB(rsp http.ResponseWriter, r *http.Request) *appError { return nil } -type MyClaims struct { - Exp int64 - RepoID string `json:"repo_id"` - UserName string `json:"username"` - jwt.RegisteredClaims -} - -func (*MyClaims) Valid() error { - return nil -} - func getJWTTokenCB(rsp http.ResponseWriter, r *http.Request) *appError { vars := mux.Vars(r) repoID := vars["repoid"] @@ -750,7 +738,7 @@ func getJWTTokenCB(rsp http.ResponseWriter, r *http.Request) *appError { return appErr } - tokenString, err := genJWTToken(repoID, user) + tokenString, err := utils.GenJWTToken(repoID, user, false) if err != nil { return &appError{err, "", http.StatusInternalServerError} } @@ -762,24 +750,6 @@ func getJWTTokenCB(rsp http.ResponseWriter, r *http.Request) *appError { return nil } -func genJWTToken(repoID, user string) (string, error) { - claims := MyClaims{ - time.Now().Add(time.Hour * 72).Unix(), - repoID, - user, - jwt.RegisteredClaims{}, - } - - token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &claims) - tokenString, err := token.SignedString([]byte(seahubPK)) - if err != nil { - err := fmt.Errorf("failed to gen jwt token for repo %s", repoID) - return "", err - } - - return tokenString, nil -} - func getFsObjIDCB(rsp http.ResponseWriter, r *http.Request) *appError { recvChan := make(chan *calResult) diff --git a/fileserver/utils/utils.go b/fileserver/utils/utils.go index 34f1ad1e..f031f470 100644 --- a/fileserver/utils/utils.go +++ b/fileserver/utils/utils.go @@ -1,7 +1,12 @@ package utils import ( + "fmt" + "time" + + jwt "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" + "github.com/haiwen/seafile-server/fileserver/option" ) func IsValidUUID(u string) bool { @@ -22,3 +27,36 @@ func IsObjectIDValid(objID string) bool { } return true } + +type MyClaims struct { + Exp int64 `json:"exp"` + RepoID string `json:"repo_id,omitempty"` + UserName string `json:"username,omitempty"` + IsInternal bool `json:"is_internal,omitempty"` + jwt.RegisteredClaims +} + +func (*MyClaims) Valid() error { + return nil +} + +func GenJWTToken(repoID, user string, isInternal bool) (string, error) { + claims := new(MyClaims) + if isInternal { + claims.Exp = time.Now().Add(time.Second * 300).Unix() + claims.IsInternal = true + } else { + claims.Exp = time.Now().Add(time.Hour * 72).Unix() + claims.RepoID = repoID + claims.UserName = user + } + + token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), claims) + tokenString, err := token.SignedString([]byte(option.PrivateKey)) + if err != nil { + err := fmt.Errorf("failed to gen jwt token for repo %s", repoID) + return "", err + } + + return tokenString, nil +}