mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-03 08:02:36 +09:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf7a5b3d91 | ||
|
|
5d1a8d23b0 | ||
|
|
dbd0a2e6dc | ||
|
|
7697a282d6 | ||
|
|
76e8eec3d9 | ||
|
|
10effb396a | ||
|
|
5e97b2d00e | ||
|
|
873acd884d | ||
|
|
dc73b2748d | ||
|
|
31ad8b7026 | ||
|
|
d07edc5336 | ||
|
|
63cb160cb1 | ||
|
|
8d5c3d3d0b | ||
|
|
706d85b87d | ||
|
|
75e491c03e | ||
|
|
608f46e59c | ||
|
|
895764e7f5 | ||
|
|
21983965d0 | ||
|
|
e069a75817 | ||
|
|
ebb8fa610c | ||
|
|
c8fc7fce4a |
25
CHANGELOG.md
25
CHANGELOG.md
@@ -4,6 +4,31 @@ This changelog goes through all the changes that have been made in each release
|
|||||||
without substantial changes to our git log; to see the highlights of what has
|
without substantial changes to our git log; to see the highlights of what has
|
||||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||||
|
|
||||||
|
## [1.8.3](https://github.com/go-gitea/gitea/releases/tag/v1.8.3) - 2019-06-17
|
||||||
|
* BUGFIXES
|
||||||
|
* Always set userID on LFS authentication (#7224) (Part of #6993)
|
||||||
|
* Fix LFS Locks over SSH (#6999) (#7223)
|
||||||
|
* Fix duplicated file on pull request conflicted files (#7211) (#7214)
|
||||||
|
* Detect noreply email address as user (#7133) (#7195)
|
||||||
|
* Don't get milestone from DB if ID is zero (#7169) (#7174)
|
||||||
|
* Allow archived repos to be (un)starred and (un)watched (#7163) (#7168)
|
||||||
|
* Fix GCArgs load from ini (#7156) (#7157)
|
||||||
|
|
||||||
|
## [1.8.2](https://github.com/go-gitea/gitea/releases/tag/v1.8.2) - 2019-05-29
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix possbile mysql invalid connnection error (#7051) (#7071)
|
||||||
|
* Handle invalid administrator username on install page (#7060) (#7063)
|
||||||
|
* Disable arm7 builds (#7037) (#7042)
|
||||||
|
* Fix default for allowing new organization creation for new users (#7017) (#7034)
|
||||||
|
* SearchRepositoryByName improvements and unification (#6897) (#7002)
|
||||||
|
* Fix u2f registrationlist ToRegistrations() method (#6980) (#6982)
|
||||||
|
* Allow collaborators to view repo owned by private org (#6965) (#6968)
|
||||||
|
* Use AppURL for Oauth user link (#6894) (#6925)
|
||||||
|
* Escape the commit message on issues update (#6901) (#6902)
|
||||||
|
* Fix regression for API users search (#6882) (#6885)
|
||||||
|
* Handle early git version's lack of get-url (#7065) (#7076)
|
||||||
|
* Fix wrong init dependency on markup extensions (#7038) (#7074)
|
||||||
|
|
||||||
## [1.8.1](https://github.com/go-gitea/gitea/releases/tag/v1.8.1) - 2019-05-08
|
## [1.8.1](https://github.com/go-gitea/gitea/releases/tag/v1.8.1) - 2019-05-08
|
||||||
* BUGFIXES
|
* BUGFIXES
|
||||||
* Fix 404 when sending pull requests in some situations (#6871) (#6873)
|
* Fix 404 when sending pull requests in some situations (#6871) (#6873)
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -336,7 +336,7 @@ release-linux:
|
|||||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||||
$(GO) get -u src.techknowlogick.com/xgo; \
|
$(GO) get -u src.techknowlogick.com/xgo; \
|
||||||
fi
|
fi
|
||||||
xgo -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/*' -out gitea-$(VERSION) .
|
xgo -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/mips64le,linux/mips,linux/mipsle' -out gitea-$(VERSION) .
|
||||||
ifeq ($(CI),drone)
|
ifeq ($(CI),drone)
|
||||||
cp /build/* $(DIST)/binaries
|
cp /build/* $(DIST)/binaries
|
||||||
endif
|
endif
|
||||||
|
|||||||
14
cmd/serv.go
14
cmd/serv.go
@@ -219,8 +219,9 @@ func runServ(c *cli.Context) error {
|
|||||||
var (
|
var (
|
||||||
keyID int64
|
keyID int64
|
||||||
user *models.User
|
user *models.User
|
||||||
|
userID int64
|
||||||
)
|
)
|
||||||
if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
|
|
||||||
keys := strings.Split(c.Args()[0], "-")
|
keys := strings.Split(c.Args()[0], "-")
|
||||||
if len(keys) != 2 {
|
if len(keys) != 2 {
|
||||||
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||||
@@ -231,8 +232,8 @@ func runServ(c *cli.Context) error {
|
|||||||
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
|
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
|
||||||
}
|
}
|
||||||
keyID = key.ID
|
keyID = key.ID
|
||||||
|
userID = key.OwnerID
|
||||||
|
|
||||||
// Check deploy key or user key.
|
|
||||||
if key.Type == models.KeyTypeDeploy {
|
if key.Type == models.KeyTypeDeploy {
|
||||||
// Now we have to get the deploy key for this repo
|
// Now we have to get the deploy key for this repo
|
||||||
deployKey, err := private.GetDeployKey(key.ID, repo.ID)
|
deployKey, err := private.GetDeployKey(key.ID, repo.ID)
|
||||||
@@ -258,7 +259,9 @@ func runServ(c *cli.Context) error {
|
|||||||
// so for now use the owner
|
// so for now use the owner
|
||||||
os.Setenv(models.EnvPusherName, username)
|
os.Setenv(models.EnvPusherName, username)
|
||||||
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", repo.OwnerID))
|
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", repo.OwnerID))
|
||||||
} else {
|
userID = repo.OwnerID
|
||||||
|
} else if requestedMode == models.AccessModeWrite || repo.IsPrivate || setting.Service.RequireSignInView {
|
||||||
|
// Check deploy key or user key.
|
||||||
user, err = private.GetUserByKeyID(key.ID)
|
user, err = private.GetUserByKeyID(key.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
|
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
|
||||||
@@ -286,7 +289,6 @@ func runServ(c *cli.Context) error {
|
|||||||
os.Setenv(models.EnvPusherName, user.Name)
|
os.Setenv(models.EnvPusherName, user.Name)
|
||||||
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
|
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//LFS token authentication
|
//LFS token authentication
|
||||||
if verb == lfsAuthenticateVerb {
|
if verb == lfsAuthenticateVerb {
|
||||||
@@ -299,8 +301,8 @@ func runServ(c *cli.Context) error {
|
|||||||
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
|
"exp": now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
|
||||||
"nbf": now.Unix(),
|
"nbf": now.Unix(),
|
||||||
}
|
}
|
||||||
if user != nil {
|
if userID > 0 {
|
||||||
claims["user"] = user.ID
|
claims["user"] = userID
|
||||||
}
|
}
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/markup/external"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/routers"
|
"code.gitea.io/gitea/routers"
|
||||||
"code.gitea.io/gitea/routers/routes"
|
"code.gitea.io/gitea/routers/routes"
|
||||||
@@ -120,8 +119,6 @@ func runWeb(ctx *cli.Context) error {
|
|||||||
|
|
||||||
routers.GlobalInit()
|
routers.GlobalInit()
|
||||||
|
|
||||||
external.RegisterParsers()
|
|
||||||
|
|
||||||
m := routes.NewMacaron()
|
m := routes.NewMacaron()
|
||||||
routes.RegisterRoutes(m)
|
routes.RegisterRoutes(m)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/markup"
|
||||||
"code.gitea.io/gitea/modules/markup/external"
|
"code.gitea.io/gitea/modules/markup/external"
|
||||||
"code.gitea.io/gitea/routers"
|
"code.gitea.io/gitea/routers"
|
||||||
"code.gitea.io/gitea/routers/routes"
|
"code.gitea.io/gitea/routers/routes"
|
||||||
@@ -113,6 +114,7 @@ func runPR() {
|
|||||||
log.Printf("[PR] Setting up router\n")
|
log.Printf("[PR] Setting up router\n")
|
||||||
//routers.GlobalInit()
|
//routers.GlobalInit()
|
||||||
external.RegisterParsers()
|
external.RegisterParsers()
|
||||||
|
markup.Init()
|
||||||
m := routes.NewMacaron()
|
m := routes.NewMacaron()
|
||||||
routes.RegisterRoutes(m)
|
routes.RegisterRoutes(m)
|
||||||
|
|
||||||
|
|||||||
@@ -129,3 +129,18 @@ func TestAPIListUsers(t *testing.T) {
|
|||||||
numberOfUsers := models.GetCount(t, &models.User{}, "type = 0")
|
numberOfUsers := models.GetCount(t, &models.User{}, "type = 0")
|
||||||
assert.Equal(t, numberOfUsers, len(users))
|
assert.Equal(t, numberOfUsers, len(users))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPIListUsersNotLoggedIn(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
req := NewRequest(t, "GET", "/api/v1/admin/users")
|
||||||
|
MakeRequest(t, req, http.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIListUsersNonAdmin(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
nonAdminUsername := "user2"
|
||||||
|
session := loginUser(t, nonAdminUsername)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/admin/users?token=%s", token)
|
||||||
|
session.MakeRequest(t, req, http.StatusForbidden)
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,40 +69,41 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
name, requestURL string
|
name, requestURL string
|
||||||
expectedResults
|
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: 19},
|
nil: {count: 19},
|
||||||
user: {count: 19},
|
user: {count: 19},
|
||||||
user2: {count: 19}},
|
user2: {count: 19}},
|
||||||
},
|
},
|
||||||
{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},
|
nil: {count: 10},
|
||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {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},
|
nil: {count: 10},
|
||||||
user: {count: 10},
|
user: {count: 10},
|
||||||
user2: {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_"},
|
nil: {count: 7, repoName: "big_test_"},
|
||||||
user: {count: 7, repoName: "big_test_"},
|
user: {count: 7, repoName: "big_test_"},
|
||||||
user2: {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{
|
{name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{
|
||||||
nil: {count: 4},
|
nil: {count: 5},
|
||||||
user: {count: 8, includesPrivate: true},
|
user: {count: 9, includesPrivate: true},
|
||||||
user2: {count: 4}},
|
user2: {count: 5, includesPrivate: true}},
|
||||||
},
|
},
|
||||||
{name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{
|
{name: "RepositoriesAccessibleAndRelatedToUser2", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user2.ID), expectedResults: expectedResults{
|
||||||
nil: {count: 1},
|
nil: {count: 1},
|
||||||
user: {count: 1},
|
user: {count: 2, includesPrivate: true},
|
||||||
user2: {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{
|
{name: "RepositoriesAccessibleAndRelatedToUser3", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user3.ID), expectedResults: expectedResults{
|
||||||
nil: {count: 1},
|
nil: {count: 1},
|
||||||
user: {count: 1},
|
user: {count: 4, includesPrivate: true},
|
||||||
user2: {count: 1},
|
user2: {count: 2, includesPrivate: true},
|
||||||
user3: {count: 4, includesPrivate: true}},
|
user3: {count: 4, includesPrivate: true}},
|
||||||
},
|
},
|
||||||
{name: "RepositoriesOwnedByOrganization", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", orgUser.ID), expectedResults: expectedResults{
|
{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{
|
{name: "RepositoriesAccessibleAndRelatedToUser4", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user4.ID), expectedResults: expectedResults{
|
||||||
nil: {count: 3},
|
nil: {count: 3},
|
||||||
user: {count: 3},
|
user: {count: 4, includesPrivate: true},
|
||||||
user4: {count: 6, 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{
|
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeSource", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "source"), expectedResults: expectedResults{
|
||||||
nil: {count: 0},
|
nil: {count: 0},
|
||||||
user: {count: 0},
|
user: {count: 1, includesPrivate: true},
|
||||||
user4: {count: 0, 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{
|
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeFork", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "fork"), expectedResults: expectedResults{
|
||||||
nil: {count: 1},
|
nil: {count: 1},
|
||||||
user: {count: 1},
|
user: {count: 1},
|
||||||
@@ -136,8 +137,8 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
user4: {count: 2, includesPrivate: true}}},
|
user4: {count: 2, includesPrivate: true}}},
|
||||||
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeCollaborative", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "collaborative"), expectedResults: expectedResults{
|
{name: "RepositoriesAccessibleAndRelatedToUser4/SearchModeCollaborative", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d&mode=%s", user4.ID, "collaborative"), expectedResults: expectedResults{
|
||||||
nil: {count: 0},
|
nil: {count: 0},
|
||||||
user: {count: 0},
|
user: {count: 1, includesPrivate: true},
|
||||||
user4: {count: 0, includesPrivate: true}}},
|
user4: {count: 1, includesPrivate: true}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
@@ -164,14 +165,19 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
var body api.SearchResults
|
var body api.SearchResults
|
||||||
DecodeJSON(t, response, &body)
|
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 {
|
for _, repo := range body.Data {
|
||||||
r := getRepo(t, repo.ID)
|
r := getRepo(t, repo.ID)
|
||||||
hasAccess, err := models.HasAccess(userID, r)
|
hasAccess, err := models.HasAccess(userID, r)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err, "Error when checking if User: %d has access to %s: %v", userID, repo.FullName, err)
|
||||||
assert.True(t, hasAccess)
|
assert.True(t, hasAccess, "User: %d does not have access to %s", userID, repo.FullName)
|
||||||
|
|
||||||
assert.NotEmpty(t, repo.Name)
|
assert.NotEmpty(t, repo.Name)
|
||||||
|
assert.Equal(t, repo.Name, r.Name)
|
||||||
|
|
||||||
if len(expected.repoName) > 0 {
|
if len(expected.repoName) > 0 {
|
||||||
assert.Contains(t, repo.Name, expected.repoName)
|
assert.Contains(t, repo.Name, expected.repoName)
|
||||||
@@ -182,7 +188,7 @@ func TestAPISearchRepo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !expected.includesPrivate {
|
if !expected.includesPrivate {
|
||||||
assert.False(t, repo.Private)
|
assert.False(t, repo.Private, "User: %d not expecting private repository: %s", userID, repo.FullName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
52
integrations/api_user_search_test.go
Normal file
52
integrations/api_user_search_test.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.package models
|
||||||
|
|
||||||
|
package integrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
api "code.gitea.io/sdk/gitea"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SearchResults struct {
|
||||||
|
OK bool `json:"ok"`
|
||||||
|
Data []*api.User `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIUserSearchLoggedIn(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
adminUsername := "user1"
|
||||||
|
session := loginUser(t, adminUsername)
|
||||||
|
token := getTokenForLoggedInUser(t, session)
|
||||||
|
query := "user2"
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/users/search?token=%s&q=%s", token, query)
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var results SearchResults
|
||||||
|
DecodeJSON(t, resp, &results)
|
||||||
|
assert.NotEmpty(t, results.Data)
|
||||||
|
for _, user := range results.Data {
|
||||||
|
assert.Contains(t, user.UserName, query)
|
||||||
|
assert.NotEmpty(t, user.Email)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPIUserSearchNotLoggedIn(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
query := "user2"
|
||||||
|
req := NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var results SearchResults
|
||||||
|
DecodeJSON(t, resp, &results)
|
||||||
|
assert.NotEmpty(t, results.Data)
|
||||||
|
for _, user := range results.Data {
|
||||||
|
assert.Contains(t, user.UserName, query)
|
||||||
|
assert.Empty(t, user.Email)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,6 +61,10 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
little = commitAndPush(t, littleSize, dstPath)
|
little = commitAndPush(t, littleSize, dstPath)
|
||||||
})
|
})
|
||||||
t.Run("Big", func(t *testing.T) {
|
t.Run("Big", func(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
return
|
||||||
|
}
|
||||||
big = commitAndPush(t, bigSize, dstPath)
|
big = commitAndPush(t, bigSize, dstPath)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -77,9 +81,15 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
|
|
||||||
t.Run("Little", func(t *testing.T) {
|
t.Run("Little", func(t *testing.T) {
|
||||||
littleLFS = commitAndPush(t, littleSize, dstPath)
|
littleLFS = commitAndPush(t, littleSize, dstPath)
|
||||||
|
lockFileTest(t, littleLFS, dstPath)
|
||||||
})
|
})
|
||||||
t.Run("Big", func(t *testing.T) {
|
t.Run("Big", func(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
return
|
||||||
|
}
|
||||||
bigLFS = commitAndPush(t, bigSize, dstPath)
|
bigLFS = commitAndPush(t, bigSize, dstPath)
|
||||||
|
lockFileTest(t, bigLFS, dstPath)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("Locks", func(t *testing.T) {
|
t.Run("Locks", func(t *testing.T) {
|
||||||
@@ -94,19 +104,21 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big))
|
|
||||||
nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
|
||||||
assert.Equal(t, bigSize, nilResp.Length)
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, littleSize, resp.Body.Len())
|
assert.NotEqual(t, littleSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big))
|
||||||
|
nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
|
assert.Equal(t, bigSize, nilResp.Length)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, bigSize, resp.Body.Len())
|
assert.NotEqual(t, bigSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
t.Run("Media", func(t *testing.T) {
|
t.Run("Media", func(t *testing.T) {
|
||||||
@@ -117,17 +129,19 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big))
|
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Length)
|
assert.Equal(t, littleSize, resp.Length)
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big))
|
||||||
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Length)
|
assert.Equal(t, bigSize, resp.Length)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -160,6 +174,10 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
little = commitAndPush(t, littleSize, dstPath)
|
little = commitAndPush(t, littleSize, dstPath)
|
||||||
})
|
})
|
||||||
t.Run("Big", func(t *testing.T) {
|
t.Run("Big", func(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode.")
|
||||||
|
return
|
||||||
|
}
|
||||||
big = commitAndPush(t, bigSize, dstPath)
|
big = commitAndPush(t, bigSize, dstPath)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -176,9 +194,16 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
|
|
||||||
t.Run("Little", func(t *testing.T) {
|
t.Run("Little", func(t *testing.T) {
|
||||||
littleLFS = commitAndPush(t, littleSize, dstPath)
|
littleLFS = commitAndPush(t, littleSize, dstPath)
|
||||||
|
lockFileTest(t, littleLFS, dstPath)
|
||||||
|
|
||||||
})
|
})
|
||||||
t.Run("Big", func(t *testing.T) {
|
t.Run("Big", func(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
return
|
||||||
|
}
|
||||||
bigLFS = commitAndPush(t, bigSize, dstPath)
|
bigLFS = commitAndPush(t, bigSize, dstPath)
|
||||||
|
lockFileTest(t, bigLFS, dstPath)
|
||||||
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("Locks", func(t *testing.T) {
|
t.Run("Locks", func(t *testing.T) {
|
||||||
@@ -193,20 +218,21 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big))
|
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
assert.Equal(t, bigSize, resp.Body.Len())
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, littleSize, resp.Body.Len())
|
assert.NotEqual(t, littleSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
assert.Equal(t, bigSize, resp.Body.Len())
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.NotEqual(t, bigSize, resp.Body.Len())
|
assert.NotEqual(t, bigSize, resp.Body.Len())
|
||||||
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
t.Run("Media", func(t *testing.T) {
|
t.Run("Media", func(t *testing.T) {
|
||||||
session := loginUser(t, "user2")
|
session := loginUser(t, "user2")
|
||||||
@@ -216,17 +242,19 @@ func testGit(t *testing.T, u *url.URL) {
|
|||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big))
|
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
|
||||||
assert.Equal(t, bigSize, resp.Body.Len())
|
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, littleSize, resp.Body.Len())
|
assert.Equal(t, littleSize, resp.Body.Len())
|
||||||
|
|
||||||
|
if !testing.Short() {
|
||||||
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
assert.Equal(t, bigSize, resp.Body.Len())
|
||||||
|
|
||||||
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS))
|
req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
assert.Equal(t, bigSize, resp.Body.Len())
|
assert.Equal(t, bigSize, resp.Body.Len())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -243,15 +271,17 @@ func ensureAnonymousClone(t *testing.T, u *url.URL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func lockTest(t *testing.T, remote, repoPath string) {
|
func lockTest(t *testing.T, remote, repoPath string) {
|
||||||
_, err := git.NewCommand("remote").AddArguments("set-url", "origin", remote).RunInDir(repoPath) //TODO add test ssh git-lfs-creds
|
lockFileTest(t, "README.md", repoPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func lockFileTest(t *testing.T, filename, repoPath string) {
|
||||||
|
_, err := git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = git.NewCommand("lfs").AddArguments("lock", filename).RunInDir(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
|
_, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, err = git.NewCommand("lfs").AddArguments("lock", "README.md").RunInDir(repoPath)
|
_, err = git.NewCommand("lfs").AddArguments("unlock", filename).RunInDir(repoPath)
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
_, err = git.NewCommand("lfs").AddArguments("unlock", "README.md").RunInDir(repoPath)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,15 @@ func TestPrivateOrg(t *testing.T) {
|
|||||||
req = NewRequest(t, "GET", "/privated_org/private_repo_on_private_org")
|
req = NewRequest(t, "GET", "/privated_org/private_repo_on_private_org")
|
||||||
session.MakeRequest(t, req, http.StatusNotFound)
|
session.MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
|
// non-org member who is collaborator on repo in private org
|
||||||
|
session = loginUser(t, "user4")
|
||||||
|
req = NewRequest(t, "GET", "/privated_org")
|
||||||
|
session.MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
req = NewRequest(t, "GET", "/privated_org/public_repo_on_private_org") // colab of this repo
|
||||||
|
session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
req = NewRequest(t, "GET", "/privated_org/private_repo_on_private_org")
|
||||||
|
session.MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
// site admin
|
// site admin
|
||||||
session = loginUser(t, "user1")
|
session = loginUser(t, "user1")
|
||||||
req = NewRequest(t, "GET", "/privated_org")
|
req = NewRequest(t, "GET", "/privated_org")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -532,7 +533,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
|
|||||||
}
|
}
|
||||||
refMarked[issue.ID] = true
|
refMarked[issue.ID] = true
|
||||||
|
|
||||||
message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, c.Message)
|
message := fmt.Sprintf(`<a href="%s/commit/%s">%s</a>`, repo.Link(), c.Sha1, html.EscapeString(c.Message))
|
||||||
if err = CreateRefComment(doer, repo, issue, message, c.Sha1); err != nil {
|
if err = CreateRefComment(doer, repo, issue, message, c.Sha1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,3 +9,9 @@
|
|||||||
repo_id: 4
|
repo_id: 4
|
||||||
user_id: 4
|
user_id: 4
|
||||||
mode: 2 # write
|
mode: 2 # write
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
repo_id: 38
|
||||||
|
user_id: 4
|
||||||
|
mode: 2 # write
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@@ -277,6 +278,11 @@ func SetEngine() (err error) {
|
|||||||
// so use log file to instead print to stdout.
|
// so use log file to instead print to stdout.
|
||||||
x.SetLogger(log.XORMLogger)
|
x.SetLogger(log.XORMLogger)
|
||||||
x.ShowSQL(setting.LogSQL)
|
x.ShowSQL(setting.LogSQL)
|
||||||
|
if DbCfg.Type == "mysql" {
|
||||||
|
x.SetMaxIdleConns(0)
|
||||||
|
x.SetConnMaxLifetime(3 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -861,7 +861,17 @@ func (pr *PullRequest) testPatch(e Engine) (err error) {
|
|||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
|
||||||
if strings.HasPrefix(line, prefix) {
|
if strings.HasPrefix(line, prefix) {
|
||||||
pr.ConflictedFiles = append(pr.ConflictedFiles, strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0]))
|
var found bool
|
||||||
|
var filepath = strings.TrimSpace(strings.Split(line[len(prefix):], ":")[0])
|
||||||
|
for _, f := range pr.ConflictedFiles {
|
||||||
|
if f == filepath {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
pr.ConflictedFiles = append(pr.ConflictedFiles, filepath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// only list 10 conflicted files
|
// only list 10 conflicted files
|
||||||
if len(pr.ConflictedFiles) >= 10 {
|
if len(pr.ConflictedFiles) >= 10 {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/go-xorm/builder"
|
"github.com/go-xorm/builder"
|
||||||
"github.com/go-xorm/core"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RepositoryListDefaultPageSize is the default number of repositories
|
// RepositoryListDefaultPageSize is the default number of repositories
|
||||||
@@ -112,11 +111,13 @@ func (repos MirrorRepositoryList) LoadAttributes() error {
|
|||||||
|
|
||||||
// SearchRepoOptions holds the search options
|
// SearchRepoOptions holds the search options
|
||||||
type SearchRepoOptions struct {
|
type SearchRepoOptions struct {
|
||||||
|
UserID int64
|
||||||
|
UserIsAdmin bool
|
||||||
Keyword string
|
Keyword string
|
||||||
OwnerID int64
|
OwnerID int64
|
||||||
OrderBy SearchOrderBy
|
OrderBy SearchOrderBy
|
||||||
Private bool // Include private repositories in results
|
Private bool // Include private repositories in results
|
||||||
Starred bool
|
StarredByID int64
|
||||||
Page int
|
Page int
|
||||||
IsProfile bool
|
IsProfile bool
|
||||||
AllPublic bool // Include also all public repositories
|
AllPublic bool // Include also all public repositories
|
||||||
@@ -168,21 +169,53 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
|
|||||||
if opts.Page <= 0 {
|
if opts.Page <= 0 {
|
||||||
opts.Page = 1
|
opts.Page = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var cond = builder.NewCond()
|
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})
|
cond = cond.And(builder.Eq{"is_private": false})
|
||||||
accessCond := builder.Or(
|
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}))),
|
// A. Aren't in organisations __OR__
|
||||||
builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})))
|
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)
|
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.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()
|
var accessCond = builder.NewCond()
|
||||||
if opts.Collaborate != util.OptionalBoolTrue {
|
if opts.Collaborate != util.OptionalBoolTrue {
|
||||||
accessCond = builder.Eq{"owner_id": opts.OwnerID}
|
accessCond = builder.Eq{"owner_id": opts.OwnerID}
|
||||||
@@ -190,7 +223,12 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
|
|||||||
|
|
||||||
if opts.Collaborate != util.OptionalBoolFalse {
|
if opts.Collaborate != util.OptionalBoolFalse {
|
||||||
collaborateCond := builder.And(
|
collaborateCond := builder.And(
|
||||||
|
builder.Or(
|
||||||
builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID),
|
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})
|
builder.Neq{"owner_id": opts.OwnerID})
|
||||||
if !opts.Private {
|
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))
|
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))
|
||||||
@@ -199,42 +237,12 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
|
|||||||
accessCond = accessCond.Or(collaborateCond)
|
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 {
|
if opts.AllPublic {
|
||||||
accessCond = accessCond.Or(builder.Eq{"is_private": false})
|
accessCond = accessCond.Or(builder.Eq{"is_private": false})
|
||||||
}
|
}
|
||||||
|
|
||||||
cond = cond.And(accessCond)
|
cond = cond.And(accessCond)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Keyword != "" {
|
if opts.Keyword != "" {
|
||||||
// separate keyword
|
// separate keyword
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ func TestSearchRepositoryByName(t *testing.T) {
|
|||||||
count: 4},
|
count: 4},
|
||||||
{name: "PublicRepositoriesOfUserIncludingCollaborative",
|
{name: "PublicRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15},
|
||||||
count: 4},
|
count: 5},
|
||||||
{name: "PublicRepositoriesOfUser2IncludingCollaborative",
|
{name: "PublicRepositoriesOfUser2IncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18},
|
||||||
count: 1},
|
count: 1},
|
||||||
@@ -126,13 +126,13 @@ func TestSearchRepositoryByName(t *testing.T) {
|
|||||||
count: 3},
|
count: 3},
|
||||||
{name: "PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
{name: "PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true},
|
||||||
count: 8},
|
count: 9},
|
||||||
{name: "PublicAndPrivateRepositoriesOfUser2IncludingCollaborative",
|
{name: "PublicAndPrivateRepositoriesOfUser2IncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18, Private: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 18, Private: true},
|
||||||
count: 4},
|
count: 4},
|
||||||
{name: "PublicAndPrivateRepositoriesOfUser3IncludingCollaborative",
|
{name: "PublicAndPrivateRepositoriesOfUser3IncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 20, Private: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 20, Private: true},
|
||||||
count: 6},
|
count: 7},
|
||||||
{name: "PublicRepositoriesOfOrganization",
|
{name: "PublicRepositoriesOfOrganization",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, Collaborate: util.OptionalBoolFalse},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 17, Collaborate: util.OptionalBoolFalse},
|
||||||
count: 1},
|
count: 1},
|
||||||
@@ -150,7 +150,7 @@ func TestSearchRepositoryByName(t *testing.T) {
|
|||||||
count: 19},
|
count: 19},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
|
||||||
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
||||||
count: 24},
|
count: 25},
|
||||||
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
{name: "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborativeByName",
|
||||||
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
opts: &SearchRepoOptions{Keyword: "test", Page: 1, PageSize: 10, OwnerID: 15, Private: true, AllPublic: true},
|
||||||
count: 13},
|
count: 13},
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MirrorQueue holds an UniqueQueue object of the mirror
|
// MirrorQueue holds an UniqueQueue object of the mirror
|
||||||
@@ -70,7 +71,17 @@ func (m *Mirror) ScheduleNextUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func remoteAddress(repoPath string) (string, error) {
|
func remoteAddress(repoPath string) (string, error) {
|
||||||
cmd := git.NewCommand("remote", "get-url", "origin")
|
var cmd *git.Command
|
||||||
|
binVersion, err := git.BinVersion()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if version.Compare(binVersion, "2.7", ">=") {
|
||||||
|
cmd = git.NewCommand("remote", "get-url", "origin")
|
||||||
|
} else {
|
||||||
|
cmd = git.NewCommand("config", "--get", "remote.origin.url")
|
||||||
|
}
|
||||||
|
|
||||||
result, err := cmd.RunInDir(repoPath)
|
result, err := cmd.RunInDir(repoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
if strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||||
|
|||||||
@@ -107,7 +107,17 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
|
|||||||
repo.mustOwner(e)
|
repo.mustOwner(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if repo.Owner.IsOrganization() && !HasOrgVisible(repo.Owner, user) {
|
var isCollaborator bool
|
||||||
|
if user != nil {
|
||||||
|
isCollaborator, err = repo.isCollaborator(e, user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return perm, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent strangers from checking out public repo of private orginization
|
||||||
|
// Allow user if they are collaborator of a repo within a private orginization but not a member of the orginization itself
|
||||||
|
if repo.Owner.IsOrganization() && !HasOrgVisible(repo.Owner, user) && !isCollaborator {
|
||||||
perm.AccessMode = AccessModeNone
|
perm.AccessMode = AccessModeNone
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -146,9 +156,7 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
|
|||||||
perm.UnitsMode = make(map[UnitType]AccessMode)
|
perm.UnitsMode = make(map[UnitType]AccessMode)
|
||||||
|
|
||||||
// Collaborators on organization
|
// Collaborators on organization
|
||||||
if isCollaborator, err := repo.isCollaborator(e, user.ID); err != nil {
|
if isCollaborator {
|
||||||
return perm, err
|
|
||||||
} else if isCollaborator {
|
|
||||||
for _, u := range repo.Units {
|
for _, u := range repo.Units {
|
||||||
perm.UnitsMode[u.Type] = perm.AccessMode
|
perm.UnitsMode[u.Type] = perm.AccessMode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ type U2FRegistrationList []*U2FRegistration
|
|||||||
|
|
||||||
// ToRegistrations will convert all U2FRegistrations to u2f.Registrations
|
// ToRegistrations will convert all U2FRegistrations to u2f.Registrations
|
||||||
func (list U2FRegistrationList) ToRegistrations() []u2f.Registration {
|
func (list U2FRegistrationList) ToRegistrations() []u2f.Registration {
|
||||||
regs := make([]u2f.Registration, len(list))
|
regs := make([]u2f.Registration, 0, len(list))
|
||||||
for _, reg := range list {
|
for _, reg := range list {
|
||||||
r, err := reg.Parse()
|
r, err := reg.Parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -832,10 +832,9 @@ func CreateUser(u *User) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
u.HashPassword(u.Passwd)
|
u.HashPassword(u.Passwd)
|
||||||
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization
|
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation
|
||||||
u.MaxRepoCreation = -1
|
u.MaxRepoCreation = -1
|
||||||
u.Theme = setting.UI.DefaultTheme
|
u.Theme = setting.UI.DefaultTheme
|
||||||
u.AllowCreateOrganization = !setting.Admin.DisableRegularOrgCreation
|
|
||||||
|
|
||||||
if _, err = sess.Insert(u); err != nil {
|
if _, err = sess.Insert(u); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1347,6 +1346,19 @@ func GetUserByEmail(email string) (*User, error) {
|
|||||||
return GetUserByID(emailAddress.UID)
|
return GetUserByID(emailAddress.UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, if email address is the protected email address:
|
||||||
|
if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) {
|
||||||
|
username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress))
|
||||||
|
user := &User{LowerName: username}
|
||||||
|
has, err := x.Get(user)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil, ErrUserNotExist{0, email, 0}
|
return nil, ErrUserNotExist{0, email, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -261,6 +261,8 @@ func TestCreateUser_Issue5882(t *testing.T) {
|
|||||||
{&User{Name: "GiteaBot2", Email: "GiteaBot2@gitea.io", Passwd: passwd, MustChangePassword: false}, true},
|
{&User{Name: "GiteaBot2", Email: "GiteaBot2@gitea.io", Passwd: passwd, MustChangePassword: false}, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setting.Service.DefaultAllowCreateOrganization = true
|
||||||
|
|
||||||
for _, v := range tt {
|
for _, v := range tt {
|
||||||
setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation
|
setting.Admin.DisableRegularOrgCreation = v.disableOrgCreation
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/sdk/gitea"
|
api "code.gitea.io/sdk/gitea"
|
||||||
)
|
)
|
||||||
@@ -44,7 +45,7 @@ func checkIsValidRequest(ctx *context.Context, post bool) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
|
func handleLockListOut(ctx *context.Context, repo *models.Repository, lock *models.LFSLock, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrLFSLockNotExist(err) {
|
if models.IsErrLFSLockNotExist(err) {
|
||||||
ctx.JSON(200, api.LFSLockList{
|
ctx.JSON(200, api.LFSLockList{
|
||||||
@@ -57,7 +58,7 @@ func handleLockListOut(ctx *context.Context, lock *models.LFSLock, err error) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ctx.Repo.Repository.ID != lock.RepoID {
|
if repo.ID != lock.RepoID {
|
||||||
ctx.JSON(200, api.LFSLockList{
|
ctx.JSON(200, api.LFSLockList{
|
||||||
Locks: []*api.LFSLock{},
|
Locks: []*api.LFSLock{},
|
||||||
})
|
})
|
||||||
@@ -75,17 +76,21 @@ func GetListLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
||||||
|
|
||||||
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeRead)
|
rv := unpack(ctx)
|
||||||
|
|
||||||
|
repository, err := models.GetRepositoryByOwnerAndName(rv.User, rv.Repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrLFSUnauthorizedAction(err) {
|
log.Debug("Could not find repository: %s/%s - %s", rv.User, rv.Repo, err)
|
||||||
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
writeStatus(ctx, 404)
|
||||||
ctx.JSON(401, api.LFSLockError{
|
|
||||||
Message: "You must have pull access to list locks : " + err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.JSON(500, api.LFSLockError{
|
repository.MustOwner()
|
||||||
Message: "unable to list lock : " + err.Error(),
|
|
||||||
|
authenticated := authenticate(ctx, repository, rv.Authorization, false)
|
||||||
|
if !authenticated {
|
||||||
|
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
||||||
|
ctx.JSON(401, api.LFSLockError{
|
||||||
|
Message: "You must have pull access to list locks",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -100,19 +105,19 @@ func GetListLockHandler(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
lock, err := models.GetLFSLockByID(int64(v))
|
lock, err := models.GetLFSLockByID(int64(v))
|
||||||
handleLockListOut(ctx, lock, err)
|
handleLockListOut(ctx, repository, lock, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path != "" { //Case where we request a specific id
|
if path != "" { //Case where we request a specific id
|
||||||
lock, err := models.GetLFSLock(ctx.Repo.Repository, path)
|
lock, err := models.GetLFSLock(repository, path)
|
||||||
handleLockListOut(ctx, lock, err)
|
handleLockListOut(ctx, repository, lock, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//If no query params path or id
|
//If no query params path or id
|
||||||
lockList, err := models.GetLFSLockByRepoID(ctx.Repo.Repository.ID)
|
lockList, err := models.GetLFSLockByRepoID(repository.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(500, api.LFSLockError{
|
ctx.JSON(500, api.LFSLockError{
|
||||||
Message: "unable to list locks : " + err.Error(),
|
Message: "unable to list locks : " + err.Error(),
|
||||||
@@ -135,16 +140,36 @@ func PostLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
||||||
|
|
||||||
|
userName := ctx.Params("username")
|
||||||
|
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
|
||||||
|
authorization := ctx.Req.Header.Get("Authorization")
|
||||||
|
|
||||||
|
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
|
||||||
|
writeStatus(ctx, 404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repository.MustOwner()
|
||||||
|
|
||||||
|
authenticated := authenticate(ctx, repository, authorization, true)
|
||||||
|
if !authenticated {
|
||||||
|
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
||||||
|
ctx.JSON(401, api.LFSLockError{
|
||||||
|
Message: "You must have push access to create locks",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var req api.LFSLockRequest
|
var req api.LFSLockRequest
|
||||||
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
||||||
err := dec.Decode(&req)
|
if err := dec.Decode(&req); err != nil {
|
||||||
if err != nil {
|
|
||||||
writeStatus(ctx, 400)
|
writeStatus(ctx, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := models.CreateLFSLock(&models.LFSLock{
|
lock, err := models.CreateLFSLock(&models.LFSLock{
|
||||||
Repo: ctx.Repo.Repository,
|
Repo: repository,
|
||||||
Path: req.Path,
|
Path: req.Path,
|
||||||
Owner: ctx.User,
|
Owner: ctx.User,
|
||||||
})
|
})
|
||||||
@@ -178,23 +203,29 @@ func VerifyLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
||||||
|
|
||||||
err := models.CheckLFSAccessForRepo(ctx.User, ctx.Repo.Repository, models.AccessModeWrite)
|
userName := ctx.Params("username")
|
||||||
|
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
|
||||||
|
authorization := ctx.Req.Header.Get("Authorization")
|
||||||
|
|
||||||
|
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrLFSUnauthorizedAction(err) {
|
log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
|
||||||
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
writeStatus(ctx, 404)
|
||||||
ctx.JSON(401, api.LFSLockError{
|
|
||||||
Message: "You must have push access to verify locks : " + err.Error(),
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.JSON(500, api.LFSLockError{
|
repository.MustOwner()
|
||||||
Message: "unable to verify lock : " + err.Error(),
|
|
||||||
|
authenticated := authenticate(ctx, repository, authorization, true)
|
||||||
|
if !authenticated {
|
||||||
|
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
||||||
|
ctx.JSON(401, api.LFSLockError{
|
||||||
|
Message: "You must have push access to verify locks",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO handle body json cursor and limit
|
//TODO handle body json cursor and limit
|
||||||
lockList, err := models.GetLFSLockByRepoID(ctx.Repo.Repository.ID)
|
lockList, err := models.GetLFSLockByRepoID(repository.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(500, api.LFSLockError{
|
ctx.JSON(500, api.LFSLockError{
|
||||||
Message: "unable to list locks : " + err.Error(),
|
Message: "unable to list locks : " + err.Error(),
|
||||||
@@ -223,10 +254,30 @@ func UnLockHandler(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
ctx.Resp.Header().Set("Content-Type", metaMediaType)
|
||||||
|
|
||||||
|
userName := ctx.Params("username")
|
||||||
|
repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
|
||||||
|
authorization := ctx.Req.Header.Get("Authorization")
|
||||||
|
|
||||||
|
repository, err := models.GetRepositoryByOwnerAndName(userName, repoName)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Could not find repository: %s/%s - %s", userName, repoName, err)
|
||||||
|
writeStatus(ctx, 404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
repository.MustOwner()
|
||||||
|
|
||||||
|
authenticated := authenticate(ctx, repository, authorization, true)
|
||||||
|
if !authenticated {
|
||||||
|
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
|
||||||
|
ctx.JSON(401, api.LFSLockError{
|
||||||
|
Message: "You must have push access to delete locks",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var req api.LFSLockDeleteRequest
|
var req api.LFSLockDeleteRequest
|
||||||
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
dec := json.NewDecoder(ctx.Req.Body().ReadCloser())
|
||||||
err := dec.Decode(&req)
|
if err := dec.Decode(&req); err != nil {
|
||||||
if err != nil {
|
|
||||||
writeStatus(ctx, 400)
|
writeStatus(ctx, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ import (
|
|||||||
func Init() {
|
func Init() {
|
||||||
getIssueFullPattern()
|
getIssueFullPattern()
|
||||||
NewSanitizer()
|
NewSanitizer()
|
||||||
|
|
||||||
|
// since setting maybe changed extensions, this will reload all parser extensions mapping
|
||||||
|
extParsers = make(map[string]Parser)
|
||||||
|
for _, parser := range parsers {
|
||||||
|
for _, ext := range parser.Extensions() {
|
||||||
|
extParsers[strings.ToLower(ext)] = parser
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parser defines an interface for parsering markup file to HTML
|
// Parser defines an interface for parsering markup file to HTML
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ var (
|
|||||||
MaxGitDiffLines int
|
MaxGitDiffLines int
|
||||||
MaxGitDiffLineCharacters int
|
MaxGitDiffLineCharacters int
|
||||||
MaxGitDiffFiles int
|
MaxGitDiffFiles int
|
||||||
GCArgs []string `delim:" "`
|
GCArgs []string `ini:"GC_ARGS" delim:" "`
|
||||||
Timeout struct {
|
Timeout struct {
|
||||||
Default int
|
Default int
|
||||||
Migrate int
|
Migrate int
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ sqlite_helper = File path for the SQLite3 database.<br>Enter an absolute path if
|
|||||||
err_empty_db_path = The SQLite3 database path cannot be empty.
|
err_empty_db_path = The SQLite3 database path cannot be empty.
|
||||||
no_admin_and_disable_registration = You cannot disable user self-registration without creating an administrator account.
|
no_admin_and_disable_registration = You cannot disable user self-registration without creating an administrator account.
|
||||||
err_empty_admin_password = The administrator password cannot be empty.
|
err_empty_admin_password = The administrator password cannot be empty.
|
||||||
|
err_empty_admin_email = The administrator email cannot be empty.
|
||||||
|
err_admin_name_is_reserved = Administrator Username is invalid, username is reserved
|
||||||
|
err_admin_name_pattern_not_allowed = Administrator Username is invalid, username is pattern is not allowed
|
||||||
|
err_admin_name_is_invalid = Administrator Username is invalid
|
||||||
|
|
||||||
general_title = General Settings
|
general_title = General Settings
|
||||||
app_name = Site Title
|
app_name = Site Title
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ func GetAllUsers(ctx *context.APIContext) {
|
|||||||
|
|
||||||
results := make([]*api.User, len(users))
|
results := make([]*api.User, len(users))
|
||||||
for i := range users {
|
for i := range users {
|
||||||
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
|
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, &results)
|
ctx.JSON(200, &results)
|
||||||
|
|||||||
@@ -55,6 +55,15 @@ func Search(ctx *context.APIContext) {
|
|||||||
// description: search only for repos that the user with the given id owns or contributes to
|
// description: search only for repos that the user with the given id owns or contributes to
|
||||||
// type: integer
|
// type: integer
|
||||||
// format: int64
|
// 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
|
// - name: page
|
||||||
// in: query
|
// in: query
|
||||||
// description: page number of results to return (1-based)
|
// description: page number of results to return (1-based)
|
||||||
@@ -95,6 +104,10 @@ func Search(ctx *context.APIContext) {
|
|||||||
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
|
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
|
||||||
TopicOnly: ctx.QueryBool("topic"),
|
TopicOnly: ctx.QueryBool("topic"),
|
||||||
Collaborate: util.OptionalBoolNone,
|
Collaborate: util.OptionalBoolNone,
|
||||||
|
Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")),
|
||||||
|
UserIsAdmin: ctx.IsSigned && ctx.User.IsAdmin,
|
||||||
|
UserID: ctx.Data["SignedUserID"].(int64),
|
||||||
|
StarredByID: ctx.QueryInt64("starredBy"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.QueryBool("exclusive") {
|
if ctx.QueryBool("exclusive") {
|
||||||
@@ -139,42 +152,6 @@ func Search(ctx *context.APIContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
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)
|
repos, count, err := models.SearchRepositoryByName(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(500, api.SearchError{
|
ctx.JSON(500, api.SearchError{
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func Search(ctx *context.APIContext) {
|
|||||||
|
|
||||||
results := make([]*api.User, len(users))
|
results := make([]*api.User, len(users))
|
||||||
for i := range users {
|
for i := range users {
|
||||||
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
|
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, map[string]interface{}{
|
ctx.JSON(200, map[string]interface{}{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/mailer"
|
"code.gitea.io/gitea/modules/mailer"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
|
"code.gitea.io/gitea/modules/markup/external"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/ssh"
|
"code.gitea.io/gitea/modules/ssh"
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ func GlobalInit() {
|
|||||||
|
|
||||||
if setting.InstallLock {
|
if setting.InstallLock {
|
||||||
highlight.NewContext()
|
highlight.NewContext()
|
||||||
|
external.RegisterParsers()
|
||||||
markup.Init()
|
markup.Init()
|
||||||
if err := initDBEngine(); err == nil {
|
if err := initDBEngine(); err == nil {
|
||||||
log.Info("ORM engine initialization successful!")
|
log.Info("ORM engine initialization successful!")
|
||||||
|
|||||||
@@ -213,8 +213,31 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check admin user creation
|
||||||
|
if len(form.AdminName) > 0 {
|
||||||
|
// Ensure AdminName is valid
|
||||||
|
if err := models.IsUsableUsername(form.AdminName); err != nil {
|
||||||
|
ctx.Data["Err_Admin"] = true
|
||||||
|
ctx.Data["Err_AdminName"] = true
|
||||||
|
if models.IsErrNameReserved(err) {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_reserved"), tplInstall, form)
|
||||||
|
return
|
||||||
|
} else if models.IsErrNamePatternNotAllowed(err) {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("install.err_admin_name_pattern_not_allowed"), tplInstall, form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.RenderWithErr(ctx.Tr("install.err_admin_name_is_invalid"), tplInstall, form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Check Admin email
|
||||||
|
if len(form.AdminEmail) == 0 {
|
||||||
|
ctx.Data["Err_Admin"] = true
|
||||||
|
ctx.Data["Err_AdminEmail"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_email"), tplInstall, form)
|
||||||
|
return
|
||||||
|
}
|
||||||
// Check admin password.
|
// Check admin password.
|
||||||
if len(form.AdminName) > 0 && len(form.AdminPasswd) == 0 {
|
if len(form.AdminPasswd) == 0 {
|
||||||
ctx.Data["Err_Admin"] = true
|
ctx.Data["Err_Admin"] = true
|
||||||
ctx.Data["Err_AdminPasswd"] = true
|
ctx.Data["Err_AdminPasswd"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
|
ctx.RenderWithErr(ctx.Tr("install.err_empty_admin_password"), tplInstall, form)
|
||||||
@@ -226,6 +249,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
|
|||||||
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
|
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplInstall, form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if form.AppURL[len(form.AppURL)-1] != '/' {
|
if form.AppURL[len(form.AppURL)-1] != '/' {
|
||||||
form.AppURL += "/"
|
form.AppURL += "/"
|
||||||
|
|||||||
@@ -406,6 +406,7 @@ func NewIssue(ctx *context.Context) {
|
|||||||
ctx.Data["BodyQuery"] = body
|
ctx.Data["BodyQuery"] = body
|
||||||
|
|
||||||
milestoneID := ctx.QueryInt64("milestone")
|
milestoneID := ctx.QueryInt64("milestone")
|
||||||
|
if milestoneID > 0 {
|
||||||
milestone, err := models.GetMilestoneByID(milestoneID)
|
milestone, err := models.GetMilestoneByID(milestoneID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(4, "GetMilestoneByID: %d: %v", milestoneID, err)
|
log.Error(4, "GetMilestoneByID: %d: %v", milestoneID, err)
|
||||||
@@ -413,6 +414,7 @@ func NewIssue(ctx *context.Context) {
|
|||||||
ctx.Data["milestone_id"] = milestoneID
|
ctx.Data["milestone_id"] = milestoneID
|
||||||
ctx.Data["Milestone"] = milestone
|
ctx.Data["Milestone"] = milestone
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
|
setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates)
|
||||||
renderAttachmentSettings(ctx)
|
renderAttachmentSettings(ctx)
|
||||||
|
|||||||
@@ -578,7 +578,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
})
|
})
|
||||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef())
|
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.UnitTypes(), context.RepoRef())
|
||||||
|
|
||||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), context.RepoMustNotBeArchived(), repo.Action)
|
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
|
||||||
|
|
||||||
m.Group("/:username/:reponame", func() {
|
m.Group("/:username/:reponame", func() {
|
||||||
m.Group("/issues", func() {
|
m.Group("/issues", func() {
|
||||||
@@ -827,7 +827,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Post("/", lfs.PostLockHandler)
|
m.Post("/", lfs.PostLockHandler)
|
||||||
m.Post("/verify", lfs.VerifyLockHandler)
|
m.Post("/verify", lfs.VerifyLockHandler)
|
||||||
m.Post("/:lid/unlock", lfs.UnLockHandler)
|
m.Post("/:lid/unlock", lfs.UnLockHandler)
|
||||||
}, context.RepoAssignment())
|
})
|
||||||
m.Any("/*", func(ctx *context.Context) {
|
m.Any("/*", func(ctx *context.Context) {
|
||||||
ctx.NotFound("", nil)
|
ctx.NotFound("", nil)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -435,41 +435,13 @@ func showOrgProfile(ctx *context.Context) {
|
|||||||
count int64
|
count int64
|
||||||
err error
|
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{
|
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
OwnerID: org.ID,
|
OwnerID: org.ID,
|
||||||
OrderBy: orderBy,
|
OrderBy: orderBy,
|
||||||
Private: showPrivate,
|
Private: ctx.IsSigned,
|
||||||
|
UserIsAdmin: ctx.IsSigned && ctx.User.IsAdmin,
|
||||||
|
UserID: ctx.Data["SignedUserID"].(int64),
|
||||||
Page: page,
|
Page: page,
|
||||||
IsProfile: true,
|
IsProfile: true,
|
||||||
PageSize: setting.UI.User.RepoPagingNum,
|
PageSize: setting.UI.User.RepoPagingNum,
|
||||||
@@ -478,8 +450,6 @@ func showOrgProfile(ctx *context.Context) {
|
|||||||
ctx.ServerError("SearchRepositoryByName", err)
|
ctx.ServerError("SearchRepositoryByName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := org.GetMembers(); err != nil {
|
if err := org.GetMembers(); err != nil {
|
||||||
ctx.ServerError("GetMembers", err)
|
ctx.ServerError("GetMembers", err)
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ func AuthorizeOAuth(ctx *context.Context, form auth.AuthorizationForm) {
|
|||||||
ctx.Data["Application"] = app
|
ctx.Data["Application"] = app
|
||||||
ctx.Data["RedirectURI"] = form.RedirectURI
|
ctx.Data["RedirectURI"] = form.RedirectURI
|
||||||
ctx.Data["State"] = form.State
|
ctx.Data["State"] = form.State
|
||||||
ctx.Data["ApplicationUserLink"] = "<a href=\"" + setting.LocalURL + app.User.LowerName + "\">@" + app.User.Name + "</a>"
|
ctx.Data["ApplicationUserLink"] = "<a href=\"" + setting.AppURL + app.User.LowerName + "\">@" + app.User.Name + "</a>"
|
||||||
ctx.Data["ApplicationRedirectDomainHTML"] = "<strong>" + form.RedirectURI + "</strong>"
|
ctx.Data["ApplicationRedirectDomainHTML"] = "<strong>" + form.RedirectURI + "</strong>"
|
||||||
// TODO document SESSION <=> FORM
|
// TODO document SESSION <=> FORM
|
||||||
ctx.Session.Set("client_id", app.ClientID)
|
ctx.Session.Set("client_id", app.ClientID)
|
||||||
|
|||||||
@@ -158,27 +158,15 @@ func Profile(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
case "stars":
|
case "stars":
|
||||||
ctx.Data["PageIsProfileStarList"] = true
|
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{
|
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
OwnerID: ctxUser.ID,
|
|
||||||
OrderBy: orderBy,
|
OrderBy: orderBy,
|
||||||
Private: showPrivate,
|
Private: ctx.IsSigned,
|
||||||
|
UserIsAdmin: ctx.IsSigned && ctx.User.IsAdmin,
|
||||||
|
UserID: ctx.Data["SignedUserID"].(int64),
|
||||||
Page: page,
|
Page: page,
|
||||||
PageSize: setting.UI.User.RepoPagingNum,
|
PageSize: setting.UI.User.RepoPagingNum,
|
||||||
Starred: true,
|
StarredByID: ctxUser.ID,
|
||||||
Collaborate: util.OptionalBoolFalse,
|
Collaborate: util.OptionalBoolFalse,
|
||||||
TopicOnly: topicOnly,
|
TopicOnly: topicOnly,
|
||||||
})
|
})
|
||||||
@@ -186,40 +174,18 @@ func Profile(ctx *context.Context) {
|
|||||||
ctx.ServerError("SearchRepositoryByName", err)
|
ctx.ServerError("SearchRepositoryByName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Data["Repos"] = repos
|
ctx.Data["Repos"] = repos
|
||||||
ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||||
ctx.Data["Total"] = count
|
ctx.Data["Total"] = count
|
||||||
default:
|
default:
|
||||||
if len(keyword) == 0 {
|
|
||||||
var total int
|
|
||||||
repos, err = models.GetUserRepositories(ctxUser.ID, showPrivate, page, setting.UI.User.RepoPagingNum, orderBy.String())
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetRepositories", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Repos"] = repos
|
|
||||||
|
|
||||||
if showPrivate {
|
|
||||||
total = ctxUser.NumRepos
|
|
||||||
} else {
|
|
||||||
count, err := models.GetPublicRepositoryCount(ctxUser)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetPublicRepositoryCount", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
total = int(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Data["Page"] = paginater.New(total, setting.UI.User.RepoPagingNum, page, 5)
|
|
||||||
ctx.Data["Total"] = total
|
|
||||||
} else {
|
|
||||||
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
OwnerID: ctxUser.ID,
|
OwnerID: ctxUser.ID,
|
||||||
OrderBy: orderBy,
|
OrderBy: orderBy,
|
||||||
Private: showPrivate,
|
Private: ctx.IsSigned,
|
||||||
|
UserIsAdmin: ctx.IsSigned && ctx.User.IsAdmin,
|
||||||
|
UserID: ctx.Data["SignedUserID"].(int64),
|
||||||
Page: page,
|
Page: page,
|
||||||
IsProfile: true,
|
IsProfile: true,
|
||||||
PageSize: setting.UI.User.RepoPagingNum,
|
PageSize: setting.UI.User.RepoPagingNum,
|
||||||
@@ -230,12 +196,10 @@ func Profile(ctx *context.Context) {
|
|||||||
ctx.ServerError("SearchRepositoryByName", err)
|
ctx.ServerError("SearchRepositoryByName", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Repos"] = repos
|
ctx.Data["Repos"] = repos
|
||||||
ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
ctx.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||||
ctx.Data["Total"] = count
|
ctx.Data["Total"] = count
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
|
ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.User.ID)
|
||||||
|
|
||||||
|
|||||||
@@ -1085,6 +1085,19 @@
|
|||||||
"name": "uid",
|
"name": "uid",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"description": "search only for repos that the user with the given id has starred",
|
||||||
|
"name": "starredBy",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "include private repositories this user has access to (defaults to true)",
|
||||||
|
"name": "private",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "page number of results to return (1-based)",
|
"description": "page number of results to return (1-based)",
|
||||||
|
|||||||
Reference in New Issue
Block a user