diff options
author | zeripath <art27@cantab.net> | 2020-03-27 12:34:39 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-27 14:34:39 +0200 |
commit | e6baa656f757fd1f2f6ba20c677e0c83422a8739 (patch) | |
tree | b2a396f41e1b8a08b796084d169f202d593f7357 /modules | |
parent | a3f90948d8fa4dd5c92e15cc10e86d2fec37f6e7 (diff) | |
download | gitea-e6baa656f757fd1f2f6ba20c677e0c83422a8739.tar.gz gitea-e6baa656f757fd1f2f6ba20c677e0c83422a8739.zip |
make avatar lookup occur at image request (#10540)
speed up page generation by making avatar lookup occur at the browser
not at page generation
* Protect against evil email address ".."
* hash the complete email address
Signed-off-by: Andrew Thornton <art27@cantab.net>
Co-Authored-By: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/base/tool.go | 31 | ||||
-rw-r--r-- | modules/base/tool_test.go | 11 | ||||
-rw-r--r-- | modules/cache/cache.go | 28 | ||||
-rw-r--r-- | modules/repository/commits.go | 3 | ||||
-rw-r--r-- | modules/repository/commits_test.go | 4 | ||||
-rw-r--r-- | modules/templates/helper.go | 2 |
6 files changed, 59 insertions, 20 deletions
diff --git a/modules/base/tool.go b/modules/base/tool.go index 86606c8bee..157bd9bc3d 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -193,11 +193,32 @@ func SizedAvatarLink(email string, size int) string { return avatarURL.String() } -// AvatarLink returns relative avatar link to the site domain by given email, -// which includes app sub-url as prefix. However, it is possible -// to return full URL if user enables Gravatar-like service. -func AvatarLink(email string) string { - return SizedAvatarLink(email, DefaultAvatarSize) +// SizedAvatarLinkWithDomain returns a sized link to the avatar for the given email +// address. +func SizedAvatarLinkWithDomain(email string, size int) string { + var avatarURL *url.URL + if setting.EnableFederatedAvatar && setting.LibravatarService != nil { + var err error + avatarURL, err = libravatarURL(email) + if err != nil { + return DefaultAvatarLink() + } + } else if !setting.DisableGravatar { + // copy GravatarSourceURL, because we will modify its Path. + copyOfGravatarSourceURL := *setting.GravatarSourceURL + avatarURL = ©OfGravatarSourceURL + avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email)) + } else { + return DefaultAvatarLink() + } + + vals := avatarURL.Query() + vals.Set("d", "identicon") + if size != DefaultAvatarSize { + vals.Set("s", strconv.Itoa(size)) + } + avatarURL.RawQuery = vals.Encode() + return avatarURL.String() } // FileSize calculates the file size and generate user-friendly string. diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index 075b5ed817..9c1a79e3f2 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -90,17 +90,6 @@ func TestSizedAvatarLink(t *testing.T) { ) } -func TestAvatarLink(t *testing.T) { - disableGravatar() - assert.Equal(t, "/img/avatar_default.png", AvatarLink("gitea@example.com")) - - enableGravatar(t) - assert.Equal(t, - "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon", - AvatarLink("gitea@example.com"), - ) -} - func TestFileSize(t *testing.T) { var size int64 = 512 assert.Equal(t, "512 B", FileSize(size)) diff --git a/modules/cache/cache.go b/modules/cache/cache.go index e3a905e3fa..859f4a4b47 100644 --- a/modules/cache/cache.go +++ b/modules/cache/cache.go @@ -41,6 +41,34 @@ func NewContext() error { return err } +// GetString returns the key value from cache with callback when no key exists in cache +func GetString(key string, getFunc func() (string, error)) (string, error) { + if conn == nil || setting.CacheService.TTL == 0 { + return getFunc() + } + if !conn.IsExist(key) { + var ( + value string + err error + ) + if value, err = getFunc(); err != nil { + return value, err + } + err = conn.Put(key, value, int64(setting.CacheService.TTL.Seconds())) + if err != nil { + return "", err + } + } + value := conn.Get(key) + if v, ok := value.(string); ok { + return v, nil + } + if v, ok := value.(fmt.Stringer); ok { + return v.String(), nil + } + return fmt.Sprintf("%s", conn.Get(key)), nil +} + // GetInt returns key value from cache with callback when no key exists in cache func GetInt(key string, getFunc func() (int, error)) (int, error) { if conn == nil || setting.CacheService.TTL == 0 { diff --git a/modules/repository/commits.go b/modules/repository/commits.go index 7345aaae24..e02f3d11ca 100644 --- a/modules/repository/commits.go +++ b/modules/repository/commits.go @@ -10,7 +10,6 @@ import ( "time" "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" @@ -124,7 +123,7 @@ func (pc *PushCommits) AvatarLink(email string) string { var err error u, err = models.GetUserByEmail(email) if err != nil { - pc.avatars[email] = base.AvatarLink(email) + pc.avatars[email] = models.AvatarLink(email) if !models.IsErrUserNotExist(err) { log.Error("GetUserByEmail: %v", err) return "" diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 2f61ce3329..cb00e19c2e 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -6,6 +6,8 @@ package repository import ( "container/list" + "crypto/md5" + "fmt" "testing" "time" @@ -114,7 +116,7 @@ func TestPushCommits_AvatarLink(t *testing.T) { pushCommits.AvatarLink("user2@example.com")) assert.Equal(t, - "https://secure.gravatar.com/avatar/19ade630b94e1e0535b3df7387434154?d=identicon", + "/avatar/"+fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com"))), pushCommits.AvatarLink("nonexistent@example.com")) } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 9d3206934e..b5b4987427 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -85,7 +85,7 @@ func NewFuncMap() []template.FuncMap { "AllowedReactions": func() []string { return setting.UI.Reactions }, - "AvatarLink": base.AvatarLink, + "AvatarLink": models.AvatarLink, "Safe": Safe, "SafeJS": SafeJS, "Str2html": Str2html, |