From 9e6bbd3386145c4b6a16c49439a25469b3597695 Mon Sep 17 00:00:00 2001 From: naiba Date: Sat, 19 Oct 2024 23:14:53 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20init=20swaggo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 5 - .gitignore | 1 + cmd/dashboard/controller/common_page.go | 9 + cmd/dashboard/controller/controller.go | 5 + cmd/dashboard/controller/guest_page.go | 5 - cmd/dashboard/controller/member_api.go | 6 +- cmd/dashboard/controller/oauth2.go | 296 ------------------------ cmd/dashboard/main.go | 7 +- go.mod | 26 +-- go.sum | 92 ++++---- model/config.go | 11 +- model/user.go | 68 +----- pkg/mygin/auth.go | 3 +- pkg/oidc/cloudflare/cloudflare.go | 22 -- pkg/oidc/general/general.go | 56 ----- proto/nezha.pb.go | 22 +- proto/nezha_grpc.pb.go | 2 +- script/{proto.sh => bootstrap.sh} | 1 + 18 files changed, 108 insertions(+), 529 deletions(-) delete mode 100644 cmd/dashboard/controller/oauth2.go delete mode 100644 pkg/oidc/cloudflare/cloudflare.go delete mode 100644 pkg/oidc/general/general.go rename script/{proto.sh => bootstrap.sh} (69%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc91970..ed3b310 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,17 +2,12 @@ name: Run Tests on: push: - branches: - - master paths: - "**.go" - "go.mod" - "go.sum" - "resource/**" - ".github/workflows/test.yml" - pull_request: - branches: - - master jobs: tests: diff --git a/.gitignore b/.gitignore index 41e59cc..ba67c4e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ /config.yml /resource/template/theme-custom /resource/static/custom +/cmd/dashboard/docs diff --git a/cmd/dashboard/controller/common_page.go b/cmd/dashboard/controller/common_page.go index a2cf93a..eb8d09f 100644 --- a/cmd/dashboard/controller/common_page.go +++ b/cmd/dashboard/controller/common_page.go @@ -54,6 +54,15 @@ type viewPasswordForm struct { Password string } +// PingExample godoc +// @Summary ping example +// @Schemes +// @Description do ping +// @Tags example +// @Accept json +// @Produce json +// @Success 200 {string} Helloworld +// @Router /example/helloworld [get] func (p *commonPage) issueViewPassword(c *gin.Context) { var vpf viewPasswordForm err := c.ShouldBind(&vpf) diff --git a/cmd/dashboard/controller/controller.go b/cmd/dashboard/controller/controller.go index 51d1f74..5913a1e 100644 --- a/cmd/dashboard/controller/controller.go +++ b/cmd/dashboard/controller/controller.go @@ -16,7 +16,10 @@ import ( "github.com/gin-gonic/gin" "github.com/hashicorp/go-uuid" "github.com/nicksnyder/go-i18n/v2/i18n" + swaggerfiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" + docs "github.com/naiba/nezha/cmd/dashboard/docs" "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" "github.com/naiba/nezha/pkg/utils" @@ -29,11 +32,13 @@ import ( func ServeWeb(port uint) *http.Server { gin.SetMode(gin.ReleaseMode) r := gin.Default() + docs.SwaggerInfo.BasePath = "/api/v1" if singleton.Conf.Debug { gin.SetMode(gin.DebugMode) pprof.Register(r) } r.Use(natGateway) + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) tmpl := template.New("").Funcs(funcMap) var err error tmpl, err = tmpl.ParseFS(resource.TemplateFS, "template/**/*.html") diff --git a/cmd/dashboard/controller/guest_page.go b/cmd/dashboard/controller/guest_page.go index 2ea91a9..37546ad 100644 --- a/cmd/dashboard/controller/guest_page.go +++ b/cmd/dashboard/controller/guest_page.go @@ -27,11 +27,6 @@ func (gp *guestPage) serve() { })) gr.GET("/login", gp.login) - - oauth := &oauth2controller{ - r: gr, - } - oauth.serve() } func (gp *guestPage) login(c *gin.Context) { diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 4d76a2d..da2bd77 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -991,8 +991,8 @@ func (ma *memberAPI) logout(c *gin.Context) { return } singleton.DB.Model(admin).UpdateColumns(model.User{ - Token: "", - TokenExpired: time.Now(), + // Token: "", + // TokenExpired: time.Now(), }) c.JSON(http.StatusOK, model.Response{ Code: http.StatusOK, @@ -1071,7 +1071,7 @@ func (ma *memberAPI) updateSetting(c *gin.Context) { singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on" singleton.Conf.DisableSwitchTemplateInFrontend = sf.DisableSwitchTemplateInFrontend == "on" singleton.Conf.Cover = sf.Cover - singleton.Conf.GRPCHost = sf.GRPCHost + // singleton.Conf.GRPCHost = sf.GRPCHost singleton.Conf.IgnoredIPNotification = sf.IgnoredIPNotification singleton.Conf.IPChangeNotificationTag = sf.IPChangeNotificationTag singleton.Conf.Site.Brand = sf.Title diff --git a/cmd/dashboard/controller/oauth2.go b/cmd/dashboard/controller/oauth2.go deleted file mode 100644 index 3b057ed..0000000 --- a/cmd/dashboard/controller/oauth2.go +++ /dev/null @@ -1,296 +0,0 @@ -package controller - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/coreos/go-oidc/v3/oidc" - "github.com/naiba/nezha/pkg/oidc/cloudflare" - myOidc "github.com/naiba/nezha/pkg/oidc/general" - - "code.gitea.io/sdk/gitea" - "github.com/gin-gonic/gin" - GitHubAPI "github.com/google/go-github/v47/github" - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/pkg/mygin" - "github.com/naiba/nezha/pkg/utils" - "github.com/naiba/nezha/service/singleton" - "github.com/patrickmn/go-cache" - "github.com/xanzy/go-gitlab" - "golang.org/x/oauth2" - GitHubOauth2 "golang.org/x/oauth2/github" - GitlabOauth2 "golang.org/x/oauth2/gitlab" -) - -type oauth2controller struct { - r gin.IRoutes - oidcProvider *oidc.Provider -} - -func (oa *oauth2controller) serve() { - oa.r.GET("/oauth2/login", oa.login) - oa.r.GET("/oauth2/callback", oa.callback) -} - -func (oa *oauth2controller) getCommonOauth2Config(c *gin.Context) *oauth2.Config { - if singleton.Conf.Oauth2.Type == model.ConfigTypeGitee { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: []string{}, - Endpoint: oauth2.Endpoint{ - AuthURL: "https://gitee.com/oauth/authorize", - TokenURL: "https://gitee.com/oauth/token", - }, - RedirectURL: oa.getRedirectURL(c), - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeGitlab { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: []string{"read_user", "read_api"}, - Endpoint: GitlabOauth2.Endpoint, - RedirectURL: oa.getRedirectURL(c), - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeJihulab { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: []string{"read_user", "read_api"}, - Endpoint: oauth2.Endpoint{ - AuthURL: "https://jihulab.com/oauth/authorize", - TokenURL: "https://jihulab.com/oauth/token", - }, - RedirectURL: oa.getRedirectURL(c), - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeGitea { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Endpoint: oauth2.Endpoint{ - AuthURL: fmt.Sprintf("%s/login/oauth/authorize", singleton.Conf.Oauth2.Endpoint), - TokenURL: fmt.Sprintf("%s/login/oauth/access_token", singleton.Conf.Oauth2.Endpoint), - }, - RedirectURL: oa.getRedirectURL(c), - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeCloudflare { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: []string{"openid", "email", "profile", "groups"}, - Endpoint: oauth2.Endpoint{ - AuthURL: fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/authorization", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID), - TokenURL: fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/token", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID), - }, - RedirectURL: oa.getRedirectURL(c), - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeOidc { - var err error - oa.oidcProvider, err = oidc.NewProvider(c.Request.Context(), singleton.Conf.Oauth2.OidcIssuer) - if err != nil { - mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusBadRequest, - Title: fmt.Sprintf("Cannot get OIDC infomaion from issuer from %s", singleton.Conf.Oauth2.OidcIssuer), - Msg: err.Error(), - }, true) - return nil - } - scopes := strings.Split(singleton.Conf.Oauth2.OidcScopes, ",") - scopes = append(scopes, oidc.ScopeOpenID) - uniqueScopes := removeDuplicates(scopes) - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: uniqueScopes, - Endpoint: oa.oidcProvider.Endpoint(), - RedirectURL: oa.getRedirectURL(c), - } - } else { - return &oauth2.Config{ - ClientID: singleton.Conf.Oauth2.ClientID, - ClientSecret: singleton.Conf.Oauth2.ClientSecret, - Scopes: []string{}, - Endpoint: GitHubOauth2.Endpoint, - } - } -} - -func (oa *oauth2controller) getRedirectURL(c *gin.Context) string { - scheme := "http://" - referer := c.Request.Referer() - if forwardedProto := c.Request.Header.Get("X-Forwarded-Proto"); forwardedProto == "https" || strings.HasPrefix(referer, "https://") { - scheme = "https://" - } - return scheme + c.Request.Host + "/oauth2/callback" -} - -func (oa *oauth2controller) login(c *gin.Context) { - randomString, err := utils.GenerateRandomString(32) - if err != nil { - mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusBadRequest, - Title: "Something Wrong", - Msg: err.Error(), - }, true) - return - } - state, stateKey := randomString[:16], randomString[16:] - singleton.Cache.Set(fmt.Sprintf("%s%s", model.CacheKeyOauth2State, stateKey), state, cache.DefaultExpiration) - url := oa.getCommonOauth2Config(c).AuthCodeURL(state, oauth2.AccessTypeOnline) - c.SetCookie(singleton.Conf.Site.CookieName+"-sk", stateKey, 60*5, "", "", false, false) - c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/redirect", mygin.CommonEnvironment(c, gin.H{ - "URL": url, - })) -} - -func (oa *oauth2controller) callback(c *gin.Context) { - var err error - // 验证登录跳转时的 State - stateKey, err := c.Cookie(singleton.Conf.Site.CookieName + "-sk") - if err == nil { - state, ok := singleton.Cache.Get(fmt.Sprintf("%s%s", model.CacheKeyOauth2State, stateKey)) - if !ok || state.(string) != c.Query("state") { - err = errors.New("非法的登录方式") - } - } - oauth2Config := oa.getCommonOauth2Config(c) - ctx := context.Background() - var otk *oauth2.Token - if err == nil { - otk, err = oauth2Config.Exchange(ctx, c.Query("code")) - } - - var user model.User - - if err == nil { - if singleton.Conf.Oauth2.Type == model.ConfigTypeGitlab || singleton.Conf.Oauth2.Type == model.ConfigTypeJihulab { - var gitlabApiClient *gitlab.Client - if singleton.Conf.Oauth2.Type == model.ConfigTypeGitlab { - gitlabApiClient, err = gitlab.NewOAuthClient(otk.AccessToken) - } else { - gitlabApiClient, err = gitlab.NewOAuthClient(otk.AccessToken, gitlab.WithBaseURL("https://jihulab.com/api/v4/")) - } - var u *gitlab.User - if err == nil { - u, _, err = gitlabApiClient.Users.CurrentUser() - } - if err == nil { - user = model.NewUserFromGitlab(u) - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeGitea { - var giteaApiClient *gitea.Client - giteaApiClient, err = gitea.NewClient(singleton.Conf.Oauth2.Endpoint, gitea.SetToken(otk.AccessToken)) - var u *gitea.User - if err == nil { - u, _, err = giteaApiClient.GetMyUserInfo() - } - if err == nil { - user = model.NewUserFromGitea(u) - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeCloudflare { - client := oauth2Config.Client(context.Background(), otk) - resp, err := client.Get(fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/userinfo", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID)) - if err == nil { - defer resp.Body.Close() - var cloudflareUserInfo *cloudflare.UserInfo - if err := utils.Json.NewDecoder(resp.Body).Decode(&cloudflareUserInfo); err == nil { - user = cloudflareUserInfo.MapToNezhaUser() - } - } - } else if singleton.Conf.Oauth2.Type == model.ConfigTypeOidc { - userInfo, err := oa.oidcProvider.UserInfo(c.Request.Context(), oauth2.StaticTokenSource(otk)) - if err == nil { - loginClaim := singleton.Conf.Oauth2.OidcLoginClaim - groupClain := singleton.Conf.Oauth2.OidcGroupClaim - adminGroups := strings.Split(singleton.Conf.Oauth2.AdminGroups, ",") - autoCreate := singleton.Conf.Oauth2.OidcAutoCreate - var oidceUserInfo *myOidc.UserInfo - if err := userInfo.Claims(&oidceUserInfo); err == nil { - user = oidceUserInfo.MapToNezhaUser(loginClaim, groupClain, adminGroups, autoCreate) - } - } - } else { - var client *GitHubAPI.Client - oc := oauth2Config.Client(ctx, otk) - if singleton.Conf.Oauth2.Type == model.ConfigTypeGitee { - baseURL, _ := url.Parse("https://gitee.com/api/v5/") - uploadURL, _ := url.Parse("https://gitee.com/api/v5/uploads/") - client = GitHubAPI.NewClient(oc) - client.BaseURL = baseURL - client.UploadURL = uploadURL - } else { - client = GitHubAPI.NewClient(oc) - } - var gu *GitHubAPI.User - gu, _, err = client.Users.Get(ctx, "") - if err == nil { - user = model.NewUserFromGitHub(gu) - } - } - } - if err == nil && user.Login == "" { - err = errors.New("获取用户信息失败") - } - - if err != nil || user.Login == "" { - mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusBadRequest, - Title: "登录失败", - Msg: fmt.Sprintf("错误信息:%s", err), - }, true) - return - } - var isAdmin bool - - if user.SuperAdmin { - isAdmin = true - } else { - for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") { - if admin != "" && strings.EqualFold(user.Login, admin) { - isAdmin = true - break - } - } - } - if !isAdmin { - mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusBadRequest, - Title: "登录失败", - Msg: fmt.Sprintf("错误信息:%s", "该用户不是本站点管理员,无法登录"), - }, true) - return - } - user.Token, err = utils.GenerateRandomString(32) - if err != nil { - mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusBadRequest, - Title: "Something wrong", - Msg: err.Error(), - }, true) - return - } - user.TokenExpired = time.Now().AddDate(0, 2, 0) - singleton.DB.Save(&user) - c.SetCookie(singleton.Conf.Site.CookieName, user.Token, 60*60*24, "", "", false, false) - c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/redirect", mygin.CommonEnvironment(c, gin.H{ - "URL": "/", - })) -} - -func removeDuplicates(elements []string) []string { - encountered := map[string]bool{} - result := []string{} - - for _, v := range elements { - if !encountered[v] { - encountered[v] = true - result = append(result, v) - } - } - return result -} diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index b59b320..a3982d4 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -14,6 +14,8 @@ import ( "github.com/naiba/nezha/service/singleton" "github.com/ory/graceful" flag "github.com/spf13/pflag" + // gin-swagger middleware + // swagger embed files ) type DashboardCliParam struct { @@ -64,13 +66,14 @@ func main() { // TODO 使用 cmux 在同一端口服务 HTTP 和 gRPC singleton.CleanMonitorHistory() - go rpc.ServeRPC(singleton.Conf.GRPCPort) + go rpc.ServeRPC(singleton.Conf.ListenPort) serviceSentinelDispatchBus := make(chan model.Monitor) // 用于传递服务监控任务信息的channel go rpc.DispatchTask(serviceSentinelDispatchBus) go rpc.DispatchKeepalive() go singleton.AlertSentinelStart() singleton.NewServiceSentinel(serviceSentinelDispatchBus) - srv := controller.ServeWeb(singleton.Conf.HTTPPort) + srv := controller.ServeWeb(singleton.Conf.ListenPort) + go dispatchReportInfoTask() if err := graceful.Graceful(func() error { return srv.ListenAndServe() diff --git a/go.mod b/go.mod index 4a99117..0b123f0 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,9 @@ go 1.21 require ( code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea - code.gitea.io/sdk/gitea v0.18.0 github.com/BurntSushi/toml v1.3.2 - github.com/coreos/go-oidc/v3 v3.11.0 github.com/gin-contrib/pprof v1.4.0 github.com/gin-gonic/gin v1.9.1 - github.com/google/go-github/v47 v47.1.0 github.com/gorilla/websocket v1.5.1 github.com/hashicorp/go-uuid v1.0.3 github.com/jinzhu/copier v0.4.0 @@ -25,11 +22,12 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 + github.com/swaggo/files v1.0.1 + github.com/swaggo/gin-swagger v1.6.0 + github.com/swaggo/swag v1.16.4 github.com/tidwall/gjson v1.18.0 - github.com/xanzy/go-gitlab v0.103.0 golang.org/x/crypto v0.25.0 golang.org/x/net v0.27.0 - golang.org/x/oauth2 v0.21.0 golang.org/x/sync v0.7.0 golang.org/x/text v0.16.0 google.golang.org/grpc v1.63.0 @@ -40,28 +38,30 @@ require ( ) require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/davidmz/go-pageant v1.0.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-fed/httpsig v1.1.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/swag v0.19.15 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/google/go-querystring v1.1.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.7 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -86,9 +86,9 @@ require ( golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/sys v0.22.0 // indirect - golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 14f23c5..e75f325 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,32 @@ code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea h1:1tgMNDgo8PjpsHhlaxdibj28C0WyLeOW2SPJ7GGdc9A= code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea/go.mod h1:3+xXJBOD8PsGHDqHedtCLalbaVJ+yi1OW+mXx9IcNxI= -code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI= -code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= -github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0= -github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4= +github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk= github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg= github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -34,12 +34,18 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= -github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -58,30 +64,17 @@ github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGF github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8= -github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= @@ -90,6 +83,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -115,8 +110,10 @@ github.com/libdns/tencentcloud v1.0.0 h1:u4LXnYu/lu/9P5W+MCVPeSDnwI+6w+DxYhQ1wSn github.com/libdns/tencentcloud v1.0.0/go.mod h1:NlCgPumzUsZWSOo1+Q/Hfh8G6TNRAaTUeWQdg6LbtUI= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -133,6 +130,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM= github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= @@ -188,6 +186,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M= +github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo= +github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A= +github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.597 h1:C0GHdLTfikLVoEzfhgPfrZ7LwlG0xiCmk6iwNKE+xs0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.597/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -202,8 +206,7 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w= -github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= @@ -212,46 +215,55 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= @@ -263,6 +275,7 @@ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6h google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -272,6 +285,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/model/config.go b/model/config.go index bae904d..a49bd16 100644 --- a/model/config.go +++ b/model/config.go @@ -105,11 +105,9 @@ type Config struct { OidcAutoCreate bool // for OIDC Auto Create OidcAutoLogin bool // for OIDC Auto Login } - HTTPPort uint - GRPCPort uint - GRPCHost string - ProxyGRPCPort uint - TLS bool + ListenPort uint + InstallHost string + TLS bool EnablePlainIPInNotification bool // 通知信息IP不打码 DisableSwitchTemplateInFrontend bool // 前台禁用切换模板功能 @@ -153,9 +151,6 @@ func (c *Config) Read(path string) error { if c.Language == "" { c.Language = "zh-CN" } - if c.GRPCPort == 0 { - c.GRPCPort = 5555 - } if c.EnableIPChangeNotification && c.IPChangeNotificationTag == "" { c.IPChangeNotificationTag = "default" } diff --git a/model/user.go b/model/user.go index 11579eb..30f075c 100644 --- a/model/user.go +++ b/model/user.go @@ -1,71 +1,7 @@ package model -import ( - "time" - - "code.gitea.io/sdk/gitea" - "github.com/google/go-github/v47/github" - "github.com/xanzy/go-gitlab" -) - type User struct { Common - Login string `json:"login,omitempty"` // 登录名 - AvatarURL string `json:"avatar_url,omitempty"` // 头像地址 - Name string `json:"name,omitempty"` // 昵称 - Blog string `json:"blog,omitempty"` // 网站链接 - Email string `json:"email,omitempty"` // 邮箱 - Hireable bool `json:"hireable,omitempty"` - Bio string `json:"bio,omitempty"` // 个人简介 - - Token string `json:"-"` // 认证 Token - TokenExpired time.Time `json:"token_expired,omitempty"` // Token 过期时间 - SuperAdmin bool `json:"super_admin,omitempty"` // 超级管理员 -} - -func NewUserFromGitea(gu *gitea.User) User { - var u User - u.ID = uint64(gu.ID) - u.Login = gu.UserName - u.AvatarURL = gu.AvatarURL - u.Name = gu.FullName - if u.Name == "" { - u.Name = u.Login - } - u.Blog = gu.Website - u.Email = gu.Email - u.Bio = gu.Description - return u -} - -func NewUserFromGitlab(gu *gitlab.User) User { - var u User - u.ID = uint64(gu.ID) - u.Login = gu.Username - u.AvatarURL = gu.AvatarURL - u.Name = gu.Name - if u.Name == "" { - u.Name = u.Login - } - u.Blog = gu.WebsiteURL - u.Email = gu.Email - u.Bio = gu.Bio - return u -} - -func NewUserFromGitHub(gu *github.User) User { - var u User - u.ID = uint64(gu.GetID()) - u.Login = gu.GetLogin() - u.AvatarURL = gu.GetAvatarURL() - u.Name = gu.GetName() - // 昵称为空的情况 - if u.Name == "" { - u.Name = u.Login - } - u.Blog = gu.GetBlog() - u.Email = gu.GetEmail() - u.Hireable = gu.GetHireable() - u.Bio = gu.GetBio() - return u + Username string + Password string } diff --git a/pkg/mygin/auth.go b/pkg/mygin/auth.go index a019c8a..134060c 100644 --- a/pkg/mygin/auth.go +++ b/pkg/mygin/auth.go @@ -3,7 +3,6 @@ package mygin import ( "net/http" "strings" - "time" "github.com/gin-gonic/gin" @@ -43,7 +42,7 @@ func Authorize(opt AuthorizeOption) func(*gin.Context) { if token != "" { var u model.User if err := singleton.DB.Where("token = ?", token).First(&u).Error; err == nil { - isLogin = u.TokenExpired.After(time.Now()) + isLogin = true // u.TokenExpired.After(time.Now()) } if isLogin { c.Set(model.CtxKeyAuthorizedUser, &u) diff --git a/pkg/oidc/cloudflare/cloudflare.go b/pkg/oidc/cloudflare/cloudflare.go deleted file mode 100644 index f7de13f..0000000 --- a/pkg/oidc/cloudflare/cloudflare.go +++ /dev/null @@ -1,22 +0,0 @@ -package cloudflare - -import ( - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/service/singleton" -) - -type UserInfo struct { - Sub string `json:"sub"` - Email string `json:"email"` - Name string `json:"name"` - Groups []string `json:"groups"` -} - -func (u UserInfo) MapToNezhaUser() model.User { - var user model.User - singleton.DB.Where("login = ?", u.Sub).First(&user) - user.Login = u.Sub - user.Email = u.Email - user.Name = u.Name - return user -} diff --git a/pkg/oidc/general/general.go b/pkg/oidc/general/general.go deleted file mode 100644 index acf8feb..0000000 --- a/pkg/oidc/general/general.go +++ /dev/null @@ -1,56 +0,0 @@ -package general - -import ( - "github.com/naiba/nezha/model" - "github.com/naiba/nezha/service/singleton" -) - -type UserInfo struct { - Sub string `json:"sub"` - Username string `json:"preferred_username"` - Email string `json:"email"` - Name string `json:"name"` - Groups []string `json:"groups,omitempty"` - Roles []string `json:"roles,omitempty"` -} - -func (u UserInfo) MapToNezhaUser(loginClaim string, groupClaim string, adminGroups []string, autoCreate bool) model.User { - var user model.User - var login string - var groups []string - var isAdmin bool - if loginClaim == "email" { - login = u.Email - } else if loginClaim == "preferred_username" { - login = u.Username - } else { - login = u.Sub - } - if groupClaim == "roles" { - groups = u.Roles - } else { - groups = u.Groups - } - // Check if user is admin - adminGroupSet := make(map[string]struct{}, len(adminGroups)) - for _, adminGroup := range adminGroups { - adminGroupSet[adminGroup] = struct{}{} - } - for _, group := range groups { - if _, found := adminGroupSet[group]; found { - isAdmin = true - break - } - } - result := singleton.DB.Where("login = ?", login).First(&user) - user.Login = login - user.Email = u.Email - user.Name = u.Name - user.SuperAdmin = isAdmin - if result.Error != nil && autoCreate { - singleton.DB.Create(&user) - } else if result.Error != nil { - return model.User{} - } - return user -} diff --git a/proto/nezha.pb.go b/proto/nezha.pb.go index 729deb0..f491d51 100644 --- a/proto/nezha.pb.go +++ b/proto/nezha.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 -// protoc v5.26.1 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: proto/nezha.proto package proto @@ -808,7 +808,7 @@ func file_proto_nezha_proto_rawDescGZIP() []byte { } var file_proto_nezha_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_proto_nezha_proto_goTypes = []interface{}{ +var file_proto_nezha_proto_goTypes = []any{ (*Host)(nil), // 0: proto.Host (*State)(nil), // 1: proto.State (*State_SensorTemperature)(nil), // 2: proto.State_SensorTemperature @@ -845,7 +845,7 @@ func file_proto_nezha_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_proto_nezha_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Host); i { case 0: return &v.state @@ -857,7 +857,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*State); i { case 0: return &v.state @@ -869,7 +869,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*State_SensorTemperature); i { case 0: return &v.state @@ -881,7 +881,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Task); i { case 0: return &v.state @@ -893,7 +893,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*TaskResult); i { case 0: return &v.state @@ -905,7 +905,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*Receipt); i { case 0: return &v.state @@ -917,7 +917,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*IOStreamData); i { case 0: return &v.state @@ -929,7 +929,7 @@ func file_proto_nezha_proto_init() { return nil } } - file_proto_nezha_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_proto_nezha_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*GeoIP); i { case 0: return &v.state diff --git a/proto/nezha_grpc.pb.go b/proto/nezha_grpc.pb.go index 07543ce..bbe775b 100644 --- a/proto/nezha_grpc.pb.go +++ b/proto/nezha_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v5.26.1 +// - protoc v5.28.1 // source: proto/nezha.proto package proto diff --git a/script/proto.sh b/script/bootstrap.sh similarity index 69% rename from script/proto.sh rename to script/bootstrap.sh index fb334e8..7df6558 100755 --- a/script/proto.sh +++ b/script/bootstrap.sh @@ -1,3 +1,4 @@ +swag init -g cmd/dashboard/main.go -o cmd/dashboard/docs protoc --go-grpc_out="require_unimplemented_servers=false:." --go_out="." proto/*.proto rm -rf ../agent/proto cp -r proto ../agent \ No newline at end of file