<commit_before>package ole

var (
	// IID_NULL is null Interface ID, used when no other Interface ID is known.
	IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}

	// IID_IUnknown is for IUnknown interfaces.
	IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IDispatch is for IDispatch interfaces.
	IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IConnectionPointContainer is for IConnectionPointContainer interfaces.
	IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IConnectionPoint is for IConnectionPoint interfaces.
	IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IInspectable is for IInspectable interfaces.
	IID_IInspectable = &GUID{0xaf86e2e0, 0xb12d, 0x4c6a, [8]byte{0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90}}

	// IID_IProvideClassInfo is for IProvideClassInfo interfaces.
	IID_IProvideClassInfo = &GUID{0xb196b283, 0xbab4, 0x101a, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
)

// These are for testing and not part of any library.
var (
	// IID_ICOMTestString is for ICOMTestString interfaces.
	//
	// {E0133EB4-C36F-469A-9D3D-C66B84BE19ED}
	IID_ICOMTestString = &GUID{0xe0133eb4, 0xc36f, 0x469a, [8]byte{0x9d, 0x3d, 0xc6, 0x6b, 0x84, 0xbe, 0x19, 0xed}}

	// IID_ICOMTestInt8 is for ICOMTestInt8 interfaces.
	//
	// {BEB06610-EB84-4155-AF58-E2BFF53608B4}
	IID_ICOMTestInt8 = &GUID{0xbeb06610, 0xeb84, 0x4155, [8]byte{0xaf, 0x58, 0xe2, 0xbf, 0xf5, 0x36, 0x80, 0xb4}}

	// IID_ICOMTestInt16 is for ICOMTestInt16 interfaces.
	//
	// {DAA3F9FA-761E-4976-A860-8364CE55F6FC}
	IID_ICOMTestInt16 = &GUID{0xdaa3f9fa, 0x761e, 0x4976, [8]byte{0xa8, 0x60, 0x83, 0x64, 0xce, 0x55, 0xf6, 0xfc}}

	// IID_ICOMTestInt32 is for ICOMTestInt32 interfaces.
	//
	// {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}
	IID_ICOMTestInt32 = &GUID{0xe3dedee7, 0x38a2, 0x4540, [8]byte{0x91, 0xd1, 0x2e, 0xef, 0x1d, 0x88, 0x91, 0xb0}}

	// IID_ICOMTestInt64 is for ICOMTestInt64 interfaces.
	//
	// {8D437CBC-B3ED-485C-BC32-C336432A1623}
	IID_ICOMTestInt64 = &GUID{0x8d437cbc, 0xb3ed, 0x485c, [8]byte{0xbc, 0x32, 0xc3, 0x36, 0x43, 0x2a, 0x16, 0x23}}

	// IID_ICOMTestFloat is for ICOMTestFloat interfaces.
	//
	// {BF1ED004-EA02-456A-AA55-2AC8AC6B054C}
	IID_ICOMTestFloat = &GUID{0xbf1ed004, 0xea02, 0x456a, [8]byte{0xaa, 0x55, 0x2a, 0xc8, 0xac, 0x6b, 0x5, 0x4c}}

	// IID_ICOMTestDouble is for ICOMTestDouble interfaces.
	//
	// {BF908A81-8687-4E93-999F-D86FAB284BA0}
	IID_ICOMTestDouble = &GUID{0xbf908a81, 0x8687, 0x4e93, [8]byte{0x99, 0x9f, 0xd8, 0x6f, 0xab, 0x28, 0x4b, 0xa0}}

	// IID_ICOMTestBoolean is for ICOMTestBoolean interfaces.
	//
	// {D530E7A6-4EE8-40D1-8931-3D63B8605001}
	IID_ICOMTestBoolean = &GUID{0xd530e7a6, 0x4ee8, 0x40d1, [8]byte{0x89, 0x31, 0x3d, 0x63, 0xb8, 0x60, 0x50, 0x10}}

	// IID_ICOMTestObject is for ICOMTestObject interfaces.
	//
	// {6485B1EF-D780-4834-A4FE-1EBB51746CA3}
	IID_ICOMTestObject = &GUID{0x6485b1ef, 0xd780, 0x4834, [8]byte{0xa4, 0xfe, 0x1e, 0xbb, 0x51, 0x74, 0x6c, 0xa3}}

	// IID_ICOMTestTypes is for ICOMTestTypes interfaces.
	//
	// {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}
	IID_ICOMTestTypes = &GUID{0xcca8d7ae, 0x91c0, 0x4277, [8]byte{0xa8, 0xb3, 0xff, 0x4e, 0xdf, 0x28, 0xd3, 0xc0}}

	// CLSID_COMTestScalarClass is for COMTestScalarClass class.
	//
	// {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}
	CLSID_COMTestScalarClass = &GUID{0x865b85c5, 0x3340, 0x4ac6, [8]byte{0x9e, 0xf6, 0xaa, 0xce, 0xc8, 0xfc, 0x5e, 0x86}}
)

// GUID is Windows API specific GUID type.
//
// This exists to match Windows GUID type for direct passing for COM.
// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

// IsEqualGUID compares two GUID.
//
// Not constant time comparison.
func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool {
	return guid1.Data1 == guid2.Data1 &&
		guid1.Data2 == guid2.Data2 &&
		guid1.Data3 == guid2.Data3 &&
		guid1.Data4[0] == guid2.Data4[0] &&
		guid1.Data4[1] == guid2.Data4[1] &&
		guid1.Data4[2] == guid2.Data4[2] &&
		guid1.Data4[3] == guid2.Data4[3] &&
		guid1.Data4[4] == guid2.Data4[4] &&
		guid1.Data4[5] == guid2.Data4[5] &&
		guid1.Data4[6] == guid2.Data4[6] &&
		guid1.Data4[7] == guid2.Data4[7]
}
<commit_msg>Add new test class and fix reference to old test class.<commit_after>package ole

var (
	// IID_NULL is null Interface ID, used when no other Interface ID is known.
	IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}

	// IID_IUnknown is for IUnknown interfaces.
	IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IDispatch is for IDispatch interfaces.
	IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}

	// IID_IConnectionPointContainer is for IConnectionPointContainer interfaces.
	IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IConnectionPoint is for IConnectionPoint interfaces.
	IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}

	// IID_IInspectable is for IInspectable interfaces.
	IID_IInspectable = &GUID{0xaf86e2e0, 0xb12d, 0x4c6a, [8]byte{0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90}}

	// IID_IProvideClassInfo is for IProvideClassInfo interfaces.
	IID_IProvideClassInfo = &GUID{0xb196b283, 0xbab4, 0x101a, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
)

// These are for testing and not part of any library.
var (
	// IID_ICOMTestString is for ICOMTestString interfaces.
	//
	// {E0133EB4-C36F-469A-9D3D-C66B84BE19ED}
	IID_ICOMTestString = &GUID{0xe0133eb4, 0xc36f, 0x469a, [8]byte{0x9d, 0x3d, 0xc6, 0x6b, 0x84, 0xbe, 0x19, 0xed}}

	// IID_ICOMTestInt8 is for ICOMTestInt8 interfaces.
	//
	// {BEB06610-EB84-4155-AF58-E2BFF53608B4}
	IID_ICOMTestInt8 = &GUID{0xbeb06610, 0xeb84, 0x4155, [8]byte{0xaf, 0x58, 0xe2, 0xbf, 0xf5, 0x36, 0x80, 0xb4}}

	// IID_ICOMTestInt16 is for ICOMTestInt16 interfaces.
	//
	// {DAA3F9FA-761E-4976-A860-8364CE55F6FC}
	IID_ICOMTestInt16 = &GUID{0xdaa3f9fa, 0x761e, 0x4976, [8]byte{0xa8, 0x60, 0x83, 0x64, 0xce, 0x55, 0xf6, 0xfc}}

	// IID_ICOMTestInt32 is for ICOMTestInt32 interfaces.
	//
	// {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}
	IID_ICOMTestInt32 = &GUID{0xe3dedee7, 0x38a2, 0x4540, [8]byte{0x91, 0xd1, 0x2e, 0xef, 0x1d, 0x88, 0x91, 0xb0}}

	// IID_ICOMTestInt64 is for ICOMTestInt64 interfaces.
	//
	// {8D437CBC-B3ED-485C-BC32-C336432A1623}
	IID_ICOMTestInt64 = &GUID{0x8d437cbc, 0xb3ed, 0x485c, [8]byte{0xbc, 0x32, 0xc3, 0x36, 0x43, 0x2a, 0x16, 0x23}}

	// IID_ICOMTestFloat is for ICOMTestFloat interfaces.
	//
	// {BF1ED004-EA02-456A-AA55-2AC8AC6B054C}
	IID_ICOMTestFloat = &GUID{0xbf1ed004, 0xea02, 0x456a, [8]byte{0xaa, 0x55, 0x2a, 0xc8, 0xac, 0x6b, 0x5, 0x4c}}

	// IID_ICOMTestDouble is for ICOMTestDouble interfaces.
	//
	// {BF908A81-8687-4E93-999F-D86FAB284BA0}
	IID_ICOMTestDouble = &GUID{0xbf908a81, 0x8687, 0x4e93, [8]byte{0x99, 0x9f, 0xd8, 0x6f, 0xab, 0x28, 0x4b, 0xa0}}

	// IID_ICOMTestBoolean is for ICOMTestBoolean interfaces.
	//
	// {D530E7A6-4EE8-40D1-8931-3D63B8605001}
	IID_ICOMTestBoolean = &GUID{0xd530e7a6, 0x4ee8, 0x40d1, [8]byte{0x89, 0x31, 0x3d, 0x63, 0xb8, 0x60, 0x50, 0x10}}

	// IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces.
	//
	// {6485B1EF-D780-4834-A4FE-1EBB51746CA3}
	IID_ICOMEchoTestObject = &GUID{0x6485b1ef, 0xd780, 0x4834, [8]byte{0xa4, 0xfe, 0x1e, 0xbb, 0x51, 0x74, 0x6c, 0xa3}}

	// IID_ICOMTestTypes is for ICOMTestTypes interfaces.
	//
	// {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}
	IID_ICOMTestTypes = &GUID{0xcca8d7ae, 0x91c0, 0x4277, [8]byte{0xa8, 0xb3, 0xff, 0x4e, 0xdf, 0x28, 0xd3, 0xc0}}

	// CLSID_COMEchoTestObject is for COMEchoTestObject class.
	//
	// {3C24506A-AE9E-4D50-9157-EF317281F1B0}
	CLSID_COMEchoTestObject = &GUID{0x3c24506a, 0xae9e, 0x4d50, [8]byte{0x91, 0x57, 0xef, 0x31, 0x72, 0x81, 0xf1, 0xb00}};

	// CLSID_COMTestScalarClass is for COMTestScalarClass class.
	//
	// {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}
	CLSID_COMTestScalarClass = &GUID{0x865b85c5, 0x3340, 0x4ac6, [8]byte{0x9e, 0xf6, 0xaa, 0xce, 0xc8, 0xfc, 0x5e, 0x86}}
)

// GUID is Windows API specific GUID type.
//
// This exists to match Windows GUID type for direct passing for COM.
// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

// IsEqualGUID compares two GUID.
//
// Not constant time comparison.
func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool {
	return guid1.Data1 == guid2.Data1 &&
		guid1.Data2 == guid2.Data2 &&
		guid1.Data3 == guid2.Data3 &&
		guid1.Data4[0] == guid2.Data4[0] &&
		guid1.Data4[1] == guid2.Data4[1] &&
		guid1.Data4[2] == guid2.Data4[2] &&
		guid1.Data4[3] == guid2.Data4[3] &&
		guid1.Data4[4] == guid2.Data4[4] &&
		guid1.Data4[5] == guid2.Data4[5] &&
		guid1.Data4[6] == guid2.Data4[6] &&
		guid1.Data4[7] == guid2.Data4[7]
}
<|endoftext|>


<commit_before><commit_msg>[process/test] Fix regexp for windows.<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package wallet

import (
	"encoding/hex"
	"fmt"
	"os"

	"github.com/FactomProject/factom"
	"github.com/FactomProject/factomd/common/directoryBlock"
	"github.com/FactomProject/factomd/common/factoid"
	"github.com/FactomProject/factomd/common/interfaces"
	"github.com/FactomProject/factomd/common/primitives"
	"github.com/FactomProject/factomd/database/databaseOverlay"
	"github.com/FactomProject/factomd/database/hybridDB"
	"github.com/FactomProject/factomd/database/mapdb"
)

// Database keys and key prefixes
var (
	fblockDBPrefix = []byte("FBlock")
)

type TXDatabaseOverlay struct {
	DBO databaseOverlay.Overlay

	// To indicate to sub processes to quit
	quit bool
}

func NewTXOverlay(db interfaces.IDatabase) *TXDatabaseOverlay {
	answer := new(TXDatabaseOverlay)
	answer.DBO.DB = db
	return answer
}

func NewTXMapDB() *TXDatabaseOverlay {
	return NewTXOverlay(new(mapdb.MapDB))
}

func NewTXLevelDB(ldbpath string) (*TXDatabaseOverlay, error) {
	db, err := hybridDB.NewLevelMapHybridDB(ldbpath, false)
	if err != nil {
		fmt.Printf("err opening transaction db: %v\n", err)
	}

	if db == nil {
		fmt.Println("Creating new transaction db ...")
		db, err = hybridDB.NewLevelMapHybridDB(ldbpath, true)

		if err != nil {
			return nil, err
		}
	}
	fmt.Println("Transaction database started from: " + ldbpath)
	return NewTXOverlay(db), nil
}

