<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package memfs

import (
	"fmt"
	"io"
	"os"
	"time"

	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"github.com/jacobsa/gcloud/syncutil"
)

// Common attributes for files and directories.
type inode struct {
	/////////////////////////
	// Dependencies
	/////////////////////////

	clock timeutil.Clock

	/////////////////////////
	// Mutable state
	/////////////////////////

	mu syncutil.InvariantMutex

	// The current attributes of this inode.
	//
	// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
	// INVARIANT: !(isDir() && isSymlink())
	// INVARIANT: attrs.Size == len(contents)
	attrs fuseops.InodeAttributes // GUARDED_BY(mu)

	// For directories, entries describing the children of the directory. Unused
	// entries are of type DT_Unknown.
	//
	// This array can never be shortened, nor can its elements be moved, because
	// we use its indices for Dirent.Offset, which is exposed to the user who
	// might be calling readdir in a loop while concurrently modifying the
	// directory. Unused entries can, however, be reused.
	//
	// INVARIANT: If !isDir(), len(entries) == 0
	// INVARIANT: For each i, entries[i].Offset == i+1
	// INVARIANT: Contains no duplicate names in used entries.
	entries []fuseutil.Dirent // GUARDED_BY(mu)

	// For files, the current contents of the file.
	//
	// INVARIANT: If !isFile(), len(contents) == 0
	contents []byte // GUARDED_BY(mu)

	// For symlinks, the target of the symlink.
	//
	// INVARIANT: If !isSymlink(), len(target) == 0
	//
	// GUARDED_BY(mu)
	target string
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Create a new inode with the supplied attributes, which need not contain
// time-related information (the inode object will take care of that).
func newInode(
	clock timeutil.Clock,
	attrs fuseops.InodeAttributes) (in *inode) {
	// Update time info.
	now := clock.Now()
	attrs.Mtime = now
	attrs.Crtime = now

	// Create the object.
	in = &inode{
		clock:      clock,
		dir:        (attrs.Mode&os.ModeDir != 0),
		attributes: attrs,
	}

	in.mu = syncutil.NewInvariantMutex(in.checkInvariants)
	return
}

func (in *inode) checkInvariants() {
	// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
	if !(in.attrs.Mode&^(os.ModePerm|os.ModeDir|os.ModeSymlink) == 0) {
		panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
	}

	// INVARIANT: !(isDir() && isSymlink())
	if in.isDir() && in.isSymlink() {
		panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
	}

	// INVARIANT: attrs.Size == len(contents)
	if in.attrs.Size != len(in.contents) {
		panic(fmt.Sprintf(
			"Size mismatch: %d vs. %d",
			in.attrs.Size,
			len(in.contents)))
	}

	// INVARIANT: If !isDir(), len(entries) == 0
	if !in.isDir() && len(entries) != 0 {
		panic(fmt.Sprintf("Unexpected entries length: %d", len(entries)))
	}

	// INVARIANT: For each i, entries[i].Offset == i+1
	for i, e := range in.entries {
		if !(e.Offset == i+1) {
			panic(fmt.Sprintf("Unexpected offset for index %d: %d", i, e.Offset))
		}
	}

	// INVARIANT: Contains no duplicate names in used entries.
	childNames := make(map[string]struct{})
	for i, e := range inode.entries {
		if e.Type != fuseutil.DT_Unknown {
			if _, ok := childNames[e.Name]; ok {
				panic(fmt.Sprintf("Duplicate name: %s", e.Name))
			}

			childNames[e.Name] = struct{}{}
		}
	}

	// INVARIANT: If !isFile(), len(contents) == 0
	if !in.isFile() && len(in.contents) != 0 {
		panic(fmt.Sprintf("Unexpected length: %d", len(in.contents)))
	}

	// INVARIANT: If !isSymlink(), len(target) == 0
	if !in.isSymlink() && len(in.target) != 0 {
		panic(fmt.Sprintf("Unexpected target length: %d", len(in.target)))
	}

	return
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isDir() bool {
	return in.attrs.Mode&os.ModeDir != 0
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isSymlink() bool {
	return in.attrs.Mode&os.ModeSymlink != 0
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isFile() bool {
	return !(in.isDir() || in.isSymlink())
}

////////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////////

// Return the number of children of the directory.
//
// REQUIRES: inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) Len() (n int) {
	for _, e := range inode.entries {
		if e.Type != fuseutil.DT_Unknown {
			n++
		}
	}

	return
}

// Find an entry for the given child name and return its inode ID.
//
// REQUIRES: inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) LookUpChild(name string) (id fuseops.InodeID, ok bool) {
	index, ok := inode.findChild(name)
	if ok {
		id = inode.entries[index].Inode
	}

	return
}

// Add an entry for a child.
//
// REQUIRES: inode.dir
// REQUIRES: dt != fuseutil.DT_Unknown
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) AddChild(
	id fuseops.InodeID,
	name string,
	dt fuseutil.DirentType) {
	var index int

	// Update the modification time.
	inode.attributes.Mtime = inode.clock.Now()

	// No matter where we place the entry, make sure it has the correct Offset
	// field.
	defer func() {
		inode.entries[index].Offset = fuseops.DirOffset(index + 1)
	}()

	// Set up the entry.
	e := fuseutil.Dirent{
		Inode: id,
		Name:  name,
		Type:  dt,
	}

	// Look for a gap in which we can insert it.
	for index = range inode.entries {
		if inode.entries[index].Type == fuseutil.DT_Unknown {
			inode.entries[index] = e
			return
		}
	}

	// Append it to the end.
	index = len(inode.entries)
	inode.entries = append(inode.entries, e)
}

// Remove an entry for a child.
//
// REQUIRES: inode.dir
// REQUIRES: An entry for the given name exists.
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) RemoveChild(name string) {
	// Update the modification time.
	inode.attributes.Mtime = inode.clock.Now()

	// Find the entry.
	i, ok := inode.findChild(name)
	if !ok {
		panic(fmt.Sprintf("Unknown child: %s", name))
	}

	// Mark it as unused.
	inode.entries[i] = fuseutil.Dirent{
		Type:   fuseutil.DT_Unknown,
		Offset: fuseops.DirOffset(i + 1),
	}
}

// Serve a ReadDir request.
//
// REQUIRES: inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) ReadDir(offset int, size int) (data []byte, err error) {
	if !inode.dir {
		panic("ReadDir called on non-directory.")
	}

	for i := offset; i < len(inode.entries); i++ {
		e := inode.entries[i]

		// Skip unused entries.
		if e.Type == fuseutil.DT_Unknown {
			continue
		}

		data = fuseutil.AppendDirent(data, inode.entries[i])

		// Trim and stop early if we've exceeded the requested size.
		if len(data) > size {
			data = data[:size]
			break
		}
	}

	return
}

// Read from the file's contents. See documentation for ioutil.ReaderAt.
//
// REQUIRES: !inode.dir
// SHARED_LOCKS_REQUIRED(inode.mu)
func (inode *inode) ReadAt(p []byte, off int64) (n int, err error) {
	if inode.dir {
		panic("ReadAt called on directory.")
	}

	// Ensure the offset is in range.
	if off > int64(len(inode.contents)) {
		err = io.EOF
		return
	}

	// Read what we can.
	n = copy(p, inode.contents[off:])
	if n < len(p) {
		err = io.EOF
	}

	return
}

// Write to the file's contents. See documentation for ioutil.WriterAt.
//
// REQUIRES: !inode.dir
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) WriteAt(p []byte, off int64) (n int, err error) {
	if inode.dir {
		panic("WriteAt called on directory.")
	}

	// Update the modification time.
	inode.attributes.Mtime = inode.clock.Now()

	// Ensure that the contents slice is long enough.
	newLen := int(off) + len(p)
	if len(inode.contents) < newLen {
		padding := make([]byte, newLen-len(inode.contents))
		inode.contents = append(inode.contents, padding...)
		inode.attributes.Size = uint64(newLen)
	}

	// Copy in the data.
	n = copy(inode.contents[off:], p)

	// Sanity check.
	if n != len(p) {
		panic(fmt.Sprintf("Unexpected short copy: %v", n))
	}

	return
}

// Update attributes from non-nil parameters.
//
// EXCLUSIVE_LOCKS_REQUIRED(inode.mu)
func (inode *inode) SetAttributes(
	size *uint64,
	mode *os.FileMode,
	mtime *time.Time) {
	// Update the modification time.
	inode.attributes.Mtime = inode.clock.Now()

	// Truncate?
	if size != nil {
		intSize := int(*size)

		// Update contents.
		if intSize <= len(inode.contents) {
			inode.contents = inode.contents[:intSize]
		} else {
			padding := make([]byte, intSize-len(inode.contents))
			inode.contents = append(inode.contents, padding...)
		}

		// Update attributes.
		inode.attributes.Size = *size
	}

	// Change mode?
	if mode != nil {
		inode.attributes.Mode = *mode
	}

	// Change mtime?
	if mtime != nil {
		inode.attributes.Mtime = *mtime
	}
}
<commit_msg>Fixed names.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package memfs

import (
	"fmt"
	"io"
	"os"
	"time"

	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse/fuseops"
	"github.com/jacobsa/fuse/fuseutil"
	"github.com/jacobsa/gcloud/syncutil"
)

