<commit_before>// Package idn implements encoding from and to punycode as speficied by RFC 3492.
package idn

import (
	"bytes"
	"github.com/miekg/dns"
	"strings"
	"unicode"
)

// See http://tools.ietf.org/html/rfc3492
// Implementation idea from RFC itself and from from IDNA::Punycode created by
// Tatsuhiko Miyagawa <miyagawa@bulknews.net> and released under Perl Artistic
// License in 2002

const (
	_MIN  rune = 1
	_MAX  rune = 26
	_SKEW rune = 38
	_DAMP rune = 700
	_BASE rune = 36
	_BIAS rune = 72
	_N    rune = 128

	_DELIMITER = '-'
	_PREFIX    = "xn--"
)

// ToPunycode converts unicode domain names to DNS-appropriate punycode names.
// This function would return incorrect result for strings for non-canonical
// unicode strings.
func ToPunycode(s string) string {
	tokens := dns.SplitDomainName(s)
	if s[len(s)-1] == '.' {
		if tokens == nil {
			tokens = []string{"", ""}
		} else {
			tokens = append(tokens, "")
		}
	}
	for i := range tokens {
		tokens[i] = string(encodeBytes([]byte(tokens[i])))
	}
	return strings.Join(tokens, ".")
}

// FromPunycode returns uncode domain name from provided punycode string.
func FromPunycode(s string) string {
	tokens := dns.SplitDomainName(s)
	if s[len(s)-1] == '.' {
		if tokens == nil {
			tokens = []string{"", ""}
		} else {
			tokens = append(tokens, "")
		}
	}
	for i := range tokens {
		tokens[i] = string(decodeBytes([]byte(tokens[i])))
	}
	return strings.Join(tokens, ".")
}

// digitval converts single byte into meaningful value that's used to calculate decoded unicode character.
const errdigit = 0xffff

func digitval(code rune) rune {
	switch {
	case code >= 'A' && code <= 'Z':
		return code - 'A'
	case code >= 'a' && code <= 'z':
		return code - 'a'
	case code >= '0' && code <= '9':
		return code - '0' + 26
	}
	return errdigit
}

// lettercode finds BASE36 byte (a-z0-9) based on calculated number.
func lettercode(digit rune) rune {
	switch {
	case digit >= 0 && digit <= 25:
		return digit + 'a'
	case digit >= 26 && digit <= 36:
		return digit - 26 + '0'
	}
	panic("dns: not reached")
}

// adapt calculates next bias to be used for next iteration delta
func adapt(delta rune, numpoints rune, firsttime bool) rune {
	if firsttime {
		delta /= _DAMP
	} else {
		delta /= 2
	}

	var k rune
	for delta = delta + delta/numpoints; delta > (_BASE-_MIN)*_MAX/2; k += _BASE {
		delta /= _BASE - _MIN
	}

	return k + ((_BASE-_MIN+1)*delta)/(delta+_SKEW)
}

// next finds minimal rune (one with lowest codepoint value) that should be equal or above boundary.
func next(b []rune, boundary rune) rune {
	if len(b) == 0 {
		panic("invalid set of runes to determine next one")
	}
	m := b[0]
	for _, x := range b[1:] {
		if x >= boundary && (m < boundary || x < m) {
			m = x
		}
	}
	return m
}

// preprune converts unicode rune to lower case. At this time it's not
// supporting all things described RFC3454.
func preprune(r rune) rune {
	if unicode.IsUpper(r) {
		r = unicode.ToLower(r)
	}
	return r
}

// tfunc is a function that helps calculate each character weight
func tfunc(k, bias rune) rune {
	switch {
	case k <= bias:
		return _MIN
	case k >= bias+_MAX:
		return _MAX
	}
	return k - bias
}

// encodeBytes transforms Unicode input bytes (that represent DNS label) into punycode bytestream
func encodeBytes(input []byte) []byte {
	n, delta, bias := _N, rune(0), _BIAS

	b := bytes.Runes(input)
	for i := range b {
		b[i] = preprune(b[i])
	}

	basic := make([]byte, 0, len(b))
	for _, ltr := range b {
		if ltr <= 0x7f {
			basic = append(basic, byte(ltr))
		}
	}
	basiclen := rune(len(basic))
	fulllen := rune(len(b))
	if basiclen == fulllen {
		return basic
	}

	var out bytes.Buffer

	out.WriteString(_PREFIX)
	if basiclen > 0 {
		out.Write(basic)
		out.WriteByte(_DELIMITER)
	}

	for h := basiclen; h < fulllen; n, delta = n+1, delta+1 {
		next := next(b, n)
		s := &bytes.Buffer{}
		s.WriteRune(next)
		delta, n = delta+(next-n)*(h+1), next

		for _, ltr := range b {
			if ltr < n {
				delta++
			}
			if ltr == n {
				q := delta
				for k := _BASE; ; k += _BASE {
					t := tfunc(k, bias)
					if q < t {
						break
					}
					cp := t + ((q - t) % (_BASE - t))
					out.WriteRune(lettercode(cp))
					q = (q - t) / (_BASE - t)
				}

				out.WriteRune(lettercode(q))

				bias = adapt(delta, h+1, h == basiclen)
				h, delta = h+1, 0
			}
		}
	}
	return out.Bytes()
}

// decodeBytes transforms punycode input bytes (that represent DNS label) into Unicode bytestream
func decodeBytes(b []byte) []byte {
	src := b // b would move and we need to keep it

	n, bias := _N, _BIAS
	if !bytes.HasPrefix(b, []byte(_PREFIX)) {
		return b
	}
	out := make([]rune, 0, len(b))
	b = b[len(_PREFIX):]
	for pos, x := range b {
		if x == _DELIMITER {
			out = append(out, bytes.Runes(b[:pos])...)
			b = b[pos+1:] // trim source string
			break
		}
	}
	if len(b) == 0 {
		return src
	}
	for i := rune(0); len(b) > 0; i++ {
		oldi, w, ch := i, rune(1), byte(0)
		for k := _BASE; len(b) > 0; k += _BASE {
			ch, b = b[0], b[1:]
			digit := digitval(rune(ch))
			if digit == errdigit {
				return src
			}
			i += digit * w

			t := tfunc(k, bias)
			if digit < t {
				break
			}

			w *= _BASE - t
		}
		ln := rune(len(out) + 1)
		bias = adapt(i-oldi, ln, oldi == 0)
		n += i / ln
		i = i % ln
		// insert
		out = append(out, 0)
		copy(out[i+1:], out[i:])
		out[i] = n
	}

	var ret bytes.Buffer
	for _, r := range out {
		ret.WriteRune(r)
	}
	return ret.Bytes()
}
<commit_msg>Replaced rune(0) to new const<commit_after>// Package idn implements encoding from and to punycode as speficied by RFC 3492.
package idn

import (
	"bytes"
	"github.com/miekg/dns"
	"strings"
	"unicode"
)

// See http://tools.ietf.org/html/rfc3492
// Implementation idea from RFC itself and from from IDNA::Punycode created by
// Tatsuhiko Miyagawa <miyagawa@bulknews.net> and released under Perl Artistic
// License in 2002

const (
	_MIN  rune = 1
	_MAX  rune = 26
	_SKEW rune = 38
	_BASE rune = 36
	_BIAS rune = 72
	_N    rune = 128
	_DAMP rune = 700

	_DELIMITER = '-'
	_PREFIX    = "xn--"
)

// ToPunycode converts unicode domain names to DNS-appropriate punycode names.
// This function would return incorrect result for strings for non-canonical
// unicode strings.
func ToPunycode(s string) string {
	tokens := dns.SplitDomainName(s)
	if s[len(s)-1] == '.' {
		if tokens == nil {
			tokens = []string{"", ""}
		} else {
			tokens = append(tokens, "")
		}
	}
	for i := range tokens {
		tokens[i] = string(encodeBytes([]byte(tokens[i])))
	}
	return strings.Join(tokens, ".")
}

// FromPunycode returns uncode domain name from provided punycode string.
func FromPunycode(s string) string {
	tokens := dns.SplitDomainName(s)
	if s[len(s)-1] == '.' {
		if tokens == nil {
			tokens = []string{"", ""}
		} else {
			tokens = append(tokens, "")
		}
	}
	for i := range tokens {
		tokens[i] = string(decodeBytes([]byte(tokens[i])))
	}
	return strings.Join(tokens, ".")
}

// digitval converts single byte into meaningful value that's used to calculate decoded unicode character.
const errdigit = 0xffff

func digitval(code rune) rune {
	switch {
	case code >= 'A' && code <= 'Z':
		return code - 'A'
	case code >= 'a' && code <= 'z':
		return code - 'a'
	case code >= '0' && code <= '9':
		return code - '0' + 26
	}
	return errdigit
}

// lettercode finds BASE36 byte (a-z0-9) based on calculated number.
func lettercode(digit rune) rune {
	switch {
	case digit >= 0 && digit <= 25:
		return digit + 'a'
	case digit >= 26 && digit <= 36:
		return digit - 26 + '0'
	}
	panic("dns: not reached")
}

// adapt calculates next bias to be used for next iteration delta
func adapt(delta rune, numpoints rune, firsttime bool) rune {
	if firsttime {
		delta /= _DAMP
	} else {
		delta /= 2
	}

	var k rune
	for delta = delta + delta/numpoints; delta > (_BASE-_MIN)*_MAX/2; k += _BASE {
		delta /= _BASE - _MIN
	}

	return k + ((_BASE-_MIN+1)*delta)/(delta+_SKEW)
}

// next finds minimal rune (one with lowest codepoint value) that should be equal or above boundary.
func next(b []rune, boundary rune) rune {
	if len(b) == 0 {
		panic("invalid set of runes to determine next one")
	}
	m := b[0]
	for _, x := range b[1:] {
		if x >= boundary && (m < boundary || x < m) {
			m = x
		}
	}
	return m
}

// preprune converts unicode rune to lower case. At this time it's not
// supporting all things described RFC3454.
func preprune(r rune) rune {
	if unicode.IsUpper(r) {
		r = unicode.ToLower(r)
	}
	return r
}

// tfunc is a function that helps calculate each character weight
func tfunc(k, bias rune) rune {
	switch {
	case k <= bias:
		return _MIN
	case k >= bias+_MAX:
		return _MAX
	}
	return k - bias
}

// encodeBytes transforms Unicode input bytes (that represent DNS label) into punycode bytestream
func encodeBytes(input []byte) []byte {
	n, bias := _N, _BIAS

	b := bytes.Runes(input)
	for i := range b {
		b[i] = preprune(b[i])
	}

	basic := make([]byte, 0, len(b))
	for _, ltr := range b {
		if ltr <= 0x7f {
			basic = append(basic, byte(ltr))
		}
	}
	basiclen := rune(len(basic))
	fulllen := rune(len(b))
	if basiclen == fulllen {
		return basic
	}

	var out bytes.Buffer

	out.WriteString(_PREFIX)
	if basiclen > 0 {
		out.Write(basic)
		out.WriteByte(_DELIMITER)
	}

	var (
		ltr, nextltr rune
		delta, q     rune // delta calculation (see rfc)
		t, k, cp     rune // weight and codepoint calculation
	)

	s := &bytes.Buffer{}
	for h := basiclen; h < fulllen; n, delta = n+1, delta+1 {
		nextltr = next(b, n)
		s.Truncate(0)
		s.WriteRune(nextltr)
		delta, n = delta+(nextltr-n)*(h+1), nextltr

		for _, ltr = range b {
			if ltr < n {
				delta++
			}
			if ltr == n {
				q = delta
				for k = _BASE; ; k += _BASE {
					t = tfunc(k, bias)
					if q < t {
						break
					}
					cp = t + ((q - t) % (_BASE - t))
					out.WriteRune(lettercode(cp))
					q = (q - t) / (_BASE - t)
				}

				out.WriteRune(lettercode(q))

				bias = adapt(delta, h+1, h == basiclen)
				h, delta = h+1, 0
			}
		}
	}
	return out.Bytes()
}