func NewTXBoltDB(boltPath string) (*TXDatabaseOverlay, error) {
	fileInfo, err := os.Stat(boltPath)
	if err == nil {
		if fileInfo.IsDir() {
			return nil, fmt.Errorf("%s is not a Bolt databse file", boltPath)
		}
	}
	if err != nil && !os.IsNotExist(err) {
		fmt.Printf("database error %s\n", err)
		return nil, err
	}

	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("Could not use wallet cache database file \"%s\"\n%v\n", boltPath, r)
			os.Exit(1)
		}
	}()
	db := hybridDB.NewBoltMapHybridDB(nil, boltPath)

	fmt.Println("Database started from: " + boltPath)
	return NewTXOverlay(db), nil
}

func (db *TXDatabaseOverlay) Close() error {
	db.quit = true
	return db.DBO.Close()
}

// GetAllTXs returns a list of all transactions in the history of Factom. A
// local database is used to cache the factoid blocks.
func (db *TXDatabaseOverlay) GetAllTXs() ([]interfaces.ITransaction, error) {
	// update the database and get the newest fblock
	_, err := db.Update()
	if err != nil {
		return nil, err
	}
	fblock, err := db.DBO.FetchFBlockHead()
	if err != nil {
		return nil, err
	}
	if fblock == nil {
		return nil, fmt.Errorf("FBlock Chain has not finished syncing")
	}
	txs := make([]interfaces.ITransaction, 0)

	for {
		// get all of the txs from the block
		height := fblock.GetDatabaseHeight()
		for _, tx := range fblock.GetTransactions() {
			ins, err := tx.TotalInputs()
			if err != nil {
				return nil, err
			}
			outs, err := tx.TotalOutputs()
			if err != nil {
				return nil, err
			}

			if ins != 0 || outs != 0 {
				tx.SetBlockHeight(height)
				txs = append(txs, tx)
			}
		}

		if pre := fblock.GetPrevKeyMR().String(); pre != factom.ZeroHash {
			// get the previous block
			fblock, err = db.GetFBlock(pre)
			if err != nil {
				return nil, err
			} else if fblock == nil {
				return nil, fmt.Errorf("Missing fblock in database: %s", pre)
			}
		} else {
			break
		}
	}

	return txs, nil
}

// GetTX gets a transaction by the transaction id
func (db *TXDatabaseOverlay) GetTX(txid string) (interfaces.ITransaction, error) {
	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	for _, tx := range txs {
		if tx.GetSigHash().String() == txid {
			return tx, nil
		}
	}

	return nil, fmt.Errorf("Transaction not found")
}

