<commit_before>package builtin

import (
	"github.com/mediocregopher/hyrax/types"
	stypes "github.com/mediocregopher/hyrax/server/types"
	"strings"
)

type BuiltInFunc func(
	stypes.ClientId,
	*types.ClientCommand) (interface{}, error)

type builtInCommandInfo struct {
	Func BuiltInFunc
	Admin    bool
	Modifies bool
}

var builtInMap = map[string]*builtInCommandInfo{
	"madd":       &builtInCommandInfo{Func: MAdd, Modifies: true},
	"mrem":       &builtInCommandInfo{Func: MRem, Modifies: true},
	"eadd":       &builtInCommandInfo{Func: EAdd, Modifies: true},
	"erem":       &builtInCommandInfo{Func: ERem, Modifies: true},
	"emembers":   &builtInCommandInfo{Func: EMembers},
	"ecard":      &builtInCommandInfo{Func: ECard},

	"anodeadd":
		&builtInCommandInfo{
			Func: ANodeAdd,
			Modifies: true,
			Admin: true,
		},

	"anoderem":
		&builtInCommandInfo{
			Func: ANodeRem,
			Modifies: true,
			Admin: true,
		},

	"abucketset":
		&builtInCommandInfo{
			Func: ABucketSet,
			Modifies: true,
			Admin: true,
		},

	"abuckets":
		&builtInCommandInfo{
			Func: ABuckets,
			Admin: true,
		},

	"aglobalsecretadd":
		&builtInCommandInfo{
			Func: AGlobalSecretAdd,
			Modifies: true,
			Admin: true,
		},

	"aglobalsecretrem":
		&builtInCommandInfo{
			Func: AGlobalSecretRem,
			Modifies: true,
			Admin: true,
		},

	"aglobalsecrets":
		&builtInCommandInfo{
			Func: AGlobalSecrets,
			Admin: true,
		},

	"asecretadd":
		&builtInCommandInfo{
			Func: ASecretAdd,
			Modifies: true,
			Admin: true,
		},

	"asecretrem":
		&builtInCommandInfo{
			Func: ASecretRem,
			Modifies: true,
			Admin: true,
		},

	"asecrets":
		&builtInCommandInfo{
			Func: ASecrets,
			Admin: true,
		},
}

func getBuiltInCommandInfo(cmd []byte) (*builtInCommandInfo, bool) {
	cinfo, ok := builtInMap[strings.ToLower(string(cmd))]
	return cinfo, ok
}

// IsBuiltInCommand returns whether or not the given command is a valid builtin
// one
func IsBuiltInCommand(cmd []byte) bool {
	_, ok := getBuiltInCommandInfo(cmd)
	return ok
}

// CommandModifies returns whether or not a given builtin command modifies the
// backend state, or false if it's not a valid builtin command
func CommandModifies(cmd []byte) bool {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Modifies
	}
	return false
}

// IsAdminCommand returns whether or not a given builtin command is an admin
// only command, or false if it's not a valid builtin command
func IsAdminCommand(cmd []byte) bool {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Admin
	}
	return false
}

// GetFunc returns the function for a given builtin command, or nil if the
// command isn't a valid builtin command
func GetFunc(cmd []byte) BuiltInFunc {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Func
	}
	return nil
}
<commit_msg>monitor commands don't modify (why am I so dumb!?)<commit_after>package builtin

import (
	"github.com/mediocregopher/hyrax/types"
	stypes "github.com/mediocregopher/hyrax/server/types"
	"strings"
)

type BuiltInFunc func(
	stypes.ClientId,
	*types.ClientCommand) (interface{}, error)

type builtInCommandInfo struct {
	Func BuiltInFunc
	Admin    bool
	Modifies bool
}

var builtInMap = map[string]*builtInCommandInfo{
	"madd":       &builtInCommandInfo{Func: MAdd},
	"mrem":       &builtInCommandInfo{Func: MRem},
	"eadd":       &builtInCommandInfo{Func: EAdd, Modifies: true},
	"erem":       &builtInCommandInfo{Func: ERem, Modifies: true},
	"emembers":   &builtInCommandInfo{Func: EMembers},
	"ecard":      &builtInCommandInfo{Func: ECard},

	"anodeadd":
		&builtInCommandInfo{
			Func: ANodeAdd,
			Modifies: true,
			Admin: true,
		},

	"anoderem":
		&builtInCommandInfo{
			Func: ANodeRem,
			Modifies: true,
			Admin: true,
		},

	"abucketset":
		&builtInCommandInfo{
			Func: ABucketSet,
			Modifies: true,
			Admin: true,
		},

	"abuckets":
		&builtInCommandInfo{
			Func: ABuckets,
			Admin: true,
		},

	"aglobalsecretadd":
		&builtInCommandInfo{
			Func: AGlobalSecretAdd,
			Modifies: true,
			Admin: true,
		},

	"aglobalsecretrem":
		&builtInCommandInfo{
			Func: AGlobalSecretRem,
			Modifies: true,
			Admin: true,
		},

	"aglobalsecrets":
		&builtInCommandInfo{
			Func: AGlobalSecrets,
			Admin: true,
		},

	"asecretadd":
		&builtInCommandInfo{
			Func: ASecretAdd,
			Modifies: true,
			Admin: true,
		},

	"asecretrem":
		&builtInCommandInfo{
			Func: ASecretRem,
			Modifies: true,
			Admin: true,
		},

	"asecrets":
		&builtInCommandInfo{
			Func: ASecrets,
			Admin: true,
		},
}

func getBuiltInCommandInfo(cmd []byte) (*builtInCommandInfo, bool) {
	cinfo, ok := builtInMap[strings.ToLower(string(cmd))]
	return cinfo, ok
}

// IsBuiltInCommand returns whether or not the given command is a valid builtin
// one
func IsBuiltInCommand(cmd []byte) bool {
	_, ok := getBuiltInCommandInfo(cmd)
	return ok
}

// CommandModifies returns whether or not a given builtin command modifies the
// backend state, or false if it's not a valid builtin command
func CommandModifies(cmd []byte) bool {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Modifies
	}
	return false
}

// IsAdminCommand returns whether or not a given builtin command is an admin
// only command, or false if it's not a valid builtin command
func IsAdminCommand(cmd []byte) bool {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Admin
	}
	return false
}

// GetFunc returns the function for a given builtin command, or nil if the
// command isn't a valid builtin command
func GetFunc(cmd []byte) BuiltInFunc {
	if cinfo, ok := getBuiltInCommandInfo(cmd); ok {
		return cinfo.Func
	}
	return nil
}
<|endoftext|>


<commit_before>package slack

import (
	"crypto/sha256"
	"encoding/hex"
)

type ID interface {
	String() string
	Equals(ID) bool
	Valid() bool
}

type UserID struct {
	UserID string
	TeamID string
}

// SecureID is an opaque, deterministic representation of a Slack user identity
// which can be used in place of UserID to minimize the consequences
// of accidentally logging or otherwise compromising a user's ID.
//
// A SecureID can be constructed from a UserID
// by calling UserID.Secure()
type SecureID struct {
	HashSum string
}

// Equals indicates if id and o represents the same user identity.
func (id UserID) Equals(o ID) bool {
	switch o := o.(type) {
	case UserID:
		if !(id.Valid() && o.Valid()) {
			return false
		}

		// Notice that user IDs are not guaranteed to be globally unique across all Slack users.
		// The combination of user ID and team ID, on the other hand, is guaranteed to be globally unique.
		//
		// - Slack API documentation
		return id.UserID == o.UserID && id.TeamID == o.TeamID
	case SecureID:
		return id.Secure().Equals(o)
	}

	return false
}

func (id UserID) Valid() bool {
	return id.UserID != "" && id.TeamID != ""
}

func (id UserID) String() string {
	return id.TeamID + "." + id.UserID
}

// Secure converts id into a SecureID.
func (id UserID) Secure() SecureID {
	if !id.Valid() {
		return SecureID{}
	}

	concat := id.TeamID + "." + id.UserID
	h := sha256.New()
	h.Write([]byte(concat))
	s := hex.EncodeToString(h.Sum(nil))

	return SecureID{
		HashSum: s,
	}
}

// Equals indicates if id and o represents the same user identity.
func (id SecureID) Equals(o ID) bool {
	switch o := o.(type) {
	case SecureID:
		if !id.Valid() || !o.Valid() {
			return false
		}

		return id.HashSum == o.HashSum
	case UserID:
		return o.Secure().Equals(id)
	}
	return false
}

func (id SecureID) Valid() bool {
	return id.HashSum != ""
}

func (id SecureID) String() string {
	return id.HashSum
}
<commit_msg>Fix grammar<commit_after>package slack

import (
	"crypto/sha256"
	"encoding/hex"
)

type ID interface {
	String() string
	Equals(ID) bool
	Valid() bool
}

type UserID struct {
	UserID string
	TeamID string
}

// SecureID is an opaque, deterministic representation of a Slack user identity
// which can be used in place of UserID to minimize the consequences
// of accidentally logging or otherwise compromising a user's ID.
//
// A SecureID can be constructed from a UserID
// by calling UserID.Secure()
type SecureID struct {
	HashSum string
}

// Equals indicates if id and o represent the same user identity.
func (id UserID) Equals(o ID) bool {
	switch o := o.(type) {
	case UserID:
		if !(id.Valid() && o.Valid()) {
			return false
		}

		// > Notice that user IDs are not guaranteed to be globally unique across all Slack users.
		// > The combination of user ID and team ID, on the other hand, is guaranteed to be globally unique.
		//
		// - Slack API documentation
		return id.UserID == o.UserID && id.TeamID == o.TeamID
	case SecureID:
		return id.Secure().Equals(o)
	}

	return false
}

func (id UserID) Valid() bool {
	return id.UserID != "" && id.TeamID != ""
}

func (id UserID) String() string {
	return id.TeamID + "." + id.UserID
}

// Secure converts id into a SecureID.
func (id UserID) Secure() SecureID {
	if !id.Valid() {
		return SecureID{}
	}

	concat := id.TeamID + "." + id.UserID
	h := sha256.New()
	h.Write([]byte(concat))
	s := hex.EncodeToString(h.Sum(nil))

	return SecureID{
		HashSum: s,
	}
}

// Equals indicates if id and o represent the same user identity.
func (id SecureID) Equals(o ID) bool {
	switch o := o.(type) {
	case SecureID:
		if !id.Valid() || !o.Valid() {
			return false
		}

		return id.HashSum == o.HashSum
	case UserID:
		return o.Secure().Equals(id)
	}
	return false
}

func (id SecureID) Valid() bool {
	return id.HashSum != ""
}

func (id SecureID) String() string {
	return id.HashSum
}
<|endoftext|>


<commit_before>package configuration

import (
	"encoding/json"
	"github.com/cloud-ca/go-cloudca/api"
)

type Organization struct {
	Id           string        `json:"id,omitempty"`
	Name         string        `json:"name,omitempty"`
	EntryPoint   string        `json:"entryPoint,omitempty"`
	Users        []User        `json:"users"`
	Environments []Environment `json:"environments"`
	Roles        []Role        `json:"roles"`
}

type OrganizationService interface {
	Get(id string) (*Organization, error)
	List() ([]Organization, error)
	ListWithOptions(options map[string]string) ([]Organization, error)
}

type OrganizationApi struct {
	configurationService ConfigurationService
}

