aboutsummaryrefslogtreecommitdiffstats
path: root/models/avatar.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/avatar.go')
-rw-r--r--models/avatar.go77
1 files changed, 75 insertions, 2 deletions
diff --git a/models/avatar.go b/models/avatar.go
index c9ba2961ef..ac260fbd93 100644
--- a/models/avatar.go
+++ b/models/avatar.go
@@ -8,9 +8,13 @@ import (
"crypto/md5"
"fmt"
"net/url"
+ "path"
+ "strconv"
"strings"
+ "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@@ -20,6 +24,28 @@ type EmailHash struct {
Email string `xorm:"UNIQUE NOT NULL"`
}
+// DefaultAvatarLink the default avatar link
+func DefaultAvatarLink() string {
+ u, err := url.Parse(setting.AppSubURL)
+ if err != nil {
+ log.Error("GetUserByEmail: %v", err)
+ return ""
+ }
+
+ u.Path = path.Join(u.Path, "/img/avatar_default.png")
+ return u.String()
+}
+
+// DefaultAvatarSize is a sentinel value for the default avatar size, as
+// determined by the avatar-hosting service.
+const DefaultAvatarSize = -1
+
+// HashEmail hashes email address to MD5 string.
+// https://en.gravatar.com/site/implement/hash/
+func HashEmail(email string) string {
+ return base.EncodeMD5(strings.ToLower(strings.TrimSpace(email)))
+}
+
// GetEmailForHash converts a provided md5sum to the email
func GetEmailForHash(md5Sum string) (string, error) {
return cache.GetString("Avatar:"+md5Sum, func() (string, error) {
@@ -32,8 +58,24 @@ func GetEmailForHash(md5Sum string) (string, error) {
})
}
-// AvatarLink returns an avatar link for a provided email
-func AvatarLink(email string) string {
+// 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("LibravatarService.FromEmail(email=%s): error %v", email, err)
+ return nil, err
+ }
+ u, err := url.Parse(urlStr)
+ if err != nil {
+ log.Error("Failed to parse libravatar url(%s): error %v", urlStr, err)
+ return nil, err
+ }
+ return u, nil
+}
+
+// HashedAvatarLink returns an avatar link for a provided email
+func HashedAvatarLink(email string) string {
lowerEmail := strings.ToLower(strings.TrimSpace(email))
sum := fmt.Sprintf("%x", md5.Sum([]byte(lowerEmail)))
_, _ = cache.GetString("Avatar:"+sum, func() (string, error) {
@@ -57,3 +99,34 @@ func AvatarLink(email string) string {
})
return setting.AppSubURL + "/avatar/" + url.PathEscape(sum)
}
+
+// MakeFinalAvatarURL constructs the final avatar URL string
+func MakeFinalAvatarURL(u *url.URL, size int) string {
+ vals := u.Query()
+ vals.Set("d", "identicon")
+ if size != DefaultAvatarSize {
+ vals.Set("s", strconv.Itoa(size))
+ }
+ u.RawQuery = vals.Encode()
+ return u.String()
+}
+
+// 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 {
+ // This is the slow path that would need to call LibravatarURL() which
+ // does DNS lookups. Avoid it by issuing a redirect so we don't block
+ // the template render with network requests.
+ return HashedAvatarLink(email)
+ } 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()
+ }
+
+ return MakeFinalAvatarURL(avatarURL, size)
+}