// GetTXAddress returns a list of all transactions in the history of Factom that
// include a specific address.
func (db *TXDatabaseOverlay) GetTXAddress(adr string) (
	[]interfaces.ITransaction, error) {
	filtered := make([]interfaces.ITransaction, 0)

	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	if factom.AddressStringType(adr) == factom.FactoidPub {
		for _, tx := range txs {
			for _, in := range tx.GetInputs() {
				if primitives.ConvertFctAddressToUserStr(in.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
			for _, out := range tx.GetOutputs() {
				if primitives.ConvertFctAddressToUserStr(out.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
		}
	} else if factom.AddressStringType(adr) == factom.ECPub {
		for _, tx := range txs {
			for _, out := range tx.GetECOutputs() {
				if primitives.ConvertECAddressToUserStr(out.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
		}
	} else {
		return nil, fmt.Errorf("not a valid address")
	}

	return filtered, nil
}

func (db *TXDatabaseOverlay) GetTXRange(start, end int) (
	[]interfaces.ITransaction, error) {
	if start < 0 || end < 0 {
		return nil, fmt.Errorf("Range cannot have negative numbers")
	}
	s, e := uint32(start), uint32(end)

	filtered := make([]interfaces.ITransaction, 0)

	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	for _, tx := range txs {
		if s <= tx.GetBlockHeight() && tx.GetBlockHeight() <= e {
			filtered = append(filtered, tx)
		}
	}

	return filtered, nil
}

// GetFBlock retrives a Factoid Block from Factom
func (db *TXDatabaseOverlay) GetFBlock(keymr string) (interfaces.IFBlock, error) {
	h, err := primitives.NewShaHashFromStr(keymr)
	if err != nil {
		return nil, err
	}

	fBlock, err := db.DBO.FetchFBlock(h)
	if err != nil {
		return nil, err
	}
	return fBlock, nil
}

func (db *TXDatabaseOverlay) FetchNextFBlockHeight() (uint32, error) {
	block, err := db.DBO.FetchFBlockHead()
	if err != nil {
		return 0, err
	}
	if block == nil {
		return 0, nil
	}
	return block.GetDBHeight() + 1, nil
}

func (db *TXDatabaseOverlay) InsertFBlockHead(fblock interfaces.IFBlock) error {
	return db.DBO.SaveFactoidBlockHead(fblock)
}

// Update gets all fblocks written since the database was last updated, and
// returns the most recent fblock keymr.
func (db *TXDatabaseOverlay) Update() (string, error) {
	newestFBlock, err := fblockHead()
	if err != nil {
		return "", err
	}

	start, err := db.FetchNextFBlockHeight()
	if err != nil {
		return "", err
	}

	// Make sure we didn't switch networks
	genesis, err := db.DBO.FetchFBlockByHeight(0)
	if err != nil {
		return "", err
	}
	if genesis != nil {
		genesis2, err := getdblockbyheight(0)
		if err != nil {
			return "", err
		}

		var gensisFBlockKeyMr interfaces.IHash
		for _, e := range genesis2.GetDBEntries() {
			if e.GetChainID().String() == "000000000000000000000000000000000000000000000000000000000000000f" {
				gensisFBlockKeyMr = e.GetKeyMR()
				break
			}
		}

		if gensisFBlockKeyMr == nil {
			return "", fmt.Errorf("unable to fetch the genesis block via the api")
		}

		if !gensisFBlockKeyMr.IsSameAs(genesis.GetKeyMR()) {
			start = 0
		}
	}

	newestHeight := newestFBlock.GetDatabaseHeight()

	// If the newest block in the tx cashe has a greater height than the newest
	// fblock then clear the cashe and start from 0.
	if start >= newestHeight {
		db.DBO.Clear(databaseOverlay.FACTOIDBLOCK)
		return newestFBlock.GetKeyMR().String(), nil
	}

	// If the latest block from the database is not available from the blockchain
	// then clear the cashe and start from 0.
	if f, err := getfblockbyheight(start); err != nil {
		db.DBO.Clear(databaseOverlay.FACTOIDBLOCK)
		return f.GetKeyMR().String(), err
	}

	db.DBO.StartMultiBatch()
	for i := start; i <= newestHeight; i++ {
		if i%1000 == 0 {
			if newestHeight-start > 1000 {
				fmt.Printf("Fetching block %v/%v\n", i, newestHeight)
			}
		}
		fblock, err := getfblockbyheight(i)
		if err != nil {
			db.DBO.ExecuteMultiBatch()
			return "", err
		}
		db.DBO.ProcessFBlockMultiBatch(fblock)

		// Save to DB every 500 blocks
		if i%500 == 0 {
			db.DBO.ExecuteMultiBatch()
			db.DBO.StartMultiBatch()
		}

		// If the wallet is stopped, this process becomes hard to kill. Have it exit
		if db.quit {
			break
		}
	}

	if !db.quit {
		fmt.Printf("Fetching block %v/%v\n", newestHeight, newestHeight)
	}

	// Save the remaining blocks
	if err = db.DBO.ExecuteMultiBatch(); err != nil {
		return "", err
	}

	return newestFBlock.GetKeyMR().String(), nil
}

// fblockHead gets the most recent fblock.
func fblockHead() (interfaces.IFBlock, error) {
	fblockID := "000000000000000000000000000000000000000000000000000000000000000f"

	dbhead, err := factom.GetDBlockHead()
	if err != nil {
		return nil, err
	}
	dblock, err := factom.GetDBlock(dbhead)
	if err != nil {
		return nil, err
	}

	var fblockmr string
	for _, eblock := range dblock.EntryBlockList {
		if eblock.ChainID == fblockID {
			fblockmr = eblock.KeyMR
		}
	}
	if fblockmr == "" {
		return nil, err
	}

	return getfblock(fblockmr)
}

func getfblock(keymr string) (interfaces.IFBlock, error) {
	p, err := factom.GetRaw(keymr)
	if err != nil {
		return nil, err
	}
	return factoid.UnmarshalFBlock(p)
}

func getfblockbyheight(height uint32) (interfaces.IFBlock, error) {
	_, raw, err := factom.GetFBlockByHeight(int64(height))
	if err != nil {
		return nil, err
	}
	return factoid.UnmarshalFBlock(raw)
}

func getdblockbyheight(height uint32) (interfaces.IDirectoryBlock, error) {
	p, err := factom.GetDBlockByHeight(int64(height))
	if err != nil {
		return nil, err
	}
	h, err := hex.DecodeString(p.RawData)
	if err != nil {
		return nil, err
	}
	return directoryBlock.UnmarshalDBlock(h)
}
<commit_msg>wallet update for new fblock Get funcs<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package wallet

import (
	"encoding/hex"
	"fmt"
	"os"

	"github.com/FactomProject/factom"
	"github.com/FactomProject/factomd/common/directoryBlock"
	"github.com/FactomProject/factomd/common/factoid"
	"github.com/FactomProject/factomd/common/interfaces"
	"github.com/FactomProject/factomd/common/primitives"
	"github.com/FactomProject/factomd/database/databaseOverlay"
	"github.com/FactomProject/factomd/database/hybridDB"
	"github.com/FactomProject/factomd/database/mapdb"
)

// Database keys and key prefixes
var (
	fblockDBPrefix = []byte("FBlock")
)

type TXDatabaseOverlay struct {
	DBO databaseOverlay.Overlay

	// To indicate to sub processes to quit
	quit bool
}

func NewTXOverlay(db interfaces.IDatabase) *TXDatabaseOverlay {
	answer := new(TXDatabaseOverlay)
	answer.DBO.DB = db
	return answer
}

func NewTXMapDB() *TXDatabaseOverlay {
	return NewTXOverlay(new(mapdb.MapDB))
}

func NewTXLevelDB(ldbpath string) (*TXDatabaseOverlay, error) {
	db, err := hybridDB.NewLevelMapHybridDB(ldbpath, false)
	if err != nil {
		fmt.Printf("err opening transaction db: %v\n", err)
	}

	if db == nil {
		fmt.Println("Creating new transaction db ...")
		db, err = hybridDB.NewLevelMapHybridDB(ldbpath, true)

		if err != nil {
			return nil, err
		}
	}
	fmt.Println("Transaction database started from: " + ldbpath)
	return NewTXOverlay(db), nil
}

func NewTXBoltDB(boltPath string) (*TXDatabaseOverlay, error) {
	fileInfo, err := os.Stat(boltPath)
	if err == nil {
		if fileInfo.IsDir() {
			return nil, fmt.Errorf("%s is not a Bolt databse file", boltPath)
		}
	}
	if err != nil && !os.IsNotExist(err) {
		fmt.Printf("database error %s\n", err)
		return nil, err
	}

	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("Could not use wallet cache database file \"%s\"\n%v\n", boltPath, r)
			os.Exit(1)
		}
	}()
	db := hybridDB.NewBoltMapHybridDB(nil, boltPath)

	fmt.Println("Database started from: " + boltPath)
	return NewTXOverlay(db), nil
}

func (db *TXDatabaseOverlay) Close() error {
	db.quit = true
	return db.DBO.Close()
}

// GetAllTXs returns a list of all transactions in the history of Factom. A
// local database is used to cache the factoid blocks.
func (db *TXDatabaseOverlay) GetAllTXs() ([]interfaces.ITransaction, error) {
	// update the database and get the newest fblock
	_, err := db.Update()
	if err != nil {
		return nil, err
	}
	fblock, err := db.DBO.FetchFBlockHead()
	if err != nil {
		return nil, err
	}
	if fblock == nil {
		return nil, fmt.Errorf("FBlock Chain has not finished syncing")
	}
	txs := make([]interfaces.ITransaction, 0)

	for {
		// get all of the txs from the block
		height := fblock.GetDatabaseHeight()
		for _, tx := range fblock.GetTransactions() {
			ins, err := tx.TotalInputs()
			if err != nil {
				return nil, err
			}
			outs, err := tx.TotalOutputs()
			if err != nil {
				return nil, err
			}

			if ins != 0 || outs != 0 {
				tx.SetBlockHeight(height)
				txs = append(txs, tx)
			}
		}

		if pre := fblock.GetPrevKeyMR().String(); pre != factom.ZeroHash {
			// get the previous block
			fblock, err = db.GetFBlock(pre)
			if err != nil {
				return nil, err
			} else if fblock == nil {
				return nil, fmt.Errorf("Missing fblock in database: %s", pre)
			}
		} else {
			break
		}
	}

	return txs, nil
}

// GetTX gets a transaction by the transaction id
func (db *TXDatabaseOverlay) GetTX(txid string) (interfaces.ITransaction, error) {
	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	for _, tx := range txs {
		if tx.GetSigHash().String() == txid {
			return tx, nil
		}
	}

	return nil, fmt.Errorf("Transaction not found")
}

// GetTXAddress returns a list of all transactions in the history of Factom that
// include a specific address.
func (db *TXDatabaseOverlay) GetTXAddress(adr string) (
	[]interfaces.ITransaction, error) {
	filtered := make([]interfaces.ITransaction, 0)

	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	if factom.AddressStringType(adr) == factom.FactoidPub {
		for _, tx := range txs {
			for _, in := range tx.GetInputs() {
				if primitives.ConvertFctAddressToUserStr(in.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
			for _, out := range tx.GetOutputs() {
				if primitives.ConvertFctAddressToUserStr(out.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
		}
	} else if factom.AddressStringType(adr) == factom.ECPub {
		for _, tx := range txs {
			for _, out := range tx.GetECOutputs() {
				if primitives.ConvertECAddressToUserStr(out.GetAddress()) == adr {
					filtered = append(filtered, tx)
				}
			}
		}
	} else {
		return nil, fmt.Errorf("not a valid address")
	}

	return filtered, nil
}

func (db *TXDatabaseOverlay) GetTXRange(start, end int) (
	[]interfaces.ITransaction, error) {
	if start < 0 || end < 0 {
		return nil, fmt.Errorf("Range cannot have negative numbers")
	}
	s, e := uint32(start), uint32(end)

	filtered := make([]interfaces.ITransaction, 0)

	txs, err := db.GetAllTXs()
	if err != nil {
		return nil, err
	}

	for _, tx := range txs {
		if s <= tx.GetBlockHeight() && tx.GetBlockHeight() <= e {
			filtered = append(filtered, tx)
		}
	}

	return filtered, nil
}

// GetFBlock retrives a Factoid Block from Factom
func (db *TXDatabaseOverlay) GetFBlock(keymr string) (interfaces.IFBlock, error) {
	h, err := primitives.NewShaHashFromStr(keymr)
	if err != nil {
		return nil, err
	}

	fBlock, err := db.DBO.FetchFBlock(h)
	if err != nil {
		return nil, err
	}
	return fBlock, nil
}

func (db *TXDatabaseOverlay) FetchNextFBlockHeight() (uint32, error) {
	block, err := db.DBO.FetchFBlockHead()
	if err != nil {
		return 0, err
	}
	if block == nil {
		return 0, nil
	}
	return block.GetDBHeight() + 1, nil
}

func (db *TXDatabaseOverlay) InsertFBlockHead(fblock interfaces.IFBlock) error {
	return db.DBO.SaveFactoidBlockHead(fblock)
}

// Update gets all fblocks written since the database was last updated, and
// returns the most recent fblock keymr.
func (db *TXDatabaseOverlay) Update() (string, error) {
	newestFBlock, err := fblockHead()
	if err != nil {
		return "", err
	}

	start, err := db.FetchNextFBlockHeight()
	if err != nil {
		return "", err
	}

	// Make sure we didn't switch networks
	genesis, err := db.DBO.FetchFBlockByHeight(0)
	if err != nil {
		return "", err
	}
	if genesis != nil {
		genesis2, err := getdblockbyheight(0)
		if err != nil {
			return "", err
		}

		var gensisFBlockKeyMr interfaces.IHash
		for _, e := range genesis2.GetDBEntries() {
			if e.GetChainID().String() == "000000000000000000000000000000000000000000000000000000000000000f" {
				gensisFBlockKeyMr = e.GetKeyMR()
				break
			}
		}

		if gensisFBlockKeyMr == nil {
			return "", fmt.Errorf("unable to fetch the genesis block via the api")
		}

		if !gensisFBlockKeyMr.IsSameAs(genesis.GetKeyMR()) {
			start = 0
		}
	}

	newestHeight := newestFBlock.GetDatabaseHeight()

	// If the newest block in the tx cashe has a greater height than the newest
	// fblock then clear the cashe and start from 0.
	if start >= newestHeight {
		db.DBO.Clear(databaseOverlay.FACTOIDBLOCK)
		return newestFBlock.GetKeyMR().String(), nil
	}

	// If the latest block from the database is not available from the blockchain
	// then clear the cashe and start from 0.
	if f, err := getfblockbyheight(start); err != nil {
		db.DBO.Clear(databaseOverlay.FACTOIDBLOCK)
		return f.GetKeyMR().String(), err
	}

	db.DBO.StartMultiBatch()
	for i := start; i <= newestHeight; i++ {
		if i%1000 == 0 {
			if newestHeight-start > 1000 {
				fmt.Printf("Fetching block %v/%v\n", i, newestHeight)
			}
		}
		fblock, err := getfblockbyheight(i)
		if err != nil {
			db.DBO.ExecuteMultiBatch()
			return "", err
		}
		db.DBO.ProcessFBlockMultiBatch(fblock)

		// Save to DB every 500 blocks
		if i%500 == 0 {
			db.DBO.ExecuteMultiBatch()
			db.DBO.StartMultiBatch()
		}

		// If the wallet is stopped, this process becomes hard to kill. Have it exit
		if db.quit {
			break
		}
	}

	if !db.quit {
		fmt.Printf("Fetching block %v/%v\n", newestHeight, newestHeight)
	}

	// Save the remaining blocks
	if err = db.DBO.ExecuteMultiBatch(); err != nil {
		return "", err
	}

	return newestFBlock.GetKeyMR().String(), nil
}

// fblockHead gets the most recent fblock.
func fblockHead() (interfaces.IFBlock, error) {
	fblockID := "000000000000000000000000000000000000000000000000000000000000000f"

	dbhead, err := factom.GetDBlockHead()
	if err != nil {
		return nil, err
	}
	dblock, err := factom.GetDBlock(dbhead)
	if err != nil {
		return nil, err
	}

	var fblockmr string
	for _, eblock := range dblock.EntryBlockList {
		if eblock.ChainID == fblockID {
			fblockmr = eblock.KeyMR
		}
	}
	if fblockmr == "" {
		return nil, err
	}

	return getfblock(fblockmr)
}

func getfblock(keymr string) (interfaces.IFBlock, error) {
	_, raw, err := factom.GetFBlock(keymr)
	if err != nil {
		return nil, err
	}
	return factoid.UnmarshalFBlock(raw)
}

func getfblockbyheight(height uint32) (interfaces.IFBlock, error) {
	_, raw, err := factom.GetFBlockByHeight(int64(height))
	if err != nil {
		return nil, err
	}
	return factoid.UnmarshalFBlock(raw)
}

func getdblockbyheight(height uint32) (interfaces.IDirectoryBlock, error) {
	p, err := factom.GetDBlockByHeight(int64(height))
	if err != nil {
		return nil, err
	}
	h, err := hex.DecodeString(p.RawData)
	if err != nil {
		return nil, err
	}
	return directoryBlock.UnmarshalDBlock(h)
}
<|endoftext|>


<commit_before>package reverseproxy

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"path"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/koding/websocketproxy"
)

const (
	Version = "0.0.1"
	Name    = "proxy"
)

type Proxy struct {
	Kite *kite.Kite

	listener  net.Listener
	TLSConfig *tls.Config

	readyC chan bool // To signal when kite is ready to accept connections
	closeC chan bool // To signal when kite is closed with Close()

	// Holds registered kites. Keys are kite IDs.
	kites   map[string]*url.URL
	kitesMu sync.Mutex

	// muxer for proxy
	mux            *http.ServeMux
	websocketProxy http.Handler
	httpProxy      http.Handler

	// Proxy properties used to give urls and bind the listener
	Scheme     string
	PublicHost string // If given it must match the domain in certificate.
	PublicPort int    // Uses for registering and defining the public port.
}

func New(conf *config.Config) *Proxy {
	k := kite.New(Name, Version)
	k.Config = conf

	p := &Proxy{
		Kite:   k,
		kites:  make(map[string]*url.URL),
		readyC: make(chan bool),
		closeC: make(chan bool),
		mux:    http.NewServeMux(),
	}

	// third part kites are going to use this to register themself to
	// proxy-kite and get a proxy url, which they use for register to kontrol.
	p.Kite.HandleFunc("register", p.handleRegister)

	// create our websocketproxy http.handler

	p.websocketProxy = &websocketproxy.WebsocketProxy{
		Backend: p.backend,
		Upgrader: &websocket.Upgrader{
			ReadBufferSize:  4096,
			WriteBufferSize: 4096,
			CheckOrigin: func(r *http.Request) bool {
				// TODO: change this to publicdomain and also kites should add them to
				return true
			},
		},
	}

	p.httpProxy = &httputil.ReverseProxy{
		Director: p.director,
	}

	p.mux.Handle("/", k)
	p.mux.Handle("/proxy/", p)

	// OnDisconnect is called whenever a kite is disconnected from us.
	k.OnDisconnect(func(r *kite.Client) {
		k.Log.Info("Removing kite Id '%s' from proxy. It's disconnected", r.Kite.ID)
		delete(p.kites, r.Kite.ID)
	})

	return p
}

// ServeHTTP implements the http.Handler interface.
func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if isWebsocket(req) {
		p.websocketProxy.ServeHTTP(rw, req)
		return
	}

	p.httpProxy.ServeHTTP(rw, req)
}

// isWebsocket checks wether the incoming request is a part of websocket
// handshake
func isWebsocket(req *http.Request) bool {
	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
		return false
	}
	return true
}

func (p *Proxy) CloseNotify() chan bool {
	return p.closeC
}

func (p *Proxy) ReadyNotify() chan bool {
	return p.readyC
}

func (p *Proxy) handleRegister(r *kite.Request) (interface{}, error) {
	kiteUrl, err := url.Parse(r.Args.One().MustString())
	if err != nil {
		return nil, err
	}

	p.kites[r.Client.ID] = kiteUrl

	proxyURL := url.URL{
		Scheme: p.Scheme,
		Host:   p.PublicHost + ":" + strconv.Itoa(p.PublicPort),
		Path:   "/proxy/" + r.Client.ID,
	}

	s := proxyURL.String()
	p.Kite.Log.Info("Registering kite with url: '%s'. Can be reached now with: '%s'", kiteUrl, s)

	return s, nil
}

func (p *Proxy) backend(req *http.Request) *url.URL {
	withoutProxy := strings.TrimPrefix(req.URL.Path, "/proxy")
	paths := strings.Split(withoutProxy, "/")

	if len(paths) == 0 {
		p.Kite.Log.Error("Invalid path '%s'", req.URL.String())
		return nil
	}

	// remove the first empty path
	paths = paths[1:]

	// get our kiteId and indiviudal paths
	kiteId, rest := paths[0], path.Join(paths[1:]...)

	p.Kite.Log.Info("[%s] Incoming proxy request for endpoint '/%s'", kiteId, rest)

	p.kitesMu.Lock()
	defer p.kitesMu.Unlock()

	backendURL, ok := p.kites[kiteId]
	if !ok {
		p.Kite.Log.Error("kite for id '%s' is not found: %s", kiteId, req.URL.String())
		return nil
	}

	oldScheme := backendURL.Scheme // for logging

	// change "http" with "ws" because websocket procol expects a ws or wss as
	// scheme.
	if err := replaceSchemeWithWS(backendURL); err != nil {
		return nil
	}

	p.Kite.Log.Info("[%s] Changing scheme from '%s' to '%s' to make Websocket connection.", kiteId, oldScheme, backendURL.Scheme)

	// change now the path for the backend kite. Kite register itself with
	// something like "localhost:7777/kite" however we are going to
	// dial/connect to a sockjs server and there is no sessionId/serverId in
	// the path. This causes problem because the SockJS serve can't parse it.
	// Therefore we as an intermediate client are getting the path as (ommited the query):
	// "/proxy/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"
	// which will be converted to
	// "localhost:7777/kite/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"

	// backendURL.Path contains the baseURL, like "/kite"
	backendURL.Path += "/" + rest

	// also change the Origin to the client's host name, like as if someone
	// with the same backendUrl is trying to connect to the kite. Otherwise
	// will get an "Origin not allowed"
	req.Header.Set("Origin", "http://"+backendURL.Host)

	p.Kite.Log.Info("[%s] Proxying to backend url: '%s'.", kiteId, backendURL.String())
	return backendURL
}

func (p *Proxy) director(req *http.Request) {
	u := p.backend(req)
	if u == nil {
		return
	}

	// we don't need this for http proxy
	req.Header.Del("Origin")

	newScheme := "http"
	if u.Scheme == "wss" {
		newScheme = "https"
	}

	req.URL.Scheme = newScheme
	req.URL.Host = u.Host
	req.URL.Path = u.Path
}

// TODO: put this into a util package, is used by others too
func replaceSchemeWithWS(u *url.URL) error {
	switch u.Scheme {
	case "http":
		u.Scheme = "ws"
	case "https":
		u.Scheme = "wss"
	default:
		return fmt.Errorf("invalid scheme in url: %s", u.Scheme)
	}
	return nil
}

// ListenAndServe listens on the TCP network address addr and then calls Serve
// with handler to handle requests on incoming connections.
func (p *Proxy) ListenAndServe() error {
	var err error
	p.listener, err = net.Listen("tcp4",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		return err
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	close(p.readyC)

	server := http.Server{
		Handler: p.mux,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		p.Kite.Log.Fatal("Could not load cert/key files: %s", err.Error())
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	p.listener, err = net.Listen("tcp",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		p.Kite.Log.Fatal(err.Error())
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	// now we are ready
	close(p.readyC)

	p.listener = tls.NewListener(p.listener, tlsConfig)

	server := &http.Server{
		Handler:   p.mux,
		TLSConfig: tlsConfig,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) Run() {
	p.ListenAndServe()
}
<commit_msg>reverseproxy: do not store of URLS<commit_after>package reverseproxy

import (
	"crypto/tls"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"path"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/koding/websocketproxy"
)

const (
	Version = "0.0.1"
	Name    = "proxy"
)

type Proxy struct {
	Kite *kite.Kite

	listener  net.Listener
	TLSConfig *tls.Config

	readyC chan bool // To signal when kite is ready to accept connections
	closeC chan bool // To signal when kite is closed with Close()

	// Holds registered kites. Keys are kite IDs.
	kites   map[string]url.URL
	kitesMu sync.Mutex

	// muxer for proxy
	mux            *http.ServeMux
	websocketProxy http.Handler
	httpProxy      http.Handler

	// Proxy properties used to give urls and bind the listener
	Scheme     string
	PublicHost string // If given it must match the domain in certificate.
	PublicPort int    // Uses for registering and defining the public port.
}

func New(conf *config.Config) *Proxy {
	k := kite.New(Name, Version)
	k.Config = conf

	p := &Proxy{
		Kite:   k,
		kites:  make(map[string]url.URL),
		readyC: make(chan bool),
		closeC: make(chan bool),
		mux:    http.NewServeMux(),
	}

	// third part kites are going to use this to register themself to
	// proxy-kite and get a proxy url, which they use for register to kontrol.
	p.Kite.HandleFunc("register", p.handleRegister)

	// create our websocketproxy http.handler

	p.websocketProxy = &websocketproxy.WebsocketProxy{
		Backend: p.backend,
		Upgrader: &websocket.Upgrader{
			ReadBufferSize:  4096,
			WriteBufferSize: 4096,
			CheckOrigin: func(r *http.Request) bool {
				// TODO: change this to publicdomain and also kites should add them to
				return true
			},
		},
	}

	p.httpProxy = &httputil.ReverseProxy{
		Director: p.director,
	}

	p.mux.Handle("/", k)
	p.mux.Handle("/proxy/", p)

	// OnDisconnect is called whenever a kite is disconnected from us.
	k.OnDisconnect(func(r *kite.Client) {
		k.Log.Info("Removing kite Id '%s' from proxy. It's disconnected", r.Kite.ID)
		delete(p.kites, r.Kite.ID)
	})

	return p
}

// ServeHTTP implements the http.Handler interface.
func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if isWebsocket(req) {
		p.websocketProxy.ServeHTTP(rw, req)
		return
	}

	p.httpProxy.ServeHTTP(rw, req)
}

// isWebsocket checks wether the incoming request is a part of websocket
// handshake
func isWebsocket(req *http.Request) bool {
	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
		return false
	}
	return true
}

func (p *Proxy) CloseNotify() chan bool {
	return p.closeC
}

func (p *Proxy) ReadyNotify() chan bool {
	return p.readyC
}

func (p *Proxy) handleRegister(r *kite.Request) (interface{}, error) {
	kiteUrl, err := url.Parse(r.Args.One().MustString())
	if err != nil {
		return nil, err
	}

	p.kites[r.Client.ID] = *kiteUrl

	proxyURL := url.URL{
		Scheme: p.Scheme,
		Host:   p.PublicHost + ":" + strconv.Itoa(p.PublicPort),
		Path:   "/proxy/" + r.Client.ID,
	}

	s := proxyURL.String()
	p.Kite.Log.Info("Registering kite with url: '%s'. Can be reached now with: '%s'", kiteUrl, s)

	return s, nil
}

func (p *Proxy) backend(req *http.Request) *url.URL {
	withoutProxy := strings.TrimPrefix(req.URL.Path, "/proxy")
	paths := strings.Split(withoutProxy, "/")

	if len(paths) == 0 {
		p.Kite.Log.Error("Invalid path '%s'", req.URL.String())
		return nil
	}

	// remove the first empty path
	paths = paths[1:]

	// get our kiteId and indiviudal paths
	kiteId, rest := paths[0], path.Join(paths[1:]...)

	p.Kite.Log.Info("[%s] Incoming proxy request for endpoint '/%s'", kiteId, rest)

	p.kitesMu.Lock()
	defer p.kitesMu.Unlock()

	backendURL, ok := p.kites[kiteId]
	if !ok {
		p.Kite.Log.Error("kite for id '%s' is not found: %s", kiteId, req.URL.String())
		return nil
	}

	oldScheme := backendURL.Scheme // for logging

	// change "http" with "ws" because websocket procol expects a ws or wss as
	// scheme.
	if err := replaceSchemeWithWS(&backendURL); err != nil {
		return nil
	}

	p.Kite.Log.Info("[%s] Changing scheme from '%s' to '%s' to make Websocket connection.", kiteId, oldScheme, backendURL.Scheme)

	// backendURL.Path contains the baseURL, like "/kite" and rest contains
	// SockJS related endpoints, like /info or /123/kjasd213/websocket
	backendURL.Path += "/" + rest

	// also change the Origin to the client's host name, like as if someone
	// with the same backendUrl is trying to connect to the kite. Otherwise
	// will get an "Origin not allowed"
	req.Header.Set("Origin", "http://"+backendURL.Host)

	p.Kite.Log.Info("[%s] Proxying to backend url: '%s'.", kiteId, backendURL.String())
	return &backendURL
}

func (p *Proxy) director(req *http.Request) {
	u := p.backend(req)
	if u == nil {
		return
	}

	// we don't need this for http proxy
	req.Header.Del("Origin")

	newScheme := "http"
	if u.Scheme == "wss" {
		newScheme = "https"
	}

	req.URL.Scheme = newScheme
	req.URL.Host = u.Host
	req.URL.Path = u.Path
}

// TODO: put this into a util package, is used by others too
func replaceSchemeWithWS(u *url.URL) error {
	switch u.Scheme {
	case "http":
		u.Scheme = "ws"
	case "https":
		u.Scheme = "wss"
	}
	return nil
}

// ListenAndServe listens on the TCP network address addr and then calls Serve
// with handler to handle requests on incoming connections.
func (p *Proxy) ListenAndServe() error {
	var err error
	p.listener, err = net.Listen("tcp4",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		return err
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	close(p.readyC)

	server := http.Server{
		Handler: p.mux,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		p.Kite.Log.Fatal("Could not load cert/key files: %s", err.Error())
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	p.listener, err = net.Listen("tcp",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		p.Kite.Log.Fatal(err.Error())
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	// now we are ready
	close(p.readyC)

	p.listener = tls.NewListener(p.listener, tlsConfig)

	server := &http.Server{
		Handler:   p.mux,
		TLSConfig: tlsConfig,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) Run() {
	p.ListenAndServe()
}
<|endoftext|>


<commit_before><commit_msg>Refactored to improve readibility<commit_after><|endoftext|>


<commit_before><commit_msg>Marshal configVars<commit_after><|endoftext|>


<commit_before>package algoholic

import "testing"

type searchFunc func([]int, int) int

// Generate integers in range [from, to].
func generateRange(from, to int) []int {
	length := to - from + 1

	if length < 0 {
		panic("Invalid from, to.")
	}

	ret := make([]int, length)

	for i := 0; i < length; i++ {
		ret[i] = from + i
	}

	return ret
}

func correctlySearchesEmptySlice(t *testing.T, doSearch searchFunc) {
	if res := doSearch(nil, 123); res != -1 {
		t.Errorf("Search of nil returned %d, not expected -1.", res)
	}

	if res := doSearch([]int{}, 123); res != -1 {
		t.Errorf("Search of []int{} returned %d, not expected -1.", res)
	}
}

func correctlyFailsToFindMissingItem(t *testing.T, doSearch searchFunc) {
	for length := 0; length <= 100; length++ {
		ns := generateRange(1, length)
		if res := doSearch(ns, 0); res != -1 {
			t.Fatalf("Search of slice of [1, %d] for 0 returned %d, not expected -1.",
				length, res)
		}
		if res := doSearch(ns, length+1); res != -1 {
			t.Fatalf("Search of slice of [1, %d] for %d returned %d, not expected -1.",
				length, length+1, res)
		}
	}
}

func correctlyFindsItem(t *testing.T, doSearch searchFunc) {
	for length := 1; length <= 1e3; length++ {
		ns := generateRange(1, length)
		for i := 1; i <= length; i++ {
			if res := doSearch(ns, i); res != i-1 {
				t.Fatalf("Search of slice of [1, %d] for %d returned %d, not expected %d.",
					length, i, res, i-1)
			}
		}
	}
}
<commit_msg>Remove unnecessary verbiage.<commit_after>package algoholic

import "testing"

type searchFunc func([]int, int) int

// Generate integers in range [from, to].
func generateRange(from, to int) []int {
	length := to - from + 1

	if length < 0 {
		panic("Invalid from, to.")
	}

	ret := make([]int, length)

	for i := 0; i < length; i++ {
		ret[i] = from + i
	}

	return ret
}

func correctlySearchesEmptySlice(t *testing.T, doSearch searchFunc) {
	if res := doSearch(nil, 123); res != -1 {
		t.Errorf("Search of nil returned %d, not expected -1.", res)
	}

	if res := doSearch([]int{}, 123); res != -1 {
		t.Errorf("Search of []int{} returned %d, not expected -1.", res)
	}
}

func correctlyFailsToFindMissingItem(t *testing.T, doSearch searchFunc) {
	for length := 0; length <= 100; length++ {
		ns := generateRange(1, length)
		if res := doSearch(ns, 0); res != -1 {
			t.Fatalf("Search of [1, %d] for 0 returned %d, not expected -1.",
				length, res)
		}
		if res := doSearch(ns, length+1); res != -1 {
			t.Fatalf("Search of [1, %d] for %d returned %d, not expected -1.",
				length, length+1, res)
		}
	}
}

func correctlyFindsItem(t *testing.T, doSearch searchFunc) {
	for length := 1; length <= 1e3; length++ {
		ns := generateRange(1, length)
		for i := 1; i <= length; i++ {
			if res := doSearch(ns, i); res != i-1 {
				t.Fatalf("Search of [1, %d] for %d returned %d, not expected %d.",
					length, i, res, i-1)
			}
		}
	}
}
<|endoftext|>


<commit_before>package toystore

import (
	"encoding/gob"
	"fmt"
	"log"
	"time"

	"github.com/charlesetc/circle"
	"github.com/charlesetc/dive"
)

type Toystore struct {
	// Config
	ReplicationLevel int
	W                int
	R                int

	// Internal use
	dive            *dive.Node
	Port            int
	Data            Store
	Ring            *circle.Circle
	request_address chan []byte
	receive_address chan func() ([]byte, error) // will eventually not be bool anymore.
}

type ToystoreMetaData struct {
	Address    string
	RPCAddress string
}

type Store interface {
	Get(string) (string, bool)
	Put(string, string) bool
	Keys() []string
}

func (t *Toystore) UpdateMembers() {
	addresses := []string{t.rpcAddress()}

	for _, member := range t.dive.Members {
		if member.MetaData != nil {
			metaData := member.MetaData.(ToystoreMetaData)
			addresses = append(addresses, metaData.RPCAddress)
		}
	}

	// old_ring := t.Ring
	t.Ring = circle.CircleFromList(addresses)
	// Finish this up...
}

func (t *Toystore) Address() string {
	return fmt.Sprintf(":%d", t.Port)
}

func (t *Toystore) rpcAddress() string {
	return fmt.Sprintf(":%d", t.Port+20)
}

func RpcToAddress(rpc string) string {
	var port int
	fmt.Sscanf(rpc, ":%d", &port)
	return fmt.Sprintf(":%d", port-20)
}

func (t *Toystore) isCoordinator(address []byte) bool {
	return string(address) == t.rpcAddress()
}

func (t *Toystore) CoordinateGet(key string) (string, bool) {

	log.Printf("%s coordinating GET request %s.", t.Address(), key)

	var value string
	var ok bool

	lookup := t.KeyAddress([]byte(key))
	reads := 0

	for address, err := lookup(); err == nil; address, err = lookup() {
		if string(address) != t.rpcAddress() {
			log.Printf("%s sending GET request to %s.", t.Address(), address)
			value, ok = GetCall(string(address), key)

			if ok {
				reads++
			}
		} else {
			log.Printf("Coordinator %s retrieving %s.", t.Address(), key)
			value, ok = t.Data.Get(key)

			if ok {
				reads++
			}
		}
	}

	return value, ok && reads >= t.R
}

// An exposed endpoint to the client.
// Should function by directing each get or put
// to the proper machine.
func (t *Toystore) Get(key string) (value string, ok bool) {
	// t.UpdateMembers()

	lookup := t.KeyAddress([]byte(key))
	address, _ := lookup()

	// if this is the right node...
	if t.isCoordinator(address) {
		// take care of the get myself
		value, ok = t.CoordinateGet(key)
	} else {
		// send it off to the right one.
		value, ok = CoordinateGetCall(string(address), key)
	}
	return
}

func (t *Toystore) CoordinatePut(key string, value string) bool {

	log.Printf("%s coordinating PUT request %s/%s.", t.Address(), key, value)

	lookup := t.KeyAddress([]byte(key))
	writes := 0

	for address, err := lookup(); err == nil; address, err = lookup() {
		if string(address) != t.rpcAddress() {
			log.Printf("%s sending replation request to %s.", t.Address(), address)
			ok := PutCall(string(address), key, value)

			if ok {
				writes++
			}
		} else {
			log.Printf("Coordinator %s saving %s/%s.", t.Address(), key, value)
			ok := t.Data.Put(key, value)

			if ok {
				writes++
			}
		}
	}

	return writes >= t.W
}

func (t *Toystore) Put(key string, value string) (ok bool) {
	// t.UpdateMembers()

	lookup := t.KeyAddress([]byte(key))
	address, _ := lookup()

	if t.isCoordinator(address) {
		ok = t.CoordinatePut(key, value)
	} else {
		ok = CoordinatePutCall(string(address), key, value)
	}

	return
}

func (t *Toystore) KeyAddress(key []byte) func() ([]byte, error) {
	t.request_address <- key
	f := <-t.receive_address
	return f
}

func (t *Toystore) serveAsync() {
	for {
		select {
		case event := <-t.dive.Events:
			switch event.Kind {
			case dive.Join:
				address := event.Data.(ToystoreMetaData).RPCAddress
				log.Printf("Toystore joined: %s\n", address)
				log.Printf("Members count: %d\n", len(t.dive.Members))
				t.Ring.AddString(address)
			case dive.Fail:
				address := event.Data.(ToystoreMetaData).RPCAddress
				log.Printf("Toystore left: %s\n", address)
				t.Ring.RemoveString(address)
			}
		case key := <-t.request_address:
			log.Println("request_address")
			t.receive_address <- t.Ring.KeyAddress(key)
		}
	}
}

func New(port int, store Store, seed string, seedMeta interface{}) *Toystore {
	t := &Toystore{
		ReplicationLevel: 3,
		W:                1,
		R:                1,
		Port:             port,
		Data:             store,
		request_address:  make(chan []byte),
		receive_address:  make(chan func() ([]byte, error)),
		Ring:             circle.NewCircleHead(),
	}

	circle.ReplicationDepth = t.ReplicationLevel

	dive.PingInterval = time.Second
	n := dive.NewNode(
		"localhost",
		port+10,
		&dive.BasicRecord{Address: seed, MetaData: seedMeta},
		make(chan *dive.Event),
	)
	n.MetaData = ToystoreMetaData{t.Address(), t.rpcAddress()}
	gob.RegisterName("ToystoreMetaData", n.MetaData)

	t.dive = n

	// Add yourself to the ring
	t.Ring.AddString(t.rpcAddress())

	go t.serveAsync()

	go ServeRPC(t)

	return t
}
<commit_msg>Joins implemented but not transferring<commit_after>package toystore

import (
	"encoding/gob"
	"fmt"
	"log"
	"time"

	"github.com/charlesetc/circle"
	"github.com/charlesetc/dive"
)

type Toystore struct {
	// Config
	ReplicationLevel int
	W                int
	R                int

	// Internal use
	dive            *dive.Node
	Port            int
	Data            Store
	Ring            *circle.Circle
	request_address chan []byte
	receive_address chan func() ([]byte, error) // will eventually not be bool anymore.
}

type ToystoreMetaData struct {
	Address    string
	RPCAddress string
}

type Store interface {
	Get(string) (string, bool)
	Put(string, string) bool
	Keys() []string
}

func (t *Toystore) UpdateMembers() {
	addresses := []string{t.rpcAddress()}

	for _, member := range t.dive.Members {
		if member.MetaData != nil {
			metaData := member.MetaData.(ToystoreMetaData)
			addresses = append(addresses, metaData.RPCAddress)
		}
	}

	// old_ring := t.Ring
	t.Ring = circle.CircleFromList(addresses)
	// Finish this up...
}

func (t *Toystore) Address() string {
	return fmt.Sprintf(":%d", t.Port)
}

func (t *Toystore) rpcAddress() string {
	return fmt.Sprintf(":%d", t.Port+20)
}

func RpcToAddress(rpc string) string {
	var port int
	fmt.Sscanf(rpc, ":%d", &port)
	return fmt.Sprintf(":%d", port-20)
}

func (t *Toystore) isCoordinator(address []byte) bool {
	return string(address) == t.rpcAddress()
}

func (t *Toystore) CoordinateGet(key string) (string, bool) {

	log.Printf("%s coordinating GET request %s.", t.Address(), key)

	var value string
	var ok bool

	lookup := t.KeyAddress([]byte(key))
	reads := 0

	for address, err := lookup(); err == nil; address, err = lookup() {
		if string(address) != t.rpcAddress() {
			log.Printf("%s sending GET request to %s.", t.Address(), address)
			value, ok = GetCall(string(address), key)

			if ok {
				reads++
			}
		} else {
			log.Printf("Coordinator %s retrieving %s.", t.Address(), key)
			value, ok = t.Data.Get(key)

			if ok {
				reads++
			}
		}
	}

	return value, ok && reads >= t.R
}

// An exposed endpoint to the client.
// Should function by directing each get or put
// to the proper machine.
func (t *Toystore) Get(key string) (value string, ok bool) {
	// t.UpdateMembers()

	lookup := t.KeyAddress([]byte(key))
	address, _ := lookup()

	// if this is the right node...
	if t.isCoordinator(address) {
		// take care of the get myself
		value, ok = t.CoordinateGet(key)
	} else {
		// send it off to the right one.
		value, ok = CoordinateGetCall(string(address), key)
	}
	return
}

func (t *Toystore) CoordinatePut(key string, value string) bool {

	log.Printf("%s coordinating PUT request %s/%s.", t.Address(), key, value)

	lookup := t.KeyAddress([]byte(key))
	writes := 0

	for address, err := lookup(); err == nil; address, err = lookup() {
		if string(address) != t.rpcAddress() {
			log.Printf("%s sending replation request to %s.", t.Address(), address)
			ok := PutCall(string(address), key, value)

			if ok {
				writes++
			}
		} else {
			log.Printf("Coordinator %s saving %s/%s.", t.Address(), key, value)
			ok := t.Data.Put(key, value)

			if ok {
				writes++
			}
		}
	}

	return writes >= t.W
}

func (t *Toystore) Put(key string, value string) (ok bool) {
	// t.UpdateMembers()

	lookup := t.KeyAddress([]byte(key))
	address, _ := lookup()

	if t.isCoordinator(address) {
		ok = t.CoordinatePut(key, value)
	} else {
		ok = CoordinatePutCall(string(address), key, value)
	}

	return
}

func (t *Toystore) KeyAddress(key []byte) func() ([]byte, error) {
	t.request_address <- key
	f := <-t.receive_address
	return f
}

func (t *Toystore) Adjacent(address string) bool {
	return t.Ring.Adjacent([]byte(t.rpcAddress()), []byte(address))
}

func (t *Toystore) Transfer(address string) {
	keys := t.Data.Keys()
	for _, key := range keys {
		log.Printf("Test forward %s\n", key)
		val, ok := t.Data.Get(key)
		if !ok {
			// Should not happen.
			panic("I was told this key existed but it doesn't...")
		}
		// Checks to see if it's my key and if it's not, it forwards
		// the put call.
		ok = t.Put(key, val)
	}
}

func (t *Toystore) handleJoin(address string) {
	log.Printf("Toystore joined: %s\n", address)
	t.Ring.AddString(address)

	if t.Adjacent(address) {
		log.Println("Adjacent.")
		t.Transfer(address)
	}
}

func (t *Toystore) handleFail(address string) {
	log.Printf("Toystore left: %s\n", address)
	t.Ring.RemoveString(address)
}

func (t *Toystore) serveAsync() {
	for {
		select {
		case event := <-t.dive.Events:
			switch event.Kind {
			case dive.Join:
				address := event.Data.(ToystoreMetaData).RPCAddress // might not be rpc..
				t.handleJoin(address)
			case dive.Fail:
				address := event.Data.(ToystoreMetaData).RPCAddress
				t.handleFail(address)
			}
		case key := <-t.request_address:
			log.Println("request_address")
			t.receive_address <- t.Ring.KeyAddress(key)
		}
	}
}

func New(port int, store Store, seed string, seedMeta interface{}) *Toystore {
	t := &Toystore{
		ReplicationLevel: 3,
		W:                1,
		R:                1,
		Port:             port,
		Data:             store,
		request_address:  make(chan []byte),
		receive_address:  make(chan func() ([]byte, error)),
		Ring:             circle.NewCircleHead(),
	}

	circle.ReplicationDepth = t.ReplicationLevel

	dive.PingInterval = time.Second
	n := dive.NewNode(
		"localhost",
		port+10,
		&dive.BasicRecord{Address: seed, MetaData: seedMeta},
		make(chan *dive.Event),
	)
	n.MetaData = ToystoreMetaData{t.Address(), t.rpcAddress()}
	gob.RegisterName("ToystoreMetaData", n.MetaData)

	t.dive = n

	// Add yourself to the ring
	t.Ring.AddString(t.rpcAddress())

	go t.serveAsync()

	go ServeRPC(t)

	return t
}
<|endoftext|>


<commit_before>package stripe

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	assert "github.com/stretchr/testify/require"
)

func TestErrorError(t *testing.T) {
	err := &Error{Type: "foo", Msg: "bar"}
	assert.Equal(t, `{"message":"bar","type":"foo"}`, err.Error())
}

func TestErrorResponse(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Request-Id", "req_123")
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, `{"error":{"message":"bar","type":"`+ErrorTypeInvalidRequest+`"}}`)
	}))
	defer ts.Close()

	backend := GetBackendWithConfig(APIBackend, &BackendConfig{
		// Suppress error log output to make a verbose run of this test less
		// alarming (because we're testing specifically for an error).
		LeveledLogger: &LeveledLogger{Level: LevelNull},

		URL: String(ts.URL),
	})

	err := backend.Call(http.MethodGet, "/v1/account", "sk_test_badKey", nil, nil)
	assert.Error(t, err)

	stripeErr := err.(*Error)
	assert.Equal(t, ErrorTypeInvalidRequest, stripeErr.Type)
	assert.Equal(t, "req_123", stripeErr.RequestID)
	assert.Equal(t, 401, stripeErr.HTTPStatusCode)
}

func TestErrorRedact(t *testing.T) {
	pi := &PaymentIntent{Amount: int64(400), ClientSecret: "foo"}
	si := &SetupIntent{Description: "keepme", ClientSecret: "foo"}

	// Both
	{
		err := &Error{PaymentIntent: pi, SetupIntent: si}
		redacted := err.redact()
		assert.Equal(t, int64(400), err.PaymentIntent.Amount)
		assert.Equal(t, int64(400), redacted.PaymentIntent.Amount)
		assert.Equal(t, "keepme", err.SetupIntent.Description)
		assert.Equal(t, "keepme", redacted.SetupIntent.Description)
		assert.Equal(t, "foo", err.PaymentIntent.ClientSecret)
		assert.Equal(t, "foo", err.SetupIntent.ClientSecret)
		assert.Equal(t, "foo", pi.ClientSecret)
		assert.Equal(t, "foo", si.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.PaymentIntent.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.SetupIntent.ClientSecret)
	}

	// Neither
	{
		err := Error{PaymentIntent: nil, SetupIntent: nil}
		redacted := err.redact()
		assert.Nil(t, err.PaymentIntent)
		assert.Nil(t, redacted.PaymentIntent)
	}

	// Just PaymentIntent
	{
		err := &Error{PaymentIntent: pi}
		redacted := err.redact()
		assert.Equal(t, int64(400), err.PaymentIntent.Amount)
		assert.Equal(t, int64(400), redacted.PaymentIntent.Amount)
		assert.Equal(t, "foo", err.PaymentIntent.ClientSecret)
		assert.Equal(t, "foo", pi.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.PaymentIntent.ClientSecret)
	}

	// Just SetupIntent
	{
		err := &Error{SetupIntent: si}
		redacted := err.redact()
		assert.Equal(t, "keepme", err.SetupIntent.Description)
		assert.Equal(t, "keepme", redacted.SetupIntent.Description)
		assert.Equal(t, "foo", err.SetupIntent.ClientSecret)
		assert.Equal(t, "foo", si.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.SetupIntent.ClientSecret)
	}

}
<commit_msg>Subtests<commit_after>package stripe

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"

	assert "github.com/stretchr/testify/require"
)

func TestErrorError(t *testing.T) {
	err := &Error{Type: "foo", Msg: "bar"}
	assert.Equal(t, `{"message":"bar","type":"foo"}`, err.Error())
}

func TestErrorResponse(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Request-Id", "req_123")
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprintln(w, `{"error":{"message":"bar","type":"`+ErrorTypeInvalidRequest+`"}}`)
	}))
	defer ts.Close()

	backend := GetBackendWithConfig(APIBackend, &BackendConfig{
		// Suppress error log output to make a verbose run of this test less
		// alarming (because we're testing specifically for an error).
		LeveledLogger: &LeveledLogger{Level: LevelNull},

		URL: String(ts.URL),
	})

	err := backend.Call(http.MethodGet, "/v1/account", "sk_test_badKey", nil, nil)
	assert.Error(t, err)

	stripeErr := err.(*Error)
	assert.Equal(t, ErrorTypeInvalidRequest, stripeErr.Type)
	assert.Equal(t, "req_123", stripeErr.RequestID)
	assert.Equal(t, 401, stripeErr.HTTPStatusCode)
}

func TestErrorRedact(t *testing.T) {
	pi := &PaymentIntent{Amount: int64(400), ClientSecret: "foo"}
	si := &SetupIntent{Description: "keepme", ClientSecret: "foo"}

	t.Run("BothIntentObjects", func(t *testing.T) {
		err := &Error{PaymentIntent: pi, SetupIntent: si}
		redacted := err.redact()
		assert.Equal(t, int64(400), err.PaymentIntent.Amount)
		assert.Equal(t, int64(400), redacted.PaymentIntent.Amount)
		assert.Equal(t, "keepme", err.SetupIntent.Description)
		assert.Equal(t, "keepme", redacted.SetupIntent.Description)
		assert.Equal(t, "foo", err.PaymentIntent.ClientSecret)
		assert.Equal(t, "foo", err.SetupIntent.ClientSecret)
		assert.Equal(t, "foo", pi.ClientSecret)
		assert.Equal(t, "foo", si.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.PaymentIntent.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.SetupIntent.ClientSecret)
	})

	t.Run("NeitherIntentObject", func(t *testing.T) {
		err := Error{PaymentIntent: nil, SetupIntent: nil}
		redacted := err.redact()
		assert.Nil(t, err.PaymentIntent)
		assert.Nil(t, redacted.PaymentIntent)
	})

	t.Run("PaymentIntentAlonee", func(t *testing.T) {
		err := &Error{PaymentIntent: pi}
		redacted := err.redact()
		assert.Equal(t, int64(400), err.PaymentIntent.Amount)
		assert.Equal(t, int64(400), redacted.PaymentIntent.Amount)
		assert.Equal(t, "foo", err.PaymentIntent.ClientSecret)
		assert.Equal(t, "foo", pi.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.PaymentIntent.ClientSecret)
	})

	t.Run("SetupIntentAlone", func(t *testing.T) {
		err := &Error{SetupIntent: si}
		redacted := err.redact()
		assert.Equal(t, "keepme", err.SetupIntent.Description)
		assert.Equal(t, "keepme", redacted.SetupIntent.Description)
		assert.Equal(t, "foo", err.SetupIntent.ClientSecret)
		assert.Equal(t, "foo", si.ClientSecret)
		assert.Equal(t, "REDACTED", redacted.SetupIntent.ClientSecret)
	})
}
<|endoftext|>


<commit_before>package mmh3

import (
	"bytes"
	"encoding/binary"
	"hash"
	"reflect"
	"unsafe"
)

const (
	c1_64 uint64 = 0x87c37b91114253d5
	c2_64 uint64 = 0x4cf5ad432745937f
)

type hash128 struct {
	h1   uint64
	h2   uint64
	tail []byte
	size uint64
}

func New128() hash.Hash {
	return new(hash128)
}

func (h *hash128) BlockSize() int {
	return 16
}

func (h *hash128) Reset() {
	h.h1 = 0
	h.h2 = 0
	h.tail = nil
	h.size = 0
}

func (h *hash128) Size() int {
	return 16
}

func (h *hash128) Sum(in []byte) []byte {
	var k1, k2 uint64
	h1 := h.h1
	h2 := h.h2
	tail := h.tail

	if tail != nil {
		switch len(h.tail) {
		case 15:
			k2 ^= uint64(tail[14]) << 48
			fallthrough
		case 14:
			k2 ^= uint64(tail[13]) << 40
			fallthrough
		case 13:
			k2 ^= uint64(tail[12]) << 32
			fallthrough
		case 12:
			k2 ^= uint64(tail[11]) << 24
			fallthrough
		case 11:
			k2 ^= uint64(tail[10]) << 16
			fallthrough
		case 10:
			k2 ^= uint64(tail[9]) << 8
			fallthrough
		case 9:
			k2 ^= uint64(tail[8])
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			fallthrough
		case 8:
			k1 ^= uint64(tail[7]) << 56
			fallthrough
		case 7:
			k1 ^= uint64(tail[6]) << 48
			fallthrough
		case 6:
			k1 ^= uint64(tail[5]) << 40
			fallthrough
		case 5:
			k1 ^= uint64(tail[4]) << 32
			fallthrough
		case 4:
			k1 ^= uint64(tail[3]) << 24
			fallthrough
		case 3:
			k1 ^= uint64(tail[2]) << 16
			fallthrough
		case 2:
			k1 ^= uint64(tail[1]) << 8
			fallthrough
		case 1:
			k1 ^= uint64(tail[0])
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
		}
	}

	h1 ^= uint64(h.size)
	h2 ^= uint64(h.size)
	h1 += h2
	h2 += h1
	h1 ^= h1 >> 33
	h1 *= 0xff51afd7ed558ccd
	h1 ^= h1 >> 33
	h1 *= 0xc4ceb9fe1a85ec53
	h1 ^= h1 >> 33
	h2 ^= h2 >> 33
	h2 *= 0xff51afd7ed558ccd
	h2 ^= h2 >> 33
	h2 *= 0xc4ceb9fe1a85ec53
	h2 ^= h2 >> 33
	h1 += h2
	h2 += h1

	h.h1 = h1
	h.h2 = h2

	ret := make([]byte, 16)
	retHeader := (*reflect.SliceHeader)(unsafe.Pointer(&ret))
	var tuple []uint64
	tupleHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tuple))
	tupleHeader.Data = retHeader.Data
	tupleHeader.Len = 2
	tupleHeader.Cap = 2
	tuple[0] = h1
	tuple[1] = h2
	return append(in, ret...)

}