// decodeBytes transforms punycode input bytes (that represent DNS label) into Unicode bytestream
func decodeBytes(b []byte) []byte {
	src := b // b would move and we need to keep it

	n, bias := _N, _BIAS
	if !bytes.HasPrefix(b, []byte(_PREFIX)) {
		return b
	}
	out := make([]rune, 0, len(b))
	b = b[len(_PREFIX):]
	for pos, x := range b {
		if x == _DELIMITER {
			out = append(out, bytes.Runes(b[:pos])...)
			b = b[pos+1:] // trim source string
			break
		}
	}
	if len(b) == 0 {
		return src
	}
	var (
		i, oldi, w   rune
		ch           byte
		t, digit, ln rune
	)

	for i = 0; len(b) > 0; i++ {
		oldi, w = i, 1
		for k := _BASE; len(b) > 0; k += _BASE {
			ch, b = b[0], b[1:]
			digit = digitval(rune(ch))
			if digit == errdigit {
				return src
			}
			i += digit * w

			t = tfunc(k, bias)
			if digit < t {
				break
			}

			w *= _BASE - t
		}
		ln = rune(len(out) + 1)
		bias = adapt(i-oldi, ln, oldi == 0)
		n += i / ln
		i = i % ln
		// insert
		out = append(out, 0)
		copy(out[i+1:], out[i:])
		out[i] = n
	}

	var ret bytes.Buffer
	for _, r := range out {
		ret.WriteRune(r)
	}
	return ret.Bytes()
}
<|endoftext|>


<commit_before>package wally

import (
	"io/ioutil"
	"net/http"

	rdb "github.com/dancannon/gorethink"
	"github.com/nylar/odlaw"
)

func GrabUrl(url string) ([]byte, error) {
	resp, err := http.Get(url)
	if err != nil {
		return []byte{}, err
	}

	data, err := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()
	if err != nil {
		return []byte{}, err
	}
	return data, nil
}

func Crawler(url string, session *rdb.Session) error {
	data, err := GrabUrl(url)
	if err != nil {
		return err
	}

	doc := odlaw.NewDocument(string(data))
	title := odlaw.ExtractTitle(doc)
	author := odlaw.ExtractAuthor(doc)
	content := odlaw.ExtractText(doc)

	d := Document{
		Source:  url,
		Title:   title,
		Author:  author,
		Content: content,
	}
	if err := d.Put(session); err != nil {
		return err
	}

	indexes := Indexer(content, d.Id)

	if _, err := rdb.Db(Database).Table(IndexTable).Insert(indexes).RunWrite(session); err != nil {
		return err
	}

	return nil
}
<commit_msg>Remove error from ioutil.ReadAll because it's very hard to make it fail<commit_after>package wally

import (
	"io/ioutil"
	"net/http"

	rdb "github.com/dancannon/gorethink"
	"github.com/nylar/odlaw"
)

func GrabUrl(url string) ([]byte, error) {
	resp, err := http.Get(url)
	if err != nil {
		return []byte{}, err
	}

	data, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()

	return data, nil
}

func Crawler(url string, session *rdb.Session) error {
	data, err := GrabUrl(url)
	if err != nil {
		return err
	}

	doc := odlaw.NewDocument(string(data))
	title := odlaw.ExtractTitle(doc)
	author := odlaw.ExtractAuthor(doc)
	content := odlaw.ExtractText(doc)

	d := Document{
		Source:  url,
		Title:   title,
		Author:  author,
		Content: content,
	}
	if err := d.Put(session); err != nil {
		return err
	}

	indexes := Indexer(content, d.Id)

	if _, err := rdb.Db(Database).Table(IndexTable).Insert(indexes).RunWrite(session); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/SudoQ/crisp/service"
	"log"
	"runtime"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

var configFilename string
var url string
var port string
var limit uint

func init() {
	flag.StringVar(&configFilename, "f", "config.json", "Path to configuration file")
	flag.StringVar(&url, "url", "http://whatthecommit.com/index.txt", "URL to cache")
	flag.StringVar(&port, "p", "8080", "Port number of the crisp service")
	flag.UintVar(&limit, "l", 60, "Limit of requests per hour")
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	flag.Parse()

	useConfig := false
	flag.Visit(func(flg *flag.Flag) {
		if flg.Name == "f" {
			useConfig = true
		}
	})

	var srv *service.Service
	if useConfig {
		var err error
		srv, err = service.NewFromFile(configFilename)
		if err != nil {
			log.Fatal(err)
			return
		}
	} else {
		srv = service.New(url, port, limit)
	}
	log.Println(srv.Info())
	srv.Run()
}
<commit_msg>Commit that got lost<commit_after>package main

import (
	"flag"
	"github.com/SudoQ/crisp/service"
	"log"
	"runtime"
)

func check(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

var configFilename string
var port string
var limit uint

func init() {
	flag.StringVar(&configFilename, "file", "config.json", "Path to configuration file")
	flag.StringVar(&configFilename, "f", "config.json", "Path to configuration file (shorthand)")

	flag.StringVar(&port, "port", "8080", "Port number of the crisp service")
	flag.StringVar(&port, "p", "8080", "Port number of the crisp service (shorthand)")

	flag.UintVar(&limit, "limit", 60, "Limit of requests per hour")
	flag.UintVar(&limit, "l", 60, "Limit of requests per hour (shorthand)")

	runtime.GOMAXPROCS(runtime.NumCPU())
}

func main() {
	flag.Parse()

	useConfig := false
	flag.Visit(func(flg *flag.Flag) {
		if flg.Name == "f" {
			useConfig = true
		}
	})

	var url string
	if len(flag.Args()) != 1 {
		log.Println(
			fmt.Sprintf("Usage: \n\t%s\n\t%s",
									"crisp [-p=port] [-l=limit] <url>",
									"crisp -f=<file>"))
		return
	}
	url = flag.Arg(0)

	var srv *service.Service
	if useConfig {
		var err error
		srv, err = service.NewFromFile(configFilename)
		if err != nil {
			log.Fatal(err)
			return
		}
	} else {
		srv = service.New(url, port, limit)
	}
	log.Println(srv.Info())
	srv.Run()
}
<|endoftext|>


<commit_before>package dbf

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"sync"
)

type StructCrackTask struct {
	Crack_id string `json:"crack_id"`
	Start    string `json:"start"`
	Offset   string `json:"offset"`
	Platform string `json:"platform"`
}

var wg sync.WaitGroup

func saveTask(tasks *[]StructCrackTask) {
	taskPath := getPath(_PATH_TASK)
	for _, task := range *tasks {
		taskJson, err := json.Marshal(&task)
		if err == nil {
			err = checkDir(taskPath + task.Platform)
			if err == nil {
				err = ioutil.WriteFile(taskPath+task.Platform+PATH_SEPARATOR+"task.json", taskJson, 0664)
				if err == nil {
					wg.Add(1)
					go processTask(task)
					//					if processTask(&task) == false {
					//						Log.Printf("Error in processing crack #%s \n", task.Crack_id)
					//					}
				} else {
					Log.Printf("%s\n", err)
				}
			} else {
				Log.Printf("%s\n", err)
			}
		} else {
			Log.Printf("%s\n", err)
		}
	}

	wg.Wait() // Wait for all tasks to finish
}

func processTask(task StructCrackTask) bool {
	defer wg.Done()

	crackInfoPath := getPath(_PATH_CRACK) + task.Crack_id + PATH_SEPARATOR
	err := checkDir(crackInfoPath)
	if err != nil {
		Log.Printf("%s\n", err)
		return false
	}
	crackInfoPath += "crack.json"

	if _, err := os.Stat(crackInfoPath); err != nil {
		if os.IsNotExist(err) { // Does not exist, so get it

			fmt.Printf("Getting crack info of crack #%s...\n", task.Crack_id)

			if getCrackInfo(`{"id":"`+task.Crack_id+`","platform":"`+task.Platform+`"}`, &crackInfoPath) == false {
				return false
			}
		} else {
			Log.Printf("%s\n", err) // Error in accessing
			return false
		}
	}

	// Process crack
	return processCrack(&task, &crackInfoPath)
}
<commit_msg>Log error of task processing<commit_after>package dbf

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"sync"
)

type StructCrackTask struct {
	Crack_id string `json:"crack_id"`
	Start    string `json:"start"`
	Offset   string `json:"offset"`
	Platform string `json:"platform"`
}

var wg sync.WaitGroup

func saveTask(tasks *[]StructCrackTask) {
	taskPath := getPath(_PATH_TASK)
	for _, task := range *tasks {
		taskJson, err := json.Marshal(&task)
		if err == nil {
			err = checkDir(taskPath + task.Platform)
			if err == nil {
				err = ioutil.WriteFile(taskPath+task.Platform+PATH_SEPARATOR+"task.json", taskJson, 0664)
				if err == nil {
					wg.Add(1)
					go processTask(task)
				} else {
					Log.Printf("%s\n", err)
				}
			} else {
				Log.Printf("%s\n", err)
			}
		} else {
			Log.Printf("%s\n", err)
		}
	}

	wg.Wait() // Wait for all tasks to finish
}

func processTask(task StructCrackTask) (status bool) {
	defer func() {
		if status == false {
			Log.Printf("Error in processing crack #%s \n", task.Crack_id)
		}

		wg.Done()
	}()

	crackInfoPath := getPath(_PATH_CRACK) + task.Crack_id + PATH_SEPARATOR
	err := checkDir(crackInfoPath)
	if err != nil {
		Log.Printf("%s\n", err)
		return false
	}
	crackInfoPath += "crack.json"

	if _, err := os.Stat(crackInfoPath); err != nil {
		if os.IsNotExist(err) { // Does not exist, so get it

			fmt.Printf("Getting crack info of crack #%s...\n", task.Crack_id)

			if getCrackInfo(`{"id":"`+task.Crack_id+`","platform":"`+task.Platform+`"}`, &crackInfoPath) == false {
				return false
			}
		} else {
			Log.Printf("%s\n", err) // Error in accessing
			return false
		}
	}

	// Process crack
	return processCrack(&task, &crackInfoPath)
}
<|endoftext|>


<commit_before>// An IMAP client.
package client

import (
	"bufio"
	"crypto/tls"
	"io"
	"log"
	"net"

	imap "github.com/emersion/imap/common"
	"github.com/emersion/imap/responses"
)

// An IMAP client.
type Client struct {
	conn net.Conn
	writer *imap.Writer
	handlers []imap.RespHandler

	// The server capabilities.
	Caps map[string]bool
	// The current connection state.
	State imap.ConnState
	// The selected mailbox, if there is one.
	Selected *imap.MailboxStatus
}

func (c *Client) read() error {
	r := imap.NewReader(bufio.NewReader(c.conn))

	defer (func () {
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			close(hdlr)
		}
		c.handlers = nil
	})()

	for {
		if c.State == imap.LogoutState {
			return nil
		}

		res, err := imap.ReadResp(r)
		if err == io.EOF {
			return nil
		}
		if err != nil {
			log.Println("Error reading response:", err)
			continue
		}

		var accepted bool
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			h := &imap.RespHandling{
				Resp: res,
				Accepts: make(chan bool),
			}

			hdlr <- h

			accepted = <-h.Accepts
			if accepted {
				break
			}
		}

		if !accepted {
			log.Println("Response has not been handled", res)
		}
	}

	return nil
}

func (c *Client) addHandler(hdlr imap.RespHandler) {
	// TODO: needs locker
	c.handlers = append(c.handlers, hdlr)
}

func (c *Client) removeHandler(hdlr imap.RespHandler) {
	// TODO: really remove handler from array? (needs locker)
	for i, h := range c.handlers {
		if h == hdlr {
			close(hdlr)
			c.handlers[i] = nil
		}
	}
}