func NewOrganizationService(apiClient api.ApiClient) OrganizationService {
	return &OrganizationApi{
		configurationService: NewConfigurationService(apiClient, "tenants"),
	}
}

func parseOrganization(data []byte) *Organization {
	organization := Organization{}
	json.Unmarshal(data, &organization)
	return &organization
}

func parseOrganizationList(data []byte) []Organization {
	organizations := []Organization{}
	json.Unmarshal(data, &organizations)
	return organizations
}

func (organizationApi *OrganizationApi) Get(id string) (*Organization, error) {
	data, err := organizationApi.configurationService.Get(id, map[string]string{})
	if err != nil {
		return nil, err
	}
	return parseOrganization(data), nil
}

//List all organizations
func (organizationApi *OrganizationApi) List() ([]Organization, error) {
	return organizationApi.ListWithOptions(map[string]string{})
}

//List all organizations. Can use options to do sorting and paging.
func (organizationApi *OrganizationApi) ListWithOptions(options map[string]string) ([]Organization, error) {
	data, err := organizationApi.configurationService.List(options)
	if err != nil {
		return nil, err
	}
	return parseOrganizationList(data), nil
}
<commit_msg>Fixed Organization API endpoint (tenants to organizations)<commit_after>package configuration

import (
	"encoding/json"

	"github.com/cloud-ca/go-cloudca/api"
)

type Organization struct {
	Id           string        `json:"id,omitempty"`
	Name         string        `json:"name,omitempty"`
	EntryPoint   string        `json:"entryPoint,omitempty"`
	Users        []User        `json:"users"`
	Environments []Environment `json:"environments"`
	Roles        []Role        `json:"roles"`
}

type OrganizationService interface {
	Get(id string) (*Organization, error)
	List() ([]Organization, error)
	ListWithOptions(options map[string]string) ([]Organization, error)
}

type OrganizationApi struct {
	configurationService ConfigurationService
}

func NewOrganizationService(apiClient api.ApiClient) OrganizationService {
	return &OrganizationApi{
		configurationService: NewConfigurationService(apiClient, "organizations"),
	}
}

func parseOrganization(data []byte) *Organization {
	organization := Organization{}
	json.Unmarshal(data, &organization)
	return &organization
}

func parseOrganizationList(data []byte) []Organization {
	organizations := []Organization{}
	json.Unmarshal(data, &organizations)
	return organizations
}

func (organizationApi *OrganizationApi) Get(id string) (*Organization, error) {
	data, err := organizationApi.configurationService.Get(id, map[string]string{})
	if err != nil {
		return nil, err
	}
	return parseOrganization(data), nil
}

//List all organizations
func (organizationApi *OrganizationApi) List() ([]Organization, error) {
	return organizationApi.ListWithOptions(map[string]string{})
}

//List all organizations. Can use options to do sorting and paging.
func (organizationApi *OrganizationApi) ListWithOptions(options map[string]string) ([]Organization, error) {
	data, err := organizationApi.configurationService.List(options)
	if err != nil {
		return nil, err
	}
	return parseOrganizationList(data), nil
}
<|endoftext|>


<commit_before>package translation

import (
	"archive/zip"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"math"
	"os"
	"path/filepath"

	"github.com/thomaspeugeot/tkv/barnes-hut"
	"github.com/thomaspeugeot/tkv/grump"
	"github.com/thomaspeugeot/tkv/quadtree"
)

type Country struct {
	grump.Country

	NbBodies int // nb of bodies according to the filename

	bodiesOrig     *[]quadtree.Body // original bodies position in the quatree
	bodiesSpread   *[]quadtree.Body // bodies position in the quatree after the spread simulation
	VilCoordinates [][]int
	Step           int // step when the simulation stopped

	villages [][]Village
}

type Point struct {
	X, Y float64
}

func MakePoint(x float64, y float64) Point {
	return Point{X: x, Y: y}
}

type PointList []Point

type BodySetChoice string

const (
	ORIGINAL_CONFIGURATION = "ORIGINAL_CONFIGURATION"
	SPREAD_CONFIGURATION   = "SPREAD_CONFIGURATION"
)

// number of village per X or Y axis. For 10 000 villages, this number is 100
// this value can be set interactively during the run
var nbVillagePerAxe int = 100
var numberOfVillagePerAxe float64 = 100.0

// init variables
func (country *Country) Init() {

	// unserialize from conf-<country trigram>.coord
	// store step because the unseralize set it to a wrong value
	step := country.Step
	country.Unserialize()
	country.Step = step

	Info.Printf("Init after Unserialize name %s", country.Name)
	Info.Printf("Init after Unserialize step %d", country.Step)

	country.LoadConfig(true)  // load config at the end  of the simulation
	country.LoadConfig(false) // load config at the start of the simulation

	// init village array
	country.villages = make([][]Village, nbVillagePerAxe)
	for x, _ := range country.villages {
		country.villages[x] = make([]Village, nbVillagePerAxe)
	}

	country.VilCoordinates = make([][]int, country.NbBodies)
	for idx, _ := range country.VilCoordinates {
		country.VilCoordinates[idx] = make([]int, 2)
	}

	country.ComputeBaryCenters()

}

// load configuration from filename into country
// check that it matches the
func (country *Country) LoadConfig(isOriginal bool) bool {

	Info.Printf("Load Config begin : Country is %s, step %d isOriginal %t", country.Name, country.Step, isOriginal)

	// computing the file name from the step
	step := 0

	// if isOrignal load the file with the step number 0, else use spread
	if !isOriginal {
		step = country.Step
	}

	filename := fmt.Sprintf(barnes_hut.CountryBodiesNamePattern, country.Name, country.NbBodies, step)
	Info.Printf("LoadConfig (orig = true/final = false) %t file %s for country %s at step %d", isOriginal, filename, country.Name, step)

	// check if file is missing.
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		Info.Printf("File %s is missing, trying to find the zip file", filename)

		zipFilename := filename + ".zip"
		Info.Printf("Checking if zip file %s is present", zipFilename)
		if _, err := os.Stat(zipFilename); os.IsNotExist(err) {
			log.Fatal(err)
			return false
		}

		Info.Printf("Loading zip file %s in tmp dir", zipFilename)
		// unzip file in tmp directory and change filename to it

		reader, err := zip.OpenReader(zipFilename)
		if err != nil {
			log.Fatal(err)
		}
		defer reader.Close()

		target := "tmp"
		// create tmp dir
		if err := os.MkdirAll(target, 0755); err != nil {
			log.Fatal(err)
			return false
		}

		for _, file := range reader.File {
			path := filepath.Join(target, file.Name)
			if file.FileInfo().IsDir() {
				os.MkdirAll(path, file.Mode())
				continue
			}

			fileReader, err := file.Open()
			if err != nil {
				log.Fatal(err)
				return false
			}
			defer fileReader.Close()

			targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
			if err != nil {
				log.Fatal(err)
				return false
			}
			defer targetFile.Close()

			if _, err := io.Copy(targetFile, fileReader); err != nil {
				log.Fatal(err)
				return false
			}
		}
		filename = target + "/" + filename
	}

	file, err := os.Open(filename)
	if err != nil {
		log.Fatal(err)
		return false
	}

	jsonParser := json.NewDecoder(file)

	bodies := (make([]quadtree.Body, 0))
	if isOriginal {
		country.bodiesOrig = &bodies
		if err = jsonParser.Decode(country.bodiesOrig); err != nil {
			log.Fatal(fmt.Sprintf("parsing config file %s", err.Error()))
		}
		Info.Printf("nb item parsed in file for orig %d\n", len(*country.bodiesOrig))
	} else {
		country.bodiesSpread = &bodies
		if err = jsonParser.Decode(country.bodiesSpread); err != nil {
			log.Fatal(fmt.Sprintf("parsing config file %s", err.Error()))
		}
		Info.Printf("nb item parsed in file for spread %d\n", len(*country.bodiesSpread))
	}

	file.Close()

	Info.Printf("Load Config end : Country is %s, step %d", country.Name, country.Step)

	return true
}

// compute villages barycenters
func (country *Country) ComputeBaryCenters() {
	Info.Printf("ComputeBaryCenters begins for country %s", country.Name)

	// parse bodiesSpread to compute bary centers
	// use bodiesOrig to compute bary centers
	for index, b := range *country.bodiesSpread {

		// compute village coordinate (from 0 to nbVillagePerAxe-1)
		villageX := int(math.Floor(float64(nbVillagePerAxe) * b.X))
		villageY := int(math.Floor(float64(nbVillagePerAxe) * b.Y))

		Trace.Printf("Adding body index %d to village %d %d", index, villageX, villageY)

		// add body (original) to the barycenter of the village
		bOrig := (*country.bodiesOrig)[index]
		country.villages[villageX][villageY].addBody(bOrig)

		country.VilCoordinates[index][0] = villageX
		country.VilCoordinates[index][1] = villageY
	}
}

// given lat, lng
// return xClosest, yClosest, distance, latClosest, lngClosest of the closest body within the country (original position)
func (country *Country) ClosestBodyInOriginalPosition(lat, lng float64) (xRelClosest, yRelClosest, distance, latClosest, lngClosest, xSpread, ySpread float64, closestIndex int) {

	// compute relative coordinates within the square
	xRel, yRel := country.LatLng2XY(lat, lng)

	// parse all bodies and get closest body
	closestIndex = -1
	minDistance := 1000000000.0 // we start from away
	for index, b := range *country.bodiesOrig {
		distanceX := b.X - xRel
		distanceY := b.Y - yRel
		distance := math.Sqrt((distanceX * distanceX) + (distanceY * distanceY))

		if distance < minDistance {
			closestIndex = index
			minDistance = distance
		}
	}

	xRelClosest = (*country.bodiesOrig)[closestIndex].X
	yRelClosest = (*country.bodiesOrig)[closestIndex].Y

	latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)

	Info.Printf("ClosestBodyInOriginalPosition %f %f relative to country %f %f", lat, lng, xRel, yRel)
	Info.Printf("ClosestBodyInOriginalPosition rel closest %f %f lat lng closest %f %f", xRelClosest, yRelClosest, latOptimClosest, lngOptimClosest)

	// compute x, y in spread bodies
	xSpread = (*country.bodiesSpread)[closestIndex].X
	ySpread = (*country.bodiesSpread)[closestIndex].Y

	Info.Printf("ClosestBodyInOriginalPosition village %f %f index %d", xSpread, ySpread, closestIndex)

	return xRelClosest, yRelClosest, minDistance, latOptimClosest, lngOptimClosest, xSpread, ySpread, closestIndex
}

func (country *Country) XYSpreadToLatLngOrig(x, y float64) (lat, lng float64) {

	Info.Printf("XYSpreadToLatLngOrig input x %f y %f", x, y)

	// parse all bodies and get closest body
	closestIndex := -1
	minDistance := 1000000000.0 // we start from away
	for index, b := range *country.bodiesSpread {
		distanceX := b.X - x
		distanceY := b.Y - y
		distance := math.Sqrt((distanceX * distanceX) + (distanceY * distanceY))

		if distance < minDistance {
			closestIndex = index
			minDistance = distance
		}
	}

	xRelClosest := (*country.bodiesOrig)[closestIndex].X
	yRelClosest := (*country.bodiesOrig)[closestIndex].Y
	latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)
	Info.Printf("XYSpreadToLatLngOrig target x %f y %f index %d distance %f", xRelClosest, yRelClosest, closestIndex, minDistance)

	Info.Printf("XYSpreadToLatLngOrig target lat %f lng %f", latOptimClosest, lngOptimClosest)

	return latOptimClosest, lngOptimClosest
}