func (h *hash128) Write(key []byte) (n int, err error) {
	n = len(key)
	h.size += uint64(n)
	h1 := h.h1
	h2 := h.h2

	if h.tail != nil {
		for len(key) > 0 && len(h.tail) < 16 {
			h.tail = append(h.tail, key[0])
			key = key[1:]
		}
		if len(h.tail) == 16 { // a full block
			var k1, k2 uint64
			r := bytes.NewReader(h.tail)
			binary.Read(r, binary.LittleEndian, &k1)
			binary.Read(r, binary.LittleEndian, &k2)
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
			h1 = (h1 << 27) | (h1 >> (64 - 27))
			h1 += h2
			h1 = h1*5 + 0x52dce729
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			h2 = (h2 << 31) | (h2 >> (64 - 31))
			h2 += h1
			h2 = h2*5 + 0x38495ab5
			h.tail = nil
		}
	}

	length := len(key)
	nblocks := length / 16
	if nblocks > 0 {
		var uint64s []uint64
		var k1, k2 uint64
		keyHeader := (*reflect.SliceHeader)(unsafe.Pointer(&key))
		uint64sHeader := (*reflect.SliceHeader)(unsafe.Pointer(&uint64s))
		uint64sHeader.Data = keyHeader.Data
		uint64sHeader.Len = nblocks * 2
		uint64sHeader.Cap = uint64sHeader.Len
		for i := 0; i < nblocks*2; i += 2 {
			k1 = uint64s[i] // assuming no endian swapping
			k2 = uint64s[i+1]
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
			h1 = (h1 << 27) | (h1 >> (64 - 27))
			h1 += h2
			h1 = h1*5 + 0x52dce729
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			h2 = (h2 << 31) | (h2 >> (64 - 31))
			h2 += h1
			h2 = h2*5 + 0x38495ab5
		}
	}

	if length%16 != 0 {
		h.tail = key[nblocks*16 : length]
	}

	h.h1 = h1
	h.h2 = h2
	return
}
<commit_msg>minor clean-up<commit_after>package mmh3