func (c *Client) execute(cmdr imap.Commander, res imap.RespHandlerFrom) (status *imap.StatusResp, err error) {
	cmd := cmdr.Command()
	cmd.Tag = generateTag()

	_, err = cmd.WriteTo(c.writer)
	if err != nil {
		return
	}

	statusHdlr := make(imap.RespHandler)
	c.addHandler(statusHdlr)
	defer c.removeHandler(statusHdlr)

	var hdlr imap.RespHandler
	var done chan error
	defer (func () {
		if hdlr != nil { close(hdlr) }
		if done != nil { close(done) }
	})()

	if res != nil {
		hdlr = make(imap.RespHandler)
		done = make(chan error)

		go (func() {
			err := res.HandleFrom(hdlr)
			done <- err
		})()
	}

	for h := range statusHdlr {
		if s, ok := h.Resp.(*imap.StatusResp); ok && s.Tag == cmd.Tag {
			h.Accept()
			status = s
			if hdlr != nil {
				close(hdlr)
				hdlr = nil
			}
			break
		} else if hdlr != nil {
			hdlr <- h
		} else {
			h.Reject()
		}
	}

	if done != nil {
		err = <-done
	}
	return
}

func (c *Client) handleContinuationReqs(continues chan bool) {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	defer close(continues)

	for h := range hdlr {
		if _, ok := h.Resp.(*imap.ContinuationResp); ok {
			h.Accept()
			continues <- true
		} else {
			h.Reject()
		}
	}
}

func (c *Client) gotStatusCaps(args []interface{}) {
	c.Caps = map[string]bool{}
	for _, cap := range args {
		c.Caps[cap.(string)] = true
	}
}

func (c *Client) handleGreeting() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || (status.Type != imap.OK && status.Type != imap.PREAUTH && status.Type != imap.BYE) {
			h.Reject()
			continue
		}

		h.Accept()

		if status.Code == "CAPABILITY" {
			c.gotStatusCaps(status.Arguments)
		}

		if status.Type == imap.PREAUTH {
			c.State = imap.AuthenticatedState
		}
		if status.Type == imap.BYE {
			c.State = imap.LogoutState
		}

		go c.handleBye()

		return status
	}

	return nil
}

func (c *Client) handleBye() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || status.Type != imap.BYE {
			h.Reject()
			continue
		}

		h.Accept()

		c.State = imap.LogoutState
		c.Selected = nil
		c.conn.Close()

		return status
	}

	return nil
}

func (c *Client) handleCaps() (err error) {
	res := &responses.Capability{}

	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for {
		err = res.HandleFrom(hdlr)
		if err != nil {
			return
		}

		c.Caps = map[string]bool{}
		for _, name := range res.Caps {
			c.Caps[name] = true
		}
	}

	return nil
}

// Create a new client from an existing connection.
func NewClient(conn net.Conn) (c *Client, err error) {
	c = &Client{
		conn: conn,
		State: imap.NotAuthenticatedState,
	}

	continues := make(chan bool)
	c.writer = imap.NewClientWriter(c.conn, continues)

	go c.read()
	go c.handleContinuationReqs(continues)
	go c.handleCaps()

	greeting := c.handleGreeting()
	greeting.Err()
	return
}

// Connect to an IMAP server using an unencrypted connection.
func Dial(addr string) (c *Client, err error) {
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}

// Connect to an IMAP server using an encrypted connection.
func DialTLS(addr string, tlsConfig *tls.Config) (c *Client, err error) {
	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}
<commit_msg>Fixes send on close channel in client<commit_after>// An IMAP client.
package client

import (
	"bufio"
	"crypto/tls"
	"io"
	"log"
	"net"

	imap "github.com/emersion/imap/common"
	"github.com/emersion/imap/responses"
)

// An IMAP client.
type Client struct {
	conn net.Conn
	writer *imap.Writer
	handlers []imap.RespHandler

	// The server capabilities.
	Caps map[string]bool
	// The current connection state.
	State imap.ConnState
	// The selected mailbox, if there is one.
	Selected *imap.MailboxStatus
}

func (c *Client) read() error {
	r := imap.NewReader(bufio.NewReader(c.conn))

	defer (func () {
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			c.removeHandler(hdlr)
		}
	})()

	for {
		if c.State == imap.LogoutState {
			return nil
		}

		res, err := imap.ReadResp(r)
		if err == io.EOF {
			return nil
		}
		if err != nil {
			log.Println("Error reading response:", err)
			continue
		}

		var accepted bool
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			h := &imap.RespHandling{
				Resp: res,
				Accepts: make(chan bool),
			}

			hdlr <- h

			accepted = <-h.Accepts
			if accepted {
				break
			}
		}

		if !accepted {
			log.Println("Response has not been handled", res)
		}
	}

	return nil
}

func (c *Client) addHandler(hdlr imap.RespHandler) {
	// TODO: needs locker
	c.handlers = append(c.handlers, hdlr)
}

func (c *Client) removeHandler(hdlr imap.RespHandler) {
	// TODO: really remove handler from array? (needs locker)
	for i, h := range c.handlers {
		if h == hdlr {
			c.handlers[i] = nil
			close(hdlr)
		}
	}
}

func (c *Client) execute(cmdr imap.Commander, res imap.RespHandlerFrom) (status *imap.StatusResp, err error) {
	cmd := cmdr.Command()
	cmd.Tag = generateTag()

	_, err = cmd.WriteTo(c.writer)
	if err != nil {
		return
	}

	statusHdlr := make(imap.RespHandler)
	c.addHandler(statusHdlr)
	defer c.removeHandler(statusHdlr)

	var hdlr imap.RespHandler
	var done chan error
	defer (func () {
		if hdlr != nil { close(hdlr) }
		if done != nil { close(done) }
	})()

	if res != nil {
		hdlr = make(imap.RespHandler)
		done = make(chan error)

		go (func() {
			err := res.HandleFrom(hdlr)
			done <- err
		})()
	}

	for h := range statusHdlr {
		if s, ok := h.Resp.(*imap.StatusResp); ok && s.Tag == cmd.Tag {
			h.Accept()
			status = s
			if hdlr != nil {
				close(hdlr)
				hdlr = nil
			}
			break
		} else if hdlr != nil {
			hdlr <- h
		} else {
			h.Reject()
		}
	}

	if done != nil {
		err = <-done
	}
	return
}

func (c *Client) handleContinuationReqs(continues chan bool) {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	defer close(continues)

	for h := range hdlr {
		if _, ok := h.Resp.(*imap.ContinuationResp); ok {
			h.Accept()
			continues <- true
		} else {
			h.Reject()
		}
	}
}

func (c *Client) gotStatusCaps(args []interface{}) {
	c.Caps = map[string]bool{}
	for _, cap := range args {
		c.Caps[cap.(string)] = true
	}
}

func (c *Client) handleGreeting() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || (status.Type != imap.OK && status.Type != imap.PREAUTH && status.Type != imap.BYE) {
			h.Reject()
			continue
		}

		h.Accept()

		if status.Code == "CAPABILITY" {
			c.gotStatusCaps(status.Arguments)
		}

		if status.Type == imap.PREAUTH {
			c.State = imap.AuthenticatedState
		}
		if status.Type == imap.BYE {
			c.State = imap.LogoutState
		}

		go c.handleBye()

		return status
	}

	return nil
}

func (c *Client) handleBye() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || status.Type != imap.BYE {
			h.Reject()
			continue
		}

		h.Accept()

		c.State = imap.LogoutState
		c.Selected = nil
		c.conn.Close()

		return status
	}

	return nil
}

func (c *Client) handleCaps() (err error) {
	res := &responses.Capability{}

	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for {
		err = res.HandleFrom(hdlr)
		if err != nil {
			return
		}

		c.Caps = map[string]bool{}
		for _, name := range res.Caps {
			c.Caps[name] = true
		}
	}

	return nil
}

// Create a new client from an existing connection.
func NewClient(conn net.Conn) (c *Client, err error) {
	c = &Client{
		conn: conn,
		State: imap.NotAuthenticatedState,
	}

	continues := make(chan bool)
	c.writer = imap.NewClientWriter(c.conn, continues)

	go c.read()
	go c.handleContinuationReqs(continues)
	go c.handleCaps()

	greeting := c.handleGreeting()
	greeting.Err()
	return
}

// Connect to an IMAP server using an unencrypted connection.
func Dial(addr string) (c *Client, err error) {
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}

// Connect to an IMAP server using an encrypted connection.
func DialTLS(addr string, tlsConfig *tls.Config) (c *Client, err error) {
	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}
<|endoftext|>


<commit_before>// deepcopy deep copies maps, slices, etc. A standard copy will copy the
// pointers: deep copy copies the values pointed to.
package deepcopy

import (
	"reflect"
)

// InterfaceToSliceString takes an interface that is a slice of strings
// and returns a deep copy of it as a slice of strings. An error is returned if
// the interface is not a slice of strings
func InterfaceToSliceString(v interface{}) []string {
	if v == nil {
		return nil
	}
	var sl []string

	switch reflect.TypeOf(v).Kind() {
	case reflect.Slice:
		s := reflect.ValueOf(v)
		sLen := s.Len()

		for i := 0; i < sLen; i++ {
			sl = append(sl, s.Index(i).Interface().(string))
		}

	default:
		return nil
	}
	return sl
}

// MapStringInterface makes a deep copy of a map[string]interface{} and
// returns the copy of the map[string]interface{}
//
// notes: This assumes that the interface{} is a []string. Adjust as needed.
func MapStringInterface(m map[string]interface{}) map[string]interface{} {
	c := map[string]interface{}{}
	var tmp  []string
	for k, v := range m {
		switch reflect.TypeOf(v).Kind() {
		case reflect.Slice:
			tmp = deepCopyInterfaceToSliceString(v)
		}
		c[k] = tmp
	}

	return c
}

<commit_msg>updated function call to match new definition<commit_after>// deepcopy deep copies maps, slices, etc. A standard copy will copy the
// pointers: deep copy copies the values pointed to.
package deepcopy

import (
	"reflect"
)

// InterfaceToSliceString takes an interface that is a slice of strings
// and returns a deep copy of it as a slice of strings. An error is returned if
// the interface is not a slice of strings
func InterfaceToSliceString(v interface{}) []string {
	if v == nil {
		return nil
	}
	var sl []string

	switch reflect.TypeOf(v).Kind() {
	case reflect.Slice:
		s := reflect.ValueOf(v)
		sLen := s.Len()

		for i := 0; i < sLen; i++ {
			sl = append(sl, s.Index(i).Interface().(string))
		}

	default:
		return nil
	}
	return sl
}

// MapStringInterface makes a deep copy of a map[string]interface{} and
// returns the copy of the map[string]interface{}
//
// notes: This assumes that the interface{} is a []string. Adjust as needed.
func MapStringInterface(m map[string]interface{}) map[string]interface{} {
	c := map[string]interface{}{}
	var tmp  []string
	for k, v := range m {
		switch reflect.TypeOf(v).Kind() {
		case reflect.Slice:
			tmp = InterfaceToSliceString(v)
		}
		c[k] = tmp
	}

	return c
}

<|endoftext|>


<commit_before>//Docket Client
//Author: Sivamani Varun
//Gopher Gala
package main

//push
//pull
//-h[ost]
//-p[ort]

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/alecthomas/kingpin"
	"github.com/fsouza/go-dockerclient"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

var (
	host = kingpin.Flag("host", "Set host of docket registry.").Short('h').Default("http://127.0.0.1").String()
	port = kingpin.Flag("port", "Set port of docket registry.").Short('p').Default("8000").String()

	push      = kingpin.Command("push", "Push to the docket registry.")
	pushImage = push.Arg("push", "Image to push.").Required().String()

	pull      = kingpin.Command("pull", "pull to the docket registry.")
	pullImage = pull.Arg("pull", "Image to pull.").Required().String()
)

// Creates a new tarball upload http request to the Docket registry
func uploadFile(params map[string]string, paramName, path string) (*http.Request, error) {
	uri := *host + ":" + *port + "/images"
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(paramName, filepath.Base(path))
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(part, file)

	err = writer.Close()
	if err != nil {
		return nil, err
	}

	request, err := http.NewRequest("POST", uri, body)
	if err != nil {
		return nil, err
	}
	request.Header.Add("Content-Type", writer.FormDataContentType())
	for key, val := range params {
		fmt.Println("key = ", key, " val = ", val)
		request.Header.Add(key, val)
	}
	return request, nil
}