// Common attributes for files and directories.
type inode struct {
	/////////////////////////
	// Dependencies
	/////////////////////////

	clock timeutil.Clock

	/////////////////////////
	// Mutable state
	/////////////////////////

	mu syncutil.InvariantMutex

	// The current attributes of this inode.
	//
	// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
	// INVARIANT: !(isDir() && isSymlink())
	// INVARIANT: attrs.Size == len(contents)
	attrs fuseops.InodeAttributes // GUARDED_BY(mu)

	// For directories, entries describing the children of the directory. Unused
	// entries are of type DT_Unknown.
	//
	// This array can never be shortened, nor can its elements be moved, because
	// we use its indices for Dirent.Offset, which is exposed to the user who
	// might be calling readdir in a loop while concurrently modifying the
	// directory. Unused entries can, however, be reused.
	//
	// INVARIANT: If !isDir(), len(entries) == 0
	// INVARIANT: For each i, entries[i].Offset == i+1
	// INVARIANT: Contains no duplicate names in used entries.
	entries []fuseutil.Dirent // GUARDED_BY(mu)

	// For files, the current contents of the file.
	//
	// INVARIANT: If !isFile(), len(contents) == 0
	contents []byte // GUARDED_BY(mu)

	// For symlinks, the target of the symlink.
	//
	// INVARIANT: If !isSymlink(), len(target) == 0
	//
	// GUARDED_BY(mu)
	target string
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Create a new inode with the supplied attributes, which need not contain
// time-related information (the inode object will take care of that).
func newInode(
	clock timeutil.Clock,
	attrs fuseops.InodeAttributes) (in *inode) {
	// Update time info.
	now := clock.Now()
	attrs.Mtime = now
	attrs.Crtime = now

	// Create the object.
	in = &inode{
		clock:      clock,
		dir:        (attrs.Mode&os.ModeDir != 0),
		attributes: attrs,
	}

	in.mu = syncutil.NewInvariantMutex(in.checkInvariants)
	return
}

func (in *inode) checkInvariants() {
	// INVARIANT: attrs.Mode &^ (os.ModePerm|os.ModeDir|os.ModeSymlink) == 0
	if !(in.attrs.Mode&^(os.ModePerm|os.ModeDir|os.ModeSymlink) == 0) {
		panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
	}

	// INVARIANT: !(isDir() && isSymlink())
	if in.isDir() && in.isSymlink() {
		panic(fmt.Sprintf("Unexpected mode: %v", in.attrs.Mode))
	}

	// INVARIANT: attrs.Size == len(contents)
	if in.attrs.Size != len(in.contents) {
		panic(fmt.Sprintf(
			"Size mismatch: %d vs. %d",
			in.attrs.Size,
			len(in.contents)))
	}

	// INVARIANT: If !isDir(), len(entries) == 0
	if !in.isDir() && len(entries) != 0 {
		panic(fmt.Sprintf("Unexpected entries length: %d", len(entries)))
	}

	// INVARIANT: For each i, entries[i].Offset == i+1
	for i, e := range in.entries {
		if !(e.Offset == i+1) {
			panic(fmt.Sprintf("Unexpected offset for index %d: %d", i, e.Offset))
		}
	}

	// INVARIANT: Contains no duplicate names in used entries.
	childNames := make(map[string]struct{})
	for i, e := range in.entries {
		if e.Type != fuseutil.DT_Unknown {
			if _, ok := childNames[e.Name]; ok {
				panic(fmt.Sprintf("Duplicate name: %s", e.Name))
			}

			childNames[e.Name] = struct{}{}
		}
	}

	// INVARIANT: If !isFile(), len(contents) == 0
	if !in.isFile() && len(in.contents) != 0 {
		panic(fmt.Sprintf("Unexpected length: %d", len(in.contents)))
	}

	// INVARIANT: If !isSymlink(), len(target) == 0
	if !in.isSymlink() && len(in.target) != 0 {
		panic(fmt.Sprintf("Unexpected target length: %d", len(in.target)))
	}

	return
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isDir() bool {
	return in.attrs.Mode&os.ModeDir != 0
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isSymlink() bool {
	return in.attrs.Mode&os.ModeSymlink != 0
}

// LOCKS_REQUIRED(in.mu)
func (in *inode) isFile() bool {
	return !(in.isDir() || in.isSymlink())
}

////////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////////

// Return the number of children of the directory.
//
// REQUIRES: in.isDir()
// SHARED_LOCKS_REQUIRED(in.mu)
func (in *inode) Len() (n int) {
	for _, e := range in.entries {
		if e.Type != fuseutil.DT_Unknown {
			n++
		}
	}

	return
}

// Find an entry for the given child name and return its inode ID.
//
// REQUIRES: in.isDir()
// SHARED_LOCKS_REQUIRED(in.mu)
func (in *inode) LookUpChild(name string) (id fuseops.InodeID, ok bool) {
	index, ok := in.findChild(name)
	if ok {
		id = in.entries[index].Inode
	}

	return
}

// Add an entry for a child.
//
// REQUIRES: in.isDir()
// REQUIRES: dt != fuseutil.DT_Unknown
// EXCLUSIVE_LOCKS_REQUIRED(in.mu)
func (in *inode) AddChild(
	id fuseops.InodeID,
	name string,
	dt fuseutil.DirentType) {
	var index int

	// Update the modification time.
	in.attributes.Mtime = in.clock.Now()

	// No matter where we place the entry, make sure it has the correct Offset
	// field.
	defer func() {
		in.entries[index].Offset = fuseops.DirOffset(index + 1)
	}()

	// Set up the entry.
	e := fuseutil.Dirent{
		Inode: id,
		Name:  name,
		Type:  dt,
	}

	// Look for a gap in which we can insert it.
	for index = range in.entries {
		if in.entries[index].Type == fuseutil.DT_Unknown {
			in.entries[index] = e
			return
		}
	}

	// Append it to the end.
	index = len(in.entries)
	in.entries = append(in.entries, e)
}

// Remove an entry for a child.
//
// REQUIRES: in.isDir()
// REQUIRES: An entry for the given name exists.
// EXCLUSIVE_LOCKS_REQUIRED(in.mu)
func (in *inode) RemoveChild(name string) {
	// Update the modification time.
	in.attributes.Mtime = in.clock.Now()

	// Find the entry.
	i, ok := in.findChild(name)
	if !ok {
		panic(fmt.Sprintf("Unknown child: %s", name))
	}

	// Mark it as unused.
	in.entries[i] = fuseutil.Dirent{
		Type:   fuseutil.DT_Unknown,
		Offset: fuseops.DirOffset(i + 1),
	}
}

// Serve a ReadDir request.
//
// REQUIRES: in.isDir()
// SHARED_LOCKS_REQUIRED(in.mu)
func (in *inode) ReadDir(offset int, size int) (data []byte, err error) {
	if !in.dir {
		panic("ReadDir called on non-directory.")
	}

	for i := offset; i < len(in.entries); i++ {
		e := in.entries[i]

		// Skip unused entries.
		if e.Type == fuseutil.DT_Unknown {
			continue
		}

		data = fuseutil.AppendDirent(data, in.entries[i])

		// Trim and stop early if we've exceeded the requested size.
		if len(data) > size {
			data = data[:size]
			break
		}
	}

	return
}

// Read from the file's contents. See documentation for ioutil.ReaderAt.
//
// REQUIRES: in.isFile()
// SHARED_LOCKS_REQUIRED(in.mu)
func (in *inode) ReadAt(p []byte, off int64) (n int, err error) {
	if in.dir {
		panic("ReadAt called on directory.")
	}

	// Ensure the offset is in range.
	if off > int64(len(in.contents)) {
		err = io.EOF
		return
	}

	// Read what we can.
	n = copy(p, in.contents[off:])
	if n < len(p) {
		err = io.EOF
	}

	return
}

// Write to the file's contents. See documentation for ioutil.WriterAt.
//
// REQUIRES: in.isFile()
// EXCLUSIVE_LOCKS_REQUIRED(in.mu)
func (in *inode) WriteAt(p []byte, off int64) (n int, err error) {
	if in.dir {
		panic("WriteAt called on directory.")
	}

	// Update the modification time.
	in.attributes.Mtime = in.clock.Now()

	// Ensure that the contents slice is long enough.
	newLen := int(off) + len(p)
	if len(in.contents) < newLen {
		padding := make([]byte, newLen-len(in.contents))
		in.contents = append(in.contents, padding...)
		in.attributes.Size = uint64(newLen)
	}

	// Copy in the data.
	n = copy(in.contents[off:], p)

	// Sanity check.
	if n != len(p) {
		panic(fmt.Sprintf("Unexpected short copy: %v", n))
	}

	return
}

// Update attributes from non-nil parameters.
//
// EXCLUSIVE_LOCKS_REQUIRED(in.mu)
func (in *inode) SetAttributes(
	size *uint64,
	mode *os.FileMode,
	mtime *time.Time) {
	// Update the modification time.
	in.attributes.Mtime = in.clock.Now()

	// Truncate?
	if size != nil {
		intSize := int(*size)

		// Update contents.
		if intSize <= len(in.contents) {
			in.contents = in.contents[:intSize]
		} else {
			padding := make([]byte, intSize-len(in.contents))
			in.contents = append(in.contents, padding...)
		}

		// Update attributes.
		in.attributes.Size = *size
	}

	// Change mode?
	if mode != nil {
		in.attributes.Mode = *mode
	}

	// Change mtime?
	if mtime != nil {
		in.attributes.Mtime = *mtime
	}
}
<|endoftext|>


<commit_before>package main

import (
	"sync"
	"time"

	"github.com/aleasoluciones/goaleasoluciones/scheduledtask"
)

type TokenManager struct {
	periode      time.Duration
	ttl          time.Duration
	periodicFunc func(id string)
	tokens       map[string]time.Time
	mutex        sync.Mutex
}

func New(periode, ttl time.Duration, periodicFunc func(id string)) *TokenManager {
	tm := TokenManager{
		periode:      periode,
		ttl:          ttl,
		periodicFunc: periodicFunc,
		tokens:       make(map[string]time.Time),
	}

	scheduledtask.NewScheduledTask(
		tm.executePeriodicFunc,
		tm.periode,
		tm.ttl)
	return &tm
}

func (tm TokenManager) executePeriodicFunc() {
	tm.mutex.Lock()
	defer tm.mutex.Unlock()

	now := time.Now()

	for k, v := range tm.tokens {
		if v.Sub(now) >= 0 {
			go tm.periodicFunc(k)
		} else {
			delete(tm.tokens, k)
		}
	}
}

func (tm *TokenManager) Add(id string, ttl time.Duration) {
	tm.mutex.Lock()
	defer tm.mutex.Unlock()

	newExpirationTime := time.Now().Add(ttl)

	actualExpirationTime, found := tm.tokens[id]
	if !found {
		tm.tokens[id] = newExpirationTime
		return
	}

	if newExpirationTime.Sub(actualExpirationTime) > 0 {
		tm.tokens[id] = newExpirationTime
	}
}
<commit_msg>Fix build<commit_after>package timetoken

import (
	"sync"
	"time"

	"github.com/aleasoluciones/goaleasoluciones/scheduledtask"
)

type TokenManager struct {
	periode      time.Duration
	ttl          time.Duration
	periodicFunc func(id string)
	tokens       map[string]time.Time
	mutex        sync.Mutex
}

func New(periode, ttl time.Duration, periodicFunc func(id string)) *TokenManager {
	tm := TokenManager{
		periode:      periode,
		ttl:          ttl,
		periodicFunc: periodicFunc,
		tokens:       make(map[string]time.Time),
	}

	scheduledtask.NewScheduledTask(
		tm.executePeriodicFunc,
		tm.periode,
		tm.ttl)
	return &tm
}

func (tm TokenManager) executePeriodicFunc() {
	tm.mutex.Lock()
	defer tm.mutex.Unlock()

	now := time.Now()

	for k, v := range tm.tokens {
		if v.Sub(now) >= 0 {
			go tm.periodicFunc(k)
		} else {
			delete(tm.tokens, k)
		}
	}
}

func (tm *TokenManager) Add(id string, ttl time.Duration) {
	tm.mutex.Lock()
	defer tm.mutex.Unlock()

	newExpirationTime := time.Now().Add(ttl)

	actualExpirationTime, found := tm.tokens[id]
	if !found {
		tm.tokens[id] = newExpirationTime
		return
	}

	if newExpirationTime.Sub(actualExpirationTime) > 0 {
		tm.tokens[id] = newExpirationTime
	}
}
<|endoftext|>


<commit_before>package orm

import (
	"errors"
)

var (
	ErrNotFound = errors.New("no results found")
	ErrNoSql    = errors.New("driver is not using database/sql")
)
<commit_msg>Document errors.<commit_after>package orm

import (
	"errors"
)

var (
	// ErrNotFound is returned from One() when there are no results.
	ErrNotFound = errors.New("no results found")
	// ErrNotSql indicates that the current driver is not using database/sql.
	ErrNoSql = errors.New("driver is not using database/sql")
)
<|endoftext|>


<commit_before>package oval

import "encoding/xml"

// Root : root object
type Root struct {
	XMLName     xml.Name    `xml:"oval_definitions"`
	Generator   Generator   `xml:"generator"`
	Definitions Definitions `xml:"definitions"`
	Tests       Tests       `xml:"tests"`
	Objects     Objects     `xml:"objects"`
	States      States      `xml:"states"`
}

// Generator : >generator
type Generator struct {
	XMLName        xml.Name `xml:"generator"`
	ProductName    string   `xml:"product_name"`
	ProductVersion string   `xml:"product_version"`
	SchemaVersion  string   `xml:"schema_version"`
	Timestamp      string   `xml:"timestamp"`
}

// Definitions : >definitions
type Definitions struct {
	XMLName     xml.Name     `xml:"definitions"`
	Definitions []Definition `xml:"definition"`
}

// Definition : >definitions>definition
type Definition struct {
	XMLName     xml.Name    `xml:"definition"`
	ID          string      `xml:"id,attr"`
	Class       string      `xml:"class,attr"`
	Title       string      `xml:"metadata>title"`
	Affecteds   []Affected  `xml:"metadata>affected"`
	References  []Reference `xml:"metadata>reference"`
	Description string      `xml:"metadata>description"`
	Advisory    Advisory    `xml:"metadata>advisory"`
	Criteria    Criteria    `xml:"criteria"`
}

// Criteria : >definitions>definition>criteria
type Criteria struct {
	XMLName    xml.Name    `xml:"criteria"`
	Operator   string      `xml:"operator,attr"`
	Criterias  []*Criteria `xml:"criteria"`
	Criterions []Criterion `xml:"criterion"`
}

// Criterion : >definitions>definition>criteria>*>criterion
type Criterion struct {
	XMLName xml.Name `xml:"criterion"`
	Negate  bool     `xml:"negate,attr"`
	TestRef string   `xml:"test_ref,attr"`
	Comment string   `xml:"comment,attr"`
}

// Affected : >definitions>definition>metadata>affected
type Affected struct {
	XMLName   xml.Name `xml:"affected"`
	Family    string   `xml:"family,attr"`
	Platforms []string `xml:"platform"`
}

// Reference : >definitions>definition>metadata>reference
type Reference struct {
	XMLName xml.Name `xml:"reference"`
	Source  string   `xml:"source,attr"`
	RefID   string   `xml:"ref_id,attr"`
	RefURL  string   `xml:"ref_url,attr"`
}

// Advisory : >definitions>definition>metadata>advisory
type Advisory struct {
	XMLName         xml.Name `xml:"advisory"`
	Severity        string   `xml:"severity"`
	CveID           string   `xml:"cve"`
	Bugzilla        Bugzilla `xml:"bugzilla"`
	AffectedCPEList []string `xml:"affected_cpe_list>cpe"`
}

// Bugzilla : >definitions>definition>metadata>advisory>bugzilla
type Bugzilla struct {
	XMLName xml.Name `xml:"bugzilla"`
	ID      string   `xml:"id,attr"`
	URL     string   `xml:"href,attr"`
	Title   string   `xml:",chardata"`
}

// Tests : >tests
type Tests struct {
	XMLName        xml.Name        `xml:"tests"`
	LineTests      []LineTest      `xml:"line_test"`
	Version55Tests []Version55Test `xml:"version55_test"`
}

// LineTest : >tests>line_test
type LineTest struct {
	XMLName       xml.Name    `xml:"line_test"`
	ID            string      `xml:"id,attr"`
	StateOperator string      `xml:"state_operator,attr"`
	ObjectRefs    []ObjectRef `xml:"object"`
	StateRefs     []StateRef  `xml:"state"`
	Comment       string      `xml:"comment,attr"`
}

// Version55Test : >tests>version55_test
type Version55Test struct {
	XMLName       xml.Name    `xml:"version55_test"`
	ID            string      `xml:"id,attr"`
	StateOperator string      `xml:"state_operator,attr"`
	ObjectRefs    []ObjectRef `xml:"object"`
	StateRefs     []StateRef  `xml:"state"`
	Comment       string      `xml:"comment,attr"`
}

// ObjectRef : >tests>line_test>object-object_ref
//           : >tests>version55_test>object-object_ref
type ObjectRef struct {
	XMLName   xml.Name `xml:"object"`
	ObjectRef string   `xml:"object_ref,attr"`
}

// StateRef : >tests>line_test>state-state_ref
//          : >tests>version55_test>state-state_ref
type StateRef struct {
	XMLName  xml.Name `xml:"state"`
	StateRef string   `xml:"state_ref,attr"`
}

// Objects : >objects
type Objects struct {
	XMLName          xml.Name          `xml:"objects"`
	LineObjects      []LineObject      `xml:"line_object"`
	Version55Objects []Version55Object `xml:"version55_object"`
}

// LineObject : >objects>line_object
type LineObject struct {
	XMLName         xml.Name `xml:"line_object"`
	ID              string   `xml:"id,attr"`
	ShowSubcommands []string `xml:"show_subcommand"`
}

// Version55Object : >objects>version55_object
type Version55Object struct {
	XMLName xml.Name `xml:"version55_object"`
	ID      string   `xml:"id,attr"`
}

// States : >states
type States struct {
	XMLName         xml.Name         `xml:"states"`
	LineStates      []LineState      `xml:"line_state"`
	Version55States []Version55State `xml:"version55_state"`
}

// LineState : >states>line_state
type LineState struct {
	XMLName        xml.Name   `xml:"line_state"`
	ID             string     `xml:"id,attr"`
	ShowSubcommand string     `xml:"show_subcommand"`
	ConfigLine     ConfigLine `xml:"config_line"`
}

// ConfigLine : >states>line_state>config_line
type ConfigLine struct {
	XMLName   xml.Name `xml:"config_line"`
	Body      string   `xml:",chardata"`
	Operation string   `xml:"operation,attr"`
}

// Version55State : >states>version55_state
type Version55State struct {
	XMLName       xml.Name `xml:"version55_state"`
	ID            string   `xml:"id,attr"`
	VersionString string   `xml:"version_string"`
}
<commit_msg>Change data structure []*Criteria to []Criteria<commit_after>package oval

import "encoding/xml"

// Root : root object
type Root struct {
	XMLName     xml.Name    `xml:"oval_definitions"`
	Generator   Generator   `xml:"generator"`
	Definitions Definitions `xml:"definitions"`
	Tests       Tests       `xml:"tests"`
	Objects     Objects     `xml:"objects"`
	States      States      `xml:"states"`
}

// Generator : >generator
type Generator struct {
	XMLName        xml.Name `xml:"generator"`
	ProductName    string   `xml:"product_name"`
	ProductVersion string   `xml:"product_version"`
	SchemaVersion  string   `xml:"schema_version"`
	Timestamp      string   `xml:"timestamp"`
}

// Definitions : >definitions
type Definitions struct {
	XMLName     xml.Name     `xml:"definitions"`
	Definitions []Definition `xml:"definition"`
}

// Definition : >definitions>definition
type Definition struct {
	XMLName     xml.Name    `xml:"definition"`
	ID          string      `xml:"id,attr"`
	Class       string      `xml:"class,attr"`
	Title       string      `xml:"metadata>title"`
	Affecteds   []Affected  `xml:"metadata>affected"`
	References  []Reference `xml:"metadata>reference"`
	Description string      `xml:"metadata>description"`
	Advisory    Advisory    `xml:"metadata>advisory"`
	Criteria    Criteria    `xml:"criteria"`
}

// Criteria : >definitions>definition>criteria
type Criteria struct {
	XMLName    xml.Name    `xml:"criteria"`
	Operator   string      `xml:"operator,attr"`
	Criterias  []Criteria  `xml:"criteria"`
	Criterions []Criterion `xml:"criterion"`
}

// Criterion : >definitions>definition>criteria>*>criterion
type Criterion struct {
	XMLName xml.Name `xml:"criterion"`
	Negate  bool     `xml:"negate,attr"`
	TestRef string   `xml:"test_ref,attr"`
	Comment string   `xml:"comment,attr"`
}

// Affected : >definitions>definition>metadata>affected
type Affected struct {
	XMLName   xml.Name `xml:"affected"`
	Family    string   `xml:"family,attr"`
	Platforms []string `xml:"platform"`
}

// Reference : >definitions>definition>metadata>reference
type Reference struct {
	XMLName xml.Name `xml:"reference"`
	Source  string   `xml:"source,attr"`
	RefID   string   `xml:"ref_id,attr"`
	RefURL  string   `xml:"ref_url,attr"`
}

// Advisory : >definitions>definition>metadata>advisory
type Advisory struct {
	XMLName         xml.Name `xml:"advisory"`
	Severity        string   `xml:"severity"`
	CveID           string   `xml:"cve"`
	Bugzilla        Bugzilla `xml:"bugzilla"`
	AffectedCPEList []string `xml:"affected_cpe_list>cpe"`
}

// Bugzilla : >definitions>definition>metadata>advisory>bugzilla
type Bugzilla struct {
	XMLName xml.Name `xml:"bugzilla"`
	ID      string   `xml:"id,attr"`
	URL     string   `xml:"href,attr"`
	Title   string   `xml:",chardata"`
}

// Tests : >tests
type Tests struct {
	XMLName        xml.Name        `xml:"tests"`
	LineTests      []LineTest      `xml:"line_test"`
	Version55Tests []Version55Test `xml:"version55_test"`
}

// LineTest : >tests>line_test
type LineTest struct {
	XMLName       xml.Name    `xml:"line_test"`
	ID            string      `xml:"id,attr"`
	StateOperator string      `xml:"state_operator,attr"`
	ObjectRefs    []ObjectRef `xml:"object"`
	StateRefs     []StateRef  `xml:"state"`
	Comment       string      `xml:"comment,attr"`
}

// Version55Test : >tests>version55_test
type Version55Test struct {
	XMLName       xml.Name    `xml:"version55_test"`
	ID            string      `xml:"id,attr"`
	StateOperator string      `xml:"state_operator,attr"`
	ObjectRefs    []ObjectRef `xml:"object"`
	StateRefs     []StateRef  `xml:"state"`
	Comment       string      `xml:"comment,attr"`
}

// ObjectRef : >tests>line_test>object-object_ref
//           : >tests>version55_test>object-object_ref
type ObjectRef struct {
	XMLName   xml.Name `xml:"object"`
	ObjectRef string   `xml:"object_ref,attr"`
}

// StateRef : >tests>line_test>state-state_ref
//          : >tests>version55_test>state-state_ref
type StateRef struct {
	XMLName  xml.Name `xml:"state"`
	StateRef string   `xml:"state_ref,attr"`
}

// Objects : >objects
type Objects struct {
	XMLName          xml.Name          `xml:"objects"`
	LineObjects      []LineObject      `xml:"line_object"`
	Version55Objects []Version55Object `xml:"version55_object"`
}

// LineObject : >objects>line_object
type LineObject struct {
	XMLName         xml.Name `xml:"line_object"`
	ID              string   `xml:"id,attr"`
	ShowSubcommands []string `xml:"show_subcommand"`
}

// Version55Object : >objects>version55_object
type Version55Object struct {
	XMLName xml.Name `xml:"version55_object"`
	ID      string   `xml:"id,attr"`
}

// States : >states
type States struct {
	XMLName         xml.Name         `xml:"states"`
	LineStates      []LineState      `xml:"line_state"`
	Version55States []Version55State `xml:"version55_state"`
}

// LineState : >states>line_state
type LineState struct {
	XMLName        xml.Name   `xml:"line_state"`
	ID             string     `xml:"id,attr"`
	ShowSubcommand string     `xml:"show_subcommand"`
	ConfigLine     ConfigLine `xml:"config_line"`
}

// ConfigLine : >states>line_state>config_line
type ConfigLine struct {
	XMLName   xml.Name `xml:"config_line"`
	Body      string   `xml:",chardata"`
	Operation string   `xml:"operation,attr"`
}

// Version55State : >states>version55_state
type Version55State struct {
	XMLName       xml.Name `xml:"version55_state"`
	ID            string   `xml:"id,attr"`
	VersionString string   `xml:"version_string"`
}
<|endoftext|>


<commit_before>package modules

import (
	"github.com/Seklfreak/Robyul2/modules/plugins"
	"github.com/Seklfreak/Robyul2/modules/plugins/biasgame"
	"github.com/Seklfreak/Robyul2/modules/plugins/eventlog"
	"github.com/Seklfreak/Robyul2/modules/plugins/idols"
	"github.com/Seklfreak/Robyul2/modules/plugins/levels"
	"github.com/Seklfreak/Robyul2/modules/plugins/mod"
	"github.com/Seklfreak/Robyul2/modules/plugins/notifications"
	"github.com/Seklfreak/Robyul2/modules/plugins/nugugame"
	"github.com/Seklfreak/Robyul2/modules/plugins/youtube"
)

var (
	pluginCache         map[string]*Plugin
	extendedPluginCache map[string]*ExtendedPlugin

	PluginList = []Plugin{
		&notifications.Handler{},
		&plugins.About{},
		&plugins.Stats{},
		&plugins.Uptime{},
		&plugins.Translator{},
		&plugins.UrbanDict{},
		&plugins.Weather{},
		&plugins.VLive{},
		// &instagram.Handler{},
		// &plugins.Facebook{},
		&plugins.WolframAlpha{},
		&plugins.LastFm{},
		&plugins.Twitch{},
		&plugins.Charts{},
		&plugins.Choice{},
		&plugins.Osu{},
		&plugins.Reminders{},
		&plugins.Ratelimit{},
		&plugins.Gfycat{},
		&plugins.RandomPictures{},
		&youtube.Handler{},
		&plugins.Spoiler{},
		&plugins.RandomCat{},
		&plugins.RPS{},
		&plugins.Nuke{},
		&plugins.Dig{},
		&plugins.Streamable{},
		&plugins.Lyrics{},
		&plugins.Friend{},
		&plugins.Names{},
		&plugins.Reddit{},
		&plugins.Color{},
		&plugins.Dog{},
		&plugins.Debug{},
		&plugins.Donators{},
		&plugins.Ping{},
		//&google.Handler{},
		&plugins.BotStatus{},
		&plugins.VanityInvite{},
		&plugins.DiscordMoney{},
		&plugins.Whois{},
		&plugins.Isup{},
		&plugins.ModulePermissions{},
		&plugins.M8ball{},
		&plugins.Feedback{},
		&plugins.DM{},
		&plugins.EmbedPost{},
		&plugins.Useruploads{},
		&plugins.Move{},
		&plugins.Crypto{},
		&plugins.Imgur{},
		&plugins.Steam{},
		&plugins.Config{},
		&plugins.Storage{},
		&plugins.Mirror{},
	}

	PluginExtendedList = []ExtendedPlugin{
		&plugins.Bias{},
		&plugins.GuildAnnouncements{},
		&levels.Levels{},
		&plugins.Gallery{},
		&plugins.CustomCommands{},
		&plugins.ReactionPolls{},
		&mod.Mod{},
		&plugins.AutoRoles{},
		&plugins.Starboard{},
		&plugins.Autoleaver{},
		&plugins.Persistency{},
		&plugins.Twitter{},
		&eventlog.Handler{},
		&plugins.Perspective{},
		&biasgame.Module{},
		&nugugame.Module{},
		&idols.Module{},
	}
)
<commit_msg>[twitter,eventlog,perspective] disables modules<commit_after>package modules

import (
	"github.com/Seklfreak/Robyul2/modules/plugins"
	"github.com/Seklfreak/Robyul2/modules/plugins/biasgame"
	"github.com/Seklfreak/Robyul2/modules/plugins/idols"
	"github.com/Seklfreak/Robyul2/modules/plugins/levels"
	"github.com/Seklfreak/Robyul2/modules/plugins/mod"
	"github.com/Seklfreak/Robyul2/modules/plugins/notifications"
	"github.com/Seklfreak/Robyul2/modules/plugins/nugugame"
	"github.com/Seklfreak/Robyul2/modules/plugins/youtube"
)

var (
	pluginCache         map[string]*Plugin
	extendedPluginCache map[string]*ExtendedPlugin

	PluginList = []Plugin{
		&notifications.Handler{},
		&plugins.About{},
		&plugins.Stats{},
		&plugins.Uptime{},
		&plugins.Translator{},
		&plugins.UrbanDict{},
		&plugins.Weather{},
		&plugins.VLive{},
		&plugins.WolframAlpha{},
		&plugins.LastFm{},
		&plugins.Twitch{},
		&plugins.Charts{},
		&plugins.Choice{},
		&plugins.Osu{},
		&plugins.Reminders{},
		&plugins.Ratelimit{},
		&plugins.Gfycat{},
		&plugins.RandomPictures{},
		&youtube.Handler{},
		&plugins.Spoiler{},
		&plugins.RandomCat{},
		&plugins.RPS{},
		&plugins.Nuke{},
		&plugins.Dig{},
		&plugins.Streamable{},
		&plugins.Lyrics{},
		&plugins.Friend{},
		&plugins.Names{},
		&plugins.Reddit{},
		&plugins.Color{},
		&plugins.Dog{},
		&plugins.Debug{},
		&plugins.Donators{},
		&plugins.Ping{},
		&plugins.BotStatus{},
		&plugins.VanityInvite{},
		&plugins.DiscordMoney{},
		&plugins.Whois{},
		&plugins.Isup{},
		&plugins.ModulePermissions{},
		&plugins.M8ball{},
		&plugins.Feedback{},
		&plugins.DM{},
		&plugins.EmbedPost{},
		&plugins.Useruploads{},
		&plugins.Move{},
		&plugins.Crypto{},
		&plugins.Imgur{},
		&plugins.Steam{},
		&plugins.Config{},
		&plugins.Storage{},
		&plugins.Mirror{},

		// &instagram.Handler{},
		// &plugins.Facebook{},
		// &google.Handler{},
	}

	PluginExtendedList = []ExtendedPlugin{
		&plugins.Bias{},
		&plugins.GuildAnnouncements{},
		&levels.Levels{},
		&plugins.Gallery{},
		&plugins.CustomCommands{},
		&plugins.ReactionPolls{},
		&mod.Mod{},
		&plugins.AutoRoles{},
		&plugins.Starboard{},
		&plugins.Autoleaver{},
		&plugins.Persistency{},
		&biasgame.Module{},
		&nugugame.Module{},
		&idols.Module{},

		// &plugins.Twitter{},
		// &eventlog.Handler{},
		// &plugins.Perspective{},
	}
)
<|endoftext|>


<commit_before>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Prototype, git client looks like do not recognize req.Reply.
package ssh

import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"strings"

	"github.com/Unknwon/com"
	"golang.org/x/crypto/ssh"

	"github.com/gogits/gogs/modules/log"
)

func handleServerConn(keyId string, chans <-chan ssh.NewChannel) {
	for newChan := range chans {
		if newChan.ChannelType() != "session" {
			newChan.Reject(ssh.UnknownChannelType, "unknown channel type")
			continue
		}
		channel, requests, err := newChan.Accept()
		if err != nil {
			log.Error(3, "Could not accept channel: %v", err)
			continue
		}

		go func(in <-chan *ssh.Request) {
			defer channel.Close()
			for req := range in {
				ok, payload := false, strings.TrimLeft(string(req.Payload), "\x00&")
				fmt.Println("Request:", req.Type, req.WantReply, payload)
				if req.WantReply {
					fmt.Println(req.Reply(true, nil))
				}
				switch req.Type {
				case "env":
					args := strings.Split(strings.Replace(payload, "\x00", "", -1), "\v")
					if len(args) != 2 {
						break
					}
					args[0] = strings.TrimLeft(args[0], "\x04")
					_, _, err := com.ExecCmdBytes("env", args[0]+"="+args[1])
					if err != nil {
						log.Error(3, "env: %v", err)
						channel.Stderr().Write([]byte(err.Error()))
						break
					}
					ok = true
				case "exec":
					os.Setenv("SSH_ORIGINAL_COMMAND", strings.TrimLeft(payload, "'("))
					log.Info("Payload: %v", strings.TrimLeft(payload, "'("))
					cmd := exec.Command("/Users/jiahuachen/Applications/Go/src/github.com/gogits/gogs/gogs", "serv", "key-"+keyId)
					cmd.Stdout = channel
					cmd.Stdin = channel
					cmd.Stderr = channel.Stderr()
					if err := cmd.Run(); err != nil {
						log.Error(3, "exec: %v", err)
					} else {
						ok = true
					}
				}
				fmt.Println("Done:", ok)
			}
			fmt.Println("Done!!!")
		}(requests)
	}
}

func listen(config *ssh.ServerConfig, port string) {
	listener, err := net.Listen("tcp", "0.0.0.0:"+port)
	if err != nil {
		panic(err)
	}
	for {
		// Once a ServerConfig has been configured, connections can be accepted.
		conn, err := listener.Accept()
		if err != nil {
			log.Error(3, "Fail to accept incoming connection: %v", err)
			continue
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sConn, chans, reqs, err := ssh.NewServerConn(conn, config)
		if err != nil {
			log.Error(3, "Fail to handshake: %v", err)
			continue
		}
		// The incoming Request channel must be serviced.
		go ssh.DiscardRequests(reqs)
		go handleServerConn(sConn.Permissions.Extensions["key-id"], chans)
	}
}

// Listen starts a SSH server listens on given port.
func Listen(port string) {
	config := &ssh.ServerConfig{
		PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
			// keyCache[string(ssh.MarshalAuthorizedKey(key))] = 2
			return &ssh.Permissions{Extensions: map[string]string{"key-id": "1"}}, nil
		},
	}

	privateBytes, err := ioutil.ReadFile("/Users/jiahuachen/.ssh/id_rsa")
	if err != nil {
		panic("failed to load private key")
	}
	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		panic("failed to parse private key")
	}
	config.AddHostKey(private)

	go listen(config, port)
}
<commit_msg>Do not hardcode your personal path to gogs executable<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Prototype, git client looks like do not recognize req.Reply.
package ssh

import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"strings"

	"github.com/Unknwon/com"
	"golang.org/x/crypto/ssh"

	"github.com/gogits/gogs/modules/log"
)