import (
	"bytes"
	"encoding/binary"
	"hash"
	"reflect"
	"unsafe"
)

const (
	c1_64 uint64 = 0x87c37b91114253d5
	c2_64 uint64 = 0x4cf5ad432745937f
)

type hash128 struct {
	h1   uint64
	h2   uint64
	tail []byte
	size uint64
}

func New128() hash.Hash {
	return new(hash128)
}

func (h *hash128) BlockSize() int {
	return 16
}

func (h *hash128) Reset() {
	h.h1 = 0
	h.h2 = 0
	h.tail = nil
	h.size = 0
}

func (h *hash128) Size() int {
	return 16
}

func (h *hash128) Sum(in []byte) []byte {
	var k1, k2 uint64
	h1 := h.h1
	h2 := h.h2
	tail := h.tail

	if tail != nil {
		switch len(h.tail) {
		case 15:
			k2 ^= uint64(tail[14]) << 48
			fallthrough
		case 14:
			k2 ^= uint64(tail[13]) << 40
			fallthrough
		case 13:
			k2 ^= uint64(tail[12]) << 32
			fallthrough
		case 12:
			k2 ^= uint64(tail[11]) << 24
			fallthrough
		case 11:
			k2 ^= uint64(tail[10]) << 16
			fallthrough
		case 10:
			k2 ^= uint64(tail[9]) << 8
			fallthrough
		case 9:
			k2 ^= uint64(tail[8])
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			fallthrough
		case 8:
			k1 ^= uint64(tail[7]) << 56
			fallthrough
		case 7:
			k1 ^= uint64(tail[6]) << 48
			fallthrough
		case 6:
			k1 ^= uint64(tail[5]) << 40
			fallthrough
		case 5:
			k1 ^= uint64(tail[4]) << 32
			fallthrough
		case 4:
			k1 ^= uint64(tail[3]) << 24
			fallthrough
		case 3:
			k1 ^= uint64(tail[2]) << 16
			fallthrough
		case 2:
			k1 ^= uint64(tail[1]) << 8
			fallthrough
		case 1:
			k1 ^= uint64(tail[0])
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
		}
	}

	h1 ^= uint64(h.size)
	h2 ^= uint64(h.size)
	h1 += h2
	h2 += h1
	h1 ^= h1 >> 33
	h1 *= 0xff51afd7ed558ccd
	h1 ^= h1 >> 33
	h1 *= 0xc4ceb9fe1a85ec53
	h1 ^= h1 >> 33
	h2 ^= h2 >> 33
	h2 *= 0xff51afd7ed558ccd
	h2 ^= h2 >> 33
	h2 *= 0xc4ceb9fe1a85ec53
	h2 ^= h2 >> 33
	h1 += h2
	h2 += h1

	h.h1 = h1
	h.h2 = h2

	ret := make([]byte, 16)
	retHeader := (*reflect.SliceHeader)(unsafe.Pointer(&ret))
	var tuple []uint64
	tupleHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tuple))
	tupleHeader.Data = retHeader.Data
	tupleHeader.Len = 2
	tupleHeader.Cap = 2
	tuple[0] = h1
	tuple[1] = h2
	return append(in, ret...)

}