func applyPush(image string) error {
	reg, err := regexp.Compile("[^A-Za-z0-9]+")
	if err != nil {
		return err
	}

	endpoint := "unix:///var/run/docker.sock"
	client, _ := docker.NewClient(endpoint)
	imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})

	found := false
	imageId := ""
	filePath := ""
	created := ""

	for _, img := range imgs {
		tags := img.RepoTags
		for _, tag := range tags {
			if tag == image {
				found = true
				imageId = img.ID
				created = strconv.FormatInt(img.Created, 10)
				fmt.Println("Found image: ", image)
				fmt.Println("ID: ", img.ID)
				fmt.Println("RepoTags: ", img.RepoTags)
				fmt.Println("Created: ", img.Created)
				fmt.Println("Size: ", img.Size)
				fmt.Println("VirtualSize: ", img.VirtualSize)
				fmt.Println("ParentId: ", img.ParentID)
				safeImageName := reg.ReplaceAllString(image, "_")
				s := []string{"/tmp/", imageId, "_", safeImageName, ".tar"}
				filePath = strings.Join(s, "")
				break
			}
		}
	}
	if !found {
		return errors.New("Sorry the image could not be found.")
	}

	//Run export command
	//command invocation
	//run docker command save to tar ball in /tmp
	fmt.Println("Exporting image to tarball...")
	cmd := fmt.Sprintf("docker save %s > %s", image, filePath)
	_, err1 := exec.Command("sh", "-c", cmd).Output()
	if err1 != nil {
		return err1
	}

	fmt.Println("Successively exported tarball...")
	//make post request with contents of tarball to docket registry

	imageParams := map[string]string{
		"image":   image,
		"id":      imageId,
		"created": created,
	}

	//Adapted from http://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/ (C) Matt Aimonetti
	request, err := uploadFile(imageParams, "file", filePath)
	if err != nil {
		log.Fatal(err)
	}
	uploadClient := &http.Client{}
	resp, err := uploadClient.Do(request)
	if err != nil {
		log.Fatal(err)
	} else {
		body := &bytes.Buffer{}
		_, err := body.ReadFrom(resp.Body)
		if err != nil {
			log.Fatal(err)
		}
		resp.Body.Close()
		if resp.StatusCode != 200 {
			return errors.New("Failed to push image...")
		}
	}
	fmt.Println("Successfully uploaded image: ", image, " to the Docket registry.")
	return nil
}

//Adapted from https://github.com/thbar/golang-playground/blob/master/download-files.go
func downloadFromUrl(url string, fileName string) (err error) {
	output, err := os.Create(fileName)
	if err != nil {
		fmt.Println("Error while creating", fileName, "-", err)
		return err
	}
	defer output.Close()

	response, err := http.Get(url)
	if err != nil {
		fmt.Println("Error while downloading", url, "-", err)
		return err
	}
	defer response.Body.Close()

	n, err := io.Copy(output, response.Body)
	if err != nil {
		fmt.Println("Error while downloading", url, "-", err)
		return err
	}

	fmt.Println(n, "bytes downloaded.")
	return nil
}

func applyPull(image string) error {
	reg, err := regexp.Compile("[^A-Za-z0-9]+")
	if err != nil {
		return err
	}
	safeImageName := reg.ReplaceAllString(image, "_")
	filePath := "/tmp/docket/"
	fileName := filePath + safeImageName + ".torrent"

	//Download torrent file
	queryParam := map[string]string{
		"image": image,
	}
	queryParamJson, _ := json.Marshal(queryParam)

	fmt.Println("Downloading the torrent file for image: ", image)

	url := *host + ":" + *port + "/torrents?q=" + url.QueryEscape(string(queryParamJson))
	err1 := downloadFromUrl(url, fileName)
	if err1 != nil {
		return err
	}

	fmt.Println("Downloading from the torrent file...")
	ctorrentCmd := fmt.Sprintf("cd %s && ctorrent -e 0 %s", filePath, fileName)
	cmd := exec.Command("bash", "-c", ctorrentCmd)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()

	tarballPath := filePath + "353b94eb357ddb343ebe054ccc80b49bb6d0828522e9f2eff313406363449d17_netvarun_test_latest.tar"

	//Load the downloaded tarball
	fmt.Println("Exporting image to tarball...")
	importCmd := fmt.Sprintf("docker load -i %s", tarballPath)
	_, err2 := exec.Command("sh", "-c", importCmd).Output()
	if err2 != nil {
		fmt.Printf("Failed to load image into docker!")
		return err2
	}
	fmt.Printf("Successfively pulled image: ", image)
	return nil
}

func main() {
	kingpin.CommandLine.Help = "Docket Client"

	switch kingpin.Parse() {
	case "push":
		kingpin.FatalIfError(applyPush(*pushImage), "Pushing of image failed")
	case "pull":
		kingpin.FatalIfError(applyPull((*pullImage)), "Pushing of image failed")
	}
}
<commit_msg>pulls image metadata<commit_after>//Docket Client
//Author: Sivamani Varun
//Gopher Gala
package main

//push
//pull
//-h[ost]
//-p[ort]

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/alecthomas/kingpin"
	"github.com/fsouza/go-dockerclient"
	"io"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

var (
	host = kingpin.Flag("host", "Set host of docket registry.").Short('h').Default("http://127.0.0.1").String()
	port = kingpin.Flag("port", "Set port of docket registry.").Short('p').Default("8000").String()

	push      = kingpin.Command("push", "Push to the docket registry.")
	pushImage = push.Arg("push", "Image to push.").Required().String()

	pull      = kingpin.Command("pull", "pull to the docket registry.")
	pullImage = pull.Arg("pull", "Image to pull.").Required().String()
)

// Creates a new tarball upload http request to the Docket registry
func uploadFile(params map[string]string, paramName, path string) (*http.Request, error) {
	uri := *host + ":" + *port + "/images"
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(paramName, filepath.Base(path))
	if err != nil {
		return nil, err
	}
	_, err = io.Copy(part, file)

	err = writer.Close()
	if err != nil {
		return nil, err
	}

	request, err := http.NewRequest("POST", uri, body)
	if err != nil {
		return nil, err
	}
	request.Header.Add("Content-Type", writer.FormDataContentType())
	for key, val := range params {
		fmt.Println("key = ", key, " val = ", val)
		request.Header.Add(key, val)
	}
	return request, nil
}

func applyPush(image string) error {
	reg, err := regexp.Compile("[^A-Za-z0-9]+")
	if err != nil {
		return err
	}

	endpoint := "unix:///var/run/docker.sock"
	client, _ := docker.NewClient(endpoint)
	imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})

	found := false
	imageId := ""
	filePath := ""
	created := ""

	for _, img := range imgs {
		tags := img.RepoTags
		for _, tag := range tags {
			if tag == image {
				found = true
				imageId = img.ID
				created = strconv.FormatInt(img.Created, 10)
				fmt.Println("Found image: ", image)
				fmt.Println("ID: ", img.ID)
				fmt.Println("RepoTags: ", img.RepoTags)
				fmt.Println("Created: ", img.Created)
				fmt.Println("Size: ", img.Size)
				fmt.Println("VirtualSize: ", img.VirtualSize)
				fmt.Println("ParentId: ", img.ParentID)
				safeImageName := reg.ReplaceAllString(image, "_")
				s := []string{"/tmp/", imageId, "_", safeImageName, ".tar"}
				filePath = strings.Join(s, "")
				break
			}
		}
	}
	if !found {
		return errors.New("Sorry the image could not be found.")
	}

	//Run export command
	//command invocation
	//run docker command save to tar ball in /tmp
	fmt.Println("Exporting image to tarball...")
	cmd := fmt.Sprintf("docker save %s > %s", image, filePath)
	_, err1 := exec.Command("sh", "-c", cmd).Output()
	if err1 != nil {
		return err1
	}

	fmt.Println("Successively exported tarball...")
	//make post request with contents of tarball to docket registry

	imageParams := map[string]string{
		"image":   image,
		"id":      imageId,
		"created": created,
	}

	//Adapted from http://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/ (C) Matt Aimonetti
	request, err := uploadFile(imageParams, "file", filePath)
	if err != nil {
		log.Fatal(err)
	}
	uploadClient := &http.Client{}
	resp, err := uploadClient.Do(request)
	if err != nil {
		log.Fatal(err)
	} else {
		body := &bytes.Buffer{}
		_, err := body.ReadFrom(resp.Body)
		if err != nil {
			log.Fatal(err)
		}
		resp.Body.Close()
		if resp.StatusCode != 200 {
			return errors.New("Failed to push image...")
		}
	}
	fmt.Println("Successfully uploaded image: ", image, " to the Docket registry.")
	return nil
}

//Adapted from https://github.com/thbar/golang-playground/blob/master/download-files.go
func downloadFromUrl(url string, fileName string) (err error) {
	output, err := os.Create(fileName)
	if err != nil {
		fmt.Println("Error while creating", fileName, "-", err)
		return err
	}
	defer output.Close()

	response, err := http.Get(url)
	if err != nil {
		fmt.Println("Error while downloading", url, "-", err)
		return err
	}
	if response.StatusCode != 200 {
		fmt.Println("Failed to pull image")
		return errors.New("Failed to pull image...")
	}
	defer response.Body.Close()

	n, err := io.Copy(output, response.Body)
	if err != nil {
		fmt.Println("Error while downloading", url, "-", err)
		return err
	}

	//fmt.Println(n, "bytes downloaded.")
	//Hack: trivial check to ensure if file downloaded is too small
	if n < 100 {
		return errors.New("Failed to pull image...")
	}
	return nil
}

func applyPull(image string) error {
	reg, err := regexp.Compile("[^A-Za-z0-9]+")
	if err != nil {
		return err
	}
	safeImageName := reg.ReplaceAllString(image, "_")
	filePath := "/tmp/docket/"
	fileName := filePath + safeImageName + ".torrent"

	//Download torrent file
	queryParam := map[string]string{
		"image": image,
	}
	queryParamJson, _ := json.Marshal(queryParam)

	metaUrl := *host + ":" + *port + "/images?q=" + url.QueryEscape(string(queryParamJson))
	//TODO:Get metadata GET /images?q={"image":}
	response, err3 := http.Get(metaUrl)
	if err3 != nil {
		fmt.Println("Failed to query image metadata endpoint")
		return err3
	}
	if response.StatusCode != 200 {
		fmt.Println("Failed to get image metadata")
		return errors.New("Failed to get images metadata...")
	}
	defer response.Body.Close()
	metaJson, err4 := ioutil.ReadAll(response.Body)
	if err4 != nil {
		fmt.Println("Failed to get image metadata json")
		return errors.New("Failed to get image metadata json")
	}

	var queryObj map[string]interface{}
	if err := json.Unmarshal([]byte(metaJson), &queryObj); err != nil {
		return errors.New("Failed to decode images metadata json...")
	}

	tarballNameInterface := queryObj["fileName"]
	tarballName := tarballNameInterface.(string)

	fmt.Println("Downloading the torrent file for image: ", image)

	url := *host + ":" + *port + "/torrents?q=" + url.QueryEscape(string(queryParamJson))
	err1 := downloadFromUrl(url, fileName)
	if err1 != nil {
		fmt.Println("Failed to pull image")
		return err
	}

	fmt.Println("Downloading from the torrent file...")
	ctorrentCmd := fmt.Sprintf("cd %s && ctorrent -e 0 %s", filePath, fileName)
	cmd := exec.Command("bash", "-c", ctorrentCmd)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()

	//TODO:Replace filename with that from metadata
	tarballPath := filePath + tarballName
	fmt.Println("Tarball path = ", tarballPath)

	//Load the downloaded tarball
	fmt.Println("Exporting image to tarball...")
	importCmd := fmt.Sprintf("docker load -i %s", tarballPath)
	_, err2 := exec.Command("sh", "-c", importCmd).Output()
	if err2 != nil {
		fmt.Printf("Failed to load image into docker!")
		return err2
	}
	fmt.Printf("Successfively pulled image: ", image)
	return nil
}

func main() {
	kingpin.CommandLine.Help = "Docket Client"

	switch kingpin.Parse() {
	case "push":
		kingpin.FatalIfError(applyPush(*pushImage), "Pushing of image failed")
	case "pull":
		kingpin.FatalIfError(applyPull((*pullImage)), "Pushing of image failed")
	}
}
<|endoftext|>