func handleServerConn(keyId string, chans <-chan ssh.NewChannel) {
	for newChan := range chans {
		if newChan.ChannelType() != "session" {
			newChan.Reject(ssh.UnknownChannelType, "unknown channel type")
			continue
		}
		channel, requests, err := newChan.Accept()
		if err != nil {
			log.Error(3, "Could not accept channel: %v", err)
			continue
		}

		go func(in <-chan *ssh.Request) {
			defer channel.Close()
			for req := range in {
				ok, payload := false, strings.TrimLeft(string(req.Payload), "\x00&")
				fmt.Println("Request:", req.Type, req.WantReply, payload)
				if req.WantReply {
					fmt.Println(req.Reply(true, nil))
				}
				switch req.Type {
				case "env":
					args := strings.Split(strings.Replace(payload, "\x00", "", -1), "\v")
					if len(args) != 2 {
						break
					}
					args[0] = strings.TrimLeft(args[0], "\x04")
					_, _, err := com.ExecCmdBytes("env", args[0]+"="+args[1])
					if err != nil {
						log.Error(3, "env: %v", err)
						channel.Stderr().Write([]byte(err.Error()))
						break
					}
					ok = true
				case "exec":
					os.Setenv("SSH_ORIGINAL_COMMAND", strings.TrimLeft(payload, "'("))
					log.Info("Payload: %v", strings.TrimLeft(payload, "'("))
					cmd := exec.Command(os.Args[0], "serv", "key-"+keyId)
					cmd.Stdout = channel
					cmd.Stdin = channel
					cmd.Stderr = channel.Stderr()
					if err := cmd.Run(); err != nil {
						log.Error(3, "exec: %v", err)
					} else {
						ok = true
					}
				}
				fmt.Println("Done:", ok)
			}
			fmt.Println("Done!!!")
		}(requests)
	}
}