func (h *hash128) Write(key []byte) (n int, err error) {
	n = len(key)
	h.size += uint64(n)
	h1 := h.h1
	h2 := h.h2

	if h.tail != nil {
		for len(key) > 0 && len(h.tail) < 16 {
			h.tail = append(h.tail, key[0])
			key = key[1:]
		}
		if len(h.tail) == 16 { // a full block
			var k1, k2 uint64
			r := bytes.NewReader(h.tail)
			binary.Read(r, binary.LittleEndian, &k1)
			binary.Read(r, binary.LittleEndian, &k2)
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
			h1 = (h1 << 27) | (h1 >> (64 - 27))
			h1 += h2
			h1 = h1*5 + 0x52dce729
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			h2 = (h2 << 31) | (h2 >> (64 - 31))
			h2 += h1
			h2 = h2*5 + 0x38495ab5
			h.tail = nil
		}
	}

	length := len(key)
	nblocks := length / 16
	if nblocks > 0 {
		var k1, k2 uint64
		var blocks [][2]uint64
		keyHeader := (*reflect.SliceHeader)(unsafe.Pointer(&key))
		blocksHeader := (*reflect.SliceHeader)(unsafe.Pointer(&blocks))
		blocksHeader.Data = keyHeader.Data
		blocksHeader.Len = nblocks
		blocksHeader.Cap = nblocks
		for _, b := range blocks {
			k1, k2 = b[0], b[1]
			k1 *= c1_64
			k1 = (k1 << 31) | (k1 >> (64 - 31))
			k1 *= c2_64
			h1 ^= k1
			h1 = (h1 << 27) | (h1 >> (64 - 27))
			h1 += h2
			h1 = h1*5 + 0x52dce729
			k2 *= c2_64
			k2 = (k2 << 33) | (k2 >> (64 - 33))
			k2 *= c1_64
			h2 ^= k2
			h2 = (h2 << 31) | (h2 >> (64 - 31))
			h2 += h1
			h2 = h2*5 + 0x38495ab5
		}
	}

	if length%16 != 0 {
		h.tail = key[nblocks*16 : length]
	}

	h.h1 = h1
	h.h2 = h2
	return
}
<|endoftext|>


<commit_before>package imexport

import (
	"fmt"
	"io"
	"net/http"
	"os"

	"github.com/cozy/cozy-stack/pkg/imexport"
	"github.com/cozy/cozy-stack/pkg/jobs"
	"github.com/cozy/cozy-stack/pkg/utils"
	workers "github.com/cozy/cozy-stack/pkg/workers/mails"
	"github.com/cozy/cozy-stack/web/middlewares"
	"github.com/cozy/echo"
)

func export(c echo.Context) error {
	instance := middlewares.GetInstance(c)
	fs := instance.VFS()

	domain := instance.Domain

	id := utils.RandomString(16)

	w, err := os.Create(fmt.Sprintf("%s-%s.tar.gz", domain, id))
	if err != nil {
		return err
	}
	defer w.Close()

	err = imexport.Tardir(w, fs)
	if err != nil {
		return err
	}

	fmt.Println(instance.Domain, c.Path())

	mailBody := fmt.Sprintf("Bonjour, vous pouvez dès à présent récupérer vos documents sur le lien suivant : http://%s%s%s-%s",
		domain, c.Path(), domain, id)
	msg, err := jobs.NewMessage("json", workers.Options{
		Mode:    workers.ModeNoReply,
		Subject: "Cozy: vos documents sont prêts",
		Parts: []*workers.Part{
			{
				Type: "text/plain",
				Body: mailBody,
			},
		},
	})
	if err != nil {
		return err
	}

	context := jobs.NewWorkerContext(instance.Domain, "abcd")
	err = workers.SendMail(context, msg)
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, echo.Map{
		"message": "bienvenue sur la super page",
	})
}

func exportDir(c echo.Context) error {
	domID := c.Param("domain-id")
	fmt.Println(domID)

	src, err := os.Open(fmt.Sprintf("%s.tar.gz", domID))
	if err != nil {
		return err
	}
	dst, err := os.Create("cozy.tar.gz")
	if err != nil {
		return err
	}

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	err = os.Remove(fmt.Sprintf("%s.tar.gz", domID))
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, echo.Map{
		"message": "bienvenue sur la super page bis",
	})
}

