diff options
Diffstat (limited to 'vendor/github.com/gogits/go-libravatar/libravatar.go')
-rw-r--r-- | vendor/github.com/gogits/go-libravatar/libravatar.go | 300 |
1 files changed, 0 insertions, 300 deletions
diff --git a/vendor/github.com/gogits/go-libravatar/libravatar.go b/vendor/github.com/gogits/go-libravatar/libravatar.go deleted file mode 100644 index 5088d02c..00000000 --- a/vendor/github.com/gogits/go-libravatar/libravatar.go +++ /dev/null @@ -1,300 +0,0 @@ -// Copyright 2016 by Sandro Santilli <strk@kbt.io> -// Use of this source code is governed by a MIT -// license that can be found in the LICENSE file. - -// Implements support for federated avatars lookup. -// See https://wiki.libravatar.org/api/ - -package libravatar - -import ( - "crypto/md5" - "crypto/sha256" - "fmt" - "math/rand" - "net" - "net/mail" - "net/url" - "strings" - "time" -) - -// Default images (to be used as defaultURL) -const ( - // Do not load any image if none is associated with the email - // hash, instead return an HTTP 404 (File Not Found) response - HTTP404 = "404" - // (mystery-man) a simple, cartoon-style silhouetted outline of - // a person (does not vary by email hash) - MysteryMan = "mm" - // a geometric pattern based on an email hash - IdentIcon = "identicon" - // a generated 'monster' with different colors, faces, etc - MonsterID = "monsterid" - // generated faces with differing features and backgrounds - Wavatar = "wavatar" - // awesome generated, 8-bit arcade-style pixelated faces - Retro = "retro" -) - -var ( - // DefaultLibravatar is a default Libravatar object, - // enabling object-less function calls - DefaultLibravatar = New() -) - -/* This should be moved in its own file */ -type cacheKey struct { - service string - domain string -} - -type cacheValue struct { - target string - checkedAt time.Time -} - -// Libravatar is an opaque structure holding service configuration -type Libravatar struct { - defURL string // default url - picSize int // picture size - fallbackHost string // default fallback URL - secureFallbackHost string // default fallback URL for secure connections - useHTTPS bool - nameCache map[cacheKey]cacheValue - nameCacheDuration time.Duration - minSize uint // smallest image dimension allowed - maxSize uint // largest image dimension allowed - size uint // what dimension should be used - serviceBase string // SRV record to be queried for federation - secureServiceBase string // SRV record to be queried for federation with secure servers -} - -// New instanciates a new Libravatar object (handle) -func New() *Libravatar { - // According to https://wiki.libravatar.org/running_your_own/ - // the time-to-live (cache expiry) should be set to at least 1 day. - return &Libravatar{ - fallbackHost: `cdn.libravatar.org`, - secureFallbackHost: `seccdn.libravatar.org`, - minSize: 1, - maxSize: 512, - size: 0, // unset, defaults to 80 - serviceBase: `avatars`, - secureServiceBase: `avatars-sec`, - nameCache: make(map[cacheKey]cacheValue), - nameCacheDuration: 24 * time.Hour, - } -} - -// SetFallbackHost sets the hostname for fallbacks in case no avatar -// service is defined for a domain -func (v *Libravatar) SetFallbackHost(host string) { - v.fallbackHost = host -} - -// SetSecureFallbackHost sets the hostname for fallbacks in case no -// avatar service is defined for a domain, when requiring secure domains -func (v *Libravatar) SetSecureFallbackHost(host string) { - v.secureFallbackHost = host -} - -// SetUseHTTPS sets flag requesting use of https for fetching avatars -func (v *Libravatar) SetUseHTTPS(use bool) { - v.useHTTPS = use -} - -// SetAvatarSize sets avatars image dimension (0 for default) -func (v *Libravatar) SetAvatarSize(size uint) { - v.size = size -} - -// generate hash, either with email address or OpenID -func (v *Libravatar) genHash(email *mail.Address, openid *url.URL) string { - if email != nil { - email.Address = strings.ToLower(strings.TrimSpace(email.Address)) - sum := md5.Sum([]byte(email.Address)) - return fmt.Sprintf("%x", sum) - } else if openid != nil { - openid.Scheme = strings.ToLower(openid.Scheme) - openid.Host = strings.ToLower(openid.Host) - sum := sha256.Sum256([]byte(openid.String())) - return fmt.Sprintf("%x", sum) - } - // panic, because this should not be reachable - panic("Neither Email or OpenID set") -} - -// Gets domain out of email or openid (for openid to be parsed, email has to be nil) -func (v *Libravatar) getDomain(email *mail.Address, openid *url.URL) string { - if email != nil { - u, err := url.Parse("//" + email.Address) - if err != nil { - if v.useHTTPS && v.secureFallbackHost != "" { - return v.secureFallbackHost - } - return v.fallbackHost - } - return u.Host - } else if openid != nil { - return openid.Host - } - // panic, because this should not be reachable - panic("Neither Email or OpenID set") -} - -// Processes email or openid (for openid to be processed, email has to be nil) -func (v *Libravatar) process(email *mail.Address, openid *url.URL) (string, error) { - URL, err := v.baseURL(email, openid) - if err != nil { - return "", err - } - res := fmt.Sprintf("%s/avatar/%s", URL, v.genHash(email, openid)) - - values := make(url.Values) - if v.defURL != "" { - values.Add("d", v.defURL) - } - if v.size > 0 { - values.Add("s", fmt.Sprintf("%d", v.size)) - } - - if len(values) > 0 { - return fmt.Sprintf("%s?%s", res, values.Encode()), nil - } - return res, nil -} - -// Finds or defaults a URL for Federation (for openid to be used, email has to be nil) -func (v *Libravatar) baseURL(email *mail.Address, openid *url.URL) (string, error) { - var service, protocol, domain string - - if v.useHTTPS { - protocol = "https://" - service = v.secureServiceBase - domain = v.secureFallbackHost - - } else { - protocol = "http://" - service = v.serviceBase - domain = v.fallbackHost - } - - host := v.getDomain(email, openid) - key := cacheKey{service, host} - now := time.Now() - val, found := v.nameCache[key] - if found && now.Sub(val.checkedAt) <= v.nameCacheDuration { - return protocol + val.target, nil - } - - _, addrs, err := net.LookupSRV(service, "tcp", host) - if err != nil && err.(*net.DNSError).IsTimeout { - return "", err - } - - if len(addrs) == 1 { - // select only record, if only one is available - domain = strings.TrimSuffix(addrs[0].Target, ".") - } else if len(addrs) > 1 { - // Select first record according to RFC2782 weight - // ordering algorithm (page 3) - - type record struct { - srv *net.SRV - weight uint16 - } - - var ( - totalWeight uint16 - records []record - topPriority = addrs[0].Priority - topRecord *net.SRV - ) - - for _, rr := range addrs { - if rr.Priority > topPriority { - continue - } else if rr.Priority < topPriority { - // won't happen, because net sorts - // by priority, but just in case - totalWeight = 0 - records = nil - topPriority = rr.Priority - } - - totalWeight += rr.Weight - - if rr.Weight > 0 { - records = append(records, record{rr, totalWeight}) - } else if rr.Weight == 0 { - records = append([]record{record{srv: rr, weight: totalWeight}}, records...) - } - } - - if len(records) == 1 { - topRecord = records[0].srv - } else { - randnum := uint16(rand.Intn(int(totalWeight))) - - for _, rr := range records { - if rr.weight >= randnum { - topRecord = rr.srv - break - } - } - } - - domain = fmt.Sprintf("%s:%d", topRecord.Target, topRecord.Port) - } - - v.nameCache[key] = cacheValue{checkedAt: now, target: domain} - return protocol + domain, nil -} - -// FromEmail returns the url of the avatar for the given email -func (v *Libravatar) FromEmail(email string) (string, error) { - addr, err := mail.ParseAddress(email) - if err != nil { - return "", err - } - - link, err := v.process(addr, nil) - if err != nil { - return "", err - } - - return link, nil -} - -// FromEmail is the object-less call to DefaultLibravatar for an email adders -func FromEmail(email string) (string, error) { - return DefaultLibravatar.FromEmail(email) -} - -// FromURL returns the url of the avatar for the given url (typically -// for OpenID) -func (v *Libravatar) FromURL(openid string) (string, error) { - ourl, err := url.Parse(openid) - if err != nil { - return "", err - } - - if !ourl.IsAbs() { - return "", fmt.Errorf("Is not an absolute URL") - } else if ourl.Scheme != "http" && ourl.Scheme != "https" { - return "", fmt.Errorf("Invalid protocol: %s", ourl.Scheme) - } - - link, err := v.process(nil, ourl) - if err != nil { - return "", err - } - - return link, nil -} - -// FromURL is the object-less call to DefaultLibravatar for a URL -func FromURL(openid string) (string, error) { - return DefaultLibravatar.FromURL(openid) -} |