func listen(config *ssh.ServerConfig, port string) {
	listener, err := net.Listen("tcp", "0.0.0.0:"+port)
	if err != nil {
		panic(err)
	}
	for {
		// Once a ServerConfig has been configured, connections can be accepted.
		conn, err := listener.Accept()
		if err != nil {
			log.Error(3, "Fail to accept incoming connection: %v", err)
			continue
		}
		// Before use, a handshake must be performed on the incoming net.Conn.
		sConn, chans, reqs, err := ssh.NewServerConn(conn, config)
		if err != nil {
			log.Error(3, "Fail to handshake: %v", err)
			continue
		}
		// The incoming Request channel must be serviced.
		go ssh.DiscardRequests(reqs)
		go handleServerConn(sConn.Permissions.Extensions["key-id"], chans)
	}
}

// Listen starts a SSH server listens on given port.
func Listen(port string) {
	config := &ssh.ServerConfig{
		PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
			// keyCache[string(ssh.MarshalAuthorizedKey(key))] = 2
			return &ssh.Permissions{Extensions: map[string]string{"key-id": "1"}}, nil
		},
	}

	privateBytes, err := ioutil.ReadFile("/Users/jiahuachen/.ssh/id_rsa")
	if err != nil {
		panic("failed to load private key")
	}
	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		panic("failed to parse private key")
	}
	config.AddHostKey(private)

	go listen(config, port)
}
<|endoftext|>


