diff options
author | Thomas Boerger <thomas@webhippie.de> | 2016-11-03 23:16:01 +0100 |
---|---|---|
committer | Thomas Boerger <thomas@webhippie.de> | 2016-11-04 08:43:11 +0100 |
commit | 1ebb35b98889ff77299f24d82da426b434b0cca0 (patch) | |
tree | 6dcb814d6df4d11c7e7a0ba6da8a6945628e2c5d /vendor/strk.kbt.io | |
parent | 78f86abba45cb35018c58b8bd5f4c48a86cc8634 (diff) | |
download | gitea-1ebb35b98889ff77299f24d82da426b434b0cca0.tar.gz gitea-1ebb35b98889ff77299f24d82da426b434b0cca0.zip |
Added all required dependencies
Diffstat (limited to 'vendor/strk.kbt.io')
-rw-r--r-- | vendor/strk.kbt.io/projects/go/libravatar/LICENSE | 19 | ||||
-rw-r--r-- | vendor/strk.kbt.io/projects/go/libravatar/README.md | 25 | ||||
-rw-r--r-- | vendor/strk.kbt.io/projects/go/libravatar/libravatar.go | 297 |
3 files changed, 341 insertions, 0 deletions
diff --git a/vendor/strk.kbt.io/projects/go/libravatar/LICENSE b/vendor/strk.kbt.io/projects/go/libravatar/LICENSE new file mode 100644 index 0000000000..8c89d4e34c --- /dev/null +++ b/vendor/strk.kbt.io/projects/go/libravatar/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 Sandro Santilli <strk@kbt.io> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/strk.kbt.io/projects/go/libravatar/README.md b/vendor/strk.kbt.io/projects/go/libravatar/README.md new file mode 100644 index 0000000000..660cd90643 --- /dev/null +++ b/vendor/strk.kbt.io/projects/go/libravatar/README.md @@ -0,0 +1,25 @@ +Simple [golang](https://www.golang.org) library for serving +[federated avatars](https://www.libravatar.org) + +# Use + +```sh +go get strk.kbt.io/projects/go/libravatar +cd $GOPATH/src/strk.kbt.io/projects/go/libravatar +go doc +``` + +# Contribute + +A clone of the code repository would be downloaded by `go get`. +You can send patches or pull requests to strk@kbt.io. + +If you need a place to publish your contribution branches, +you could start from a fork of the gitlab mirror: +https://gitlab.com/strk/go-libravatar + +# Contacts + + * Project homepage: http://strk.kbt.io/projects/go/libravatar + * Maintainer: Sandro Santilli <strk@kbt.io> + diff --git a/vendor/strk.kbt.io/projects/go/libravatar/libravatar.go b/vendor/strk.kbt.io/projects/go/libravatar/libravatar.go new file mode 100644 index 0000000000..4c748456f3 --- /dev/null +++ b/vendor/strk.kbt.io/projects/go/libravatar/libravatar.go @@ -0,0 +1,297 @@ +// 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 ( + // Default 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 +} + +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 +} + +// Instanciate a library 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, + } +} + +// Set the hostname for fallbacks in case no avatar service is defined +// for a domain +func (v *Libravatar) SetFallbackHost(host string) { + v.fallbackHost = host +} + +// Set 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 +} + +// Set useHTTPS flag +func (v *Libravatar) SetUseHTTPS(use bool) { + v.useHTTPS = use +} + +// Set 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 ( + total_weight uint16 + records []record + top_priority = addrs[0].Priority + top_record *net.SRV + ) + + for _, rr := range addrs { + if rr.Priority > top_priority { + continue + } else if rr.Priority < top_priority { + // won't happen, because net sorts + // by priority, but just in case + total_weight = 0 + records = nil + top_priority = rr.Priority + } + + total_weight += rr.Weight + + if rr.Weight > 0 { + records = append(records, record{rr, total_weight}) + } else if rr.Weight == 0 { + records = append([]record{record{srv: rr, weight: total_weight}}, records...) + } + } + + if len(records) == 1 { + top_record = records[0].srv + } else { + randnum := uint16(rand.Intn(int(total_weight))) + + for _, rr := range records { + if rr.weight >= randnum { + top_record = rr.srv + break + } + } + } + + domain = fmt.Sprintf("%s:%d", top_record.Target, top_record.Port) + } + + v.nameCache[key] = cacheValue{checkedAt: now, target: domain} + return protocol + domain, nil +} + +// Return 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 +} + +// Object-less call to DefaultLibravatar for an email adders +func FromEmail(email string) (string, error) { + return DefaultLibravatar.FromEmail(email) +} + +// Return 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 +} + +// Object-less call to DefaultLibravatar for a URL +func FromURL(openid string) (string, error) { + return DefaultLibravatar.FromURL(openid) +} |