<commit_before>// An IMAP client.
package client

import (
	"bufio"
	"crypto/tls"
	"io"
	"log"
	"net"
	"sync"

	imap "github.com/emersion/imap/common"
	"github.com/emersion/imap/responses"
)

// An IMAP client.
type Client struct {
	conn net.Conn
	writer *imap.Writer

	handlersLock sync.Locker
	handlers []imap.RespHandler

	// The server capabilities.
	Caps map[string]bool
	// The current connection state.
	State imap.ConnState
	// The selected mailbox, if there is one.
	Selected *imap.MailboxStatus
}

func (c *Client) read() error {
	r := imap.NewReader(bufio.NewReader(c.conn))

	defer (func () {
		c.handlersLock.Lock()
		defer c.handlersLock.Unlock()

		for _, hdlr := range c.handlers {
			close(hdlr)
		}
		c.handlers = nil
	})()

	for {
		if c.State == imap.LogoutState {
			return nil
		}

		res, err := imap.ReadResp(r)
		if err == io.EOF {
			return nil
		}
		if err != nil {
			log.Println("Error reading response:", err)
			continue
		}

		c.handlersLock.Lock()

		var accepted bool
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			h := &imap.RespHandling{
				Resp: res,
				Accepts: make(chan bool),
			}

			hdlr <- h

			accepted = <-h.Accepts
			if accepted {
				break
			}
		}

		c.handlersLock.Unlock()

		if !accepted {
			log.Println("Response has not been handled", res)
		}
	}

	return nil
}

func (c *Client) addHandler(hdlr imap.RespHandler) {
	c.handlersLock.Lock()
	defer c.handlersLock.Unlock()

	c.handlers = append(c.handlers, hdlr)
}

func (c *Client) removeHandler(hdlr imap.RespHandler) {
	c.handlersLock.Lock()
	defer c.handlersLock.Unlock()

	for i, h := range c.handlers {
		if h == hdlr {
			close(hdlr)
			c.handlers = append(c.handlers[:i], c.handlers[i+1:]...)
		}
	}
}

func (c *Client) execute(cmdr imap.Commander, res imap.RespHandlerFrom) (status *imap.StatusResp, err error) {
	cmd := cmdr.Command()
	cmd.Tag = generateTag()

	_, err = cmd.WriteTo(c.writer)
	if err != nil {
		return
	}

	statusHdlr := make(imap.RespHandler)
	c.addHandler(statusHdlr)
	defer c.removeHandler(statusHdlr)

	var hdlr imap.RespHandler
	var done chan error
	defer (func () {
		if hdlr != nil { close(hdlr) }
		if done != nil { close(done) }
	})()

	if res != nil {
		hdlr = make(imap.RespHandler)
		done = make(chan error)

		go (func() {
			err := res.HandleFrom(hdlr)
			done <- err
		})()
	}

	for h := range statusHdlr {
		if s, ok := h.Resp.(*imap.StatusResp); ok && s.Tag == cmd.Tag {
			h.Accept()
			status = s
			if hdlr != nil {
				close(hdlr)
				hdlr = nil
			}
			break
		} else if hdlr != nil {
			hdlr <- h
		} else {
			h.Reject()
		}
	}

	if done != nil {
		err = <-done
	}
	return
}

func (c *Client) handleContinuationReqs(continues chan bool) {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	defer close(continues)

	for h := range hdlr {
		if _, ok := h.Resp.(*imap.ContinuationResp); ok {
			h.Accept()
			continues <- true
		} else {
			h.Reject()
		}
	}
}

func (c *Client) gotStatusCaps(args []interface{}) {
	c.Caps = map[string]bool{}
	for _, cap := range args {
		c.Caps[cap.(string)] = true
	}
}

func (c *Client) handleGreeting() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	// Make sure to start reading after we have set up the base handlers,
	// otherwise some messages will be lost.
	go c.read()

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || (status.Type != imap.OK && status.Type != imap.PREAUTH && status.Type != imap.BYE) {
			h.Reject()
			continue
		}

		h.Accept()

		if status.Code == "CAPABILITY" {
			c.gotStatusCaps(status.Arguments)
		}

		if status.Type == imap.PREAUTH {
			c.State = imap.AuthenticatedState
		}
		if status.Type == imap.BYE {
			c.State = imap.LogoutState
		}

		go c.handleBye()

		return status
	}

	return nil
}

func (c *Client) handleBye() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || status.Type != imap.BYE {
			h.Reject()
			continue
		}

		h.Accept()

		c.State = imap.LogoutState
		c.Selected = nil
		c.conn.Close()

		return status
	}

	return nil
}

func (c *Client) handleCaps() (err error) {
	res := &responses.Capability{}

	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for {
		err = res.HandleFrom(hdlr)
		if err != nil {
			return
		}

		c.Caps = map[string]bool{}
		for _, name := range res.Caps {
			c.Caps[name] = true
		}
	}

	return nil
}

// Create a new client from an existing connection.
func NewClient(conn net.Conn) (c *Client, err error) {
	c = &Client{
		conn: conn,
		handlersLock: &sync.Mutex{},
		State: imap.NotAuthenticatedState,
	}

	continues := make(chan bool)
	c.writer = imap.NewClientWriter(c.conn, continues)

	go c.handleContinuationReqs(continues)
	go c.handleCaps()

	greeting := c.handleGreeting()
	greeting.Err()
	return
}

// Connect to an IMAP server using an unencrypted connection.
func Dial(addr string) (c *Client, err error) {
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}

// Connect to an IMAP server using an encrypted connection.
func DialTLS(addr string, tlsConfig *tls.Config) (c *Client, err error) {
	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}
<commit_msg>Renames a variable<commit_after>// An IMAP client.
package client

import (
	"bufio"
	"crypto/tls"
	"io"
	"log"
	"net"
	"sync"

	imap "github.com/emersion/imap/common"
	"github.com/emersion/imap/responses"
)

// An IMAP client.
type Client struct {
	conn net.Conn
	writer *imap.Writer

	handlers []imap.RespHandler
	handlersLocker sync.Locker

	// The server capabilities.
	Caps map[string]bool
	// The current connection state.
	State imap.ConnState
	// The selected mailbox, if there is one.
	Selected *imap.MailboxStatus
}

func (c *Client) read() error {
	r := imap.NewReader(bufio.NewReader(c.conn))

	defer (func () {
		c.handlersLocker.Lock()
		defer c.handlersLocker.Unlock()

		for _, hdlr := range c.handlers {
			close(hdlr)
		}
		c.handlers = nil
	})()

	for {
		if c.State == imap.LogoutState {
			return nil
		}

		res, err := imap.ReadResp(r)
		if err == io.EOF {
			return nil
		}
		if err != nil {
			log.Println("Error reading response:", err)
			continue
		}

		c.handlersLocker.Lock()

		var accepted bool
		for _, hdlr := range c.handlers {
			if hdlr == nil {
				continue
			}

			h := &imap.RespHandling{
				Resp: res,
				Accepts: make(chan bool),
			}

			hdlr <- h

			accepted = <-h.Accepts
			if accepted {
				break
			}
		}

		c.handlersLocker.Unlock()

		if !accepted {
			log.Println("Response has not been handled", res)
		}
	}

	return nil
}

func (c *Client) addHandler(hdlr imap.RespHandler) {
	c.handlersLocker.Lock()
	defer c.handlersLocker.Unlock()

	c.handlers = append(c.handlers, hdlr)
}

func (c *Client) removeHandler(hdlr imap.RespHandler) {
	c.handlersLocker.Lock()
	defer c.handlersLocker.Unlock()

	for i, h := range c.handlers {
		if h == hdlr {
			close(hdlr)
			c.handlers = append(c.handlers[:i], c.handlers[i+1:]...)
		}
	}
}

func (c *Client) execute(cmdr imap.Commander, res imap.RespHandlerFrom) (status *imap.StatusResp, err error) {
	cmd := cmdr.Command()
	cmd.Tag = generateTag()

	_, err = cmd.WriteTo(c.writer)
	if err != nil {
		return
	}

	statusHdlr := make(imap.RespHandler)
	c.addHandler(statusHdlr)
	defer c.removeHandler(statusHdlr)

	var hdlr imap.RespHandler
	var done chan error
	defer (func () {
		if hdlr != nil { close(hdlr) }
		if done != nil { close(done) }
	})()

	if res != nil {
		hdlr = make(imap.RespHandler)
		done = make(chan error)

		go (func() {
			err := res.HandleFrom(hdlr)
			done <- err
		})()
	}

	for h := range statusHdlr {
		if s, ok := h.Resp.(*imap.StatusResp); ok && s.Tag == cmd.Tag {
			h.Accept()
			status = s
			if hdlr != nil {
				close(hdlr)
				hdlr = nil
			}
			break
		} else if hdlr != nil {
			hdlr <- h
		} else {
			h.Reject()
		}
	}

	if done != nil {
		err = <-done
	}
	return
}

func (c *Client) handleContinuationReqs(continues chan bool) {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	defer close(continues)

	for h := range hdlr {
		if _, ok := h.Resp.(*imap.ContinuationResp); ok {
			h.Accept()
			continues <- true
		} else {
			h.Reject()
		}
	}
}

func (c *Client) gotStatusCaps(args []interface{}) {
	c.Caps = map[string]bool{}
	for _, cap := range args {
		c.Caps[cap.(string)] = true
	}
}

func (c *Client) handleGreeting() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	// Make sure to start reading after we have set up the base handlers,
	// otherwise some messages will be lost.
	go c.read()

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || (status.Type != imap.OK && status.Type != imap.PREAUTH && status.Type != imap.BYE) {
			h.Reject()
			continue
		}

		h.Accept()

		if status.Code == "CAPABILITY" {
			c.gotStatusCaps(status.Arguments)
		}

		if status.Type == imap.PREAUTH {
			c.State = imap.AuthenticatedState
		}
		if status.Type == imap.BYE {
			c.State = imap.LogoutState
		}

		go c.handleBye()

		return status
	}

	return nil
}

func (c *Client) handleBye() *imap.StatusResp {
	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for h := range hdlr {
		status, ok := h.Resp.(*imap.StatusResp)
		if !ok || status.Tag != "*" || status.Type != imap.BYE {
			h.Reject()
			continue
		}

		h.Accept()

		c.State = imap.LogoutState
		c.Selected = nil
		c.conn.Close()

		return status
	}

	return nil
}

func (c *Client) handleCaps() (err error) {
	res := &responses.Capability{}

	hdlr := make(imap.RespHandler)
	c.addHandler(hdlr)
	defer c.removeHandler(hdlr)

	for {
		err = res.HandleFrom(hdlr)
		if err != nil {
			return
		}

		c.Caps = map[string]bool{}
		for _, name := range res.Caps {
			c.Caps[name] = true
		}
	}

	return nil
}

// Create a new client from an existing connection.
func NewClient(conn net.Conn) (c *Client, err error) {
	c = &Client{
		conn: conn,
		handlersLocker: &sync.Mutex{},
		State: imap.NotAuthenticatedState,
	}

	continues := make(chan bool)
	c.writer = imap.NewClientWriter(c.conn, continues)

	go c.handleContinuationReqs(continues)
	go c.handleCaps()

	greeting := c.handleGreeting()
	greeting.Err()
	return
}

// Connect to an IMAP server using an unencrypted connection.
func Dial(addr string) (c *Client, err error) {
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}

// Connect to an IMAP server using an encrypted connection.
func DialTLS(addr string, tlsConfig *tls.Config) (c *Client, err error) {
	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		return
	}

	c, err = NewClient(conn)
	return
}
<|endoftext|>


<commit_before>package config

import (
	"gopkg.in/redis.v5"
	"github.com/gempir/gempbotgo/modules"
)

type UserConfig struct {
	rClient    redis.Client
}

func NewUserConfig(rClient redis.Client) UserConfig {
	return UserConfig{
		rClient:    rClient,
	}
}

func (uCfg *UserConfig) IsEnabled(channel, key string) bool {
	if key == modules.STATUS {
		return true
	}

	res, err := uCfg.rClient.HGet(channel, key).Result()

	if err != nil {
		return false
	}
	if res == "true" || res == "1" {
		return true
	}
	return false
}