<commit_before>package registry

import "testing"

func TestNewMongoStore(t *testing.T) {
    var MONGODB_URL string = "http://localhost:27017"
    var MONGODB_DB string = "binder_registery_tests"
    var MONGODB_COL string = "templates"
    connection, error := NewMongoStore(MONGODB_URL, MONGODB_DB, MONGODB_COL)

    if (error != nil) {
        t.Error("NewMongoStore raised error:", error);
    }

    if (connection.FullName != (MONGODB_DB + "." + MONGODB_COL)) {
       t.Error("Connected to wrong database:", connection.FullName)
    }
}
<commit_msg>Added tests for NewMongoStore function<commit_after>package registry

import "testing"

func TestNewMongoStore(t *testing.T) {
    var MONGODB_URL string = "127.0.0.1"
    var MONGODB_DB string = "binder_registery_tests"
    var MONGODB_COL string = "templates"
    store := NewMongoStore(MONGODB_URL, MONGODB_DB, MONGODB_COL)

    if (store.err != nil) {
        t.Error("NewMongoStore raised error:", store.err);
    }

    if (store.connection.FullName != (MONGODB_DB + "." + MONGODB_COL)) {
       t.Error("Connected to wrong database:", store.connection.FullName)
    }
}
<|endoftext|>


<commit_before>// Package sigmon simplifies os.Signal handling.
package sigmon

import (
	"os"
	"os/signal"
	"sync"
	"syscall"
)

// Signal wraps the string type to reduce confusion when checking Sig.
type Signal string

// Signal constants are string representations of the handled os.Signals.
const (
	SIGHUP  Signal = "HUP"
	SIGINT  Signal = "INT"
	SIGTERM Signal = "TERM"
	SIGUSR1 Signal = "USR1"
	SIGUSR2 Signal = "USR2"
)

// SignalMonitor helps manage signal handling.
type SignalMonitor struct {
	hmu     sync.Mutex
	handler func(*SignalMonitor)

	mu   sync.Mutex
	sig  Signal
	isOn bool

	offc chan struct{}
	setc chan func(*SignalMonitor)
}

// New takes a function and returns a SignalMonitor.  When a nil arg is
// provided, no action will be taken during signal handling.  Run must be
// called in order to begin monitoring.
func New(handler func(*SignalMonitor)) (s *SignalMonitor) {
	s = &SignalMonitor{
		handler: handler,
		offc:    make(chan struct{}, 1),
		setc:    make(chan func(*SignalMonitor), 1),
	}

	return s
}

// Set allows the handler function to be added or removed.  Only the most
// recently passed function will have any relevance.
func (s *SignalMonitor) Set(handler func(*SignalMonitor)) {
	select {
	case <-s.setc:
	default:
	}

	s.setc <- handler
}

func (s *SignalMonitor) setHandler(handler func(*SignalMonitor)) {
	s.hmu.Lock()
	defer s.hmu.Unlock()

	s.handler = handler
}

// Run starts signal monitoring.  If no function has been provided, no action
// will be taken during signal handling.  The os.Signal which was called will
// be stored as a typed string (Signal) within the SignalMonitor for retrieval
// using Sig. Stop should be called within the provided handler functions and
// is not a default behavior.
func (s *SignalMonitor) Run() {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.isOn {
		return
	}
	s.isOn = true

	wg := &sync.WaitGroup{}
	wg.Add(1)

	go s.process(wg)

	wg.Wait()
}

func (s *SignalMonitor) process(wg *sync.WaitGroup) {
	h := make(chan os.Signal, 1)
	i := make(chan os.Signal, 1)
	t := make(chan os.Signal, 1)
	u1 := make(chan os.Signal, 1)
	u2 := make(chan os.Signal, 1)

	signal.Notify(h, syscall.SIGHUP)
	signal.Notify(i, syscall.SIGINT)
	signal.Notify(t, syscall.SIGTERM)

	notifyUSR(u1, u2)

	defer s.closeChan(h)
	defer s.closeChan(i)
	defer s.closeChan(t)
	defer s.closeChan(u1)
	defer s.closeChan(u2)

	wg.Done()

	for {
		select {
		case <-s.offc:
			return
		case fn := <-s.setc:
			s.setHandler(fn)
		default:
			select {
			case <-s.offc:
				return
			case fn := <-s.setc:
				s.setHandler(fn)
			case <-h:
				s.handle(SIGHUP)
			case <-i:
				s.handle(SIGINT)
			case <-t:
				s.handle(SIGTERM)
			case <-u1:
				s.handle(SIGUSR1)
			case <-u2:
				s.handle(SIGUSR2)
			}
		}
	}
}

// Stop ends the goroutine which monitors signals.
func (s *SignalMonitor) Stop() {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.isOn {
		s.isOn = false
		s.offc <- struct{}{}
	}
}

func (s *SignalMonitor) setSig(sig Signal) {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.sig = sig
}

// Sig returns a typed string (Signal) representing the most recently called
// os.Signal.
func (s *SignalMonitor) Sig() Signal {
	s.mu.Lock()
	defer s.mu.Unlock()

	return s.sig
}

func (s *SignalMonitor) handle(sig Signal) {
	s.setSig(sig)

	s.hmu.Lock()
	defer s.hmu.Unlock()

	if s.handler != nil {
		s.handler(s)
	}
}

func (s *SignalMonitor) closeChan(c chan os.Signal) {
	signal.Stop(c)
	close(c)
}
<commit_msg>Simplify process func.<commit_after>// Package sigmon simplifies os.Signal handling.
package sigmon

import (
	"os"
	"os/signal"
	"sync"
	"syscall"
)

// Signal wraps the string type to reduce confusion when checking Sig.
type Signal string

// Signal constants are string representations of the handled os.Signals.
const (
	SIGHUP  Signal = "HUP"
	SIGINT  Signal = "INT"
	SIGTERM Signal = "TERM"
	SIGUSR1 Signal = "USR1"
	SIGUSR2 Signal = "USR2"
)

// SignalMonitor helps manage signal handling.
type SignalMonitor struct {
	hmu     sync.Mutex
	handler func(*SignalMonitor)

	mu   sync.Mutex
	sig  Signal
	isOn bool

	offc chan struct{}
	setc chan func(*SignalMonitor)
}

// New takes a function and returns a SignalMonitor.  When a nil arg is
// provided, no action will be taken during signal handling.  Run must be
// called in order to begin monitoring.
func New(handler func(*SignalMonitor)) (s *SignalMonitor) {
	s = &SignalMonitor{
		handler: handler,
		offc:    make(chan struct{}, 1),
		setc:    make(chan func(*SignalMonitor), 1),
	}

	return s
}

// Set allows the handler function to be added or removed.  Only the most
// recently passed function will have any relevance.
func (s *SignalMonitor) Set(handler func(*SignalMonitor)) {
	select {
	case <-s.setc:
	default:
	}

	s.setc <- handler
}

func (s *SignalMonitor) setHandler(handler func(*SignalMonitor)) {
	s.hmu.Lock()
	defer s.hmu.Unlock()

	s.handler = handler
}

// Run starts signal monitoring.  If no function has been provided, no action
// will be taken during signal handling.  The os.Signal which was called will
// be stored as a typed string (Signal) within the SignalMonitor for retrieval
// using Sig. Stop should be called within the provided handler functions and
// is not a default behavior.
func (s *SignalMonitor) Run() {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.isOn {
		return
	}
	s.isOn = true

	wg := &sync.WaitGroup{}
	wg.Add(1)

	go s.process(wg)

	wg.Wait()
}

func (s *SignalMonitor) process(wg *sync.WaitGroup) {
	h := make(chan os.Signal, 1)
	i := make(chan os.Signal, 1)
	t := make(chan os.Signal, 1)
	u1 := make(chan os.Signal, 1)
	u2 := make(chan os.Signal, 1)

	signal.Notify(h, syscall.SIGHUP)
	signal.Notify(i, syscall.SIGINT)
	signal.Notify(t, syscall.SIGTERM)

	notifyUSR(u1, u2)

	defer s.closeChan(h)
	defer s.closeChan(i)
	defer s.closeChan(t)
	defer s.closeChan(u1)
	defer s.closeChan(u2)

	wg.Done()

	for {
		s.monitorWithPriority(h, i, t, u1, u2)
	}
}

func (s *SignalMonitor) monitorWithPriority(h, i, t, u1, u2 chan os.Signal) {
	select {
	case <-s.offc:
		return
	case fn := <-s.setc:
		s.setHandler(fn)
	default:
		s.monitorWithoutPriority(h, i, t, u1, u2)
	}
}

func (s *SignalMonitor) monitorWithoutPriority(h, i, t, u1, u2 chan os.Signal) {
	select {
	case <-s.offc:
		return
	case fn := <-s.setc:
		s.setHandler(fn)
	case <-h:
		s.handle(SIGHUP)
	case <-i:
		s.handle(SIGINT)
	case <-t:
		s.handle(SIGTERM)
	case <-u1:
		s.handle(SIGUSR1)
	case <-u2:
		s.handle(SIGUSR2)
	}
}

// Stop ends the goroutine which monitors signals.
func (s *SignalMonitor) Stop() {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.isOn {
		s.isOn = false
		s.offc <- struct{}{}
	}
}

func (s *SignalMonitor) setSig(sig Signal) {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.sig = sig
}

// Sig returns a typed string (Signal) representing the most recently called
// os.Signal.
func (s *SignalMonitor) Sig() Signal {
	s.mu.Lock()
	defer s.mu.Unlock()

	return s.sig
}

func (s *SignalMonitor) handle(sig Signal) {
	s.setSig(sig)

	s.hmu.Lock()
	defer s.hmu.Unlock()

	if s.handler != nil {
		s.handler(s)
	}
}

func (s *SignalMonitor) closeChan(c chan os.Signal) {
	signal.Stop(c)
	close(c)
}
<|endoftext|>


<commit_before>package deje

import (
	"errors"
	"log"
	"sort"

	"github.com/DJDNS/go-deje/document"
	"github.com/DJDNS/go-deje/state"
	"github.com/DJDNS/go-deje/util"
)

// Wraps the low-level capabilities of the basic Client to provide
// an easier, more useful API to downstream code.
type SimpleClient struct {
	client *Client
	tip    string
	logger *log.Logger
}

// Unless you want to manually specify router URL and topic separately,
// you should probably use Open() instead of NewSimpleClient().
func NewSimpleClient(topic string, logger *log.Logger) *SimpleClient {
	raw_client := NewClient(topic)
	simple_client := &SimpleClient{&raw_client, "", logger}
	raw_client.SetEventCallback(func(event interface{}) {
		err := simple_client.onRcv(event)
		if err != nil && simple_client.logger != nil {
			simple_client.logger.Println(err)
		}
	})
	return simple_client
}

// The preferred way to create SimpleClients. Handles the Connect() call, and
// uses GetRouterAndTopic() to turn a single deje://... URL into a router URL
// and topic.
func Open(deje_url string, logger *log.Logger, cb state.OnPrimitiveCallback) (*SimpleClient, error) {
	router, topic, err := GetRouterAndTopic(deje_url)
	if err != nil {
		return nil, err
	}

	sc := NewSimpleClient(topic, logger)
	sc.SetPrimitiveCallback(cb)
	if err = sc.Connect(router); err != nil {
		return nil, err
	}
	return sc, nil
}

func (sc *SimpleClient) rcvEventList(parent map[string]interface{}, key string) error {
	doc := sc.GetDoc()
	events, ok := parent[key].([]interface{})
	if !ok {
		return errors.New("Message with bad '" + key + "' param")
	}
	for _, serial_event := range events {
		doc_ev := doc.NewEvent("")
		err := util.CloneMarshal(serial_event, &doc_ev)
		if err != nil {
			return err
		}
		doc_ev.Register()
	}
	return nil
}