// get the bodies of a village from x, y spread coordinates
func (country *Country) XYSpreadToTerritoryBorder(x, y float64) PointList {

	Info.Printf("XYSpreadToTerritoryBorder Country %s x %f y %f", country.Name, x, y)

	points := make(PointList, 0)

	// compute village min & max coord
	xMinVillage := float64(int(x*numberOfVillagePerAxe)) / numberOfVillagePerAxe
	xMaxVillage := float64(int(x*numberOfVillagePerAxe+1.0)) / numberOfVillagePerAxe
	yMinVillage := float64(int(y*numberOfVillagePerAxe)) / numberOfVillagePerAxe
	yMaxVillage := float64(int(y*numberOfVillagePerAxe+1.0)) / numberOfVillagePerAxe

	Info.Printf("XYSpreadToTerritoryBorder input village Min x %f Max x %f", xMinVillage, xMaxVillage)

	// parse all bodies and get closest body
	for index, b := range *country.bodiesSpread {
		if (xMinVillage <= b.X) && (b.X < xMaxVillage) && (yMinVillage <= b.Y) && (b.Y < yMaxVillage) {

			xRelClosest := (*country.bodiesOrig)[index].X
			yRelClosest := (*country.bodiesOrig)[index].Y
			latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)

			points = append(points, MakePoint(latOptimClosest, lngOptimClosest))
			Info.Printf("XYSpreadToTerritoryBorder %f %f", latOptimClosest, lngOptimClosest)
		}
	}

	Info.Printf("XYSpreadToTerritoryBorder Country %s nb bodies in village %d", country.Name, len(points))
	return points
}

// given x, y of a point, return the border in the country
func (country *Country) LatLngToTerritoryBorder(lat, lng float64) PointList {

	Info.Printf("")
	Info.Printf("LatLngToTerritoryBorder country %s input lat %f lng %f", country.Name, lat, lng)

	// from input lat, lng, get the xSpread, ySpread
	_, _, _, _, _, xSpread, ySpread, _ := country.ClosestBodyInOriginalPosition(lat, lng)
	Info.Printf("LatLngToTerritoryBorder country %s input xSpread %f ySpread %f", country.Name, xSpread, ySpread)

	points := country.XYSpreadToTerritoryBorder(xSpread, ySpread)

	Info.Printf("LatLngToTerritoryBorder nb of border points %d", len(points))
	Info.Printf("")

	return points
}
<commit_msg>runtime_server reads zip file instead of plain files (in order to go below the 35 MB of app engine)<commit_after>package translation

import (
	"archive/zip"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"math"
	"os"

	"github.com/thomaspeugeot/tkv/barnes-hut"
	"github.com/thomaspeugeot/tkv/grump"
	"github.com/thomaspeugeot/tkv/quadtree"
)

type Country struct {
	grump.Country

	NbBodies int // nb of bodies according to the filename

	bodiesOrig     *[]quadtree.Body // original bodies position in the quatree
	bodiesSpread   *[]quadtree.Body // bodies position in the quatree after the spread simulation
	VilCoordinates [][]int
	Step           int // step when the simulation stopped

	villages [][]Village
}

type Point struct {
	X, Y float64
}

func MakePoint(x float64, y float64) Point {
	return Point{X: x, Y: y}
}

type PointList []Point

type BodySetChoice string

const (
	ORIGINAL_CONFIGURATION = "ORIGINAL_CONFIGURATION"
	SPREAD_CONFIGURATION   = "SPREAD_CONFIGURATION"
)

// number of village per X or Y axis. For 10 000 villages, this number is 100
// this value can be set interactively during the run
var nbVillagePerAxe int = 100
var numberOfVillagePerAxe float64 = 100.0

// init variables
func (country *Country) Init() {

	// unserialize from conf-<country trigram>.coord
	// store step because the unseralize set it to a wrong value
	step := country.Step
	country.Unserialize()
	country.Step = step

	Info.Printf("Init after Unserialize name %s", country.Name)
	Info.Printf("Init after Unserialize step %d", country.Step)

	country.LoadConfig(true)  // load config at the end  of the simulation
	country.LoadConfig(false) // load config at the start of the simulation

	// init village array
	country.villages = make([][]Village, nbVillagePerAxe)
	for x, _ := range country.villages {
		country.villages[x] = make([]Village, nbVillagePerAxe)
	}

	country.VilCoordinates = make([][]int, country.NbBodies)
	for idx, _ := range country.VilCoordinates {
		country.VilCoordinates[idx] = make([]int, 2)
	}

	country.ComputeBaryCenters()

}

var bodsFileReader io.ReadCloser
var bodsFileReaderErr error

// load configuration from filename into country
// check that it matches the
func (country *Country) LoadConfig(isOriginal bool) bool {

	bodsFileReaderErr = nil

	Info.Printf("Load Config begin : Country is %s, step %d isOriginal %t", country.Name, country.Step, isOriginal)

	// computing the file name from the step
	step := 0

	// if isOrignal load the file with the step number 0, else use spread
	if !isOriginal {
		step = country.Step
	}

	filename := fmt.Sprintf(barnes_hut.CountryBodiesNamePattern, country.Name, country.NbBodies, step)
	Info.Printf("LoadConfig (orig = true/final = false) %t file %s for country %s at step %d", isOriginal, filename, country.Name, step)

	// check if file is missing.
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		Info.Printf("File %s is missing, trying to find the zip file", filename)

		zipFilename := filename + ".zip"
		Info.Printf("Checking if zip file %s is present", zipFilename)
		if _, err := os.Stat(zipFilename); os.IsNotExist(err) {
			log.Fatal(err)
			return false
		}

		Info.Printf("Loading zip file %s", zipFilename)
		reader, err := zip.OpenReader(zipFilename)
		if err != nil {
			log.Fatal(err)
		}
		defer reader.Close()
		Info.Printf("Loading zip file %s done", zipFilename)

		for _, file := range reader.File {

			bodsFileReader, bodsFileReaderErr = file.Open()
			Info.Printf("Open bods file %s in zip", file.Name)
			if bodsFileReaderErr != nil {
				log.Fatal(bodsFileReaderErr)
				return false
			}
			defer bodsFileReader.Close()

		}
	}

	jsonParser := json.NewDecoder(bodsFileReader)

	bodies := (make([]quadtree.Body, 0))
	if isOriginal {
		country.bodiesOrig = &bodies
		if err := jsonParser.Decode(country.bodiesOrig); err != nil {
			log.Fatal(fmt.Sprintf("parsing config file %s", err.Error()))
		}
		Info.Printf("nb item parsed in file for orig %d\n", len(*country.bodiesOrig))
	} else {
		country.bodiesSpread = &bodies
		if err := jsonParser.Decode(country.bodiesSpread); err != nil {
			log.Fatal(fmt.Sprintf("parsing config file %s", err.Error()))
		}
		Info.Printf("nb item parsed in file for spread %d\n", len(*country.bodiesSpread))
	}

	bodsFileReader.Close()

	Info.Printf("Load Config end : Country is %s, step %d", country.Name, country.Step)

	return true
}

// compute villages barycenters
func (country *Country) ComputeBaryCenters() {
	Info.Printf("ComputeBaryCenters begins for country %s", country.Name)

	// parse bodiesSpread to compute bary centers
	// use bodiesOrig to compute bary centers
	for index, b := range *country.bodiesSpread {

		// compute village coordinate (from 0 to nbVillagePerAxe-1)
		villageX := int(math.Floor(float64(nbVillagePerAxe) * b.X))
		villageY := int(math.Floor(float64(nbVillagePerAxe) * b.Y))

		Trace.Printf("Adding body index %d to village %d %d", index, villageX, villageY)

		// add body (original) to the barycenter of the village
		bOrig := (*country.bodiesOrig)[index]
		country.villages[villageX][villageY].addBody(bOrig)

		country.VilCoordinates[index][0] = villageX
		country.VilCoordinates[index][1] = villageY
	}
}

// given lat, lng
// return xClosest, yClosest, distance, latClosest, lngClosest of the closest body within the country (original position)
func (country *Country) ClosestBodyInOriginalPosition(lat, lng float64) (xRelClosest, yRelClosest, distance, latClosest, lngClosest, xSpread, ySpread float64, closestIndex int) {

	// compute relative coordinates within the square
	xRel, yRel := country.LatLng2XY(lat, lng)

	// parse all bodies and get closest body
	closestIndex = -1
	minDistance := 1000000000.0 // we start from away
	for index, b := range *country.bodiesOrig {
		distanceX := b.X - xRel
		distanceY := b.Y - yRel
		distance := math.Sqrt((distanceX * distanceX) + (distanceY * distanceY))

		if distance < minDistance {
			closestIndex = index
			minDistance = distance
		}
	}

	xRelClosest = (*country.bodiesOrig)[closestIndex].X
	yRelClosest = (*country.bodiesOrig)[closestIndex].Y

	latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)

	Info.Printf("ClosestBodyInOriginalPosition %f %f relative to country %f %f", lat, lng, xRel, yRel)
	Info.Printf("ClosestBodyInOriginalPosition rel closest %f %f lat lng closest %f %f", xRelClosest, yRelClosest, latOptimClosest, lngOptimClosest)

	// compute x, y in spread bodies
	xSpread = (*country.bodiesSpread)[closestIndex].X
	ySpread = (*country.bodiesSpread)[closestIndex].Y

	Info.Printf("ClosestBodyInOriginalPosition village %f %f index %d", xSpread, ySpread, closestIndex)

	return xRelClosest, yRelClosest, minDistance, latOptimClosest, lngOptimClosest, xSpread, ySpread, closestIndex
}

func (country *Country) XYSpreadToLatLngOrig(x, y float64) (lat, lng float64) {

	Info.Printf("XYSpreadToLatLngOrig input x %f y %f", x, y)

	// parse all bodies and get closest body
	closestIndex := -1
	minDistance := 1000000000.0 // we start from away
	for index, b := range *country.bodiesSpread {
		distanceX := b.X - x
		distanceY := b.Y - y
		distance := math.Sqrt((distanceX * distanceX) + (distanceY * distanceY))

		if distance < minDistance {
			closestIndex = index
			minDistance = distance
		}
	}

	xRelClosest := (*country.bodiesOrig)[closestIndex].X
	yRelClosest := (*country.bodiesOrig)[closestIndex].Y
	latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)
	Info.Printf("XYSpreadToLatLngOrig target x %f y %f index %d distance %f", xRelClosest, yRelClosest, closestIndex, minDistance)

	Info.Printf("XYSpreadToLatLngOrig target lat %f lng %f", latOptimClosest, lngOptimClosest)

	return latOptimClosest, lngOptimClosest
}

