mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 10:56:10 +01:00 
			
		
		
		
	Move some files into models' sub packages (#20262)
* Move some files into models' sub packages * Move functions * merge main branch * Fix check * fix check * Fix some tests * Fix lint * Fix lint * Revert lint changes * Fix error comments * Fix lint Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		
							
								
								
									
										35
									
								
								cmd/admin.go
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								cmd/admin.go
									
									
									
									
									
								
							| @@ -13,9 +13,8 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"text/tabwriter" | 	"text/tabwriter" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| 	"code.gitea.io/gitea/models/auth" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -593,12 +592,12 @@ func runCreateUser(c *cli.Context) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if c.Bool("access-token") { | 	if c.Bool("access-token") { | ||||||
| 		t := &models.AccessToken{ | 		t := &auth_model.AccessToken{ | ||||||
| 			Name: "gitea-admin", | 			Name: "gitea-admin", | ||||||
| 			UID:  u.ID, | 			UID:  u.ID, | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if err := models.NewAccessToken(t); err != nil { | 		if err := auth_model.NewAccessToken(t); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -700,12 +699,12 @@ func runGenerateAccessToken(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	t := &models.AccessToken{ | 	t := &auth_model.AccessToken{ | ||||||
| 		Name: c.String("token-name"), | 		Name: c.String("token-name"), | ||||||
| 		UID:  user.ID, | 		UID:  user.ID, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NewAccessToken(t); err != nil { | 	if err := auth_model.NewAccessToken(t); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -779,9 +778,9 @@ func runRepoSyncReleases(_ *cli.Context) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func getReleaseCount(id int64) (int64, error) { | func getReleaseCount(id int64) (int64, error) { | ||||||
| 	return models.GetReleaseCountByRepoID( | 	return repo_model.GetReleaseCountByRepoID( | ||||||
| 		id, | 		id, | ||||||
| 		models.FindReleasesOptions{ | 		repo_model.FindReleasesOptions{ | ||||||
| 			IncludeTags: true, | 			IncludeTags: true, | ||||||
| 		}, | 		}, | ||||||
| 	) | 	) | ||||||
| @@ -844,8 +843,8 @@ func runAddOauth(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return auth.CreateSource(&auth.Source{ | 	return auth_model.CreateSource(&auth_model.Source{ | ||||||
| 		Type:     auth.OAuth2, | 		Type:     auth_model.OAuth2, | ||||||
| 		Name:     c.String("name"), | 		Name:     c.String("name"), | ||||||
| 		IsActive: true, | 		IsActive: true, | ||||||
| 		Cfg:      parseOAuth2Config(c), | 		Cfg:      parseOAuth2Config(c), | ||||||
| @@ -864,7 +863,7 @@ func runUpdateOauth(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	source, err := auth.GetSourceByID(c.Int64("id")) | 	source, err := auth_model.GetSourceByID(c.Int64("id")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -944,7 +943,7 @@ func runUpdateOauth(c *cli.Context) error { | |||||||
| 	oAuth2Config.CustomURLMapping = customURLMapping | 	oAuth2Config.CustomURLMapping = customURLMapping | ||||||
| 	source.Cfg = oAuth2Config | 	source.Cfg = oAuth2Config | ||||||
|  |  | ||||||
| 	return auth.UpdateSource(source) | 	return auth_model.UpdateSource(source) | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error { | func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error { | ||||||
| @@ -1015,8 +1014,8 @@ func runAddSMTP(c *cli.Context) error { | |||||||
| 		smtpConfig.Auth = "PLAIN" | 		smtpConfig.Auth = "PLAIN" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return auth.CreateSource(&auth.Source{ | 	return auth_model.CreateSource(&auth_model.Source{ | ||||||
| 		Type:     auth.SMTP, | 		Type:     auth_model.SMTP, | ||||||
| 		Name:     c.String("name"), | 		Name:     c.String("name"), | ||||||
| 		IsActive: active, | 		IsActive: active, | ||||||
| 		Cfg:      &smtpConfig, | 		Cfg:      &smtpConfig, | ||||||
| @@ -1035,7 +1034,7 @@ func runUpdateSMTP(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	source, err := auth.GetSourceByID(c.Int64("id")) | 	source, err := auth_model.GetSourceByID(c.Int64("id")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -1056,7 +1055,7 @@ func runUpdateSMTP(c *cli.Context) error { | |||||||
|  |  | ||||||
| 	source.Cfg = smtpConfig | 	source.Cfg = smtpConfig | ||||||
|  |  | ||||||
| 	return auth.UpdateSource(source) | 	return auth_model.UpdateSource(source) | ||||||
| } | } | ||||||
|  |  | ||||||
| func runListAuth(c *cli.Context) error { | func runListAuth(c *cli.Context) error { | ||||||
| @@ -1067,7 +1066,7 @@ func runListAuth(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	authSources, err := auth.Sources() | 	authSources, err := auth_model.Sources() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -1105,7 +1104,7 @@ func runDeleteAuth(c *cli.Context) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	source, err := auth.GetSourceByID(c.Int64("id")) | 	source, err := auth_model.GetSourceByID(c.Int64("id")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -23,7 +23,7 @@ func TestAPINotification(t *testing.T) { | |||||||
|  |  | ||||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||||
| 	thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) | 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5}) | ||||||
| 	assert.NoError(t, thread5.LoadAttributes()) | 	assert.NoError(t, thread5.LoadAttributes()) | ||||||
| 	session := loginUser(t, user2.Name) | 	session := loginUser(t, user2.Name) | ||||||
| 	token := getTokenForLoggedInUser(t, session) | 	token := getTokenForLoggedInUser(t, session) | ||||||
| @@ -126,9 +126,9 @@ func TestAPINotification(t *testing.T) { | |||||||
| 	req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) | 	req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) | ||||||
| 	session.MakeRequest(t, req, http.StatusResetContent) | 	session.MakeRequest(t, req, http.StatusResetContent) | ||||||
|  |  | ||||||
| 	assert.Equal(t, models.NotificationStatusUnread, thread5.Status) | 	assert.Equal(t, activities_model.NotificationStatusUnread, thread5.Status) | ||||||
| 	thread5 = unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) | 	thread5 = unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5}) | ||||||
| 	assert.Equal(t, models.NotificationStatusRead, thread5.Status) | 	assert.Equal(t, activities_model.NotificationStatusRead, thread5.Status) | ||||||
|  |  | ||||||
| 	// -- check notifications -- | 	// -- check notifications -- | ||||||
| 	req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token)) | 	req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token)) | ||||||
| @@ -141,7 +141,7 @@ func TestAPINotificationPUT(t *testing.T) { | |||||||
| 	defer prepareTestEnv(t)() | 	defer prepareTestEnv(t)() | ||||||
|  |  | ||||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) | 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5}) | ||||||
| 	assert.NoError(t, thread5.LoadAttributes()) | 	assert.NoError(t, thread5.LoadAttributes()) | ||||||
| 	session := loginUser(t, user2.Name) | 	session := loginUser(t, user2.Name) | ||||||
| 	token := getTokenForLoggedInUser(t, session) | 	token := getTokenForLoggedInUser(t, session) | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -84,7 +83,7 @@ func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, | |||||||
|  |  | ||||||
| 	var newRelease api.Release | 	var newRelease api.Release | ||||||
| 	DecodeJSON(t, resp, &newRelease) | 	DecodeJSON(t, resp, &newRelease) | ||||||
| 	rel := &models.Release{ | 	rel := &repo_model.Release{ | ||||||
| 		ID:      newRelease.ID, | 		ID:      newRelease.ID, | ||||||
| 		TagName: newRelease.TagName, | 		TagName: newRelease.TagName, | ||||||
| 		Title:   newRelease.Title, | 		Title:   newRelease.Title, | ||||||
| @@ -138,7 +137,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { | |||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
|  |  | ||||||
| 	DecodeJSON(t, resp, &newRelease) | 	DecodeJSON(t, resp, &newRelease) | ||||||
| 	rel := &models.Release{ | 	rel := &repo_model.Release{ | ||||||
| 		ID:      newRelease.ID, | 		ID:      newRelease.ID, | ||||||
| 		TagName: newRelease.TagName, | 		TagName: newRelease.TagName, | ||||||
| 		Title:   newRelease.Title, | 		Title:   newRelease.Title, | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| @@ -27,7 +27,7 @@ func TestAPICreateAndDeleteToken(t *testing.T) { | |||||||
|  |  | ||||||
| 	var newAccessToken api.AccessToken | 	var newAccessToken api.AccessToken | ||||||
| 	DecodeJSON(t, resp, &newAccessToken) | 	DecodeJSON(t, resp, &newAccessToken) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &models.AccessToken{ | 	unittest.AssertExistsAndLoadBean(t, &auth_model.AccessToken{ | ||||||
| 		ID:    newAccessToken.ID, | 		ID:    newAccessToken.ID, | ||||||
| 		Name:  newAccessToken.Name, | 		Name:  newAccessToken.Name, | ||||||
| 		Token: newAccessToken.Token, | 		Token: newAccessToken.Token, | ||||||
| @@ -38,7 +38,7 @@ func TestAPICreateAndDeleteToken(t *testing.T) { | |||||||
| 	req = AddBasicAuthHeader(req, user.Name) | 	req = AddBasicAuthHeader(req, user.Name) | ||||||
| 	MakeRequest(t, req, http.StatusNoContent) | 	MakeRequest(t, req, http.StatusNoContent) | ||||||
|  |  | ||||||
| 	unittest.AssertNotExistsBean(t, &models.AccessToken{ID: newAccessToken.ID}) | 	unittest.AssertNotExistsBean(t, &auth_model.AccessToken{ID: newAccessToken.ID}) | ||||||
|  |  | ||||||
| 	req = NewRequestWithJSON(t, "POST", "/api/v1/users/user1/tokens", map[string]string{ | 	req = NewRequestWithJSON(t, "POST", "/api/v1/users/user1/tokens", map[string]string{ | ||||||
| 		"name": "test-key-2", | 		"name": "test-key-2", | ||||||
| @@ -51,7 +51,7 @@ func TestAPICreateAndDeleteToken(t *testing.T) { | |||||||
| 	req = AddBasicAuthHeader(req, user.Name) | 	req = AddBasicAuthHeader(req, user.Name) | ||||||
| 	MakeRequest(t, req, http.StatusNoContent) | 	MakeRequest(t, req, http.StatusNoContent) | ||||||
|  |  | ||||||
| 	unittest.AssertNotExistsBean(t, &models.AccessToken{ID: newAccessToken.ID}) | 	unittest.AssertNotExistsBean(t, &auth_model.AccessToken{ID: newAccessToken.ID}) | ||||||
| } | } | ||||||
|  |  | ||||||
| // TestAPIDeleteMissingToken ensures that error is thrown when token not found | // TestAPIDeleteMissingToken ensures that error is thrown when token not found | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -29,10 +29,10 @@ func TestUserHeatmap(t *testing.T) { | |||||||
| 	urlStr := fmt.Sprintf("/api/v1/users/%s/heatmap?token=%s", normalUsername, token) | 	urlStr := fmt.Sprintf("/api/v1/users/%s/heatmap?token=%s", normalUsername, token) | ||||||
| 	req := NewRequest(t, "GET", urlStr) | 	req := NewRequest(t, "GET", urlStr) | ||||||
| 	resp := MakeRequest(t, req, http.StatusOK) | 	resp := MakeRequest(t, req, http.StatusOK) | ||||||
| 	var heatmap []*models.UserHeatmapData | 	var heatmap []*activities_model.UserHeatmapData | ||||||
| 	DecodeJSON(t, resp, &heatmap) | 	DecodeJSON(t, resp, &heatmap) | ||||||
| 	var dummyheatmap []*models.UserHeatmapData | 	var dummyheatmap []*activities_model.UserHeatmapData | ||||||
| 	dummyheatmap = append(dummyheatmap, &models.UserHeatmapData{Timestamp: 1603227600, Contributions: 1}) | 	dummyheatmap = append(dummyheatmap, &activities_model.UserHeatmapData{Timestamp: 1603227600, Contributions: 1}) | ||||||
|  |  | ||||||
| 	assert.Equal(t, dummyheatmap, heatmap) | 	assert.Equal(t, dummyheatmap, heatmap) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -42,7 +42,7 @@ func TestEventSourceManagerRun(t *testing.T) { | |||||||
| 				if !ok { | 				if !ok { | ||||||
| 					return false | 					return false | ||||||
| 				} | 				} | ||||||
| 				data, ok := event.Data.(models.UserIDCount) | 				data, ok := event.Data.(activities_model.UserIDCount) | ||||||
| 				if !ok { | 				if !ok { | ||||||
| 					return false | 					return false | ||||||
| 				} | 				} | ||||||
| @@ -55,7 +55,7 @@ func TestEventSourceManagerRun(t *testing.T) { | |||||||
|  |  | ||||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||||
| 	thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}) | 	thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5}) | ||||||
| 	assert.NoError(t, thread5.LoadAttributes()) | 	assert.NoError(t, thread5.LoadAttributes()) | ||||||
| 	session := loginUser(t, user2.Name) | 	session := loginUser(t, user2.Name) | ||||||
| 	token := getTokenForLoggedInUser(t, session) | 	token := getTokenForLoggedInUser(t, session) | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -38,7 +37,7 @@ func TestMirrorPull(t *testing.T) { | |||||||
| 		Releases:    false, | 		Releases:    false, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mirrorRepo, err := repository.CreateRepository(user, user, models.CreateRepoOptions{ | 	mirrorRepo, err := repository.CreateRepository(user, user, repository.CreateRepoOptions{ | ||||||
| 		Name:        opts.RepoName, | 		Name:        opts.RepoName, | ||||||
| 		Description: opts.Description, | 		Description: opts.Description, | ||||||
| 		IsPrivate:   opts.Private, | 		IsPrivate:   opts.Private, | ||||||
| @@ -57,11 +56,11 @@ func TestMirrorPull(t *testing.T) { | |||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	defer gitRepo.Close() | 	defer gitRepo.Close() | ||||||
|  |  | ||||||
| 	findOptions := models.FindReleasesOptions{IncludeDrafts: true, IncludeTags: true} | 	findOptions := repo_model.FindReleasesOptions{IncludeDrafts: true, IncludeTags: true} | ||||||
| 	initCount, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions) | 	initCount, err := repo_model.GetReleaseCountByRepoID(mirror.ID, findOptions) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	assert.NoError(t, release_service.CreateRelease(gitRepo, &models.Release{ | 	assert.NoError(t, release_service.CreateRelease(gitRepo, &repo_model.Release{ | ||||||
| 		RepoID:       repo.ID, | 		RepoID:       repo.ID, | ||||||
| 		Repo:         repo, | 		Repo:         repo, | ||||||
| 		PublisherID:  user.ID, | 		PublisherID:  user.ID, | ||||||
| @@ -81,18 +80,18 @@ func TestMirrorPull(t *testing.T) { | |||||||
| 	ok := mirror_service.SyncPullMirror(ctx, mirror.ID) | 	ok := mirror_service.SyncPullMirror(ctx, mirror.ID) | ||||||
| 	assert.True(t, ok) | 	assert.True(t, ok) | ||||||
|  |  | ||||||
| 	count, err := models.GetReleaseCountByRepoID(mirror.ID, findOptions) | 	count, err := repo_model.GetReleaseCountByRepoID(mirror.ID, findOptions) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, initCount+1, count) | 	assert.EqualValues(t, initCount+1, count) | ||||||
|  |  | ||||||
| 	release, err := models.GetRelease(repo.ID, "v0.2") | 	release, err := repo_model.GetRelease(repo.ID, "v0.2") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, release_service.DeleteReleaseByID(ctx, release.ID, user, true)) | 	assert.NoError(t, release_service.DeleteReleaseByID(ctx, release.ID, user, true)) | ||||||
|  |  | ||||||
| 	ok = mirror_service.SyncPullMirror(ctx, mirror.ID) | 	ok = mirror_service.SyncPullMirror(ctx, mirror.ID) | ||||||
| 	assert.True(t, ok) | 	assert.True(t, ok) | ||||||
|  |  | ||||||
| 	count, err = models.GetReleaseCountByRepoID(mirror.ID, findOptions) | 	count, err = repo_model.GetReleaseCountByRepoID(mirror.ID, findOptions) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, initCount, count) | 	assert.EqualValues(t, initCount, count) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,7 +12,6 @@ import ( | |||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -39,7 +38,7 @@ func testMirrorPush(t *testing.T, u *url.URL) { | |||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | 	srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||||
|  |  | ||||||
| 	mirrorRepo, err := repository.CreateRepository(user, user, models.CreateRepoOptions{ | 	mirrorRepo, err := repository.CreateRepository(user, user, repository.CreateRepoOptions{ | ||||||
| 		Name: "test-push-mirror", | 		Name: "test-push-mirror", | ||||||
| 	}) | 	}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -117,7 +117,7 @@ func testPrivateActivityHelperHasHeatmapContentFromPublic(t *testing.T) bool { | |||||||
| 	req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap", privateActivityTestUser) | 	req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap", privateActivityTestUser) | ||||||
| 	resp := MakeRequest(t, req, http.StatusOK) | 	resp := MakeRequest(t, req, http.StatusOK) | ||||||
|  |  | ||||||
| 	var items []*models.UserHeatmapData | 	var items []*activities_model.UserHeatmapData | ||||||
| 	DecodeJSON(t, resp, &items) | 	DecodeJSON(t, resp, &items) | ||||||
|  |  | ||||||
| 	return len(items) != 0 | 	return len(items) != 0 | ||||||
| @@ -129,7 +129,7 @@ func testPrivateActivityHelperHasHeatmapContentFromSession(t *testing.T, session | |||||||
| 	req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap?token=%s", privateActivityTestUser, token) | 	req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap?token=%s", privateActivityTestUser, token) | ||||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||||
|  |  | ||||||
| 	var items []*models.UserHeatmapData | 	var items []*activities_model.UserHeatmapData | ||||||
| 	DecodeJSON(t, resp, &items) | 	DecodeJSON(t, resp, &items) | ||||||
|  |  | ||||||
| 	return len(items) != 0 | 	return len(items) != 0 | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import ( | |||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/models/webhook" | 	"code.gitea.io/gitea/models/webhook" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
|  | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/test" | 	"code.gitea.io/gitea/modules/test" | ||||||
| 	"code.gitea.io/gitea/modules/translation" | 	"code.gitea.io/gitea/modules/translation" | ||||||
| @@ -355,7 +356,7 @@ func TestConflictChecking(t *testing.T) { | |||||||
| 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  |  | ||||||
| 		// Create new clean repo to test conflict checking. | 		// Create new clean repo to test conflict checking. | ||||||
| 		baseRepo, err := repo_service.CreateRepository(user, user, models.CreateRepoOptions{ | 		baseRepo, err := repo_service.CreateRepository(user, user, repo_module.CreateRepoOptions{ | ||||||
| 			Name:          "conflict-checking", | 			Name:          "conflict-checking", | ||||||
| 			Description:   "Tempo repo", | 			Description:   "Tempo repo", | ||||||
| 			AutoInit:      true, | 			AutoInit:      true, | ||||||
|   | |||||||
| @@ -10,12 +10,12 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
|  | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
| 	pull_service "code.gitea.io/gitea/services/pull" | 	pull_service "code.gitea.io/gitea/services/pull" | ||||||
| 	repo_service "code.gitea.io/gitea/services/repository" | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
| 	files_service "code.gitea.io/gitea/services/repository/files" | 	files_service "code.gitea.io/gitea/services/repository/files" | ||||||
| @@ -80,7 +80,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { | func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { | ||||||
| 	baseRepo, err := repo_service.CreateRepository(actor, actor, models.CreateRepoOptions{ | 	baseRepo, err := repo_service.CreateRepository(actor, actor, repo_module.CreateRepoOptions{ | ||||||
| 		Name:        "repo-pr-update", | 		Name:        "repo-pr-update", | ||||||
| 		Description: "repo-tmp-pr-update description", | 		Description: "repo-tmp-pr-update description", | ||||||
| 		AutoInit:    true, | 		AutoInit:    true, | ||||||
|   | |||||||
| @@ -77,14 +77,14 @@ func TestCreateNewTagProtected(t *testing.T) { | |||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	// Cleanup | 	// Cleanup | ||||||
| 	releases, err := models.GetReleasesByRepoID(repo.ID, models.FindReleasesOptions{ | 	releases, err := repo_model.GetReleasesByRepoID(repo.ID, repo_model.FindReleasesOptions{ | ||||||
| 		IncludeTags: true, | 		IncludeTags: true, | ||||||
| 		TagNames:    []string{"v-1", "v-1.1"}, | 		TagNames:    []string{"v-1", "v-1.1"}, | ||||||
| 	}) | 	}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	for _, release := range releases { | 	for _, release := range releases { | ||||||
| 		err = models.DeleteReleaseByID(release.ID) | 		err = repo_model.DeleteReleaseByID(release.ID) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -211,21 +211,6 @@ func (a *Action) GetRepoLink() string { | |||||||
| 	return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName())) | 	return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName())) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetRepositoryFromMatch returns a *repo_model.Repository from a username and repo strings |  | ||||||
| func GetRepositoryFromMatch(ownerName, repoName string) (*repo_model.Repository, error) { |  | ||||||
| 	var err error |  | ||||||
| 	refRepo, err := repo_model.GetRepositoryByOwnerAndName(ownerName, repoName) |  | ||||||
| 	if err != nil { |  | ||||||
| 		if repo_model.IsErrRepoNotExist(err) { |  | ||||||
| 			log.Warn("Repository referenced in commit but does not exist: %v", err) |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 		log.Error("repo_model.GetRepositoryByOwnerAndName: %v", err) |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return refRepo, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetCommentLink returns link to action comment. | // GetCommentLink returns link to action comment. | ||||||
| func (a *Action) GetCommentLink() string { | func (a *Action) GetCommentLink() string { | ||||||
| 	return a.getCommentLink(db.DefaultContext) | 	return a.getCommentLink(db.DefaultContext) | ||||||
| @@ -372,7 +357,8 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, error) { | |||||||
| 	return actions, nil | 	return actions, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func activityReadable(user, doer *user_model.User) bool { | // ActivityReadable return whether doer can read activities of user | ||||||
|  | func ActivityReadable(user, doer *user_model.User) bool { | ||||||
| 	return !user.KeepActivityPrivate || | 	return !user.KeepActivityPrivate || | ||||||
| 		doer != nil && (doer.IsAdmin || user.ID == doer.ID) | 		doer != nil && (doer.IsAdmin || user.ID == doer.ID) | ||||||
| } | } | ||||||
| @@ -602,3 +588,23 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error { | |||||||
| 		Delete(&Action{}) | 		Delete(&Action{}) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // CountActionCreatedUnixString count actions where created_unix is an empty string | ||||||
|  | func CountActionCreatedUnixString() (int64, error) { | ||||||
|  | 	if setting.Database.UseSQLite3 { | ||||||
|  | 		return db.GetEngine(db.DefaultContext).Where(`created_unix = ""`).Count(new(Action)) | ||||||
|  | 	} | ||||||
|  | 	return 0, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FixActionCreatedUnixString set created_unix to zero if it is an empty string | ||||||
|  | func FixActionCreatedUnixString() (int64, error) { | ||||||
|  | 	if setting.Database.UseSQLite3 { | ||||||
|  | 		res, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0, err | ||||||
|  | 		} | ||||||
|  | 		return res.RowsAffected() | ||||||
|  | 	} | ||||||
|  | 	return 0, nil | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -2,12 +2,13 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"path" | 	"path" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -21,7 +22,7 @@ func TestAction_GetRepoPath(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||||
| 	action := &Action{RepoID: repo.ID} | 	action := &activities_model.Action{RepoID: repo.ID} | ||||||
| 	assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath()) | 	assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -29,7 +30,7 @@ func TestAction_GetRepoLink(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}) | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||||
| 	action := &Action{RepoID: repo.ID} | 	action := &activities_model.Action{RepoID: repo.ID} | ||||||
| 	setting.AppSubURL = "/suburl" | 	setting.AppSubURL = "/suburl" | ||||||
| 	expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) | 	expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) | ||||||
| 	assert.Equal(t, expected, action.GetRepoLink()) | 	assert.Equal(t, expected, action.GetRepoLink()) | ||||||
| @@ -40,7 +41,7 @@ func TestGetFeeds(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 
 | 
 | ||||||
| 	actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedUser:   user, | 		RequestedUser:   user, | ||||||
| 		Actor:           user, | 		Actor:           user, | ||||||
| 		IncludePrivate:  true, | 		IncludePrivate:  true, | ||||||
| @@ -53,7 +54,7 @@ func TestGetFeeds(t *testing.T) { | |||||||
| 		assert.EqualValues(t, user.ID, actions[0].UserID) | 		assert.EqualValues(t, user.ID, actions[0].UserID) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedUser:   user, | 		RequestedUser:   user, | ||||||
| 		Actor:           user, | 		Actor:           user, | ||||||
| 		IncludePrivate:  false, | 		IncludePrivate:  false, | ||||||
| @@ -70,7 +71,7 @@ func TestGetFeedsForRepos(t *testing.T) { | |||||||
| 	pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) | 	pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}) | ||||||
| 
 | 
 | ||||||
| 	// private repo & no login | 	// private repo & no login | ||||||
| 	actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedRepo:  privRepo, | 		RequestedRepo:  privRepo, | ||||||
| 		IncludePrivate: true, | 		IncludePrivate: true, | ||||||
| 	}) | 	}) | ||||||
| @@ -78,7 +79,7 @@ func TestGetFeedsForRepos(t *testing.T) { | |||||||
| 	assert.Len(t, actions, 0) | 	assert.Len(t, actions, 0) | ||||||
| 
 | 
 | ||||||
| 	// public repo & no login | 	// public repo & no login | ||||||
| 	actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedRepo:  pubRepo, | 		RequestedRepo:  pubRepo, | ||||||
| 		IncludePrivate: true, | 		IncludePrivate: true, | ||||||
| 	}) | 	}) | ||||||
| @@ -86,7 +87,7 @@ func TestGetFeedsForRepos(t *testing.T) { | |||||||
| 	assert.Len(t, actions, 1) | 	assert.Len(t, actions, 1) | ||||||
| 
 | 
 | ||||||
| 	// private repo and login | 	// private repo and login | ||||||
| 	actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedRepo:  privRepo, | 		RequestedRepo:  privRepo, | ||||||
| 		IncludePrivate: true, | 		IncludePrivate: true, | ||||||
| 		Actor:          user, | 		Actor:          user, | ||||||
| @@ -95,7 +96,7 @@ func TestGetFeedsForRepos(t *testing.T) { | |||||||
| 	assert.Len(t, actions, 1) | 	assert.Len(t, actions, 1) | ||||||
| 
 | 
 | ||||||
| 	// public repo & login | 	// public repo & login | ||||||
| 	actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedRepo:  pubRepo, | 		RequestedRepo:  pubRepo, | ||||||
| 		IncludePrivate: true, | 		IncludePrivate: true, | ||||||
| 		Actor:          user, | 		Actor:          user, | ||||||
| @@ -110,7 +111,7 @@ func TestGetFeeds2(t *testing.T) { | |||||||
| 	org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) | 	org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 
 | 
 | ||||||
| 	actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedUser:   org, | 		RequestedUser:   org, | ||||||
| 		Actor:           user, | 		Actor:           user, | ||||||
| 		IncludePrivate:  true, | 		IncludePrivate:  true, | ||||||
| @@ -124,7 +125,7 @@ func TestGetFeeds2(t *testing.T) { | |||||||
| 		assert.EqualValues(t, org.ID, actions[0].UserID) | 		assert.EqualValues(t, org.ID, actions[0].UserID) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	actions, err = GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedUser:   org, | 		RequestedUser:   org, | ||||||
| 		Actor:           user, | 		Actor:           user, | ||||||
| 		IncludePrivate:  false, | 		IncludePrivate:  false, | ||||||
| @@ -171,40 +172,40 @@ func TestActivityReadable(t *testing.T) { | |||||||
| 		result: true, | 		result: true, | ||||||
| 	}} | 	}} | ||||||
| 	for _, test := range tt { | 	for _, test := range tt { | ||||||
| 		assert.Equal(t, test.result, activityReadable(test.user, test.doer), test.desc) | 		assert.Equal(t, test.result, activities_model.ActivityReadable(test.user, test.doer), test.desc) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestNotifyWatchers(t *testing.T) { | func TestNotifyWatchers(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 
 | 
 | ||||||
| 	action := &Action{ | 	action := &activities_model.Action{ | ||||||
| 		ActUserID: 8, | 		ActUserID: 8, | ||||||
| 		RepoID:    1, | 		RepoID:    1, | ||||||
| 		OpType:    ActionStarRepo, | 		OpType:    activities_model.ActionStarRepo, | ||||||
| 	} | 	} | ||||||
| 	assert.NoError(t, NotifyWatchers(action)) | 	assert.NoError(t, activities_model.NotifyWatchers(action)) | ||||||
| 
 | 
 | ||||||
| 	// One watchers are inactive, thus action is only created for user 8, 1, 4, 11 | 	// One watchers are inactive, thus action is only created for user 8, 1, 4, 11 | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ActUserID: action.ActUserID, | 		ActUserID: action.ActUserID, | ||||||
| 		UserID:    8, | 		UserID:    8, | ||||||
| 		RepoID:    action.RepoID, | 		RepoID:    action.RepoID, | ||||||
| 		OpType:    action.OpType, | 		OpType:    action.OpType, | ||||||
| 	}) | 	}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ActUserID: action.ActUserID, | 		ActUserID: action.ActUserID, | ||||||
| 		UserID:    1, | 		UserID:    1, | ||||||
| 		RepoID:    action.RepoID, | 		RepoID:    action.RepoID, | ||||||
| 		OpType:    action.OpType, | 		OpType:    action.OpType, | ||||||
| 	}) | 	}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ActUserID: action.ActUserID, | 		ActUserID: action.ActUserID, | ||||||
| 		UserID:    4, | 		UserID:    4, | ||||||
| 		RepoID:    action.RepoID, | 		RepoID:    action.RepoID, | ||||||
| 		OpType:    action.OpType, | 		OpType:    action.OpType, | ||||||
| 	}) | 	}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ActUserID: action.ActUserID, | 		ActUserID: action.ActUserID, | ||||||
| 		UserID:    11, | 		UserID:    11, | ||||||
| 		RepoID:    action.RepoID, | 		RepoID:    action.RepoID, | ||||||
| @@ -215,12 +216,12 @@ func TestNotifyWatchers(t *testing.T) { | |||||||
| func TestGetFeedsCorrupted(t *testing.T) { | func TestGetFeedsCorrupted(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ID:     8, | 		ID:     8, | ||||||
| 		RepoID: 1700, | 		RepoID: 1700, | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ | 	actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 		RequestedUser:  user, | 		RequestedUser:  user, | ||||||
| 		Actor:          user, | 		Actor:          user, | ||||||
| 		IncludePrivate: true, | 		IncludePrivate: true, | ||||||
| @@ -235,12 +236,12 @@ func TestConsistencyUpdateAction(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	id := 8 | 	id := 8 | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Action{ | 	unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ | ||||||
| 		ID: int64(id), | 		ID: int64(id), | ||||||
| 	}) | 	}) | ||||||
| 	_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) | 	_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	actions := make([]*Action, 0, 1) | 	actions := make([]*activities_model.Action, 0, 1) | ||||||
| 	// | 	// | ||||||
| 	// XORM returns an error when created_unix is a string | 	// XORM returns an error when created_unix is a string | ||||||
| 	// | 	// | ||||||
| @@ -251,17 +252,17 @@ func TestConsistencyUpdateAction(t *testing.T) { | |||||||
| 	// | 	// | ||||||
| 	// Get rid of incorrectly set created_unix | 	// Get rid of incorrectly set created_unix | ||||||
| 	// | 	// | ||||||
| 	count, err := CountActionCreatedUnixString() | 	count, err := activities_model.CountActionCreatedUnixString() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 1, count) | 	assert.EqualValues(t, 1, count) | ||||||
| 	count, err = FixActionCreatedUnixString() | 	count, err = activities_model.FixActionCreatedUnixString() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 1, count) | 	assert.EqualValues(t, 1, count) | ||||||
| 
 | 
 | ||||||
| 	count, err = CountActionCreatedUnixString() | 	count, err = activities_model.CountActionCreatedUnixString() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 0, count) | 	assert.EqualValues(t, 0, count) | ||||||
| 	count, err = FixActionCreatedUnixString() | 	count, err = activities_model.FixActionCreatedUnixString() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 0, count) | 	assert.EqualValues(t, 0, count) | ||||||
| 
 | 
 | ||||||
| @@ -269,5 +270,5 @@ func TestConsistencyUpdateAction(t *testing.T) { | |||||||
| 	// XORM must be happy now | 	// XORM must be happy now | ||||||
| 	// | 	// | ||||||
| 	assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) | 	assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) | ||||||
| 	unittest.CheckConsistencyFor(t, &Action{}) | 	unittest.CheckConsistencyFor(t, &activities_model.Action{}) | ||||||
| } | } | ||||||
							
								
								
									
										20
									
								
								models/activities/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								models/activities/main_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | // Copyright 2020 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 activities_test | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
|  | 	_ "code.gitea.io/gitea/models" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMain(m *testing.M) { | ||||||
|  | 	unittest.MainTest(m, &unittest.TestOptions{ | ||||||
|  | 		GiteaRootPath: filepath.Join("..", ".."), | ||||||
|  | 	}) | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -267,10 +268,10 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n | |||||||
| 
 | 
 | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		if issue.IsPull && !CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypePullRequests) { | 		if issue.IsPull && !access_model.CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypePullRequests) { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		if !issue.IsPull && !CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypeIssues) { | 		if !issue.IsPull && !access_model.CheckRepoUnitUser(ctx, issue.Repo, user, unit.TypeIssues) { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @@ -2,11 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -19,22 +20,22 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) | 	issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) | 	assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0)) | ||||||
| 
 | 
 | ||||||
| 	// User 9 is inactive, thus notifications for user 1 and 4 are created | 	// User 9 is inactive, thus notifications for user 1 and 4 are created | ||||||
| 	notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}) | 	notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 1, IssueID: issue.ID}) | ||||||
| 	assert.Equal(t, NotificationStatusUnread, notf.Status) | 	assert.Equal(t, activities_model.NotificationStatusUnread, notf.Status) | ||||||
| 	unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) | 	unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID}) | ||||||
| 
 | 
 | ||||||
| 	notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}) | 	notf = unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 4, IssueID: issue.ID}) | ||||||
| 	assert.Equal(t, NotificationStatusUnread, notf.Status) | 	assert.Equal(t, activities_model.NotificationStatusUnread, notf.Status) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestNotificationsForUser(t *testing.T) { | func TestNotificationsForUser(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	statuses := []NotificationStatus{NotificationStatusRead, NotificationStatusUnread} | 	statuses := []activities_model.NotificationStatus{activities_model.NotificationStatusRead, activities_model.NotificationStatusUnread} | ||||||
| 	notfs, err := NotificationsForUser(db.DefaultContext, user, statuses, 1, 10) | 	notfs, err := activities_model.NotificationsForUser(db.DefaultContext, user, statuses, 1, 10) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	if assert.Len(t, notfs, 3) { | 	if assert.Len(t, notfs, 3) { | ||||||
| 		assert.EqualValues(t, 5, notfs[0].ID) | 		assert.EqualValues(t, 5, notfs[0].ID) | ||||||
| @@ -48,7 +49,7 @@ func TestNotificationsForUser(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestNotification_GetRepo(t *testing.T) { | func TestNotification_GetRepo(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) | 	notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) | ||||||
| 	repo, err := notf.GetRepo() | 	repo, err := notf.GetRepo() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, repo, notf.Repository) | 	assert.Equal(t, repo, notf.Repository) | ||||||
| @@ -57,7 +58,7 @@ func TestNotification_GetRepo(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestNotification_GetIssue(t *testing.T) { | func TestNotification_GetIssue(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}) | 	notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1}) | ||||||
| 	issue, err := notf.GetIssue() | 	issue, err := notf.GetIssue() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, issue, notf.Issue) | 	assert.Equal(t, issue, notf.Issue) | ||||||
| @@ -67,11 +68,11 @@ func TestNotification_GetIssue(t *testing.T) { | |||||||
| func TestGetNotificationCount(t *testing.T) { | func TestGetNotificationCount(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
| 	cnt, err := GetNotificationCount(db.DefaultContext, user, NotificationStatusRead) | 	cnt, err := activities_model.GetNotificationCount(db.DefaultContext, user, activities_model.NotificationStatusRead) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 0, cnt) | 	assert.EqualValues(t, 0, cnt) | ||||||
| 
 | 
 | ||||||
| 	cnt, err = GetNotificationCount(db.DefaultContext, user, NotificationStatusUnread) | 	cnt, err = activities_model.GetNotificationCount(db.DefaultContext, user, activities_model.NotificationStatusUnread) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.EqualValues(t, 1, cnt) | 	assert.EqualValues(t, 1, cnt) | ||||||
| } | } | ||||||
| @@ -80,15 +81,15 @@ func TestSetNotificationStatus(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	notf := unittest.AssertExistsAndLoadBean(t, | 	notf := unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{UserID: user.ID, Status: NotificationStatusRead}) | 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) | ||||||
| 	_, err := SetNotificationStatus(notf.ID, user, NotificationStatusPinned) | 	_, err := activities_model.SetNotificationStatus(notf.ID, user, activities_model.NotificationStatusPinned) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, | 	unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{ID: notf.ID, Status: NotificationStatusPinned}) | 		&activities_model.Notification{ID: notf.ID, Status: activities_model.NotificationStatusPinned}) | ||||||
| 
 | 
 | ||||||
| 	_, err = SetNotificationStatus(1, user, NotificationStatusRead) | 	_, err = activities_model.SetNotificationStatus(1, user, activities_model.NotificationStatusRead) | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	_, err = SetNotificationStatus(unittest.NonexistentID, user, NotificationStatusRead) | 	_, err = activities_model.SetNotificationStatus(unittest.NonexistentID, user, activities_model.NotificationStatusRead) | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -96,16 +97,16 @@ func TestUpdateNotificationStatuses(t *testing.T) { | |||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
| 	notfUnread := unittest.AssertExistsAndLoadBean(t, | 	notfUnread := unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{UserID: user.ID, Status: NotificationStatusUnread}) | 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusUnread}) | ||||||
| 	notfRead := unittest.AssertExistsAndLoadBean(t, | 	notfRead := unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{UserID: user.ID, Status: NotificationStatusRead}) | 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead}) | ||||||
| 	notfPinned := unittest.AssertExistsAndLoadBean(t, | 	notfPinned := unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{UserID: user.ID, Status: NotificationStatusPinned}) | 		&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusPinned}) | ||||||
| 	assert.NoError(t, UpdateNotificationStatuses(user, NotificationStatusUnread, NotificationStatusRead)) | 	assert.NoError(t, activities_model.UpdateNotificationStatuses(user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, | 	unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{ID: notfUnread.ID, Status: NotificationStatusRead}) | 		&activities_model.Notification{ID: notfUnread.ID, Status: activities_model.NotificationStatusRead}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, | 	unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{ID: notfRead.ID, Status: NotificationStatusRead}) | 		&activities_model.Notification{ID: notfRead.ID, Status: activities_model.NotificationStatusRead}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, | 	unittest.AssertExistsAndLoadBean(t, | ||||||
| 		&Notification{ID: notfPinned.ID, Status: NotificationStatusPinned}) | 		&activities_model.Notification{ID: notfPinned.ID, Status: activities_model.NotificationStatusPinned}) | ||||||
| } | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -39,7 +39,7 @@ type ActivityStats struct { | |||||||
| 	ClosedIssues                issues_model.IssueList | 	ClosedIssues                issues_model.IssueList | ||||||
| 	ClosedIssueAuthorCount      int64 | 	ClosedIssueAuthorCount      int64 | ||||||
| 	UnresolvedIssues            issues_model.IssueList | 	UnresolvedIssues            issues_model.IssueList | ||||||
| 	PublishedReleases           []*Release | 	PublishedReleases           []*repo_model.Release | ||||||
| 	PublishedReleaseAuthorCount int64 | 	PublishedReleaseAuthorCount int64 | ||||||
| 	Code                        *git.CodeActivityStats | 	Code                        *git.CodeActivityStats | ||||||
| } | } | ||||||
| @@ -344,7 +344,7 @@ func (stats *ActivityStats) FillReleases(repoID int64, fromTime time.Time) error | |||||||
| 	// Published releases list | 	// Published releases list | ||||||
| 	sess := releasesForActivityStatement(repoID, fromTime) | 	sess := releasesForActivityStatement(repoID, fromTime) | ||||||
| 	sess.OrderBy("release.created_unix DESC") | 	sess.OrderBy("release.created_unix DESC") | ||||||
| 	stats.PublishedReleases = make([]*Release, 0) | 	stats.PublishedReleases = make([]*repo_model.Release, 0) | ||||||
| 	if err = sess.Find(&stats.PublishedReleases); err != nil { | 	if err = sess.Find(&stats.PublishedReleases); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| @@ -101,7 +101,7 @@ func GetStatistic() (stats Statistic) { | |||||||
| 	stats.Counter.Oauth = 0 | 	stats.Counter.Oauth = 0 | ||||||
| 	stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) | 	stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) | ||||||
| 	stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) | 	stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) | ||||||
| 	stats.Counter.Release, _ = e.Count(new(Release)) | 	stats.Counter.Release, _ = e.Count(new(repo_model.Release)) | ||||||
| 	stats.Counter.AuthSource = auth.CountSources() | 	stats.Counter.AuthSource = auth.CountSources() | ||||||
| 	stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) | 	stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) | ||||||
| 	stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) | 	stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file.package models | // license that can be found in the LICENSE file.package models | ||||||
| 
 | 
 | ||||||
| package models | package activities | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| @@ -31,7 +31,7 @@ func GetUserHeatmapDataByUserTeam(user *user_model.User, team *organization.Team | |||||||
| func getUserHeatmapData(user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { | func getUserHeatmapData(user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) { | ||||||
| 	hdata := make([]*UserHeatmapData, 0) | 	hdata := make([]*UserHeatmapData, 0) | ||||||
| 
 | 
 | ||||||
| 	if !activityReadable(user, doer) { | 	if !ActivityReadable(user, doer) { | ||||||
| 		return hdata, nil | 		return hdata, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @@ -2,13 +2,14 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file.package models | // license that can be found in the LICENSE file.package models | ||||||
| 
 | 
 | ||||||
| package models | package activities_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -73,7 +74,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// get the action for comparison | 		// get the action for comparison | ||||||
| 		actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{ | 		actions, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ | ||||||
| 			RequestedUser:   user, | 			RequestedUser:   user, | ||||||
| 			Actor:           doer, | 			Actor:           doer, | ||||||
| 			IncludePrivate:  true, | 			IncludePrivate:  true, | ||||||
| @@ -83,7 +84,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) { | |||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 		// Get the heatmap and compare | 		// Get the heatmap and compare | ||||||
| 		heatmap, err := GetUserHeatmapDataByUser(user, doer) | 		heatmap, err := activities_model.GetUserHeatmapDataByUser(user, doer) | ||||||
| 		var contributions int | 		var contributions int | ||||||
| 		for _, hm := range heatmap { | 		for _, hm := range heatmap { | ||||||
| 			contributions += int(hm.Contributions) | 			contributions += int(hm.Contributions) | ||||||
| @@ -2,18 +2,21 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package admin | package admin_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
|  | 	_ "code.gitea.io/gitea/models" | ||||||
|  | 	_ "code.gitea.io/gitea/models/activities" | ||||||
|  | 	_ "code.gitea.io/gitea/models/perm/access" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestMain(m *testing.M) { | func TestMain(m *testing.M) { | ||||||
| 	unittest.MainTest(m, &unittest.TestOptions{ | 	unittest.MainTest(m, &unittest.TestOptions{ | ||||||
| 		GiteaRootPath: filepath.Join("..", ".."), | 		GiteaRootPath: filepath.Join("..", ".."), | ||||||
| 		FixtureFiles:  []string{"notice.yml"}, |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,11 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package admin | package admin_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/admin" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
| @@ -14,8 +15,8 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestNotice_TrStr(t *testing.T) { | func TestNotice_TrStr(t *testing.T) { | ||||||
| 	notice := &Notice{ | 	notice := &admin.Notice{ | ||||||
| 		Type:        NoticeRepository, | 		Type:        admin.NoticeRepository, | ||||||
| 		Description: "test description", | 		Description: "test description", | ||||||
| 	} | 	} | ||||||
| 	assert.Equal(t, "admin.notices.type_1", notice.TrStr()) | 	assert.Equal(t, "admin.notices.type_1", notice.TrStr()) | ||||||
| @@ -24,24 +25,24 @@ func TestNotice_TrStr(t *testing.T) { | |||||||
| func TestCreateNotice(t *testing.T) { | func TestCreateNotice(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	noticeBean := &Notice{ | 	noticeBean := &admin.Notice{ | ||||||
| 		Type:        NoticeRepository, | 		Type:        admin.NoticeRepository, | ||||||
| 		Description: "test description", | 		Description: "test description", | ||||||
| 	} | 	} | ||||||
| 	unittest.AssertNotExistsBean(t, noticeBean) | 	unittest.AssertNotExistsBean(t, noticeBean) | ||||||
| 	assert.NoError(t, CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) | 	assert.NoError(t, admin.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, noticeBean) | 	unittest.AssertExistsAndLoadBean(t, noticeBean) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestCreateRepositoryNotice(t *testing.T) { | func TestCreateRepositoryNotice(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	noticeBean := &Notice{ | 	noticeBean := &admin.Notice{ | ||||||
| 		Type:        NoticeRepository, | 		Type:        admin.NoticeRepository, | ||||||
| 		Description: "test description", | 		Description: "test description", | ||||||
| 	} | 	} | ||||||
| 	unittest.AssertNotExistsBean(t, noticeBean) | 	unittest.AssertNotExistsBean(t, noticeBean) | ||||||
| 	assert.NoError(t, CreateRepositoryNotice(noticeBean.Description)) | 	assert.NoError(t, admin.CreateRepositoryNotice(noticeBean.Description)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, noticeBean) | 	unittest.AssertExistsAndLoadBean(t, noticeBean) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -49,20 +50,20 @@ func TestCreateRepositoryNotice(t *testing.T) { | |||||||
|  |  | ||||||
| func TestCountNotices(t *testing.T) { | func TestCountNotices(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	assert.Equal(t, int64(3), CountNotices()) | 	assert.Equal(t, int64(3), admin.CountNotices()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestNotices(t *testing.T) { | func TestNotices(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	notices, err := Notices(1, 2) | 	notices, err := admin.Notices(1, 2) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	if assert.Len(t, notices, 2) { | 	if assert.Len(t, notices, 2) { | ||||||
| 		assert.Equal(t, int64(3), notices[0].ID) | 		assert.Equal(t, int64(3), notices[0].ID) | ||||||
| 		assert.Equal(t, int64(2), notices[1].ID) | 		assert.Equal(t, int64(2), notices[1].ID) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	notices, err = Notices(2, 2) | 	notices, err = admin.Notices(2, 2) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	if assert.Len(t, notices, 1) { | 	if assert.Len(t, notices, 1) { | ||||||
| 		assert.Equal(t, int64(1), notices[0].ID) | 		assert.Equal(t, int64(1), notices[0].ID) | ||||||
| @@ -72,45 +73,45 @@ func TestNotices(t *testing.T) { | |||||||
| func TestDeleteNotice(t *testing.T) { | func TestDeleteNotice(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| 	assert.NoError(t, DeleteNotice(3)) | 	assert.NoError(t, admin.DeleteNotice(3)) | ||||||
| 	unittest.AssertNotExistsBean(t, &Notice{ID: 3}) | 	unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestDeleteNotices(t *testing.T) { | func TestDeleteNotices(t *testing.T) { | ||||||
| 	// delete a non-empty range | 	// delete a non-empty range | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| 	assert.NoError(t, DeleteNotices(1, 2)) | 	assert.NoError(t, admin.DeleteNotices(1, 2)) | ||||||
| 	unittest.AssertNotExistsBean(t, &Notice{ID: 1}) | 	unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertNotExistsBean(t, &Notice{ID: 2}) | 	unittest.AssertNotExistsBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestDeleteNotices2(t *testing.T) { | func TestDeleteNotices2(t *testing.T) { | ||||||
| 	// delete an empty range | 	// delete an empty range | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| 	assert.NoError(t, DeleteNotices(3, 2)) | 	assert.NoError(t, admin.DeleteNotices(3, 2)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestDeleteNoticesByIDs(t *testing.T) { | func TestDeleteNoticesByIDs(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 1}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 3}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 3}) | ||||||
| 	assert.NoError(t, DeleteNoticesByIDs([]int64{1, 3})) | 	assert.NoError(t, admin.DeleteNoticesByIDs([]int64{1, 3})) | ||||||
| 	unittest.AssertNotExistsBean(t, &Notice{ID: 1}) | 	unittest.AssertNotExistsBean(t, &admin.Notice{ID: 1}) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &Notice{ID: 2}) | 	unittest.AssertExistsAndLoadBean(t, &admin.Notice{ID: 2}) | ||||||
| 	unittest.AssertNotExistsBean(t, &Notice{ID: 3}) | 	unittest.AssertNotExistsBean(t, &admin.Notice{ID: 3}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package admin | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -2,24 +2,22 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package auth | package auth_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
|  | 	_ "code.gitea.io/gitea/models" | ||||||
|  | 	_ "code.gitea.io/gitea/models/activities" | ||||||
|  | 	_ "code.gitea.io/gitea/models/auth" | ||||||
|  | 	_ "code.gitea.io/gitea/models/perm/access" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestMain(m *testing.M) { | func TestMain(m *testing.M) { | ||||||
| 	unittest.MainTest(m, &unittest.TestOptions{ | 	unittest.MainTest(m, &unittest.TestOptions{ | ||||||
| 		GiteaRootPath: filepath.Join("..", ".."), | 		GiteaRootPath: filepath.Join("..", ".."), | ||||||
| 		FixtureFiles: []string{ |  | ||||||
| 			"login_source.yml", |  | ||||||
| 			"oauth2_application.yml", |  | ||||||
| 			"oauth2_authorization_code.yml", |  | ||||||
| 			"oauth2_grant.yml", |  | ||||||
| 			"webauthn_credential.yml", |  | ||||||
| 		}, |  | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,11 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package auth | package auth_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
| @@ -17,23 +18,23 @@ import ( | |||||||
|  |  | ||||||
| func TestOAuth2Application_GenerateClientSecret(t *testing.T) { | func TestOAuth2Application_GenerateClientSecret(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) | 	app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) | ||||||
| 	secret, err := app.GenerateClientSecret() | 	secret, err := app.GenerateClientSecret() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, len(secret) > 0) | 	assert.True(t, len(secret) > 0) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1, ClientSecret: app.ClientSecret}) | 	unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) { | func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) { | ||||||
| 	assert.NoError(b, unittest.PrepareTestDatabase()) | 	assert.NoError(b, unittest.PrepareTestDatabase()) | ||||||
| 	app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1}) | 	app := unittest.AssertExistsAndLoadBean(b, &auth_model.OAuth2Application{ID: 1}) | ||||||
| 	for i := 0; i < b.N; i++ { | 	for i := 0; i < b.N; i++ { | ||||||
| 		_, _ = app.GenerateClientSecret() | 		_, _ = app.GenerateClientSecret() | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { | func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { | ||||||
| 	app := &OAuth2Application{ | 	app := &auth_model.OAuth2Application{ | ||||||
| 		RedirectURIs: []string{"a", "b", "c"}, | 		RedirectURIs: []string{"a", "b", "c"}, | ||||||
| 	} | 	} | ||||||
| 	assert.True(t, app.ContainsRedirectURI("a")) | 	assert.True(t, app.ContainsRedirectURI("a")) | ||||||
| @@ -44,7 +45,7 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) { | |||||||
|  |  | ||||||
| func TestOAuth2Application_ValidateClientSecret(t *testing.T) { | func TestOAuth2Application_ValidateClientSecret(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) | 	app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) | ||||||
| 	secret, err := app.GenerateClientSecret() | 	secret, err := app.GenerateClientSecret() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, app.ValidateClientSecret([]byte(secret))) | 	assert.True(t, app.ValidateClientSecret([]byte(secret))) | ||||||
| @@ -53,31 +54,31 @@ func TestOAuth2Application_ValidateClientSecret(t *testing.T) { | |||||||
|  |  | ||||||
| func TestGetOAuth2ApplicationByClientID(t *testing.T) { | func TestGetOAuth2ApplicationByClientID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app, err := GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138") | 	app, err := auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID) | 	assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID) | ||||||
|  |  | ||||||
| 	app, err = GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id") | 	app, err = auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id") | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	assert.Nil(t, app) | 	assert.Nil(t, app) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestCreateOAuth2Application(t *testing.T) { | func TestCreateOAuth2Application(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app, err := CreateOAuth2Application(db.DefaultContext, CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) | 	app, err := auth_model.CreateOAuth2Application(db.DefaultContext, auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, "newapp", app.Name) | 	assert.Equal(t, "newapp", app.Name) | ||||||
| 	assert.Len(t, app.ClientID, 36) | 	assert.Len(t, app.ClientID, 36) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &OAuth2Application{Name: "newapp"}) | 	unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{Name: "newapp"}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Application_TableName(t *testing.T) { | func TestOAuth2Application_TableName(t *testing.T) { | ||||||
| 	assert.Equal(t, "oauth2_application", new(OAuth2Application).TableName()) | 	assert.Equal(t, "oauth2_application", new(auth_model.OAuth2Application).TableName()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Application_GetGrantByUserID(t *testing.T) { | func TestOAuth2Application_GetGrantByUserID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) | 	app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) | ||||||
| 	grant, err := app.GetGrantByUserID(db.DefaultContext, 1) | 	grant, err := app.GetGrantByUserID(db.DefaultContext, 1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, int64(1), grant.UserID) | 	assert.Equal(t, int64(1), grant.UserID) | ||||||
| @@ -89,7 +90,7 @@ func TestOAuth2Application_GetGrantByUserID(t *testing.T) { | |||||||
|  |  | ||||||
| func TestOAuth2Application_CreateGrant(t *testing.T) { | func TestOAuth2Application_CreateGrant(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}) | 	app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1}) | ||||||
| 	grant, err := app.CreateGrant(db.DefaultContext, 2, "") | 	grant, err := app.CreateGrant(db.DefaultContext, 2, "") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NotNil(t, grant) | 	assert.NotNil(t, grant) | ||||||
| @@ -102,26 +103,26 @@ func TestOAuth2Application_CreateGrant(t *testing.T) { | |||||||
|  |  | ||||||
| func TestGetOAuth2GrantByID(t *testing.T) { | func TestGetOAuth2GrantByID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	grant, err := GetOAuth2GrantByID(db.DefaultContext, 1) | 	grant, err := auth_model.GetOAuth2GrantByID(db.DefaultContext, 1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, int64(1), grant.ID) | 	assert.Equal(t, int64(1), grant.ID) | ||||||
|  |  | ||||||
| 	grant, err = GetOAuth2GrantByID(db.DefaultContext, 34923458) | 	grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, 34923458) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Nil(t, grant) | 	assert.Nil(t, grant) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Grant_IncreaseCounter(t *testing.T) { | func TestOAuth2Grant_IncreaseCounter(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1}) | 	grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 1}) | ||||||
| 	assert.NoError(t, grant.IncreaseCounter(db.DefaultContext)) | 	assert.NoError(t, grant.IncreaseCounter(db.DefaultContext)) | ||||||
| 	assert.Equal(t, int64(2), grant.Counter) | 	assert.Equal(t, int64(2), grant.Counter) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 2}) | 	unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 2}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Grant_ScopeContains(t *testing.T) { | func TestOAuth2Grant_ScopeContains(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"}) | 	grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Scope: "openid profile"}) | ||||||
| 	assert.True(t, grant.ScopeContains("openid")) | 	assert.True(t, grant.ScopeContains("openid")) | ||||||
| 	assert.True(t, grant.ScopeContains("profile")) | 	assert.True(t, grant.ScopeContains("profile")) | ||||||
| 	assert.False(t, grant.ScopeContains("profil")) | 	assert.False(t, grant.ScopeContains("profil")) | ||||||
| @@ -130,7 +131,7 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) { | |||||||
|  |  | ||||||
| func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { | func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1}) | 	grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1}) | ||||||
| 	code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") | 	code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NotNil(t, code) | 	assert.NotNil(t, code) | ||||||
| @@ -138,46 +139,46 @@ func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2Grant_TableName(t *testing.T) { | func TestOAuth2Grant_TableName(t *testing.T) { | ||||||
| 	assert.Equal(t, "oauth2_grant", new(OAuth2Grant).TableName()) | 	assert.Equal(t, "oauth2_grant", new(auth_model.OAuth2Grant).TableName()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestGetOAuth2GrantsByUserID(t *testing.T) { | func TestGetOAuth2GrantsByUserID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	result, err := GetOAuth2GrantsByUserID(db.DefaultContext, 1) | 	result, err := auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Len(t, result, 1) | 	assert.Len(t, result, 1) | ||||||
| 	assert.Equal(t, int64(1), result[0].ID) | 	assert.Equal(t, int64(1), result[0].ID) | ||||||
| 	assert.Equal(t, result[0].ApplicationID, result[0].Application.ID) | 	assert.Equal(t, result[0].ApplicationID, result[0].Application.ID) | ||||||
|  |  | ||||||
| 	result, err = GetOAuth2GrantsByUserID(db.DefaultContext, 34134) | 	result, err = auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 34134) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Empty(t, result) | 	assert.Empty(t, result) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestRevokeOAuth2Grant(t *testing.T) { | func TestRevokeOAuth2Grant(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	assert.NoError(t, RevokeOAuth2Grant(db.DefaultContext, 1, 1)) | 	assert.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1)) | ||||||
| 	unittest.AssertNotExistsBean(t, &OAuth2Grant{ID: 1, UserID: 1}) | 	unittest.AssertNotExistsBean(t, &auth_model.OAuth2Grant{ID: 1, UserID: 1}) | ||||||
| } | } | ||||||
|  |  | ||||||
| //////////////////// Authorization Code | //////////////////// Authorization Code | ||||||
|  |  | ||||||
| func TestGetOAuth2AuthorizationByCode(t *testing.T) { | func TestGetOAuth2AuthorizationByCode(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	code, err := GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode") | 	code, err := auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NotNil(t, code) | 	assert.NotNil(t, code) | ||||||
| 	assert.Equal(t, "authcode", code.Code) | 	assert.Equal(t, "authcode", code.Code) | ||||||
| 	assert.Equal(t, int64(1), code.ID) | 	assert.Equal(t, int64(1), code.ID) | ||||||
|  |  | ||||||
| 	code, err = GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist") | 	code, err = auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Nil(t, code) | 	assert.Nil(t, code) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { | func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { | ||||||
| 	// test plain | 	// test plain | ||||||
| 	code := &OAuth2AuthorizationCode{ | 	code := &auth_model.OAuth2AuthorizationCode{ | ||||||
| 		CodeChallengeMethod: "plain", | 		CodeChallengeMethod: "plain", | ||||||
| 		CodeChallenge:       "test123", | 		CodeChallenge:       "test123", | ||||||
| 	} | 	} | ||||||
| @@ -185,7 +186,7 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { | |||||||
| 	assert.False(t, code.ValidateCodeChallenge("ierwgjoergjio")) | 	assert.False(t, code.ValidateCodeChallenge("ierwgjoergjio")) | ||||||
|  |  | ||||||
| 	// test S256 | 	// test S256 | ||||||
| 	code = &OAuth2AuthorizationCode{ | 	code = &auth_model.OAuth2AuthorizationCode{ | ||||||
| 		CodeChallengeMethod: "S256", | 		CodeChallengeMethod: "S256", | ||||||
| 		CodeChallenge:       "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", | 		CodeChallenge:       "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", | ||||||
| 	} | 	} | ||||||
| @@ -193,14 +194,14 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { | |||||||
| 	assert.False(t, code.ValidateCodeChallenge("wiogjerogorewngoenrgoiuenorg")) | 	assert.False(t, code.ValidateCodeChallenge("wiogjerogorewngoenrgoiuenorg")) | ||||||
|  |  | ||||||
| 	// test unknown | 	// test unknown | ||||||
| 	code = &OAuth2AuthorizationCode{ | 	code = &auth_model.OAuth2AuthorizationCode{ | ||||||
| 		CodeChallengeMethod: "monkey", | 		CodeChallengeMethod: "monkey", | ||||||
| 		CodeChallenge:       "foiwgjioriogeiogjerger", | 		CodeChallenge:       "foiwgjioriogeiogjerger", | ||||||
| 	} | 	} | ||||||
| 	assert.False(t, code.ValidateCodeChallenge("foiwgjioriogeiogjerger")) | 	assert.False(t, code.ValidateCodeChallenge("foiwgjioriogeiogjerger")) | ||||||
|  |  | ||||||
| 	// test no code challenge | 	// test no code challenge | ||||||
| 	code = &OAuth2AuthorizationCode{ | 	code = &auth_model.OAuth2AuthorizationCode{ | ||||||
| 		CodeChallengeMethod: "", | 		CodeChallengeMethod: "", | ||||||
| 		CodeChallenge:       "foierjiogerogerg", | 		CodeChallenge:       "foierjiogerogerg", | ||||||
| 	} | 	} | ||||||
| @@ -208,7 +209,7 @@ func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { | func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { | ||||||
| 	code := &OAuth2AuthorizationCode{ | 	code := &auth_model.OAuth2AuthorizationCode{ | ||||||
| 		RedirectURI: "https://example.com/callback", | 		RedirectURI: "https://example.com/callback", | ||||||
| 		Code:        "thecode", | 		Code:        "thecode", | ||||||
| 	} | 	} | ||||||
| @@ -224,11 +225,11 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) { | |||||||
|  |  | ||||||
| func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) { | func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) | 	code := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) | ||||||
| 	assert.NoError(t, code.Invalidate(db.DefaultContext)) | 	assert.NoError(t, code.Invalidate(db.DefaultContext)) | ||||||
| 	unittest.AssertNotExistsBean(t, &OAuth2AuthorizationCode{Code: "authcode"}) | 	unittest.AssertNotExistsBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestOAuth2AuthorizationCode_TableName(t *testing.T) { | func TestOAuth2AuthorizationCode_TableName(t *testing.T) { | ||||||
| 	assert.Equal(t, "oauth2_authorization_code", new(OAuth2AuthorizationCode).TableName()) | 	assert.Equal(t, "oauth2_authorization_code", new(auth_model.OAuth2AuthorizationCode).TableName()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,12 +2,13 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package auth | package auth_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	"code.gitea.io/gitea/modules/json" | 	"code.gitea.io/gitea/modules/json" | ||||||
| @@ -37,13 +38,13 @@ func (source *TestSource) ToDB() ([]byte, error) { | |||||||
| func TestDumpAuthSource(t *testing.T) { | func TestDumpAuthSource(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	authSourceSchema, err := db.TableInfo(new(Source)) | 	authSourceSchema, err := db.TableInfo(new(auth_model.Source)) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	RegisterTypeConfig(OAuth2, new(TestSource)) | 	auth_model.RegisterTypeConfig(auth_model.OAuth2, new(TestSource)) | ||||||
|  |  | ||||||
| 	CreateSource(&Source{ | 	auth_model.CreateSource(&auth_model.Source{ | ||||||
| 		Type:     OAuth2, | 		Type:     auth_model.OAuth2, | ||||||
| 		Name:     "TestSource", | 		Name:     "TestSource", | ||||||
| 		IsActive: false, | 		IsActive: false, | ||||||
| 		Cfg: &TestSource{ | 		Cfg: &TestSource{ | ||||||
|   | |||||||
| @@ -3,14 +3,13 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package auth | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"crypto/subtle" | 	"crypto/subtle" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models/auth" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| @@ -21,6 +20,34 @@ import ( | |||||||
| 	lru "github.com/hashicorp/golang-lru" | 	lru "github.com/hashicorp/golang-lru" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // ErrAccessTokenNotExist represents a "AccessTokenNotExist" kind of error. | ||||||
|  | type ErrAccessTokenNotExist struct { | ||||||
|  | 	Token string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsErrAccessTokenNotExist checks if an error is a ErrAccessTokenNotExist. | ||||||
|  | func IsErrAccessTokenNotExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrAccessTokenNotExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrAccessTokenNotExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("access token does not exist [sha: %s]", err.Token) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error. | ||||||
|  | type ErrAccessTokenEmpty struct{} | ||||||
|  | 
 | ||||||
|  | // IsErrAccessTokenEmpty checks if an error is a ErrAccessTokenEmpty. | ||||||
|  | func IsErrAccessTokenEmpty(err error) bool { | ||||||
|  | 	_, ok := err.(ErrAccessTokenEmpty) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrAccessTokenEmpty) Error() string { | ||||||
|  | 	return "access token is empty" | ||||||
|  | } | ||||||
|  | 
 | ||||||
| var successfulAccessTokenCache *lru.Cache | var successfulAccessTokenCache *lru.Cache | ||||||
| 
 | 
 | ||||||
| // AccessToken represents a personal access token. | // AccessToken represents a personal access token. | ||||||
| @@ -68,7 +95,7 @@ func NewAccessToken(t *AccessToken) error { | |||||||
| 	} | 	} | ||||||
| 	t.TokenSalt = salt | 	t.TokenSalt = salt | ||||||
| 	t.Token = base.EncodeSha1(gouuid.New().String()) | 	t.Token = base.EncodeSha1(gouuid.New().String()) | ||||||
| 	t.TokenHash = auth.HashToken(t.Token, t.TokenSalt) | 	t.TokenHash = HashToken(t.Token, t.TokenSalt) | ||||||
| 	t.TokenLastEight = t.Token[len(t.Token)-8:] | 	t.TokenLastEight = t.Token[len(t.Token)-8:] | ||||||
| 	_, err = db.GetEngine(db.DefaultContext).Insert(t) | 	_, err = db.GetEngine(db.DefaultContext).Insert(t) | ||||||
| 	return err | 	return err | ||||||
| @@ -130,7 +157,7 @@ func GetAccessTokenBySHA(token string) (*AccessToken, error) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, t := range tokens { | 	for _, t := range tokens { | ||||||
| 		tempHash := auth.HashToken(token, t.TokenSalt) | 		tempHash := HashToken(token, t.TokenSalt) | ||||||
| 		if subtle.ConstantTimeCompare([]byte(t.TokenHash), []byte(tempHash)) == 1 { | 		if subtle.ConstantTimeCompare([]byte(t.TokenHash), []byte(tempHash)) == 1 { | ||||||
| 			if successfulAccessTokenCache != nil { | 			if successfulAccessTokenCache != nil { | ||||||
| 				successfulAccessTokenCache.Add(token, t.ID) | 				successfulAccessTokenCache.Add(token, t.ID) | ||||||
| @@ -2,11 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package auth_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -14,77 +15,77 @@ import ( | |||||||
| 
 | 
 | ||||||
| func TestNewAccessToken(t *testing.T) { | func TestNewAccessToken(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	token := &AccessToken{ | 	token := &auth_model.AccessToken{ | ||||||
| 		UID:  3, | 		UID:  3, | ||||||
| 		Name: "Token C", | 		Name: "Token C", | ||||||
| 	} | 	} | ||||||
| 	assert.NoError(t, NewAccessToken(token)) | 	assert.NoError(t, auth_model.NewAccessToken(token)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, token) | 	unittest.AssertExistsAndLoadBean(t, token) | ||||||
| 
 | 
 | ||||||
| 	invalidToken := &AccessToken{ | 	invalidToken := &auth_model.AccessToken{ | ||||||
| 		ID:   token.ID, // duplicate | 		ID:   token.ID, // duplicate | ||||||
| 		UID:  2, | 		UID:  2, | ||||||
| 		Name: "Token F", | 		Name: "Token F", | ||||||
| 	} | 	} | ||||||
| 	assert.Error(t, NewAccessToken(invalidToken)) | 	assert.Error(t, auth_model.NewAccessToken(invalidToken)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestAccessTokenByNameExists(t *testing.T) { | func TestAccessTokenByNameExists(t *testing.T) { | ||||||
| 	name := "Token Gitea" | 	name := "Token Gitea" | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	token := &AccessToken{ | 	token := &auth_model.AccessToken{ | ||||||
| 		UID:  3, | 		UID:  3, | ||||||
| 		Name: name, | 		Name: name, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Check to make sure it doesn't exists already | 	// Check to make sure it doesn't exists already | ||||||
| 	exist, err := AccessTokenByNameExists(token) | 	exist, err := auth_model.AccessTokenByNameExists(token) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, exist) | 	assert.False(t, exist) | ||||||
| 
 | 
 | ||||||
| 	// Save it to the database | 	// Save it to the database | ||||||
| 	assert.NoError(t, NewAccessToken(token)) | 	assert.NoError(t, auth_model.NewAccessToken(token)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, token) | 	unittest.AssertExistsAndLoadBean(t, token) | ||||||
| 
 | 
 | ||||||
| 	// This token must be found by name in the DB now | 	// This token must be found by name in the DB now | ||||||
| 	exist, err = AccessTokenByNameExists(token) | 	exist, err = auth_model.AccessTokenByNameExists(token) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, exist) | 	assert.True(t, exist) | ||||||
| 
 | 
 | ||||||
| 	user4Token := &AccessToken{ | 	user4Token := &auth_model.AccessToken{ | ||||||
| 		UID:  4, | 		UID:  4, | ||||||
| 		Name: name, | 		Name: name, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Name matches but different user ID, this shouldn't exists in the | 	// Name matches but different user ID, this shouldn't exists in the | ||||||
| 	// database | 	// database | ||||||
| 	exist, err = AccessTokenByNameExists(user4Token) | 	exist, err = auth_model.AccessTokenByNameExists(user4Token) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, exist) | 	assert.False(t, exist) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetAccessTokenBySHA(t *testing.T) { | func TestGetAccessTokenBySHA(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	token, err := GetAccessTokenBySHA("d2c6c1ba3890b309189a8e618c72a162e4efbf36") | 	token, err := auth_model.GetAccessTokenBySHA("d2c6c1ba3890b309189a8e618c72a162e4efbf36") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, int64(1), token.UID) | 	assert.Equal(t, int64(1), token.UID) | ||||||
| 	assert.Equal(t, "Token A", token.Name) | 	assert.Equal(t, "Token A", token.Name) | ||||||
| 	assert.Equal(t, "2b3668e11cb82d3af8c6e4524fc7841297668f5008d1626f0ad3417e9fa39af84c268248b78c481daa7e5dc437784003494f", token.TokenHash) | 	assert.Equal(t, "2b3668e11cb82d3af8c6e4524fc7841297668f5008d1626f0ad3417e9fa39af84c268248b78c481daa7e5dc437784003494f", token.TokenHash) | ||||||
| 	assert.Equal(t, "e4efbf36", token.TokenLastEight) | 	assert.Equal(t, "e4efbf36", token.TokenLastEight) | ||||||
| 
 | 
 | ||||||
| 	_, err = GetAccessTokenBySHA("notahash") | 	_, err = auth_model.GetAccessTokenBySHA("notahash") | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	assert.True(t, IsErrAccessTokenNotExist(err)) | 	assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) | ||||||
| 
 | 
 | ||||||
| 	_, err = GetAccessTokenBySHA("") | 	_, err = auth_model.GetAccessTokenBySHA("") | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	assert.True(t, IsErrAccessTokenEmpty(err)) | 	assert.True(t, auth_model.IsErrAccessTokenEmpty(err)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestListAccessTokens(t *testing.T) { | func TestListAccessTokens(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	tokens, err := ListAccessTokens(ListAccessTokensOptions{UserID: 1}) | 	tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 1}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	if assert.Len(t, tokens, 2) { | 	if assert.Len(t, tokens, 2) { | ||||||
| 		assert.Equal(t, int64(1), tokens[0].UID) | 		assert.Equal(t, int64(1), tokens[0].UID) | ||||||
| @@ -93,39 +94,39 @@ func TestListAccessTokens(t *testing.T) { | |||||||
| 		assert.Contains(t, []string{tokens[0].Name, tokens[1].Name}, "Token B") | 		assert.Contains(t, []string{tokens[0].Name, tokens[1].Name}, "Token B") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	tokens, err = ListAccessTokens(ListAccessTokensOptions{UserID: 2}) | 	tokens, err = auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 2}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	if assert.Len(t, tokens, 1) { | 	if assert.Len(t, tokens, 1) { | ||||||
| 		assert.Equal(t, int64(2), tokens[0].UID) | 		assert.Equal(t, int64(2), tokens[0].UID) | ||||||
| 		assert.Equal(t, "Token A", tokens[0].Name) | 		assert.Equal(t, "Token A", tokens[0].Name) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	tokens, err = ListAccessTokens(ListAccessTokensOptions{UserID: 100}) | 	tokens, err = auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{UserID: 100}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Empty(t, tokens) | 	assert.Empty(t, tokens) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestUpdateAccessToken(t *testing.T) { | func TestUpdateAccessToken(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	token, err := GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") | 	token, err := auth_model.GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	token.Name = "Token Z" | 	token.Name = "Token Z" | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, UpdateAccessToken(token)) | 	assert.NoError(t, auth_model.UpdateAccessToken(token)) | ||||||
| 	unittest.AssertExistsAndLoadBean(t, token) | 	unittest.AssertExistsAndLoadBean(t, token) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestDeleteAccessTokenByID(t *testing.T) { | func TestDeleteAccessTokenByID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 
 | 
 | ||||||
| 	token, err := GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") | 	token, err := auth_model.GetAccessTokenBySHA("4c6f36e6cf498e2a448662f915d932c09c5a146c") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, int64(1), token.UID) | 	assert.Equal(t, int64(1), token.UID) | ||||||
| 
 | 
 | ||||||
| 	assert.NoError(t, DeleteAccessTokenByID(token.ID, 1)) | 	assert.NoError(t, auth_model.DeleteAccessTokenByID(token.ID, 1)) | ||||||
| 	unittest.AssertNotExistsBean(t, token) | 	unittest.AssertNotExistsBean(t, token) | ||||||
| 
 | 
 | ||||||
| 	err = DeleteAccessTokenByID(100, 100) | 	err = auth_model.DeleteAccessTokenByID(100, 100) | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	assert.True(t, IsErrAccessTokenNotExist(err)) | 	assert.True(t, auth_model.IsErrAccessTokenNotExist(err)) | ||||||
| } | } | ||||||
| @@ -2,11 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| package auth | package auth_test | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
| 	"github.com/duo-labs/webauthn/webauthn" | 	"github.com/duo-labs/webauthn/webauthn" | ||||||
| @@ -16,51 +17,51 @@ import ( | |||||||
| func TestGetWebAuthnCredentialByID(t *testing.T) { | func TestGetWebAuthnCredentialByID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	res, err := GetWebAuthnCredentialByID(1) | 	res, err := auth_model.GetWebAuthnCredentialByID(1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, "WebAuthn credential", res.Name) | 	assert.Equal(t, "WebAuthn credential", res.Name) | ||||||
|  |  | ||||||
| 	_, err = GetWebAuthnCredentialByID(342432) | 	_, err = auth_model.GetWebAuthnCredentialByID(342432) | ||||||
| 	assert.Error(t, err) | 	assert.Error(t, err) | ||||||
| 	assert.True(t, IsErrWebAuthnCredentialNotExist(err)) | 	assert.True(t, auth_model.IsErrWebAuthnCredentialNotExist(err)) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestGetWebAuthnCredentialsByUID(t *testing.T) { | func TestGetWebAuthnCredentialsByUID(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	res, err := GetWebAuthnCredentialsByUID(32) | 	res, err := auth_model.GetWebAuthnCredentialsByUID(32) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Len(t, res, 1) | 	assert.Len(t, res, 1) | ||||||
| 	assert.Equal(t, "WebAuthn credential", res[0].Name) | 	assert.Equal(t, "WebAuthn credential", res[0].Name) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestWebAuthnCredential_TableName(t *testing.T) { | func TestWebAuthnCredential_TableName(t *testing.T) { | ||||||
| 	assert.Equal(t, "webauthn_credential", WebAuthnCredential{}.TableName()) | 	assert.Equal(t, "webauthn_credential", auth_model.WebAuthnCredential{}.TableName()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { | func TestWebAuthnCredential_UpdateSignCount(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) | 	cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) | ||||||
| 	cred.SignCount = 1 | 	cred.SignCount = 1 | ||||||
| 	assert.NoError(t, cred.UpdateSignCount()) | 	assert.NoError(t, cred.UpdateSignCount()) | ||||||
| 	unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 1}) | 	unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) { | func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
| 	cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}) | 	cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1}) | ||||||
| 	cred.SignCount = 0xffffffff | 	cred.SignCount = 0xffffffff | ||||||
| 	assert.NoError(t, cred.UpdateSignCount()) | 	assert.NoError(t, cred.UpdateSignCount()) | ||||||
| 	unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) | 	unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestCreateCredential(t *testing.T) { | func TestCreateCredential(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	res, err := CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) | 	res, err := auth_model.CreateCredential(1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Equal(t, "WebAuthn Created Credential", res.Name) | 	assert.Equal(t, "WebAuthn Created Credential", res.Name) | ||||||
| 	assert.Equal(t, []byte("Test"), res.CredentialID) | 	assert.Equal(t, []byte("Test"), res.CredentialID) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsIf(t, true, &WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1}) | 	unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,56 +0,0 @@ | |||||||
| // Copyright 2017 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 |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"code.gitea.io/gitea/models/db" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" |  | ||||||
| 	user_model "code.gitea.io/gitea/models/user" |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" |  | ||||||
|  |  | ||||||
| 	"xorm.io/builder" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // CountNullArchivedRepository counts the number of repositories with is_archived is null |  | ||||||
| func CountNullArchivedRepository() (int64, error) { |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(repo_model.Repository)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FixNullArchivedRepository sets is_archived to false where it is null |  | ||||||
| func FixNullArchivedRepository() (int64, error) { |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&repo_model.Repository{ |  | ||||||
| 		IsArchived: false, |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CountWrongUserType count OrgUser who have wrong type |  | ||||||
| func CountWrongUserType() (int64, error) { |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(user_model.User)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FixWrongUserType fix OrgUser who have wrong type |  | ||||||
| func FixWrongUserType() (int64, error) { |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&user_model.User{Type: 1}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CountActionCreatedUnixString count actions where created_unix is an empty string |  | ||||||
| func CountActionCreatedUnixString() (int64, error) { |  | ||||||
| 	if setting.Database.UseSQLite3 { |  | ||||||
| 		return db.GetEngine(db.DefaultContext).Where(`created_unix = ""`).Count(new(Action)) |  | ||||||
| 	} |  | ||||||
| 	return 0, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // FixActionCreatedUnixString set created_unix to zero if it is an empty string |  | ||||||
| func FixActionCreatedUnixString() (int64, error) { |  | ||||||
| 	if setting.Database.UseSQLite3 { |  | ||||||
| 		res, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0, err |  | ||||||
| 		} |  | ||||||
| 		return res.RowsAffected() |  | ||||||
| 	} |  | ||||||
| 	return 0, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										203
									
								
								models/error.go
									
									
									
									
									
								
							
							
						
						
									
										203
									
								
								models/error.go
									
									
									
									
									
								
							| @@ -57,93 +57,6 @@ func (err ErrUserOwnPackages) Error() string { | |||||||
| 	return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID) | 	return fmt.Sprintf("user still has ownership of packages [uid: %d]", err.UID) | ||||||
| } | } | ||||||
|  |  | ||||||
| //  __      __.__ __   .__ |  | ||||||
| // /  \    /  \__|  | _|__| |  | ||||||
| // \   \/\/   /  |  |/ /  | |  | ||||||
| //  \        /|  |    <|  | |  | ||||||
| //   \__/\  / |__|__|_ \__| |  | ||||||
| //        \/          \/ |  | ||||||
|  |  | ||||||
| // ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error. |  | ||||||
| type ErrWikiAlreadyExist struct { |  | ||||||
| 	Title string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrWikiAlreadyExist checks if an error is an ErrWikiAlreadyExist. |  | ||||||
| func IsErrWikiAlreadyExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrWikiAlreadyExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrWikiAlreadyExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("wiki page already exists [title: %s]", err.Title) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrWikiReservedName represents a reserved name error. |  | ||||||
| type ErrWikiReservedName struct { |  | ||||||
| 	Title string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrWikiReservedName checks if an error is an ErrWikiReservedName. |  | ||||||
| func IsErrWikiReservedName(err error) bool { |  | ||||||
| 	_, ok := err.(ErrWikiReservedName) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrWikiReservedName) Error() string { |  | ||||||
| 	return fmt.Sprintf("wiki title is reserved: %s", err.Title) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrWikiInvalidFileName represents an invalid wiki file name. |  | ||||||
| type ErrWikiInvalidFileName struct { |  | ||||||
| 	FileName string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrWikiInvalidFileName checks if an error is an ErrWikiInvalidFileName. |  | ||||||
| func IsErrWikiInvalidFileName(err error) bool { |  | ||||||
| 	_, ok := err.(ErrWikiInvalidFileName) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrWikiInvalidFileName) Error() string { |  | ||||||
| 	return fmt.Sprintf("Invalid wiki filename: %s", err.FileName) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //    _____                                   ___________     __ |  | ||||||
| //   /  _  \   ____  ____  ____   ______ _____\__    ___/___ |  | __ ____   ____ |  | ||||||
| //  /  /_\  \_/ ___\/ ___\/ __ \ /  ___//  ___/ |    | /  _ \|  |/ // __ \ /    \ |  | ||||||
| // /    |    \  \__\  \__\  ___/ \___ \ \___ \  |    |(  <_> )    <\  ___/|   |  \ |  | ||||||
| // \____|__  /\___  >___  >___  >____  >____  > |____| \____/|__|_ \\___  >___|  / |  | ||||||
| //         \/     \/    \/    \/     \/     \/                    \/    \/     \/ |  | ||||||
|  |  | ||||||
| // ErrAccessTokenNotExist represents a "AccessTokenNotExist" kind of error. |  | ||||||
| type ErrAccessTokenNotExist struct { |  | ||||||
| 	Token string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrAccessTokenNotExist checks if an error is a ErrAccessTokenNotExist. |  | ||||||
| func IsErrAccessTokenNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrAccessTokenNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrAccessTokenNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("access token does not exist [sha: %s]", err.Token) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrAccessTokenEmpty represents a "AccessTokenEmpty" kind of error. |  | ||||||
| type ErrAccessTokenEmpty struct{} |  | ||||||
|  |  | ||||||
| // IsErrAccessTokenEmpty checks if an error is a ErrAccessTokenEmpty. |  | ||||||
| func IsErrAccessTokenEmpty(err error) bool { |  | ||||||
| 	_, ok := err.(ErrAccessTokenEmpty) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrAccessTokenEmpty) Error() string { |  | ||||||
| 	return "access token is empty" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrNoPendingRepoTransfer is an error type for repositories without a pending | // ErrNoPendingRepoTransfer is an error type for repositories without a pending | ||||||
| // transfer request | // transfer request | ||||||
| type ErrNoPendingRepoTransfer struct { | type ErrNoPendingRepoTransfer struct { | ||||||
| @@ -178,23 +91,6 @@ func (err ErrRepoTransferInProgress) Error() string { | |||||||
| 	return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) | 	return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ErrForkAlreadyExist represents a "ForkAlreadyExist" kind of error. |  | ||||||
| type ErrForkAlreadyExist struct { |  | ||||||
| 	Uname    string |  | ||||||
| 	RepoName string |  | ||||||
| 	ForkName string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrForkAlreadyExist checks if an error is an ErrForkAlreadyExist. |  | ||||||
| func IsErrForkAlreadyExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrForkAlreadyExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrForkAlreadyExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("repository is already forked by user [uname: %s, repo path: %s, fork path: %s]", err.Uname, err.RepoName, err.ForkName) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. | // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. | ||||||
| type ErrInvalidCloneAddr struct { | type ErrInvalidCloneAddr struct { | ||||||
| 	Host               string | 	Host               string | ||||||
| @@ -243,37 +139,6 @@ func (err ErrUpdateTaskNotExist) Error() string { | |||||||
| 	return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID) | 	return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ErrReleaseAlreadyExist represents a "ReleaseAlreadyExist" kind of error. |  | ||||||
| type ErrReleaseAlreadyExist struct { |  | ||||||
| 	TagName string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrReleaseAlreadyExist checks if an error is a ErrReleaseAlreadyExist. |  | ||||||
| func IsErrReleaseAlreadyExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrReleaseAlreadyExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrReleaseAlreadyExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("release tag already exist [tag_name: %s]", err.TagName) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrReleaseNotExist represents a "ReleaseNotExist" kind of error. |  | ||||||
| type ErrReleaseNotExist struct { |  | ||||||
| 	ID      int64 |  | ||||||
| 	TagName string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrReleaseNotExist checks if an error is a ErrReleaseNotExist. |  | ||||||
| func IsErrReleaseNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrReleaseNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrReleaseNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ErrInvalidTagName represents a "InvalidTagName" kind of error. | // ErrInvalidTagName represents a "InvalidTagName" kind of error. | ||||||
| type ErrInvalidTagName struct { | type ErrInvalidTagName struct { | ||||||
| 	TagName string | 	TagName string | ||||||
| @@ -657,71 +522,3 @@ func (err ErrPullRequestHasMerged) Error() string { | |||||||
| 	return fmt.Sprintf("pull request has merged [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", | 	return fmt.Sprintf("pull request has merged [id: %d, issue_id: %d, head_repo_id: %d, base_repo_id: %d, head_branch: %s, base_branch: %s]", | ||||||
| 		err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) | 		err.ID, err.IssueID, err.HeadRepoID, err.BaseRepoID, err.HeadBranch, err.BaseBranch) | ||||||
| } | } | ||||||
|  |  | ||||||
| //  _________ __                                __         .__ |  | ||||||
| //  /   _____//  |_  ____ ________  _  _______ _/  |_  ____ |  |__ |  | ||||||
| //  \_____  \\   __\/  _ \\____ \ \/ \/ /\__  \\   __\/ ___\|  |  \ |  | ||||||
| //  /        \|  | (  <_> )  |_> >     /  / __ \|  | \  \___|   Y  \ |  | ||||||
| //  /_______  /|__|  \____/|   __/ \/\_/  (____  /__|  \___  >___|  / |  | ||||||
| // \/             |__|                \/          \/     \/ |  | ||||||
|  |  | ||||||
| // ErrStopwatchNotExist represents a "Stopwatch Not Exist" kind of error. |  | ||||||
| type ErrStopwatchNotExist struct { |  | ||||||
| 	ID int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrStopwatchNotExist checks if an error is a ErrStopwatchNotExist. |  | ||||||
| func IsErrStopwatchNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrStopwatchNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrStopwatchNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("stopwatch does not exist [id: %d]", err.ID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ___________                     __              .______________.__ |  | ||||||
| // \__    ___/___________    ____ |  | __ ____   __| _/\__    ___/|__| _____   ____ |  | ||||||
| // |    |  \_  __ \__  \ _/ ___\|  |/ // __ \ / __ |   |    |   |  |/     \_/ __ \ |  | ||||||
| // |    |   |  | \// __ \\  \___|    <\  ___// /_/ |   |    |   |  |  Y Y  \  ___/ |  | ||||||
| // |____|   |__|  (____  /\___  >__|_ \\___  >____ |   |____|   |__|__|_|  /\___  > |  | ||||||
| // \/     \/     \/    \/     \/                     \/     \/ |  | ||||||
|  |  | ||||||
| // ErrTrackedTimeNotExist represents a "TrackedTime Not Exist" kind of error. |  | ||||||
| type ErrTrackedTimeNotExist struct { |  | ||||||
| 	ID int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrTrackedTimeNotExist checks if an error is a ErrTrackedTimeNotExist. |  | ||||||
| func IsErrTrackedTimeNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrTrackedTimeNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrTrackedTimeNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("tracked time does not exist [id: %d]", err.ID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //  ____ ___        .__                    .___ |  | ||||||
| // |    |   \______ |  |   _________     __| _/ |  | ||||||
| // |    |   /\____ \|  |  /  _ \__  \   / __ | |  | ||||||
| // |    |  / |  |_> >  |_(  <_> ) __ \_/ /_/ | |  | ||||||
| // |______/  |   __/|____/\____(____  /\____ | |  | ||||||
| //           |__|                   \/      \/ |  | ||||||
| // |  | ||||||
|  |  | ||||||
| // ErrUploadNotExist represents a "UploadNotExist" kind of error. |  | ||||||
| type ErrUploadNotExist struct { |  | ||||||
| 	ID   int64 |  | ||||||
| 	UUID string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsErrUploadNotExist checks if an error is a ErrUploadNotExist. |  | ||||||
| func IsErrUploadNotExist(err error) bool { |  | ||||||
| 	_, ok := err.(ErrUploadNotExist) |  | ||||||
| 	return ok |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (err ErrUploadNotExist) Error() string { |  | ||||||
| 	return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -28,7 +29,7 @@ func TestFixturesAreConsistent(t *testing.T) { | |||||||
| 		&user_model.User{}, | 		&user_model.User{}, | ||||||
| 		&repo_model.Repository{}, | 		&repo_model.Repository{}, | ||||||
| 		&organization.Team{}, | 		&organization.Team{}, | ||||||
| 		&Action{}) | 		&activities_model.Action{}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestMain(m *testing.M) { | func TestMain(m *testing.M) { | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -154,7 +155,7 @@ func InsertPullRequests(prs ...*issues_model.PullRequest) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| // InsertReleases migrates release | // InsertReleases migrates release | ||||||
| func InsertReleases(rels ...*Release) error { | func InsertReleases(rels ...*repo_model.Release) error { | ||||||
| 	ctx, committer, err := db.TxContext() | 	ctx, committer, err := db.TxContext() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -191,7 +192,7 @@ func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, us | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { | 	if err := repo_model.UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -149,7 +149,7 @@ func TestMigrate_InsertReleases(t *testing.T) { | |||||||
| 	a := &repo_model.Attachment{ | 	a := &repo_model.Attachment{ | ||||||
| 		UUID: "a0eebc91-9c0c-4ef7-bb6e-6bb9bd380a12", | 		UUID: "a0eebc91-9c0c-4ef7-bb6e-6bb9bd380a12", | ||||||
| 	} | 	} | ||||||
| 	r := &Release{ | 	r := &repo_model.Release{ | ||||||
| 		Attachments: []*repo_model.Attachment{a}, | 		Attachments: []*repo_model.Attachment{a}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,79 +8,13 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" |  | ||||||
| 	user_model "code.gitea.io/gitea/models/user" |  | ||||||
|  |  | ||||||
| 	"xorm.io/builder" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // MinimalOrg represents a simple orgnization with only needed columns |  | ||||||
| type MinimalOrg = organization.Organization |  | ||||||
|  |  | ||||||
| // GetUserOrgsList returns one user's all orgs list |  | ||||||
| func GetUserOrgsList(user *user_model.User) ([]*MinimalOrg, error) { |  | ||||||
| 	schema, err := db.TableInfo(new(user_model.User)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	outputCols := []string{ |  | ||||||
| 		"id", |  | ||||||
| 		"name", |  | ||||||
| 		"full_name", |  | ||||||
| 		"visibility", |  | ||||||
| 		"avatar", |  | ||||||
| 		"avatar_email", |  | ||||||
| 		"use_custom_avatar", |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	groupByCols := &strings.Builder{} |  | ||||||
| 	for _, col := range outputCols { |  | ||||||
| 		fmt.Fprintf(groupByCols, "`%s`.%s,", schema.Name, col) |  | ||||||
| 	} |  | ||||||
| 	groupByStr := groupByCols.String() |  | ||||||
| 	groupByStr = groupByStr[0 : len(groupByStr)-1] |  | ||||||
|  |  | ||||||
| 	sess := db.GetEngine(db.DefaultContext) |  | ||||||
| 	sess = sess.Select(groupByStr+", count(distinct repo_id) as org_count"). |  | ||||||
| 		Table("user"). |  | ||||||
| 		Join("INNER", "team", "`team`.org_id = `user`.id"). |  | ||||||
| 		Join("INNER", "team_user", "`team`.id = `team_user`.team_id"). |  | ||||||
| 		Join("LEFT", builder. |  | ||||||
| 			Select("id as repo_id, owner_id as repo_owner_id"). |  | ||||||
| 			From("repository"). |  | ||||||
| 			Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), "`repository`.repo_owner_id = `team`.org_id"). |  | ||||||
| 		Where("`team_user`.uid = ?", user.ID). |  | ||||||
| 		GroupBy(groupByStr) |  | ||||||
|  |  | ||||||
| 	type OrgCount struct { |  | ||||||
| 		organization.Organization `xorm:"extends"` |  | ||||||
| 		OrgCount                  int |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	orgCounts := make([]*OrgCount, 0, 10) |  | ||||||
|  |  | ||||||
| 	if err := sess. |  | ||||||
| 		Asc("`user`.name"). |  | ||||||
| 		Find(&orgCounts); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	orgs := make([]*MinimalOrg, len(orgCounts)) |  | ||||||
| 	for i, orgCount := range orgCounts { |  | ||||||
| 		orgCount.Organization.NumRepos = orgCount.OrgCount |  | ||||||
| 		orgs[i] = &orgCount.Organization |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return orgs, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func removeOrgUser(ctx context.Context, orgID, userID int64) error { | func removeOrgUser(ctx context.Context, orgID, userID int64) error { | ||||||
| 	ou := new(organization.OrgUser) | 	ou := new(organization.OrgUser) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,12 +25,12 @@ import ( | |||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.Repository) (err error) { | func AddRepository(ctx context.Context, t *organization.Team, repo *repo_model.Repository) (err error) { | ||||||
| 	if err = organization.AddTeamRepo(ctx, t.OrgID, t.ID, repo.ID); err != nil { | 	if err = organization.AddTeamRepo(ctx, t.OrgID, t.ID, repo.ID); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if _, err = db.GetEngine(ctx).Incr("num_repos").ID(t.ID).Update(new(organization.Team)); err != nil { | 	if err = organization.IncrTeamRepoNum(ctx, t.ID); err != nil { | ||||||
| 		return fmt.Errorf("update team: %v", err) | 		return fmt.Errorf("update team: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -58,16 +58,15 @@ func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.R | |||||||
| // addAllRepositories adds all repositories to the team. | // addAllRepositories adds all repositories to the team. | ||||||
| // If the team already has some repositories they will be left unchanged. | // If the team already has some repositories they will be left unchanged. | ||||||
| func addAllRepositories(ctx context.Context, t *organization.Team) error { | func addAllRepositories(ctx context.Context, t *organization.Team) error { | ||||||
| 	var orgRepos []repo_model.Repository | 	orgRepos, err := organization.GetOrgRepositories(ctx, t.OrgID) | ||||||
| 	e := db.GetEngine(ctx) | 	if err != nil { | ||||||
| 	if err := e.Where("owner_id = ?", t.OrgID).Find(&orgRepos); err != nil { |  | ||||||
| 		return fmt.Errorf("get org repos: %v", err) | 		return fmt.Errorf("get org repos: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, repo := range orgRepos { | 	for _, repo := range orgRepos { | ||||||
| 		if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) { | 		if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) { | ||||||
| 			if err := addRepository(ctx, t, &repo); err != nil { | 			if err := AddRepository(ctx, t, repo); err != nil { | ||||||
| 				return fmt.Errorf("addRepository: %v", err) | 				return fmt.Errorf("AddRepository: %v", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -90,27 +89,6 @@ func AddAllRepositories(t *organization.Team) (err error) { | |||||||
| 	return committer.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddRepository adds new repository to team of organization. |  | ||||||
| func AddRepository(t *organization.Team, repo *repo_model.Repository) (err error) { |  | ||||||
| 	if repo.OwnerID != t.OrgID { |  | ||||||
| 		return errors.New("Repository does not belong to organization") |  | ||||||
| 	} else if HasRepository(t, repo.ID) { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ctx, committer, err := db.TxContext() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer committer.Close() |  | ||||||
|  |  | ||||||
| 	if err = addRepository(ctx, t, repo); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return committer.Commit() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RemoveAllRepositories removes all repositories from team and recalculates access | // RemoveAllRepositories removes all repositories from team and recalculates access | ||||||
| func RemoveAllRepositories(t *organization.Team) (err error) { | func RemoveAllRepositories(t *organization.Team) (err error) { | ||||||
| 	if t.IncludesAllRepositories { | 	if t.IncludesAllRepositories { | ||||||
|   | |||||||
| @@ -68,25 +68,6 @@ func TestTeam_HasRepository(t *testing.T) { | |||||||
| 	test(2, 5, false) | 	test(2, 5, false) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestTeam_AddRepository(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	testSuccess := func(teamID, repoID int64) { |  | ||||||
| 		team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) |  | ||||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) |  | ||||||
| 		assert.NoError(t, AddRepository(team, repo)) |  | ||||||
| 		unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID}) |  | ||||||
| 		unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID}) |  | ||||||
| 	} |  | ||||||
| 	testSuccess(2, 3) |  | ||||||
| 	testSuccess(2, 5) |  | ||||||
|  |  | ||||||
| 	team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}) |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) |  | ||||||
| 	assert.Error(t, AddRepository(team, repo)) |  | ||||||
| 	unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestTeam_RemoveRepository(t *testing.T) { | func TestTeam_RemoveRepository(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								models/organization/mini_org.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								models/organization/mini_org.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | // Copyright 2022 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 organization | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | 	"code.gitea.io/gitea/models/unit" | ||||||
|  | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // MinimalOrg represents a simple organization with only the needed columns | ||||||
|  | type MinimalOrg = Organization | ||||||
|  |  | ||||||
|  | // GetUserOrgsList returns all organizations the given user has access to | ||||||
|  | func GetUserOrgsList(user *user_model.User) ([]*MinimalOrg, error) { | ||||||
|  | 	schema, err := db.TableInfo(new(user_model.User)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	outputCols := []string{ | ||||||
|  | 		"id", | ||||||
|  | 		"name", | ||||||
|  | 		"full_name", | ||||||
|  | 		"visibility", | ||||||
|  | 		"avatar", | ||||||
|  | 		"avatar_email", | ||||||
|  | 		"use_custom_avatar", | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	groupByCols := &strings.Builder{} | ||||||
|  | 	for _, col := range outputCols { | ||||||
|  | 		fmt.Fprintf(groupByCols, "`%s`.%s,", schema.Name, col) | ||||||
|  | 	} | ||||||
|  | 	groupByStr := groupByCols.String() | ||||||
|  | 	groupByStr = groupByStr[0 : len(groupByStr)-1] | ||||||
|  |  | ||||||
|  | 	sess := db.GetEngine(db.DefaultContext) | ||||||
|  | 	sess = sess.Select(groupByStr+", count(distinct repo_id) as org_count"). | ||||||
|  | 		Table("user"). | ||||||
|  | 		Join("INNER", "team", "`team`.org_id = `user`.id"). | ||||||
|  | 		Join("INNER", "team_user", "`team`.id = `team_user`.team_id"). | ||||||
|  | 		Join("LEFT", builder. | ||||||
|  | 			Select("id as repo_id, owner_id as repo_owner_id"). | ||||||
|  | 			From("repository"). | ||||||
|  | 			Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), "`repository`.repo_owner_id = `team`.org_id"). | ||||||
|  | 		Where("`team_user`.uid = ?", user.ID). | ||||||
|  | 		GroupBy(groupByStr) | ||||||
|  |  | ||||||
|  | 	type OrgCount struct { | ||||||
|  | 		Organization `xorm:"extends"` | ||||||
|  | 		OrgCount     int | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	orgCounts := make([]*OrgCount, 0, 10) | ||||||
|  |  | ||||||
|  | 	if err := sess. | ||||||
|  | 		Asc("`user`.name"). | ||||||
|  | 		Find(&orgCounts); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	orgs := make([]*MinimalOrg, len(orgCounts)) | ||||||
|  | 	for i, orgCount := range orgCounts { | ||||||
|  | 		orgCount.Organization.NumRepos = orgCount.OrgCount | ||||||
|  | 		orgs[i] = &orgCount.Organization | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return orgs, nil | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								models/organization/org_repo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								models/organization/org_repo.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | // Copyright 2022 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 organization | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // GetOrgRepositories get repos belonging to the given organization | ||||||
|  | func GetOrgRepositories(ctx context.Context, orgID int64) ([]*repo_model.Repository, error) { | ||||||
|  | 	var orgRepos []*repo_model.Repository | ||||||
|  | 	return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) | ||||||
|  | } | ||||||
| @@ -359,3 +359,9 @@ func GetRepoTeams(ctx context.Context, repo *repo_model.Repository) (teams []*Te | |||||||
| 		OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END"). | 		OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END"). | ||||||
| 		Find(&teams) | 		Find(&teams) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IncrTeamRepoNum increases the number of repos for the given team by 1 | ||||||
|  | func IncrTeamRepoNum(ctx context.Context, teamID int64) error { | ||||||
|  | 	_, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team)) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|   | |||||||
| @@ -7,13 +7,10 @@ package access_test | |||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" |  | ||||||
| 	perm_model "code.gitea.io/gitea/models/perm" | 	perm_model "code.gitea.io/gitea/models/perm" | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" |  | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
| @@ -128,249 +125,3 @@ func TestRepository_RecalculateAccesses2(t *testing.T) { | |||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, has) | 	assert.False(t, has) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	// public non-organization repo |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) |  | ||||||
| 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) |  | ||||||
|  |  | ||||||
| 	// plain user |  | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) |  | ||||||
| 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// change to collaborator |  | ||||||
| 	assert.NoError(t, models.AddCollaborator(repo, user)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// collaborator |  | ||||||
| 	collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// owner |  | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// admin |  | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	// private non-organization repo |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) |  | ||||||
| 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) |  | ||||||
|  |  | ||||||
| 	// plain user |  | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) |  | ||||||
| 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.False(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// change to collaborator to default write access |  | ||||||
| 	assert.NoError(t, models.AddCollaborator(repo, user)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// owner |  | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// admin |  | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepoPermissionPublicOrgRepo(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	// public organization repo |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) |  | ||||||
| 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) |  | ||||||
|  |  | ||||||
| 	// plain user |  | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) |  | ||||||
| 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// change to collaborator to default write access |  | ||||||
| 	assert.NoError(t, models.AddCollaborator(repo, user)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// org member team owner |  | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// org member team tester |  | ||||||
| 	member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 	} |  | ||||||
| 	assert.True(t, perm.CanWrite(unit.TypeIssues)) |  | ||||||
| 	assert.False(t, perm.CanWrite(unit.TypeCode)) |  | ||||||
|  |  | ||||||
| 	// admin |  | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepoPermissionPrivateOrgRepo(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	// private organization repo |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) |  | ||||||
| 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) |  | ||||||
|  |  | ||||||
| 	// plain user |  | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) |  | ||||||
| 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.False(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// change to collaborator to default write access |  | ||||||
| 	assert.NoError(t, models.AddCollaborator(repo, user)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.False(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// org member team owner |  | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// update team information and then check permission |  | ||||||
| 	team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) |  | ||||||
| 	err = organization.UpdateTeamUnits(team, nil) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// org member team tester |  | ||||||
| 	tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.True(t, perm.CanWrite(unit.TypeIssues)) |  | ||||||
| 	assert.False(t, perm.CanWrite(unit.TypeCode)) |  | ||||||
| 	assert.False(t, perm.CanRead(unit.TypeCode)) |  | ||||||
|  |  | ||||||
| 	// org member team reviewer |  | ||||||
| 	reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.False(t, perm.CanRead(unit.TypeIssues)) |  | ||||||
| 	assert.False(t, perm.CanWrite(unit.TypeCode)) |  | ||||||
| 	assert.True(t, perm.CanRead(unit.TypeCode)) |  | ||||||
|  |  | ||||||
| 	// admin |  | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) |  | ||||||
| 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	for _, unit := range repo.Units { |  | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) |  | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -430,3 +430,17 @@ func IsRepoReader(ctx context.Context, repo *repo_model.Repository, userID int64 | |||||||
| 	} | 	} | ||||||
| 	return db.GetEngine(ctx).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm_model.AccessModeRead).Get(&Access{}) | 	return db.GetEngine(ctx).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm_model.AccessModeRead).Get(&Access{}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CheckRepoUnitUser check whether user could visit the unit of this repository | ||||||
|  | func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool { | ||||||
|  | 	if user != nil && user.IsAdmin { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	perm, err := GetUserRepoPermission(ctx, repo, user) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Error("GetUserRepoPermission: %w", err) | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return perm.CanRead(unitType) | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										169
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								models/repo.go
									
									
									
									
									
								
							| @@ -12,13 +12,13 @@ import ( | |||||||
|  |  | ||||||
| 	_ "image/jpeg" // Needed for jpeg support | 	_ "image/jpeg" // Needed for jpeg support | ||||||
|  |  | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	admin_model "code.gitea.io/gitea/models/admin" | 	admin_model "code.gitea.io/gitea/models/admin" | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" |  | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	project_model "code.gitea.io/gitea/models/project" | 	project_model "code.gitea.io/gitea/models/project" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -27,10 +27,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/webhook" | 	"code.gitea.io/gitea/models/webhook" | ||||||
| 	"code.gitea.io/gitea/modules/lfs" | 	"code.gitea.io/gitea/modules/lfs" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" |  | ||||||
| 	"code.gitea.io/gitea/modules/storage" | 	"code.gitea.io/gitea/modules/storage" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" |  | ||||||
| 	"code.gitea.io/gitea/modules/util" |  | ||||||
|  |  | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
| @@ -40,162 +37,6 @@ func NewRepoContext() { | |||||||
| 	unit.LoadUnitConfig() | 	unit.LoadUnitConfig() | ||||||
| } | } | ||||||
|  |  | ||||||
| // CheckRepoUnitUser check whether user could visit the unit of this repository |  | ||||||
| func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool { |  | ||||||
| 	if user != nil && user.IsAdmin { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	perm, err := access_model.GetUserRepoPermission(ctx, repo, user) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Error("GetUserRepoPermission(): %v", err) |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return perm.CanRead(unitType) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CreateRepoOptions contains the create repository options |  | ||||||
| type CreateRepoOptions struct { |  | ||||||
| 	Name           string |  | ||||||
| 	Description    string |  | ||||||
| 	OriginalURL    string |  | ||||||
| 	GitServiceType api.GitServiceType |  | ||||||
| 	Gitignores     string |  | ||||||
| 	IssueLabels    string |  | ||||||
| 	License        string |  | ||||||
| 	Readme         string |  | ||||||
| 	DefaultBranch  string |  | ||||||
| 	IsPrivate      bool |  | ||||||
| 	IsMirror       bool |  | ||||||
| 	IsTemplate     bool |  | ||||||
| 	AutoInit       bool |  | ||||||
| 	Status         repo_model.RepositoryStatus |  | ||||||
| 	TrustModel     repo_model.TrustModelType |  | ||||||
| 	MirrorInterval string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CreateRepository creates a repository for the user/organization. |  | ||||||
| func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { |  | ||||||
| 	if err = repo_model.IsUsableRepoName(repo.Name); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	has, err := repo_model.IsRepositoryExist(ctx, u, repo.Name) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("IsRepositoryExist: %v", err) |  | ||||||
| 	} else if has { |  | ||||||
| 		return repo_model.ErrRepoAlreadyExist{ |  | ||||||
| 			Uname: u.Name, |  | ||||||
| 			Name:  repo.Name, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	repoPath := repo_model.RepoPath(u.Name, repo.Name) |  | ||||||
| 	isExist, err := util.IsExist(repoPath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if !overwriteOrAdopt && isExist { |  | ||||||
| 		log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) |  | ||||||
| 		return repo_model.ErrRepoFilesAlreadyExist{ |  | ||||||
| 			Uname: u.Name, |  | ||||||
| 			Name:  repo.Name, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = db.Insert(ctx, repo); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// insert units for repo |  | ||||||
| 	units := make([]repo_model.RepoUnit, 0, len(unit.DefaultRepoUnits)) |  | ||||||
| 	for _, tp := range unit.DefaultRepoUnits { |  | ||||||
| 		if tp == unit.TypeIssues { |  | ||||||
| 			units = append(units, repo_model.RepoUnit{ |  | ||||||
| 				RepoID: repo.ID, |  | ||||||
| 				Type:   tp, |  | ||||||
| 				Config: &repo_model.IssuesConfig{ |  | ||||||
| 					EnableTimetracker:                setting.Service.DefaultEnableTimetracking, |  | ||||||
| 					AllowOnlyContributorsToTrackTime: setting.Service.DefaultAllowOnlyContributorsToTrackTime, |  | ||||||
| 					EnableDependencies:               setting.Service.DefaultEnableDependencies, |  | ||||||
| 				}, |  | ||||||
| 			}) |  | ||||||
| 		} else if tp == unit.TypePullRequests { |  | ||||||
| 			units = append(units, repo_model.RepoUnit{ |  | ||||||
| 				RepoID: repo.ID, |  | ||||||
| 				Type:   tp, |  | ||||||
| 				Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle), AllowRebaseUpdate: true}, |  | ||||||
| 			}) |  | ||||||
| 		} else { |  | ||||||
| 			units = append(units, repo_model.RepoUnit{ |  | ||||||
| 				RepoID: repo.ID, |  | ||||||
| 				Type:   tp, |  | ||||||
| 			}) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = db.Insert(ctx, units); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Remember visibility preference. |  | ||||||
| 	u.LastRepoVisibility = repo.IsPrivate |  | ||||||
| 	if err = user_model.UpdateUserCols(ctx, u, "last_repo_visibility"); err != nil { |  | ||||||
| 		return fmt.Errorf("updateUser: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if _, err = db.GetEngine(ctx).Incr("num_repos").ID(u.ID).Update(new(user_model.User)); err != nil { |  | ||||||
| 		return fmt.Errorf("increment user total_repos: %v", err) |  | ||||||
| 	} |  | ||||||
| 	u.NumRepos++ |  | ||||||
|  |  | ||||||
| 	// Give access to all members in teams with access to all repositories. |  | ||||||
| 	if u.IsOrganization() { |  | ||||||
| 		teams, err := organization.FindOrgTeams(ctx, u.ID) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return fmt.Errorf("loadTeams: %v", err) |  | ||||||
| 		} |  | ||||||
| 		for _, t := range teams { |  | ||||||
| 			if t.IncludesAllRepositories { |  | ||||||
| 				if err := addRepository(ctx, t, repo); err != nil { |  | ||||||
| 					return fmt.Errorf("addRepository: %v", err) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if isAdmin, err := access_model.IsUserRepoAdmin(ctx, repo, doer); err != nil { |  | ||||||
| 			return fmt.Errorf("IsUserRepoAdminCtx: %v", err) |  | ||||||
| 		} else if !isAdmin { |  | ||||||
| 			// Make creator repo admin if it wasn't assigned automatically |  | ||||||
| 			if err = addCollaborator(ctx, repo, doer); err != nil { |  | ||||||
| 				return fmt.Errorf("AddCollaborator: %v", err) |  | ||||||
| 			} |  | ||||||
| 			if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil { |  | ||||||
| 				return fmt.Errorf("ChangeCollaborationAccessMode: %v", err) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { |  | ||||||
| 		// Organization automatically called this in addRepository method. |  | ||||||
| 		return fmt.Errorf("recalculateAccesses: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if setting.Service.AutoWatchNewRepos { |  | ||||||
| 		if err = repo_model.WatchRepo(ctx, doer.ID, repo.ID, true); err != nil { |  | ||||||
| 			return fmt.Errorf("watchRepo: %v", err) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err = webhook.CopyDefaultWebhooksToRepo(ctx, repo.ID); err != nil { |  | ||||||
| 		return fmt.Errorf("copyDefaultWebhooksToRepo: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DeleteRepository deletes a repository for a user or organization. | // DeleteRepository deletes a repository for a user or organization. | ||||||
| // make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock) | // make sure if you call this func to close open sessions (sqlite will otherwise get a deadlock) | ||||||
| func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | ||||||
| @@ -279,7 +120,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | |||||||
|  |  | ||||||
| 	if err := db.DeleteBeans(ctx, | 	if err := db.DeleteBeans(ctx, | ||||||
| 		&access_model.Access{RepoID: repo.ID}, | 		&access_model.Access{RepoID: repo.ID}, | ||||||
| 		&Action{RepoID: repo.ID}, | 		&activities_model.Action{RepoID: repo.ID}, | ||||||
| 		&repo_model.Collaboration{RepoID: repoID}, | 		&repo_model.Collaboration{RepoID: repoID}, | ||||||
| 		&issues_model.Comment{RefRepoID: repoID}, | 		&issues_model.Comment{RefRepoID: repoID}, | ||||||
| 		&git_model.CommitStatus{RepoID: repoID}, | 		&git_model.CommitStatus{RepoID: repoID}, | ||||||
| @@ -289,16 +130,16 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | |||||||
| 		&repo_model.LanguageStat{RepoID: repoID}, | 		&repo_model.LanguageStat{RepoID: repoID}, | ||||||
| 		&issues_model.Milestone{RepoID: repoID}, | 		&issues_model.Milestone{RepoID: repoID}, | ||||||
| 		&repo_model.Mirror{RepoID: repoID}, | 		&repo_model.Mirror{RepoID: repoID}, | ||||||
| 		&Notification{RepoID: repoID}, | 		&activities_model.Notification{RepoID: repoID}, | ||||||
| 		&git_model.ProtectedBranch{RepoID: repoID}, | 		&git_model.ProtectedBranch{RepoID: repoID}, | ||||||
| 		&git_model.ProtectedTag{RepoID: repoID}, | 		&git_model.ProtectedTag{RepoID: repoID}, | ||||||
| 		&repo_model.PushMirror{RepoID: repoID}, | 		&repo_model.PushMirror{RepoID: repoID}, | ||||||
| 		&Release{RepoID: repoID}, | 		&repo_model.Release{RepoID: repoID}, | ||||||
| 		&repo_model.RepoIndexerStatus{RepoID: repoID}, | 		&repo_model.RepoIndexerStatus{RepoID: repoID}, | ||||||
| 		&repo_model.Redirect{RedirectRepoID: repoID}, | 		&repo_model.Redirect{RedirectRepoID: repoID}, | ||||||
| 		&repo_model.RepoUnit{RepoID: repoID}, | 		&repo_model.RepoUnit{RepoID: repoID}, | ||||||
| 		&repo_model.Star{RepoID: repoID}, | 		&repo_model.Star{RepoID: repoID}, | ||||||
| 		&Task{RepoID: repoID}, | 		&admin_model.Task{RepoID: repoID}, | ||||||
| 		&repo_model.Watch{RepoID: repoID}, | 		&repo_model.Watch{RepoID: repoID}, | ||||||
| 		&webhook.Webhook{RepoID: repoID}, | 		&webhook.Webhook{RepoID: repoID}, | ||||||
| 	); err != nil { | 	); err != nil { | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package repo | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -14,7 +14,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" |  | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| @@ -23,14 +22,45 @@ import ( | |||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // ErrReleaseAlreadyExist represents a "ReleaseAlreadyExist" kind of error. | ||||||
|  | type ErrReleaseAlreadyExist struct { | ||||||
|  | 	TagName string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsErrReleaseAlreadyExist checks if an error is a ErrReleaseAlreadyExist. | ||||||
|  | func IsErrReleaseAlreadyExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrReleaseAlreadyExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrReleaseAlreadyExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("release tag already exist [tag_name: %s]", err.TagName) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ErrReleaseNotExist represents a "ReleaseNotExist" kind of error. | ||||||
|  | type ErrReleaseNotExist struct { | ||||||
|  | 	ID      int64 | ||||||
|  | 	TagName string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // IsErrReleaseNotExist checks if an error is a ErrReleaseNotExist. | ||||||
|  | func IsErrReleaseNotExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrReleaseNotExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrReleaseNotExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("release tag does not exist [id: %d, tag_name: %s]", err.ID, err.TagName) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Release represents a release of repository. | // Release represents a release of repository. | ||||||
| type Release struct { | type Release struct { | ||||||
| 	ID               int64                  `xorm:"pk autoincr"` | 	ID               int64            `xorm:"pk autoincr"` | ||||||
| 	RepoID           int64                  `xorm:"INDEX UNIQUE(n)"` | 	RepoID           int64            `xorm:"INDEX UNIQUE(n)"` | ||||||
| 	Repo             *repo_model.Repository `xorm:"-"` | 	Repo             *Repository      `xorm:"-"` | ||||||
| 	PublisherID      int64                  `xorm:"INDEX"` | 	PublisherID      int64            `xorm:"INDEX"` | ||||||
| 	Publisher        *user_model.User       `xorm:"-"` | 	Publisher        *user_model.User `xorm:"-"` | ||||||
| 	TagName          string                 `xorm:"INDEX UNIQUE(n)"` | 	TagName          string           `xorm:"INDEX UNIQUE(n)"` | ||||||
| 	OriginalAuthor   string | 	OriginalAuthor   string | ||||||
| 	OriginalAuthorID int64 `xorm:"index"` | 	OriginalAuthorID int64 `xorm:"index"` | ||||||
| 	LowerTagName     string | 	LowerTagName     string | ||||||
| @@ -38,14 +68,14 @@ type Release struct { | |||||||
| 	Title            string | 	Title            string | ||||||
| 	Sha1             string `xorm:"VARCHAR(40)"` | 	Sha1             string `xorm:"VARCHAR(40)"` | ||||||
| 	NumCommits       int64 | 	NumCommits       int64 | ||||||
| 	NumCommitsBehind int64                    `xorm:"-"` | 	NumCommitsBehind int64              `xorm:"-"` | ||||||
| 	Note             string                   `xorm:"TEXT"` | 	Note             string             `xorm:"TEXT"` | ||||||
| 	RenderedNote     string                   `xorm:"-"` | 	RenderedNote     string             `xorm:"-"` | ||||||
| 	IsDraft          bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsDraft          bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsPrerelease     bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsPrerelease     bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsTag            bool                     `xorm:"NOT NULL DEFAULT false"` | 	IsTag            bool               `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	Attachments      []*repo_model.Attachment `xorm:"-"` | 	Attachments      []*Attachment      `xorm:"-"` | ||||||
| 	CreatedUnix      timeutil.TimeStamp       `xorm:"INDEX"` | 	CreatedUnix      timeutil.TimeStamp `xorm:"INDEX"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| @@ -55,7 +85,7 @@ func init() { | |||||||
| func (r *Release) loadAttributes(ctx context.Context) error { | func (r *Release) loadAttributes(ctx context.Context) error { | ||||||
| 	var err error | 	var err error | ||||||
| 	if r.Repo == nil { | 	if r.Repo == nil { | ||||||
| 		r.Repo, err = repo_model.GetRepositoryByIDCtx(ctx, r.RepoID) | 		r.Repo, err = GetRepositoryByIDCtx(ctx, r.RepoID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -116,7 +146,7 @@ func UpdateRelease(ctx context.Context, rel *Release) error { | |||||||
| // AddReleaseAttachments adds a release attachments | // AddReleaseAttachments adds a release attachments | ||||||
| func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { | func AddReleaseAttachments(ctx context.Context, releaseID int64, attachmentUUIDs []string) (err error) { | ||||||
| 	// Check attachments | 	// Check attachments | ||||||
| 	attachments, err := repo_model.GetAttachmentsByUUIDs(ctx, attachmentUUIDs) | 	attachments, err := GetAttachmentsByUUIDs(ctx, attachmentUUIDs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) | 		return fmt.Errorf("GetAttachmentsByUUIDs [uuids: %v]: %v", attachmentUUIDs, err) | ||||||
| 	} | 	} | ||||||
| @@ -279,9 +309,9 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) { | |||||||
| 
 | 
 | ||||||
| 	// Sort | 	// Sort | ||||||
| 	sortedRels := releaseMetaSearch{ID: make([]int64, len(rels)), Rel: make([]*Release, len(rels))} | 	sortedRels := releaseMetaSearch{ID: make([]int64, len(rels)), Rel: make([]*Release, len(rels))} | ||||||
| 	var attachments []*repo_model.Attachment | 	var attachments []*Attachment | ||||||
| 	for index, element := range rels { | 	for index, element := range rels { | ||||||
| 		element.Attachments = []*repo_model.Attachment{} | 		element.Attachments = []*Attachment{} | ||||||
| 		sortedRels.ID[index] = element.ID | 		sortedRels.ID[index] = element.ID | ||||||
| 		sortedRels.Rel[index] = element | 		sortedRels.Rel[index] = element | ||||||
| 	} | 	} | ||||||
| @@ -291,7 +321,7 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) { | |||||||
| 	err = db.GetEngine(ctx). | 	err = db.GetEngine(ctx). | ||||||
| 		Asc("release_id", "name"). | 		Asc("release_id", "name"). | ||||||
| 		In("release_id", sortedRels.ID). | 		In("release_id", sortedRels.ID). | ||||||
| 		Find(&attachments, repo_model.Attachment{}) | 		Find(&attachments, Attachment{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -354,7 +384,7 @@ func UpdateReleasesMigrationsByType(gitServiceType structs.GitServiceType, origi | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // PushUpdateDeleteTagsContext updates a number of delete tags with context | // PushUpdateDeleteTagsContext updates a number of delete tags with context | ||||||
| func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repository, tags []string) error { | func PushUpdateDeleteTagsContext(ctx context.Context, repo *Repository, tags []string) error { | ||||||
| 	if len(tags) == 0 { | 	if len(tags) == 0 { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -384,7 +414,7 @@ func PushUpdateDeleteTagsContext(ctx context.Context, repo *repo_model.Repositor | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // PushUpdateDeleteTag must be called for any push actions to delete tag | // PushUpdateDeleteTag must be called for any push actions to delete tag | ||||||
| func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { | func PushUpdateDeleteTag(repo *Repository, tagName string) error { | ||||||
| 	rel, err := GetRelease(repo.ID, tagName) | 	rel, err := GetRelease(repo.ID, tagName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if IsErrReleaseNotExist(err) { | 		if IsErrReleaseNotExist(err) { | ||||||
| @@ -409,7 +439,7 @@ func PushUpdateDeleteTag(repo *repo_model.Repository, tagName string) error { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SaveOrUpdateTag must be called for any push actions to add tag | // SaveOrUpdateTag must be called for any push actions to add tag | ||||||
| func SaveOrUpdateTag(repo *repo_model.Repository, newRel *Release) error { | func SaveOrUpdateTag(repo *Repository, newRel *Release) error { | ||||||
| 	rel, err := GetRelease(repo.ID, newRel.TagName) | 	rel, err := GetRelease(repo.ID, newRel.TagName) | ||||||
| 	if err != nil && !IsErrReleaseNotExist(err) { | 	if err != nil && !IsErrReleaseNotExist(err) { | ||||||
| 		return fmt.Errorf("GetRelease: %v", err) | 		return fmt.Errorf("GetRelease: %v", err) | ||||||
| @@ -23,6 +23,8 @@ import ( | |||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
|  | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. | // ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo. | ||||||
| @@ -784,3 +786,15 @@ func UpdateRepoIssueNumbers(ctx context.Context, repoID int64, isPull, isClosed | |||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CountNullArchivedRepository counts the number of repositories with is_archived is null | ||||||
|  | func CountNullArchivedRepository() (int64, error) { | ||||||
|  | 	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Count(new(Repository)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FixNullArchivedRepository sets is_archived to false where it is null | ||||||
|  | func FixNullArchivedRepository() (int64, error) { | ||||||
|  | 	return db.GetEngine(db.DefaultContext).Where(builder.IsNull{"is_archived"}).Cols("is_archived").NoAutoTime().Update(&Repository{ | ||||||
|  | 		IsArchived: false, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package repo | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| @@ -20,13 +20,21 @@ import ( | |||||||
| 	gouuid "github.com/google/uuid" | 	gouuid "github.com/google/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| //  ____ ___        .__                    .___ ___________.___.__ | // ErrUploadNotExist represents a "UploadNotExist" kind of error. | ||||||
| // |    |   \______ |  |   _________     __| _/ \_   _____/|   |  |   ____   ______ | type ErrUploadNotExist struct { | ||||||
| // |    |   /\____ \|  |  /  _ \__  \   / __ |   |    __)  |   |  | _/ __ \ /  ___/ | 	ID   int64 | ||||||
| // |    |  / |  |_> >  |_(  <_> ) __ \_/ /_/ |   |     \   |   |  |_\  ___/ \___ \ | 	UUID string | ||||||
| // |______/  |   __/|____/\____(____  /\____ |   \___  /   |___|____/\___  >____  > | } | ||||||
| //           |__|                   \/      \/       \/                  \/     \/ | 
 | ||||||
| // | // IsErrUploadNotExist checks if an error is a ErrUploadNotExist. | ||||||
|  | func IsErrUploadNotExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrUploadNotExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (err ErrUploadNotExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // Upload represent a uploaded file to a repo to be deleted when moved | // Upload represent a uploaded file to a repo to be deleted when moved | ||||||
| type Upload struct { | type Upload struct { | ||||||
| @@ -6,6 +6,7 @@ | |||||||
| package repo | package repo | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"fmt" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| @@ -14,6 +15,51 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error. | ||||||
|  | type ErrWikiAlreadyExist struct { | ||||||
|  | 	Title string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrWikiAlreadyExist checks if an error is an ErrWikiAlreadyExist. | ||||||
|  | func IsErrWikiAlreadyExist(err error) bool { | ||||||
|  | 	_, ok := err.(ErrWikiAlreadyExist) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrWikiAlreadyExist) Error() string { | ||||||
|  | 	return fmt.Sprintf("wiki page already exists [title: %s]", err.Title) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ErrWikiReservedName represents a reserved name error. | ||||||
|  | type ErrWikiReservedName struct { | ||||||
|  | 	Title string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrWikiReservedName checks if an error is an ErrWikiReservedName. | ||||||
|  | func IsErrWikiReservedName(err error) bool { | ||||||
|  | 	_, ok := err.(ErrWikiReservedName) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrWikiReservedName) Error() string { | ||||||
|  | 	return fmt.Sprintf("wiki title is reserved: %s", err.Title) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ErrWikiInvalidFileName represents an invalid wiki file name. | ||||||
|  | type ErrWikiInvalidFileName struct { | ||||||
|  | 	FileName string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsErrWikiInvalidFileName checks if an error is an ErrWikiInvalidFileName. | ||||||
|  | func IsErrWikiInvalidFileName(err error) bool { | ||||||
|  | 	_, ok := err.(ErrWikiInvalidFileName) | ||||||
|  | 	return ok | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (err ErrWikiInvalidFileName) Error() string { | ||||||
|  | 	return fmt.Sprintf("Invalid wiki filename: %s", err.FileName) | ||||||
|  | } | ||||||
|  |  | ||||||
| // WikiCloneLink returns clone URLs of repository wiki. | // WikiCloneLink returns clone URLs of repository wiki. | ||||||
| func (repo *Repository) WikiCloneLink() *CloneLink { | func (repo *Repository) WikiCloneLink() *CloneLink { | ||||||
| 	return repo.cloneLink(true) | 	return repo.cloneLink(true) | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/perm" |  | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -19,42 +18,6 @@ import ( | |||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { |  | ||||||
| 	collaboration := &repo_model.Collaboration{ |  | ||||||
| 		RepoID: repo.ID, |  | ||||||
| 		UserID: u.ID, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	has, err := db.GetByBean(ctx, collaboration) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else if has { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	collaboration.Mode = perm.AccessModeWrite |  | ||||||
|  |  | ||||||
| 	if err = db.Insert(ctx, collaboration); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return access_model.RecalculateUserAccess(ctx, repo, u.ID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddCollaborator adds new collaboration to a repository with default access mode. |  | ||||||
| func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error { |  | ||||||
| 	ctx, committer, err := db.TxContext() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer committer.Close() |  | ||||||
|  |  | ||||||
| 	if err := addCollaborator(ctx, repo, u); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return committer.Commit() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DeleteCollaboration removes collaboration relation between the user and repository. | // DeleteCollaboration removes collaboration relation between the user and repository. | ||||||
| func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { | func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { | ||||||
| 	collaboration := &repo_model.Collaboration{ | 	collaboration := &repo_model.Collaboration{ | ||||||
|   | |||||||
| @@ -10,26 +10,10 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" |  | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestRepository_AddCollaborator(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	testSuccess := func(repoID, userID int64) { |  | ||||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) |  | ||||||
| 		assert.NoError(t, repo.GetOwner(db.DefaultContext)) |  | ||||||
| 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) |  | ||||||
| 		assert.NoError(t, AddCollaborator(repo, user)) |  | ||||||
| 		unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) |  | ||||||
| 	} |  | ||||||
| 	testSuccess(1, 4) |  | ||||||
| 	testSuccess(1, 4) |  | ||||||
| 	testSuccess(3, 4) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepository_DeleteCollaboration(t *testing.T) { | func TestRepository_DeleteCollaboration(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -327,8 +327,8 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo | |||||||
| 		} | 		} | ||||||
| 		for _, t := range teams { | 		for _, t := range teams { | ||||||
| 			if t.IncludesAllRepositories { | 			if t.IncludesAllRepositories { | ||||||
| 				if err := addRepository(ctx, t, repo); err != nil { | 				if err := AddRepository(ctx, t, repo); err != nil { | ||||||
| 					return fmt.Errorf("addRepository: %v", err) | 					return fmt.Errorf("AddRepository: %v", err) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
|  |  | ||||||
| 	_ "image/jpeg" // Needed for jpeg support | 	_ "image/jpeg" // Needed for jpeg support | ||||||
|  |  | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| 	auth_model "code.gitea.io/gitea/models/auth" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| @@ -70,14 +71,14 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) | |||||||
| 	// ***** END: Follow ***** | 	// ***** END: Follow ***** | ||||||
|  |  | ||||||
| 	if err = db.DeleteBeans(ctx, | 	if err = db.DeleteBeans(ctx, | ||||||
| 		&AccessToken{UID: u.ID}, | 		&auth_model.AccessToken{UID: u.ID}, | ||||||
| 		&repo_model.Collaboration{UserID: u.ID}, | 		&repo_model.Collaboration{UserID: u.ID}, | ||||||
| 		&access_model.Access{UserID: u.ID}, | 		&access_model.Access{UserID: u.ID}, | ||||||
| 		&repo_model.Watch{UserID: u.ID}, | 		&repo_model.Watch{UserID: u.ID}, | ||||||
| 		&repo_model.Star{UID: u.ID}, | 		&repo_model.Star{UID: u.ID}, | ||||||
| 		&user_model.Follow{UserID: u.ID}, | 		&user_model.Follow{UserID: u.ID}, | ||||||
| 		&user_model.Follow{FollowID: u.ID}, | 		&user_model.Follow{FollowID: u.ID}, | ||||||
| 		&Action{UserID: u.ID}, | 		&activities_model.Action{UserID: u.ID}, | ||||||
| 		&issues_model.IssueUser{UID: u.ID}, | 		&issues_model.IssueUser{UID: u.ID}, | ||||||
| 		&user_model.EmailAddress{UID: u.ID}, | 		&user_model.EmailAddress{UID: u.ID}, | ||||||
| 		&user_model.UserOpenID{UID: u.ID}, | 		&user_model.UserOpenID{UID: u.ID}, | ||||||
|   | |||||||
| @@ -1317,6 +1317,16 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool { | |||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CountWrongUserType count OrgUser who have wrong type | ||||||
|  | func CountWrongUserType() (int64, error) { | ||||||
|  | 	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Count(new(User)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FixWrongUserType fix OrgUser who have wrong type | ||||||
|  | func FixWrongUserType() (int64, error) { | ||||||
|  | 	return db.GetEngine(db.DefaultContext).Where(builder.Eq{"type": 0}.And(builder.Neq{"num_teams": 0})).Cols("type").NoAutoTime().Update(&User{Type: 1}) | ||||||
|  | } | ||||||
|  |  | ||||||
| func GetOrderByName() string { | func GetOrderByName() string { | ||||||
| 	if setting.UI.DefaultShowFullName { | 	if setting.UI.DefaultShowFullName { | ||||||
| 		return "full_name, name" | 		return "full_name, name" | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								models/user/user_update.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								models/user/user_update.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | // Copyright 2022 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 user | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func IncrUserRepoNum(ctx context.Context, userID int64) error { | ||||||
|  | 	_, err := db.GetEngine(ctx).Incr("num_repos").ID(userID).Update(new(User)) | ||||||
|  | 	return err | ||||||
|  | } | ||||||
| @@ -118,7 +118,8 @@ type CanCommitToBranchResults struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // CanCommitToBranch returns true if repository is editable and user has proper access level | // CanCommitToBranch returns true if repository is editable and user has proper access level | ||||||
| //   and branch is not protected for push | // | ||||||
|  | // and branch is not protected for push | ||||||
| func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) { | func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) { | ||||||
| 	protectedBranch, err := git_model.GetProtectedBranchBy(ctx, r.Repository.ID, r.BranchName) | 	protectedBranch, err := git_model.GetProtectedBranchBy(ctx, r.Repository.ID, r.BranchName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -523,14 +524,14 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { | |||||||
| 		ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL | 		ctx.Data["RepoExternalIssuesLink"] = unit.ExternalTrackerConfig().ExternalTrackerURL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{ | 	ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{ | ||||||
| 		IncludeTags: true, | 		IncludeTags: true, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetReleaseCountByRepoID", err) | 		ctx.ServerError("GetReleaseCountByRepoID", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["NumReleases"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{}) | 	ctx.Data["NumReleases"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetReleaseCountByRepoID", err) | 		ctx.ServerError("GetReleaseCountByRepoID", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -7,17 +7,17 @@ package convert | |||||||
| import ( | import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ToNotificationThread convert a Notification to api.NotificationThread | // ToNotificationThread convert a Notification to api.NotificationThread | ||||||
| func ToNotificationThread(n *models.Notification) *api.NotificationThread { | func ToNotificationThread(n *activities_model.Notification) *api.NotificationThread { | ||||||
| 	result := &api.NotificationThread{ | 	result := &api.NotificationThread{ | ||||||
| 		ID:        n.ID, | 		ID:        n.ID, | ||||||
| 		Unread:    !(n.Status == models.NotificationStatusRead || n.Status == models.NotificationStatusPinned), | 		Unread:    !(n.Status == activities_model.NotificationStatusRead || n.Status == activities_model.NotificationStatusPinned), | ||||||
| 		Pinned:    n.Status == models.NotificationStatusPinned, | 		Pinned:    n.Status == activities_model.NotificationStatusPinned, | ||||||
| 		UpdatedAt: n.UpdatedUnix.AsTime(), | 		UpdatedAt: n.UpdatedUnix.AsTime(), | ||||||
| 		URL:       n.APIURL(), | 		URL:       n.APIURL(), | ||||||
| 	} | 	} | ||||||
| @@ -34,7 +34,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { | |||||||
|  |  | ||||||
| 	// handle Subject | 	// handle Subject | ||||||
| 	switch n.Source { | 	switch n.Source { | ||||||
| 	case models.NotificationSourceIssue: | 	case activities_model.NotificationSourceIssue: | ||||||
| 		result.Subject = &api.NotificationSubject{Type: api.NotifySubjectIssue} | 		result.Subject = &api.NotificationSubject{Type: api.NotifySubjectIssue} | ||||||
| 		if n.Issue != nil { | 		if n.Issue != nil { | ||||||
| 			result.Subject.Title = n.Issue.Title | 			result.Subject.Title = n.Issue.Title | ||||||
| @@ -47,7 +47,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { | |||||||
| 				result.Subject.LatestCommentHTMLURL = comment.HTMLURL() | 				result.Subject.LatestCommentHTMLURL = comment.HTMLURL() | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	case models.NotificationSourcePullRequest: | 	case activities_model.NotificationSourcePullRequest: | ||||||
| 		result.Subject = &api.NotificationSubject{Type: api.NotifySubjectPull} | 		result.Subject = &api.NotificationSubject{Type: api.NotifySubjectPull} | ||||||
| 		if n.Issue != nil { | 		if n.Issue != nil { | ||||||
| 			result.Subject.Title = n.Issue.Title | 			result.Subject.Title = n.Issue.Title | ||||||
| @@ -65,7 +65,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { | |||||||
| 				result.Subject.State = "merged" | 				result.Subject.State = "merged" | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	case models.NotificationSourceCommit: | 	case activities_model.NotificationSourceCommit: | ||||||
| 		url := n.Repository.HTMLURL() + "/commit/" + url.PathEscape(n.CommitID) | 		url := n.Repository.HTMLURL() + "/commit/" + url.PathEscape(n.CommitID) | ||||||
| 		result.Subject = &api.NotificationSubject{ | 		result.Subject = &api.NotificationSubject{ | ||||||
| 			Type:    api.NotifySubjectCommit, | 			Type:    api.NotifySubjectCommit, | ||||||
| @@ -73,7 +73,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { | |||||||
| 			URL:     url, | 			URL:     url, | ||||||
| 			HTMLURL: url, | 			HTMLURL: url, | ||||||
| 		} | 		} | ||||||
| 	case models.NotificationSourceRepository: | 	case activities_model.NotificationSourceRepository: | ||||||
| 		result.Subject = &api.NotificationSubject{ | 		result.Subject = &api.NotificationSubject{ | ||||||
| 			Type:  api.NotifySubjectRepository, | 			Type:  api.NotifySubjectRepository, | ||||||
| 			Title: n.Repository.FullName(), | 			Title: n.Repository.FullName(), | ||||||
| @@ -87,7 +87,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ToNotifications convert list of Notification to api.NotificationThread list | // ToNotifications convert list of Notification to api.NotificationThread list | ||||||
| func ToNotifications(nl models.NotificationList) []*api.NotificationThread { | func ToNotifications(nl activities_model.NotificationList) []*api.NotificationThread { | ||||||
| 	result := make([]*api.NotificationThread, 0, len(nl)) | 	result := make([]*api.NotificationThread, 0, len(nl)) | ||||||
| 	for _, n := range nl { | 	for _, n := range nl { | ||||||
| 		result = append(result, ToNotificationThread(n)) | 		result = append(result, ToNotificationThread(n)) | ||||||
|   | |||||||
| @@ -5,13 +5,12 @@ | |||||||
| package convert | package convert | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ToRelease convert a models.Release to api.Release | // ToRelease convert a repo_model.Release to api.Release | ||||||
| func ToRelease(r *models.Release) *api.Release { | func ToRelease(r *repo_model.Release) *api.Release { | ||||||
| 	assets := make([]*api.Attachment, 0) | 	assets := make([]*api.Attachment, 0) | ||||||
| 	for _, att := range r.Attachments { | 	for _, att := range r.Attachments { | ||||||
| 		assets = append(assets, ToReleaseAttachment(att)) | 		assets = append(assets, ToReleaseAttachment(att)) | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ func innerToRepo(repo *repo_model.Repository, mode perm.AccessMode, isParent boo | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	numReleases, _ := models.GetReleaseCountByRepoID(repo.ID, models.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false}) | 	numReleases, _ := repo_model.GetReleaseCountByRepoID(repo.ID, repo_model.FindReleasesOptions{IncludeDrafts: false, IncludeTags: false}) | ||||||
|  |  | ||||||
| 	mirrorInterval := "" | 	mirrorInterval := "" | ||||||
| 	var mirrorUpdated time.Time | 	var mirrorUpdated time.Time | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ package doctor | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/migrations" | 	"code.gitea.io/gitea/models/migrations" | ||||||
| @@ -121,8 +121,8 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er | |||||||
| 		// find null archived repositories | 		// find null archived repositories | ||||||
| 		{ | 		{ | ||||||
| 			Name:         "Repositories with is_archived IS NULL", | 			Name:         "Repositories with is_archived IS NULL", | ||||||
| 			Counter:      models.CountNullArchivedRepository, | 			Counter:      repo_model.CountNullArchivedRepository, | ||||||
| 			Fixer:        models.FixNullArchivedRepository, | 			Fixer:        repo_model.FixNullArchivedRepository, | ||||||
| 			FixedMessage: "Fixed", | 			FixedMessage: "Fixed", | ||||||
| 		}, | 		}, | ||||||
| 		// find label comments with empty labels | 		// find label comments with empty labels | ||||||
| @@ -148,8 +148,8 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er | |||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			Name:         "Action with created_unix set as an empty string", | 			Name:         "Action with created_unix set as an empty string", | ||||||
| 			Counter:      models.CountActionCreatedUnixString, | 			Counter:      activities_model.CountActionCreatedUnixString, | ||||||
| 			Fixer:        models.FixActionCreatedUnixString, | 			Fixer:        activities_model.FixActionCreatedUnixString, | ||||||
| 			FixedMessage: "Set to zero", | 			FixedMessage: "Set to zero", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -7,19 +7,19 @@ package doctor | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error { | func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error { | ||||||
| 	count, err := models.CountWrongUserType() | 	count, err := user_model.CountWrongUserType() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		logger.Critical("Error: %v whilst counting wrong user types") | 		logger.Critical("Error: %v whilst counting wrong user types") | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if count > 0 { | 	if count > 0 { | ||||||
| 		if autofix { | 		if autofix { | ||||||
| 			if count, err = models.FixWrongUserType(); err != nil { | 			if count, err = user_model.FixWrongUserType(); err != nil { | ||||||
| 				logger.Critical("Error: %v whilst fixing wrong user types") | 				logger.Critical("Error: %v whilst fixing wrong user types") | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	"code.gitea.io/gitea/modules/graceful" | 	"code.gitea.io/gitea/modules/graceful" | ||||||
| @@ -72,7 +72,7 @@ loop: | |||||||
|  |  | ||||||
| 			now := timeutil.TimeStampNow().Add(-2) | 			now := timeutil.TimeStampNow().Add(-2) | ||||||
|  |  | ||||||
| 			uidCounts, err := models.GetUIDsAndNotificationCounts(then, now) | 			uidCounts, err := activities_model.GetUIDsAndNotificationCounts(then, now) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("Unable to get UIDcounts: %v", err) | 				log.Error("Unable to get UIDcounts: %v", err) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| package metrics | package metrics | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
|  |  | ||||||
| 	"github.com/prometheus/client_golang/prometheus" | 	"github.com/prometheus/client_golang/prometheus" | ||||||
| ) | ) | ||||||
| @@ -225,7 +225,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) { | |||||||
|  |  | ||||||
| // Collect returns the metrics with values | // Collect returns the metrics with values | ||||||
| func (c Collector) Collect(ch chan<- prometheus.Metric) { | func (c Collector) Collect(ch chan<- prometheus.Metric) { | ||||||
| 	stats := models.GetStatistic() | 	stats := activities_model.GetStatistic() | ||||||
|  |  | ||||||
| 	ch <- prometheus.MustNewConstMetric( | 	ch <- prometheus.MustNewConstMetric( | ||||||
| 		c.Accesses, | 		c.Accesses, | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
| 	"path" | 	"path" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -45,10 +45,10 @@ func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*u | |||||||
| 	} | 	} | ||||||
| 	repo := issue.Repo | 	repo := issue.Repo | ||||||
|  |  | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: issue.Poster.ID, | 		ActUserID: issue.Poster.ID, | ||||||
| 		ActUser:   issue.Poster, | 		ActUser:   issue.Poster, | ||||||
| 		OpType:    models.ActionCreateIssue, | 		OpType:    activities_model.ActionCreateIssue, | ||||||
| 		Content:   fmt.Sprintf("%d|%s", issue.Index, issue.Title), | 		Content:   fmt.Sprintf("%d|%s", issue.Index, issue.Title), | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| @@ -62,7 +62,7 @@ func (a *actionNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*u | |||||||
| func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { | func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { | ||||||
| 	// Compose comment action, could be plain comment, close or reopen issue/pull request. | 	// Compose comment action, could be plain comment, close or reopen issue/pull request. | ||||||
| 	// This object will be used to notify watchers in the end of function. | 	// This object will be used to notify watchers in the end of function. | ||||||
| 	act := &models.Action{ | 	act := &activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		Content:   fmt.Sprintf("%d|%s", issue.Index, ""), | 		Content:   fmt.Sprintf("%d|%s", issue.Index, ""), | ||||||
| @@ -74,19 +74,19 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *i | |||||||
| 	} | 	} | ||||||
| 	// Check comment type. | 	// Check comment type. | ||||||
| 	if closeOrReopen { | 	if closeOrReopen { | ||||||
| 		act.OpType = models.ActionCloseIssue | 		act.OpType = activities_model.ActionCloseIssue | ||||||
| 		if issue.IsPull { | 		if issue.IsPull { | ||||||
| 			act.OpType = models.ActionClosePullRequest | 			act.OpType = activities_model.ActionClosePullRequest | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		act.OpType = models.ActionReopenIssue | 		act.OpType = activities_model.ActionReopenIssue | ||||||
| 		if issue.IsPull { | 		if issue.IsPull { | ||||||
| 			act.OpType = models.ActionReopenPullRequest | 			act.OpType = activities_model.ActionReopenPullRequest | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Notify watchers for whatever action comes in, ignore if no action type. | 	// Notify watchers for whatever action comes in, ignore if no action type. | ||||||
| 	if err := models.NotifyWatchers(act); err != nil { | 	if err := activities_model.NotifyWatchers(act); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		log.Error("NotifyWatchers: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -95,7 +95,7 @@ func (a *actionNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *i | |||||||
| func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, | func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, | ||||||
| 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, | 	issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, | ||||||
| ) { | ) { | ||||||
| 	act := &models.Action{ | 	act := &activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		RepoID:    issue.Repo.ID, | 		RepoID:    issue.Repo.ID, | ||||||
| @@ -116,13 +116,13 @@ func (a *actionNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *r | |||||||
| 	act.Content = fmt.Sprintf("%d|%s", issue.Index, truncatedContent) | 	act.Content = fmt.Sprintf("%d|%s", issue.Index, truncatedContent) | ||||||
|  |  | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		act.OpType = models.ActionCommentPull | 		act.OpType = activities_model.ActionCommentPull | ||||||
| 	} else { | 	} else { | ||||||
| 		act.OpType = models.ActionCommentIssue | 		act.OpType = activities_model.ActionCommentIssue | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Notify watchers for whatever action comes in, ignore if no action type. | 	// Notify watchers for whatever action comes in, ignore if no action type. | ||||||
| 	if err := models.NotifyWatchers(act); err != nil { | 	if err := activities_model.NotifyWatchers(act); err != nil { | ||||||
| 		log.Error("NotifyWatchers: %v", err) | 		log.Error("NotifyWatchers: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -141,10 +141,10 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, me | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: pull.Issue.Poster.ID, | 		ActUserID: pull.Issue.Poster.ID, | ||||||
| 		ActUser:   pull.Issue.Poster, | 		ActUser:   pull.Issue.Poster, | ||||||
| 		OpType:    models.ActionCreatePullRequest, | 		OpType:    activities_model.ActionCreatePullRequest, | ||||||
| 		Content:   fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title), | 		Content:   fmt.Sprintf("%d|%s", pull.Issue.Index, pull.Issue.Title), | ||||||
| 		RepoID:    pull.Issue.Repo.ID, | 		RepoID:    pull.Issue.Repo.ID, | ||||||
| 		Repo:      pull.Issue.Repo, | 		Repo:      pull.Issue.Repo, | ||||||
| @@ -155,10 +155,10 @@ func (a *actionNotifier) NotifyNewPullRequest(pull *issues_model.PullRequest, me | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) { | func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *repo_model.Repository, oldRepoName string) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionRenameRepo, | 		OpType:    activities_model.ActionRenameRepo, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -169,10 +169,10 @@ func (a *actionNotifier) NotifyRenameRepository(doer *user_model.User, repo *rep | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) { | func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionTransferRepo, | 		OpType:    activities_model.ActionTransferRepo, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -183,10 +183,10 @@ func (a *actionNotifier) NotifyTransferRepository(doer *user_model.User, repo *r | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) { | func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo *repo_model.Repository) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionCreateRepo, | 		OpType:    activities_model.ActionCreateRepo, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -196,10 +196,10 @@ func (a *actionNotifier) NotifyCreateRepository(doer, u *user_model.User, repo * | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) { | func (a *actionNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionCreateRepo, | 		OpType:    activities_model.ActionCreateRepo, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -221,15 +221,15 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	actions := make([]*models.Action, 0, 10) | 	actions := make([]*activities_model.Action, 0, 10) | ||||||
| 	for _, lines := range review.CodeComments { | 	for _, lines := range review.CodeComments { | ||||||
| 		for _, comments := range lines { | 		for _, comments := range lines { | ||||||
| 			for _, comm := range comments { | 			for _, comm := range comments { | ||||||
| 				actions = append(actions, &models.Action{ | 				actions = append(actions, &activities_model.Action{ | ||||||
| 					ActUserID: review.Reviewer.ID, | 					ActUserID: review.Reviewer.ID, | ||||||
| 					ActUser:   review.Reviewer, | 					ActUser:   review.Reviewer, | ||||||
| 					Content:   fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]), | 					Content:   fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comm.Content, "\n")[0]), | ||||||
| 					OpType:    models.ActionCommentPull, | 					OpType:    activities_model.ActionCommentPull, | ||||||
| 					RepoID:    review.Issue.RepoID, | 					RepoID:    review.Issue.RepoID, | ||||||
| 					Repo:      review.Issue.Repo, | 					Repo:      review.Issue.Repo, | ||||||
| 					IsPrivate: review.Issue.Repo.IsPrivate, | 					IsPrivate: review.Issue.Repo.IsPrivate, | ||||||
| @@ -241,7 +241,7 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if review.Type != issues_model.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { | 	if review.Type != issues_model.ReviewTypeComment || strings.TrimSpace(comment.Content) != "" { | ||||||
| 		action := &models.Action{ | 		action := &activities_model.Action{ | ||||||
| 			ActUserID: review.Reviewer.ID, | 			ActUserID: review.Reviewer.ID, | ||||||
| 			ActUser:   review.Reviewer, | 			ActUser:   review.Reviewer, | ||||||
| 			Content:   fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]), | 			Content:   fmt.Sprintf("%d|%s", review.Issue.Index, strings.Split(comment.Content, "\n")[0]), | ||||||
| @@ -254,26 +254,26 @@ func (a *actionNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r | |||||||
|  |  | ||||||
| 		switch review.Type { | 		switch review.Type { | ||||||
| 		case issues_model.ReviewTypeApprove: | 		case issues_model.ReviewTypeApprove: | ||||||
| 			action.OpType = models.ActionApprovePullRequest | 			action.OpType = activities_model.ActionApprovePullRequest | ||||||
| 		case issues_model.ReviewTypeReject: | 		case issues_model.ReviewTypeReject: | ||||||
| 			action.OpType = models.ActionRejectPullRequest | 			action.OpType = activities_model.ActionRejectPullRequest | ||||||
| 		default: | 		default: | ||||||
| 			action.OpType = models.ActionCommentPull | 			action.OpType = activities_model.ActionCommentPull | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		actions = append(actions, action) | 		actions = append(actions, action) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NotifyWatchersActions(actions); err != nil { | 	if err := activities_model.NotifyWatchersActions(actions); err != nil { | ||||||
| 		log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err) | 		log.Error("notify watchers '%d/%d': %v", review.Reviewer.ID, review.Issue.RepoID, err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { | func (*actionNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer *user_model.User) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionMergePullRequest, | 		OpType:    activities_model.ActionMergePullRequest, | ||||||
| 		Content:   fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title), | 		Content:   fmt.Sprintf("%d|%s", pr.Issue.Index, pr.Issue.Title), | ||||||
| 		RepoID:    pr.Issue.Repo.ID, | 		RepoID:    pr.Issue.Repo.ID, | ||||||
| 		Repo:      pr.Issue.Repo, | 		Repo:      pr.Issue.Repo, | ||||||
| @@ -288,10 +288,10 @@ func (*actionNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *i | |||||||
| 	if len(review.OriginalAuthor) > 0 { | 	if len(review.OriginalAuthor) > 0 { | ||||||
| 		reviewerName = review.OriginalAuthor | 		reviewerName = review.OriginalAuthor | ||||||
| 	} | 	} | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    models.ActionPullReviewDismissed, | 		OpType:    activities_model.ActionPullReviewDismissed, | ||||||
| 		Content:   fmt.Sprintf("%d|%s|%s", review.Issue.Index, reviewerName, comment.Content), | 		Content:   fmt.Sprintf("%d|%s|%s", review.Issue.Index, reviewerName, comment.Content), | ||||||
| 		RepoID:    review.Issue.Repo.ID, | 		RepoID:    review.Issue.Repo.ID, | ||||||
| 		Repo:      review.Issue.Repo, | 		Repo:      review.Issue.Repo, | ||||||
| @@ -310,19 +310,19 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opType := models.ActionCommitRepo | 	opType := activities_model.ActionCommitRepo | ||||||
|  |  | ||||||
| 	// Check it's tag push or branch. | 	// Check it's tag push or branch. | ||||||
| 	if opts.IsTag() { | 	if opts.IsTag() { | ||||||
| 		opType = models.ActionPushTag | 		opType = activities_model.ActionPushTag | ||||||
| 		if opts.IsDelRef() { | 		if opts.IsDelRef() { | ||||||
| 			opType = models.ActionDeleteTag | 			opType = activities_model.ActionDeleteTag | ||||||
| 		} | 		} | ||||||
| 	} else if opts.IsDelRef() { | 	} else if opts.IsDelRef() { | ||||||
| 		opType = models.ActionDeleteBranch | 		opType = activities_model.ActionDeleteBranch | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = models.NotifyWatchers(&models.Action{ | 	if err = activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: pusher.ID, | 		ActUserID: pusher.ID, | ||||||
| 		ActUser:   pusher, | 		ActUser:   pusher, | ||||||
| 		OpType:    opType, | 		OpType:    opType, | ||||||
| @@ -337,12 +337,12 @@ func (a *actionNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_m | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { | func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { | ||||||
| 	opType := models.ActionCommitRepo | 	opType := activities_model.ActionCommitRepo | ||||||
| 	if refType == "tag" { | 	if refType == "tag" { | ||||||
| 		// has sent same action in `NotifyPushCommits`, so skip it. | 		// has sent same action in `NotifyPushCommits`, so skip it. | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    opType, | 		OpType:    opType, | ||||||
| @@ -356,12 +356,12 @@ func (a *actionNotifier) NotifyCreateRef(doer *user_model.User, repo *repo_model | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { | func (a *actionNotifier) NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { | ||||||
| 	opType := models.ActionDeleteBranch | 	opType := activities_model.ActionDeleteBranch | ||||||
| 	if refType == "tag" { | 	if refType == "tag" { | ||||||
| 		// has sent same action in `NotifyPushCommits`, so skip it. | 		// has sent same action in `NotifyPushCommits`, so skip it. | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: doer.ID, | 		ActUserID: doer.ID, | ||||||
| 		ActUser:   doer, | 		ActUser:   doer, | ||||||
| 		OpType:    opType, | 		OpType:    opType, | ||||||
| @@ -381,10 +381,10 @@ func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *re | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: repo.OwnerID, | 		ActUserID: repo.OwnerID, | ||||||
| 		ActUser:   repo.MustOwner(), | 		ActUser:   repo.MustOwner(), | ||||||
| 		OpType:    models.ActionMirrorSyncPush, | 		OpType:    activities_model.ActionMirrorSyncPush, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -396,10 +396,10 @@ func (a *actionNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *re | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { | func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: repo.OwnerID, | 		ActUserID: repo.OwnerID, | ||||||
| 		ActUser:   repo.MustOwner(), | 		ActUser:   repo.MustOwner(), | ||||||
| 		OpType:    models.ActionMirrorSyncCreate, | 		OpType:    activities_model.ActionMirrorSyncCreate, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -410,10 +410,10 @@ func (a *actionNotifier) NotifySyncCreateRef(doer *user_model.User, repo *repo_m | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { | func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) { | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: repo.OwnerID, | 		ActUserID: repo.OwnerID, | ||||||
| 		ActUser:   repo.MustOwner(), | 		ActUser:   repo.MustOwner(), | ||||||
| 		OpType:    models.ActionMirrorSyncDelete, | 		OpType:    activities_model.ActionMirrorSyncDelete, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| 		Repo:      repo, | 		Repo:      repo, | ||||||
| 		IsPrivate: repo.IsPrivate, | 		IsPrivate: repo.IsPrivate, | ||||||
| @@ -423,15 +423,15 @@ func (a *actionNotifier) NotifySyncDeleteRef(doer *user_model.User, repo *repo_m | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (a *actionNotifier) NotifyNewRelease(rel *models.Release) { | func (a *actionNotifier) NotifyNewRelease(rel *repo_model.Release) { | ||||||
| 	if err := rel.LoadAttributes(); err != nil { | 	if err := rel.LoadAttributes(); err != nil { | ||||||
| 		log.Error("NotifyNewRelease: %v", err) | 		log.Error("NotifyNewRelease: %v", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err := models.NotifyWatchers(&models.Action{ | 	if err := activities_model.NotifyWatchers(&activities_model.Action{ | ||||||
| 		ActUserID: rel.PublisherID, | 		ActUserID: rel.PublisherID, | ||||||
| 		ActUser:   rel.Publisher, | 		ActUser:   rel.Publisher, | ||||||
| 		OpType:    models.ActionPublishRelease, | 		OpType:    activities_model.ActionPublishRelease, | ||||||
| 		RepoID:    rel.RepoID, | 		RepoID:    rel.RepoID, | ||||||
| 		Repo:      rel.Repo, | 		Repo:      rel.Repo, | ||||||
| 		IsPrivate: rel.Repo.IsPrivate, | 		IsPrivate: rel.Repo.IsPrivate, | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -35,8 +35,8 @@ func TestRenameRepoAction(t *testing.T) { | |||||||
| 	repo.Name = newRepoName | 	repo.Name = newRepoName | ||||||
| 	repo.LowerName = strings.ToLower(newRepoName) | 	repo.LowerName = strings.ToLower(newRepoName) | ||||||
|  |  | ||||||
| 	actionBean := &models.Action{ | 	actionBean := &activities_model.Action{ | ||||||
| 		OpType:    models.ActionRenameRepo, | 		OpType:    activities_model.ActionRenameRepo, | ||||||
| 		ActUserID: user.ID, | 		ActUserID: user.ID, | ||||||
| 		ActUser:   user, | 		ActUser:   user, | ||||||
| 		RepoID:    repo.ID, | 		RepoID:    repo.ID, | ||||||
| @@ -49,5 +49,5 @@ func TestRenameRepoAction(t *testing.T) { | |||||||
| 	NewNotifier().NotifyRenameRepository(user, repo, oldRepoName) | 	NewNotifier().NotifyRenameRepository(user, repo, oldRepoName) | ||||||
|  |  | ||||||
| 	unittest.AssertExistsAndLoadBean(t, actionBean) | 	unittest.AssertExistsAndLoadBean(t, actionBean) | ||||||
| 	unittest.CheckConsistencyFor(t, &models.Action{}) | 	unittest.CheckConsistencyFor(t, &activities_model.Action{}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| package base | package base | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -46,9 +45,9 @@ type Notifier interface { | |||||||
| 		issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) | 		issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User) | ||||||
| 	NotifyUpdateComment(*user_model.User, *issues_model.Comment, string) | 	NotifyUpdateComment(*user_model.User, *issues_model.Comment, string) | ||||||
| 	NotifyDeleteComment(*user_model.User, *issues_model.Comment) | 	NotifyDeleteComment(*user_model.User, *issues_model.Comment) | ||||||
| 	NotifyNewRelease(rel *models.Release) | 	NotifyNewRelease(rel *repo_model.Release) | ||||||
| 	NotifyUpdateRelease(doer *user_model.User, rel *models.Release) | 	NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) | ||||||
| 	NotifyDeleteRelease(doer *user_model.User, rel *models.Release) | 	NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) | ||||||
| 	NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) | 	NotifyPushCommits(pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) | ||||||
| 	NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) | 	NotifyCreateRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName, refID string) | ||||||
| 	NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) | 	NotifyDeleteRef(doer *user_model.User, repo *repo_model.Repository, refType, refFullName string) | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| package base | package base | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -80,15 +79,15 @@ func (*NullNotifier) NotifyDeleteComment(doer *user_model.User, c *issues_model. | |||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyNewRelease places a place holder function | // NotifyNewRelease places a place holder function | ||||||
| func (*NullNotifier) NotifyNewRelease(rel *models.Release) { | func (*NullNotifier) NotifyNewRelease(rel *repo_model.Release) { | ||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyUpdateRelease places a place holder function | // NotifyUpdateRelease places a place holder function | ||||||
| func (*NullNotifier) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { | func (*NullNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyDeleteRelease places a place holder function | // NotifyDeleteRelease places a place holder function | ||||||
| func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { | func (*NullNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyIssueChangeMilestone places a place holder function | // NotifyIssueChangeMilestone places a place holder function | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ package mail | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -35,15 +35,15 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyCreateIssueComment Issue[%d] #%d in [%d]", issue.ID, issue.Index, issue.RepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	var act models.ActionType | 	var act activities_model.ActionType | ||||||
| 	if comment.Type == issues_model.CommentTypeClose { | 	if comment.Type == issues_model.CommentTypeClose { | ||||||
| 		act = models.ActionCloseIssue | 		act = activities_model.ActionCloseIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypeReopen { | 	} else if comment.Type == issues_model.CommentTypeReopen { | ||||||
| 		act = models.ActionReopenIssue | 		act = activities_model.ActionReopenIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypeComment { | 	} else if comment.Type == issues_model.CommentTypeComment { | ||||||
| 		act = models.ActionCommentIssue | 		act = activities_model.ActionCommentIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypeCode { | 	} else if comment.Type == issues_model.CommentTypeCode { | ||||||
| 		act = models.ActionCommentIssue | 		act = activities_model.ActionCommentIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypePullRequestPush { | 	} else if comment.Type == issues_model.CommentTypePullRequestPush { | ||||||
| 		act = 0 | 		act = 0 | ||||||
| 	} | 	} | ||||||
| @@ -54,24 +54,24 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *rep | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { | func (m *mailNotifier) NotifyNewIssue(issue *issues_model.Issue, mentions []*user_model.User) { | ||||||
| 	if err := mailer.MailParticipants(issue, issue.Poster, models.ActionCreateIssue, mentions); err != nil { | 	if err := mailer.MailParticipants(issue, issue.Poster, activities_model.ActionCreateIssue, mentions); err != nil { | ||||||
| 		log.Error("MailParticipants: %v", err) | 		log.Error("MailParticipants: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { | func (m *mailNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { | ||||||
| 	var actionType models.ActionType | 	var actionType activities_model.ActionType | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		if isClosed { | 		if isClosed { | ||||||
| 			actionType = models.ActionClosePullRequest | 			actionType = activities_model.ActionClosePullRequest | ||||||
| 		} else { | 		} else { | ||||||
| 			actionType = models.ActionReopenPullRequest | 			actionType = activities_model.ActionReopenPullRequest | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		if isClosed { | 		if isClosed { | ||||||
| 			actionType = models.ActionCloseIssue | 			actionType = activities_model.ActionCloseIssue | ||||||
| 		} else { | 		} else { | ||||||
| 			actionType = models.ActionReopenIssue | 			actionType = activities_model.ActionReopenIssue | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -86,14 +86,14 @@ func (m *mailNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *issu | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { | 	if issue.IsPull && issues_model.HasWorkInProgressPrefix(oldTitle) && !issue.PullRequest.IsWorkInProgress() { | ||||||
| 		if err := mailer.MailParticipants(issue, doer, models.ActionPullRequestReadyForReview, nil); err != nil { | 		if err := mailer.MailParticipants(issue, doer, activities_model.ActionPullRequestReadyForReview, nil); err != nil { | ||||||
| 			log.Error("MailParticipants: %v", err) | 			log.Error("MailParticipants: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { | func (m *mailNotifier) NotifyNewPullRequest(pr *issues_model.PullRequest, mentions []*user_model.User) { | ||||||
| 	if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, models.ActionCreatePullRequest, mentions); err != nil { | 	if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, activities_model.ActionCreatePullRequest, mentions); err != nil { | ||||||
| 		log.Error("MailParticipants: %v", err) | 		log.Error("MailParticipants: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -102,13 +102,13 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *issues_model.PullRequest, r * | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRequestReview Pull[%d] #%d in [%d]", pr.ID, pr.Index, pr.BaseRepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	var act models.ActionType | 	var act activities_model.ActionType | ||||||
| 	if comment.Type == issues_model.CommentTypeClose { | 	if comment.Type == issues_model.CommentTypeClose { | ||||||
| 		act = models.ActionCloseIssue | 		act = activities_model.ActionCloseIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypeReopen { | 	} else if comment.Type == issues_model.CommentTypeReopen { | ||||||
| 		act = models.ActionReopenIssue | 		act = activities_model.ActionReopenIssue | ||||||
| 	} else if comment.Type == issues_model.CommentTypeComment { | 	} else if comment.Type == issues_model.CommentTypeComment { | ||||||
| 		act = models.ActionCommentPull | 		act = activities_model.ActionCommentPull | ||||||
| 	} | 	} | ||||||
| 	if err := mailer.MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { | 	if err := mailer.MailParticipantsComment(ctx, comment, act, pr.Issue, mentions); err != nil { | ||||||
| 		log.Error("MailParticipantsComment: %v", err) | 		log.Error("MailParticipantsComment: %v", err) | ||||||
| @@ -148,7 +148,7 @@ func (m *mailNotifier) NotifyMergePullRequest(pr *issues_model.PullRequest, doer | |||||||
| 		log.Error("pr.LoadIssue: %v", err) | 		log.Error("pr.LoadIssue: %v", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err := mailer.MailParticipants(pr.Issue, doer, models.ActionMergePullRequest, nil); err != nil { | 	if err := mailer.MailParticipants(pr.Issue, doer, activities_model.ActionMergePullRequest, nil); err != nil { | ||||||
| 		log.Error("MailParticipants: %v", err) | 		log.Error("MailParticipants: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -184,12 +184,12 @@ func (m *mailNotifier) NotifyPullRevieweDismiss(doer *user_model.User, review *i | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyPullRevieweDismiss Review[%d] in Issue[%d]", review.ID, review.IssueID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	if err := mailer.MailParticipantsComment(ctx, comment, models.ActionPullReviewDismissed, review.Issue, nil); err != nil { | 	if err := mailer.MailParticipantsComment(ctx, comment, activities_model.ActionPullReviewDismissed, review.Issue, nil); err != nil { | ||||||
| 		log.Error("MailParticipantsComment: %v", err) | 		log.Error("MailParticipantsComment: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mailNotifier) NotifyNewRelease(rel *models.Release) { | func (m *mailNotifier) NotifyNewRelease(rel *repo_model.Release) { | ||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyNewRelease rel[%d]%s in [%d]", rel.ID, rel.Title, rel.RepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("mailNotifier.NotifyNewRelease rel[%d]%s in [%d]", rel.ID, rel.Title, rel.RepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| package notification | package notification | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -142,21 +141,21 @@ func NotifyDeleteComment(doer *user_model.User, c *issues_model.Comment) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyNewRelease notifies new release to notifiers | // NotifyNewRelease notifies new release to notifiers | ||||||
| func NotifyNewRelease(rel *models.Release) { | func NotifyNewRelease(rel *repo_model.Release) { | ||||||
| 	for _, notifier := range notifiers { | 	for _, notifier := range notifiers { | ||||||
| 		notifier.NotifyNewRelease(rel) | 		notifier.NotifyNewRelease(rel) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyUpdateRelease notifies update release to notifiers | // NotifyUpdateRelease notifies update release to notifiers | ||||||
| func NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { | func NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| 	for _, notifier := range notifiers { | 	for _, notifier := range notifiers { | ||||||
| 		notifier.NotifyUpdateRelease(doer, rel) | 		notifier.NotifyUpdateRelease(doer, rel) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // NotifyDeleteRelease notifies delete release to notifiers | // NotifyDeleteRelease notifies delete release to notifiers | ||||||
| func NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { | func NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| 	for _, notifier := range notifiers { | 	for _, notifier := range notifiers { | ||||||
| 		notifier.NotifyDeleteRelease(doer, rel) | 		notifier.NotifyDeleteRelease(doer, rel) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| package ui | package ui | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -42,7 +42,7 @@ func NewNotifier() base.Notifier { | |||||||
| func (ns *notificationService) handle(data ...queue.Data) []queue.Data { | func (ns *notificationService) handle(data ...queue.Data) []queue.Data { | ||||||
| 	for _, datum := range data { | 	for _, datum := range data { | ||||||
| 		opts := datum.(issueNotificationOpts) | 		opts := datum.(issueNotificationOpts) | ||||||
| 		if err := models.CreateOrUpdateIssueNotifications(opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { | 		if err := activities_model.CreateOrUpdateIssueNotifications(opts.IssueID, opts.CommentID, opts.NotificationAuthorID, opts.ReceiverID); err != nil { | ||||||
| 			log.Error("Was unable to create issue notification: %v", err) | 			log.Error("Was unable to create issue notification: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -237,7 +237,7 @@ func (ns *notificationService) NotifyPullReviewRequest(doer *user_model.User, is | |||||||
| } | } | ||||||
|  |  | ||||||
| func (ns *notificationService) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) { | func (ns *notificationService) NotifyRepoPendingTransfer(doer, newOwner *user_model.User, repo *repo_model.Repository) { | ||||||
| 	if err := models.CreateRepoTransferNotification(doer, newOwner, repo); err != nil { | 	if err := activities_model.CreateRepoTransferNotification(doer, newOwner, repo); err != nil { | ||||||
| 		log.Error("NotifyRepoPendingTransfer: %v", err) | 		log.Error("NotifyRepoPendingTransfer: %v", err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ package webhook | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| @@ -797,7 +796,7 @@ func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *repo_mo | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func sendReleaseHook(doer *user_model.User, rel *models.Release, action api.HookReleaseAction) { | func sendReleaseHook(doer *user_model.User, rel *repo_model.Release, action api.HookReleaseAction) { | ||||||
| 	if err := rel.LoadAttributes(); err != nil { | 	if err := rel.LoadAttributes(); err != nil { | ||||||
| 		log.Error("LoadAttributes: %v", err) | 		log.Error("LoadAttributes: %v", err) | ||||||
| 		return | 		return | ||||||
| @@ -814,15 +813,15 @@ func sendReleaseHook(doer *user_model.User, rel *models.Release, action api.Hook | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *webhookNotifier) NotifyNewRelease(rel *models.Release) { | func (m *webhookNotifier) NotifyNewRelease(rel *repo_model.Release) { | ||||||
| 	sendReleaseHook(rel.Publisher, rel, api.HookReleasePublished) | 	sendReleaseHook(rel.Publisher, rel, api.HookReleasePublished) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *webhookNotifier) NotifyUpdateRelease(doer *user_model.User, rel *models.Release) { | func (m *webhookNotifier) NotifyUpdateRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| 	sendReleaseHook(doer, rel, api.HookReleaseUpdated) | 	sendReleaseHook(doer, rel, api.HookReleaseUpdated) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *webhookNotifier) NotifyDeleteRelease(doer *user_model.User, rel *models.Release) { | func (m *webhookNotifier) NotifyDeleteRelease(doer *user_model.User, rel *repo_model.Release) { | ||||||
| 	sendReleaseHook(doer, rel, api.HookReleaseDeleted) | 	sendReleaseHook(doer, rel, api.HookReleaseDeleted) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								modules/repository/collaborator.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								modules/repository/collaborator.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | // Copyright 2022 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 repository | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { | ||||||
|  | 	collaboration := &repo_model.Collaboration{ | ||||||
|  | 		RepoID: repo.ID, | ||||||
|  | 		UserID: u.ID, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	has, err := db.GetByBean(ctx, collaboration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} else if has { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	collaboration.Mode = perm.AccessModeWrite | ||||||
|  |  | ||||||
|  | 	if err = db.Insert(ctx, collaboration); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return access_model.RecalculateUserAccess(ctx, repo, u.ID) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddCollaborator adds new collaboration to a repository with default access mode. | ||||||
|  | func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error { | ||||||
|  | 	return db.WithTx(func(ctx context.Context) error { | ||||||
|  | 		return addCollaborator(ctx, repo, u) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
							
								
								
									
										281
									
								
								modules/repository/collaborator_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								modules/repository/collaborator_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,281 @@ | |||||||
|  | // 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 repository | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	perm_model "code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | 	"code.gitea.io/gitea/models/unit" | ||||||
|  | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestRepository_AddCollaborator(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	testSuccess := func(repoID, userID int64) { | ||||||
|  | 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) | ||||||
|  | 		assert.NoError(t, repo.GetOwner(db.DefaultContext)) | ||||||
|  | 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}) | ||||||
|  | 		assert.NoError(t, AddCollaborator(repo, user)) | ||||||
|  | 		unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID}) | ||||||
|  | 	} | ||||||
|  | 	testSuccess(1, 4) | ||||||
|  | 	testSuccess(1, 4) | ||||||
|  | 	testSuccess(3, 4) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	// public non-organization repo | ||||||
|  | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) | ||||||
|  | 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) | ||||||
|  |  | ||||||
|  | 	// plain user | ||||||
|  | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// change to collaborator | ||||||
|  | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// collaborator | ||||||
|  | 	collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// owner | ||||||
|  | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// admin | ||||||
|  | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	// private non-organization repo | ||||||
|  | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) | ||||||
|  | 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) | ||||||
|  |  | ||||||
|  | 	// plain user | ||||||
|  | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) | ||||||
|  | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.False(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// change to collaborator to default write access | ||||||
|  | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// owner | ||||||
|  | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// admin | ||||||
|  | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestRepoPermissionPublicOrgRepo(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	// public organization repo | ||||||
|  | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) | ||||||
|  | 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) | ||||||
|  |  | ||||||
|  | 	// plain user | ||||||
|  | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) | ||||||
|  | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// change to collaborator to default write access | ||||||
|  | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// org member team owner | ||||||
|  | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// org member team tester | ||||||
|  | 	member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 	} | ||||||
|  | 	assert.True(t, perm.CanWrite(unit.TypeIssues)) | ||||||
|  | 	assert.False(t, perm.CanWrite(unit.TypeCode)) | ||||||
|  |  | ||||||
|  | 	// admin | ||||||
|  | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	// private organization repo | ||||||
|  | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}) | ||||||
|  | 	assert.NoError(t, repo.LoadUnits(db.DefaultContext)) | ||||||
|  |  | ||||||
|  | 	// plain user | ||||||
|  | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) | ||||||
|  | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.False(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// change to collaborator to default write access | ||||||
|  | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.False(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// org member team owner | ||||||
|  | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// update team information and then check permission | ||||||
|  | 	team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}) | ||||||
|  | 	err = organization.UpdateTeamUnits(team, nil) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// org member team tester | ||||||
|  | 	tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.True(t, perm.CanWrite(unit.TypeIssues)) | ||||||
|  | 	assert.False(t, perm.CanWrite(unit.TypeCode)) | ||||||
|  | 	assert.False(t, perm.CanRead(unit.TypeCode)) | ||||||
|  |  | ||||||
|  | 	// org member team reviewer | ||||||
|  | 	reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.False(t, perm.CanRead(unit.TypeIssues)) | ||||||
|  | 	assert.False(t, perm.CanWrite(unit.TypeCode)) | ||||||
|  | 	assert.True(t, perm.CanRead(unit.TypeCode)) | ||||||
|  |  | ||||||
|  | 	// admin | ||||||
|  | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) | ||||||
|  | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	for _, unit := range repo.Units { | ||||||
|  | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|  | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -13,11 +13,16 @@ import ( | |||||||
| 	"unicode/utf8" | 	"unicode/utf8" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
|  | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	"code.gitea.io/gitea/models/perm" | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
|  | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	"code.gitea.io/gitea/models/webhook" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| @@ -25,8 +30,150 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // CreateRepositoryByExample creates a repository for the user/organization. | ||||||
|  | func CreateRepositoryByExample(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { | ||||||
|  | 	if err = repo_model.IsUsableRepoName(repo.Name); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	has, err := repo_model.IsRepositoryExist(ctx, u, repo.Name) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("IsRepositoryExist: %v", err) | ||||||
|  | 	} else if has { | ||||||
|  | 		return repo_model.ErrRepoAlreadyExist{ | ||||||
|  | 			Uname: u.Name, | ||||||
|  | 			Name:  repo.Name, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	repoPath := repo_model.RepoPath(u.Name, repo.Name) | ||||||
|  | 	isExist, err := util.IsExist(repoPath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Error("Unable to check if %s exists. Error: %v", repoPath, err) | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if !overwriteOrAdopt && isExist { | ||||||
|  | 		log.Error("Files already exist in %s and we are not going to adopt or delete.", repoPath) | ||||||
|  | 		return repo_model.ErrRepoFilesAlreadyExist{ | ||||||
|  | 			Uname: u.Name, | ||||||
|  | 			Name:  repo.Name, | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = db.Insert(ctx, repo); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	if err = repo_model.DeleteRedirect(ctx, u.ID, repo.Name); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// insert units for repo | ||||||
|  | 	units := make([]repo_model.RepoUnit, 0, len(unit.DefaultRepoUnits)) | ||||||
|  | 	for _, tp := range unit.DefaultRepoUnits { | ||||||
|  | 		if tp == unit.TypeIssues { | ||||||
|  | 			units = append(units, repo_model.RepoUnit{ | ||||||
|  | 				RepoID: repo.ID, | ||||||
|  | 				Type:   tp, | ||||||
|  | 				Config: &repo_model.IssuesConfig{ | ||||||
|  | 					EnableTimetracker:                setting.Service.DefaultEnableTimetracking, | ||||||
|  | 					AllowOnlyContributorsToTrackTime: setting.Service.DefaultAllowOnlyContributorsToTrackTime, | ||||||
|  | 					EnableDependencies:               setting.Service.DefaultEnableDependencies, | ||||||
|  | 				}, | ||||||
|  | 			}) | ||||||
|  | 		} else if tp == unit.TypePullRequests { | ||||||
|  | 			units = append(units, repo_model.RepoUnit{ | ||||||
|  | 				RepoID: repo.ID, | ||||||
|  | 				Type:   tp, | ||||||
|  | 				Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle), AllowRebaseUpdate: true}, | ||||||
|  | 			}) | ||||||
|  | 		} else { | ||||||
|  | 			units = append(units, repo_model.RepoUnit{ | ||||||
|  | 				RepoID: repo.ID, | ||||||
|  | 				Type:   tp, | ||||||
|  | 			}) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = db.Insert(ctx, units); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Remember visibility preference. | ||||||
|  | 	u.LastRepoVisibility = repo.IsPrivate | ||||||
|  | 	if err = user_model.UpdateUserCols(ctx, u, "last_repo_visibility"); err != nil { | ||||||
|  | 		return fmt.Errorf("UpdateUserCols: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = user_model.IncrUserRepoNum(ctx, u.ID); err != nil { | ||||||
|  | 		return fmt.Errorf("IncrUserRepoNum: %v", err) | ||||||
|  | 	} | ||||||
|  | 	u.NumRepos++ | ||||||
|  |  | ||||||
|  | 	// Give access to all members in teams with access to all repositories. | ||||||
|  | 	if u.IsOrganization() { | ||||||
|  | 		teams, err := organization.FindOrgTeams(ctx, u.ID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("FindOrgTeams: %v", err) | ||||||
|  | 		} | ||||||
|  | 		for _, t := range teams { | ||||||
|  | 			if t.IncludesAllRepositories { | ||||||
|  | 				if err := models.AddRepository(ctx, t, repo); err != nil { | ||||||
|  | 					return fmt.Errorf("AddRepository: %v", err) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if isAdmin, err := access_model.IsUserRepoAdmin(ctx, repo, doer); err != nil { | ||||||
|  | 			return fmt.Errorf("IsUserRepoAdmin: %v", err) | ||||||
|  | 		} else if !isAdmin { | ||||||
|  | 			// Make creator repo admin if it wasn't assigned automatically | ||||||
|  | 			if err = addCollaborator(ctx, repo, doer); err != nil { | ||||||
|  | 				return fmt.Errorf("addCollaborator: %v", err) | ||||||
|  | 			} | ||||||
|  | 			if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil { | ||||||
|  | 				return fmt.Errorf("ChangeCollaborationAccessModeCtx: %v", err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { | ||||||
|  | 		// Organization automatically called this in AddRepository method. | ||||||
|  | 		return fmt.Errorf("RecalculateAccesses: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if setting.Service.AutoWatchNewRepos { | ||||||
|  | 		if err = repo_model.WatchRepo(ctx, doer.ID, repo.ID, true); err != nil { | ||||||
|  | 			return fmt.Errorf("WatchRepo: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if err = webhook.CopyDefaultWebhooksToRepo(ctx, repo.ID); err != nil { | ||||||
|  | 		return fmt.Errorf("CopyDefaultWebhooksToRepo: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CreateRepoOptions contains the create repository options | ||||||
|  | type CreateRepoOptions struct { | ||||||
|  | 	Name           string | ||||||
|  | 	Description    string | ||||||
|  | 	OriginalURL    string | ||||||
|  | 	GitServiceType api.GitServiceType | ||||||
|  | 	Gitignores     string | ||||||
|  | 	IssueLabels    string | ||||||
|  | 	License        string | ||||||
|  | 	Readme         string | ||||||
|  | 	DefaultBranch  string | ||||||
|  | 	IsPrivate      bool | ||||||
|  | 	IsMirror       bool | ||||||
|  | 	IsTemplate     bool | ||||||
|  | 	AutoInit       bool | ||||||
|  | 	Status         repo_model.RepositoryStatus | ||||||
|  | 	TrustModel     repo_model.TrustModelType | ||||||
|  | 	MirrorInterval string | ||||||
|  | } | ||||||
|  |  | ||||||
| // CreateRepository creates a repository for the user/organization. | // CreateRepository creates a repository for the user/organization. | ||||||
| func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (*repo_model.Repository, error) { | func CreateRepository(doer, u *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) { | ||||||
| 	if !doer.IsAdmin && !u.CanCreateRepo() { | 	if !doer.IsAdmin && !u.CanCreateRepo() { | ||||||
| 		return nil, repo_model.ErrReachLimitOfRepo{ | 		return nil, repo_model.ErrReachLimitOfRepo{ | ||||||
| 			Limit: u.MaxRepoCreation, | 			Limit: u.MaxRepoCreation, | ||||||
| @@ -66,7 +213,7 @@ func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) ( | |||||||
| 	var rollbackRepo *repo_model.Repository | 	var rollbackRepo *repo_model.Repository | ||||||
|  |  | ||||||
| 	if err := db.WithTx(func(ctx context.Context) error { | 	if err := db.WithTx(func(ctx context.Context) error { | ||||||
| 		if err := models.CreateRepository(ctx, doer, u, repo, false); err != nil { | 		if err := CreateRepositoryByExample(ctx, doer, u, repo, false); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -220,7 +367,7 @@ func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibili | |||||||
|  |  | ||||||
| 		// If repo has become private, we need to set its actions to private. | 		// If repo has become private, we need to set its actions to private. | ||||||
| 		if repo.IsPrivate { | 		if repo.IsPrivate { | ||||||
| 			_, err = e.Where("repo_id = ?", repo.ID).Cols("is_private").Update(&models.Action{ | 			_, err = e.Where("repo_id = ?", repo.ID).Cols("is_private").Update(&activities_model.Action{ | ||||||
| 				IsPrivate: true, | 				IsPrivate: true, | ||||||
| 			}) | 			}) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
| @@ -56,7 +57,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { | |||||||
| 	// Create repos. | 	// Create repos. | ||||||
| 	repoIds := make([]int64, 0) | 	repoIds := make([]int64, 0) | ||||||
| 	for i := 0; i < 3; i++ { | 	for i := 0; i < 3; i++ { | ||||||
| 		r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) | 		r, err := CreateRepository(user, org.AsUser(), CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) | ||||||
| 		assert.NoError(t, err, "CreateRepository %d", i) | 		assert.NoError(t, err, "CreateRepository %d", i) | ||||||
| 		if r != nil { | 		if r != nil { | ||||||
| 			repoIds = append(repoIds, r.ID) | 			repoIds = append(repoIds, r.ID) | ||||||
| @@ -118,7 +119,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Create repo and check teams repositories. | 	// Create repo and check teams repositories. | ||||||
| 	r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: "repo-last"}) | 	r, err := CreateRepository(user, org.AsUser(), CreateRepoOptions{Name: "repo-last"}) | ||||||
| 	assert.NoError(t, err, "CreateRepository last") | 	assert.NoError(t, err, "CreateRepository last") | ||||||
| 	if r != nil { | 	if r != nil { | ||||||
| 		repoIds = append(repoIds, r.ID) | 		repoIds = append(repoIds, r.ID) | ||||||
| @@ -162,7 +163,7 @@ func TestUpdateRepositoryVisibilityChanged(t *testing.T) { | |||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|  |  | ||||||
| 	// Check visibility of action has become private | 	// Check visibility of action has become private | ||||||
| 	act := models.Action{} | 	act := activities_model.Action{} | ||||||
| 	_, err = db.GetEngine(db.DefaultContext).ID(3).Get(&act) | 	_, err = db.GetEngine(db.DefaultContext).ID(3).Get(&act) | ||||||
|  |  | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -321,7 +320,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ | |||||||
| 		TrustModel:    templateRepo.TrustModel, | 		TrustModel:    templateRepo.TrustModel, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = models.CreateRepository(ctx, doer, owner, generateRepo, false); err != nil { | 	if err = CreateRepositoryByExample(ctx, doer, owner, generateRepo, false); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -214,7 +213,7 @@ func LoadRepoConfig() { | |||||||
| 	Licenses = sortedLicenses | 	Licenses = sortedLicenses | ||||||
| } | } | ||||||
|  |  | ||||||
| func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts models.CreateRepoOptions) error { | func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { | ||||||
| 	commitTimeStr := time.Now().Format(time.RFC3339) | 	commitTimeStr := time.Now().Format(time.RFC3339) | ||||||
| 	authorSig := repo.Owner.NewGitSig() | 	authorSig := repo.Owner.NewGitSig() | ||||||
|  |  | ||||||
| @@ -387,7 +386,7 @@ func checkInitRepository(ctx context.Context, owner, name string) (err error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // InitRepository initializes README and .gitignore if needed. | // InitRepository initializes README and .gitignore if needed. | ||||||
| func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts models.CreateRepoOptions) (err error) { | func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { | ||||||
| 	if err = checkInitRepository(ctx, repo.OwnerName, repo.Name); err != nil { | 	if err = checkInitRepository(ctx, repo.OwnerName, repo.Name); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| @@ -31,8 +30,8 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| /* | /* | ||||||
| 	GitHub, GitLab, Gogs: *.wiki.git | GitHub, GitLab, Gogs: *.wiki.git | ||||||
| 	BitBucket: *.git/wiki | BitBucket: *.git/wiki | ||||||
| */ | */ | ||||||
| var commonWikiURLSuffixes = []string{".wiki.git", ".git/wiki"} | var commonWikiURLSuffixes = []string{".wiki.git", ".git/wiki"} | ||||||
|  |  | ||||||
| @@ -277,14 +276,14 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	existingRelTags := make(map[string]struct{}) | 	existingRelTags := make(map[string]struct{}) | ||||||
| 	opts := models.FindReleasesOptions{ | 	opts := repo_model.FindReleasesOptions{ | ||||||
| 		IncludeDrafts: true, | 		IncludeDrafts: true, | ||||||
| 		IncludeTags:   true, | 		IncludeTags:   true, | ||||||
| 		ListOptions:   db.ListOptions{PageSize: 50}, | 		ListOptions:   db.ListOptions{PageSize: 50}, | ||||||
| 	} | 	} | ||||||
| 	for page := 1; ; page++ { | 	for page := 1; ; page++ { | ||||||
| 		opts.Page = page | 		opts.Page = page | ||||||
| 		rels, err := models.GetReleasesByRepoID(repo.ID, opts) | 		rels, err := repo_model.GetReleasesByRepoID(repo.ID, opts) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) | 			return fmt.Errorf("unable to GetReleasesByRepoID in Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) | ||||||
| 		} | 		} | ||||||
| @@ -300,7 +299,7 @@ func SyncReleasesWithTags(repo *repo_model.Repository, gitRepo *git.Repository) | |||||||
| 				return fmt.Errorf("unable to GetTagCommitID for %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) | 				return fmt.Errorf("unable to GetTagCommitID for %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) | ||||||
| 			} | 			} | ||||||
| 			if git.IsErrNotExist(err) || commitID != rel.Sha1 { | 			if git.IsErrNotExist(err) || commitID != rel.Sha1 { | ||||||
| 				if err := models.PushUpdateDeleteTag(repo, rel.TagName); err != nil { | 				if err := repo_model.PushUpdateDeleteTag(repo, rel.TagName); err != nil { | ||||||
| 					return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) | 					return fmt.Errorf("unable to PushUpdateDeleteTag: %q in Repo[%d:%s/%s]: %w", rel.TagName, repo.ID, repo.OwnerName, repo.Name, err) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| @@ -359,7 +358,7 @@ func PushUpdateAddTag(repo *repo_model.Repository, gitRepo *git.Repository, tagN | |||||||
| 		return fmt.Errorf("unable to get CommitsCount: %w", err) | 		return fmt.Errorf("unable to get CommitsCount: %w", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	rel := models.Release{ | 	rel := repo_model.Release{ | ||||||
| 		RepoID:       repo.ID, | 		RepoID:       repo.ID, | ||||||
| 		TagName:      tagName, | 		TagName:      tagName, | ||||||
| 		LowerTagName: strings.ToLower(tagName), | 		LowerTagName: strings.ToLower(tagName), | ||||||
| @@ -372,7 +371,7 @@ func PushUpdateAddTag(repo *repo_model.Repository, gitRepo *git.Repository, tagN | |||||||
| 		rel.PublisherID = author.ID | 		rel.PublisherID = author.ID | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return models.SaveOrUpdateTag(repo, &rel) | 	return repo_model.SaveOrUpdateTag(repo, &rel) | ||||||
| } | } | ||||||
|  |  | ||||||
| // StoreMissingLfsObjectsInRepository downloads missing LFS objects | // StoreMissingLfsObjectsInRepository downloads missing LFS objects | ||||||
| @@ -489,14 +488,14 @@ func pullMirrorReleaseSync(repo *repo_model.Repository, gitRepo *git.Repository) | |||||||
| 		// | 		// | ||||||
| 		// clear out existing releases | 		// clear out existing releases | ||||||
| 		// | 		// | ||||||
| 		if _, err := db.DeleteByBean(ctx, &models.Release{RepoID: repo.ID}); err != nil { | 		if _, err := db.DeleteByBean(ctx, &repo_model.Release{RepoID: repo.ID}); err != nil { | ||||||
| 			return fmt.Errorf("unable to clear releases for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) | 			return fmt.Errorf("unable to clear releases for pull-mirror Repo[%d:%s/%s]: %w", repo.ID, repo.OwnerName, repo.Name, err) | ||||||
| 		} | 		} | ||||||
| 		// | 		// | ||||||
| 		// make release set identical to upstream tags | 		// make release set identical to upstream tags | ||||||
| 		// | 		// | ||||||
| 		for _, tag := range tags { | 		for _, tag := range tags { | ||||||
| 			release := models.Release{ | 			release := repo_model.Release{ | ||||||
| 				RepoID:       repo.ID, | 				RepoID:       repo.ID, | ||||||
| 				TagName:      tag.Name, | 				TagName:      tag.Name, | ||||||
| 				LowerTagName: strings.ToLower(tag.Name), | 				LowerTagName: strings.ToLower(tag.Name), | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| 	"unicode" | 	"unicode" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/avatars" | 	"code.gitea.io/gitea/models/avatars" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| @@ -655,7 +655,7 @@ func Avatar(item interface{}, others ...interface{}) template.HTML { | |||||||
| } | } | ||||||
|  |  | ||||||
| // AvatarByAction renders user avatars from action. args: action, size (int), class (string) | // AvatarByAction renders user avatars from action. args: action, size (int), class (string) | ||||||
| func AvatarByAction(action *models.Action, others ...interface{}) template.HTML { | func AvatarByAction(action *activities_model.Action, others ...interface{}) template.HTML { | ||||||
| 	action.LoadActUser() | 	action.LoadActUser() | ||||||
| 	return Avatar(action.ActUser, others...) | 	return Avatar(action.ActUser, others...) | ||||||
| } | } | ||||||
| @@ -854,7 +854,7 @@ func IsMultilineCommitMessage(msg string) bool { | |||||||
|  |  | ||||||
| // Actioner describes an action | // Actioner describes an action | ||||||
| type Actioner interface { | type Actioner interface { | ||||||
| 	GetOpType() models.ActionType | 	GetOpType() activities_model.ActionType | ||||||
| 	GetActUserName() string | 	GetActUserName() string | ||||||
| 	GetRepoUserName() string | 	GetRepoUserName() string | ||||||
| 	GetRepoName() string | 	GetRepoName() string | ||||||
| @@ -867,33 +867,33 @@ type Actioner interface { | |||||||
| } | } | ||||||
|  |  | ||||||
| // ActionIcon accepts an action operation type and returns an icon class name. | // ActionIcon accepts an action operation type and returns an icon class name. | ||||||
| func ActionIcon(opType models.ActionType) string { | func ActionIcon(opType activities_model.ActionType) string { | ||||||
| 	switch opType { | 	switch opType { | ||||||
| 	case models.ActionCreateRepo, models.ActionTransferRepo, models.ActionRenameRepo: | 	case activities_model.ActionCreateRepo, activities_model.ActionTransferRepo, activities_model.ActionRenameRepo: | ||||||
| 		return "repo" | 		return "repo" | ||||||
| 	case models.ActionCommitRepo, models.ActionPushTag, models.ActionDeleteTag, models.ActionDeleteBranch: | 	case activities_model.ActionCommitRepo, activities_model.ActionPushTag, activities_model.ActionDeleteTag, activities_model.ActionDeleteBranch: | ||||||
| 		return "git-commit" | 		return "git-commit" | ||||||
| 	case models.ActionCreateIssue: | 	case activities_model.ActionCreateIssue: | ||||||
| 		return "issue-opened" | 		return "issue-opened" | ||||||
| 	case models.ActionCreatePullRequest: | 	case activities_model.ActionCreatePullRequest: | ||||||
| 		return "git-pull-request" | 		return "git-pull-request" | ||||||
| 	case models.ActionCommentIssue, models.ActionCommentPull: | 	case activities_model.ActionCommentIssue, activities_model.ActionCommentPull: | ||||||
| 		return "comment-discussion" | 		return "comment-discussion" | ||||||
| 	case models.ActionMergePullRequest: | 	case activities_model.ActionMergePullRequest: | ||||||
| 		return "git-merge" | 		return "git-merge" | ||||||
| 	case models.ActionCloseIssue, models.ActionClosePullRequest: | 	case activities_model.ActionCloseIssue, activities_model.ActionClosePullRequest: | ||||||
| 		return "issue-closed" | 		return "issue-closed" | ||||||
| 	case models.ActionReopenIssue, models.ActionReopenPullRequest: | 	case activities_model.ActionReopenIssue, activities_model.ActionReopenPullRequest: | ||||||
| 		return "issue-reopened" | 		return "issue-reopened" | ||||||
| 	case models.ActionMirrorSyncPush, models.ActionMirrorSyncCreate, models.ActionMirrorSyncDelete: | 	case activities_model.ActionMirrorSyncPush, activities_model.ActionMirrorSyncCreate, activities_model.ActionMirrorSyncDelete: | ||||||
| 		return "mirror" | 		return "mirror" | ||||||
| 	case models.ActionApprovePullRequest: | 	case activities_model.ActionApprovePullRequest: | ||||||
| 		return "check" | 		return "check" | ||||||
| 	case models.ActionRejectPullRequest: | 	case activities_model.ActionRejectPullRequest: | ||||||
| 		return "diff" | 		return "diff" | ||||||
| 	case models.ActionPublishRelease: | 	case activities_model.ActionPublishRelease: | ||||||
| 		return "tag" | 		return "tag" | ||||||
| 	case models.ActionPullReviewDismissed: | 	case activities_model.ActionPullReviewDismissed: | ||||||
| 		return "x" | 		return "x" | ||||||
| 	default: | 	default: | ||||||
| 		return "question" | 		return "question" | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ package nuget | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
| @@ -22,9 +22,9 @@ func (a *Auth) Name() string { | |||||||
|  |  | ||||||
| // https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters | // https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters | ||||||
| func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { | func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { | ||||||
| 	token, err := models.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey")) | 	token, err := auth_model.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if !(models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err)) { | 		if !(auth_model.IsErrAccessTokenNotExist(err) || auth_model.IsErrAccessTokenEmpty(err)) { | ||||||
| 			log.Error("GetAccessTokenBySHA: %v", err) | 			log.Error("GetAccessTokenBySHA: %v", err) | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return nil | ||||||
| @@ -37,7 +37,7 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	token.UpdatedUnix = timeutil.TimeStampNow() | 	token.UpdatedUnix = timeutil.TimeStampNow() | ||||||
| 	if err := models.UpdateAccessToken(token); err != nil { | 	if err := auth_model.UpdateAccessToken(token); err != nil { | ||||||
| 		log.Error("UpdateAccessToken:  %v", err) | 		log.Error("UpdateAccessToken:  %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,10 +7,10 @@ package admin | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||||
| 	repo_service "code.gitea.io/gitea/services/repository" | 	repo_service "code.gitea.io/gitea/services/repository" | ||||||
| @@ -110,7 +110,7 @@ func AdoptRepository(ctx *context.APIContext) { | |||||||
| 		ctx.NotFound() | 		ctx.NotFound() | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, models.CreateRepoOptions{ | 	if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ | ||||||
| 		Name:      repoName, | 		Name:      repoName, | ||||||
| 		IsPrivate: true, | 		IsPrivate: true, | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||||
| @@ -22,16 +22,16 @@ func NewAvailable(ctx *context.APIContext) { | |||||||
| 	// responses: | 	// responses: | ||||||
| 	//   "200": | 	//   "200": | ||||||
| 	//     "$ref": "#/responses/NotificationCount" | 	//     "$ref": "#/responses/NotificationCount" | ||||||
| 	ctx.JSON(http.StatusOK, api.NotificationCount{New: models.CountUnread(ctx, ctx.Doer.ID)}) | 	ctx.JSON(http.StatusOK, api.NotificationCount{New: activities_model.CountUnread(ctx, ctx.Doer.ID)}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getFindNotificationOptions(ctx *context.APIContext) *models.FindNotificationOptions { | func getFindNotificationOptions(ctx *context.APIContext) *activities_model.FindNotificationOptions { | ||||||
| 	before, since, err := context.GetQueryBeforeSince(ctx.Context) | 	before, since, err := context.GetQueryBeforeSince(ctx.Context) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) | 		ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	opts := &models.FindNotificationOptions{ | 	opts := &activities_model.FindNotificationOptions{ | ||||||
| 		ListOptions:       utils.GetListOptions(ctx), | 		ListOptions:       utils.GetListOptions(ctx), | ||||||
| 		UserID:            ctx.Doer.ID, | 		UserID:            ctx.Doer.ID, | ||||||
| 		UpdatedBeforeUnix: before, | 		UpdatedBeforeUnix: before, | ||||||
| @@ -50,17 +50,17 @@ func getFindNotificationOptions(ctx *context.APIContext) *models.FindNotificatio | |||||||
| 	return opts | 	return opts | ||||||
| } | } | ||||||
|  |  | ||||||
| func subjectToSource(value []string) (result []models.NotificationSource) { | func subjectToSource(value []string) (result []activities_model.NotificationSource) { | ||||||
| 	for _, v := range value { | 	for _, v := range value { | ||||||
| 		switch strings.ToLower(v) { | 		switch strings.ToLower(v) { | ||||||
| 		case "issue": | 		case "issue": | ||||||
| 			result = append(result, models.NotificationSourceIssue) | 			result = append(result, activities_model.NotificationSourceIssue) | ||||||
| 		case "pull": | 		case "pull": | ||||||
| 			result = append(result, models.NotificationSourcePullRequest) | 			result = append(result, activities_model.NotificationSourcePullRequest) | ||||||
| 		case "commit": | 		case "commit": | ||||||
| 			result = append(result, models.NotificationSourceCommit) | 			result = append(result, activities_model.NotificationSourceCommit) | ||||||
| 		case "repository": | 		case "repository": | ||||||
| 			result = append(result, models.NotificationSourceRepository) | 			result = append(result, activities_model.NotificationSourceRepository) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return result | 	return result | ||||||
|   | |||||||
| @@ -9,31 +9,31 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func statusStringToNotificationStatus(status string) models.NotificationStatus { | func statusStringToNotificationStatus(status string) activities_model.NotificationStatus { | ||||||
| 	switch strings.ToLower(strings.TrimSpace(status)) { | 	switch strings.ToLower(strings.TrimSpace(status)) { | ||||||
| 	case "unread": | 	case "unread": | ||||||
| 		return models.NotificationStatusUnread | 		return activities_model.NotificationStatusUnread | ||||||
| 	case "read": | 	case "read": | ||||||
| 		return models.NotificationStatusRead | 		return activities_model.NotificationStatusRead | ||||||
| 	case "pinned": | 	case "pinned": | ||||||
| 		return models.NotificationStatusPinned | 		return activities_model.NotificationStatusPinned | ||||||
| 	default: | 	default: | ||||||
| 		return 0 | 		return 0 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func statusStringsToNotificationStatuses(statuses, defaultStatuses []string) []models.NotificationStatus { | func statusStringsToNotificationStatuses(statuses, defaultStatuses []string) []activities_model.NotificationStatus { | ||||||
| 	if len(statuses) == 0 { | 	if len(statuses) == 0 { | ||||||
| 		statuses = defaultStatuses | 		statuses = defaultStatuses | ||||||
| 	} | 	} | ||||||
| 	results := make([]models.NotificationStatus, 0, len(statuses)) | 	results := make([]activities_model.NotificationStatus, 0, len(statuses)) | ||||||
| 	for _, status := range statuses { | 	for _, status := range statuses { | ||||||
| 		notificationStatus := statusStringToNotificationStatus(status) | 		notificationStatus := statusStringToNotificationStatus(status) | ||||||
| 		if notificationStatus > 0 { | 		if notificationStatus > 0 { | ||||||
| @@ -109,13 +109,13 @@ func ListRepoNotifications(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
| 	opts.RepoID = ctx.Repo.Repository.ID | 	opts.RepoID = ctx.Repo.Repository.ID | ||||||
|  |  | ||||||
| 	totalCount, err := models.CountNotifications(opts) | 	totalCount, err := activities_model.CountNotifications(opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	nl, err := models.GetNotifications(ctx, opts) | 	nl, err := activities_model.GetNotifications(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -192,7 +192,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opts := &models.FindNotificationOptions{ | 	opts := &activities_model.FindNotificationOptions{ | ||||||
| 		UserID:            ctx.Doer.ID, | 		UserID:            ctx.Doer.ID, | ||||||
| 		RepoID:            ctx.Repo.Repository.ID, | 		RepoID:            ctx.Repo.Repository.ID, | ||||||
| 		UpdatedBeforeUnix: lastRead, | 		UpdatedBeforeUnix: lastRead, | ||||||
| @@ -203,7 +203,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { | |||||||
| 		opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) | 		opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) | ||||||
| 		log.Error("%v", opts.Status) | 		log.Error("%v", opts.Status) | ||||||
| 	} | 	} | ||||||
| 	nl, err := models.GetNotifications(ctx, opts) | 	nl, err := activities_model.GetNotifications(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -211,13 +211,13 @@ func ReadRepoNotifications(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | ||||||
| 	if targetStatus == 0 { | 	if targetStatus == 0 { | ||||||
| 		targetStatus = models.NotificationStatusRead | 		targetStatus = activities_model.NotificationStatusRead | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	changed := make([]*structs.NotificationThread, 0, len(nl)) | 	changed := make([]*structs.NotificationThread, 0, len(nl)) | ||||||
|  |  | ||||||
| 	for _, n := range nl { | 	for _, n := range nl { | ||||||
| 		notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | 		notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.InternalServerError(err) | 			ctx.InternalServerError(err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -86,10 +86,10 @@ func ReadThread(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | ||||||
| 	if targetStatus == 0 { | 	if targetStatus == 0 { | ||||||
| 		targetStatus = models.NotificationStatusRead | 		targetStatus = activities_model.NotificationStatusRead | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | 	notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -101,8 +101,8 @@ func ReadThread(ctx *context.APIContext) { | |||||||
| 	ctx.JSON(http.StatusResetContent, convert.ToNotificationThread(notif)) | 	ctx.JSON(http.StatusResetContent, convert.ToNotificationThread(notif)) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getThread(ctx *context.APIContext) *models.Notification { | func getThread(ctx *context.APIContext) *activities_model.Notification { | ||||||
| 	n, err := models.GetNotificationByID(ctx.ParamsInt64(":id")) | 	n, err := activities_model.GetNotificationByID(ctx.ParamsInt64(":id")) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if db.IsErrNotExist(err) { | 		if db.IsErrNotExist(err) { | ||||||
| 			ctx.Error(http.StatusNotFound, "GetNotificationByID", err) | 			ctx.Error(http.StatusNotFound, "GetNotificationByID", err) | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	"code.gitea.io/gitea/modules/structs" | 	"code.gitea.io/gitea/modules/structs" | ||||||
| @@ -69,13 +69,13 @@ func ListNotifications(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	totalCount, err := models.CountNotifications(opts) | 	totalCount, err := activities_model.CountNotifications(opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	nl, err := models.GetNotifications(ctx, opts) | 	nl, err := activities_model.GetNotifications(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -140,7 +140,7 @@ func ReadNotifications(ctx *context.APIContext) { | |||||||
| 			lastRead = tmpLastRead.Unix() | 			lastRead = tmpLastRead.Unix() | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	opts := &models.FindNotificationOptions{ | 	opts := &activities_model.FindNotificationOptions{ | ||||||
| 		UserID:            ctx.Doer.ID, | 		UserID:            ctx.Doer.ID, | ||||||
| 		UpdatedBeforeUnix: lastRead, | 		UpdatedBeforeUnix: lastRead, | ||||||
| 	} | 	} | ||||||
| @@ -148,7 +148,7 @@ func ReadNotifications(ctx *context.APIContext) { | |||||||
| 		statuses := ctx.FormStrings("status-types") | 		statuses := ctx.FormStrings("status-types") | ||||||
| 		opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) | 		opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) | ||||||
| 	} | 	} | ||||||
| 	nl, err := models.GetNotifications(ctx, opts) | 	nl, err := activities_model.GetNotifications(ctx, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -156,13 +156,13 @@ func ReadNotifications(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | 	targetStatus := statusStringToNotificationStatus(ctx.FormString("to-status")) | ||||||
| 	if targetStatus == 0 { | 	if targetStatus == 0 { | ||||||
| 		targetStatus = models.NotificationStatusRead | 		targetStatus = activities_model.NotificationStatusRead | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	changed := make([]*structs.NotificationThread, 0, len(nl)) | 	changed := make([]*structs.NotificationThread, 0, len(nl)) | ||||||
|  |  | ||||||
| 	for _, n := range nl { | 	for _, n := range nl { | ||||||
| 		notif, err := models.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | 		notif, err := activities_model.SetNotificationStatus(n.ID, ctx.Doer, targetStatus) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.InternalServerError(err) | 			ctx.InternalServerError(err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/web" | 	"code.gitea.io/gitea/modules/web" | ||||||
| 	"code.gitea.io/gitea/routers/api/v1/user" | 	"code.gitea.io/gitea/routers/api/v1/user" | ||||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||||
|  | 	org_service "code.gitea.io/gitea/services/org" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ListTeams list all the teams of an organization | // ListTeams list all the teams of an organization | ||||||
| @@ -656,8 +657,8 @@ func AddTeamRepository(ctx *context.APIContext) { | |||||||
| 		ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") | 		ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err := models.AddRepository(ctx.Org.Team, repo); err != nil { | 	if err := org_service.TeamAddRepository(ctx.Org.Team, repo); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "AddRepository", err) | 		ctx.Error(http.StatusInternalServerError, "TeamAddRepository", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	ctx.Status(http.StatusNoContent) | 	ctx.Status(http.StatusNoContent) | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
|  | 	repo_module "code.gitea.io/gitea/modules/repository" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| 	"code.gitea.io/gitea/modules/web" | 	"code.gitea.io/gitea/modules/web" | ||||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||||
| @@ -174,7 +175,7 @@ func AddCollaborator(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.AddCollaborator(ctx.Repo.Repository, collaborator); err != nil { | 	if err := repo_module.AddCollaborator(ctx.Repo.Repository, collaborator); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "AddCollaborator", err) | 		ctx.Error(http.StatusInternalServerError, "AddCollaborator", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -170,7 +170,7 @@ func Migrate(ctx *context.APIContext) { | |||||||
| 		opts.Releases = false | 		opts.Releases = false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	repo, err := repo_module.CreateRepository(ctx.Doer, repoOwner, models.CreateRepoOptions{ | 	repo, err := repo_module.CreateRepository(ctx.Doer, repoOwner, repo_module.CreateRepoOptions{ | ||||||
| 		Name:           opts.RepoName, | 		Name:           opts.RepoName, | ||||||
| 		Description:    opts.Description, | 		Description:    opts.Description, | ||||||
| 		OriginalURL:    form.CloneAddr, | 		OriginalURL:    form.CloneAddr, | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	access_model "code.gitea.io/gitea/models/perm/access" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| @@ -753,7 +754,7 @@ func MergePullRequest(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	if ctx.IsSigned { | 	if ctx.IsSigned { | ||||||
| 		// Update issue-user. | 		// Update issue-user. | ||||||
| 		if err = models.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { | 		if err = activities_model.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "ReadBy", err) | 			ctx.Error(http.StatusInternalServerError, "ReadBy", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -49,12 +50,12 @@ func GetRelease(ctx *context.APIContext) { | |||||||
| 	//     "$ref": "#/responses/notFound" | 	//     "$ref": "#/responses/notFound" | ||||||
|  |  | ||||||
| 	id := ctx.ParamsInt64(":id") | 	id := ctx.ParamsInt64(":id") | ||||||
| 	release, err := models.GetReleaseByID(ctx, id) | 	release, err := repo_model.GetReleaseByID(ctx, id) | ||||||
| 	if err != nil && !models.IsErrReleaseNotExist(err) { | 	if err != nil && !repo_model.IsErrReleaseNotExist(err) { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err != nil && models.IsErrReleaseNotExist(err) || | 	if err != nil && repo_model.IsErrReleaseNotExist(err) || | ||||||
| 		release.IsTag || release.RepoID != ctx.Repo.Repository.ID { | 		release.IsTag || release.RepoID != ctx.Repo.Repository.ID { | ||||||
| 		ctx.NotFound() | 		ctx.NotFound() | ||||||
| 		return | 		return | ||||||
| @@ -114,7 +115,7 @@ func ListReleases(ctx *context.APIContext) { | |||||||
| 		listOptions.PageSize = ctx.FormInt("per_page") | 		listOptions.PageSize = ctx.FormInt("per_page") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	opts := models.FindReleasesOptions{ | 	opts := repo_model.FindReleasesOptions{ | ||||||
| 		ListOptions:   listOptions, | 		ListOptions:   listOptions, | ||||||
| 		IncludeDrafts: ctx.Repo.AccessMode >= perm.AccessModeWrite || ctx.Repo.UnitAccessMode(unit.TypeReleases) >= perm.AccessModeWrite, | 		IncludeDrafts: ctx.Repo.AccessMode >= perm.AccessModeWrite || ctx.Repo.UnitAccessMode(unit.TypeReleases) >= perm.AccessModeWrite, | ||||||
| 		IncludeTags:   false, | 		IncludeTags:   false, | ||||||
| @@ -122,7 +123,7 @@ func ListReleases(ctx *context.APIContext) { | |||||||
| 		IsPreRelease:  ctx.FormOptionalBool("pre-release"), | 		IsPreRelease:  ctx.FormOptionalBool("pre-release"), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) | 	releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) | 		ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) | ||||||
| 		return | 		return | ||||||
| @@ -136,7 +137,7 @@ func ListReleases(ctx *context.APIContext) { | |||||||
| 		rels[i] = convert.ToRelease(release) | 		rels[i] = convert.ToRelease(release) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	filteredCount, err := models.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts) | 	filteredCount, err := repo_model.CountReleasesByRepoID(ctx.Repo.Repository.ID, opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -179,9 +180,9 @@ func CreateRelease(ctx *context.APIContext) { | |||||||
| 	//   "409": | 	//   "409": | ||||||
| 	//     "$ref": "#/responses/error" | 	//     "$ref": "#/responses/error" | ||||||
| 	form := web.GetForm(ctx).(*api.CreateReleaseOption) | 	form := web.GetForm(ctx).(*api.CreateReleaseOption) | ||||||
| 	rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName) | 	rel, err := repo_model.GetRelease(ctx.Repo.Repository.ID, form.TagName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if !models.IsErrReleaseNotExist(err) { | 		if !repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "GetRelease", err) | 			ctx.Error(http.StatusInternalServerError, "GetRelease", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -189,7 +190,7 @@ func CreateRelease(ctx *context.APIContext) { | |||||||
| 		if len(form.Target) == 0 { | 		if len(form.Target) == 0 { | ||||||
| 			form.Target = ctx.Repo.Repository.DefaultBranch | 			form.Target = ctx.Repo.Repository.DefaultBranch | ||||||
| 		} | 		} | ||||||
| 		rel = &models.Release{ | 		rel = &repo_model.Release{ | ||||||
| 			RepoID:       ctx.Repo.Repository.ID, | 			RepoID:       ctx.Repo.Repository.ID, | ||||||
| 			PublisherID:  ctx.Doer.ID, | 			PublisherID:  ctx.Doer.ID, | ||||||
| 			Publisher:    ctx.Doer, | 			Publisher:    ctx.Doer, | ||||||
| @@ -203,7 +204,7 @@ func CreateRelease(ctx *context.APIContext) { | |||||||
| 			Repo:         ctx.Repo.Repository, | 			Repo:         ctx.Repo.Repository, | ||||||
| 		} | 		} | ||||||
| 		if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil { | 		if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil { | ||||||
| 			if models.IsErrReleaseAlreadyExist(err) { | 			if repo_model.IsErrReleaseAlreadyExist(err) { | ||||||
| 				ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) | 				ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) | ||||||
| 			} else { | 			} else { | ||||||
| 				ctx.Error(http.StatusInternalServerError, "CreateRelease", err) | 				ctx.Error(http.StatusInternalServerError, "CreateRelease", err) | ||||||
| @@ -272,12 +273,12 @@ func EditRelease(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	form := web.GetForm(ctx).(*api.EditReleaseOption) | 	form := web.GetForm(ctx).(*api.EditReleaseOption) | ||||||
| 	id := ctx.ParamsInt64(":id") | 	id := ctx.ParamsInt64(":id") | ||||||
| 	rel, err := models.GetReleaseByID(ctx, id) | 	rel, err := repo_model.GetReleaseByID(ctx, id) | ||||||
| 	if err != nil && !models.IsErrReleaseNotExist(err) { | 	if err != nil && !repo_model.IsErrReleaseNotExist(err) { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err != nil && models.IsErrReleaseNotExist(err) || | 	if err != nil && repo_model.IsErrReleaseNotExist(err) || | ||||||
| 		rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { | 		rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { | ||||||
| 		ctx.NotFound() | 		ctx.NotFound() | ||||||
| 		return | 		return | ||||||
| @@ -307,7 +308,7 @@ func EditRelease(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// reload data from database | 	// reload data from database | ||||||
| 	rel, err = models.GetReleaseByID(ctx, id) | 	rel, err = repo_model.GetReleaseByID(ctx, id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | ||||||
| 		return | 		return | ||||||
| @@ -350,12 +351,12 @@ func DeleteRelease(ctx *context.APIContext) { | |||||||
| 	//     "$ref": "#/responses/empty" | 	//     "$ref": "#/responses/empty" | ||||||
|  |  | ||||||
| 	id := ctx.ParamsInt64(":id") | 	id := ctx.ParamsInt64(":id") | ||||||
| 	rel, err := models.GetReleaseByID(ctx, id) | 	rel, err := repo_model.GetReleaseByID(ctx, id) | ||||||
| 	if err != nil && !models.IsErrReleaseNotExist(err) { | 	if err != nil && !repo_model.IsErrReleaseNotExist(err) { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | 		ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if err != nil && models.IsErrReleaseNotExist(err) || | 	if err != nil && repo_model.IsErrReleaseNotExist(err) || | ||||||
| 		rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { | 		rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID { | ||||||
| 		ctx.NotFound() | 		ctx.NotFound() | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ package repo | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -102,9 +101,9 @@ func ListReleaseAttachments(ctx *context.APIContext) { | |||||||
| 	//     "$ref": "#/responses/AttachmentList" | 	//     "$ref": "#/responses/AttachmentList" | ||||||
|  |  | ||||||
| 	releaseID := ctx.ParamsInt64(":id") | 	releaseID := ctx.ParamsInt64(":id") | ||||||
| 	release, err := models.GetReleaseByID(ctx, releaseID) | 	release, err := repo_model.GetReleaseByID(ctx, releaseID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		if repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -172,9 +171,9 @@ func CreateReleaseAttachment(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	// Check if release exists an load release | 	// Check if release exists an load release | ||||||
| 	releaseID := ctx.ParamsInt64(":id") | 	releaseID := ctx.ParamsInt64(":id") | ||||||
| 	release, err := models.GetReleaseByID(ctx, releaseID) | 	release, err := repo_model.GetReleaseByID(ctx, releaseID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		if repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	releaseservice "code.gitea.io/gitea/services/release" | 	releaseservice "code.gitea.io/gitea/services/release" | ||||||
| @@ -44,9 +45,9 @@ func GetReleaseByTag(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	tag := ctx.Params(":tag") | 	tag := ctx.Params(":tag") | ||||||
|  |  | ||||||
| 	release, err := models.GetRelease(ctx.Repo.Repository.ID, tag) | 	release, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tag) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		if repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -97,9 +98,9 @@ func DeleteReleaseByTag(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	tag := ctx.Params(":tag") | 	tag := ctx.Params(":tag") | ||||||
|  |  | ||||||
| 	release, err := models.GetRelease(ctx.Repo.Repository.ID, tag) | 	release, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tag) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		if repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
| @@ -232,7 +231,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre | |||||||
| 	if opt.AutoInit && opt.Readme == "" { | 	if opt.AutoInit && opt.Readme == "" { | ||||||
| 		opt.Readme = "Default" | 		opt.Readme = "Default" | ||||||
| 	} | 	} | ||||||
| 	repo, err := repo_service.CreateRepository(ctx.Doer, owner, models.CreateRepoOptions{ | 	repo, err := repo_service.CreateRepository(ctx.Doer, owner, repo_module.CreateRepoOptions{ | ||||||
| 		Name:          opt.Name, | 		Name:          opt.Name, | ||||||
| 		Description:   opt.Description, | 		Description:   opt.Description, | ||||||
| 		IssueLabels:   opt.IssueLabels, | 		IssueLabels:   opt.IssueLabels, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| @@ -249,9 +250,9 @@ func DeleteTag(ctx *context.APIContext) { | |||||||
| 	//     "$ref": "#/responses/conflict" | 	//     "$ref": "#/responses/conflict" | ||||||
| 	tagName := ctx.Params("*") | 	tagName := ctx.Params("*") | ||||||
|  |  | ||||||
| 	tag, err := models.GetRelease(ctx.Repo.Repository.ID, tagName) | 	tag, err := repo_model.GetRelease(ctx.Repo.Repository.ID, tagName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if models.IsErrReleaseNotExist(err) { | 		if repo_model.IsErrReleaseNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
|  | 	org_service "code.gitea.io/gitea/services/org" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ListTeams list a repository's teams | // ListTeams list a repository's teams | ||||||
| @@ -199,7 +200,7 @@ func changeRepoTeam(ctx *context.APIContext, add bool) { | |||||||
| 			ctx.Error(http.StatusUnprocessableEntity, "alreadyAdded", fmt.Errorf("team '%s' is already added to repo", team.Name)) | 			ctx.Error(http.StatusUnprocessableEntity, "alreadyAdded", fmt.Errorf("team '%s' is already added to repo", team.Name)) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		err = models.AddRepository(team, ctx.Repo.Repository) | 		err = org_service.TeamAddRepository(team, ctx.Repo.Repository) | ||||||
| 	} else { | 	} else { | ||||||
| 		if !repoHasTeam { | 		if !repoHasTeam { | ||||||
| 			ctx.Error(http.StatusUnprocessableEntity, "notAdded", fmt.Errorf("team '%s' was not added to repo", team.Name)) | 			ctx.Error(http.StatusUnprocessableEntity, "notAdded", fmt.Errorf("team '%s' was not added to repo", team.Name)) | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| @@ -72,9 +72,9 @@ func NewWikiPage(ctx *context.APIContext) { | |||||||
| 	form.ContentBase64 = string(content) | 	form.ContentBase64 = string(content) | ||||||
|  |  | ||||||
| 	if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil { | 	if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil { | ||||||
| 		if models.IsErrWikiReservedName(err) { | 		if repo_model.IsErrWikiReservedName(err) { | ||||||
| 			ctx.Error(http.StatusBadRequest, "IsErrWikiReservedName", err) | 			ctx.Error(http.StatusBadRequest, "IsErrWikiReservedName", err) | ||||||
| 		} else if models.IsErrWikiAlreadyExist(err) { | 		} else if repo_model.IsErrWikiAlreadyExist(err) { | ||||||
| 			ctx.Error(http.StatusBadRequest, "IsErrWikiAlreadyExists", err) | 			ctx.Error(http.StatusBadRequest, "IsErrWikiAlreadyExists", err) | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "AddWikiPage", err) | 			ctx.Error(http.StatusInternalServerError, "AddWikiPage", err) | ||||||
| @@ -314,7 +314,7 @@ func ListWikiPages(ctx *context.APIContext) { | |||||||
| 		} | 		} | ||||||
| 		wikiName, err := wiki_service.FilenameToName(entry.Name()) | 		wikiName, err := wiki_service.FilenameToName(entry.Name()) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if models.IsErrWikiInvalidFileName(err) { | 			if repo_model.IsErrWikiInvalidFileName(err) { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) | 			ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| package swagger | package swagger | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -40,7 +40,7 @@ type swaggerModelEditUserOption struct { | |||||||
| // swagger:response UserHeatmapData | // swagger:response UserHeatmapData | ||||||
| type swaggerResponseUserHeatmapData struct { | type swaggerResponseUserHeatmapData struct { | ||||||
| 	// in:body | 	// in:body | ||||||
| 	Body []models.UserHeatmapData `json:"body"` | 	Body []activities_model.UserHeatmapData `json:"body"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // UserSettings | // UserSettings | ||||||
|   | |||||||
| @@ -11,8 +11,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	auth_model "code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/auth" |  | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| @@ -45,14 +44,14 @@ func ListAccessTokens(ctx *context.APIContext) { | |||||||
| 	//   "200": | 	//   "200": | ||||||
| 	//     "$ref": "#/responses/AccessTokenList" | 	//     "$ref": "#/responses/AccessTokenList" | ||||||
|  |  | ||||||
| 	opts := models.ListAccessTokensOptions{UserID: ctx.Doer.ID, ListOptions: utils.GetListOptions(ctx)} | 	opts := auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID, ListOptions: utils.GetListOptions(ctx)} | ||||||
|  |  | ||||||
| 	count, err := models.CountAccessTokens(opts) | 	count, err := auth_model.CountAccessTokens(opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	tokens, err := models.ListAccessTokens(opts) | 	tokens, err := auth_model.ListAccessTokens(opts) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -98,12 +97,12 @@ func CreateAccessToken(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	form := web.GetForm(ctx).(*api.CreateAccessTokenOption) | 	form := web.GetForm(ctx).(*api.CreateAccessTokenOption) | ||||||
|  |  | ||||||
| 	t := &models.AccessToken{ | 	t := &auth_model.AccessToken{ | ||||||
| 		UID:  ctx.Doer.ID, | 		UID:  ctx.Doer.ID, | ||||||
| 		Name: form.Name, | 		Name: form.Name, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	exist, err := models.AccessTokenByNameExists(t) | 	exist, err := auth_model.AccessTokenByNameExists(t) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| @@ -113,7 +112,7 @@ func CreateAccessToken(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NewAccessToken(t); err != nil { | 	if err := auth_model.NewAccessToken(t); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) | 		ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -155,7 +154,7 @@ func DeleteAccessToken(ctx *context.APIContext) { | |||||||
| 	tokenID, _ := strconv.ParseInt(token, 0, 64) | 	tokenID, _ := strconv.ParseInt(token, 0, 64) | ||||||
|  |  | ||||||
| 	if tokenID == 0 { | 	if tokenID == 0 { | ||||||
| 		tokens, err := models.ListAccessTokens(models.ListAccessTokensOptions{ | 		tokens, err := auth_model.ListAccessTokens(auth_model.ListAccessTokensOptions{ | ||||||
| 			Name:   token, | 			Name:   token, | ||||||
| 			UserID: ctx.Doer.ID, | 			UserID: ctx.Doer.ID, | ||||||
| 		}) | 		}) | ||||||
| @@ -180,8 +179,8 @@ func DeleteAccessToken(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.DeleteAccessTokenByID(tokenID, ctx.Doer.ID); err != nil { | 	if err := auth_model.DeleteAccessTokenByID(tokenID, ctx.Doer.ID); err != nil { | ||||||
| 		if models.IsErrAccessTokenNotExist(err) { | 		if auth_model.IsErrAccessTokenNotExist(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "DeleteAccessTokenByID", err) | 			ctx.Error(http.StatusInternalServerError, "DeleteAccessTokenByID", err) | ||||||
| @@ -213,7 +212,7 @@ func CreateOauth2Application(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) | 	data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) | ||||||
|  |  | ||||||
| 	app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ | 	app, err := auth_model.CreateOAuth2Application(ctx, auth_model.CreateOAuth2ApplicationOptions{ | ||||||
| 		Name:         data.Name, | 		Name:         data.Name, | ||||||
| 		UserID:       ctx.Doer.ID, | 		UserID:       ctx.Doer.ID, | ||||||
| 		RedirectURIs: data.RedirectURIs, | 		RedirectURIs: data.RedirectURIs, | ||||||
| @@ -252,7 +251,7 @@ func ListOauth2Applications(ctx *context.APIContext) { | |||||||
| 	//   "200": | 	//   "200": | ||||||
| 	//     "$ref": "#/responses/OAuth2ApplicationList" | 	//     "$ref": "#/responses/OAuth2ApplicationList" | ||||||
|  |  | ||||||
| 	apps, total, err := auth.ListOAuth2Applications(ctx.Doer.ID, utils.GetListOptions(ctx)) | 	apps, total, err := auth_model.ListOAuth2Applications(ctx.Doer.ID, utils.GetListOptions(ctx)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) | 		ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) | ||||||
| 		return | 		return | ||||||
| @@ -288,8 +287,8 @@ func DeleteOauth2Application(ctx *context.APIContext) { | |||||||
| 	//   "404": | 	//   "404": | ||||||
| 	//     "$ref": "#/responses/notFound" | 	//     "$ref": "#/responses/notFound" | ||||||
| 	appID := ctx.ParamsInt64(":id") | 	appID := ctx.ParamsInt64(":id") | ||||||
| 	if err := auth.DeleteOAuth2Application(appID, ctx.Doer.ID); err != nil { | 	if err := auth_model.DeleteOAuth2Application(appID, ctx.Doer.ID); err != nil { | ||||||
| 		if auth.IsErrOAuthApplicationNotFound(err) { | 		if auth_model.IsErrOAuthApplicationNotFound(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err) | 			ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err) | ||||||
| @@ -320,9 +319,9 @@ func GetOauth2Application(ctx *context.APIContext) { | |||||||
| 	//   "404": | 	//   "404": | ||||||
| 	//     "$ref": "#/responses/notFound" | 	//     "$ref": "#/responses/notFound" | ||||||
| 	appID := ctx.ParamsInt64(":id") | 	appID := ctx.ParamsInt64(":id") | ||||||
| 	app, err := auth.GetOAuth2ApplicationByID(ctx, appID) | 	app, err := auth_model.GetOAuth2ApplicationByID(ctx, appID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if auth.IsErrOauthClientIDInvalid(err) || auth.IsErrOAuthApplicationNotFound(err) { | 		if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "GetOauth2ApplicationByID", err) | 			ctx.Error(http.StatusInternalServerError, "GetOauth2ApplicationByID", err) | ||||||
| @@ -363,14 +362,14 @@ func UpdateOauth2Application(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| 	data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) | 	data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) | ||||||
|  |  | ||||||
| 	app, err := auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ | 	app, err := auth_model.UpdateOAuth2Application(auth_model.UpdateOAuth2ApplicationOptions{ | ||||||
| 		Name:         data.Name, | 		Name:         data.Name, | ||||||
| 		UserID:       ctx.Doer.ID, | 		UserID:       ctx.Doer.ID, | ||||||
| 		ID:           appID, | 		ID:           appID, | ||||||
| 		RedirectURIs: data.RedirectURIs, | 		RedirectURIs: data.RedirectURIs, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if auth.IsErrOauthClientIDInvalid(err) || auth.IsErrOAuthApplicationNotFound(err) { | 		if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { | ||||||
| 			ctx.NotFound() | 			ctx.NotFound() | ||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "UpdateOauth2ApplicationByID", err) | 			ctx.Error(http.StatusInternalServerError, "UpdateOauth2ApplicationByID", err) | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ package user | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -139,7 +139,7 @@ func GetUserHeatmapData(ctx *context.APIContext) { | |||||||
| 	//   "404": | 	//   "404": | ||||||
| 	//     "$ref": "#/responses/notFound" | 	//     "$ref": "#/responses/notFound" | ||||||
|  |  | ||||||
| 	heatmap, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) | 	heatmap, err := activities_model.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err) | 		ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	activities_model "code.gitea.io/gitea/models/activities" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| @@ -128,7 +128,7 @@ func Dashboard(ctx *context.Context) { | |||||||
| 	ctx.Data["Title"] = ctx.Tr("admin.dashboard") | 	ctx.Data["Title"] = ctx.Tr("admin.dashboard") | ||||||
| 	ctx.Data["PageIsAdmin"] = true | 	ctx.Data["PageIsAdmin"] = true | ||||||
| 	ctx.Data["PageIsAdminDashboard"] = true | 	ctx.Data["PageIsAdminDashboard"] = true | ||||||
| 	ctx.Data["Stats"] = models.GetStatistic() | 	ctx.Data["Stats"] = activities_model.GetStatistic() | ||||||
| 	ctx.Data["NeedUpdate"] = updatechecker.GetNeedUpdate() | 	ctx.Data["NeedUpdate"] = updatechecker.GetNeedUpdate() | ||||||
| 	ctx.Data["RemoteVersion"] = updatechecker.GetRemoteVersion() | 	ctx.Data["RemoteVersion"] = updatechecker.GetRemoteVersion() | ||||||
| 	// FIXME: update periodically | 	// FIXME: update periodically | ||||||
| @@ -144,7 +144,7 @@ func DashboardPost(ctx *context.Context) { | |||||||
| 	ctx.Data["Title"] = ctx.Tr("admin.dashboard") | 	ctx.Data["Title"] = ctx.Tr("admin.dashboard") | ||||||
| 	ctx.Data["PageIsAdmin"] = true | 	ctx.Data["PageIsAdmin"] = true | ||||||
| 	ctx.Data["PageIsAdminDashboard"] = true | 	ctx.Data["PageIsAdminDashboard"] = true | ||||||
| 	ctx.Data["Stats"] = models.GetStatistic() | 	ctx.Data["Stats"] = activities_model.GetStatistic() | ||||||
| 	updateSystemStatus() | 	updateSystemStatus() | ||||||
| 	ctx.Data["SysStatus"] = sysStatus | 	ctx.Data["SysStatus"] = sysStatus | ||||||
|  |  | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user