<commit_msg>fixed redis path to config<commit_after>package config

import (
	"gopkg.in/redis.v5"
	"github.com/gempir/gempbotgo/modules"
)

type UserConfig struct {
	rClient    redis.Client
}

func NewUserConfig(rClient redis.Client) UserConfig {
	return UserConfig{
		rClient:    rClient,
	}
}

func (uCfg *UserConfig) IsEnabled(channel, key string) bool {
	if key == modules.STATUS {
		return true
	}

	res, err := uCfg.rClient.HGet(channel + ":config", key).Result()

	if err != nil {
		return false
	}
	if res == "true" || res == "1" {
		return true
	}
	return false
}

<|endoftext|>


<commit_before>package udp

import (
	"crypto/hmac"
	"encoding/binary"
	"net"
	"time"

	sha256 "github.com/minio/sha256-simd"
)

// ttl is the number of seconds a connection ID should be valid according to
// BEP 15.
const ttl = 2 * time.Minute

// NewConnectionID creates a new 8 byte connection identifier for UDP packets
// as described by BEP 15.
//
// The first 4 bytes of the connection identifier is a unix timestamp and the
// last 4 bytes are a truncated HMAC token created from the aforementioned
// unix timestamp and the source IP address of the UDP packet.
//
// Truncated HMAC is known to be safe for 2^(-n) where n is the size in bits
// of the truncated HMAC token. In this use case we have 32 bits, thus a
// forgery probability of approximately 1 in 4 billion.
func NewConnectionID(ip net.IP, now time.Time, key string) []byte {
	buf := make([]byte, 8)
	binary.BigEndian.PutUint32(buf, uint32(now.Unix()))

	mac := hmac.New(sha256.New, []byte(key))
	mac.Write(buf[:4])
	mac.Write(ip)
	macBytes := mac.Sum(nil)[:4]
	copy(buf[4:], macBytes)

	return buf
}

// ValidConnectionID determines whether a connection identifier is legitimate.
func ValidConnectionID(connectionID []byte, ip net.IP, now time.Time, maxClockSkew time.Duration, key string) bool {
	ts := time.Unix(int64(binary.BigEndian.Uint32(connectionID[:4])), 0)
	if now.After(ts.Add(ttl)) || ts.After(now.Add(maxClockSkew)) {
		return false
	}

	mac := hmac.New(sha256.New, []byte(key))
	mac.Write(connectionID[:4])
	mac.Write(ip)
	expectedMAC := mac.Sum(nil)[:4]
	return hmac.Equal(expectedMAC, connectionID[4:])
}
<commit_msg>frontend/udp: debug log connection ID generation/validation<commit_after>package udp

import (
	"crypto/hmac"
	"encoding/binary"
	"net"
	"time"

	"github.com/minio/sha256-simd"

	"github.com/chihaya/chihaya/pkg/log"
)

// ttl is the number of seconds a connection ID should be valid according to
// BEP 15.
const ttl = 2 * time.Minute

// NewConnectionID creates a new 8 byte connection identifier for UDP packets
// as described by BEP 15.
//
// The first 4 bytes of the connection identifier is a unix timestamp and the
// last 4 bytes are a truncated HMAC token created from the aforementioned
// unix timestamp and the source IP address of the UDP packet.
//
// Truncated HMAC is known to be safe for 2^(-n) where n is the size in bits
// of the truncated HMAC token. In this use case we have 32 bits, thus a
// forgery probability of approximately 1 in 4 billion.
func NewConnectionID(ip net.IP, now time.Time, key string) []byte {
	buf := make([]byte, 8)
	binary.BigEndian.PutUint32(buf, uint32(now.Unix()))

	mac := hmac.New(sha256.New, []byte(key))
	mac.Write(buf[:4])
	mac.Write(ip)
	macBytes := mac.Sum(nil)[:4]
	copy(buf[4:], macBytes)

	log.Debug("generated connection ID", log.Fields{"ip": ip, "now": now, "key": key, "connID": buf})
	return buf
}

// ValidConnectionID determines whether a connection identifier is legitimate.
func ValidConnectionID(connectionID []byte, ip net.IP, now time.Time, maxClockSkew time.Duration, key string) bool {
	ts := time.Unix(int64(binary.BigEndian.Uint32(connectionID[:4])), 0)
	log.Debug("validating connection ID", log.Fields{"connID": connectionID, "ip": ip, "ts": ts, "now": now, "key": key})
	if now.After(ts.Add(ttl)) || ts.After(now.Add(maxClockSkew)) {
		return false
	}

	mac := hmac.New(sha256.New, []byte(key))
	mac.Write(connectionID[:4])
	mac.Write(ip)
	expectedMAC := mac.Sum(nil)[:4]
	return hmac.Equal(expectedMAC, connectionID[4:])
}
<|endoftext|>


<commit_before>package bd

import (
	"database/sql"
	"database/sql/driver"
	"time"

	"github.com/rafaeljusto/atiradorfrequente/núcleo/erros"
	"github.com/registrobr/gostk/db"
)

// Conexão armazena a conexão global do sistema com a base de dados. Todas as
// transações com o banco de dados relacional devem ser abertas a partir desta
// variável. Internamente possui um sistema de pool automático, o que garante a
// escalabilidade.
var Conexão BD

// BD representa uma conexão do banco de dados. Util para manipulação em
// cenários de testes de integração.
type BD interface {
	Begin() (Tx, error)
	Close() error
	Driver() driver.Driver
	Exec(query string, args ...interface{}) (sql.Result, error)
	Ping() error
	Prepare(query string) (*sql.Stmt, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	SetMaxIdleConns(n int)
	SetMaxOpenConns(n int)
}

// Tx representa uma transação do banco de dados. Util para reutilizar
// transações em cenários de testes de integração.
type Tx interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Prepare(query string) (*sql.Stmt, error)
	Rollback() error
	Commit() error
}

type bd struct {
	*sql.DB

	txTempoEsgotado time.Duration
}

// Begin sobrescreve o comportamento padrão da biblioteca adicionando a
// capacidade de timeout ao se criar uma nova transação.
func (b *bd) Begin() (Tx, error) {
	return db.NewTx(b.DB, b.txTempoEsgotado)
}

// IniciarConexão conecta-se ao banco de dados com os parâmetros informados.
var IniciarConexão = func(parâmetrosConexão db.ConnParams, txTempoEsgotado time.Duration) error {
	// TODO(rafaeljusto): Adicionar semáforos para evitar concorrência no acesso a
	// variável global Conexão

	if Conexão != nil && Conexão.Ping() == nil {
		return nil
	}

	conexão, err := db.ConnectPostgres(parâmetrosConexão)
	if err != nil {
		return erros.Novo(err)
	}

	Conexão = &bd{
		DB:              conexão,
		txTempoEsgotado: txTempoEsgotado,
	}

	if err := Conexão.Ping(); err != nil {
		return erros.Novo(err)
	}

	return nil
}
<commit_msg>Altera a API de banco de dados<commit_after>package bd

import (
	"database/sql"
	"database/sql/driver"
	"time"

	"github.com/rafaeljusto/atiradorfrequente/núcleo/erros"
	"github.com/registrobr/gostk/db"
)

// Conexão armazena a conexão global do sistema com a base de dados. Todas as
// transações com o banco de dados relacional devem ser abertas a partir desta
// variável. Internamente possui um sistema de pool automático, o que garante a
// escalabilidade.
var Conexão BD

// BD representa uma conexão do banco de dados. Util para manipulação em
// cenários de testes de integração.
type BD interface {
	Begin() (Tx, error)
	Close() error
	Driver() driver.Driver
	Exec(query string, args ...interface{}) (sql.Result, error)
	Ping() error
	Prepare(query string) (*sql.Stmt, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	SetMaxIdleConns(n int)
	SetMaxOpenConns(n int)
}

// Tx representa uma transação do banco de dados. Util para reutilizar
// transações em cenários de testes de integração.
type Tx interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
	Prepare(query string) (*sql.Stmt, error)
	Rollback() error
	Commit() error
}

type bd struct {
	*db.DB
}

// Begin sobrescreve o comportamento padrão da biblioteca adicionando a
// capacidade de timeout ao se criar uma nova transação.
func (b *bd) Begin() (Tx, error) {
	return b.DB.Begin()
}

// IniciarConexão conecta-se ao banco de dados com os parâmetros informados.
var IniciarConexão = func(parâmetrosConexão db.ConnParams, txTempoEsgotado time.Duration) error {
	// TODO(rafaeljusto): Adicionar semáforos para evitar concorrência no acesso a
	// variável global Conexão

	if Conexão != nil && Conexão.Ping() == nil {
		return nil
	}

	conexão, err := db.ConnectPostgres(parâmetrosConexão)
	if err != nil {
		return erros.Novo(err)
	}

	Conexão = &bd{
		DB: db.NewDB(conexão, txTempoEsgotado),
	}

	if err := Conexão.Ping(); err != nil {
		return erros.Novo(err)
	}

	return nil
}
<|endoftext|>


<commit_before>package softlayer

import (
	"koding/kites/kloud/machinestate"

	"golang.org/x/net/context"
)

func (m *Machine) Reinit(ctx context.Context) (err error) {
	meta, err := m.GetMeta()
	if err != nil {
		return err
	}

	// go and terminate the old instance, we don't need to wait for it
	go func(id int) {
		//Get the SoftLayer virtual guest service
		svc, err := m.Session.SLClient.GetSoftLayer_Virtual_Guest_Service()
		if err != nil {
			m.Log.Warning("couldn't terminate instance (code 1)")
			return
		}

		_, err = svc.DeleteObject(id)
		if err != nil {
			m.Log.Warning("couldn't terminate instance (code 2)")
		}
	}(meta.Id)

	// cleanup this too so "build" can continue with a clean setup
	m.IpAddress = ""
	m.QueryString = ""
	m.Meta["id"] = 0
	m.Status.State = machinestate.NotInitialized.String()

	// this updates/creates domain
	return m.Build(ctx)
}
<commit_msg>softlayer: do not delete in a goroutine<commit_after>package softlayer

import (
	"koding/db/mongodb/modelhelper"
	"koding/kites/kloud/machinestate"

	"golang.org/x/net/context"
)

func (m *Machine) Reinit(ctx context.Context) (err error) {
	if err := modelhelper.ChangeMachineState(m.ObjectId, "Machine is starting", machinestate.Starting); err != nil {
		return err
	}

	// update the state to intiial state if something goes wrong, we are going
	// to change latestate to a more safe state if we passed a certain step
	// below
	latestState := m.State()
	defer func() {
		if err != nil {
			modelhelper.ChangeMachineState(m.ObjectId, "Machine is marked as "+latestState.String(), latestState)
		}
	}()

	meta, err := m.GetMeta()
	if err != nil {
		return err
	}

	// go and terminate the old instance, we don't need to wait for it
	//Get the SoftLayer virtual guest service
	svc, err := m.Session.SLClient.GetSoftLayer_Virtual_Guest_Service()
	if err != nil {
		return err
	}

	_, err = svc.DeleteObject(meta.Id)
	if err != nil {
		return err
	}

	// cleanup this too so "build" can continue with a clean setup
	m.IpAddress = ""
	m.QueryString = ""
	m.Meta["id"] = 0
	m.Status.State = machinestate.NotInitialized.String()

	// this updates/creates domain
	return m.Build(ctx)
}
<|endoftext|>


<commit_before>package main

