Skip to content

Commit c868372

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Prevent security failure due to bad APP_ID (go-gitea#18678) [skip ci] Updated translations via Crowdin Let `MinUnitAccessMode` return correct perm (go-gitea#18675) Simplify Boost/Pause logic (go-gitea#18673) update the comparison documents (go-gitea#18669) Restart zero worker if there is still work to do (go-gitea#18658)
2 parents 06817b1 + 2f76608 commit c868372

File tree

8 files changed

+90
-25
lines changed

8 files changed

+90
-25
lines changed

docs/content/doc/features/comparison.en-us.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ _Symbols used in table:_
5050
| Repository Tokens with write rights ||||||||
5151
| Built-in Container Registry | [](https://github.com/go-gitea/gitea/issues/2316) |||||||
5252
| External git mirroring ||||||||
53-
| FIDO U2F (2FA) ||||||| |
53+
| WebAuthn (2FA) ||||||| ? |
5454
| Built-in CI/CD ||||||||
5555
| Subgroups: groups within groups ||||||||
5656

@@ -66,6 +66,7 @@ _Symbols used in table:_
6666
| Granular user roles (Code, Issues, Wiki etc) ||||||||
6767
| Verified Committer ||| ? |||||
6868
| GPG Signed Commits ||||||||
69+
| SSH Signed Commits |||||| ? | ? |
6970
| Reject unsigned commits | [](https://github.com/go-gitea/gitea/pull/9708) |||||||
7071
| Repository Activity page ||||||||
7172
| Branch manager ||||||||

docs/content/doc/features/comparison.zh-cn.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ _表格中的符号含义:_
4848
| 仓库写权限令牌 ||||||||
4949
| 内置容器 Registry ||||||||
5050
| 外部 Git 镜像 ||||||||
51-
| FIDO U2F (2FA) ||||||| |
51+
| WebAuthn (2FA) | ||||| | ? |
5252
| 内置 CI/CD ||||||||
5353
| 子组织:组织内的组织 ||||||||
5454

@@ -64,6 +64,7 @@ _表格中的符号含义:_
6464
| 细粒度用户角色 (例如 Code, Issues, Wiki) ||||||||
6565
| 提交人的身份验证 ||| ? |||||
6666
| GPG 签名的提交 ||||||||
67+
| SSH 签名的提交 |||||| ? | ? |
6768
| 拒绝未用通过验证的提交 ||||||||
6869
| 仓库活跃度页面 ||||||||
6970
| 分支管理 ||||||||

models/unit/unit.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,12 @@ func AllUnitKeyNames() []string {
328328
// MinUnitAccessMode returns the minial permission of the permission map
329329
func MinUnitAccessMode(unitsMap map[Type]perm.AccessMode) perm.AccessMode {
330330
res := perm.AccessModeNone
331-
for _, mode := range unitsMap {
331+
for t, mode := range unitsMap {
332+
// Don't allow `TypeExternal{Tracker,Wiki}` to influence this as they can only be set to READ perms.
333+
if t == TypeExternalTracker || t == TypeExternalWiki {
334+
continue
335+
}
336+
332337
// get the minial permission great than AccessModeNone except all are AccessModeNone
333338
if mode > perm.AccessModeNone && (res == perm.AccessModeNone || mode < res) {
334339
res = mode

modules/queue/workerpool.go

+43-10
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ func (p *WorkerPool) hasNoWorkerScaling() bool {
115115
return p.numberOfWorkers == 0 && (p.boostTimeout == 0 || p.boostWorkers == 0 || p.maxNumberOfWorkers == 0)
116116
}
117117

118+
// zeroBoost will add a temporary boost worker for a no worker queue
119+
// p.lock must be locked at the start of this function BUT it will be unlocked by the end of this function
120+
// (This is because addWorkers has to be called whilst unlocked)
118121
func (p *WorkerPool) zeroBoost() {
119122
ctx, cancel := context.WithTimeout(p.baseCtx, p.boostTimeout)
120123
mq := GetManager().GetManagedQueue(p.qid)
@@ -305,16 +308,23 @@ func (p *WorkerPool) addWorkers(ctx context.Context, cancel context.CancelFunc,
305308
p.cond.Broadcast()
306309
cancel()
307310
}
308-
if p.hasNoWorkerScaling() {
309-
select {
310-
case <-p.baseCtx.Done():
311-
// Don't warn if the baseCtx is shutdown
312-
default:
311+
select {
312+
case <-p.baseCtx.Done():
313+
// Don't warn or check for ongoing work if the baseCtx is shutdown
314+
case <-p.paused:
315+
// Don't warn or check for ongoing work if the pool is paused
316+
default:
317+
if p.hasNoWorkerScaling() {
313318
log.Warn(
314319
"Queue: %d is configured to be non-scaling and has no workers - this configuration is likely incorrect.\n"+
315320
"The queue will be paused to prevent data-loss with the assumption that you will add workers and unpause as required.", p.qid)
321+
p.pause()
322+
} else if p.numberOfWorkers == 0 && atomic.LoadInt64(&p.numInQueue) > 0 {
323+
// OK there are no workers but... there's still work to be done -> Reboost
324+
p.zeroBoost()
325+
// p.lock will be unlocked by zeroBoost
326+
return
316327
}
317-
p.pause()
318328
}
319329
p.lock.Unlock()
320330
}()
@@ -371,14 +381,37 @@ func (p *WorkerPool) pause() {
371381

372382
// Resume resumes the WorkerPool
373383
func (p *WorkerPool) Resume() {
374-
p.lock.Lock()
375-
defer p.lock.Unlock()
384+
p.lock.Lock() // can't defer unlock because of the zeroBoost at the end
376385
select {
377386
case <-p.resumed:
387+
// already resumed - there's nothing to do
388+
p.lock.Unlock()
389+
return
378390
default:
379-
p.paused = make(chan struct{})
380-
close(p.resumed)
381391
}
392+
393+
p.paused = make(chan struct{})
394+
close(p.resumed)
395+
396+
// OK now we need to check if we need to add some workers...
397+
if p.numberOfWorkers > 0 || p.hasNoWorkerScaling() || atomic.LoadInt64(&p.numInQueue) == 0 {
398+
// We either have workers, can't scale or there's no work to be done -> so just resume
399+
p.lock.Unlock()
400+
return
401+
}
402+
403+
// OK we got some work but no workers we need to think about boosting
404+
select {
405+
case <-p.baseCtx.Done():
406+
// don't bother boosting if the baseCtx is done
407+
p.lock.Unlock()
408+
return
409+
default:
410+
}
411+
412+
// OK we'd better add some boost workers!
413+
p.zeroBoost()
414+
// p.zeroBoost will unlock the lock
382415
}
383416

384417
// CleanUp will drain the remaining contents of the channel

modules/setting/setting.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -1061,11 +1061,14 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
10611061
}
10621062

10631063
// FIXME: DEPRECATED to be removed in v1.18.0
1064+
U2F.AppID = strings.TrimSuffix(AppURL, "/")
10641065
if Cfg.Section("U2F").HasKey("APP_ID") {
10651066
log.Error("Deprecated setting `[U2F]` `APP_ID` present. This fallback will be removed in v1.18.0")
1067+
U2F.AppID = Cfg.Section("U2F").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/"))
1068+
} else if Cfg.Section("u2f").HasKey("APP_ID") {
1069+
log.Error("Deprecated setting `[u2]` `APP_ID` present. This fallback will be removed in v1.18.0")
1070+
U2F.AppID = Cfg.Section("u2f").Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/"))
10661071
}
1067-
sec = Cfg.Section("U2F")
1068-
U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/"))
10691072
}
10701073

10711074
func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) {

options/locale/locale_zh-CN.ini

+1
Original file line numberDiff line numberDiff line change
@@ -2436,6 +2436,7 @@ dashboard.last_gc_pause=上次 GC 暂停时间
24362436
dashboard.gc_times=GC 执行次数
24372437
dashboard.delete_old_actions=从数据库中删除所有旧操作记录
24382438
dashboard.delete_old_actions.started=已开始从数据库中删除所有旧操作记录。
2439+
dashboard.update_checker=更新检查器
24392440

24402441
users.user_manage_panel=用户帐户管理
24412442
users.new_account=创建新帐户

services/mirror/mirror.go

+18-10
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
5959

6060
handler := func(idx int, bean interface{}, limit int) error {
6161
var item SyncRequest
62+
var repo *repo_model.Repository
6263
if m, ok := bean.(*repo_model.Mirror); ok {
6364
if m.Repo == nil {
6465
log.Error("Disconnected mirror found: %d", m.ID)
6566
return nil
6667
}
68+
repo = m.Repo
6769
item = SyncRequest{
6870
Type: PullMirrorType,
6971
RepoID: m.RepoID,
@@ -73,6 +75,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
7375
log.Error("Disconnected push-mirror found: %d", m.ID)
7476
return nil
7577
}
78+
repo = m.Repo
7679
item = SyncRequest{
7780
Type: PushMirrorType,
7881
RepoID: m.RepoID,
@@ -89,17 +92,16 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
8992
default:
9093
}
9194

92-
// Check if this request is already in the queue
93-
has, err := mirrorQueue.Has(&item)
94-
if err != nil {
95-
return err
96-
}
97-
if has {
98-
return nil
99-
}
100-
10195
// Push to the Queue
10296
if err := mirrorQueue.Push(&item); err != nil {
97+
if err == queue.ErrAlreadyInQueue {
98+
if item.Type == PushMirrorType {
99+
log.Trace("PushMirrors for %-v already queued for sync", repo)
100+
} else {
101+
log.Trace("PullMirrors for %-v already queued for sync", repo)
102+
}
103+
return nil
104+
}
103105
return err
104106
}
105107

@@ -110,23 +112,29 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error {
110112
return nil
111113
}
112114

115+
pullMirrorsRequested := 0
113116
if pullLimit != 0 {
117+
requested = 0
114118
if err := repo_model.MirrorsIterate(func(idx int, bean interface{}) error {
115119
return handler(idx, bean, pullLimit)
116120
}); err != nil && err != errLimit {
117121
log.Error("MirrorsIterate: %v", err)
118122
return err
119123
}
124+
pullMirrorsRequested, requested = requested, 0
120125
}
126+
pushMirrorsRequested := 0
121127
if pushLimit != 0 {
128+
requested = 0
122129
if err := repo_model.PushMirrorsIterate(func(idx int, bean interface{}) error {
123130
return handler(idx, bean, pushLimit)
124131
}); err != nil && err != errLimit {
125132
log.Error("PushMirrorsIterate: %v", err)
126133
return err
127134
}
135+
pushMirrorsRequested, requested = requested, 0
128136
}
129-
log.Trace("Finished: Update")
137+
log.Trace("Finished: Update: %d pull mirrors and %d push mirrors queued", pullMirrorsRequested, pushMirrorsRequested)
130138
return nil
131139
}
132140

web_src/js/features/user-auth-webauthn.js

+13
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ export function initUserAuthWebAuthn() {
2424
.then((credential) => {
2525
verifyAssertion(credential);
2626
}).catch((err) => {
27+
// Try again... without the appid
28+
if (makeAssertionOptions.publicKey.extensions && makeAssertionOptions.publicKey.extensions.appid) {
29+
delete makeAssertionOptions.publicKey.extensions['appid'];
30+
navigator.credentials.get({
31+
publicKey: makeAssertionOptions.publicKey
32+
})
33+
.then((credential) => {
34+
verifyAssertion(credential);
35+
}).catch((err) => {
36+
webAuthnError('general', err.message);
37+
});
38+
return;
39+
}
2740
webAuthnError('general', err.message);
2841
});
2942
}).fail(() => {

0 commit comments

Comments
 (0)