summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/base/tool.go57
-rw-r--r--modules/base/tool_test.go34
-rw-r--r--modules/setting/setting.go23
3 files changed, 91 insertions, 23 deletions
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 194db772cf..1316b8fad3 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -16,6 +16,8 @@ import (
"math"
"math/big"
"net/http"
+ "net/url"
+ "path"
"strconv"
"strings"
"time"
@@ -197,24 +199,59 @@ func DefaultAvatarLink() string {
return setting.AppSubURL + "/img/avatar_default.png"
}
-// 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 {
+// DefaultAvatarSize is a sentinel value for the default avatar size, as
+// determined by the avatar-hosting service.
+const DefaultAvatarSize = -1
+
+// libravatarURL returns the URL for the given email. This function should only
+// be called if a federated avatar service is enabled.
+func libravatarURL(email string) (*url.URL, error) {
+ urlStr, err := setting.LibravatarService.FromEmail(email)
+ if err != nil {
+ log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
+ return nil, err
+ }
+ u, err := url.Parse(urlStr)
+ if err != nil {
+ log.Error(4, "Failed to parse libravatar url(%s): error %v", urlStr, err)
+ return nil, err
+ }
+ return u, nil
+}
+
+// SizedAvatarLink returns a sized link to the avatar for the given email
+// address.
+func SizedAvatarLink(email string, size int) string {
+ var avatarURL *url.URL
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
- url, err := setting.LibravatarService.FromEmail(email)
+ var err error
+ avatarURL, err = libravatarURL(email)
if err != nil {
- log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
return DefaultAvatarLink()
}
- return url
+ } else if !setting.DisableGravatar {
+ // copy GravatarSourceURL, because we will modify its Path.
+ copyOfGravatarSourceURL := *setting.GravatarSourceURL
+ avatarURL = &copyOfGravatarSourceURL
+ avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email))
+ } else {
+ return DefaultAvatarLink()
}
- if !setting.DisableGravatar {
- return setting.GravatarSource + HashEmail(email) + "?d=identicon"
+ vals := avatarURL.Query()
+ vals.Set("d", "identicon")
+ if size != DefaultAvatarSize {
+ vals.Set("s", strconv.Itoa(size))
}
+ avatarURL.RawQuery = vals.Encode()
+ return avatarURL.String()
+}
- return DefaultAvatarLink()
+// 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)
}
// Seconds-based time units
diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go
index 44ea309f7c..ffa17fae00 100644
--- a/modules/base/tool_test.go
+++ b/modules/base/tool_test.go
@@ -1,11 +1,13 @@
package base
import (
+ "net/url"
"os"
"testing"
"time"
"code.gitea.io/gitea/modules/setting"
+
"github.com/Unknwon/i18n"
macaroni18n "github.com/go-macaron/i18n"
"github.com/stretchr/testify/assert"
@@ -126,16 +128,40 @@ func TestHashEmail(t *testing.T) {
)
}
-func TestAvatarLink(t *testing.T) {
+const gravatarSource = "https://secure.gravatar.com/avatar/"
+
+func disableGravatar() {
setting.EnableFederatedAvatar = false
setting.LibravatarService = nil
setting.DisableGravatar = true
+}
- assert.Equal(t, "/img/avatar_default.png", AvatarLink(""))
-
+func enableGravatar(t *testing.T) {
setting.DisableGravatar = false
+ var err error
+ setting.GravatarSourceURL, err = url.Parse(gravatarSource)
+ assert.NoError(t, err)
+}
+
+func TestSizedAvatarLink(t *testing.T) {
+ disableGravatar()
+ assert.Equal(t, "/img/avatar_default.png",
+ SizedAvatarLink("gitea@example.com", 100))
+
+ enableGravatar(t)
+ assert.Equal(t,
+ "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
+ SizedAvatarLink("gitea@example.com", 100),
+ )
+}
+
+func TestAvatarLink(t *testing.T) {
+ disableGravatar()
+ assert.Equal(t, "/img/avatar_default.png", AvatarLink("gitea@example.com"))
+
+ enableGravatar(t)
assert.Equal(t,
- "353cbad9b58e69c96154ad99f92bedc7?d=identicon",
+ "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon",
AvatarLink("gitea@example.com"),
)
}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index db6f749c06..f8da952413 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -326,6 +326,7 @@ var (
// Picture settings
AvatarUploadPath string
GravatarSource string
+ GravatarSourceURL *url.URL
DisableGravatar bool
EnableFederatedAvatar bool
LibravatarService *libravatar.Libravatar
@@ -1027,18 +1028,22 @@ func NewContext() {
if DisableGravatar {
EnableFederatedAvatar = false
}
+ if EnableFederatedAvatar || !DisableGravatar {
+ GravatarSourceURL, err = url.Parse(GravatarSource)
+ if err != nil {
+ log.Fatal(4, "Failed to parse Gravatar URL(%s): %v",
+ GravatarSource, err)
+ }
+ }
if EnableFederatedAvatar {
LibravatarService = libravatar.New()
- parts := strings.Split(GravatarSource, "/")
- if len(parts) >= 3 {
- if parts[0] == "https:" {
- LibravatarService.SetUseHTTPS(true)
- LibravatarService.SetSecureFallbackHost(parts[2])
- } else {
- LibravatarService.SetUseHTTPS(false)
- LibravatarService.SetFallbackHost(parts[2])
- }
+ if GravatarSourceURL.Scheme == "https" {
+ LibravatarService.SetUseHTTPS(true)
+ LibravatarService.SetSecureFallbackHost(GravatarSourceURL.Host)
+ } else {
+ LibravatarService.SetUseHTTPS(false)
+ LibravatarService.SetFallbackHost(GravatarSourceURL.Host)
}
}