import (
	"math/rand"
	"socialapi/models"
	"socialapi/rest"
	"strconv"
	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

func TestPinnedActivityChannel(t *testing.T) {
	Convey("while  testing pinned activity channel", t, func() {
		rand.Seed(time.Now().UnixNano())
		groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

		account := models.NewAccount()
		account.OldId = AccountOldId.Hex()
		account, err := rest.CreateAccount(account)
		So(err, ShouldBeNil)
		So(account, ShouldNotBeNil)
		So(account.Id, ShouldNotEqual, 0)

		nonOwnerAccount := models.NewAccount()
		nonOwnerAccount.OldId = AccountOldId.Hex()
		nonOwnerAccount, err = rest.CreateAccount(nonOwnerAccount)
		So(err, ShouldBeNil)
		So(nonOwnerAccount, ShouldNotBeNil)

		groupChannel, err := rest.CreateChannelByGroupNameAndType(account.Id, groupName, models.Channel_TYPE_GROUP)
		So(err, ShouldBeNil)
		So(groupChannel, ShouldNotBeNil)

		post, err := rest.CreatePost(groupChannel.Id, account.Id)
		So(err, ShouldBeNil)
		So(post, ShouldNotBeNil)

		Convey("requester should have one", func() {
			account := account
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			So(channel.Id, ShouldNotEqual, 0)
			So(channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PINNED_ACTIVITY)
			So(channel.CreatorId, ShouldEqual, account.Id)
		})

		Convey("owner should be able to update it", nil)

		Convey("non-owner should not be able to update it", nil)

		Convey("owner should not be able to add new participants into it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.AddChannelParticipant(channel.Id, account.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("normal user shouldnt be able to add new participants to it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.AddChannelParticipant(channel.Id, nonOwnerAccount.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("owner should  not be able to remove participant from it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, account.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("normal user shouldnt be able to remove participants from it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, nonOwnerAccount.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("owner should be able to add new message into it", func() {
			_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should be an err
			So(err, ShouldBeNil)

			_, err = rest.RemovePinnedMessage(account.Id, post.Id, "koding")
			So(err, ShouldBeNil)

		})

		Convey("owner should be able to list messages", func() {
			groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

			pinnedChannel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(pinnedChannel, ShouldNotBeNil)

			groupChannel, err := rest.CreateChannelByGroupNameAndType(account.Id, groupName, models.Channel_TYPE_DEFAULT)
			So(err, ShouldBeNil)
			So(groupChannel, ShouldNotBeNil)

			post1, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1times")
			So(err, ShouldBeNil)
			So(post1, ShouldNotBeNil)

			_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post1.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)

			post2, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1another")
			So(err, ShouldBeNil)
			So(post2, ShouldNotBeNil)

			_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post2.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)

			//time.Sleep(time.Second * 5)

			history, err := rest.FetchPinnedMessages(account.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)
			// channel should be nil
			So(history, ShouldNotBeNil)

			// message count should be 2
			So(len(history.MessageList), ShouldEqual, 2)

			// unread count should be 0
			So(history.UnreadCount, ShouldEqual, 0)

			// old id should be the same one
			So(history.MessageList[0].AccountOldId, ShouldContainSubstring, nonOwnerAccount.OldId)

			// replies count should be 0
			So(len(history.MessageList[0].Replies), ShouldEqual, 0)

			// interactions should not be 0, like should be there
			So(len(history.MessageList[0].Interactions), ShouldEqual, 1)

			// like count should be 0
			So(history.MessageList[0].Interactions["like"].ActorsCount, ShouldEqual, 0)
			// current user should not be interacted with it
			So(history.MessageList[0].Interactions["like"].IsInteracted, ShouldBeFalse)
		})

		Convey("Messages shouldnt be added as pinned twice ", func() {
			// use account id as message id
			_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should be an err
			So(err, ShouldBeNil)
			// use account id as message id
			_, err = rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should be an err
			So(err, ShouldNotBeNil)
		})

		Convey("Non-exist message should not be added as pinned ", nil)

	})
}
<commit_msg>Social: trying to add the same message again, won't return error<commit_after>package main

import (
	"math/rand"
	"socialapi/models"
	"socialapi/rest"
	"strconv"
	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

func TestPinnedActivityChannel(t *testing.T) {
	Convey("while  testing pinned activity channel", t, func() {
		rand.Seed(time.Now().UnixNano())
		groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

		account := models.NewAccount()
		account.OldId = AccountOldId.Hex()
		account, err := rest.CreateAccount(account)
		So(err, ShouldBeNil)
		So(account, ShouldNotBeNil)
		So(account.Id, ShouldNotEqual, 0)

		nonOwnerAccount := models.NewAccount()
		nonOwnerAccount.OldId = AccountOldId.Hex()
		nonOwnerAccount, err = rest.CreateAccount(nonOwnerAccount)
		So(err, ShouldBeNil)
		So(nonOwnerAccount, ShouldNotBeNil)

		groupChannel, err := rest.CreateChannelByGroupNameAndType(account.Id, groupName, models.Channel_TYPE_GROUP)
		So(err, ShouldBeNil)
		So(groupChannel, ShouldNotBeNil)

		post, err := rest.CreatePost(groupChannel.Id, account.Id)
		So(err, ShouldBeNil)
		So(post, ShouldNotBeNil)

		Convey("requester should have one", func() {
			account := account
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			So(channel.Id, ShouldNotEqual, 0)
			So(channel.TypeConstant, ShouldEqual, models.Channel_TYPE_PINNED_ACTIVITY)
			So(channel.CreatorId, ShouldEqual, account.Id)
		})

		Convey("owner should be able to update it", nil)

		Convey("non-owner should not be able to update it", nil)

		Convey("owner should not be able to add new participants into it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.AddChannelParticipant(channel.Id, account.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("normal user shouldnt be able to add new participants to it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.AddChannelParticipant(channel.Id, nonOwnerAccount.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("owner should  not be able to remove participant from it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, account.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("normal user shouldnt be able to remove participants from it", func() {
			channel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(channel, ShouldNotBeNil)
			channelParticipant, err := rest.DeleteChannelParticipant(channel.Id, nonOwnerAccount.Id, nonOwnerAccount.Id)
			// there should be an err
			So(err, ShouldNotBeNil)
			// channel should be nil
			So(channelParticipant, ShouldBeNil)
		})

		Convey("owner should be able to add new message into it", func() {
			_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should be an err
			So(err, ShouldBeNil)

			_, err = rest.RemovePinnedMessage(account.Id, post.Id, "koding")
			So(err, ShouldBeNil)

		})

		Convey("owner should be able to list messages", func() {
			groupName := "testgroup" + strconv.FormatInt(rand.Int63(), 10)

			pinnedChannel, err := rest.FetchPinnedActivityChannel(account.Id, groupName)
			So(err, ShouldBeNil)
			So(pinnedChannel, ShouldNotBeNil)

			groupChannel, err := rest.CreateChannelByGroupNameAndType(account.Id, groupName, models.Channel_TYPE_DEFAULT)
			So(err, ShouldBeNil)
			So(groupChannel, ShouldNotBeNil)

			post1, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1times")
			So(err, ShouldBeNil)
			So(post1, ShouldNotBeNil)

			_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post1.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)

			post2, err := rest.CreatePostWithBody(groupChannel.Id, nonOwnerAccount.Id, "create a message #1another")
			So(err, ShouldBeNil)
			So(post2, ShouldNotBeNil)

			_, err = rest.AddPinnedMessage(nonOwnerAccount.Id, post2.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)

			//time.Sleep(time.Second * 5)

			history, err := rest.FetchPinnedMessages(account.Id, groupName)
			// there should be an err
			So(err, ShouldBeNil)
			// channel should be nil
			So(history, ShouldNotBeNil)

			// message count should be 2
			So(len(history.MessageList), ShouldEqual, 2)

			// unread count should be 0
			So(history.UnreadCount, ShouldEqual, 0)

			// old id should be the same one
			So(history.MessageList[0].AccountOldId, ShouldContainSubstring, nonOwnerAccount.OldId)

			// replies count should be 0
			So(len(history.MessageList[0].Replies), ShouldEqual, 0)

			// interactions should not be 0, like should be there
			So(len(history.MessageList[0].Interactions), ShouldEqual, 1)

			// like count should be 0
			So(history.MessageList[0].Interactions["like"].ActorsCount, ShouldEqual, 0)
			// current user should not be interacted with it
			So(history.MessageList[0].Interactions["like"].IsInteracted, ShouldBeFalse)
		})

		Convey("Messages shouldnt be added as pinned twice ", func() {
			// use account id as message id
			_, err := rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should be an err
			So(err, ShouldBeNil)
			// use account id as message id, pin message is idempotent, if it is
			// in the channel, wont give error
			_, err = rest.AddPinnedMessage(account.Id, post.Id, "koding")
			// there should not be an err
			So(err, ShouldBeNil)
		})

		Convey("Non-exist message should not be added as pinned ", nil)

	})
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"strconv"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sts"
	"github.com/pkg/errors"

	"github.com/versent/saml2aws/pkg/awsconfig"
	"github.com/versent/saml2aws/pkg/flags"
	"github.com/versent/saml2aws/pkg/shell"
)

// Exec execute the supplied command after seeding the environment
func Exec(execFlags *flags.LoginExecFlags, cmdline []string) error {

	if len(cmdline) < 1 {
		return fmt.Errorf("Command to execute required")
	}

	account, err := buildIdpAccount(execFlags)
	if err != nil {
		return errors.Wrap(err, "error building login details")
	}

	sharedCreds := awsconfig.NewSharedCredentials(account.Profile)

	// this checks if the credentials file has been created yet
	// can only really be triggered if saml2aws exec is run on a new
	// system prior to creating $HOME/.aws
	exist, err := sharedCreds.CredsExists()
	if err != nil {
		return errors.Wrap(err, "error loading credentials")
	}
	if !exist {
		fmt.Println("unable to load credentials, login required to create them")
		return nil
	}

	awsCreds, err := sharedCreds.Load()
	if err != nil {
		return errors.Wrap(err, "error loading credentials")
	}

	if awsCreds.Expires.Sub(time.Now()) < 0 {
		return errors.New("error aws credentials have expired")
	}

	ok, err := checkToken(account.Profile)
	if err != nil {
		return errors.Wrap(err, "error validating token")
	}

	if !ok {
		err = Login(execFlags)
	}
	if err != nil {
		return errors.Wrap(err, "error logging in")
	}

	if execFlags.ExecProfile != "" {
		// Assume the desired role before generating env vars
		awsCreds, err = assumeRoleWithProfile(execFlags.ExecProfile, execFlags.CommonFlags.SessionDuration)
		if err != nil {
			return errors.Wrap(err,
				fmt.Sprintf("error acquiring credentials for profile: %s", execFlags.ExecProfile))
		}
	}

	return shell.ExecShellCmd(cmdline, shell.BuildEnvVars(awsCreds, account, execFlags))
}

// assumeRoleWithProfile uses an AWS profile (via ~/.aws/config) and performs (multiple levels of) role assumption
// This is extremely useful in the case of a central "authentication account" which then requires secondary, and
// often tertiary, role assumptions to acquire credentials for the target role.
func assumeRoleWithProfile(targetProfile string, sessionDuration int) (*awsconfig.AWSCredentials, error) {
	// AWS session config with verbose errors on chained credential errors
	config := *aws.NewConfig().WithCredentialsChainVerboseErrors(true)
	duration, _ := time.ParseDuration(strconv.Itoa(sessionDuration) + "s")

	// a session forcing usage of the aws config file, sets the target profile which will be found in the config
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		Config:             config,
		Profile:            targetProfile,
		SharedConfigState:  session.SharedConfigEnable,
		AssumeRoleDuration: duration,
	}))

	// use an STS client to perform the multiple role assumptions
	stsClient := sts.New(sess)
	input := &sts.GetCallerIdentityInput{}
	_, err := stsClient.GetCallerIdentity(input)
	if err != nil {
		return nil, err
	}

	creds, err := sess.Config.Credentials.Get()
	if err != nil {
		return nil, err
	}
	return &awsconfig.AWSCredentials{
		AWSAccessKey:    creds.AccessKeyID,
		AWSSecretKey:    creds.SecretAccessKey,
		AWSSessionToken: creds.SessionToken,
	}, nil
}

func checkToken(profile string) (bool, error) {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: profile,
	})
	if err != nil {
		return false, err
	}

	svc := sts.New(sess)

	params := &sts.GetCallerIdentityInput{}

	_, err = svc.GetCallerIdentity(params)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == "ExpiredToken" || awsErr.Code() == "NoCredentialProviders" {
				return false, nil
			}
		}

		return false, err
	}

	return true, nil
}
<commit_msg>fix using exec-profile<commit_after>package commands

