diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index d03ddcb353..8dedfd1ae0 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -69,40 +69,41 @@ func TestAPISearchRepo(t *testing.T) { name, requestURL string expectedResults }{ - {name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50", expectedResults: expectedResults{ + {name: "RepositoriesMax50", requestURL: "/api/v1/repos/search?limit=50&private=false", expectedResults: expectedResults{ nil: {count: 21}, user: {count: 21}, user2: {count: 21}}, }, - {name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10", expectedResults: expectedResults{ + {name: "RepositoriesMax10", requestURL: "/api/v1/repos/search?limit=10&private=false", expectedResults: expectedResults{ nil: {count: 10}, user: {count: 10}, user2: {count: 10}}, }, - {name: "RepositoriesDefaultMax10", requestURL: "/api/v1/repos/search?default", expectedResults: expectedResults{ + {name: "RepositoriesDefaultMax10", requestURL: "/api/v1/repos/search?default&private=false", expectedResults: expectedResults{ nil: {count: 10}, user: {count: 10}, user2: {count: 10}}, }, - {name: "RepositoriesByName", requestURL: fmt.Sprintf("/api/v1/repos/search?q=%s", "big_test_"), expectedResults: expectedResults{ + {name: "RepositoriesByName", requestURL: fmt.Sprintf("/api/v1/repos/search?q=%s&private=false", "big_test_"), expectedResults: expectedResults{ nil: {count: 7, repoName: "big_test_"}, user: {count: 7, repoName: "big_test_"}, user2: {count: 7, repoName: "big_test_"}}, }, {name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{ - nil: {count: 4}, - user: {count: 8, includesPrivate: true}, - user2: {count: 4}}, + nil: {count: 5}, + user: {count: 9, includesPrivate: true}, + user2: {count: 5, includesPrivate: true}}, }, {name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{ nil: {count: 1}, - user: {count: 1}, - user2: {count: 2, includesPrivate: true}}, + user: {count: 2, includesPrivate: true}, + user2: {count: 2, includesPrivate: true}, + user4: {count: 1}}, }, {name: "RepositoriesAccessibleAndRelatedToUser3", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user3.ID), expectedResults: expectedResults{ nil: {count: 1}, - user: {count: 1}, - user2: {count: 1}, + user: {count: 4, includesPrivate: true}, + user2: {count: 2, includesPrivate: true}, user3: {count: 4, includesPrivate: true}}, }, {name: "RepositoriesOwnedByOrganization", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", orgUser.ID), expectedResults: expectedResults{ @@ -112,12 +113,12 @@ func TestAPISearchRepo(t *testing.T) { }, {name: "RepositoriesAccessibleAndRelatedToUser4", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user4.ID), expectedResults: expectedResults{ nil: {count: 3}, - user: {count: 3}, - user4: {count: 6, includesPrivate: true}}}, + user: {count: 4, includesPrivate: true}, + user4: {count: 7, includesPrivate: true}}}, {name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeSource", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "source"), expectedResults: expectedResults{ nil: {count: 0}, - user: {count: 0}, - user4: {count: 0, includesPrivate: true}}}, + user: {count: 1, includesPrivate: true}, + user4: {count: 1, includesPrivate: true}}}, {name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeFork", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "fork"), expectedResults: expectedResults{ nil: {count: 1}, user: {count: 1}, @@ -136,8 +137,8 @@ func TestAPISearchRepo(t *testing.T) { user4: {count: 2, includesPrivate: true}}}, {name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeCollaborative", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "collaborative"), expectedResults: expectedResults{ nil: {count: 0}, - user: {count: 0}, - user4: {count: 0, includesPrivate: true}}}, + user: {count: 1, includesPrivate: true}, + user4: {count: 1, includesPrivate: true}}}, } for _, testCase := range testCases { @@ -164,14 +165,19 @@ func TestAPISearchRepo(t *testing.T) { var body api.SearchResults DecodeJSON(t, response, &body) - assert.Len(t, body.Data, expected.count) + repoNames := make([]string, 0, len(body.Data)) + for _, repo := range body.Data { + repoNames = append(repoNames, fmt.Sprintf("%d:%s:%t", repo.ID, repo.FullName, repo.Private)) + } + assert.Len(t, repoNames, expected.count) for _, repo := range body.Data { r := getRepo(t, repo.ID) hasAccess, err := models.HasAccess(userID, r) - assert.NoError(t, err) - assert.True(t, hasAccess) + assert.NoError(t, err, "Error when checking if User: %d has access to %s: %v", userID, repo.FullName, err) + assert.True(t, hasAccess, "User: %d does not have access to %s", userID, repo.FullName) assert.NotEmpty(t, repo.Name) + assert.Equal(t, repo.Name, r.Name) if len(expected.repoName) > 0 { assert.Contains(t, repo.Name, expected.repoName) @@ -182,7 +188,7 @@ func TestAPISearchRepo(t *testing.T) { } if !expected.includesPrivate { - assert.False(t, repo.Private) + assert.False(t, repo.Private, "User: %d not expecting private repository: %s", userID, repo.FullName) } } }) diff --git a/models/repo.go b/models/repo.go index 2f87e2f514..b37120236f 100644 --- a/models/repo.go +++ b/models/repo.go @@ -13,7 +13,6 @@ import ( "io/ioutil" "net/url" "os" - "os/exec" "path" "path/filepath" "regexp" @@ -32,11 +31,9 @@ import ( "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" - "github.com/Unknwon/cae/zip" "github.com/Unknwon/com" "github.com/go-xorm/builder" "github.com/go-xorm/xorm" - version "github.com/mcuadros/go-version" ini "gopkg.in/ini.v1" ) @@ -67,8 +64,8 @@ var ( ItemsPerPage = 40 ) -// LoadRepoConfig loads the repository config -func LoadRepoConfig() { +// loadRepoConfig loads the repository config +func loadRepoConfig() { // Load .gitignore and license files and readme templates. types := []string{"gitignore", "license", "readme", "label"} typeFiles := make([][]string, 4) @@ -119,45 +116,7 @@ func LoadRepoConfig() { // NewRepoContext creates a new repository context func NewRepoContext() { - zip.Verbose = false - - // Check Git installation. - if _, err := exec.LookPath("git"); err != nil { - log.Fatal("Failed to test 'git' command: %v (forgotten install?)", err) - } - - // Check Git version. - var err error - setting.Git.Version, err = git.BinVersion() - if err != nil { - log.Fatal("Failed to get Git version: %v", err) - } - - log.Info("Git Version: %s", setting.Git.Version) - if version.Compare("1.7.1", setting.Git.Version, ">") { - log.Fatal("Gitea requires Git version greater or equal to 1.7.1") - } - - // Git requires setting user.name and user.email in order to commit changes. - for configKey, defaultValue := range map[string]string{"user.name": "Gitea", "user.email": "gitea@fake.local"} { - if stdout, stderr, err := process.GetManager().Exec("NewRepoContext(get setting)", "git", "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" { - // ExitError indicates this config is not set - if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" { - if _, stderr, gerr := process.GetManager().Exec("NewRepoContext(set "+configKey+")", "git", "config", "--global", configKey, defaultValue); gerr != nil { - log.Fatal("Failed to set git %s(%s): %s", configKey, gerr, stderr) - } - log.Info("Git config %s set to %s", configKey, defaultValue) - } else { - log.Fatal("Failed to get git %s(%s): %s", configKey, err, stderr) - } - } - } - - // Set git some configurations. - if _, stderr, err := process.GetManager().Exec("NewRepoContext(git config --global core.quotepath false)", - "git", "config", "--global", "core.quotepath", "false"); err != nil { - log.Fatal("Failed to execute 'git config --global core.quotepath false': %s", stderr) - } + loadRepoConfig() RemoveAllWithNotice("Clean up repository temporary data", filepath.Join(setting.AppDataPath, "tmp")) } diff --git a/models/repo_list.go b/models/repo_list.go index 83d2665e8c..9686676eae 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/modules/util" "github.com/go-xorm/builder" - "github.com/go-xorm/core" ) // RepositoryListDefaultPageSize is the default number of repositories @@ -112,15 +111,17 @@ func (repos MirrorRepositoryList) LoadAttributes() error { // SearchRepoOptions holds the search options type SearchRepoOptions struct { - Keyword string - OwnerID int64 - OrderBy SearchOrderBy - Private bool // Include private repositories in results - Starred bool - Page int - IsProfile bool - AllPublic bool // Include also all public repositories - PageSize int // Can be smaller than or equal to setting.ExplorePagingNum + UserID int64 + UserIsAdmin bool + Keyword string + OwnerID int64 + OrderBy SearchOrderBy + Private bool // Include private repositories in results + StarredByID int64 + Page int + IsProfile bool + AllPublic bool // Include also all public repositories + PageSize int // Can be smaller than or equal to setting.ExplorePagingNum // None -> include collaborative AND non-collaborative // True -> include just collaborative // False -> incude just non-collaborative @@ -168,72 +169,79 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err if opts.Page <= 0 { opts.Page = 1 } - var cond = builder.NewCond() - if !opts.Private { + if opts.Private { + if !opts.UserIsAdmin && opts.UserID != 0 && opts.UserID != opts.OwnerID { + // OK we're in the context of a User + // We should be Either + cond = cond.And(builder.Or( + // 1. Be able to see all non-private repositories that either: + cond.And( + builder.Eq{"is_private": false}, + builder.Or( + // A. Aren't in organisations __OR__ + builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})), + // B. Isn't a private organisation. (Limited is OK because we're logged in) + builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePrivate}))), + ), + // 2. Be able to see all repositories that we have access to + builder.In("id", builder.Select("repo_id"). + From("`access`"). + Where(builder.And( + builder.Eq{"user_id": opts.UserID}, + builder.Gt{"mode": int(AccessModeNone)}))), + // 3. Be able to see all repositories that we are in a team + builder.In("id", builder.Select("`team_repo`.repo_id"). + From("team_repo"). + Where(builder.Eq{"`team_user`.uid": opts.UserID}). + Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id")))) + } + } else { + // Not looking at private organisations + // We should be able to see all non-private repositories that either: cond = cond.And(builder.Eq{"is_private": false}) accessCond := builder.Or( - builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}))), - builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization}))) + // A. Aren't in organisations __OR__ + builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})), + // B. Isn't a private or limited organisation. + builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate})))) cond = cond.And(accessCond) } + // Restrict to starred repositories + if opts.StarredByID > 0 { + cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.StarredByID}))) + } + + // Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate if opts.OwnerID > 0 { - if opts.Starred { - cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.OwnerID}))) - } else { - var accessCond = builder.NewCond() - if opts.Collaborate != util.OptionalBoolTrue { - accessCond = builder.Eq{"owner_id": opts.OwnerID} - } - - if opts.Collaborate != util.OptionalBoolFalse { - collaborateCond := builder.And( - builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID), - builder.Neq{"owner_id": opts.OwnerID}) - if !opts.Private { - collaborateCond = collaborateCond.And(builder.Expr("owner_id NOT IN (SELECT org_id FROM org_user WHERE org_user.uid = ? AND org_user.is_public = ?)", opts.OwnerID, false)) - } - - accessCond = accessCond.Or(collaborateCond) - } - - var exprCond builder.Cond - if DbCfg.Type == core.POSTGRES { - exprCond = builder.Expr("org_user.org_id = \"user\".id") - } else if DbCfg.Type == core.MSSQL { - exprCond = builder.Expr("org_user.org_id = [user].id") - } else { - exprCond = builder.Eq{"org_user.org_id": "user.id"} - } - - visibilityCond := builder.Or( - builder.In("owner_id", - builder.Select("org_id").From("org_user"). - LeftJoin("`user`", exprCond). - Where( - builder.And( - builder.Eq{"uid": opts.OwnerID}, - builder.Eq{"visibility": structs.VisibleTypePrivate})), - ), - builder.In("owner_id", - builder.Select("id").From("`user`"). - Where( - builder.Or( - builder.Eq{"visibility": structs.VisibleTypePublic}, - builder.Eq{"visibility": structs.VisibleTypeLimited})), - ), - builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})), - ) - cond = cond.And(visibilityCond) - - if opts.AllPublic { - accessCond = accessCond.Or(builder.Eq{"is_private": false}) - } - - cond = cond.And(accessCond) + var accessCond = builder.NewCond() + if opts.Collaborate != util.OptionalBoolTrue { + accessCond = builder.Eq{"owner_id": opts.OwnerID} } + + if opts.Collaborate != util.OptionalBoolFalse { + collaborateCond := builder.And( + builder.Or( + builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID), + builder.In("id", builder.Select("`team_repo`.repo_id"). + From("team_repo"). + Where(builder.Eq{"`team_user`.uid": opts.OwnerID}). + Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id"))), + builder.Neq{"owner_id": opts.OwnerID}) + if !opts.Private { + collaborateCond = collaborateCond.And(builder.Expr("owner_id NOT IN (SELECT org_id FROM org_user WHERE org_user.uid = ? AND org_user.is_public = ?)", opts.OwnerID, false)) + } + + accessCond = accessCond.Or(collaborateCond) + } + + if opts.AllPublic { + accessCond = accessCond.Or(builder.Eq{"is_private": false}) + } + + cond = cond.And(accessCond) } if opts.Keyword != "" { diff --git a/models/repo_list_test.go b/models/repo_list_test.go index e871c612f0..645de2a59a 100644 --- a/models/repo_list_test.go +++ b/models/repo_list_test.go @@ -117,7 +117,7 @@ func TestSearchRepositoryByName(t *testing.T) { count: 4}, {name: "PublicRepositoriesOfUserIncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15}, - count: 4}, + count: 5}, {name: "PublicRepositoriesOfUser2IncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18}, count: 1}, @@ -126,13 +126,13 @@ func TestSearchRepositoryByName(t *testing.T) { count: 3}, {name: "PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true}, - count: 8}, + count: 9}, {name: "PublicAndPrivateRepositoriesOfUser2IncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18, Private: true}, count: 4}, {name: "PublicAndPrivateRepositoriesOfUser3IncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 20, Private: true}, - count: 6}, + count: 7}, {name: "PublicRepositoriesOfOrganization", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, Collaborate: util.OptionalBoolFalse}, count: 1}, @@ -150,7 +150,7 @@ func TestSearchRepositoryByName(t *testing.T) { count: 21}, {name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative", opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true}, - count: 26}, + count: 27}, {name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName", opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true}, count: 15}, diff --git a/models/webhook.go b/models/webhook.go index 51b91879ee..48c4de2ea3 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -755,17 +755,15 @@ func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p api.Payl func (t *HookTask) deliver() { t.IsDelivered = true - t.RequestInfo = &HookRequest{ - Headers: map[string]string{}, - } - t.ResponseInfo = &HookResponse{ - Headers: map[string]string{}, - } timeout := time.Duration(setting.Webhook.DeliverTimeout) * time.Second var req *httplib.Request - if t.HTTPMethod == http.MethodPost { + switch t.HTTPMethod { + case "": + log.Info("HTTP Method for webhook %d empty, setting to POST as default", t.ID) + fallthrough + case http.MethodPost: req = httplib.Post(t.URL) switch t.ContentType { case ContentTypeJSON: @@ -773,10 +771,10 @@ func (t *HookTask) deliver() { case ContentTypeForm: req.Param("payload", t.PayloadContent) } - } else if t.HTTPMethod == http.MethodGet { + case http.MethodGet: req = httplib.Get(t.URL).Param("payload", t.PayloadContent) - } else { - t.ResponseInfo.Body = fmt.Sprintf("Invalid http method: %v", t.HTTPMethod) + default: + log.Error("Invalid http method for webhook: [%d] %v", t.ID, t.HTTPMethod) return } @@ -792,10 +790,17 @@ func (t *HookTask) deliver() { SetTLSClientConfig(&tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify}) // Record delivery information. + t.RequestInfo = &HookRequest{ + Headers: map[string]string{}, + } for k, vals := range req.Headers() { t.RequestInfo.Headers[k] = strings.Join(vals, ",") } + t.ResponseInfo = &HookResponse{ + Headers: map[string]string{}, + } + defer func() { t.Delivered = time.Now().UnixNano() if t.IsSucceed { diff --git a/modules/git/git.go b/modules/git/git.go index abae0423c2..632af539cc 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -11,6 +11,8 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/process" + "github.com/mcuadros/go-version" ) @@ -31,6 +33,8 @@ var ( // GitExecutable is the command name of git // Could be updated to an absolute path while initialization GitExecutable = "git" + + gitVersion string ) func log(format string, args ...interface{}) { @@ -46,8 +50,6 @@ func log(format string, args ...interface{}) { } } -var gitVersion string - // BinVersion returns current Git version from shell. func BinVersion() (string, error) { if len(gitVersion) > 0 { @@ -89,6 +91,26 @@ func init() { if version.Compare(gitVersion, GitVersionRequired, "<") { panic(fmt.Sprintf("Git version not supported. Requires version > %v", GitVersionRequired)) } + + // Git requires setting user.name and user.email in order to commit changes. + for configKey, defaultValue := range map[string]string{"user.name": "Gitea", "user.email": "gitea@fake.local"} { + if stdout, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", configKey); err != nil || strings.TrimSpace(stdout) == "" { + // ExitError indicates this config is not set + if _, ok := err.(*exec.ExitError); ok || strings.TrimSpace(stdout) == "" { + if _, stderr, gerr := process.GetManager().Exec("git.Init(set "+configKey+")", "git", "config", "--global", configKey, defaultValue); gerr != nil { + panic(fmt.Sprintf("Failed to set git %s(%s): %s", configKey, gerr, stderr)) + } + } else { + panic(fmt.Sprintf("Failed to get git %s(%s): %s", configKey, err, stderr)) + } + } + } + + // Set git some configurations. + if _, stderr, err := process.GetManager().Exec("git.Init(git config --global core.quotepath false)", + GitExecutable, "config", "--global", "core.quotepath", "false"); err != nil { + panic(fmt.Sprintf("Failed to execute 'git config --global core.quotepath false': %s", stderr)) + } } // Fsck verifies the connectivity and validity of the objects in the database diff --git a/modules/setting/git.go b/modules/setting/git.go index 0ad16fc81e..8625c0e780 100644 --- a/modules/setting/git.go +++ b/modules/setting/git.go @@ -16,7 +16,6 @@ import ( var ( // Git settings Git = struct { - Version string `ini:"-"` DisableDiffHighlight bool MaxGitDiffLines int MaxGitDiffLineCharacters int @@ -65,6 +64,8 @@ func newGit() { log.Fatal("Error retrieving git version: %v", err) } + log.Info("Git Version: %s", binVersion) + if version.Compare(binVersion, "2.9", ">=") { // Explicitly disable credential helper, otherwise Git credentials might leak git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "credential.helper=") diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 461e394a62..de89c67d04 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -27,6 +27,7 @@ import ( _ "code.gitea.io/gitea/modules/minwinsvc" // import minwinsvc for windows services "code.gitea.io/gitea/modules/user" + "github.com/Unknwon/cae/zip" "github.com/Unknwon/com" _ "github.com/go-macaron/cache/memcache" // memcache plugin for cache _ "github.com/go-macaron/cache/redis" @@ -931,6 +932,8 @@ func NewContext() { sec = Cfg.Section("U2F") U2F.TrustedFacets, _ = shellquote.Split(sec.Key("TRUSTED_FACETS").MustString(strings.TrimRight(AppURL, "/"))) U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimRight(AppURL, "/")) + + zip.Verbose = false } func loadInternalToken(sec *ini.Section) string { diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 7b8422fc61..0e6fa2c242 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/cron" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" ) @@ -210,7 +211,7 @@ func Config(ctx *context.Context) { ctx.Data["DisableRouterLog"] = setting.DisableRouterLog ctx.Data["RunUser"] = setting.RunUser ctx.Data["RunMode"] = strings.Title(macaron.Env) - ctx.Data["GitVersion"] = setting.Git.Version + ctx.Data["GitVersion"], _ = git.BinVersion() ctx.Data["RepoRootPath"] = setting.RepoRootPath ctx.Data["CustomRootPath"] = setting.CustomPath ctx.Data["StaticRootPath"] = setting.StaticRootPath diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 56aac8014c..62153893a6 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -56,6 +56,15 @@ func Search(ctx *context.APIContext) { // description: search only for repos that the user with the given id owns or contributes to // type: integer // format: int64 + // - name: starredBy + // in: query + // description: search only for repos that the user with the given id has starred + // type: integer + // format: int64 + // - name: private + // in: query + // description: include private repositories this user has access to (defaults to true) + // type: boolean // - name: page // in: query // description: page number of results to return (1-based) @@ -96,6 +105,10 @@ func Search(ctx *context.APIContext) { PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")), TopicOnly: ctx.QueryBool("topic"), Collaborate: util.OptionalBoolNone, + Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")), + UserIsAdmin: ctx.IsUserSiteAdmin(), + UserID: ctx.Data["SignedUserID"].(int64), + StarredByID: ctx.QueryInt64("starredBy"), } if ctx.QueryBool("exclusive") { @@ -140,42 +153,6 @@ func Search(ctx *context.APIContext) { } var err error - if opts.OwnerID > 0 { - var repoOwner *models.User - if ctx.User != nil && ctx.User.ID == opts.OwnerID { - repoOwner = ctx.User - } else { - repoOwner, err = models.GetUserByID(opts.OwnerID) - if err != nil { - ctx.JSON(500, api.SearchError{ - OK: false, - Error: err.Error(), - }) - return - } - } - - if repoOwner.IsOrganization() { - opts.Collaborate = util.OptionalBoolFalse - } - - // Check visibility. - if ctx.IsSigned { - if ctx.User.ID == repoOwner.ID { - opts.Private = true - } else if repoOwner.IsOrganization() { - opts.Private, err = repoOwner.IsOwnedBy(ctx.User.ID) - if err != nil { - ctx.JSON(500, api.SearchError{ - OK: false, - Error: err.Error(), - }) - return - } - } - } - } - repos, count, err := models.SearchRepositoryByName(opts) if err != nil { ctx.JSON(500, api.SearchError{ diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index da15850ec5..92846c5f2a 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -98,6 +98,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID URL: form.Config["url"], ContentType: models.ToHookContentType(form.Config["content_type"]), Secret: form.Config["secret"], + HTTPMethod: "POST", HookEvent: &models.HookEvent{ ChooseEvents: true, HookEvents: models.HookEvents{ diff --git a/routers/init.go b/routers/init.go index 47f837c523..88422cc6ed 100644 --- a/routers/init.go +++ b/routers/init.go @@ -86,7 +86,6 @@ func GlobalInit() { log.Fatal("Failed to initialize OAuth2 support: %v", err) } - models.LoadRepoConfig() models.NewRepoContext() // Booting long running goroutines. diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go index 7695f208ce..8daf721b50 100644 --- a/routers/repo/webhook.go +++ b/routers/repo/webhook.go @@ -564,6 +564,7 @@ func WebHooksEditPost(ctx *context.Context, form auth.NewWebhookForm) { w.Secret = form.Secret w.HookEvent = ParseHookEvent(form.WebhookForm) w.IsActive = form.Active + w.HTTPMethod = form.HTTPMethod if err := w.UpdateEvent(); err != nil { ctx.ServerError("UpdateEvent", err) return diff --git a/routers/user/home.go b/routers/user/home.go index b53a47db94..9ccd5bdb26 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -499,50 +499,20 @@ func showOrgProfile(ctx *context.Context) { count int64 err error ) - if ctx.IsSigned && !ctx.User.IsAdmin { - env, err := org.AccessibleReposEnv(ctx.User.ID) - if err != nil { - ctx.ServerError("AccessibleReposEnv", err) - return - } - env.SetSort(orderBy) - if len(keyword) != 0 { - env.AddKeyword(keyword) - } - repos, err = env.Repos(page, setting.UI.User.RepoPagingNum) - if err != nil { - ctx.ServerError("env.Repos", err) - return - } - count, err = env.CountRepos() - if err != nil { - ctx.ServerError("env.CountRepos", err) - return - } - } else { - showPrivate := ctx.IsSigned && ctx.User.IsAdmin - if len(keyword) == 0 { - repos, err = models.GetUserRepositories(org.ID, showPrivate, page, setting.UI.User.RepoPagingNum, orderBy.String()) - if err != nil { - ctx.ServerError("GetRepositories", err) - return - } - count = models.CountUserRepositories(org.ID, showPrivate) - } else { - repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ - Keyword: keyword, - OwnerID: org.ID, - OrderBy: orderBy, - Private: showPrivate, - Page: page, - IsProfile: true, - PageSize: setting.UI.User.RepoPagingNum, - }) - if err != nil { - ctx.ServerError("SearchRepositoryByName", err) - return - } - } + repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ + Keyword: keyword, + OwnerID: org.ID, + OrderBy: orderBy, + Private: ctx.IsSigned, + UserIsAdmin: ctx.IsUserSiteAdmin(), + UserID: ctx.Data["SignedUserID"].(int64), + Page: page, + IsProfile: true, + PageSize: setting.UI.User.RepoPagingNum, + }) + if err != nil { + ctx.ServerError("SearchRepositoryByName", err) + return } if err := org.GetMembers(); err != nil { diff --git a/routers/user/profile.go b/routers/user/profile.go index a7dab18c7a..bda29522d9 100644 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -170,74 +170,44 @@ func Profile(ctx *context.Context) { } case "stars": ctx.Data["PageIsProfileStarList"] = true - if len(keyword) == 0 { - repos, err = ctxUser.GetStarredRepos(showPrivate, page, setting.UI.User.RepoPagingNum, orderBy.String()) - if err != nil { - ctx.ServerError("GetStarredRepos", err) - return - } - - count, err = ctxUser.GetStarredRepoCount(showPrivate) - if err != nil { - ctx.ServerError("GetStarredRepoCount", err) - return - } - } else { - repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ - Keyword: keyword, - OwnerID: ctxUser.ID, - OrderBy: orderBy, - Private: showPrivate, - Page: page, - PageSize: setting.UI.User.RepoPagingNum, - Starred: true, - Collaborate: util.OptionalBoolFalse, - TopicOnly: topicOnly, - }) - if err != nil { - ctx.ServerError("SearchRepositoryByName", err) - return - } + repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ + Keyword: keyword, + OrderBy: orderBy, + Private: ctx.IsSigned, + UserIsAdmin: ctx.IsUserSiteAdmin(), + UserID: ctx.Data["SignedUserID"].(int64), + Page: page, + PageSize: setting.UI.User.RepoPagingNum, + StarredByID: ctxUser.ID, + Collaborate: util.OptionalBoolFalse, + TopicOnly: topicOnly, + }) + if err != nil { + ctx.ServerError("SearchRepositoryByName", err) + return } total = int(count) default: - if len(keyword) == 0 { - repos, err = models.GetUserRepositories(ctxUser.ID, showPrivate, page, setting.UI.User.RepoPagingNum, orderBy.String()) - if err != nil { - ctx.ServerError("GetRepositories", err) - return - } - - if showPrivate { - total = ctxUser.NumRepos - } else { - count, err := models.GetPublicRepositoryCount(ctxUser) - if err != nil { - ctx.ServerError("GetPublicRepositoryCount", err) - return - } - total = int(count) - } - } else { - repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ - Keyword: keyword, - OwnerID: ctxUser.ID, - OrderBy: orderBy, - Private: showPrivate, - Page: page, - IsProfile: true, - PageSize: setting.UI.User.RepoPagingNum, - Collaborate: util.OptionalBoolFalse, - TopicOnly: topicOnly, - }) - if err != nil { - ctx.ServerError("SearchRepositoryByName", err) - return - } - - total = int(count) + repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{ + Keyword: keyword, + OwnerID: ctxUser.ID, + OrderBy: orderBy, + Private: ctx.IsSigned, + UserIsAdmin: ctx.IsUserSiteAdmin(), + UserID: ctx.Data["SignedUserID"].(int64), + Page: page, + IsProfile: true, + PageSize: setting.UI.User.RepoPagingNum, + Collaborate: util.OptionalBoolFalse, + TopicOnly: topicOnly, + }) + if err != nil { + ctx.ServerError("SearchRepositoryByName", err) + return } + + total = int(count) } ctx.Data["Repos"] = repos ctx.Data["Total"] = total diff --git a/templates/repo/settings/webhook/history.tmpl b/templates/repo/settings/webhook/history.tmpl index 7f85c702b5..577f357720 100644 --- a/templates/repo/settings/webhook/history.tmpl +++ b/templates/repo/settings/webhook/history.tmpl @@ -45,7 +45,7 @@ {{if .RequestInfo}}
Request URL: {{.URL}} -Request method: POST +Request method: {{if .HTTPMethod}}{{.HTTPMethod}}{{else}}POST{{end}} {{ range $key, $val := .RequestInfo.Headers }}{{$key}}: {{$val}} {{end}}