// get the bodies of a village from x, y spread coordinates
func (country *Country) XYSpreadToTerritoryBorder(x, y float64) PointList {

	Info.Printf("XYSpreadToTerritoryBorder Country %s x %f y %f", country.Name, x, y)

	points := make(PointList, 0)

	// compute village min & max coord
	xMinVillage := float64(int(x*numberOfVillagePerAxe)) / numberOfVillagePerAxe
	xMaxVillage := float64(int(x*numberOfVillagePerAxe+1.0)) / numberOfVillagePerAxe
	yMinVillage := float64(int(y*numberOfVillagePerAxe)) / numberOfVillagePerAxe
	yMaxVillage := float64(int(y*numberOfVillagePerAxe+1.0)) / numberOfVillagePerAxe

	Info.Printf("XYSpreadToTerritoryBorder input village Min x %f Max x %f", xMinVillage, xMaxVillage)

	// parse all bodies and get closest body
	for index, b := range *country.bodiesSpread {
		if (xMinVillage <= b.X) && (b.X < xMaxVillage) && (yMinVillage <= b.Y) && (b.Y < yMaxVillage) {

			xRelClosest := (*country.bodiesOrig)[index].X
			yRelClosest := (*country.bodiesOrig)[index].Y
			latOptimClosest, lngOptimClosest := country.XY2LatLng(xRelClosest, yRelClosest)

			points = append(points, MakePoint(latOptimClosest, lngOptimClosest))
			Info.Printf("XYSpreadToTerritoryBorder %f %f", latOptimClosest, lngOptimClosest)
		}
	}

	Info.Printf("XYSpreadToTerritoryBorder Country %s nb bodies in village %d", country.Name, len(points))
	return points
}

// given x, y of a point, return the border in the country
func (country *Country) LatLngToTerritoryBorder(lat, lng float64) PointList {

	Info.Printf("")
	Info.Printf("LatLngToTerritoryBorder country %s input lat %f lng %f", country.Name, lat, lng)

	// from input lat, lng, get the xSpread, ySpread
	_, _, _, _, _, xSpread, ySpread, _ := country.ClosestBodyInOriginalPosition(lat, lng)
	Info.Printf("LatLngToTerritoryBorder country %s input xSpread %f ySpread %f", country.Name, xSpread, ySpread)

	points := country.XYSpreadToTerritoryBorder(xSpread, ySpread)

	Info.Printf("LatLngToTerritoryBorder nb of border points %d", len(points))
	Info.Printf("")

	return points
}
<|endoftext|>


<commit_before>// Copyright 2017 The Ebiten 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.

// +build js

package mp3

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"time"

	"github.com/gopherjs/gopherjs/js"
	"github.com/hajimehoshi/ebiten/audio"
)

// TODO: This just uses decodeAudioData, that can treat audio files other than MP3.

type Stream struct {
	leftData   []float32
	rightData  []float32
	posInBytes int
}

var (
	errTryAgain = errors.New("audio/mp3: try again")
	errTimeout  = errors.New("audio/mp3: timeout")
)

func (s *Stream) Read(b []byte) (int, error) {
	l := len(s.leftData)*4 - s.posInBytes
	if l > len(b) {
		l = len(b)
	}
	l = l / 4 * 4
	const max = 1<<15 - 1
	for i := 0; i < l/4; i++ {
		il := int32(s.leftData[s.posInBytes/4+i] * max)
		if il > max {
			il = max
		}
		if il < -max {
			il = -max
		}
		ir := int32(s.rightData[s.posInBytes/4+i] * max)
		if ir > max {
			ir = max
		}
		if ir < -max {
			ir = -max
		}
		b[4*i] = byte(il)
		b[4*i+1] = byte(il >> 8)
		b[4*i+2] = byte(ir)
		b[4*i+3] = byte(ir >> 8)
	}
	s.posInBytes += l
	if s.posInBytes == len(s.leftData)*4 {
		return l, io.EOF
	}
	return l, nil
}

func (s *Stream) Seek(offset int64, whence int) (int64, error) {
	next := int64(0)
	switch whence {
	case io.SeekStart:
		next = offset
	case io.SeekCurrent:
		next = int64(s.posInBytes) + offset
	case io.SeekEnd:
		next = s.Size() + offset
	}
	s.posInBytes = int(next)
	return next, nil
}

func (s *Stream) Close() error {
	return nil
}

func (s *Stream) Size() int64 {
	return int64(len(s.leftData) * 4)
}

// seekNextFrame seeks the next frame and returns the new buffer with the new position.
// seekNextFrame also returns true when seeking is successful, or false otherwise.
//
// Seeking is necessary when decoding fails. Safari's MP3 decoder can't treat IDs well (#438).
func seekNextFrame(buf []byte) ([]byte, bool) {
	// TODO: Need to skip tags explicitly? (hajimehoshi/go-mp3#9)

	if len(buf) < 1 {
		return nil, false
	}
	buf = buf[1:]

	for {
		if buf[0] == 0xff && buf[1]&0xfe == 0xfe {
			break
		}
		buf = buf[1:]
		if len(buf) < 2 {
			return nil, false
		}
	}
	return buf, true
}

func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
	b, err := ioutil.ReadAll(src)
	if err != nil {
		return nil, err
	}
	if err := src.Close(); err != nil {
		return nil, err
	}
	var s *Stream
	for {
		s, err = decode(context, b)
		switch err {
		case errTryAgain:
			buf, ok := seekNextFrame(b)
			if !ok {
				return nil, fmt.Errorf("audio/mp3: Decode failed: invalid format?")
			}
			b = buf
			continue
		case errTimeout:
			continue
		default:
			if err != nil {
				return nil, err
			}
		}
		break
	}
	return s, nil
}

var offlineAudioContextClass *js.Object

func init() {
	if klass := js.Global.Get("OfflineAudioContext"); klass != js.Undefined {
		offlineAudioContextClass = klass
		return
	}
	if klass := js.Global.Get("webkitOfflineAudioContext"); klass != js.Undefined {
		offlineAudioContextClass = klass
		return
	}
}

func decode(context *audio.Context, buf []byte) (*Stream, error) {
	if offlineAudioContextClass == nil {
		return nil, errors.New("audio/mp3: OfflineAudioContext is not available")
	}

	s := &Stream{}
	ch := make(chan error)

	// TODO: webkitOfflineAudioContext's constructor might causes 'Syntax' error
	// when the sample rate is not so usual like 22050 on Safari.
	// Should this be handled before calling this?

	// TODO: 1 is a correct second argument?
	oc := offlineAudioContextClass.New(2, 1, context.SampleRate())
	oc.Call("decodeAudioData", js.NewArrayBuffer(buf), func(buf *js.Object) {
		s.leftData = buf.Call("getChannelData", 0).Interface().([]float32)
		switch n := buf.Get("numberOfChannels").Int(); n {
		case 1:
			s.rightData = s.leftData
			close(ch)
		case 2:
			s.rightData = buf.Call("getChannelData", 1).Interface().([]float32)
			close(ch)
		default:
			ch <- fmt.Errorf("audio/mp3: number of channels must be 1 or 2 but %d", n)
		}
	}, func(err *js.Object) {
		if err != nil {
			ch <- fmt.Errorf("audio/mp3: decodeAudioData failed: %v", err)
		} else {
			// On Safari, error value might be null and it is needed to retry decoding
			// from the next frame (#438).
			ch <- errTryAgain
		}
	})

	select {
	case err := <-ch:
		if err != nil {
			return nil, err
		}
	case <-time.After(3 * time.Second):
		// Sometimes decode fails without calling the callbacks (#464).
		// Let's just try again in this case.
		return nil, errTimeout
	}
	return s, nil
}
<commit_msg>audio/mp3: Flexible timeout<commit_after>// Copyright 2017 The Ebiten 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.

// +build js

package mp3

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"time"

	"github.com/gopherjs/gopherjs/js"
	"github.com/hajimehoshi/ebiten/audio"
)

// TODO: This just uses decodeAudioData, that can treat audio files other than MP3.

type Stream struct {
	leftData   []float32
	rightData  []float32
	posInBytes int
}

var (
	errTryAgain = errors.New("audio/mp3: try again")
	errTimeout  = errors.New("audio/mp3: timeout")
)

func (s *Stream) Read(b []byte) (int, error) {
	l := len(s.leftData)*4 - s.posInBytes
	if l > len(b) {
		l = len(b)
	}
	l = l / 4 * 4
	const max = 1<<15 - 1
	for i := 0; i < l/4; i++ {
		il := int32(s.leftData[s.posInBytes/4+i] * max)
		if il > max {
			il = max
		}
		if il < -max {
			il = -max
		}
		ir := int32(s.rightData[s.posInBytes/4+i] * max)
		if ir > max {
			ir = max
		}
		if ir < -max {
			ir = -max
		}
		b[4*i] = byte(il)
		b[4*i+1] = byte(il >> 8)
		b[4*i+2] = byte(ir)
		b[4*i+3] = byte(ir >> 8)
	}
	s.posInBytes += l
	if s.posInBytes == len(s.leftData)*4 {
		return l, io.EOF
	}
	return l, nil
}

func (s *Stream) Seek(offset int64, whence int) (int64, error) {
	next := int64(0)
	switch whence {
	case io.SeekStart:
		next = offset
	case io.SeekCurrent:
		next = int64(s.posInBytes) + offset
	case io.SeekEnd:
		next = s.Size() + offset
	}
	s.posInBytes = int(next)
	return next, nil
}

func (s *Stream) Close() error {
	return nil
}

func (s *Stream) Size() int64 {
	return int64(len(s.leftData) * 4)
}

// seekNextFrame seeks the next frame and returns the new buffer with the new position.
// seekNextFrame also returns true when seeking is successful, or false otherwise.
//
// Seeking is necessary when decoding fails. Safari's MP3 decoder can't treat IDs well (#438).
func seekNextFrame(buf []byte) ([]byte, bool) {
	// TODO: Need to skip tags explicitly? (hajimehoshi/go-mp3#9)

	if len(buf) < 1 {
		return nil, false
	}
	buf = buf[1:]

	for {
		if buf[0] == 0xff && buf[1]&0xfe == 0xfe {
			break
		}
		buf = buf[1:]
		if len(buf) < 2 {
			return nil, false
		}
	}
	return buf, true
}

func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
	b, err := ioutil.ReadAll(src)
	if err != nil {
		return nil, err
	}
	if err := src.Close(); err != nil {
		return nil, err
	}
	var s *Stream
	try := 0
	for {
		s, err = decode(context, b, try)
		switch err {
		case errTryAgain:
			buf, ok := seekNextFrame(b)
			if !ok {
				return nil, fmt.Errorf("audio/mp3: Decode failed: invalid format?")
			}
			b = buf
			continue
		case errTimeout:
			try++
			continue
		default:
			if err != nil {
				return nil, err
			}
		}
		break
	}
	return s, nil
}

var offlineAudioContextClass *js.Object

func init() {
	if klass := js.Global.Get("OfflineAudioContext"); klass != js.Undefined {
		offlineAudioContextClass = klass
		return
	}
	if klass := js.Global.Get("webkitOfflineAudioContext"); klass != js.Undefined {
		offlineAudioContextClass = klass
		return
	}
}