import (
	"fmt"
	"strconv"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sts"
	"github.com/pkg/errors"

	"github.com/versent/saml2aws/pkg/awsconfig"
	"github.com/versent/saml2aws/pkg/flags"
	"github.com/versent/saml2aws/pkg/shell"
)

// Exec execute the supplied command after seeding the environment
func Exec(execFlags *flags.LoginExecFlags, cmdline []string) error {

	if len(cmdline) < 1 {
		return fmt.Errorf("Command to execute required")
	}

	account, err := buildIdpAccount(execFlags)
	if err != nil {
		return errors.Wrap(err, "error building login details")
	}

	sharedCreds := awsconfig.NewSharedCredentials(account.Profile)

	// this checks if the credentials file has been created yet
	// can only really be triggered if saml2aws exec is run on a new
	// system prior to creating $HOME/.aws
	exist, err := sharedCreds.CredsExists()
	if err != nil {
		return errors.Wrap(err, "error loading credentials")
	}
	if !exist {
		fmt.Println("unable to load credentials, login required to create them")
		return nil
	}

	awsCreds, err := sharedCreds.Load()
	if err != nil {
		return errors.Wrap(err, "error loading credentials")
	}

	if awsCreds.Expires.Sub(time.Now()) < 0 {
		return errors.New("error aws credentials have expired")
	}

	ok, err := checkToken(account.Profile)
	if err != nil {
		return errors.Wrap(err, "error validating token")
	}

	if !ok {
		err = Login(execFlags)
	}
	if err != nil {
		return errors.Wrap(err, "error logging in")
	}

	if execFlags.ExecProfile != "" {
		// Assume the desired role before generating env vars
		awsCreds, err = assumeRoleWithProfile(execFlags.ExecProfile, execFlags.CommonFlags.SessionDuration)
		if err != nil {
			return errors.Wrap(err,
				fmt.Sprintf("error acquiring credentials for profile: %s", execFlags.ExecProfile))
		}
	}

	return shell.ExecShellCmd(cmdline, shell.BuildEnvVars(awsCreds, account, execFlags))
}

// assumeRoleWithProfile uses an AWS profile (via ~/.aws/config) and performs (multiple levels of) role assumption
// This is extremely useful in the case of a central "authentication account" which then requires secondary, and
// often tertiary, role assumptions to acquire credentials for the target role.
func assumeRoleWithProfile(targetProfile string, sessionDuration int) (*awsconfig.AWSCredentials, error) {
	// AWS session config with verbose errors on chained credential errors
	config := *aws.NewConfig().WithCredentialsChainVerboseErrors(true)
	duration, _ := time.ParseDuration(strconv.Itoa(sessionDuration) + "s")

	// a session forcing usage of the aws config file, sets the target profile which will be found in the config
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		Config:             config,
		Profile:            targetProfile,
		SharedConfigState:  session.SharedConfigEnable,
		AssumeRoleDuration: duration,
	}))

	// use an STS client to perform the multiple role assumptions
	stsClient := sts.New(sess)
	input := &sts.GetCallerIdentityInput{}
	_, err := stsClient.GetCallerIdentity(input)
	if err != nil {
		return nil, err
	}

	creds, err := sess.Config.Credentials.Get()
	if err != nil {
		return nil, err
	}
	expiredAt, err := sess.Config.Credentials.ExpiresAt()
	if err != nil {
		return nil, err
	}

	return &awsconfig.AWSCredentials{
		AWSAccessKey:    creds.AccessKeyID,
		AWSSecretKey:    creds.SecretAccessKey,
		AWSSessionToken: creds.SessionToken,
		Expires:         expiredAt,
	}, nil
}

func checkToken(profile string) (bool, error) {
	sess, err := session.NewSessionWithOptions(session.Options{
		Profile: profile,
	})
	if err != nil {
		return false, err
	}

	svc := sts.New(sess)

	params := &sts.GetCallerIdentityInput{}

	_, err = svc.GetCallerIdentity(params)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			if awsErr.Code() == "ExpiredToken" || awsErr.Code() == "NoCredentialProviders" {
				return false, nil
			}
		}

		return false, err
	}

	return true, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Heavily inspired by https://github.com/btcsuite/btcd/blob/master/version.go
// Copyright (C) 2015-2017 The Lightning Network Developers

package build

import (
	"fmt"
	"strings"
)

var (
	// Commit stores the current commit of this build, which includes the
	// most recent tag, the number of commits since that tag (if non-zero),
	// the commit hash, and a dirty marker. This should be set using the
	// -ldflags during compilation.
	Commit string

	// CommitHash stores the current commit hash of this build, this should
	// be set using the -ldflags during compilation.
	CommitHash string

	// RawTags contains the raw set of build tags, separated by commas. This
	// should be set using -ldflags during compilation.
	RawTags string

	// GoVersion stores the go version that the executable was compiled
	// with. This hsould be set using -ldflags during compilation.
	GoVersion string
)

// semanticAlphabet is the set of characters that are permitted for use in an
// AppPreRelease.
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	// AppMajor defines the major version of this binary.
	AppMajor uint = 0

	// AppMinor defines the minor version of this binary.
	AppMinor uint = 10

	// AppPatch defines the application patch for this binary.
	AppPatch uint = 0

	// AppPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	AppPreRelease = "beta"
)

func init() {
	// Assert that AppPreRelease is valid according to the semantic
	// versioning guidelines for pre-release version and build metadata
	// strings. In particular it MUST only contain characters in
	// semanticAlphabet.
	for _, r := range AppPreRelease {
		if !strings.ContainsRune(semanticAlphabet, r) {
			panic(fmt.Errorf("rune: %v is not in the semantic "+
				"alphabet", r))
		}
	}
}

// Version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func Version() string {
	// Start with the major, minor, and patch versions.
	version := fmt.Sprintf("%d.%d.%d", AppMajor, AppMinor, AppPatch)

	// Append pre-release version if there is one. The hyphen called for by
	// the semantic versioning spec is automatically appended and should not
	// be contained in the pre-release string.
	if AppPreRelease != "" {
		version = fmt.Sprintf("%s-%s", version, AppPreRelease)
	}

	return version
}

// Tags returns the list of build tags that were compiled into the executable.
func Tags() []string {
	if len(RawTags) == 0 {
		return nil
	}

	return strings.Split(RawTags, ",")
}
<commit_msg>build: bump version to lnd v0.10.99-beta<commit_after>// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Heavily inspired by https://github.com/btcsuite/btcd/blob/master/version.go
// Copyright (C) 2015-2017 The Lightning Network Developers

package build

import (
	"fmt"
	"strings"
)

var (
	// Commit stores the current commit of this build, which includes the
	// most recent tag, the number of commits since that tag (if non-zero),
	// the commit hash, and a dirty marker. This should be set using the
	// -ldflags during compilation.
	Commit string

	// CommitHash stores the current commit hash of this build, this should
	// be set using the -ldflags during compilation.
	CommitHash string

	// RawTags contains the raw set of build tags, separated by commas. This
	// should be set using -ldflags during compilation.
	RawTags string

	// GoVersion stores the go version that the executable was compiled
	// with. This hsould be set using -ldflags during compilation.
	GoVersion string
)

// semanticAlphabet is the set of characters that are permitted for use in an
// AppPreRelease.
const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."

// These constants define the application version and follow the semantic
// versioning 2.0.0 spec (http://semver.org/).
const (
	// AppMajor defines the major version of this binary.
	AppMajor uint = 0

	// AppMinor defines the minor version of this binary.
	AppMinor uint = 10

	// AppPatch defines the application patch for this binary.
	AppPatch uint = 99

	// AppPreRelease MUST only contain characters from semanticAlphabet
	// per the semantic versioning spec.
	AppPreRelease = "beta"
)

func init() {
	// Assert that AppPreRelease is valid according to the semantic
	// versioning guidelines for pre-release version and build metadata
	// strings. In particular it MUST only contain characters in
	// semanticAlphabet.
	for _, r := range AppPreRelease {
		if !strings.ContainsRune(semanticAlphabet, r) {
			panic(fmt.Errorf("rune: %v is not in the semantic "+
				"alphabet", r))
		}
	}
}

// Version returns the application version as a properly formed string per the
// semantic versioning 2.0.0 spec (http://semver.org/).
func Version() string {
	// Start with the major, minor, and patch versions.
	version := fmt.Sprintf("%d.%d.%d", AppMajor, AppMinor, AppPatch)

	// Append pre-release version if there is one. The hyphen called for by
	// the semantic versioning spec is automatically appended and should not
	// be contained in the pre-release string.
	if AppPreRelease != "" {
		version = fmt.Sprintf("%s-%s", version, AppPreRelease)
	}

	return version
}

// Tags returns the list of build tags that were compiled into the executable.
func Tags() []string {
	if len(RawTags) == 0 {
		return nil
	}

	return strings.Split(RawTags, ",")
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package trace

import (
	"bytes"
	"fmt"
	"time"

	"github.com/golang/glog"
)

type traceStep struct {
	stepTime time.Time
	msg      string
}

type Trace struct {
	name      string
	startTime time.Time
	steps     []traceStep
}

func New(name string) *Trace {
	return &Trace{name, time.Now(), nil}
}

func (t *Trace) Step(msg string) {
	if t.steps == nil {
		// traces almost always have less than 6 steps, do this to avoid more than a single allocation
		t.steps = make([]traceStep, 0, 6)
	}
	t.steps = append(t.steps, traceStep{time.Now(), msg})
}

func (t *Trace) Log() {
	endTime := time.Now()
	var buffer bytes.Buffer

	buffer.WriteString(fmt.Sprintf("Trace %q (started %v):\n", t.name, t.startTime))
	lastStepTime := t.startTime
	for _, step := range t.steps {
		buffer.WriteString(fmt.Sprintf("[%v] [%v] %v\n", step.stepTime.Sub(t.startTime), step.stepTime.Sub(lastStepTime), step.msg))
		lastStepTime = step.stepTime
	}
	buffer.WriteString(fmt.Sprintf("[%v] [%v] END\n", endTime.Sub(t.startTime), endTime.Sub(lastStepTime)))
	glog.Info(buffer.String())
}

func (t *Trace) LogIfLong(threshold time.Duration) {
	if time.Since(t.startTime) >= threshold {
		t.Log()
	}
}

func (t *Trace) TotalTime() time.Duration {
	return time.Since(t.startTime)
}
<commit_msg>stop spamming logs on restart of api server<commit_after>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package trace

import (
	"bytes"
	"fmt"
	"time"

	"github.com/golang/glog"
)

type traceStep struct {
	stepTime time.Time
	msg      string
}

type Trace struct {
	name      string
	startTime time.Time
	steps     []traceStep
}

func New(name string) *Trace {
	return &Trace{name, time.Now(), nil}
}

func (t *Trace) Step(msg string) {
	if t.steps == nil {
		// traces almost always have less than 6 steps, do this to avoid more than a single allocation
		t.steps = make([]traceStep, 0, 6)
	}
	t.steps = append(t.steps, traceStep{time.Now(), msg})
}

func (t *Trace) Log() {
	endTime := time.Now()
	var buffer bytes.Buffer

	buffer.WriteString(fmt.Sprintf("Trace %q (started %v):\n", t.name, t.startTime))
	lastStepTime := t.startTime
	for _, step := range t.steps {
		buffer.WriteString(fmt.Sprintf("[%v] [%v] %v\n", step.stepTime.Sub(t.startTime), step.stepTime.Sub(lastStepTime), step.msg))
		lastStepTime = step.stepTime
	}
	buffer.WriteString(fmt.Sprintf("%q [%v] [%v] END\n", t.name, endTime.Sub(t.startTime), endTime.Sub(lastStepTime)))
	glog.Info(buffer.String())
}

func (t *Trace) LogIfLong(threshold time.Duration) {
	if time.Since(t.startTime) >= threshold {
		t.Log()
	}
}

func (t *Trace) TotalTime() time.Duration {
	return time.Since(t.startTime)
}
<|endoftext|>


<commit_before><commit_msg>chore(be): remove unused env vars from git command<commit_after><|endoftext|>