From 749af9b6f284ea6e9f57b80f84288311844a9cc8 Mon Sep 17 00:00:00 2001 From: wj00037 <1292876134@qq.com> Date: Mon, 21 Oct 2024 15:34:13 +0800 Subject: [PATCH 1/3] add 403, add logs --- auth/client.go | 8 ++++---- auth/gitee.go | 32 ++++++++++++++++++++------------ server/server.go | 19 ++++++++++++------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/auth/client.go b/auth/client.go index a2a4d68..e0a6348 100644 --- a/auth/client.go +++ b/auth/client.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "net/http" - "strings" ) type Client struct { @@ -19,7 +18,6 @@ func getParsedResponse(method, path string, header http.Header, body io.Reader, panic(err) } req.Header = header - fmt.Println(strings.Split(path, "?")[0]) response, err := http.DefaultClient.Do(req) if err != nil { panic(err) @@ -27,11 +25,13 @@ func getParsedResponse(method, path string, header http.Header, body io.Reader, defer response.Body.Close() if response.StatusCode/100 != 2 { if response.StatusCode == http.StatusNotFound { - return errors.New("repository not found") + return errors.New("not_found") } else if response.StatusCode == http.StatusUnauthorized { return errors.New("unauthorized") + } else if response.StatusCode == http.StatusForbidden { + return errors.New("forbidden") } - return errors.New("error occurred accessing gitee") + return fmt.Errorf("other error: %v", response.StatusCode) } data, err := io.ReadAll(response.Body) if err != nil { diff --git a/auth/gitee.go b/auth/gitee.go index cbf7177..43623cb 100644 --- a/auth/gitee.go +++ b/auth/gitee.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/metalogical/BigFiles/config" + "github.com/sirupsen/logrus" ) var ( @@ -23,7 +24,6 @@ var ( ) type giteeUser struct { - Login string `json:"login"` Permission string `json:"permission"` } @@ -101,7 +101,8 @@ func CheckRepoOwner(userInRepo UserInRepo) error { repo := new(Repo) err := getParsedResponse("GET", path, headers, nil, &repo) if err != nil { - return err + msg := err.Error() + ": check repo_id failed" + return errors.New(msg) } for _, allowedRepo := range allowedRepos { if strings.Split(repo.Fullname, "/")[0] == allowedRepo { @@ -116,8 +117,9 @@ func CheckRepoOwner(userInRepo UserInRepo) error { } } } - - return errors.New("your repository does not appear to have permission to use this lfs service") + msg := "forbidden: repo has no permission to use this lfs server" + logrus.Error(fmt.Sprintf("CheckRepoOwner: %s", msg)) + return errors.New(msg) } // getToken gets access_token by username and password @@ -135,7 +137,8 @@ func getToken(username, password string) (string, error) { accessToken := new(AccessToken) err := getParsedResponse("POST", path, headers, strings.NewReader(form.Encode()), &accessToken) if err != nil { - return "", err + msg := err.Error() + ": get token failed. Or may be it is already a token" + return "", errors.New(msg) } return accessToken.Token, nil @@ -156,27 +159,32 @@ func verifyUser(userInRepo UserInRepo) error { giteeUser := new(giteeUser) err := getParsedResponse("GET", path, headers, nil, &giteeUser) if err != nil { - return err + msg := err.Error() + ": verify user permission failed" + logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + return errors.New(msg) } - if giteeUser.Login != userInRepo.Username { - return errors.New("username does not match") - } if userInRepo.Operation == "upload" { for _, v := range uploadPermissions { if giteeUser.Permission == v { return nil } } - return errors.New("user has no permission uploading to the repository") + msg := "forbidden: user has no permission to upload" + logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + return errors.New(msg) } else if userInRepo.Operation == "download" { for _, v := range downloadPermissions { if giteeUser.Permission == v { return nil } } - return errors.New("user has no permission downloading in the repository") + msg := "forbidden: user has no permission to download" + logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + return errors.New(msg) } else { - return errors.New("unknow operation") + msg := "other error: unknow operation" + logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + return errors.New(msg) } } diff --git a/server/server.go b/server/server.go index 4e0f1f9..241e493 100644 --- a/server/server.go +++ b/server/server.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "regexp" + "strings" "time" "github.com/go-chi/chi" @@ -139,18 +140,22 @@ func (s *server) handleBatch(w http.ResponseWriter, r *http.Request) { userInRepo.Username = username userInRepo.Password = password err = s.isAuthorized(userInRepo) - // TODO: 若仓库无lfs服务权限,不能返回401,否则会继续提示输入用户名密码。返回403 - if err != nil { - err = fmt.Errorf("unauthorized: %w", err) - } } else { - err = errors.New("Unauthorized") + err = errors.New("unauthorized: cannot get password") } if err != nil { + v := err.Error() + switch { + case strings.HasPrefix(v, "unauthorized") || strings.HasPrefix(v, "not_found"): + w.WriteHeader(401) + case strings.HasPrefix(v, "forbidden"): + w.WriteHeader(403) + default: + w.WriteHeader(500) + } w.Header().Set("LFS-Authenticate", `Basic realm="Git LFS"`) - w.WriteHeader(401) must(json.NewEncoder(w).Encode(batch.ErrorResponse{ - Message: err.Error(), + Message: v, })) return } From 57b01d6ba27bd4545b271aa3bcd43091ad102124 Mon Sep 17 00:00:00 2001 From: wj00037 <1292876134@qq.com> Date: Mon, 28 Oct 2024 20:46:56 +0800 Subject: [PATCH 2/3] add fork err msg, add query url --- README.md | 3 ++- auth/client.go | 12 +++++++++++- auth/gitee.go | 23 ++++++++++++++--------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4a8ff1d..c1be88c 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,5 @@ v2.12.0](https://github.com/git-lfs/git-lfs/tree/v2.12.0/docs/api) server. 5. ~~认证时校验用户在仓库内权限。~~ 6. 支持ssh。 7. ~~仓库添加github action。~~ -8. 添加日志。 +8. ~~添加日志。~~ +9. 支持cdn。 diff --git a/auth/client.go b/auth/client.go index e0a6348..aa3edf5 100644 --- a/auth/client.go +++ b/auth/client.go @@ -6,6 +6,9 @@ import ( "fmt" "io" "net/http" + "strings" + + "github.com/sirupsen/logrus" ) type Client struct { @@ -23,6 +26,13 @@ func getParsedResponse(method, path string, header http.Header, body io.Reader, panic(err) } defer response.Body.Close() + + if splitPath := strings.Split(path, "?"); len(splitPath) != 1 { + logrus.Infof("query %s with token | %d", splitPath[0], response.StatusCode) + } else { + logrus.Infof("query %s without token | %d", splitPath[0], response.StatusCode) + } + if response.StatusCode/100 != 2 { if response.StatusCode == http.StatusNotFound { return errors.New("not_found") @@ -31,7 +41,7 @@ func getParsedResponse(method, path string, header http.Header, body io.Reader, } else if response.StatusCode == http.StatusForbidden { return errors.New("forbidden") } - return fmt.Errorf("other error: %v", response.StatusCode) + return fmt.Errorf("system_error: %v", response.StatusCode) } data, err := io.ReadAll(response.Body) if err != nil { diff --git a/auth/gitee.go b/auth/gitee.go index 43623cb..87ca5bb 100644 --- a/auth/gitee.go +++ b/auth/gitee.go @@ -118,7 +118,7 @@ func CheckRepoOwner(userInRepo UserInRepo) error { } } msg := "forbidden: repo has no permission to use this lfs server" - logrus.Error(fmt.Sprintf("CheckRepoOwner: %s", msg)) + logrus.Error(fmt.Sprintf("CheckRepoOwner | %s", msg)) return errors.New(msg) } @@ -160,7 +160,7 @@ func verifyUser(userInRepo UserInRepo) error { err := getParsedResponse("GET", path, headers, nil, &giteeUser) if err != nil { msg := err.Error() + ": verify user permission failed" - logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + logrus.Error(fmt.Sprintf("verifyUser | %s", msg)) return errors.New(msg) } @@ -170,21 +170,26 @@ func verifyUser(userInRepo UserInRepo) error { return nil } } - msg := "forbidden: user has no permission to upload" - logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) - return errors.New(msg) + msg := fmt.Sprintf("forbidden: user %s has no permission to upload to %s/%s", + userInRepo.Username, userInRepo.Owner, userInRepo.Repo) + remindMsg := " \n如果您正在向fork仓库上传大文件,请确认您已使用如下命令修改了本地仓库的配置:" + + "\n`git config --local lfs.url https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo}`" + + ",\n其中{owner}/{repo}请改为您fork之后的仓库的名称。" + + "详阅:https://github.com/opensourceways/BigFiles/blob/master/docs/QuickStart.md" + logrus.Error(fmt.Sprintf("verifyUser | %s", msg)) + return errors.New(msg + remindMsg) } else if userInRepo.Operation == "download" { for _, v := range downloadPermissions { if giteeUser.Permission == v { return nil } } - msg := "forbidden: user has no permission to download" - logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + msg := fmt.Sprintf("forbidden: user %s has no permission to download", userInRepo.Username) + logrus.Error(fmt.Sprintf("verifyUser | %s", msg)) return errors.New(msg) } else { - msg := "other error: unknow operation" - logrus.Error(fmt.Sprintf("verifyUser: %s", msg)) + msg := "system_error: unknow operation" + logrus.Error(fmt.Sprintf("verifyUser | %s", msg)) return errors.New(msg) } } From 921dba83d5af5c36da23fe0b9a91d8fdd7a4e530 Mon Sep 17 00:00:00 2001 From: wj00037 <1292876134@qq.com> Date: Tue, 29 Oct 2024 10:30:11 +0800 Subject: [PATCH 3/3] update docs --- docs/BasicGuide.md | 4 ++-- docs/QuickStart.md | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/BasicGuide.md b/docs/BasicGuide.md index f921308..e73ba0a 100644 --- a/docs/BasicGuide.md +++ b/docs/BasicGuide.md @@ -53,7 +53,7 @@ Git LFS initialized. ``` [lfs] -   url = https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo} + url = https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo} ``` - 或者通过命令行设置仓库中LFS远程地址: @@ -63,7 +63,7 @@ git config --local lfs.url https://openeuler-bigfiles.test.osinfra.cn/{owner}/{r ``` > - 当存在.lfsconfig文件时,使用命令行进行LFS远程地址设置的优先级将高于.lfsconfig文件。 -> - 在fork一个已经使用第三方LFS服务服务作为LFS远程服务的仓库后,需要手动修改新仓库中LFS远程地址中的{owner}以及{repo},否则会出现权限校验问题,**错误代码401**。 +> - 在fork一个已经使用第三方LFS服务服务作为LFS远程服务的仓库后,需要需手动使用上述命令设置仓库中LFS远程地址,否则可能会出现权限校验问题,**错误代码401**。 > - url中{owner}/{repo}替换为实际的仓库路径,注意仓库路径的大小写。 - 选择要用LFS追踪的文件 diff --git a/docs/QuickStart.md b/docs/QuickStart.md index f45733d..726ed4c 100644 --- a/docs/QuickStart.md +++ b/docs/QuickStart.md @@ -12,7 +12,7 @@ ``` [lfs] -    url = https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo} + url = https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo} ``` - 或者通过命令行设置仓库中LFS远程地址: @@ -22,16 +22,19 @@ $ git config --local lfs.url https://openeuler-bigfiles.test.osinfra.cn/{owner}/ ``` > 当存在.lfsconfig文件时,使用命令行进行LFS远程地址设置的优先级将高于.lfsconfig文件。 - url中{owner}/{repo}替换为实际的仓库路径,如:openeuler/lfs。由于Gitee默认会将仓库路径中的大写转化为小写,请确认仓库路径的大小写。 +> url中{owner}/{repo}替换为实际的仓库路径,如:openeuler/lfs。由于Gitee默认会将仓库路径中的大写转化为小写,请确认仓库路径的大小写。 ## 第三方LFS服务与Gitee的使用差异 关于GIT LFS的基本使用请详阅[基础教程](BasicGuide.md)。我们努力使第三方LFS服务与原生LFS服务的使用差异尽可能少,以下是现存的一些差异: -- 当您fork一个仓库: - - 在fork一个已经使用第三方LFS服务作为LFS远程服务的仓库后,需要手动修改新仓库中LFS远程地址中的{owner}以及{repo},否则会出现权限校验问题,**错误代码401**。 -- 当您使用ssh协议进行克隆或推送: - - 在使用SSH对Gitee仓库进行克隆后,在使用第三方LFS服务作为LFS远程服务时,仍然需要输入账户和密码。 +- 当您fork一个仓库:将fork仓库克隆到本地后,需手动使用如下命令修改本地仓库的lfs配置: + + ``` + $ git config --local lfs.url https://openeuler-bigfiles.test.osinfra.cn/{owner}/{repo} + ``` + +- 当您使用ssh协议进行克隆或推送:克隆或推送大文件时仍需输入用户名和密码进行认证。 ## 迁移Gitee中使用LFS服务的仓库中的大文件