func decode(context *audio.Context, buf []byte, try int) (*Stream, error) {
	if offlineAudioContextClass == nil {
		return nil, errors.New("audio/mp3: OfflineAudioContext is not available")
	}

	s := &Stream{}
	ch := make(chan error)

	// TODO: webkitOfflineAudioContext's constructor might causes 'Syntax' error
	// when the sample rate is not so usual like 22050 on Safari.
	// Should this be handled before calling this?

	// TODO: 1 is a correct second argument?
	oc := offlineAudioContextClass.New(2, 1, context.SampleRate())
	oc.Call("decodeAudioData", js.NewArrayBuffer(buf), func(buf *js.Object) {
		s.leftData = buf.Call("getChannelData", 0).Interface().([]float32)
		switch n := buf.Get("numberOfChannels").Int(); n {
		case 1:
			s.rightData = s.leftData
			close(ch)
		case 2:
			s.rightData = buf.Call("getChannelData", 1).Interface().([]float32)
			close(ch)
		default:
			ch <- fmt.Errorf("audio/mp3: number of channels must be 1 or 2 but %d", n)
		}
	}, func(err *js.Object) {
		if err != nil {
			ch <- fmt.Errorf("audio/mp3: decodeAudioData failed: %v", err)
		} else {
			// On Safari, error value might be null and it is needed to retry decoding
			// from the next frame (#438).
			ch <- errTryAgain
		}
	})

	timeout := time.Duration(math.Pow(2, float64(try))) * time.Second

	select {
	case err := <-ch:
		if err != nil {
			return nil, err
		}
	case <-time.After(timeout):
		// Sometimes decode fails without calling the callbacks (#464).
		// Let's just try again in this case.
		return nil, errTimeout
	}
	return s, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcchain

import (
	"fmt"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwire"
)

const CheckpointConfirmations = 2016

// A checkpoint is a known good point in the block chain.  Using checkpoints
// allows a few optimizations for old blocks during initial download and also
// prevents forks from old blocks.
//
// Each checkpoint is selected by the core developers based upon several
// factors.  See the documentation for IsCheckpointCandidate for details
// on the selection criteria.
//
// As alluded to above, this package provides an IsCheckpointCandidate function
// which programatically identifies a block as a checkpoint candidate.  The idea
// is that candidates are reviewed by a developer to make the final decision and
// then manually added to the list of checkpoints.
type Checkpoint struct {
	Height int64
	Hash   *btcwire.ShaHash
}

// checkpointData groups checkpoints and other pertinent checkpoint data into
// a single type.
type checkpointData struct {
	// Checkpoints ordered from oldest to newest.
	checkpoints []Checkpoint

	// A map that will be automatically generated with the heights from
	// the checkpoints as keys.
	checkpointsByHeight map[int64]*Checkpoint
}

// checkpointDataMainNet contains checkpoint data for the main network.
var checkpointDataMainNet = checkpointData{
	checkpoints: []Checkpoint{
		{11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")},
		{33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")},
		{74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")},
		{105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")},
		{134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")},
		{168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")},
		{193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")},
		{210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")},
		{216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")},
		{225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")},
	},
	checkpointsByHeight: nil, // Automatically generated in init.
}

// checkpointDataTestNet contains checkpoint data for the test network.
var checkpointDataTestNet = checkpointData{
	checkpoints: []Checkpoint{
		{546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
	},
	checkpointsByHeight: nil, // Automatically generated in init.
}

// newShaHashFromStr converts the passed big-endian hex string into a
// btcwire.ShaHash.  It only differs from the one available in btcwire in that
// it ignores the error since it will only (and must only) be called with
// hard-coded, and therefore known good, hashes.
func newShaHashFromStr(hexStr string) *btcwire.ShaHash {
	sha, _ := btcwire.NewShaHashFromStr(hexStr)
	return sha
}

// DisableCheckpoints provides a mechanism to disable validation against
// checkpoints which you DO NOT want to do in production.  It is provided only
// for debug purposes.
func (b *BlockChain) DisableCheckpoints(disable bool) {
	b.noCheckpoints = disable
}

// checkpointData returns the appropriate checkpoint data set depending on the
// network configured for the block chain.
func (b *BlockChain) checkpointData() *checkpointData {
	switch b.btcnet {
	case btcwire.TestNet3:
		return &checkpointDataTestNet
	case btcwire.MainNet:
		fallthrough
	default:
		return &checkpointDataMainNet
	}
}

// LatestCheckpoint returns the most recent checkpoint (regardless of whether it
// is already known).  When checkpoints are disabled it will return nil.
func (b *BlockChain) LatestCheckpoint() *Checkpoint {
	if b.noCheckpoints {
		return nil
	}

	checkpoints := b.checkpointData().checkpoints
	return &checkpoints[len(checkpoints)-1]
}

// verifyCheckpoint returns whether the passed block height and hash combination
// match the hard-coded checkpoint data.  It also returns true if there is no
// checkpoint data for the passed block height.
func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool {
	if b.noCheckpoints {
		return true
	}

	// Nothing to check if there is no checkpoint data for the block height.
	checkpoint, exists := b.checkpointData().checkpointsByHeight[height]
	if !exists {
		return true
	}

	return checkpoint.Hash.IsEqual(hash)
}

// findClosestKnownCheckpoint finds the most recent checkpoint that is already
// available in the downloaded portion of the block chain and returns the
// associated block.  It returns nil if a checkpoint can't be found (this should
// really only happen for blocks before the first checkpoint).
func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) {
	if b.noCheckpoints {
		return nil, nil
	}

	// Loop backwards through the available checkpoints to find one that
	// we already have.
	checkpoints := b.checkpointData().checkpoints
	clen := len(checkpoints)
	for i := clen - 1; i >= 0; i-- {
		if b.db.ExistsSha(checkpoints[i].Hash) {
			block, err := b.db.FetchBlockBySha(checkpoints[i].Hash)
			if err != nil {
				return nil, err
			}
			return block, nil
		}
	}
	return nil, nil
}

// isNonstandardTransaction determines whether a transaction contains any
// scripts which are not one of the standard types.
func isNonstandardTransaction(tx *btcwire.MsgTx) bool {
	// TODO(davec): Should there be checks for the input signature scripts?

	// Check all of the output public key scripts for non-standard scripts.
	for _, txOut := range tx.TxOut {
		scriptClass := btcscript.GetScriptClass(txOut.PkScript)
		if scriptClass == btcscript.NonStandardTy {
			return true
		}
	}
	return false
}

// IsCheckpointCandidate returns whether or not the passed block is a good
// checkpoint candidate.
//
// The factors used to determine a good checkpoint are:
//  - The block must be in the main chain
//  - The block must be at least 'CheckpointConfirmations' blocks prior to the
//    current end of the main chain
//  - The timestamps for the blocks before and after the checkpoint must have
//    timestamps which are also before and after the checkpoint, respectively
//    (due to the median time allowance this is not always the case)
//  - The block must not contain any strange transaction such as those with
//    nonstandard scripts
func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) {
	// Checkpoints must be enabled.
	if b.noCheckpoints {
		return false, fmt.Errorf("checkpoints are disabled")
	}

	blockHash, err := block.Sha()
	if err != nil {
		return false, err
	}

	// A checkpoint must be in the main chain.
	if !b.db.ExistsSha(blockHash) {
		return false, nil
	}

	// A checkpoint must be at least CheckpointConfirmations blocks before
	// the end of the main chain.
	blockHeight := block.Height()
	_, mainChainHeight, err := b.db.NewestSha()
	if err != nil {
		return false, err
	}
	if blockHeight > (mainChainHeight - CheckpointConfirmations) {
		return false, nil
	}

	// Get the previous block.
	prevHash := &block.MsgBlock().Header.PrevBlock
	prevBlock, err := b.db.FetchBlockBySha(prevHash)
	if err != nil {
		return false, err
	}

	// Get the next block.
	nextHash, err := b.db.FetchBlockShaByHeight(blockHeight + 1)
	if err != nil {
		return false, err
	}
	nextBlock, err := b.db.FetchBlockBySha(nextHash)
	if err != nil {
		return false, err
	}

	// A checkpoint must have timestamps for the block and the blocks on
	// either side of it in order (due to the median time allowance this is
	// not always the case).
	prevTime := prevBlock.MsgBlock().Header.Timestamp
	curTime := block.MsgBlock().Header.Timestamp
	nextTime := nextBlock.MsgBlock().Header.Timestamp
	if prevTime.After(curTime) || nextTime.Before(curTime) {
		return false, nil
	}

	// A checkpoint must have transactions that only contain standard
	// scripts.
	for _, tx := range block.MsgBlock().Transactions {
		if isNonstandardTransaction(tx) {
			return false, nil
		}
	}

	return true, nil
}

// init is called on package load.
func init() {
	// Generate the checkpoint by height maps from the checkpoint data
	// when the package loads.
	checkpointInitializeList := []*checkpointData{
		&checkpointDataMainNet,
		&checkpointDataTestNet,
	}
	for _, data := range checkpointInitializeList {
		data.checkpointsByHeight = make(map[int64]*Checkpoint)
		for i := range data.checkpoints {
			checkpoint := &data.checkpoints[i]
			data.checkpointsByHeight[checkpoint.Height] = checkpoint
		}
	}
}
<commit_msg>Comment CheckpointConfirmations.<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcchain

import (
	"fmt"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwire"
)

// CheckpointConfirmations is the number of blocks before the end of the current
// best block chain that a good checkpoint candidate must be.
const CheckpointConfirmations = 2016

// A checkpoint is a known good point in the block chain.  Using checkpoints
// allows a few optimizations for old blocks during initial download and also
// prevents forks from old blocks.
//
// Each checkpoint is selected by the core developers based upon several
// factors.  See the documentation for IsCheckpointCandidate for details
// on the selection criteria.
//
// As alluded to above, this package provides an IsCheckpointCandidate function
// which programatically identifies a block as a checkpoint candidate.  The idea
// is that candidates are reviewed by a developer to make the final decision and
// then manually added to the list of checkpoints.
type Checkpoint struct {
	Height int64
	Hash   *btcwire.ShaHash
}

// checkpointData groups checkpoints and other pertinent checkpoint data into
// a single type.
type checkpointData struct {
	// Checkpoints ordered from oldest to newest.
	checkpoints []Checkpoint

	// A map that will be automatically generated with the heights from
	// the checkpoints as keys.
	checkpointsByHeight map[int64]*Checkpoint
}

// checkpointDataMainNet contains checkpoint data for the main network.
var checkpointDataMainNet = checkpointData{
	checkpoints: []Checkpoint{
		{11111, newShaHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")},
		{33333, newShaHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")},
		{74000, newShaHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")},
		{105000, newShaHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")},
		{134444, newShaHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")},
		{168000, newShaHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")},
		{193000, newShaHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")},
		{210000, newShaHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")},
		{216116, newShaHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")},
		{225430, newShaHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")},
	},
	checkpointsByHeight: nil, // Automatically generated in init.
}

// checkpointDataTestNet contains checkpoint data for the test network.
var checkpointDataTestNet = checkpointData{
	checkpoints: []Checkpoint{
		{546, newShaHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
	},
	checkpointsByHeight: nil, // Automatically generated in init.
}

// newShaHashFromStr converts the passed big-endian hex string into a
// btcwire.ShaHash.  It only differs from the one available in btcwire in that
// it ignores the error since it will only (and must only) be called with
// hard-coded, and therefore known good, hashes.
func newShaHashFromStr(hexStr string) *btcwire.ShaHash {
	sha, _ := btcwire.NewShaHashFromStr(hexStr)
	return sha
}

// DisableCheckpoints provides a mechanism to disable validation against
// checkpoints which you DO NOT want to do in production.  It is provided only
// for debug purposes.
func (b *BlockChain) DisableCheckpoints(disable bool) {
	b.noCheckpoints = disable
}

// checkpointData returns the appropriate checkpoint data set depending on the
// network configured for the block chain.
func (b *BlockChain) checkpointData() *checkpointData {
	switch b.btcnet {
	case btcwire.TestNet3:
		return &checkpointDataTestNet
	case btcwire.MainNet:
		fallthrough
	default:
		return &checkpointDataMainNet
	}
}

// LatestCheckpoint returns the most recent checkpoint (regardless of whether it
// is already known).  When checkpoints are disabled it will return nil.
func (b *BlockChain) LatestCheckpoint() *Checkpoint {
	if b.noCheckpoints {
		return nil
	}

	checkpoints := b.checkpointData().checkpoints
	return &checkpoints[len(checkpoints)-1]
}

// verifyCheckpoint returns whether the passed block height and hash combination
// match the hard-coded checkpoint data.  It also returns true if there is no
// checkpoint data for the passed block height.
func (b *BlockChain) verifyCheckpoint(height int64, hash *btcwire.ShaHash) bool {
	if b.noCheckpoints {
		return true
	}

	// Nothing to check if there is no checkpoint data for the block height.
	checkpoint, exists := b.checkpointData().checkpointsByHeight[height]
	if !exists {
		return true
	}

	return checkpoint.Hash.IsEqual(hash)
}

// findClosestKnownCheckpoint finds the most recent checkpoint that is already
// available in the downloaded portion of the block chain and returns the
// associated block.  It returns nil if a checkpoint can't be found (this should
// really only happen for blocks before the first checkpoint).
func (b *BlockChain) findLatestKnownCheckpoint() (*btcutil.Block, error) {
	if b.noCheckpoints {
		return nil, nil
	}

	// Loop backwards through the available checkpoints to find one that
	// we already have.
	checkpoints := b.checkpointData().checkpoints
	clen := len(checkpoints)
	for i := clen - 1; i >= 0; i-- {
		if b.db.ExistsSha(checkpoints[i].Hash) {
			block, err := b.db.FetchBlockBySha(checkpoints[i].Hash)
			if err != nil {
				return nil, err
			}
			return block, nil
		}
	}
	return nil, nil
}

// isNonstandardTransaction determines whether a transaction contains any
// scripts which are not one of the standard types.
func isNonstandardTransaction(tx *btcwire.MsgTx) bool {
	// TODO(davec): Should there be checks for the input signature scripts?

	// Check all of the output public key scripts for non-standard scripts.
	for _, txOut := range tx.TxOut {
		scriptClass := btcscript.GetScriptClass(txOut.PkScript)
		if scriptClass == btcscript.NonStandardTy {
			return true
		}
	}
	return false
}

// IsCheckpointCandidate returns whether or not the passed block is a good
// checkpoint candidate.
//
// The factors used to determine a good checkpoint are:
//  - The block must be in the main chain
//  - The block must be at least 'CheckpointConfirmations' blocks prior to the
//    current end of the main chain
//  - The timestamps for the blocks before and after the checkpoint must have
//    timestamps which are also before and after the checkpoint, respectively
//    (due to the median time allowance this is not always the case)
//  - The block must not contain any strange transaction such as those with
//    nonstandard scripts
func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error) {
	// Checkpoints must be enabled.
	if b.noCheckpoints {
		return false, fmt.Errorf("checkpoints are disabled")
	}

	blockHash, err := block.Sha()
	if err != nil {
		return false, err
	}

	// A checkpoint must be in the main chain.
	if !b.db.ExistsSha(blockHash) {
		return false, nil
	}

	// A checkpoint must be at least CheckpointConfirmations blocks before
	// the end of the main chain.
	blockHeight := block.Height()
	_, mainChainHeight, err := b.db.NewestSha()
	if err != nil {
		return false, err
	}
	if blockHeight > (mainChainHeight - CheckpointConfirmations) {
		return false, nil
	}

	// Get the previous block.
	prevHash := &block.MsgBlock().Header.PrevBlock
	prevBlock, err := b.db.FetchBlockBySha(prevHash)
	if err != nil {
		return false, err
	}

	// Get the next block.
	nextHash, err := b.db.FetchBlockShaByHeight(blockHeight + 1)
	if err != nil {
		return false, err
	}
	nextBlock, err := b.db.FetchBlockBySha(nextHash)
	if err != nil {
		return false, err
	}

	// A checkpoint must have timestamps for the block and the blocks on
	// either side of it in order (due to the median time allowance this is
	// not always the case).
	prevTime := prevBlock.MsgBlock().Header.Timestamp
	curTime := block.MsgBlock().Header.Timestamp
	nextTime := nextBlock.MsgBlock().Header.Timestamp
	if prevTime.After(curTime) || nextTime.Before(curTime) {
		return false, nil
	}

	// A checkpoint must have transactions that only contain standard
	// scripts.
	for _, tx := range block.MsgBlock().Transactions {
		if isNonstandardTransaction(tx) {
			return false, nil
		}
	}

	return true, nil
}

// init is called on package load.
func init() {
	// Generate the checkpoint by height maps from the checkpoint data
	// when the package loads.
	checkpointInitializeList := []*checkpointData{
		&checkpointDataMainNet,
		&checkpointDataTestNet,
	}
	for _, data := range checkpointInitializeList {
		data.checkpointsByHeight = make(map[int64]*Checkpoint)
		for i := range data.checkpoints {
			checkpoint := &data.checkpoints[i]
			data.checkpointsByHeight[checkpoint.Height] = checkpoint
		}
	}
}
<|endoftext|>


<commit_before>// +build integration

package felixcheck_test

import (
	"fmt"
	"os"
	"testing"

	"net/http"
	"net/http/httptest"

	"github.com/streadway/amqp"

	. "github.com/aleasoluciones/felixcheck"
	"github.com/stretchr/testify/assert"
)

func TestHttpCheckerWithHttpServerUp(t *testing.T) {
	t.Parallel()

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, client")
	}))
	defer ts.Close()

	check := NewHttpChecker("host", "service", ts.URL, 200)
	checkResult := check()

	assert.Equal(t, "ok", checkResult.State)
}

func TestHttpCheckerWithServerDown(t *testing.T) {
	t.Parallel()

	check := NewHttpChecker("host", "service", "https://unknownurl/", 200)
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func amqpUrlFromEnv() string {
	url := os.Getenv("AMQP_URL")
	if url == "" {
		url = "amqp://"
	}
	return url
}

func publishMessage(ch *amqp.Channel, exchange, routingKey, text string) {
	ch.Publish(
		exchange,
		routingKey,
		false,
		false,
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "application/json",
			ContentEncoding: "",
			Body:            []byte(text),
			DeliveryMode:    amqp.Transient,
			Priority:        0,
		})

}

func TestRabbitMQQueueLenCheck(t *testing.T) {
	t.Parallel()
	amqpUrl := amqpUrlFromEnv()
	queue := "q"
	exchange := "e"
	routingKey := "r"

	conn, _ := amqp.Dial(amqpUrl)
	ch, _ := conn.Channel()
	defer conn.Close()
	defer ch.Close()

	ch.ExchangeDeclare(exchange, "topic", true, false, false, false, nil)
	ch.QueueDelete(queue, false, false, true)
	ch.QueueDeclare(queue, false, false, false, false, nil)
	ch.QueueBind(queue, "#", exchange, false, nil)

	check := NewRabbitMQQueueLenCheck("host", "service", amqpUrl, queue, 2)
	checkResult := check()
	assert.Equal(t, "ok", checkResult.State)
	assert.Equal(t, float32(0), checkResult.Metric)

	publishMessage(ch, exchange, routingKey, "msg1")
	publishMessage(ch, exchange, routingKey, "msg2")

	checkResult = check()
	assert.Equal(t, "ok", checkResult.State)
	assert.Equal(t, float32(2), checkResult.Metric)

	publishMessage(ch, exchange, routingKey, "msg3")
	checkResult = check()
	assert.Equal(t, "critical", checkResult.State)
	assert.Equal(t, float32(3), checkResult.Metric)

}

func TestRabbitMQQueueLenCheckReturnsCriticalWhenCantConnectToRabbitMQ(t *testing.T) {
	t.Parallel()

	check := NewRabbitMQQueueLenCheck("host", "service", amqpUrlFromEnv()+"whatever", "queue", 2)
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func TestMysqlConnectionErrorCheck(t *testing.T) {
	t.Parallel()

	check := NewMysqlConnectionCheck("host", "service", "mysql://nohost/nodb")
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func TestMysqlConnectionOkCheck(t *testing.T) {
	t.Parallel()

	check := NewMysqlConnectionCheck("host", "service", os.Getenv("MYSQL_URL"))
	checkResult := check()

	assert.Equal(t, "ok", checkResult.State)
}
<commit_msg>Reformat<commit_after>// +build integration

package felixcheck_test

import (
	"fmt"
	"os"
	"testing"

	"net/http"
	"net/http/httptest"

	"github.com/streadway/amqp"

	. "github.com/aleasoluciones/felixcheck"
	"github.com/stretchr/testify/assert"
)

func TestHttpCheckerWithHttpServerUp(t *testing.T) {
	t.Parallel()

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, client")
	}))
	defer ts.Close()

	check := NewHttpChecker("host", "service", ts.URL, 200)
	checkResult := check()

	assert.Equal(t, "ok", checkResult.State)
}

func TestHttpCheckerWithServerDown(t *testing.T) {
	t.Parallel()

	check := NewHttpChecker("host", "service", "https://unknownurl/", 200)
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func amqpUrlFromEnv() string {
	url := os.Getenv("AMQP_URL")
	if url == "" {
		url = "amqp://"
	}
	return url
}

func publishMessage(ch *amqp.Channel, exchange, routingKey, text string) {
	ch.Publish(
		exchange,
		routingKey,
		false,
		false,
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "application/json",
			ContentEncoding: "",
			Body:            []byte(text),
			DeliveryMode:    amqp.Transient,
			Priority:        0,
		})

}

func TestRabbitMQQueueLenCheck(t *testing.T) {
	t.Parallel()
	amqpUrl := amqpUrlFromEnv()
	queue := "q"
	exchange := "e"
	routingKey := "r"

	conn, _ := amqp.Dial(amqpUrl)
	ch, _ := conn.Channel()
	defer conn.Close()
	defer ch.Close()

	ch.ExchangeDeclare(exchange, "topic", true, false, false, false, nil)
	ch.QueueDelete(queue, false, false, true)
	ch.QueueDeclare(queue, false, false, false, false, nil)
	ch.QueueBind(queue, "#", exchange, false, nil)

	check := NewRabbitMQQueueLenCheck("host", "service", amqpUrl, queue, 2)
	checkResult := check()
	assert.Equal(t, "ok", checkResult.State)
	assert.Equal(t, float32(0), checkResult.Metric)

	publishMessage(ch, exchange, routingKey, "msg1")
	publishMessage(ch, exchange, routingKey, "msg2")

	checkResult = check()
	assert.Equal(t, "ok", checkResult.State)
	assert.Equal(t, float32(2), checkResult.Metric)

	publishMessage(ch, exchange, routingKey, "msg3")
	checkResult = check()

	assert.Equal(t, "critical", checkResult.State)
	assert.Equal(t, float32(3), checkResult.Metric)
}

func TestRabbitMQQueueLenCheckReturnsCriticalWhenCantConnectToRabbitMQ(t *testing.T) {
	t.Parallel()

	check := NewRabbitMQQueueLenCheck("host", "service", amqpUrlFromEnv()+"whatever", "queue", 2)
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func TestMysqlConnectionErrorCheck(t *testing.T) {
	t.Parallel()

	check := NewMysqlConnectionCheck("host", "service", "mysql://nohost/nodb")
	checkResult := check()

	assert.Equal(t, "critical", checkResult.State)
}

func TestMysqlConnectionOkCheck(t *testing.T) {
	t.Parallel()

	check := NewMysqlConnectionCheck("host", "service", os.Getenv("MYSQL_URL"))
	checkResult := check()

	assert.Equal(t, "ok", checkResult.State)
}
<|endoftext|>


<commit_before>package oauth2

import (
	"bytes"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"

	"github.com/hooklift/oauth2/providers/test"
)

func setupTest(isUserAuthenticated bool) (Provider, *config) {
	provider := test.NewProvider(isUserAuthenticated)
	tpl := `

		{{if .Errors}}

				{{range .Errors}}

{{.Code}}: {{.Desc}}

				{{end}}

		{{else}}
			<form>
			 <input type="hidden" name="client_id" value="{{.Client.ID}}"/>
			 <input type="hidden" name="response_type" value="{{.GrantType}}"/>
			 <input type="hidden" name="redirect_uri" value="{{.Client.RedirectURL}}"/>
			 <input type="hidden" name="scope" value="{{StringifyScopes .Scopes}}"/>
			 <input type="hidden" name="state" value="{{.State}}"/>
			</form>
		{{end}}

	`

	cfg := &config{
		tokenEndpoint:  "/oauth2/tokens",
		authzEndpoint:  "/oauth2/authzs",
		revokeEndpoint: "/oauth2/revoke",
	}

	SetProvider(provider)(cfg)
	SetAuthzForm(tpl)(cfg)

	return provider, cfg
}

// TestAuthorizationGrant tests a happy web authorization flow in accordance with
// http://tools.ietf.org/html/rfc6749#section-4.1
func TestAuthorizationGrant(t *testing.T) {
	provider, cfg := setupTest(true)

	state := "state-test"
	scopes := "read write identity"
	grantType := "code"

	values := url.Values{
		"client_id":     {provider.(*test.Provider).Client.ID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {provider.(*test.Provider).Client.RedirectURL.String()},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.1.1
	queryStr := values.Encode()
	req, err := http.NewRequest("GET",
		"https://example.com/oauth2/authzs?"+queryStr, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	equals(t, http.StatusOK, w.Code)

	body := w.Body.String()
	stringz := []string{
		"client_id",
		"redirect_uri",
		"response_type",
		"state",
		"scope",
		"code",
		"read write identity",
		"state-test",
	}

	for _, s := range stringz {
		assert(t, strings.Contains(body, s), "Does not look like we got an authorization form: '%s' was not found in %v", s, body)
	}

	// Sending post to acquire authorization token
	buffer := bytes.NewBufferString(queryStr)
	req, err = http.NewRequest("POST", "https://example.com/oauth2/authzs", buffer)
	ok(t, err)

	req.Header.Set("Content-type", "application/x-www-form-urlencoded")

	w = httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)

	// Tests http://tools.ietf.org/html/rfc6749#section-4.1.2
	equals(t, http.StatusFound, w.Code)

	redirectTo := w.Header().Get("Location")
	url, err := url.Parse(redirectTo)
	ok(t, err)

	authzCode := url.Query().Get("code")
	assert(t, authzCode != "", "It looks like the authorization code came back empty: %s", authzCode)
	equals(t, state, url.Query().Get("state"))
}

// TestLoginRedirect tests that logging in is required for a resource owner to
// grant any authorization codes to clients.
func TestLoginRedirect(t *testing.T) {
	provider, cfg := setupTest(false)

	state := "state-test"
	scopes := "read write identity"
	grantType := "code"
	clientID := provider.(*test.Provider).Client.ID
	redirectURL := provider.(*test.Provider).Client.RedirectURL.String()

	values := url.Values{
		"client_id":     {clientID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {redirectURL},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.1.1
	queryStr := values.Encode()
	authzURL := "https://example.com/oauth2/authzs?" + queryStr
	req, err := http.NewRequest("GET", authzURL, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	equals(t, http.StatusFound, w.Code)
	equals(t, provider.LoginURL(authzURL), w.Header().Get("Location"))
}

// TestImplicitGrant tests a happy implicit flow
func TestImplicitGrant(t *testing.T) {
	provider, cfg := setupTest(true)

	state := "state-test"
	scopes := "read write identity"
	grantType := "token"
	clientID := provider.(*test.Provider).Client.ID
	redirectURL := provider.(*test.Provider).Client.RedirectURL.String()

	values := url.Values{
		"client_id":     {clientID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {redirectURL},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.2.1
	queryStr := values.Encode()
	authzURL := "https://example.com/oauth2/authzs?" + queryStr
	req, err := http.NewRequest("GET", authzURL, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	body := w.Body.String()
	stringz := []string{
		"client_id",
		"redirect_uri",
		"response_type",
		"state",
		"scope",
		"token",
		"read write identity",
		"state-test",
	}

	for _, s := range stringz {
		assert(t, strings.Contains(body, s), "Does not look like we got an authorization form: '%s' was not found in %v", s, body)
	}

	// Sending post to acquire authorization token
	buffer := bytes.NewBufferString(queryStr)
	req, err = http.NewRequest("POST", "https://example.com/oauth2/authzs", buffer)
	ok(t, err)

	req.Header.Set("Content-type", "application/x-www-form-urlencoded")

	w = httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)

	// Tests http://tools.ietf.org/html/rfc6749#section-4.2.2
	equals(t, http.StatusFound, w.Code)

	redirectTo := w.Header().Get("Location")
	u, err := url.Parse(redirectTo)
	ok(t, err)

	fragment, err := url.ParseQuery(strings.TrimPrefix(u.Fragment, "#"))
	ok(t, err)
	accessToken := fragment.Get("access_token")
	assert(t, accessToken != "", "It looks like the authorization code came back empty: ->%s<-", accessToken)
	equals(t, state, fragment.Get("state"))
	equals(t, "600", fragment.Get("expires_in"))
	equals(t, scopes, fragment.Get("scope"))
	equals(t, "bearer", fragment.Get("token_type"))

	// Implict flow should not emit refresh tokens
	refreshToken := fragment.Get("refresh_token")
	equals(t, "", refreshToken)
}

// TestAuthzGrantExpiration makes sure that authorization codes are actually expired after used.
func TestAuthzGrantExpiration(t *testing.T) {

}

// TestReplayAttackMitigation tests that the authorization grant can be used
// only once, and that if there are attempts to use it multiple times, it is
// revoked along with all the access tokens generated with it.
func TestReplayAttackMitigation(t *testing.T) {

}

// TestRedirectURLMatch makes sure redirect_uri for requesting an authorization
// grant is the same as the redirect_uri provided to get the correspondent access token.
// This is intended to mitigate the risk of account hijacking by leaking
// authorization codes.
func TestRedirectURLMatch(t *testing.T) {

}

// TestAccessTokenIssuer makes sure a token belongs to the client_id making
// the request with it. This mitigates account hijacking as well.
func TestAccessTokenOwnership(t *testing.T) {

}

// TestAccessTokenExpiration makes sure that access tokens are actually expired.
func TestAccessTokenExpiration(t *testing.T) {

}

// TestScopeIsRequired makes sure it requires clients to provide access scopes.
func TestScopeIsRequired(t *testing.T) {

}

// TestStateIsRequired makes sure it requires clients to provide a state.
func TestStateIsRequired(t *testing.T) {

}

// TestSecurityHeaders makes sure security headers are sent along the authorization form.
func TestSecurityHeaders(t *testing.T) {

}

// TestRedirectURIScheme makes sure clients provide redirect URLs that use TLS
func TestRedirectURIScheme(t *testing.T) {

}

// TestRedirectURIUniqueness makes sure there is only one redirect URL registered across the system.
func TestRedirectURIUniqueness(t *testing.T) {

}

// TestStateParam makes sure the same state parameter value received to acquire
// the authorization grant is send back when delivering the access token.
func TestStateParam(t *testing.T) {

}
<commit_msg>Adds comment for setupTest function<commit_after>package oauth2

import (
	"bytes"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"testing"

	"github.com/hooklift/oauth2/providers/test"
)

// setupTest creates an instance of our test provider and sets up configuration
// settings.
func setupTest(isUserAuthenticated bool) (Provider, *config) {
	provider := test.NewProvider(isUserAuthenticated)
	tpl := `

		{{if .Errors}}

				{{range .Errors}}

{{.Code}}: {{.Desc}}

				{{end}}

		{{else}}
			<form>
			 <input type="hidden" name="client_id" value="{{.Client.ID}}"/>
			 <input type="hidden" name="response_type" value="{{.GrantType}}"/>
			 <input type="hidden" name="redirect_uri" value="{{.Client.RedirectURL}}"/>
			 <input type="hidden" name="scope" value="{{StringifyScopes .Scopes}}"/>
			 <input type="hidden" name="state" value="{{.State}}"/>
			</form>
		{{end}}

	`

	cfg := &config{
		tokenEndpoint:  "/oauth2/tokens",
		authzEndpoint:  "/oauth2/authzs",
		revokeEndpoint: "/oauth2/revoke",
	}

	SetProvider(provider)(cfg)
	SetAuthzForm(tpl)(cfg)

	return provider, cfg
}

// TestAuthorizationGrant tests a happy web authorization flow in accordance with
// http://tools.ietf.org/html/rfc6749#section-4.1
func TestAuthorizationGrant(t *testing.T) {
	provider, cfg := setupTest(true)

	state := "state-test"
	scopes := "read write identity"
	grantType := "code"

	values := url.Values{
		"client_id":     {provider.(*test.Provider).Client.ID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {provider.(*test.Provider).Client.RedirectURL.String()},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.1.1
	queryStr := values.Encode()
	req, err := http.NewRequest("GET",
		"https://example.com/oauth2/authzs?"+queryStr, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	equals(t, http.StatusOK, w.Code)

	body := w.Body.String()
	stringz := []string{
		"client_id",
		"redirect_uri",
		"response_type",
		"state",
		"scope",
		"code",
		"read write identity",
		"state-test",
	}

	for _, s := range stringz {
		assert(t, strings.Contains(body, s), "Does not look like we got an authorization form: '%s' was not found in %v", s, body)
	}

	// Sending post to acquire authorization token
	buffer := bytes.NewBufferString(queryStr)
	req, err = http.NewRequest("POST", "https://example.com/oauth2/authzs", buffer)
	ok(t, err)

	req.Header.Set("Content-type", "application/x-www-form-urlencoded")

	w = httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)

	// Tests http://tools.ietf.org/html/rfc6749#section-4.1.2
	equals(t, http.StatusFound, w.Code)

	redirectTo := w.Header().Get("Location")
	url, err := url.Parse(redirectTo)
	ok(t, err)

	authzCode := url.Query().Get("code")
	assert(t, authzCode != "", "It looks like the authorization code came back empty: %s", authzCode)
	equals(t, state, url.Query().Get("state"))
}

// TestLoginRedirect tests that logging in is required for a resource owner to
// grant any authorization codes to clients.
func TestLoginRedirect(t *testing.T) {
	provider, cfg := setupTest(false)

	state := "state-test"
	scopes := "read write identity"
	grantType := "code"
	clientID := provider.(*test.Provider).Client.ID
	redirectURL := provider.(*test.Provider).Client.RedirectURL.String()

	values := url.Values{
		"client_id":     {clientID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {redirectURL},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.1.1
	queryStr := values.Encode()
	authzURL := "https://example.com/oauth2/authzs?" + queryStr
	req, err := http.NewRequest("GET", authzURL, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	equals(t, http.StatusFound, w.Code)
	equals(t, provider.LoginURL(authzURL), w.Header().Get("Location"))
}

// TestImplicitGrant tests a happy implicit flow
func TestImplicitGrant(t *testing.T) {
	provider, cfg := setupTest(true)

	state := "state-test"
	scopes := "read write identity"
	grantType := "token"
	clientID := provider.(*test.Provider).Client.ID
	redirectURL := provider.(*test.Provider).Client.RedirectURL.String()

	values := url.Values{
		"client_id":     {clientID},
		"response_type": {grantType},
		"state":         {state},
		"redirect_uri":  {redirectURL},
		"scope":         {scopes},
	}

	// http://tools.ietf.org/html/rfc6749#section-4.2.1
	queryStr := values.Encode()
	authzURL := "https://example.com/oauth2/authzs?" + queryStr
	req, err := http.NewRequest("GET", authzURL, nil)
	ok(t, err)

	w := httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)
	body := w.Body.String()
	stringz := []string{
		"client_id",
		"redirect_uri",
		"response_type",
		"state",
		"scope",
		"token",
		"read write identity",
		"state-test",
	}

	for _, s := range stringz {
		assert(t, strings.Contains(body, s), "Does not look like we got an authorization form: '%s' was not found in %v", s, body)
	}

	// Sending post to acquire authorization token
	buffer := bytes.NewBufferString(queryStr)
	req, err = http.NewRequest("POST", "https://example.com/oauth2/authzs", buffer)
	ok(t, err)

	req.Header.Set("Content-type", "application/x-www-form-urlencoded")

	w = httptest.NewRecorder()
	CreateGrant(w, req, cfg, nil)

	// Tests http://tools.ietf.org/html/rfc6749#section-4.2.2
	equals(t, http.StatusFound, w.Code)

	redirectTo := w.Header().Get("Location")
	u, err := url.Parse(redirectTo)
	ok(t, err)

	fragment, err := url.ParseQuery(strings.TrimPrefix(u.Fragment, "#"))
	ok(t, err)
	accessToken := fragment.Get("access_token")
	assert(t, accessToken != "", "It looks like the authorization code came back empty: ->%s<-", accessToken)
	equals(t, state, fragment.Get("state"))
	equals(t, "600", fragment.Get("expires_in"))
	equals(t, scopes, fragment.Get("scope"))
	equals(t, "bearer", fragment.Get("token_type"))

	// Implict flow should not emit refresh tokens
	refreshToken := fragment.Get("refresh_token")
	equals(t, "", refreshToken)
}

// TestAuthzGrantExpiration makes sure that authorization codes are actually expired after used.
func TestAuthzGrantExpiration(t *testing.T) {

}

// TestReplayAttackMitigation tests that the authorization grant can be used
// only once, and that if there are attempts to use it multiple times, it is
// revoked along with all the access tokens generated with it.
func TestReplayAttackMitigation(t *testing.T) {

}

// TestRedirectURLMatch makes sure redirect_uri for requesting an authorization
// grant is the same as the redirect_uri provided to get the correspondent access token.
// This is intended to mitigate the risk of account hijacking by leaking
// authorization codes.
func TestRedirectURLMatch(t *testing.T) {

}

// TestAccessTokenIssuer makes sure a token belongs to the client_id making
// the request with it. This mitigates account hijacking as well.
func TestAccessTokenOwnership(t *testing.T) {

}

// TestAccessTokenExpiration makes sure that access tokens are actually expired.
func TestAccessTokenExpiration(t *testing.T) {

}

// TestScopeIsRequired makes sure it requires clients to provide access scopes.
func TestScopeIsRequired(t *testing.T) {

}

// TestStateIsRequired makes sure it requires clients to provide a state.
func TestStateIsRequired(t *testing.T) {

}

// TestSecurityHeaders makes sure security headers are sent along the authorization form.
func TestSecurityHeaders(t *testing.T) {

}

// TestRedirectURIScheme makes sure clients provide redirect URLs that use TLS
func TestRedirectURIScheme(t *testing.T) {

}

// TestRedirectURIUniqueness makes sure there is only one redirect URL registered across the system.
func TestRedirectURIUniqueness(t *testing.T) {

}

// TestStateParam makes sure the same state parameter value received to acquire
// the authorization grant is send back when delivering the access token.
func TestStateParam(t *testing.T) {

}
<|endoftext|>


<commit_before>package mock

import (
	"errors"
	"sync"

	"github.com/micro/go-micro/transport"
)

type mockSocket struct {
	recv chan *transport.Message
	send chan *transport.Message
	// sock exit
	exit chan bool
	// listener exit
	lexit chan bool
}

type mockClient struct {
	*mockSocket
	opts transport.DialOptions
}

type mockListener struct {
	addr string
	exit chan bool
	conn chan *mockSocket
	opts transport.ListenOptions
}

type mockTransport struct {
	opts transport.Options

	sync.Mutex
	listeners map[string]*mockListener
}

func (ms *mockSocket) Recv(m *transport.Message) error {
	select {
	case <-ms.exit:
		return errors.New("connection closed")
	case <-ms.lexit:
		return errors.New("server connection closed")
	case cm := <-ms.recv:
		*m = *cm
	}
	return nil
}

func (ms *mockSocket) Send(m *transport.Message) error {
	select {
	case <-ms.exit:
		return errors.New("connection closed")
	case <-ms.lexit:
		return errors.New("server connection closed")
	case ms.send <- m:
	}
	return nil
}

func (ms *mockSocket) Close() error {
	close(ms.exit)
	return nil
}

func (m *mockListener) Addr() string {
	return m.addr
}

func (m *mockListener) Close() error {
	close(m.exit)
	return nil
}

func (m *mockListener) Accept(fn func(transport.Socket)) error {
	for {
		select {
		case <-m.exit:
			return nil
		case c := <-m.conn:
			go fn(&mockSocket{
				lexit: make(chan bool),
				exit:  c.exit,
				send:  c.recv,
				recv:  c.send,
			})
		}
	}
	return nil
}

func (m *mockTransport) Dial(addr string, opts ...transport.DialOption) (transport.Client, error) {
	m.Lock()
	defer m.Unlock()

	listener, ok := m.listeners[addr]
	if !ok {
		return nil, errors.New("could not dial " + addr)
	}

	var options transport.DialOptions
	for _, o := range opts {
		o(&options)
	}

	client := &mockClient{
		&mockSocket{
			send:  make(chan *transport.Message),
			recv:  make(chan *transport.Message),
			exit:  make(chan bool),
			lexit: listener.exit,
		},
		options,
	}

	// pseudo connect
	select {
	case <-listener.exit:
		return nil, errors.New("connection error")
	case listener.conn <- client.mockSocket:
	}

	return client, nil
}

func (m *mockTransport) Listen(addr string, opts ...transport.ListenOption) (transport.Listener, error) {
	m.Lock()
	defer m.Unlock()

	if _, ok := m.listeners[addr]; ok {
		return nil, errors.New("already listening on " + addr)
	}

	var options transport.ListenOptions
	for _, o := range opts {
		o(&options)
	}

	listener := &mockListener{
		opts: options,
		addr: addr,
		conn: make(chan *mockSocket),
		exit: make(chan bool),
	}

	m.listeners[addr] = listener

	return listener, nil
}

func (m *mockTransport) String() string {
	return "mock"
}

func NewTransport(opts ...transport.Option) transport.Transport {
	var options transport.Options
	for _, o := range opts {
		o(&options)
	}

	return &mockTransport{
		opts:      options,
		listeners: make(map[string]*mockListener),
	}
}
<commit_msg>That should be a listener exit<commit_after>package mock

import (
	"errors"
	"sync"

	"github.com/micro/go-micro/transport"
)

type mockSocket struct {
	recv chan *transport.Message
	send chan *transport.Message
	// sock exit
	exit chan bool
	// listener exit
	lexit chan bool
}

type mockClient struct {
	*mockSocket
	opts transport.DialOptions
}

type mockListener struct {
	addr string
	exit chan bool
	conn chan *mockSocket
	opts transport.ListenOptions
}

type mockTransport struct {
	opts transport.Options

	sync.Mutex
	listeners map[string]*mockListener
}

func (ms *mockSocket) Recv(m *transport.Message) error {
	select {
	case <-ms.exit:
		return errors.New("connection closed")
	case <-ms.lexit:
		return errors.New("server connection closed")
	case cm := <-ms.recv:
		*m = *cm
	}
	return nil
}

func (ms *mockSocket) Send(m *transport.Message) error {
	select {
	case <-ms.exit:
		return errors.New("connection closed")
	case <-ms.lexit:
		return errors.New("server connection closed")
	case ms.send <- m:
	}
	return nil
}

func (ms *mockSocket) Close() error {
	close(ms.exit)
	return nil
}

func (m *mockListener) Addr() string {
	return m.addr
}

func (m *mockListener) Close() error {
	close(m.exit)
	return nil
}

func (m *mockListener) Accept(fn func(transport.Socket)) error {
	for {
		select {
		case <-m.exit:
			return nil
		case c := <-m.conn:
			go fn(&mockSocket{
				lexit: c.lexit,
				exit:  c.exit,
				send:  c.recv,
				recv:  c.send,
			})
		}
	}
	return nil
}

func (m *mockTransport) Dial(addr string, opts ...transport.DialOption) (transport.Client, error) {
	m.Lock()
	defer m.Unlock()

	listener, ok := m.listeners[addr]
	if !ok {
		return nil, errors.New("could not dial " + addr)
	}

	var options transport.DialOptions
	for _, o := range opts {
		o(&options)
	}

	client := &mockClient{
		&mockSocket{
			send:  make(chan *transport.Message),
			recv:  make(chan *transport.Message),
			exit:  make(chan bool),
			lexit: listener.exit,
		},
		options,
	}

	// pseudo connect
	select {
	case <-listener.exit:
		return nil, errors.New("connection error")
	case listener.conn <- client.mockSocket:
	}

	return client, nil
}

func (m *mockTransport) Listen(addr string, opts ...transport.ListenOption) (transport.Listener, error) {
	m.Lock()
	defer m.Unlock()

	if _, ok := m.listeners[addr]; ok {
		return nil, errors.New("already listening on " + addr)
	}

	var options transport.ListenOptions
	for _, o := range opts {
		o(&options)
	}

	listener := &mockListener{
		opts: options,
		addr: addr,
		conn: make(chan *mockSocket),
		exit: make(chan bool),
	}

	m.listeners[addr] = listener

	return listener, nil
}

func (m *mockTransport) String() string {
	return "mock"
}

func NewTransport(opts ...transport.Option) transport.Transport {
	var options transport.Options
	for _, o := range opts {
		o(&options)
	}

	return &mockTransport{
		opts:      options,
		listeners: make(map[string]*mockListener),
	}
}
<|endoftext|>