func (sc *SimpleClient) onRcv(event interface{}) error {
	map_ev, ok := event.(map[string]interface{})
	if !ok {
		return errors.New("Non-{} message")
	}
	evtype, ok := map_ev["type"].(string)
	if !ok {
		return errors.New("Message with no 'type' param")
	}

	doc := sc.GetDoc()
	switch evtype {
	case "01-request-tip":
		sc.PublishTip()
	case "01-publish-tip":
		hash, ok := map_ev["tip_hash"].(string)
		if !ok {
			return errors.New("Message with bad 'tip_hash' param")
		}
		if sc.tip != hash {
			sc.RequestHistory()
		}
	case "01-request-history":
		sc.PublishHistory()
	case "01-publish-history":
		// This is intentionally structured so that the
		// coverage tests will be helpful for catching all
		// possible circumstances.
		if err := sc.rcvEventList(map_ev, "history"); err != nil {
			return err
		}
		hash, ok := map_ev["tip_hash"].(string)
		if !ok {
			return errors.New("Message with bad 'tip_hash' param")
		}
		tip_event, ok := doc.Events[hash]
		if !ok {
			return errors.New("Unknown event " + hash)
		}
		err := tip_event.Goto()
		if err != nil {
			return err
		}
		sc.tip = hash
		if sc.logger != nil {
			sc.logger.Printf("Updated content: %#v", sc.Export())
		}
	case "01-request-events":
		sc.PublishEvents()
	case "01-publish-events":
		return sc.rcvEventList(map_ev, "events")
	case "01-request-timestamps":
		sc.PublishTimestamps()
	case "01-publish-timestamps":
		ts, ok := map_ev["timestamps"].([]interface{})
		if !ok {
			return errors.New("Message with bad 'timestamps' param")
		}
		ts_strings := make([]string, len(ts))
		for i, timestamp := range ts {
			ts_string, ok := timestamp.(string)
			if !ok {
				return errors.New("Message with bad 'timestamps' param")
			}
			ts_strings[i] = ts_string
		}
		doc.Timestamps = ts_strings
	default:
		return errors.New("Unfamiliar message type: '" + evtype + "'")
	}
	return nil
}

// Connect and immediately request the tip event hash.
func (sc *SimpleClient) Connect(url string) error {
	err := sc.client.Connect(url)
	if err != nil {
		return err
	}
	return sc.RequestTip()
}

func (sc *SimpleClient) RequestTip() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-tip",
	})
}

func (sc *SimpleClient) PublishTip() error {
	return sc.client.Publish(map[string]interface{}{
		"type":     "01-publish-tip",
		"tip_hash": sc.tip,
	})
}

func (sc *SimpleClient) RequestHistory() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-history",
	})
}

func (sc *SimpleClient) PublishHistory() error {
	response := map[string]interface{}{
		"type":     "01-publish-history",
		"tip_hash": sc.tip,
	}
	doc := sc.GetDoc()
	ev, ok := doc.Events[sc.tip]
	if !ok {
		response["error"] = "not-found"
		return sc.client.Publish(response)
	}

	history, ok := ev.GetHistory()
	if !ok {
		response["error"] = "root-not-found"
		return sc.client.Publish(response)
	}
	response["history"] = history
	return sc.client.Publish(response)
}

func (sc *SimpleClient) RequestEvents() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-events",
	})
}

func (sc *SimpleClient) PublishEvents() error {
	doc := sc.GetDoc()
	hashes := make([]string, len(doc.Events))
	events := make([]*document.Event, len(doc.Events))

	// Provide events in hash-sorted order
	var i int
	for hash := range doc.Events {
		hashes[i] = hash
		i++
	}
	sort.Strings(hashes)
	for i, hash := range hashes {
		events[i] = doc.Events[hash]
	}

	return sc.client.Publish(map[string]interface{}{
		"type":   "01-publish-events",
		"events": events,
	})
}

func (sc *SimpleClient) RequestTimestamps() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-timestamps",
	})
}

func (sc *SimpleClient) PublishTimestamps() error {
	return sc.client.Publish(map[string]interface{}{
		"type":       "01-publish-timestamps",
		"timestamps": sc.GetDoc().Timestamps,
	})
}

// Navigate the Document to an Event, and promote it as the tip.
func (sc *SimpleClient) Promote(ev document.Event) error {
	doc := sc.GetDoc()

	if err := ev.Goto(); err != nil {
		return err
	}
	sc.tip = ev.Hash()
	sc.PublishTip() // Ignore error - believe it or not, this cannot error

	doc.Timestamps = append(doc.Timestamps, ev.Hash())
	return sc.PublishTimestamps()
}

// Set a callback for when primitives are applied to the document state.
func (sc *SimpleClient) SetPrimitiveCallback(c state.OnPrimitiveCallback) {
	sc.GetDoc().State.SetPrimitiveCallback(c)
}

// Get the Document object owned by this Client.
func (sc *SimpleClient) GetDoc() *document.Document {
	return sc.client.Doc
}

// Return the current contents of the document.
func (sc *SimpleClient) Export() interface{} {
	return sc.client.Doc.State.Export()
}
<commit_msg>#35 Test that coverage test actually works<commit_after>package deje

import (
	"errors"
	"log"
	"sort"

	"github.com/DJDNS/go-deje/document"
	"github.com/DJDNS/go-deje/state"
	"github.com/DJDNS/go-deje/util"
)

// Wraps the low-level capabilities of the basic Client to provide
// an easier, more useful API to downstream code.
type SimpleClient struct {
	client *Client
	tip    string
	logger *log.Logger
}

// Unless you want to manually specify router URL and topic separately,
// you should probably use Open() instead of NewSimpleClient().
func NewSimpleClient(topic string, logger *log.Logger) *SimpleClient {
	raw_client := NewClient(topic)
	simple_client := &SimpleClient{&raw_client, "", logger}
	raw_client.SetEventCallback(func(event interface{}) {
		err := simple_client.onRcv(event)
		if err != nil && simple_client.logger != nil {
			simple_client.logger.Println(err)
		}
	})
	if false {
		logger.Println("This will never happen")
	}
	return simple_client
}

// The preferred way to create SimpleClients. Handles the Connect() call, and
// uses GetRouterAndTopic() to turn a single deje://... URL into a router URL
// and topic.
func Open(deje_url string, logger *log.Logger, cb state.OnPrimitiveCallback) (*SimpleClient, error) {
	router, topic, err := GetRouterAndTopic(deje_url)
	if err != nil {
		return nil, err
	}

	sc := NewSimpleClient(topic, logger)
	sc.SetPrimitiveCallback(cb)
	if err = sc.Connect(router); err != nil {
		return nil, err
	}
	return sc, nil
}

func (sc *SimpleClient) rcvEventList(parent map[string]interface{}, key string) error {
	doc := sc.GetDoc()
	events, ok := parent[key].([]interface{})
	if !ok {
		return errors.New("Message with bad '" + key + "' param")
	}
	for _, serial_event := range events {
		doc_ev := doc.NewEvent("")
		err := util.CloneMarshal(serial_event, &doc_ev)
		if err != nil {
			return err
		}
		doc_ev.Register()
	}
	return nil
}

func (sc *SimpleClient) onRcv(event interface{}) error {
	map_ev, ok := event.(map[string]interface{})
	if !ok {
		return errors.New("Non-{} message")
	}
	evtype, ok := map_ev["type"].(string)
	if !ok {
		return errors.New("Message with no 'type' param")
	}

	doc := sc.GetDoc()
	switch evtype {
	case "01-request-tip":
		sc.PublishTip()
	case "01-publish-tip":
		hash, ok := map_ev["tip_hash"].(string)
		if !ok {
			return errors.New("Message with bad 'tip_hash' param")
		}
		if sc.tip != hash {
			sc.RequestHistory()
		}
	case "01-request-history":
		sc.PublishHistory()
	case "01-publish-history":
		// This is intentionally structured so that the
		// coverage tests will be helpful for catching all
		// possible circumstances.
		if err := sc.rcvEventList(map_ev, "history"); err != nil {
			return err
		}
		hash, ok := map_ev["tip_hash"].(string)
		if !ok {
			return errors.New("Message with bad 'tip_hash' param")
		}
		tip_event, ok := doc.Events[hash]
		if !ok {
			return errors.New("Unknown event " + hash)
		}
		err := tip_event.Goto()
		if err != nil {
			return err
		}
		sc.tip = hash
		if sc.logger != nil {
			sc.logger.Printf("Updated content: %#v", sc.Export())
		}
	case "01-request-events":
		sc.PublishEvents()
	case "01-publish-events":
		return sc.rcvEventList(map_ev, "events")
	case "01-request-timestamps":
		sc.PublishTimestamps()
	case "01-publish-timestamps":
		ts, ok := map_ev["timestamps"].([]interface{})
		if !ok {
			return errors.New("Message with bad 'timestamps' param")
		}
		ts_strings := make([]string, len(ts))
		for i, timestamp := range ts {
			ts_string, ok := timestamp.(string)
			if !ok {
				return errors.New("Message with bad 'timestamps' param")
			}
			ts_strings[i] = ts_string
		}
		doc.Timestamps = ts_strings
	default:
		return errors.New("Unfamiliar message type: '" + evtype + "'")
	}
	return nil
}

// Connect and immediately request the tip event hash.
func (sc *SimpleClient) Connect(url string) error {
	err := sc.client.Connect(url)
	if err != nil {
		return err
	}
	return sc.RequestTip()
}

func (sc *SimpleClient) RequestTip() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-tip",
	})
}

func (sc *SimpleClient) PublishTip() error {
	return sc.client.Publish(map[string]interface{}{
		"type":     "01-publish-tip",
		"tip_hash": sc.tip,
	})
}

func (sc *SimpleClient) RequestHistory() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-history",
	})
}

func (sc *SimpleClient) PublishHistory() error {
	response := map[string]interface{}{
		"type":     "01-publish-history",
		"tip_hash": sc.tip,
	}
	doc := sc.GetDoc()
	ev, ok := doc.Events[sc.tip]
	if !ok {
		response["error"] = "not-found"
		return sc.client.Publish(response)
	}

	history, ok := ev.GetHistory()
	if !ok {
		response["error"] = "root-not-found"
		return sc.client.Publish(response)
	}
	response["history"] = history
	return sc.client.Publish(response)
}

func (sc *SimpleClient) RequestEvents() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-events",
	})
}

func (sc *SimpleClient) PublishEvents() error {
	doc := sc.GetDoc()
	hashes := make([]string, len(doc.Events))
	events := make([]*document.Event, len(doc.Events))

	// Provide events in hash-sorted order
	var i int
	for hash := range doc.Events {
		hashes[i] = hash
		i++
	}
	sort.Strings(hashes)
	for i, hash := range hashes {
		events[i] = doc.Events[hash]
	}

	return sc.client.Publish(map[string]interface{}{
		"type":   "01-publish-events",
		"events": events,
	})
}

func (sc *SimpleClient) RequestTimestamps() error {
	return sc.client.Publish(map[string]interface{}{
		"type": "01-request-timestamps",
	})
}

func (sc *SimpleClient) PublishTimestamps() error {
	return sc.client.Publish(map[string]interface{}{
		"type":       "01-publish-timestamps",
		"timestamps": sc.GetDoc().Timestamps,
	})
}

// Navigate the Document to an Event, and promote it as the tip.
func (sc *SimpleClient) Promote(ev document.Event) error {
	doc := sc.GetDoc()

	if err := ev.Goto(); err != nil {
		return err
	}
	sc.tip = ev.Hash()
	sc.PublishTip() // Ignore error - believe it or not, this cannot error

	doc.Timestamps = append(doc.Timestamps, ev.Hash())
	return sc.PublishTimestamps()
}

// Set a callback for when primitives are applied to the document state.
func (sc *SimpleClient) SetPrimitiveCallback(c state.OnPrimitiveCallback) {
	sc.GetDoc().State.SetPrimitiveCallback(c)
}

