diff --git a/go.mod b/go.mod index 3c9c2d20d..913ecaa7d 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/xanzy/go-gitlab v0.73.1 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 - golang.org/x/net v0.1.0 + golang.org/x/net v0.4.0 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 golang.org/x/sync v0.1.0 google.golang.org/grpc v1.50.1 @@ -129,9 +129,9 @@ require ( go.uber.org/zap v1.23.0 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/mod v0.6.0 // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/term v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect golang.org/x/time v0.1.0 // indirect golang.org/x/tools v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 1b616f72f..1c4e24e59 100644 --- a/go.sum +++ b/go.sum @@ -850,8 +850,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -946,13 +946,13 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -962,8 +962,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/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.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/server/router/api.go b/server/router/api.go index fe3dbdb3b..a35a0c871 100644 --- a/server/router/api.go +++ b/server/router/api.go @@ -24,168 +24,172 @@ import ( ) func apiRoutes(e *gin.Engine) { - user := e.Group("/api/user") + apiBase := e.Group("/api") { - user.Use(session.MustUser()) - user.GET("", api.GetSelf) - user.GET("/feed", api.GetFeed) - user.GET("/repos", api.GetRepos) - user.POST("/token", api.PostToken) - user.DELETE("/token", api.DeleteToken) - } - - users := e.Group("/api/users") - { - users.Use(session.MustAdmin()) - users.GET("", api.GetUsers) - users.POST("", api.PostUser) - users.GET("/:login", api.GetUser) - users.PATCH("/:login", api.PatchUser) - users.DELETE("/:login", api.DeleteUser) - } - - orgBase := e.Group("/api/orgs/:owner") - { - orgBase.GET("/permissions", api.GetOrgPermissions) - - org := orgBase.Group("") + user := apiBase.Group("/user") { - org.Use(session.MustOrgMember(true)) - org.GET("/secrets", api.GetOrgSecretList) - org.POST("/secrets", api.PostOrgSecret) - org.GET("/secrets/:secret", api.GetOrgSecret) - org.PATCH("/secrets/:secret", api.PatchOrgSecret) - org.DELETE("/secrets/:secret", api.DeleteOrgSecret) + user.Use(session.MustUser()) + user.GET("", api.GetSelf) + user.GET("/feed", api.GetFeed) + user.GET("/repos", api.GetRepos) + user.POST("/token", api.PostToken) + user.DELETE("/token", api.DeleteToken) + } + + users := apiBase.Group("/users") + { + users.Use(session.MustAdmin()) + users.GET("", api.GetUsers) + users.POST("", api.PostUser) + users.GET("/:login", api.GetUser) + users.PATCH("/:login", api.PatchUser) + users.DELETE("/:login", api.DeleteUser) + } + + orgBase := apiBase.Group("/orgs/:owner") + { + orgBase.GET("/permissions", api.GetOrgPermissions) + + org := orgBase.Group("") + { + org.Use(session.MustOrgMember(true)) + org.GET("/secrets", api.GetOrgSecretList) + org.POST("/secrets", api.PostOrgSecret) + org.GET("/secrets/:secret", api.GetOrgSecret) + org.PATCH("/secrets/:secret", api.PatchOrgSecret) + org.DELETE("/secrets/:secret", api.DeleteOrgSecret) + } + } + + repoBase := apiBase.Group("/repos/:owner/:name") + { + repoBase.Use(session.SetRepo()) + repoBase.Use(session.SetPerm()) + + repoBase.GET("/permissions", api.GetRepoPermissions) + + repo := repoBase.Group("") + { + repo.Use(session.MustPull) + + repo.POST("", session.MustRepoAdmin(), api.PostRepo) + repo.GET("", api.GetRepo) + + repo.GET("/branches", api.GetRepoBranches) + + repo.GET("/pipelines", api.GetPipelines) + repo.POST("/pipelines", session.MustPush, api.CreatePipeline) + repo.GET("/pipelines/:number", api.GetPipeline) + repo.GET("/pipelines/:number/config", api.GetPipelineConfig) + + // requires push permissions + repo.POST("/pipelines/:number", session.MustPush, api.PostPipeline) + repo.POST("/pipelines/:number/cancel", session.MustPush, api.CancelPipeline) + repo.POST("/pipelines/:number/approve", session.MustPush, api.PostApproval) + repo.POST("/pipelines/:number/decline", session.MustPush, api.PostDecline) + + repo.GET("/logs/:number/:pid", api.GetStepLogs) + repo.GET("/logs/:number/:pid/:step", api.GetPipelineLogs) + + // requires push permissions + repo.DELETE("/logs/:number", session.MustPush, api.DeletePipelineLogs) + + repo.GET("/files/:number", api.FileList) + repo.GET("/files/:number/:step/*file", api.FileGet) + + // requires push permissions + repo.GET("/secrets", session.MustPush, api.GetSecretList) + repo.POST("/secrets", session.MustPush, api.PostSecret) + repo.GET("/secrets/:secret", session.MustPush, api.GetSecret) + repo.PATCH("/secrets/:secret", session.MustPush, api.PatchSecret) + repo.DELETE("/secrets/:secret", session.MustPush, api.DeleteSecret) + + // requires push permissions + repo.GET("/registry", session.MustPush, api.GetRegistryList) + repo.POST("/registry", session.MustPush, api.PostRegistry) + repo.GET("/registry/:registry", session.MustPush, api.GetRegistry) + repo.PATCH("/registry/:registry", session.MustPush, api.PatchRegistry) + repo.DELETE("/registry/:registry", session.MustPush, api.DeleteRegistry) + + // requires push permissions + repo.GET("/cron", session.MustPush, api.GetCronList) + repo.POST("/cron", session.MustPush, api.PostCron) + repo.GET("/cron/:cron", session.MustPush, api.GetCron) + repo.POST("/cron/:cron", session.MustPush, api.RunCron) + repo.PATCH("/cron/:cron", session.MustPush, api.PatchCron) + repo.DELETE("/cron/:cron", session.MustPush, api.DeleteCron) + + // requires admin permissions + repo.PATCH("", session.MustRepoAdmin(), api.PatchRepo) + repo.DELETE("", session.MustRepoAdmin(), api.DeleteRepo) + repo.POST("/chown", session.MustRepoAdmin(), api.ChownRepo) + repo.POST("/repair", session.MustRepoAdmin(), api.RepairRepo) + repo.POST("/move", session.MustRepoAdmin(), api.MoveRepo) + } + } + + badges := apiBase.Group("/badges/:owner/:name") + { + badges.GET("/status.svg", api.GetBadge) + badges.GET("/cc.xml", api.GetCC) + } + + pipelines := apiBase.Group("/pipelines") + { + pipelines.Use(session.MustAdmin()) + pipelines.GET("", api.GetPipelineQueue) + } + + queue := apiBase.Group("/queue") + { + queue.Use(session.MustAdmin()) + queue.GET("/info", api.GetQueueInfo) + queue.GET("/pause", api.PauseQueue) + queue.GET("/resume", api.ResumeQueue) + queue.GET("/norunningpipelines", api.BlockTilQueueHasRunningItem) + } + + secrets := apiBase.Group("/secrets") + { + secrets.Use(session.MustAdmin()) + secrets.GET("", api.GetGlobalSecretList) + secrets.POST("", api.PostGlobalSecret) + secrets.GET("/:secret", api.GetGlobalSecret) + secrets.PATCH("/:secret", api.PatchGlobalSecret) + secrets.DELETE("/:secret", api.DeleteGlobalSecret) + } + + logLevel := apiBase.Group("/log-level") + { + logLevel.Use(session.MustAdmin()) + logLevel.GET("", api.LogLevel) + logLevel.POST("", api.SetLogLevel) + } + + apiBase.GET("/signature/public-key", session.MustUser(), api.GetSignaturePublicKey) + + apiBase.POST("/hook", api.PostHook) + + if zerolog.GlobalLevel() <= zerolog.DebugLevel { + debugger := apiBase.Group("/debug") + { + debugger.Use(session.MustAdmin()) + debugger.GET("/pprof/", debug.IndexHandler()) + debugger.GET("/pprof/heap", debug.HeapHandler()) + debugger.GET("/pprof/goroutine", debug.GoroutineHandler()) + debugger.GET("/pprof/block", debug.BlockHandler()) + debugger.GET("/pprof/threadcreate", debug.ThreadCreateHandler()) + debugger.GET("/pprof/cmdline", debug.CmdlineHandler()) + debugger.GET("/pprof/profile", debug.ProfileHandler()) + debugger.GET("/pprof/symbol", debug.SymbolHandler()) + debugger.POST("/pprof/symbol", debug.SymbolHandler()) + debugger.GET("/pprof/trace", debug.TraceHandler()) + } } } - repoBase := e.Group("/api/repos/:owner/:name") - { - repoBase.Use(session.SetRepo()) - repoBase.Use(session.SetPerm()) - - repoBase.GET("/permissions", api.GetRepoPermissions) - - repo := repoBase.Group("") - { - repo.Use(session.MustPull) - - repo.POST("", session.MustRepoAdmin(), api.PostRepo) - repo.GET("", api.GetRepo) - - repo.GET("/branches", api.GetRepoBranches) - - repo.GET("/pipelines", api.GetPipelines) - repo.POST("/pipelines", session.MustPush, api.CreatePipeline) - repo.GET("/pipelines/:number", api.GetPipeline) - repo.GET("/pipelines/:number/config", api.GetPipelineConfig) - - // requires push permissions - repo.POST("/pipelines/:number", session.MustPush, api.PostPipeline) - repo.POST("/pipelines/:number/cancel", session.MustPush, api.CancelPipeline) - repo.POST("/pipelines/:number/approve", session.MustPush, api.PostApproval) - repo.POST("/pipelines/:number/decline", session.MustPush, api.PostDecline) - - repo.GET("/logs/:number/:pid", api.GetStepLogs) - repo.GET("/logs/:number/:pid/:step", api.GetPipelineLogs) - - // requires push permissions - repo.DELETE("/logs/:number", session.MustPush, api.DeletePipelineLogs) - - repo.GET("/files/:number", api.FileList) - repo.GET("/files/:number/:step/*file", api.FileGet) - - // requires push permissions - repo.GET("/secrets", session.MustPush, api.GetSecretList) - repo.POST("/secrets", session.MustPush, api.PostSecret) - repo.GET("/secrets/:secret", session.MustPush, api.GetSecret) - repo.PATCH("/secrets/:secret", session.MustPush, api.PatchSecret) - repo.DELETE("/secrets/:secret", session.MustPush, api.DeleteSecret) - - // requires push permissions - repo.GET("/registry", session.MustPush, api.GetRegistryList) - repo.POST("/registry", session.MustPush, api.PostRegistry) - repo.GET("/registry/:registry", session.MustPush, api.GetRegistry) - repo.PATCH("/registry/:registry", session.MustPush, api.PatchRegistry) - repo.DELETE("/registry/:registry", session.MustPush, api.DeleteRegistry) - - // requires push permissions - repo.GET("/cron", session.MustPush, api.GetCronList) - repo.POST("/cron", session.MustPush, api.PostCron) - repo.GET("/cron/:cron", session.MustPush, api.GetCron) - repo.POST("/cron/:cron", session.MustPush, api.RunCron) - repo.PATCH("/cron/:cron", session.MustPush, api.PatchCron) - repo.DELETE("/cron/:cron", session.MustPush, api.DeleteCron) - - // requires admin permissions - repo.PATCH("", session.MustRepoAdmin(), api.PatchRepo) - repo.DELETE("", session.MustRepoAdmin(), api.DeleteRepo) - repo.POST("/chown", session.MustRepoAdmin(), api.ChownRepo) - repo.POST("/repair", session.MustRepoAdmin(), api.RepairRepo) - repo.POST("/move", session.MustRepoAdmin(), api.MoveRepo) - } - } - - badges := e.Group("/api/badges/:owner/:name") - { - badges.GET("/status.svg", api.GetBadge) - badges.GET("/cc.xml", api.GetCC) - } - - pipelines := e.Group("/api/pipelines") - { - pipelines.Use(session.MustAdmin()) - pipelines.GET("", api.GetPipelineQueue) - } - - queue := e.Group("/api/queue") - { - queue.Use(session.MustAdmin()) - queue.GET("/info", api.GetQueueInfo) - queue.GET("/pause", api.PauseQueue) - queue.GET("/resume", api.ResumeQueue) - queue.GET("/norunningpipelines", api.BlockTilQueueHasRunningItem) - } - - secrets := e.Group("/api/secrets") - { - secrets.Use(session.MustAdmin()) - secrets.GET("", api.GetGlobalSecretList) - secrets.POST("", api.PostGlobalSecret) - secrets.GET("/:secret", api.GetGlobalSecret) - secrets.PATCH("/:secret", api.PatchGlobalSecret) - secrets.DELETE("/:secret", api.DeleteGlobalSecret) - } - - if zerolog.GlobalLevel() <= zerolog.DebugLevel { - debugger := e.Group("/api/debug") - { - debugger.Use(session.MustAdmin()) - debugger.GET("/pprof/", debug.IndexHandler()) - debugger.GET("/pprof/heap", debug.HeapHandler()) - debugger.GET("/pprof/goroutine", debug.GoroutineHandler()) - debugger.GET("/pprof/block", debug.BlockHandler()) - debugger.GET("/pprof/threadcreate", debug.ThreadCreateHandler()) - debugger.GET("/pprof/cmdline", debug.CmdlineHandler()) - debugger.GET("/pprof/profile", debug.ProfileHandler()) - debugger.GET("/pprof/symbol", debug.SymbolHandler()) - debugger.POST("/pprof/symbol", debug.SymbolHandler()) - debugger.GET("/pprof/trace", debug.TraceHandler()) - } - } - - logLevel := e.Group("/api/log-level") - { - logLevel.Use(session.MustAdmin()) - logLevel.GET("", api.LogLevel) - logLevel.POST("", api.SetLogLevel) - } - - e.GET("/api/signature/public-key", session.MustUser(), api.GetSignaturePublicKey) - // TODO: remove /hook in favor of /api/hook e.POST("/hook", api.PostHook) - e.POST("/api/hook", api.PostHook) // TODO: move to /api/stream sse := e.Group("/stream")