// Routes sets the routing for export
func Routes(router *echo.Group) {
	router.GET("/", export)
	router.HEAD("/", export)

	router.GET("/:domain-id", exportDir)

}
<commit_msg>id random dans l'url et modification contenu du mail<commit_after>package imexport

import (
	"encoding/base32"
	"fmt"
	"io"
	"net/http"
	"os"

	"github.com/cozy/cozy-stack/pkg/crypto"
	"github.com/cozy/cozy-stack/pkg/imexport"
	"github.com/cozy/cozy-stack/pkg/jobs"
	workers "github.com/cozy/cozy-stack/pkg/workers/mails"
	"github.com/cozy/cozy-stack/web/middlewares"
	"github.com/cozy/echo"
)

func export(c echo.Context) error {
	instance := middlewares.GetInstance(c)
	fs := instance.VFS()

	domain := instance.Domain

	tab := crypto.GenerateRandomBytes(20)
	id := base32.StdEncoding.EncodeToString(tab)

	w, err := os.Create(fmt.Sprintf("%s-%s.tar.gz", domain, id))
	if err != nil {
		return err
	}
	defer w.Close()

	err = imexport.Tardir(w, fs)
	if err != nil {
		return err
	}

	lien := fmt.Sprintf("http://%s%s%s-%s", domain, c.Path(), domain, id)

	mailBody := fmt.Sprintf("Bonjour %s,\n\nVotre archive contenant l'ensemble de vos fichiers Cozy est prête à être téléchargée. Vous pouvez vous rendre sur %s pour y accéder.\n\nBonne journée\nL'équipe Cozy.",
		instance.Domain, lien)
	msg, err := jobs.NewMessage("json", workers.Options{
		Mode:    workers.ModeNoReply,
		Subject: "Téléchargement de vos fichiers Cozy",
		Parts: []*workers.Part{
			{
				Type: "text/plain",
				Body: mailBody,
			},
		},
	})
	if err != nil {
		return err
	}

	context := jobs.NewWorkerContext(instance.Domain, "abcd")
	err = workers.SendMail(context, msg)
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, echo.Map{
		"message": "bienvenue sur la super page",
	})
}

func exportDir(c echo.Context) error {
	domID := c.Param("domain-id")
	fmt.Println(domID)

	src, err := os.Open(fmt.Sprintf("%s.tar.gz", domID))
	if err != nil {
		return err
	}
	dst, err := os.Create("cozy.tar.gz")
	if err != nil {
		return err
	}

	_, err = io.Copy(dst, src)
	if err != nil {
		return err
	}

	err = os.Remove(fmt.Sprintf("%s.tar.gz", domID))
	if err != nil {
		return err
	}

	return c.JSON(http.StatusOK, echo.Map{
		"message": "bienvenue sur la super page bis",
	})
}

// Routes sets the routing for export
func Routes(router *echo.Group) {
	router.GET("/", export)
	router.HEAD("/", export)

	router.GET("/:domain-id", exportDir)

}
<|endoftext|>


<commit_before><commit_msg>v7: remove v6fakes usage from push unit tests<commit_after><|endoftext|>


<commit_before>package providertests

import (
	"testing"
	"time"

	"crypto/rsa"

	"github.com/jonboulle/clockwork"
	"github.com/russellhaering/gosaml2"
	"github.com/russellhaering/goxmldsig"
	"github.com/stretchr/testify/require"
)

func TestValidateResponses(t *testing.T) {
	scenarios := []ProviderTestScenario{
		{
			ScenarioName: "Auth0",
			Response:     LoadXMLResponse("./testdata/auth0_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://scaleft-test.auth0.com/samlp/rlXOZ4kOUTQaTV8icSXrfZUd1qtD1NhK",
				IdentityProviderIssuer:      "urn:scaleft-test.auth0.com",
				AssertionConsumerServiceURL: "http://localhost:8080/v1/_saml_callback",
				IDPCertificateStore:         LoadCertificateStore("./testdata/auth0_cert.pem"),
				Clock:                       dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 7, 25, 17, 50, 0, 0, time.UTC))),
			},
		},

		{
			ScenarioName: "Okta",
			Response:     LoadXMLResponse("./testdata/okta_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://dev-116807.oktapreview.com/app/scaleftdev116807_test_1/exk659aytfMeNI49v0h7/sso/saml",
				IdentityProviderIssuer:      "http://www.okta.com/exk659aytfMeNI49v0h7",
				AssertionConsumerServiceURL: "http://localhost:8080/v1/_saml_callback",
				SignAuthnRequests:           true,
				AudienceURI:                 "123",
				IDPCertificateStore:         LoadCertificateStore("./testdata/okta_cert.pem"),
				Clock:                       dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 7, 25, 17, 50, 0, 0, time.UTC))),
			},
		},
		{
			ScenarioName: "OneLogin",
			Response:     LoadXMLResponse("./testdata/onelogin_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://launchdarkly-dev.onelogin.com/trust/saml2/http-post/sso/634027",
				IdentityProviderIssuer:      "https://app.onelogin.com/saml/metadata/634027",
				AssertionConsumerServiceURL: "http://884d40bf.ngrok.io/api/sso/saml2/acs/58af624473d4f375b8e70d81",
				IDPCertificateStore:         LoadCertificateStore("./testdata/onelogin_cert.pem"),
				SkipSignatureValidation:     false,
				AllowMissingAttributes:      true,
				Clock: dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2017, 3, 7, 22, 50, 0, 0, time.UTC))),
			},
		},
		{
			ScenarioName: "OracleAccessManager",
			Response:     LoadXMLResponse("./testdata/oam_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://deaoam-dev02.jpl.nasa.gov:14101/oam/fed",
				IdentityProviderIssuer:      "https://deaoam-dev02.jpl.nasa.gov:14101/oam/fed",
				AssertionConsumerServiceURL: "http://127.0.0.1:5556/callback",
				IDPCertificateStore:         LoadCertificateStore("./testdata/oam_cert.pem"),
				SkipSignatureValidation:     false,
				AllowMissingAttributes:      false,
				Clock: dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 12, 12, 00, 00, 0, 0, time.UTC))),
			},

			// This test case currently isn't totally successful - signature verification fails.
			// It may be that the response wasn't signed with this certificate, or perhaps there
			// is another issue in our implementation.
			CheckError: func(t *testing.T, err error) {
				require.IsType(t, saml2.ErrVerification{}, err)
				ev := err.(saml2.ErrVerification)
				require.Equal(t, ev.Cause, rsa.ErrVerification)
			},
		},
	}

	ExerciseProviderTestScenarios(t, scenarios)
}
<commit_msg>Update the Oracle Access Manager test case - it should now complete successfully<commit_after>package providertests

import (
	"testing"
	"time"

	"github.com/jonboulle/clockwork"
	"github.com/russellhaering/gosaml2"
	"github.com/russellhaering/goxmldsig"
)

func TestValidateResponses(t *testing.T) {
	scenarios := []ProviderTestScenario{
		{
			ScenarioName: "Auth0",
			Response:     LoadXMLResponse("./testdata/auth0_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://scaleft-test.auth0.com/samlp/rlXOZ4kOUTQaTV8icSXrfZUd1qtD1NhK",
				IdentityProviderIssuer:      "urn:scaleft-test.auth0.com",
				AssertionConsumerServiceURL: "http://localhost:8080/v1/_saml_callback",
				IDPCertificateStore:         LoadCertificateStore("./testdata/auth0_cert.pem"),
				Clock:                       dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 7, 25, 17, 50, 0, 0, time.UTC))),
			},
		},

		{
			ScenarioName: "Okta",
			Response:     LoadXMLResponse("./testdata/okta_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://dev-116807.oktapreview.com/app/scaleftdev116807_test_1/exk659aytfMeNI49v0h7/sso/saml",
				IdentityProviderIssuer:      "http://www.okta.com/exk659aytfMeNI49v0h7",
				AssertionConsumerServiceURL: "http://localhost:8080/v1/_saml_callback",
				SignAuthnRequests:           true,
				AudienceURI:                 "123",
				IDPCertificateStore:         LoadCertificateStore("./testdata/okta_cert.pem"),
				Clock:                       dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 7, 25, 17, 50, 0, 0, time.UTC))),
			},
		},
		{
			ScenarioName: "OneLogin",
			Response:     LoadXMLResponse("./testdata/onelogin_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://launchdarkly-dev.onelogin.com/trust/saml2/http-post/sso/634027",
				IdentityProviderIssuer:      "https://app.onelogin.com/saml/metadata/634027",
				AssertionConsumerServiceURL: "http://884d40bf.ngrok.io/api/sso/saml2/acs/58af624473d4f375b8e70d81",
				IDPCertificateStore:         LoadCertificateStore("./testdata/onelogin_cert.pem"),
				SkipSignatureValidation:     false,
				AllowMissingAttributes:      true,
				Clock: dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2017, 3, 7, 22, 50, 0, 0, time.UTC))),
			},
		},
		{
			ScenarioName: "OracleAccessManager",
			Response:     LoadXMLResponse("./testdata/oam_response.xml"),
			ServiceProvider: &saml2.SAMLServiceProvider{
				IdentityProviderSSOURL:      "https://deaoam-dev02.jpl.nasa.gov:14101/oam/fed",
				IdentityProviderIssuer:      "https://deaoam-dev02.jpl.nasa.gov:14101/oam/fed",
				AssertionConsumerServiceURL: "http://127.0.0.1:5556/callback",
				IDPCertificateStore:         LoadCertificateStore("./testdata/oam_cert.pem"),
				SkipSignatureValidation:     false,
				AllowMissingAttributes:      true,
				Clock: dsig.NewFakeClock(clockwork.NewFakeClockAt(time.Date(2016, 12, 12, 00, 00, 0, 0, time.UTC))),
			},
		},
	}

	ExerciseProviderTestScenarios(t, scenarios)
}
<|endoftext|>


<commit_before>package trayhost

import (
	"errors"
	"time"
	"unsafe"
)

/*
#cgo linux pkg-config: gtk+-2.0
#cgo linux CFLAGS: -DLINUX -I/usr/include/libappindicator-0.1
#cgo linux LDFLAGS: -ldl
#cgo windows CFLAGS: -DWIN32
#cgo darwin CFLAGS: -DDARWIN -x objective-c
#cgo darwin LDFLAGS: -framework Cocoa
#include <stdlib.h>
#include "platform/common.h"
#include "platform/platform.h"
*/
import "C"

var menuItems []MenuItem

type MenuItem struct {
	Title   string
	Enabled func() bool // nil means always enabled.
	Handler func()
}

// Run the host system's event loop.
func Initialize(title string, imageData []byte, items []MenuItem) {
	cTitle := C.CString(title)
	defer C.free(unsafe.Pointer(cTitle))
	img, freeImg := create_image(Image{Kind: ImageKindPng, Bytes: imageData})
	defer freeImg()

	// Initialize menu.
	C.init(cTitle, img)

	menuItems = items
	for id, item := range menuItems {
		addItem(id, item)
	}
}

func EnterLoop() {
	C.native_loop()
}

func Exit() {
	C.exit_loop()
}

// Creates a separator MenuItem.
func SeparatorMenuItem() MenuItem { return MenuItem{Title: ""} }

func addItem(id int, item MenuItem) {
	if item.Title == "" {
		C.add_separator_item()
	} else {
		// ignore errors
		addMenuItem(id, item)
	}
}

func cAddMenuItem(id C.int, title *C.char, disabled C.int) {
	C.add_menu_item(id, title, disabled)
}

func cbool(b bool) C.int {
	if b {
		return 1
	} else {
		return 0
	}
}

// ---

// SetClipboardString sets the system clipboard to the specified UTF-8 encoded
// string.
//
// This function may only be called from the main thread.
func SetClipboardString(str string) {
	cp := C.CString(str)
	defer C.free(unsafe.Pointer(cp))

	C.set_clipboard_string(cp)
}

// GetClipboardString returns the contents of the system clipboard, if it
// contains or is convertible to a UTF-8 encoded string.
//
// This function may only be called from the main thread.
func GetClipboardString() (string, error) {
	cs := C.get_clipboard_string()
	if cs == nil {
		return "", errors.New("Can't get clipboard string.")
	}

	return C.GoString(cs), nil
}

type ImageKind uint8

const (
	ImageKindNone ImageKind = iota
	ImageKindPng
	ImageKindTiff
)

type Image struct {
	Kind  ImageKind
	Bytes []byte
}

// GetClipboardString returns the contents of the system clipboard, if it
// contains or is convertible to an image.
//
// This function may only be called from the main thread.
func GetClipboardImage() (Image, error) {
	img := C.get_clipboard_image()
	if img.kind == 0 {
		return Image{}, errors.New("Can't get clipboard image.")
	}

	return Image{Kind: ImageKind(img.kind), Bytes: C.GoBytes(img.bytes, img.length)}, nil
}

/*func GetClipboardFile() (Image, error) {
	img := C.get_clipboard_file()
	if img.kind == 0 {
		return Image{}, errors.New("Can't get clipboard file.")
	}

	return Image{Kind: ImageKind(img.kind), Bytes: C.GoBytes(img.bytes, img.length)}, nil
}*/

func GetClipboardFiles() ([]string, error) {
	files := C.get_clipboard_files()

	namesSlice := make([]string, int(files.count))
	for i := 0; i < int(files.count); i++ {
		var x *C.char
		p := (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(files.names)) + uintptr(i)*unsafe.Sizeof(x)))
		namesSlice[i] = C.GoString(*p)
	}

	return namesSlice, nil
}

// ---

// TODO: Garbage collection. Really only need this until the notification is cleared, so its Handler is accessible.
var notifications []Notification