// Get the Document object owned by this Client.
func (sc *SimpleClient) GetDoc() *document.Document {
	return sc.client.Doc
}

// Return the current contents of the document.
func (sc *SimpleClient) Export() interface{} {
	return sc.client.Doc.State.Export()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func RunCommand(dir string, name string, arg ...string) error {
	if _, err := exec.LookPath(name); err != nil {
		return err
	}

	errBuf := bytes.NewBuffer(make([]byte, 0))
	c := exec.Command(name, arg...)
	c.Dir = dir
	c.Stderr = errBuf
	if err := c.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errBuf.String()))
	}
	return nil
}

func ListPackages(filetype string) {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
}

type Package struct {
	srcURI  string
	dstPath string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		srcURI:  ToSourceURI(uri),
		dstPath: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dstPath)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}
	return RunCommand("", "git", "clone", p.srcURI, p.dstPath)
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dstPath)
	}
	return nil
}

func (p *Package) Update() error {
	if !p.installed() {
		if err := p.Install(); err != nil {
			return err
		}
	}
	return RunCommand(p.dstPath, "git", "pull")
}
<commit_msg>Do only install if package isn't already installed<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/mitchellh/go-homedir"
)

var (
	ShortGitHubURI = regexp.MustCompile(`^[\w\-.]+/[\w\-.]+$`)
	GitHubURI      = regexp.MustCompile(`^github.com/[\w\-.]+/[\w\-.]+$`)
	BitbucketURI   = regexp.MustCompile(`^bitbucket.org/[\w\-.]+/[\w\-.]+$`)
)

func ToSourceURI(uri string) string {
	switch {
	case ShortGitHubURI.MatchString(uri):
		return "https://github.com/" + uri
	case GitHubURI.MatchString(uri):
		return "https://" + uri
	case BitbucketURI.MatchString(uri):
		return "https://" + uri
	default:
		return uri
	}
}

var (
	home, errInit = homedir.Dir()
	dotvim        = filepath.Join(home, ".vim")
)

func ToDestinationPath(uri, filetype string) string {
	name := filepath.Base(uri)
	if filetype == "" {
		return filepath.Join(dotvim, "bundle", name)
	}
	return filepath.Join(dotvim, "ftbundle", filetype, name)
}

func RunCommand(dir string, name string, arg ...string) error {
	if _, err := exec.LookPath(name); err != nil {
		return err
	}

	errBuf := bytes.NewBuffer(make([]byte, 0))
	c := exec.Command(name, arg...)
	c.Dir = dir
	c.Stderr = errBuf
	if err := c.Run(); err != nil {
		return fmt.Errorf("%s", strings.TrimSpace(errBuf.String()))
	}
	return nil
}

func ListPackages(filetype string) {
	var path string
	if filetype == "" {
		path = filepath.Join(dotvim, "bundle")
	} else {
		path = filepath.Join(dotvim, "ftbundle", filetype)
	}

	// Ignore err for filetype doesn't exist.
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		fmt.Println(file.Name())
	}
}

type Package struct {
	srcURI  string
	dstPath string
}

func NewPackage(uri, filetype string) *Package {
	return &Package{
		srcURI:  ToSourceURI(uri),
		dstPath: ToDestinationPath(uri, filetype),
	}
}

func (p *Package) installed() bool {
	_, err := os.Stat(p.dstPath)
	return err == nil
}

func (p *Package) Install() error {
	if p.installed() {
		return nil
	}
	return RunCommand("", "git", "clone", p.srcURI, p.dstPath)
}

func (p *Package) Remove() error {
	if p.installed() {
		return os.RemoveAll(p.dstPath)
	}
	return nil
}

func (p *Package) Update() error {
	if !p.installed() {
		return p.Install()
	}
	return RunCommand(p.dstPath, "git", "pull")
}
<|endoftext|>


<commit_before>package todolist

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

type FileStore struct {
	FileLocation string
	Loaded       bool
}

func NewFileStore() *FileStore {
	return &FileStore{FileLocation: "", Loaded: false}
}

func (f *FileStore) Initialize() {
	if f.FileLocation == "" {
		f.FileLocation = ".todos.json"
	}

	_, err := ioutil.ReadFile(f.FileLocation)
	if err == nil {
		fmt.Println("It looks like a .todos.json file already exists!  Doing nothing.")
		os.Exit(0)
	}
	if err := ioutil.WriteFile(f.FileLocation, []byte("[]"), 0644); err != nil {
		fmt.Println("Error writing json file", err)
		os.Exit(1)
	}
	fmt.Println("Todo repo initialized.")
}

func (f *FileStore) Load() ([]*Todo, error) {
	if f.FileLocation == "" {
		f.FileLocation = getLocation()
	}

	data, err := ioutil.ReadFile(f.FileLocation)
	if err != nil {
		fmt.Println("No todo file found!")
		fmt.Println("Initialize a new todo repo by running 'todo init'")
		os.Exit(0)
		return nil, err
	}

	var todos []*Todo
	jerr := json.Unmarshal(data, &todos)
	if jerr != nil {
		fmt.Println("Error reading json data", jerr)
		os.Exit(1)
		return nil, jerr
	}
	f.Loaded = true

	return todos, nil
}

func (f *FileStore) Save(todos []*Todo) {
	data, _ := json.Marshal(todos)
	if err := ioutil.WriteFile(f.FileLocation, []byte(data), 0644); err != nil {
		fmt.Println("Error writing json file", err)
	}
}

func getLocation() string {
	localrepo := ".todos.json"
	usr, _ := user.Current()
	homerepo := fmt.Sprintf("%s/.todos.json", usr.HomeDir)
	_, ferr := os.Stat(localrepo)

	if ferr == nil {
		return localrepo
	} else {
		return homerepo
	}
}
<commit_msg>Fix typo error<commit_after>package todolist

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

type FileStore struct {
	FileLocation string
	Loaded       bool
}

func NewFileStore() *FileStore {
	return &FileStore{FileLocation: "", Loaded: false}
}

func (f *FileStore) Initialize() {
	if f.FileLocation == "" {
		f.FileLocation = ".todos.json"
	}

	_, err := ioutil.ReadFile(f.FileLocation)
	if err == nil {
		fmt.Println("It looks like a .todos.json file already exists!  Doing nothing.")
		os.Exit(0)
	}
	if err := ioutil.WriteFile(f.FileLocation, []byte("[]"), 0644); err != nil {
		fmt.Println("Error writing json file", err)
		os.Exit(1)
	}
	fmt.Println("Todo repo initialized.")
}

func (f *FileStore) Load() ([]*Todo, error) {
	if f.FileLocation == "" {
		f.FileLocation = getLocation()
	}

	data, err := ioutil.ReadFile(f.FileLocation)
	if err != nil {
		fmt.Println("No todo file found!")
		fmt.Println("Initialize a new todo repo by running 'todolist init'")
		os.Exit(0)
		return nil, err
	}

	var todos []*Todo
	jerr := json.Unmarshal(data, &todos)
	if jerr != nil {
		fmt.Println("Error reading json data", jerr)
		os.Exit(1)
		return nil, jerr
	}
	f.Loaded = true

	return todos, nil
}

func (f *FileStore) Save(todos []*Todo) {
	data, _ := json.Marshal(todos)
	if err := ioutil.WriteFile(f.FileLocation, []byte(data), 0644); err != nil {
		fmt.Println("Error writing json file", err)
	}
}

func getLocation() string {
	localrepo := ".todos.json"
	usr, _ := user.Current()
	homerepo := fmt.Sprintf("%s/.todos.json", usr.HomeDir)
	_, ferr := os.Stat(localrepo)

	if ferr == nil {
		return localrepo
	} else {
		return homerepo
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"fmt"
	"net"
	"strconv"

	"github.com/docker/docker/api/types"
	ctypes "github.com/docker/docker/api/types"
	"github.com/docker/go-connections/nat"
	"github.com/ehazlett/interlock/ext"
)

func OverlayEnabled(config ctypes.Container) (string, bool) {
	if v, ok := config.Labels[ext.InterlockNetworkLabel]; ok {
		return v, true
	}

	return "", false
}

func BackendOverlayAddress(network types.NetworkResource, cnt types.Container) (string, error) {
	c, exists := network.Containers[cnt.ID]
	if !exists {
		return "", fmt.Errorf("container %s is not connected to network %s", cnt.ID, network.Name)
	}

	ip, _, err := net.ParseCIDR(c.IPv4Address)
	if err != nil {
		return "", err
	}

	ports := cnt.Ports
	portDef := nat.PortBinding{}
	addr := ""

	portDef.HostIP = ip.String()

	// parse the port
	for _, k := range ports {
		portDef.HostPort = fmt.Sprintf("%d", k.PublicPort)
		break
	}

	// check for custom port
	if v, ok := cnt.Labels[ext.InterlockPortLabel]; ok {
		portDef.HostPort = v
	}

	addr = fmt.Sprintf("%s:%s", portDef.HostIP, portDef.HostPort)

	return addr, nil
}

func BackendAddress(cnt types.Container, backendOverrideAddress string) (string, error) {
	ports := cnt.Ports
	portDef := nat.PortBinding{}
	addr := ""

	// parse the published port
	for _, port := range ports {
		portDef.HostIP = port.IP
		portDef.HostPort = fmt.Sprintf("%d", port.PublicPort)
		break
	}

	if backendOverrideAddress != "" {
		portDef.HostIP = backendOverrideAddress
	}

	// check for custom port
	if v, ok := cnt.Labels[ext.InterlockPortLabel]; ok {
		interlockPort, err := strconv.Atoi(v)
		if err != nil {
			return "", err
		}
		for _, port := range ports {
			if port.PrivatePort == uint16(interlockPort) {
				portDef.HostPort = fmt.Sprintf("%d", port.PublicPort)
				break
			}
		}
	}

	addr = fmt.Sprintf("%s:%s", portDef.HostIP, portDef.HostPort)
	return addr, nil
}
<commit_msg>check for port 0 upon update<commit_after>package utils

import (
	"fmt"
	"net"
	"strconv"

	"github.com/docker/docker/api/types"
	ctypes "github.com/docker/docker/api/types"
	"github.com/docker/go-connections/nat"
	"github.com/ehazlett/interlock/ext"
)

func OverlayEnabled(config ctypes.Container) (string, bool) {
	if v, ok := config.Labels[ext.InterlockNetworkLabel]; ok {
		return v, true
	}

	return "", false
}

func BackendOverlayAddress(network types.NetworkResource, cnt types.Container) (string, error) {
	c, exists := network.Containers[cnt.ID]
	if !exists {
		return "", fmt.Errorf("container %s is not connected to network %s", cnt.ID, network.Name)
	}

	ip, _, err := net.ParseCIDR(c.IPv4Address)
	if err != nil {
		return "", err
	}

	ports := cnt.Ports
	portDef := nat.PortBinding{}
	addr := ""

	portDef.HostIP = ip.String()

	// parse the port
	for _, k := range ports {
		if k.PublicPort != 0 {
			portDef.HostPort = fmt.Sprintf("%d", k.PublicPort)
			break
		}
	}

	// check for custom port
	if v, ok := cnt.Labels[ext.InterlockPortLabel]; ok {
		portDef.HostPort = v
	}

	if portDef.HostPort == "" {
		return "", fmt.Errorf("unable to find exposed port")
	}

	addr = fmt.Sprintf("%s:%s", portDef.HostIP, portDef.HostPort)

	return addr, nil
}

func BackendAddress(cnt types.Container, backendOverrideAddress string) (string, error) {
	ports := cnt.Ports
	portDef := nat.PortBinding{}
	addr := ""

	// parse the published port
	for _, port := range ports {
		portDef.HostIP = port.IP
		portDef.HostPort = fmt.Sprintf("%d", port.PublicPort)
		break
	}

	if backendOverrideAddress != "" {
		portDef.HostIP = backendOverrideAddress
	}

	// check for custom port
	if v, ok := cnt.Labels[ext.InterlockPortLabel]; ok {
		interlockPort, err := strconv.Atoi(v)
		if err != nil {
			return "", err
		}
		for _, port := range ports {
			if port.PrivatePort == uint16(interlockPort) {
				portDef.HostPort = fmt.Sprintf("%d", port.PublicPort)
				break
			}
		}
	}

	addr = fmt.Sprintf("%s:%s", portDef.HostIP, portDef.HostPort)
	return addr, nil
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"io/ioutil"
	"math/big"
	"net"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "tlsgen"
	app.Usage = "Generates web server TLS certificates"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "org",
			Value: "",
			Usage: "Organization name",
		},
		cli.StringSliceFlag{
			Name:  "host",
			Value: &cli.StringSlice{},
			Usage: "Server Host",
		},
	}
	app.Action = func(c *cli.Context) {
		org := c.String("org")
		if org == "" {
			logrus.Fatal("org shoule not be empty")
		}
		host := c.StringSlice("host")
		if len(host) == 0 {
			logrus.Fatal("host shoule not be empty")
		}
		GenerateCACertificate("ca.pem", "ca.key", org, 2048)
		GenerateCert(host, "server.pem", "server.key", "ca.pem", "ca.key", org, 2048)
	}

	app.Run(os.Args)
}

