Skip to content

Commit 3db4a70

Browse files
authored
Merge branch 'main' into prev-next-conversation
2 parents 164c31f + 9b1b4b5 commit 3db4a70

File tree

31 files changed

+278
-243
lines changed

31 files changed

+278
-243
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ Kyle Dumont <[email protected]> (@kdumontnu)
4343
Patrick Schratz <[email protected]> (@pat-s)
4444
Janis Estelmann <[email protected]> (@KN4CK3R)
4545
Steven Kriegler <[email protected]> (@justusbunsi)
46+
Jimmy Praet <[email protected]> (@jpraet)

custom/conf/app.example.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,9 @@ PATH =
656656
;; Public is for users visible for everyone
657657
;DEFAULT_USER_VISIBILITY = public
658658
;;
659+
;; Set whitch visibibilty modes a user can have
660+
;ALLOWED_USER_VISIBILITY_MODES = public,limited,private
661+
;;
659662
;; Either "public", "limited" or "private", default is "public"
660663
;; Limited is for organizations visible only to signed users
661664
;; Private is for organizations visible only to members of the organization

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ relation to port exhaustion.
513513
- `AUTO_WATCH_NEW_REPOS`: **true**: Enable this to let all organisation users watch new repos when they are created
514514
- `AUTO_WATCH_ON_CHANGES`: **false**: Enable this to make users watch a repository after their first commit to it
515515
- `DEFAULT_USER_VISIBILITY`: **public**: Set default visibility mode for users, either "public", "limited" or "private".
516+
- `ALLOWED_USER_VISIBILITY_MODES`: **public,limited,private**: Set whitch visibibilty modes a user can have
516517
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
517518
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
518519
- `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via gitea.

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ var migrations = []Migration{
323323
NewMigration("Add new table repo_archiver", addRepoArchiver),
324324
// v186 -> v187
325325
NewMigration("Create protected tag table", createProtectedTagTable),
326+
// v187 -> v188
327+
NewMigration("Drop unneeded webhook related columns", dropWebhookColumns),
326328
}
327329

328330
// GetCurrentDBVersion returns the current db version

models/migrations/v187.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"xorm.io/xorm"
9+
)
10+
11+
func dropWebhookColumns(x *xorm.Engine) error {
12+
// Make sure the columns exist before dropping them
13+
type Webhook struct {
14+
Signature string `xorm:"TEXT"`
15+
IsSSL bool `xorm:"is_ssl"`
16+
}
17+
if err := x.Sync2(new(Webhook)); err != nil {
18+
return err
19+
}
20+
21+
type HookTask struct {
22+
Typ string `xorm:"VARCHAR(16) index"`
23+
URL string `xorm:"TEXT"`
24+
Signature string `xorm:"TEXT"`
25+
HTTPMethod string `xorm:"http_method"`
26+
ContentType int
27+
IsSSL bool
28+
}
29+
if err := x.Sync2(new(HookTask)); err != nil {
30+
return err
31+
}
32+
33+
sess := x.NewSession()
34+
defer sess.Close()
35+
if err := sess.Begin(); err != nil {
36+
return err
37+
}
38+
if err := dropTableColumns(sess, "webhook", "signature", "is_ssl"); err != nil {
39+
return err
40+
}
41+
if err := dropTableColumns(sess, "hook_task", "typ", "url", "signature", "http_method", "content_type", "is_ssl"); err != nil {
42+
return err
43+
}
44+
45+
return sess.Commit()
46+
}

models/user.go

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -863,26 +863,36 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
863863
return err
864864
}
865865

866+
// set system defaults
867+
u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
868+
u.Visibility = setting.Service.DefaultUserVisibilityMode
869+
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation
870+
u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification
871+
u.MaxRepoCreation = -1
872+
u.Theme = setting.UI.DefaultTheme
873+
874+
// overwrite defaults if set
875+
if len(overwriteDefault) != 0 && overwriteDefault[0] != nil {
876+
u.Visibility = overwriteDefault[0].Visibility
877+
}
878+
866879
sess := x.NewSession()
867880
defer sess.Close()
868881
if err = sess.Begin(); err != nil {
869882
return err
870883
}
871884

872-
isExist, err := isUserExist(sess, 0, u.Name)
873-
if err != nil {
874-
return err
875-
} else if isExist {
876-
return ErrUserAlreadyExist{u.Name}
877-
}
885+
// validate data
878886

879-
if err = deleteUserRedirect(sess, u.Name); err != nil {
887+
if err := validateUser(u); err != nil {
880888
return err
881889
}
882890

883-
u.Email = strings.ToLower(u.Email)
884-
if err = ValidateEmail(u.Email); err != nil {
891+
isExist, err := isUserExist(sess, 0, u.Name)
892+
if err != nil {
885893
return err
894+
} else if isExist {
895+
return ErrUserAlreadyExist{u.Name}
886896
}
887897

888898
isExist, err = isEmailUsed(sess, u.Email)
@@ -892,6 +902,8 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
892902
return ErrEmailAlreadyUsed{u.Email}
893903
}
894904

905+
// prepare for database
906+
895907
u.LowerName = strings.ToLower(u.Name)
896908
u.AvatarEmail = u.Email
897909
if u.Rands, err = GetUserSalt(); err != nil {
@@ -901,16 +913,10 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
901913
return err
902914
}
903915

904-
// set system defaults
905-
u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
906-
u.Visibility = setting.Service.DefaultUserVisibilityMode
907-
u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation
908-
u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification
909-
u.MaxRepoCreation = -1
910-
u.Theme = setting.UI.DefaultTheme
911-
// overwrite defaults if set
912-
if len(overwriteDefault) != 0 && overwriteDefault[0] != nil {
913-
u.Visibility = overwriteDefault[0].Visibility
916+
// save changes to database
917+
918+
if err = deleteUserRedirect(sess, u.Name); err != nil {
919+
return err
914920
}
915921

916922
if _, err = sess.Insert(u); err != nil {
@@ -1056,12 +1062,22 @@ func checkDupEmail(e Engine, u *User) error {
10561062
return nil
10571063
}
10581064

1059-
func updateUser(e Engine, u *User) (err error) {
1065+
// validateUser check if user is valide to insert / update into database
1066+
func validateUser(u *User) error {
1067+
if !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(u.Visibility) {
1068+
return fmt.Errorf("visibility Mode not allowed: %s", u.Visibility.String())
1069+
}
1070+
10601071
u.Email = strings.ToLower(u.Email)
1061-
if err = ValidateEmail(u.Email); err != nil {
1072+
return ValidateEmail(u.Email)
1073+
}
1074+
1075+
func updateUser(e Engine, u *User) error {
1076+
if err := validateUser(u); err != nil {
10621077
return err
10631078
}
1064-
_, err = e.ID(u.ID).AllCols().Update(u)
1079+
1080+
_, err := e.ID(u.ID).AllCols().Update(u)
10651081
return err
10661082
}
10671083

@@ -1076,6 +1092,10 @@ func UpdateUserCols(u *User, cols ...string) error {
10761092
}
10771093

10781094
func updateUserCols(e Engine, u *User, cols ...string) error {
1095+
if err := validateUser(u); err != nil {
1096+
return err
1097+
}
1098+
10791099
_, err := e.ID(u.ID).Cols(cols...).Update(u)
10801100
return err
10811101
}

models/user_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212

1313
"code.gitea.io/gitea/modules/setting"
14+
"code.gitea.io/gitea/modules/structs"
1415
"code.gitea.io/gitea/modules/util"
1516

1617
"github.com/stretchr/testify/assert"
@@ -189,6 +190,7 @@ func TestDeleteUser(t *testing.T) {
189190

190191
func TestEmailNotificationPreferences(t *testing.T) {
191192
assert.NoError(t, PrepareTestDatabase())
193+
192194
for _, test := range []struct {
193195
expected string
194196
userID int64
@@ -467,3 +469,23 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ib
467469
}
468470
}
469471
}
472+
473+
func TestUpdateUser(t *testing.T) {
474+
assert.NoError(t, PrepareTestDatabase())
475+
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
476+
477+
user.KeepActivityPrivate = true
478+
assert.NoError(t, UpdateUser(user))
479+
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
480+
assert.True(t, user.KeepActivityPrivate)
481+
482+
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
483+
user.KeepActivityPrivate = false
484+
user.Visibility = structs.VisibleTypePrivate
485+
assert.Error(t, UpdateUser(user))
486+
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
487+
assert.True(t, user.KeepActivityPrivate)
488+
489+
user.Email = "no [email protected]"
490+
assert.Error(t, UpdateUser(user))
491+
}

models/webhook.go

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,22 @@ type HookEvent struct {
109109
HookEvents `json:"events"`
110110
}
111111

112+
// HookType is the type of a webhook
113+
type HookType = string
114+
115+
// Types of webhooks
116+
const (
117+
GITEA HookType = "gitea"
118+
GOGS HookType = "gogs"
119+
SLACK HookType = "slack"
120+
DISCORD HookType = "discord"
121+
DINGTALK HookType = "dingtalk"
122+
TELEGRAM HookType = "telegram"
123+
MSTEAMS HookType = "msteams"
124+
FEISHU HookType = "feishu"
125+
MATRIX HookType = "matrix"
126+
)
127+
112128
// HookStatus is the status of a web hook
113129
type HookStatus int
114130

@@ -126,17 +142,15 @@ type Webhook struct {
126142
OrgID int64 `xorm:"INDEX"`
127143
IsSystemWebhook bool
128144
URL string `xorm:"url TEXT"`
129-
Signature string `xorm:"TEXT"`
130145
HTTPMethod string `xorm:"http_method"`
131146
ContentType HookContentType
132147
Secret string `xorm:"TEXT"`
133148
Events string `xorm:"TEXT"`
134149
*HookEvent `xorm:"-"`
135-
IsSSL bool `xorm:"is_ssl"`
136-
IsActive bool `xorm:"INDEX"`
137-
Type HookTaskType `xorm:"VARCHAR(16) 'type'"`
138-
Meta string `xorm:"TEXT"` // store hook-specific attributes
139-
LastStatus HookStatus // Last delivery status
150+
IsActive bool `xorm:"INDEX"`
151+
Type HookType `xorm:"VARCHAR(16) 'type'"`
152+
Meta string `xorm:"TEXT"` // store hook-specific attributes
153+
LastStatus HookStatus // Last delivery status
140154

141155
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
142156
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
@@ -558,22 +572,6 @@ func copyDefaultWebhooksToRepo(e Engine, repoID int64) error {
558572
// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
559573
// \/ \/ \/ \/ \/
560574

561-
// HookTaskType is the type of an hook task
562-
type HookTaskType = string
563-
564-
// Types of hook tasks
565-
const (
566-
GITEA HookTaskType = "gitea"
567-
GOGS HookTaskType = "gogs"
568-
SLACK HookTaskType = "slack"
569-
DISCORD HookTaskType = "discord"
570-
DINGTALK HookTaskType = "dingtalk"
571-
TELEGRAM HookTaskType = "telegram"
572-
MSTEAMS HookTaskType = "msteams"
573-
FEISHU HookTaskType = "feishu"
574-
MATRIX HookTaskType = "matrix"
575-
)
576-
577575
// HookEventType is the type of an hook event
578576
type HookEventType string
579577

@@ -635,7 +633,9 @@ func (h HookEventType) Event() string {
635633

636634
// HookRequest represents hook task request information.
637635
type HookRequest struct {
638-
Headers map[string]string `json:"headers"`
636+
URL string `json:"url"`
637+
HTTPMethod string `json:"http_method"`
638+
Headers map[string]string `json:"headers"`
639639
}
640640

641641
// HookResponse represents hook task response information.
@@ -651,15 +651,9 @@ type HookTask struct {
651651
RepoID int64 `xorm:"INDEX"`
652652
HookID int64
653653
UUID string
654-
Typ HookTaskType `xorm:"VARCHAR(16) index"`
655-
URL string `xorm:"TEXT"`
656-
Signature string `xorm:"TEXT"`
657654
api.Payloader `xorm:"-"`
658655
PayloadContent string `xorm:"TEXT"`
659-
HTTPMethod string `xorm:"http_method"`
660-
ContentType HookContentType
661656
EventType HookEventType
662-
IsSSL bool
663657
IsDelivered bool
664658
Delivered int64
665659
DeliveredString string `xorm:"-"`

models/webhook_test.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,6 @@ func TestCreateHookTask(t *testing.T) {
207207
hookTask := &HookTask{
208208
RepoID: 3,
209209
HookID: 3,
210-
Typ: GITEA,
211-
URL: "http://www.example.com/unit_test",
212210
Payloader: &api.PushPayload{},
213211
}
214212
AssertNotExistsBean(t, hookTask)
@@ -233,8 +231,6 @@ func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
233231
hookTask := &HookTask{
234232
RepoID: 3,
235233
HookID: 3,
236-
Typ: GITEA,
237-
URL: "http://www.example.com/unit_test",
238234
Payloader: &api.PushPayload{},
239235
IsDelivered: true,
240236
Delivered: time.Now().UnixNano(),
@@ -252,8 +248,6 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) {
252248
hookTask := &HookTask{
253249
RepoID: 2,
254250
HookID: 4,
255-
Typ: GITEA,
256-
URL: "http://www.example.com/unit_test",
257251
Payloader: &api.PushPayload{},
258252
IsDelivered: false,
259253
}
@@ -270,8 +264,6 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
270264
hookTask := &HookTask{
271265
RepoID: 2,
272266
HookID: 4,
273-
Typ: GITEA,
274-
URL: "http://www.example.com/unit_test",
275267
Payloader: &api.PushPayload{},
276268
IsDelivered: true,
277269
Delivered: time.Now().UnixNano(),
@@ -289,8 +281,6 @@ func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
289281
hookTask := &HookTask{
290282
RepoID: 3,
291283
HookID: 3,
292-
Typ: GITEA,
293-
URL: "http://www.example.com/unit_test",
294284
Payloader: &api.PushPayload{},
295285
IsDelivered: true,
296286
Delivered: time.Now().AddDate(0, 0, -8).UnixNano(),
@@ -308,8 +298,6 @@ func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) {
308298
hookTask := &HookTask{
309299
RepoID: 2,
310300
HookID: 4,
311-
Typ: GITEA,
312-
URL: "http://www.example.com/unit_test",
313301
Payloader: &api.PushPayload{},
314302
IsDelivered: false,
315303
}
@@ -326,8 +314,6 @@ func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *test
326314
hookTask := &HookTask{
327315
RepoID: 2,
328316
HookID: 4,
329-
Typ: GITEA,
330-
URL: "http://www.example.com/unit_test",
331317
Payloader: &api.PushPayload{},
332318
IsDelivered: true,
333319
Delivered: time.Now().AddDate(0, 0, -6).UnixNano(),

0 commit comments

Comments
 (0)