// Notification represents a user notification.
type Notification struct {
	Title string // Title of user notification.
	Body  string // Body of user notification.
	Image Image  // Image shown in the content of user notification.

	// Timeout specifies time after which the notification is cleared.
	//
	// A Timeout of zero means no timeout.
	Timeout time.Duration

	// Activation (click) handler.
	Handler func()
}

// Display displays the user notification.
func (n Notification) Display() {
	cTitle := C.CString(n.Title)
	defer C.free(unsafe.Pointer(cTitle))
	cBody := C.CString(n.Body)
	defer C.free(unsafe.Pointer(cBody))
	img, freeImg := create_image(n.Image)
	defer freeImg()

	// TODO: Move out of Display.
	notificationId := (C.int)(len(notifications))
	notifications = append(notifications, n)

	C.display_notification(notificationId, cTitle, cBody, img, C.double(n.Timeout.Seconds()))
}
<commit_msg>Add ImageKindMov.<commit_after>package trayhost

import (
	"errors"
	"time"
	"unsafe"
)

/*
#cgo linux pkg-config: gtk+-2.0
#cgo linux CFLAGS: -DLINUX -I/usr/include/libappindicator-0.1
#cgo linux LDFLAGS: -ldl
#cgo windows CFLAGS: -DWIN32
#cgo darwin CFLAGS: -DDARWIN -x objective-c
#cgo darwin LDFLAGS: -framework Cocoa
#include <stdlib.h>
#include "platform/common.h"
#include "platform/platform.h"
*/
import "C"

var menuItems []MenuItem

type MenuItem struct {
	Title   string
	Enabled func() bool // nil means always enabled.
	Handler func()
}

// Run the host system's event loop.
func Initialize(title string, imageData []byte, items []MenuItem) {
	cTitle := C.CString(title)
	defer C.free(unsafe.Pointer(cTitle))
	img, freeImg := create_image(Image{Kind: ImageKindPng, Bytes: imageData})
	defer freeImg()

	// Initialize menu.
	C.init(cTitle, img)

	menuItems = items
	for id, item := range menuItems {
		addItem(id, item)
	}
}

func EnterLoop() {
	C.native_loop()
}

func Exit() {
	C.exit_loop()
}

// Creates a separator MenuItem.
func SeparatorMenuItem() MenuItem { return MenuItem{Title: ""} }

func addItem(id int, item MenuItem) {
	if item.Title == "" {
		C.add_separator_item()
	} else {
		// ignore errors
		addMenuItem(id, item)
	}
}

func cAddMenuItem(id C.int, title *C.char, disabled C.int) {
	C.add_menu_item(id, title, disabled)
}

func cbool(b bool) C.int {
	if b {
		return 1
	} else {
		return 0
	}
}

// ---

// SetClipboardString sets the system clipboard to the specified UTF-8 encoded
// string.
//
// This function may only be called from the main thread.
func SetClipboardString(str string) {
	cp := C.CString(str)
	defer C.free(unsafe.Pointer(cp))

	C.set_clipboard_string(cp)
}

// GetClipboardString returns the contents of the system clipboard, if it
// contains or is convertible to a UTF-8 encoded string.
//
// This function may only be called from the main thread.
func GetClipboardString() (string, error) {
	cs := C.get_clipboard_string()
	if cs == nil {
		return "", errors.New("Can't get clipboard string.")
	}

	return C.GoString(cs), nil
}

type ImageKind uint8

const (
	ImageKindNone ImageKind = iota
	ImageKindPng
	ImageKindTiff
	ImageKindMov
)

type Image struct {
	Kind        ImageKind // TODO: Remove in favour of ContentType.
	ContentType string
	Bytes       []byte
}

// GetClipboardString returns the contents of the system clipboard, if it
// contains or is convertible to an image.
//
// This function may only be called from the main thread.
func GetClipboardImage() (Image, error) {
	img := C.get_clipboard_image()
	if img.kind == 0 {
		return Image{}, errors.New("Can't get clipboard image.")
	}

	return Image{Kind: ImageKind(img.kind), Bytes: C.GoBytes(img.bytes, img.length)}, nil
}

/*func GetClipboardFile() (Image, error) {
	img := C.get_clipboard_file()
	if img.kind == 0 {
		return Image{}, errors.New("Can't get clipboard file.")
	}

	return Image{Kind: ImageKind(img.kind), Bytes: C.GoBytes(img.bytes, img.length)}, nil
}*/

func GetClipboardFiles() ([]string, error) {
	files := C.get_clipboard_files()

	namesSlice := make([]string, int(files.count))
	for i := 0; i < int(files.count); i++ {
		var x *C.char
		p := (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(files.names)) + uintptr(i)*unsafe.Sizeof(x)))
		namesSlice[i] = C.GoString(*p)
	}

	return namesSlice, nil
}

// ---

// TODO: Garbage collection. Really only need this until the notification is cleared, so its Handler is accessible.
var notifications []Notification

// Notification represents a user notification.
type Notification struct {
	Title string // Title of user notification.
	Body  string // Body of user notification.
	Image Image  // Image shown in the content of user notification.

	// Timeout specifies time after which the notification is cleared.
	//
	// A Timeout of zero means no timeout.
	Timeout time.Duration

	// Activation (click) handler.
	Handler func()
}

// Display displays the user notification.
func (n Notification) Display() {
	cTitle := C.CString(n.Title)
	defer C.free(unsafe.Pointer(cTitle))
	cBody := C.CString(n.Body)
	defer C.free(unsafe.Pointer(cBody))
	img, freeImg := create_image(n.Image)
	defer freeImg()

	// TODO: Move out of Display.
	notificationId := (C.int)(len(notifications))
	notifications = append(notifications, n)

	C.display_notification(notificationId, cTitle, cBody, img, C.double(n.Timeout.Seconds()))
}
<|endoftext|>


<commit_before>//
//  trayicon.go
//
//  Created by Martino Facchin
//  Copyright (c) 2015 Arduino LLC
//
//  Permission is hereby granted, free of charge, to any person
//  obtaining a copy of this software and associated documentation
//  files (the "Software"), to deal in the Software without
//  restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following
//  conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//  OTHER DEALINGS IN THE SOFTWARE.
//

// +build !arm

package main

import (
	"github.com/facchinm/trayhost"
	"github.com/kardianos/osext"
	"github.com/skratchdot/open-golang/open"
	"io/ioutil"
	"path/filepath"
	"runtime"
)

var notificationThumbnail trayhost.Image

func setupSysTray() {

	menuItems := []trayhost.MenuItem{
		trayhost.MenuItem{
			Title: "Launch webide.arduino.cc",
			Handler: func() {
				open.Run("http://webide.arduino.cc:8080")
			},
		},
		trayhost.SeparatorMenuItem(),
		trayhost.MenuItem{
			Title: "Quit",
			Handler: func() {
				trayhost.Exit()
				exit()
			},
		},
	}

	runtime.LockOSThread()

	execPath, _ := osext.Executable()
	b, err := ioutil.ReadFile(filepath.Dir(execPath) + "/arduino/resources/icons/icon.png")
	if err != nil {
		panic(err)
	}

	trayhost.Initialize("WebIDEBridge", b, menuItems)
	trayhost.EnterLoop()

	// systray.SetIcon(IconData)
	// systray.SetTitle("Arduino WebIDE Bridge")

	// // We can manipulate the systray in other goroutines
	// go func() {
	// 	systray.SetIcon(IconData)
	// 	mUrl := systray.AddMenuItem("Open webide.arduino.cc", "WebIDE Home")
	// 	mQuit := systray.AddMenuItem("Quit", "Quit the bridge")
	// 	for {
	// 		select {
	// 		case <-mUrl.ClickedCh:
	// 			open.Run("http://webide.arduino.cc:8080")
	// 		case <-mQuit.ClickedCh:
	// 			systray.Quit()
	// 			fmt.Println("Quit now...")
	// 			exit()
	// 		}
	// 	}
	// }()
}
<commit_msg>change tray library (again)<commit_after>//
//  trayicon.go
//
//  Created by Martino Facchin
//  Copyright (c) 2015 Arduino LLC
//
//  Permission is hereby granted, free of charge, to any person
//  obtaining a copy of this software and associated documentation
//  files (the "Software"), to deal in the Software without
//  restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following
//  conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//  OTHER DEALINGS IN THE SOFTWARE.
//

// +build !arm

package main

import (
	"fmt"
	"github.com/facchinm/systray"
	"github.com/facchinm/systray/example/icon"
	"github.com/skratchdot/open-golang/open"
)

func setupSysTray() {
	systray.Run(setupSysTrayReal)
}

func setupSysTrayReal() {

	// We can manipulate the systray in other goroutines
	go func() {
		systray.SetIcon(icon.Data)
		mUrl := systray.AddMenuItem("Open webide.arduino.cc", "Arduino Create Home")
		mQuit := systray.AddMenuItem("Quit", "Quit the bridge")
		for {
			select {
			case <-mUrl.ClickedCh:
				open.Run("http://webide.arduino.cc:8080")
			case <-mQuit.ClickedCh:
				systray.Quit()
				fmt.Println("Quit now...")
				exit()
			}
		}
	}()
}
<|endoftext|>


<commit_before>package dedup

import (
	"bufio"
	"io"

	"github.com/kch42/buzhash"
	"github.com/pkg/errors"
)

// SegmentHandler is something capable of processing the segments handed to it
type SegmentHandler func([]byte) error

// Segmenter segments a file or stream
type Segmenter struct {
	WindowSize       uint64
	Mask             uint64
	MaxSegmentLength uint64
}

// SegmentFile does the actual work of segmenting the specified file as per the
// params configure in the Segmenter struct
func (s Segmenter) SegmentFile(file io.ReadCloser, handler SegmentHandler) error {

	if handler == nil {
		return errors.Errorf("No segment handler specified")
	}

	if s.Mask == 0 {
		return errors.Errorf("Invalid mask specified (0)")
	}

	if s.WindowSize <= 0 {
		return errors.Errorf("Invalid windows size specified")
	}

	if s.MaxSegmentLength <= 0 {
		s.MaxSegmentLength = (s.Mask + 1) * 8 // arbitrary :-)
	}

	var (
		reader     = bufio.NewReader(file)
		roller     = buzhash.NewBuzHash(uint32(s.WindowSize))
		curSegment = make([]byte, 0, s.MaxSegmentLength)
		bytesRead  = uint64(0)
		minSegLen  = s.WindowSize
	)

	// Loop over input stream one byte at a time
	for {
		b, err := reader.ReadByte()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		curSegment = append(curSegment, b)
		sum := roller.HashByte(b)
		bytesRead++

		// dont accept segments smaller than minSegLen
		if uint64(len(curSegment)) < minSegLen {
			continue
		}

		// If this is a cutpoint, process the curSegment
		if (uint64(sum) & s.Mask) == 0 {
			if err := handler(curSegment); err != nil {
				return err
			}
			curSegment = curSegment[:0] // reset the curSegment accumulator
		}
		if uint64(len(curSegment)) >= s.MaxSegmentLength {
			if err := handler(curSegment); err != nil {
				return err
			}
			curSegment = curSegment[:0] // reset the curSegment accumulator
		}
	}

	// Deal with any remaining bytes in curSegment
	if err := handler(curSegment); err != nil {
		return err
	}

	return nil
}
<commit_msg>Segmenter only needs a io.Reader<commit_after>package dedup

import (
	"bufio"
	"io"

	"github.com/kch42/buzhash"
	"github.com/pkg/errors"
)

// SegmentHandler is something capable of processing the segments handed to it
type SegmentHandler func([]byte) error

// Segmenter segments a file or stream
type Segmenter struct {
	WindowSize       uint64
	Mask             uint64
	MaxSegmentLength uint64
}

// SegmentFile does the actual work of segmenting the specified file as per the
// params configure in the Segmenter struct. It reads the io.Reader till EOF,
// calling the specified handler each time it finds a segment
func (s Segmenter) SegmentFile(file io.Reader, handler SegmentHandler) error {

	if handler == nil {
		return errors.Errorf("No segment handler specified")
	}

	if s.Mask == 0 {
		return errors.Errorf("Invalid mask specified (0)")
	}

	if s.WindowSize <= 0 {
		return errors.Errorf("Invalid windows size specified")
	}

	if s.MaxSegmentLength <= 0 {
		s.MaxSegmentLength = (s.Mask + 1) * 8 // arbitrary :-)
	}

	var (
		reader     = bufio.NewReader(file)
		roller     = buzhash.NewBuzHash(uint32(s.WindowSize))
		curSegment = make([]byte, 0, s.MaxSegmentLength)
		bytesRead  = uint64(0)
		minSegLen  = s.WindowSize
	)

	// Loop over input stream one byte at a time
	for {
		b, err := reader.ReadByte()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		curSegment = append(curSegment, b)
		sum := roller.HashByte(b)
		bytesRead++

		// dont accept segments smaller than minSegLen
		if uint64(len(curSegment)) < minSegLen {
			continue
		}

		// If this is a cutpoint, process the curSegment
		if (uint64(sum) & s.Mask) == 0 {
			if err := handler(curSegment); err != nil {
				return err
			}
			curSegment = curSegment[:0] // reset the curSegment accumulator
		}
		if uint64(len(curSegment)) >= s.MaxSegmentLength {
			if err := handler(curSegment); err != nil {
				return err
			}
			curSegment = curSegment[:0] // reset the curSegment accumulator
		}
	}

	// Deal with any remaining bytes in curSegment
	if err := handler(curSegment); err != nil {
		return err
	}

	return nil
}
<|endoftext|>