From 33f6f91008f2219e94e8d909539b38a590554122 Mon Sep 17 00:00:00 2001 From: Steven Kriegler <61625851+justusbunsi@users.noreply.github.com> Date: Mon, 4 Jul 2022 11:21:14 +0200 Subject: [PATCH 01/16] Allow enable LDAP source and disable user sync via CLI (#20206) The current `admin auth` CLI for managing authentication source of type LDAP via BindDN and Simple LDAP does not allow enabling the respective source, once disabled via `--not-active`. The same applies to `--synchronize-users` specifially for LDAP via BindDN. These changes add two new flags to LDAP related CLI commands: - `--active` for both LDAP authentication source types - `--disable-synchronize-users` for LDAP via BindDN Signed-off-by: justusbunsi <61625851+justusbunsi@users.noreply.github.com> --- cmd/admin_auth_ldap.go | 14 +++++++++ cmd/admin_auth_ldap_test.go | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/cmd/admin_auth_ldap.go b/cmd/admin_auth_ldap.go index ec86b2c671d47..9040def822e37 100644 --- a/cmd/admin_auth_ldap.go +++ b/cmd/admin_auth_ldap.go @@ -34,6 +34,10 @@ var ( Name: "not-active", Usage: "Deactivate the authentication source.", }, + cli.BoolFlag{ + Name: "active", + Usage: "Activate the authentication source.", + }, cli.StringFlag{ Name: "security-protocol", Usage: "Security protocol name.", @@ -117,6 +121,10 @@ var ( Name: "synchronize-users", Usage: "Enable user synchronization.", }, + cli.BoolFlag{ + Name: "disable-synchronize-users", + Usage: "Disable user synchronization.", + }, cli.UintFlag{ Name: "page-size", Usage: "Search page size.", @@ -183,9 +191,15 @@ func parseAuthSource(c *cli.Context, authSource *auth.Source) { if c.IsSet("not-active") { authSource.IsActive = !c.Bool("not-active") } + if c.IsSet("active") { + authSource.IsActive = c.Bool("active") + } if c.IsSet("synchronize-users") { authSource.IsSyncEnabled = c.Bool("synchronize-users") } + if c.IsSet("disable-synchronize-users") { + authSource.IsSyncEnabled = !c.Bool("disable-synchronize-users") + } } // parseLdapConfig assigns values on config according to command line flags. diff --git a/cmd/admin_auth_ldap_test.go b/cmd/admin_auth_ldap_test.go index f050b536fdf50..2180b24be58df 100644 --- a/cmd/admin_auth_ldap_test.go +++ b/cmd/admin_auth_ldap_test.go @@ -858,6 +858,36 @@ func TestUpdateLdapBindDn(t *testing.T) { }, errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2", }, + // case 24 + { + args: []string{ + "ldap-test", + "--id", "24", + "--name", "ldap (via Bind DN) flip 'active' and 'user sync' attributes", + "--active", + "--disable-synchronize-users", + }, + id: 24, + existingAuthSource: &auth.Source{ + Type: auth.LDAP, + IsActive: false, + IsSyncEnabled: true, + Cfg: &ldap.Source{ + Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", + Enabled: true, + }, + }, + authSource: &auth.Source{ + Type: auth.LDAP, + Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", + IsActive: true, + IsSyncEnabled: false, + Cfg: &ldap.Source{ + Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes", + Enabled: true, + }, + }, + }, } for n, c := range cases { @@ -1221,6 +1251,33 @@ func TestUpdateLdapSimpleAuth(t *testing.T) { }, errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM", }, + // case 20 + { + args: []string{ + "ldap-test", + "--id", "20", + "--name", "ldap (simple auth) flip 'active' attribute", + "--active", + }, + id: 20, + existingAuthSource: &auth.Source{ + Type: auth.DLDAP, + IsActive: false, + Cfg: &ldap.Source{ + Name: "ldap (simple auth) flip 'active' attribute", + Enabled: true, + }, + }, + authSource: &auth.Source{ + Type: auth.DLDAP, + Name: "ldap (simple auth) flip 'active' attribute", + IsActive: true, + Cfg: &ldap.Source{ + Name: "ldap (simple auth) flip 'active' attribute", + Enabled: true, + }, + }, + }, } for n, c := range cases { From ba0f9274e99ce7e28d587e30eee4a211b0556354 Mon Sep 17 00:00:00 2001 From: zeripath Date: Mon, 4 Jul 2022 11:17:09 +0100 Subject: [PATCH 02/16] Allow dev i18n to be more concurrent (#20159) The recent changes to add live-reloading to the i18n translation files made the i18n code totally non-concurrent when using dev. This will make discovering other concurrency related issues far more difficult. This PR fixes these, adds some more comments to the code and slightly restructures a few functions. Signed-off-by: Andrew Thornton --- modules/translation/i18n/i18n.go | 242 +++++++++++++++++++++---------- 1 file changed, 168 insertions(+), 74 deletions(-) diff --git a/modules/translation/i18n/i18n.go b/modules/translation/i18n/i18n.go index acce5f19fb0dc..bb906f3c08c1d 100644 --- a/modules/translation/i18n/i18n.go +++ b/modules/translation/i18n/i18n.go @@ -25,9 +25,13 @@ var ( ) type locale struct { + // This mutex will be set if we have live-reload enabled (e.g. dev mode) + reloadMu *sync.RWMutex + store *LocaleStore langName string - textMap map[int]string // the map key (idx) is generated by store's textIdxMap + + idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap sourceFileName string sourceFileInfo os.FileInfo @@ -35,164 +39,254 @@ type locale struct { } type LocaleStore struct { - reloadMu *sync.Mutex // for non-prod(dev), use a mutex for live-reload. for prod, no mutex, no live-reload. + // This mutex will be set if we have live-reload enabled (e.g. dev mode) + reloadMu *sync.RWMutex langNames []string langDescs []string + localeMap map[string]*locale - localeMap map[string]*locale - textIdxMap map[string]int + // this needs to be locked when live-reloading + trKeyToIdxMap map[string]int defaultLang string } func NewLocaleStore(isProd bool) *LocaleStore { - ls := &LocaleStore{localeMap: make(map[string]*locale), textIdxMap: make(map[string]int)} + store := &LocaleStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)} if !isProd { - ls.reloadMu = &sync.Mutex{} + store.reloadMu = &sync.RWMutex{} } - return ls + return store } // AddLocaleByIni adds locale by ini into the store -// if source is a string, then the file is loaded. in dev mode, the file can be live-reloaded +// if source is a string, then the file is loaded. In dev mode, this file will be checked for live-reloading // if source is a []byte, then the content is used -func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, source interface{}) error { - if _, ok := ls.localeMap[langName]; ok { +// Note: this is not concurrent safe +func (store *LocaleStore) AddLocaleByIni(langName, langDesc string, source interface{}) error { + if _, ok := store.localeMap[langName]; ok { return ErrLocaleAlreadyExist } - lc := &locale{store: ls, langName: langName} + l := &locale{store: store, langName: langName} + if store.reloadMu != nil { + l.reloadMu = &sync.RWMutex{} + l.reloadMu.Lock() // Arguably this is not necessary as AddLocaleByIni isn't concurrent safe - but for consistency we do this + defer l.reloadMu.Unlock() + } + if fileName, ok := source.(string); ok { - lc.sourceFileName = fileName - lc.sourceFileInfo, _ = os.Stat(fileName) // live-reload only works for regular files. the error can be ignored + l.sourceFileName = fileName + l.sourceFileInfo, _ = os.Stat(fileName) // live-reload only works for regular files. the error can be ignored + } + + var err error + l.idxToMsgMap, err = store.readIniToIdxToMsgMap(source) + if err != nil { + return err } - ls.langNames = append(ls.langNames, langName) - ls.langDescs = append(ls.langDescs, langDesc) - ls.localeMap[lc.langName] = lc + store.langNames = append(store.langNames, langName) + store.langDescs = append(store.langDescs, langDesc) + + store.localeMap[l.langName] = l - return ls.reloadLocaleByIni(langName, source) + return nil } -func (ls *LocaleStore) reloadLocaleByIni(langName string, source interface{}) error { +// readIniToIdxToMsgMap will read a provided ini and creates an idxToMsgMap +func (store *LocaleStore) readIniToIdxToMsgMap(source interface{}) (map[int]string, error) { iniFile, err := ini.LoadSources(ini.LoadOptions{ IgnoreInlineComment: true, UnescapeValueCommentSymbols: true, }, source) if err != nil { - return fmt.Errorf("unable to load ini: %w", err) + return nil, fmt.Errorf("unable to load ini: %w", err) } iniFile.BlockMode = false - lc := ls.localeMap[langName] - lc.textMap = make(map[int]string) + idxToMsgMap := make(map[int]string) + + if store.reloadMu != nil { + store.reloadMu.Lock() + defer store.reloadMu.Unlock() + } + for _, section := range iniFile.Sections() { for _, key := range section.Keys() { + var trKey string if section.Name() == "" || section.Name() == "DEFAULT" { trKey = key.Name() } else { trKey = section.Name() + "." + key.Name() } - textIdx, ok := ls.textIdxMap[trKey] + + // Instead of storing the key strings in multiple different maps we compute a idx which will act as numeric code for key + // This reduces the size of the locale idxToMsgMaps + idx, ok := store.trKeyToIdxMap[trKey] if !ok { - textIdx = len(ls.textIdxMap) - ls.textIdxMap[trKey] = textIdx + idx = len(store.trKeyToIdxMap) + store.trKeyToIdxMap[trKey] = idx } - lc.textMap[textIdx] = key.Value() + idxToMsgMap[idx] = key.Value() } } iniFile = nil - return nil + return idxToMsgMap, nil +} + +func (store *LocaleStore) idxForTrKey(trKey string) (int, bool) { + if store.reloadMu != nil { + store.reloadMu.RLock() + defer store.reloadMu.RUnlock() + } + idx, ok := store.trKeyToIdxMap[trKey] + return idx, ok } -func (ls *LocaleStore) HasLang(langName string) bool { - _, ok := ls.localeMap[langName] +// HasLang reports if a language is available in the store +func (store *LocaleStore) HasLang(langName string) bool { + _, ok := store.localeMap[langName] return ok } -func (ls *LocaleStore) ListLangNameDesc() (names, desc []string) { - return ls.langNames, ls.langDescs +// ListLangNameDesc reports if a language available in the store +func (store *LocaleStore) ListLangNameDesc() (names, desc []string) { + return store.langNames, store.langDescs } // SetDefaultLang sets default language as a fallback -func (ls *LocaleStore) SetDefaultLang(lang string) { - ls.defaultLang = lang +func (store *LocaleStore) SetDefaultLang(lang string) { + store.defaultLang = lang } // Tr translates content to target language. fall back to default language. -func (ls *LocaleStore) Tr(lang, trKey string, trArgs ...interface{}) string { - l, ok := ls.localeMap[lang] +func (store *LocaleStore) Tr(lang, trKey string, trArgs ...interface{}) string { + l, ok := store.localeMap[lang] if !ok { - l, ok = ls.localeMap[ls.defaultLang] + l, ok = store.localeMap[store.defaultLang] } + if ok { return l.Tr(trKey, trArgs...) } return trKey } +// reloadIfNeeded will check if the locale needs to be reloaded +// this function will assume that the l.reloadMu has been RLocked if it already exists +func (l *locale) reloadIfNeeded() { + if l.reloadMu == nil { + return + } + + now := time.Now() + if now.Sub(l.lastReloadCheckTime) < time.Second || l.sourceFileInfo == nil || l.sourceFileName == "" { + return + } + + l.reloadMu.RUnlock() + l.reloadMu.Lock() // (NOTE: a pre-emption can occur between these two locks so we need to recheck) + defer l.reloadMu.RLock() + defer l.reloadMu.Unlock() + + if now.Sub(l.lastReloadCheckTime) < time.Second || l.sourceFileInfo == nil || l.sourceFileName == "" { + return + } + + l.lastReloadCheckTime = now + sourceFileInfo, err := os.Stat(l.sourceFileName) + if err != nil || sourceFileInfo.ModTime().Equal(l.sourceFileInfo.ModTime()) { + return + } + + idxToMsgMap, err := l.store.readIniToIdxToMsgMap(l.sourceFileName) + if err == nil { + l.idxToMsgMap = idxToMsgMap + } else { + log.Error("Unable to live-reload the locale file %q, err: %v", l.sourceFileName, err) + } + + // We will set the sourceFileInfo to this file to prevent repeated attempts to re-load this broken file + l.sourceFileInfo = sourceFileInfo +} + // Tr translates content to locale language. fall back to default language. func (l *locale) Tr(trKey string, trArgs ...interface{}) string { - if l.store.reloadMu != nil { - l.store.reloadMu.Lock() - defer l.store.reloadMu.Unlock() - now := time.Now() - if now.Sub(l.lastReloadCheckTime) >= time.Second && l.sourceFileInfo != nil && l.sourceFileName != "" { - l.lastReloadCheckTime = now - if sourceFileInfo, err := os.Stat(l.sourceFileName); err == nil && !sourceFileInfo.ModTime().Equal(l.sourceFileInfo.ModTime()) { - if err = l.store.reloadLocaleByIni(l.langName, l.sourceFileName); err == nil { - l.sourceFileInfo = sourceFileInfo - } else { - log.Error("unable to live-reload the locale file %q, err: %v", l.sourceFileName, err) - } - } - } + if l.reloadMu != nil { + l.reloadMu.RLock() + defer l.reloadMu.RUnlock() + l.reloadIfNeeded() } + msg, _ := l.tryTr(trKey, trArgs...) return msg } func (l *locale) tryTr(trKey string, trArgs ...interface{}) (msg string, found bool) { trMsg := trKey - textIdx, ok := l.store.textIdxMap[trKey] + + // convert the provided trKey to a common idx from the store + idx, ok := l.store.idxForTrKey(trKey) + if ok { - if msg, found = l.textMap[textIdx]; found { - trMsg = msg // use current translation + if msg, found = l.idxToMsgMap[idx]; found { + trMsg = msg // use the translation that we have found } else if l.langName != l.store.defaultLang { + // No translation available in our current language... fallback to the default language + + // Attempt to get the default language from the locale store if def, ok := l.store.localeMap[l.store.defaultLang]; ok { - return def.tryTr(trKey, trArgs...) + + if def.reloadMu != nil { + def.reloadMu.RLock() + def.reloadIfNeeded() + } + if msg, found = def.idxToMsgMap[idx]; found { + trMsg = msg // use the translation that we have found + } + if def.reloadMu != nil { + def.reloadMu.RUnlock() + } } - } else if !setting.IsProd { - log.Error("missing i18n translation key: %q", trKey) } } - if len(trArgs) > 0 { - fmtArgs := make([]interface{}, 0, len(trArgs)) - for _, arg := range trArgs { - val := reflect.ValueOf(arg) - if val.Kind() == reflect.Slice { - // before, it can accept Tr(lang, key, a, [b, c], d, [e, f]) as Sprintf(msg, a, b, c, d, e, f), it's an unstable behavior - // now, we restrict the strange behavior and only support: - // 1. Tr(lang, key, [slice-items]) as Sprintf(msg, items...) - // 2. Tr(lang, key, args...) as Sprintf(msg, args...) - if len(trArgs) == 1 { - for i := 0; i < val.Len(); i++ { - fmtArgs = append(fmtArgs, val.Index(i).Interface()) - } - } else { - log.Error("the args for i18n shouldn't contain uncertain slices, key=%q, args=%v", trKey, trArgs) - break + if !found && !setting.IsProd { + log.Error("missing i18n translation key: %q", trKey) + } + + if len(trArgs) == 0 { + return trMsg, found + } + + fmtArgs := make([]interface{}, 0, len(trArgs)) + for _, arg := range trArgs { + val := reflect.ValueOf(arg) + if val.Kind() == reflect.Slice { + // Previously, we would accept Tr(lang, key, a, [b, c], d, [e, f]) as Sprintf(msg, a, b, c, d, e, f) + // but this is an unstable behavior. + // + // So we restrict the accepted arguments to either: + // + // 1. Tr(lang, key, [slice-items]) as Sprintf(msg, items...) + // 2. Tr(lang, key, args...) as Sprintf(msg, args...) + if len(trArgs) == 1 { + for i := 0; i < val.Len(); i++ { + fmtArgs = append(fmtArgs, val.Index(i).Interface()) } } else { - fmtArgs = append(fmtArgs, arg) + log.Error("the args for i18n shouldn't contain uncertain slices, key=%q, args=%v", trKey, trArgs) + break } + } else { + fmtArgs = append(fmtArgs, arg) } - return fmt.Sprintf(trMsg, fmtArgs...), found } - return trMsg, found + + return fmt.Sprintf(trMsg, fmtArgs...), found } // ResetDefaultLocales resets the current default locales From 2921d3c8c9ea17941e4da4381e6fb3177cd7d37d Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Mon, 4 Jul 2022 18:06:24 +0530 Subject: [PATCH 03/16] Add integration tests for the Gitea migration form (#20121) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tests: integration tests for the Gitea migration form * use a mix of ` and " instead of backslash https://github.com/go-gitea/gitea/pull/20121#discussion_r906729415 Co-authored-by: Loïc Dachary --- integrations/migrate_test.go | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/integrations/migrate_test.go b/integrations/migrate_test.go index 9b59c85a4eb7e..f67e4ed2297de 100644 --- a/integrations/migrate_test.go +++ b/integrations/migrate_test.go @@ -5,12 +5,17 @@ package integrations import ( + "fmt" + "net/http" + "net/url" "os" "testing" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/migrations" "github.com/stretchr/testify/assert" @@ -40,3 +45,54 @@ func TestMigrateLocalPath(t *testing.T) { setting.ImportLocalPaths = old } + +func TestMigrateGiteaForm(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + AllowLocalNetworks := setting.Migrations.AllowLocalNetworks + setting.Migrations.AllowLocalNetworks = true + AppVer := setting.AppVer + // Gitea SDK (go-sdk) need to parse the AppVer from server response, so we must set it to a valid version string. + setting.AppVer = "1.16.0" + defer func() { + setting.Migrations.AllowLocalNetworks = AllowLocalNetworks + setting.AppVer = AppVer + migrations.Init() + }() + assert.NoError(t, migrations.Init()) + + ownerName := "user2" + repoName := "repo1" + repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName}).(*user_model.User) + session := loginUser(t, ownerName) + token := getTokenForLoggedInUser(t, session) + + // Step 0: verify the repo is available + req := NewRequestf(t, "GET", fmt.Sprintf("/%s/%s", ownerName, repoName)) + _ = session.MakeRequest(t, req, http.StatusOK) + // Step 1: get the Gitea migration form + req = NewRequestf(t, "GET", "/repo/migrate/?service_type=%d", structs.GiteaService) + resp := session.MakeRequest(t, req, http.StatusOK) + // Step 2: load the form + htmlDoc := NewHTMLParser(t, resp.Body) + link, exists := htmlDoc.doc.Find(`form.ui.form[action^="/repo/migrate"]`).Attr("action") + assert.True(t, exists, "The template has changed") + // Step 4: submit the migration to only migrate issues + migratedRepoName := "otherrepo" + req = NewRequestWithValues(t, "POST", link, map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "service": fmt.Sprintf("%d", structs.GiteaService), + "clone_addr": fmt.Sprintf("%s%s/%s", u, ownerName, repoName), + "auth_token": token, + "issues": "on", + "repo_name": migratedRepoName, + "description": "", + "uid": fmt.Sprintf("%d", repoOwner.ID), + }) + resp = session.MakeRequest(t, req, http.StatusSeeOther) + // Step 5: a redirection displays the migrated repository + loc := resp.Header().Get("Location") + assert.EqualValues(t, fmt.Sprintf("/%s/%s", ownerName, migratedRepoName), loc) + // Step 6: check the repo was created + unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: migratedRepoName}) + }) +} From c174bdc494e44ac6b52373e86b7a3ac225091a80 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Mon, 4 Jul 2022 22:44:34 +0800 Subject: [PATCH 04/16] Adjust template for #20069 smallbell (#20108) * Adjust template for #20069 smallbell * Adjust notification Unread Count variable to global and count bell position with mobile * Adjust bell icon style * Adjust smallbell to middle * Avoid using inline styles * move notificationUnreadCount to a general code block, reduce changed lines * Solved conflicts Co-authored-by: wxiaoguang Co-authored-by: Lunny Xiao Co-authored-by: 6543 <6543@obermui.de> --- templates/base/head_navbar.tmpl | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index b04d8bcbb3850..91529dc163ac5 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -1,8 +1,22 @@ - + {{svg "octicon-bell"}} - {{.locale.Tr "notifications"}} - {{$notificationUnreadCount := 0}} - {{if .NotificationUnreadCount}}{{$notificationUnreadCount = call .NotificationUnreadCount}}{{end}} {{$notificationUnreadCount}} From a168609e847ad24c7f3d9d494bab2219fca71d60 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Tue, 5 Jul 2022 14:12:53 +0800 Subject: [PATCH 05/16] Adjust class for mobile has the problem of double small bells (#20236) * Adjust class for mobile has the problem of double small bells * Update templates/base/head_navbar.tmpl Co-authored-by: Gusted Co-authored-by: Gusted --- templates/base/head_navbar.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 91529dc163ac5..111cc02f933f5 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -114,7 +114,7 @@ - + {{svg "octicon-bell"}} From c4368fc6bc385f678c0310911d17598abdc68b40 Mon Sep 17 00:00:00 2001 From: Baekjun Kim <36013575+kimbj95@users.noreply.github.com> Date: Tue, 5 Jul 2022 06:30:05 -0500 Subject: [PATCH 06/16] Display full name (#20171) The setting `DEFAULT_SHOW_FULL_NAME` promises to use the user's full name everywhere it can be used. Unfortunately the function `*user_model.User.ShortName()` currently uses the `.Name` instead - but this should also use the `.FullName()`. Therefore we should make `*user_model.User.ShortName()` base its pre-shortened name on the `.FullName()` function. --- models/user/user.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/models/user/user.go b/models/user/user.go index 9460bd38fe428..000af585137d8 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -485,6 +485,9 @@ func (u *User) GitName() string { // ShortName ellipses username to length func (u *User) ShortName(length int) string { + if setting.UI.DefaultShowFullName && len(u.FullName) > 0 { + return base.EllipsisString(u.FullName, length) + } return base.EllipsisString(u.Name, length) } From 8ee823037f98d9975496bd75a7c5386823426e7f Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 5 Jul 2022 12:33:05 +0100 Subject: [PATCH 07/16] Adjust max-widths for the repository file table (#20243) Adjust the max-widths for the repository file table to allow for nicer resizing of the names and commit messages. Fix #20040 Signed-off-by: Andrew Thornton ## Screenshots ## MediaXL ![Screenshot from 2022-07-05 10-22-12](https://user-images.githubusercontent.com/1824502/177295867-7ba8cf60-8f61-4227-892f-e5a0477e4146.png) ## MediaLg ![Screenshot from 2022-07-05 10-24-37](https://user-images.githubusercontent.com/1824502/177296301-e066e206-10f7-4a15-a68b-0f772a95f369.png) ## MediaMd ![Screenshot from 2022-07-05 10-23-03](https://user-images.githubusercontent.com/1824502/177295965-69397649-16ca-456a-bc0c-ed507fcb7f44.png) ## MediaSm ![Screenshot from 2022-07-05 10-26-44](https://user-images.githubusercontent.com/1824502/177296700-ca2a853b-c47b-4592-baf4-4bc08a7e1c9c.png) --- web_src/less/_repository.less | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index bc1affb7703f0..7bbd412b6198d 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -352,11 +352,31 @@ overflow: initial; &.name { - max-width: 150px; + @media @mediaXl { + max-width: 150px; + } + @media @mediaLg { + max-width: 200px; + } + @media @mediaMd { + max-width: 300px; + } + width: 33%; + + max-width: calc(100vw - 140px); } &.message { - max-width: 400px; + @media @mediaXl { + max-width: 400px; + } + @media @mediaLg { + max-width: 350px; + } + @media @mediaMd { + max-width: 250px; + } + width: 66%; } &.age { From f5c97172f0e725b2bb2d00d281d82caf4dd72b9d Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 5 Jul 2022 20:27:13 +0800 Subject: [PATCH 08/16] Bypass Firefox (iOS) bug (#20244) * https://github.com/go-gitea/gitea/issues/20240 At the moment, Firefox (iOS) (10x) has an engine bug. See https://github.com/go-gitea/gitea/issues/20240 If a script inserts a newly created (and content changed) element into DOM, there will be a nonsense error event reporting: Script error: line 0, col 0. This PR ignores such nonsense error event. Fix #20240 --- web_src/js/bootstrap.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web_src/js/bootstrap.js b/web_src/js/bootstrap.js index cf13b2a559d30..213c9e41df5db 100644 --- a/web_src/js/bootstrap.js +++ b/web_src/js/bootstrap.js @@ -20,6 +20,11 @@ export function showGlobalErrorMessage(msg) { * @param {ErrorEvent} e */ function processWindowErrorEvent(e) { + if (!e.error && e.lineno === 0 && e.colno === 0 && e.filename === '' && window.navigator.userAgent.includes('FxiOS/')) { + // At the moment, Firefox (iOS) (10x) has an engine bug. See https://github.com/go-gitea/gitea/issues/20240 + // If a script inserts a newly created (and content changed) element into DOM, there will be a nonsense error event reporting: Script error: line 0, col 0. + return; // ignore such nonsense error event + } showGlobalErrorMessage(`JavaScript error: ${e.message} (${e.filename} @ ${e.lineno}:${e.colno}). Open browser console to see more details.`); } From ed13d7aadf75246a3b9ba68c5cd2def867f89f43 Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 5 Jul 2022 14:28:31 +0200 Subject: [PATCH 09/16] Init popup for new code comment (#20234) - Initialize the popup for the tooltip inside the new code comment. - This works and is good enough to have this issue fixed for 1.17 Fix #20068 --- web_src/js/features/common-global.js | 23 ++++++++++++++--------- web_src/js/features/repo-diff.js | 2 ++ web_src/js/index.js | 2 ++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index a508db39c5e6a..419c5996dc651 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -75,6 +75,20 @@ export function initGlobalButtonClickOnEnter() { }); } +export function initPopup(target) { + const $el = $(target); + const attr = $el.attr('data-variation'); + const attrs = attr ? attr.split(' ') : []; + const variations = new Set([...attrs, 'inverted', 'tiny']); + $el.attr('data-variation', [...variations].join(' ')).popup(); +} + +export function initGlobalPopups() { + $('.tooltip').each((_, el) => { + initPopup(el); + }); +} + export function initGlobalCommon() { // Show exact time $('.time-since').each(function () { @@ -121,15 +135,6 @@ export function initGlobalCommon() { $('.ui.checkbox').checkbox(); - // init popups - $('.tooltip').each((_, el) => { - const $el = $(el); - const attr = $el.attr('data-variation'); - const attrs = attr ? attr.split(' ') : []; - const variations = new Set([...attrs, 'inverted', 'tiny']); - $el.attr('data-variation', [...variations].join(' ')).popup(); - }); - $('.top.menu .tooltip').popup({ onShow() { if ($('.top.menu .menu.transition').hasClass('visible')) { diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index 8403a2fd42d13..92d8ecfc86096 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -3,6 +3,7 @@ import {initCompReactionSelector} from './comp/ReactionSelector.js'; import {initRepoIssueContentHistory} from './repo-issue-content.js'; import {validateTextareaNonEmpty} from './comp/EasyMDE.js'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles} from './pull-view-file.js'; +import {initPopup} from './common-global.js'; const {csrfToken} = window.config; @@ -52,6 +53,7 @@ export function initRepoDiffConversationForm() { const newConversationHolder = $(await $.post(form.attr('action'), form.serialize())); const {path, side, idx} = newConversationHolder.data(); + initPopup(newConversationHolder.find('.tooltip')); form.closest('.conversation-holder').replaceWith(newConversationHolder); if (form.closest('tr').data('line-type') === 'same') { $(`[data-path="${path}"] a.add-code-comment[data-idx="${idx}"]`).addClass('invisible'); diff --git a/web_src/js/index.js b/web_src/js/index.js index 0568da64aec51..6f872b5353378 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -56,6 +56,7 @@ import { initGlobalFormDirtyLeaveConfirm, initGlobalLinkActions, initHeadNavbarContentToggle, + initGlobalPopups, } from './features/common-global.js'; import {initRepoTopicBar} from './features/repo-home.js'; import {initAdminEmails} from './features/admin-emails.js'; @@ -99,6 +100,7 @@ initVueEnv(); $(document).ready(() => { initGlobalCommon(); + initGlobalPopups(); initGlobalButtonClickOnEnter(); initGlobalButtons(); initGlobalCopyToClipboardListener(); From 45f17528a856718457b79011cfd20c127ee87452 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 5 Jul 2022 16:47:45 +0100 Subject: [PATCH 10/16] Only show Followers that current user can access (#20220) Users who are following or being followed by a user should only be displayed if the viewing user can see them. Signed-off-by: Andrew Thornton --- models/user/user.go | 59 ++++++++++++++++++++++++++++----- routers/api/v1/user/follower.go | 8 ++--- routers/web/user/profile.go | 8 ++--- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index 000af585137d8..125c643f3ee88 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -316,37 +316,45 @@ func (u *User) GenerateEmailActivateCode(email string) string { } // GetUserFollowers returns range of user's followers. -func GetUserFollowers(u *User, listOptions db.ListOptions) ([]*User, error) { - sess := db.GetEngine(db.DefaultContext). +func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) { + sess := db.GetEngine(ctx). + Select("`user`.*"). + Join("LEFT", "follow", "`user`.id=follow.user_id"). Where("follow.follow_id=?", u.ID). - Join("LEFT", "follow", "`user`.id=follow.user_id") + And(isUserVisibleToViewerCond(viewer)) if listOptions.Page != 0 { sess = db.SetSessionPagination(sess, &listOptions) users := make([]*User, 0, listOptions.PageSize) - return users, sess.Find(&users) + count, err := sess.FindAndCount(&users) + return users, count, err } users := make([]*User, 0, 8) - return users, sess.Find(&users) + count, err := sess.FindAndCount(&users) + return users, count, err } // GetUserFollowing returns range of user's following. -func GetUserFollowing(u *User, listOptions db.ListOptions) ([]*User, error) { +func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) { sess := db.GetEngine(db.DefaultContext). + Select("`user`.*"). + Join("LEFT", "follow", "`user`.id=follow.follow_id"). Where("follow.user_id=?", u.ID). - Join("LEFT", "follow", "`user`.id=follow.follow_id") + And(isUserVisibleToViewerCond(viewer)) if listOptions.Page != 0 { sess = db.SetSessionPagination(sess, &listOptions) users := make([]*User, 0, listOptions.PageSize) - return users, sess.Find(&users) + count, err := sess.FindAndCount(&users) + return users, count, err } users := make([]*User, 0, 8) - return users, sess.Find(&users) + count, err := sess.FindAndCount(&users) + return users, count, err } // NewGitSig generates and returns the signature of given user. @@ -1222,6 +1230,39 @@ func GetAdminUser() (*User, error) { return &admin, nil } +func isUserVisibleToViewerCond(viewer *User) builder.Cond { + if viewer != nil && viewer.IsAdmin { + return builder.NewCond() + } + + if viewer == nil || viewer.IsRestricted { + return builder.Eq{ + "`user`.visibility": structs.VisibleTypePublic, + } + } + + return builder.Neq{ + "`user`.visibility": structs.VisibleTypePrivate, + }.Or( + builder.In("`user`.id", + builder. + Select("`follow`.user_id"). + From("follow"). + Where(builder.Eq{"`follow`.follow_id": viewer.ID})), + builder.In("`user`.id", + builder. + Select("`team_user`.uid"). + From("team_user"). + Join("INNER", "`team_user` AS t2", "`team_user`.id = `t2`.id"). + Where(builder.Eq{"`t2`.uid": viewer.ID})), + builder.In("`user`.id", + builder. + Select("`team_user`.uid"). + From("team_user"). + Join("INNER", "`team_user` AS t2", "`team_user`.org_id = `t2`.org_id"). + Where(builder.Eq{"`t2`.uid": viewer.ID}))) +} + // IsUserVisibleToViewer check if viewer is able to see user profile func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool { if viewer != nil && viewer.IsAdmin { diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 3c81b27f8dad4..22f8f40e1c810 100644 --- a/routers/api/v1/user/follower.go +++ b/routers/api/v1/user/follower.go @@ -24,13 +24,13 @@ func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) { } func listUserFollowers(ctx *context.APIContext, u *user_model.User) { - users, err := user_model.GetUserFollowers(u, utils.GetListOptions(ctx)) + users, count, err := user_model.GetUserFollowers(ctx, u, ctx.Doer, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) return } - ctx.SetTotalCountHeader(int64(u.NumFollowers)) + ctx.SetTotalCountHeader(count) responseAPIUsers(ctx, users) } @@ -86,13 +86,13 @@ func ListFollowers(ctx *context.APIContext) { } func listUserFollowing(ctx *context.APIContext, u *user_model.User) { - users, err := user_model.GetUserFollowing(u, utils.GetListOptions(ctx)) + users, count, err := user_model.GetUserFollowing(ctx, u, ctx.Doer, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err) return } - ctx.SetTotalCountHeader(int64(u.NumFollowing)) + ctx.SetTotalCountHeader(count) responseAPIUsers(ctx, users) } diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 609f3242c65e2..6f23d239e26a5 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -157,7 +157,7 @@ func Profile(ctx *context.Context) { switch tab { case "followers": - items, err := user_model.GetUserFollowers(ctx.ContextUser, db.ListOptions{ + items, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ PageSize: setting.UI.User.RepoPagingNum, Page: page, }) @@ -167,9 +167,9 @@ func Profile(ctx *context.Context) { } ctx.Data["Cards"] = items - total = ctx.ContextUser.NumFollowers + total = int(count) case "following": - items, err := user_model.GetUserFollowing(ctx.ContextUser, db.ListOptions{ + items, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{ PageSize: setting.UI.User.RepoPagingNum, Page: page, }) @@ -179,7 +179,7 @@ func Profile(ctx *context.Context) { } ctx.Data["Cards"] = items - total = ctx.ContextUser.NumFollowing + total = int(count) case "activity": ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{ RequestedUser: ctx.ContextUser, From 6efbe49439f9dff87133f14a8c64a96c0b637635 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 5 Jul 2022 16:59:27 +0100 Subject: [PATCH 11/16] EscapeFilter the group dn membership (#20200) The uid provided to the group filter must be properly escaped using the provided ldap.EscapeFilter function. Fix #20181 Signed-off-by: Andrew Thornton --- services/auth/source/ldap/source_search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/auth/source/ldap/source_search.go b/services/auth/source/ldap/source_search.go index 988d56005e011..a97a1179d9bcd 100644 --- a/services/auth/source/ldap/source_search.go +++ b/services/auth/source/ldap/source_search.go @@ -199,7 +199,7 @@ func checkRestricted(l *ldap.Conn, ls *Source, userDN string) bool { // List all group memberships of a user func (source *Source) listLdapGroupMemberships(l *ldap.Conn, uid string) []string { var ldapGroups []string - groupFilter := fmt.Sprintf("(%s=%s)", source.GroupMemberUID, uid) + groupFilter := fmt.Sprintf("(%s=%s)", source.GroupMemberUID, ldap.EscapeFilter(uid)) result, err := l.Search(ldap.NewSearchRequest( source.GroupDN, ldap.ScopeWholeSubtree, From acbbbbfaf6919dee07608c0b4cf0456f4a7e538c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 09:41:54 +0800 Subject: [PATCH 12/16] Bump mermaid from 9.1.1 to 9.1.2 (#20256) Bumps [mermaid](https://github.com/knsv/mermaid) from 9.1.1 to 9.1.2. - [Release notes](https://github.com/knsv/mermaid/releases) - [Changelog](https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md) - [Commits](https://github.com/knsv/mermaid/compare/9.1.1...9.1.2) --- updated-dependencies: - dependency-name: mermaid dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f8f7013a51c2..5264acac2589e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "less": "4.1.2", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.1", + "mermaid": "9.1.2", "mini-css-extract-plugin": "2.6.0", "monaco-editor": "0.33.0", "monaco-editor-webpack-plugin": "7.0.1", @@ -3833,9 +3833,9 @@ } }, "node_modules/dompurify": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.6.tgz", - "integrity": "sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg==" + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz", + "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw==" }, "node_modules/domutils": { "version": "2.8.0", @@ -7741,15 +7741,15 @@ } }, "node_modules/mermaid": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.1.tgz", - "integrity": "sha512-2RVD+WkzZ4VDyO9gQvQAuQ/ux2gLigJtKDTlbwjYqOR/NwsVzTSfGm/kx648/qWJsg6Sv04tE9BWCO8s6a+pFA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.2.tgz", + "integrity": "sha512-RVf3hBKqiMfyORHboCaEjOAK1TomLO50hYRPvlTrZCXlCniM5pRpe8UlkHBjjpaLtioZnbdYv/vEVj7iKnwkJQ==", "dependencies": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.6", + "dompurify": "2.3.8", "graphlib": "^2.1.8", "khroma": "^2.0.0", "moment-mini": "^2.24.0", @@ -13815,9 +13815,9 @@ } }, "dompurify": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.6.tgz", - "integrity": "sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg==" + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.8.tgz", + "integrity": "sha512-eVhaWoVibIzqdGYjwsBWodIQIaXFSB+cKDf4cfxLMsK0xiud6SE+/WCVx/Xw/UwQsa4cS3T2eITcdtmTg2UKcw==" }, "domutils": { "version": "2.8.0", @@ -16860,15 +16860,15 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "mermaid": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.1.tgz", - "integrity": "sha512-2RVD+WkzZ4VDyO9gQvQAuQ/ux2gLigJtKDTlbwjYqOR/NwsVzTSfGm/kx648/qWJsg6Sv04tE9BWCO8s6a+pFA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.1.2.tgz", + "integrity": "sha512-RVf3hBKqiMfyORHboCaEjOAK1TomLO50hYRPvlTrZCXlCniM5pRpe8UlkHBjjpaLtioZnbdYv/vEVj7iKnwkJQ==", "requires": { "@braintree/sanitize-url": "^6.0.0", "d3": "^7.0.0", "dagre": "^0.8.5", "dagre-d3": "^0.6.4", - "dompurify": "2.3.6", + "dompurify": "2.3.8", "graphlib": "^2.1.8", "khroma": "^2.0.0", "moment-mini": "^2.24.0", diff --git a/package.json b/package.json index addf5633fbf98..2e1c05bb89ef3 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "less": "4.1.2", "less-loader": "11.0.0", "license-checker-webpack-plugin": "0.2.1", - "mermaid": "9.1.1", + "mermaid": "9.1.2", "mini-css-extract-plugin": "2.6.0", "monaco-editor": "0.33.0", "monaco-editor-webpack-plugin": "7.0.1", From 1e43a885780c0f04cca3e891f43902d573f1d993 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 6 Jul 2022 18:33:10 +0100 Subject: [PATCH 13/16] Refix notification bell placement (#20251) The use of `m-4 text black` for the notification bell results in this icon being shifted upwards. Instead we should use the `item` class but adjust `not-mobile` and `mobile-only` to make their `display: none` settings `!important`. (As an aside: This is probably one of the only times we should use `!important` in our less files and the rest should be avoided or removed.) Ref #20069 Revert #20236 Signed-off-by: Andrew Thornton --- templates/base/head_navbar.tmpl | 2 +- web_src/less/_base.less | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 111cc02f933f5..91529dc163ac5 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -114,7 +114,7 @@ - + {{svg "octicon-bell"}} diff --git a/web_src/less/_base.less b/web_src/less/_base.less index 78f32956efce1..638801e3928c4 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -1329,7 +1329,7 @@ footer { @media @mediaMdAndUp { .mobile-only, .ui.button.mobile-only { - display: none; + display: none !important; } // has the same behaviour of sr-only, hiding the content for @@ -1341,7 +1341,7 @@ footer { @media @mediaSm { .not-mobile { - display: none; + display: none !important; } } From 354bfbe77948b9eaca372ab314734dccaf6f8d49 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 6 Jul 2022 21:49:27 +0100 Subject: [PATCH 14/16] Allow RSA 2047 bit keys (#20272) Unfortunately it appears that 2048 bit RSA keys can occasionally be created in such a way that they appear to have 2047 bit length. This PR simply changes our defaults to allow these. Fix #20249 Signed-off-by: Andrew Thornton --- custom/conf/app.example.ini | 2 +- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- modules/setting/setting.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 01f5cb6a47926..927dc71166033 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1231,7 +1231,7 @@ PATH = ;; Define allowed algorithms and their minimum key length (use -1 to disable a type) ;ED25519 = 256 ;ECDSA = 256 -;RSA = 2048 +;RSA = 2047 ; we allow 2047 here because an otherwise valid 2048 bit RSA key can be reported as having 2047 bit length ;DSA = -1 ; set to 1024 to switch on ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 1d067d1f1ca9d..c16a500ef3e82 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -621,7 +621,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - `ED25519`: **256** - `ECDSA`: **256** -- `RSA`: **2048** +- `RSA`: **2047**: We set 2047 here because an otherwise valid 2048 RSA key can be reported as 2047 length. - `DSA`: **-1**: DSA is now disabled by default. Set to **1024** to re-enable but ensure you may need to reconfigure your SSHD provider ## Webhook (`webhook`) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 5400bf5b9f95c..510e00e5ab120 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -170,7 +170,7 @@ var ( ServerMACs: []string{"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1"}, KeygenPath: "ssh-keygen", MinimumKeySizeCheck: true, - MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2048}, + MinimumKeySizes: map[string]int{"ed25519": 256, "ed25519-sk": 256, "ecdsa": 256, "ecdsa-sk": 256, "rsa": 2047}, ServerHostKeys: []string{"ssh/gitea.rsa", "ssh/gogs.rsa"}, AuthorizedKeysCommandTemplate: "{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}", PerWriteTimeout: PerWriteTimeout, From a704e4b547e9ef67ac0e8ddd49cc2f1d3d567d1f Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 6 Jul 2022 22:03:52 +0100 Subject: [PATCH 15/16] Fix toolip on mobile notification bell (#20270) Unfortunately there is a bug in #20108 where the translation call was not updated to use `.locale` from `.i18n`. This PR updates the template to use `.locale`. Signed-off-by: Andrew Thornton --- templates/base/head_navbar.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 91529dc163ac5..b9e9ee7cf84fb 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -8,7 +8,7 @@ {{if .IsSigned}} - + {{svg "octicon-bell"}} From 970288f0b234abd34c8499df108dfe9cbe439315 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Thu, 7 Jul 2022 05:05:12 +0800 Subject: [PATCH 16/16] Modify milestone search keywords to be case insensitive (#20266) Milestone search keywords are now sensitive, this modification is changed to insensitive --- models/issues/milestone.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/milestone.go b/models/issues/milestone.go index fba599e6ece48..c49799f391dc3 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -361,7 +361,7 @@ func (opts GetMilestonesOption) toCond() builder.Cond { } if len(opts.Name) != 0 { - cond = cond.And(builder.Like{"name", opts.Name}) + cond = cond.And(builder.Like{"UPPER(name)", strings.ToUpper(opts.Name)}) } return cond