func getTLSConfig(caCert, cert, key []byte, allowInsecure bool) (*tls.Config, error) {
	// TLS config
	var tlsConfig tls.Config
	tlsConfig.InsecureSkipVerify = allowInsecure
	certPool := x509.NewCertPool()

	certPool.AppendCertsFromPEM(caCert)
	tlsConfig.RootCAs = certPool
	keypair, err := tls.X509KeyPair(cert, key)
	if err != nil {
		return &tlsConfig, err
	}
	tlsConfig.Certificates = []tls.Certificate{keypair}
	if allowInsecure {
		tlsConfig.InsecureSkipVerify = true
	}

	return &tlsConfig, nil
}

func newCertificate(org string) (*x509.Certificate, error) {
	now := time.Now()
	// need to set notBefore slightly in the past to account for time
	// skew in the VMs otherwise the certs sometimes are not yet valid
	notBefore := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-5, 0, 0, time.Local)
	notAfter := notBefore.Add(time.Hour * 24 * 1080)

	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		return nil, err
	}

	return &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Organization: []string{org},
		},
		NotBefore: notBefore,
		NotAfter:  notAfter,

		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		BasicConstraintsValid: true,
	}, nil

}

// GenerateCACertificate generates a new certificate authority from the specified org
// and bit size and stores the resulting certificate and key file
// in the arguments.
func GenerateCACertificate(certFile, keyFile, org string, bits int) error {
	template, err := newCertificate(org)
	if err != nil {
		return err
	}

	template.IsCA = true
	template.KeyUsage |= x509.KeyUsageCertSign

	priv, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
	if err != nil {
		return err
	}

	certOut, err := os.Create(certFile)
	if err != nil {
		return err
	}

	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	certOut.Close()

	keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err

	}

	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
	keyOut.Close()

	return nil
}

// GenerateCert generates a new certificate signed using the provided
// certificate authority files and stores the result in the certificate
// file and key provided.  The provided host names are set to the
// appropriate certificate fields.
func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile, org string, bits int) error {
	template, err := newCertificate(org)
	if err != nil {
		return err
	}
	// client
	if len(hosts) == 1 && hosts[0] == "" {
		template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
		template.KeyUsage = x509.KeyUsageDigitalSignature
	} else { // server
		template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}
		for _, h := range hosts {
			if ip := net.ParseIP(h); ip != nil {
				template.IPAddresses = append(template.IPAddresses, ip)

			} else {
				template.DNSNames = append(template.DNSNames, h)
			}
		}
	}

	tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile)
	if err != nil {
		return err

	}

	priv, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err

	}

	x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
	if err != nil {
		return err
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey)
	if err != nil {
		return err
	}

	certOut, err := os.Create(certFile)
	if err != nil {
		return err

	}

	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	certOut.Close()

	keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err

	}

	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
	keyOut.Close()

	return nil
}

func ValidateCertificate(addr, caCertPath, serverCertPath, serverKeyPath string) (bool, error) {
	caCert, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		return false, err
	}

	serverCert, err := ioutil.ReadFile(serverCertPath)
	if err != nil {
		return false, err
	}

	serverKey, err := ioutil.ReadFile(serverKeyPath)
	if err != nil {
		return false, err
	}

	tlsConfig, err := getTLSConfig(caCert, serverCert, serverKey, false)
	if err != nil {
		return false, err
	}

	dialer := &net.Dialer{
		Timeout: time.Second * 2,
	}

	_, err = tls.DialWithDialer(dialer, "tcp", addr, tlsConfig)
	if err != nil {
		return false, nil
	}

	return true, nil
}
<commit_msg>add days option<commit_after>package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"io/ioutil"
	"math/big"
	"net"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "tlsgen"
	app.Usage = "Generates web server TLS certificates"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "org",
			Value: "",
			Usage: "Organization name",
		},
		cli.IntFlag{
			Name:  "days",
			Value: 365,
			Usage: "Expired in day",
		},
		cli.StringSliceFlag{
			Name:  "host",
			Value: &cli.StringSlice{},
			Usage: "Server Host",
		},
	}
	app.Action = func(c *cli.Context) {
		org := c.String("org")
		if org == "" {
			logrus.Fatal("org shoule not be empty")
		}
		days := c.Int("days")
		if days == 0 {
			logrus.Fatal("days must not be 0")
		}
		host := c.StringSlice("host")
		if len(host) == 0 {
			logrus.Fatal("host shoule not be empty")
		}
		GenerateCACertificate("ca.pem", "ca.key", org, days, 2048)
		GenerateCert(host, "server.pem", "server.key", "ca.pem", "ca.key", org, days, 2048)
	}

	app.Run(os.Args)
}

func getTLSConfig(caCert, cert, key []byte, allowInsecure bool) (*tls.Config, error) {
	// TLS config
	var tlsConfig tls.Config
	tlsConfig.InsecureSkipVerify = allowInsecure
	certPool := x509.NewCertPool()

	certPool.AppendCertsFromPEM(caCert)
	tlsConfig.RootCAs = certPool
	keypair, err := tls.X509KeyPair(cert, key)
	if err != nil {
		return &tlsConfig, err
	}
	tlsConfig.Certificates = []tls.Certificate{keypair}
	if allowInsecure {
		tlsConfig.InsecureSkipVerify = true
	}

	return &tlsConfig, nil
}

func newCertificate(org string, days int) (*x509.Certificate, error) {
	now := time.Now()
	// need to set notBefore slightly in the past to account for time
	// skew in the VMs otherwise the certs sometimes are not yet valid
	notBefore := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-5, 0, 0, time.Local)
	notAfter := notBefore.Add(time.Hour * 24 * time.Duration(days))

	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
	if err != nil {
		return nil, err
	}

	return &x509.Certificate{
		SerialNumber: serialNumber,
		Subject: pkix.Name{
			Organization: []string{org},
		},
		NotBefore: notBefore,
		NotAfter:  notAfter,

		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		BasicConstraintsValid: true,
	}, nil

}

// GenerateCACertificate generates a new certificate authority from the specified org
// and bit size and stores the resulting certificate and key file
// in the arguments.
func GenerateCACertificate(certFile, keyFile, org string, days, bits int) error {
	template, err := newCertificate(org, days)
	if err != nil {
		return err
	}

	template.IsCA = true
	template.KeyUsage |= x509.KeyUsageCertSign

	priv, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
	if err != nil {
		return err
	}

	certOut, err := os.Create(certFile)
	if err != nil {
		return err
	}

	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	certOut.Close()

	keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err

	}

	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
	keyOut.Close()

	return nil
}

// GenerateCert generates a new certificate signed using the provided
// certificate authority files and stores the result in the certificate
// file and key provided.  The provided host names are set to the
// appropriate certificate fields.
func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile, org string, days, bits int) error {
	template, err := newCertificate(org, days)
	if err != nil {
		return err
	}
	// client
	if len(hosts) == 1 && hosts[0] == "" {
		template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
		template.KeyUsage = x509.KeyUsageDigitalSignature
	} else { // server
		template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}
		for _, h := range hosts {
			if ip := net.ParseIP(h); ip != nil {
				template.IPAddresses = append(template.IPAddresses, ip)

			} else {
				template.DNSNames = append(template.DNSNames, h)
			}
		}
	}

	tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile)
	if err != nil {
		return err

	}

	priv, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err

	}

	x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
	if err != nil {
		return err
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey)
	if err != nil {
		return err
	}

	certOut, err := os.Create(certFile)
	if err != nil {
		return err

	}

	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
	certOut.Close()

	keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		return err

	}

	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
	keyOut.Close()

	return nil
}

func ValidateCertificate(addr, caCertPath, serverCertPath, serverKeyPath string) (bool, error) {
	caCert, err := ioutil.ReadFile(caCertPath)
	if err != nil {
		return false, err
	}

	serverCert, err := ioutil.ReadFile(serverCertPath)
	if err != nil {
		return false, err
	}

	serverKey, err := ioutil.ReadFile(serverKeyPath)
	if err != nil {
		return false, err
	}

	tlsConfig, err := getTLSConfig(caCert, serverCert, serverKey, false)
	if err != nil {
		return false, err
	}

	dialer := &net.Dialer{
		Timeout: time.Second * 2,
	}

	_, err = tls.DialWithDialer(dialer, "tcp", addr, tlsConfig)
	if err != nil {
		return false, nil
	}

	return true, nil
}
<|endoftext|>


<commit_before>package refctx

import (
	"context"
	"sync/atomic"

	"github.com/SentimensRG/ctx"
)

// RefCtr cancels a context when no references are held
type RefCtr struct {
	cancel func()
	refcnt uint32
}

// Incr increments the refcount
func (r *RefCtr) Incr() { r.Add(1) }

// Add i refcounts
func (r *RefCtr) Add(i uint32) {
	if v := atomic.AddUint32(&r.refcnt, i); v == 0 {
		r.cancel()
	}
}

// Decr decrements the refcount
func (r *RefCtr) Decr() { r.Add(^uint32(0)) }

// WithRefCount derives a ctx.C that will be cancelled when all references are
// freed
func WithRefCount(d ctx.Doner) (ctx.C, *RefCtr) {
	ch, cancel := ctx.WithCancel(d)
	return ch, &RefCtr{cancel: cancel}
}

// ContextWithRefCount derives a context that will be cancelled when all
// references are freed.
func ContextWithRefCount(c context.Context) (context.Context, *RefCtr) {
	c, cancel := context.WithCancel(c)
	return c, &RefCtr{cancel: cancel}
}
<commit_msg>Package docstring<commit_after>// Package refctx provides a context tied to a reference-counter.
package refctx

import (
	"context"
	"sync/atomic"

	"github.com/SentimensRG/ctx"
)

// RefCtr cancels a context when no references are held
type RefCtr struct {
	cancel func()
	refcnt uint32
}

// Incr increments the refcount
func (r *RefCtr) Incr() { r.Add(1) }

// Add i refcounts
func (r *RefCtr) Add(i uint32) {
	if v := atomic.AddUint32(&r.refcnt, i); v == 0 {
		r.cancel()
	}
}

// Decr decrements the refcount
func (r *RefCtr) Decr() { r.Add(^uint32(0)) }

// WithRefCount derives a ctx.C that will be cancelled when all references are
// freed
func WithRefCount(d ctx.Doner) (ctx.C, *RefCtr) {
	ch, cancel := ctx.WithCancel(d)
	return ch, &RefCtr{cancel: cancel}
}

// ContextWithRefCount derives a context that will be cancelled when all
// references are freed.
func ContextWithRefCount(c context.Context) (context.Context, *RefCtr) {
	c, cancel := context.WithCancel(c)
	return c, &RefCtr{cancel: cancel}
}
<|endoftext|>