diff options
Diffstat (limited to 'models/avatar.go')
-rw-r--r-- | models/avatar.go | 77 |
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 = ©OfGravatarSourceURL + avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email)) + } else { + return DefaultAvatarLink() + } + + return MakeFinalAvatarURL(avatarURL, size) +} |