├── Godeps ├── _workspace │ ├── .gitignore │ └── src │ │ ├── gopkg.in │ │ └── fsnotify.v1 │ │ │ ├── NotUsed.xcworkspace │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── open_mode_bsd.go │ │ │ ├── open_mode_darwin.go │ │ │ ├── circle.yml │ │ │ ├── example_test.go │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ └── fsnotify.go │ │ ├── github.com │ │ ├── kr │ │ │ ├── pretty │ │ │ │ ├── .gitignore │ │ │ │ ├── Readme │ │ │ │ ├── example_test.go │ │ │ │ ├── License │ │ │ │ ├── zero.go │ │ │ │ └── diff_test.go │ │ │ └── text │ │ │ │ ├── doc.go │ │ │ │ ├── Readme │ │ │ │ ├── colwriter │ │ │ │ ├── Readme │ │ │ │ └── column_test.go │ │ │ │ ├── mc │ │ │ │ ├── Readme │ │ │ │ └── mc.go │ │ │ │ ├── License │ │ │ │ ├── wrap_test.go │ │ │ │ ├── indent.go │ │ │ │ ├── wrap.go │ │ │ │ └── indent_test.go │ │ ├── 18F │ │ │ └── hmacauth │ │ │ │ ├── .gitignore │ │ │ │ ├── .travis.yml │ │ │ │ ├── README.md │ │ │ │ └── .about.yml │ │ ├── BurntSushi │ │ │ └── toml │ │ │ │ ├── session.vim │ │ │ │ ├── .gitignore │ │ │ │ ├── COMPATIBLE │ │ │ │ ├── .travis.yml │ │ │ │ ├── Makefile │ │ │ │ ├── COPYING │ │ │ │ ├── cmd │ │ │ │ ├── tomlv │ │ │ │ │ ├── COPYING │ │ │ │ │ ├── README.md │ │ │ │ │ └── main.go │ │ │ │ ├── toml-test-decoder │ │ │ │ │ ├── COPYING │ │ │ │ │ ├── README.md │ │ │ │ │ └── main.go │ │ │ │ └── toml-test-encoder │ │ │ │ │ ├── COPYING │ │ │ │ │ └── README.md │ │ │ │ ├── encoding_types_1.1.go │ │ │ │ ├── encoding_types.go │ │ │ │ └── doc.go │ │ ├── jonboulle │ │ │ └── clockwork │ │ │ │ ├── .travis.yml │ │ │ │ ├── .gitignore │ │ │ │ ├── example_test.go │ │ │ │ └── README.md │ │ ├── bmizerany │ │ │ └── assert │ │ │ │ ├── example │ │ │ │ ├── point.go │ │ │ │ └── point_test.go │ │ │ │ ├── .gitignore │ │ │ │ ├── assert_test.go │ │ │ │ ├── README.md │ │ │ │ └── assert.go │ │ ├── mreiferson │ │ │ └── go-options │ │ │ │ ├── .travis.yml │ │ │ │ ├── README.md │ │ │ │ ├── example_test.go │ │ │ │ └── LICENSE │ │ ├── coreos │ │ │ ├── go-oidc │ │ │ │ ├── oidc │ │ │ │ │ ├── interface.go │ │ │ │ │ ├── identity.go │ │ │ │ │ ├── key.go │ │ │ │ │ └── transport.go │ │ │ │ ├── http │ │ │ │ │ ├── middleware.go │ │ │ │ │ ├── url.go │ │ │ │ │ ├── url_test.go │ │ │ │ │ └── client.go │ │ │ │ ├── jose │ │ │ │ │ ├── sig.go │ │ │ │ │ ├── jws.go │ │ │ │ │ ├── jwk_test.go │ │ │ │ │ ├── jose.go │ │ │ │ │ ├── sig_hmac.go │ │ │ │ │ ├── sig_rsa.go │ │ │ │ │ ├── jws_test.go │ │ │ │ │ ├── jwt.go │ │ │ │ │ ├── sig_hmac_test.go │ │ │ │ │ ├── claims.go │ │ │ │ │ └── jwt_test.go │ │ │ │ ├── key │ │ │ │ │ ├── repo.go │ │ │ │ │ ├── key_test.go │ │ │ │ │ ├── sync.go │ │ │ │ │ └── manager.go │ │ │ │ └── oauth2 │ │ │ │ │ ├── error.go │ │ │ │ │ └── error_test.go │ │ │ └── pkg │ │ │ │ ├── httputil │ │ │ │ ├── README.md │ │ │ │ ├── cookie.go │ │ │ │ ├── json.go │ │ │ │ ├── cookie_test.go │ │ │ │ └── json_test.go │ │ │ │ ├── timeutil │ │ │ │ ├── backoff.go │ │ │ │ └── backoff_test.go │ │ │ │ ├── health │ │ │ │ └── README.md │ │ │ │ └── capnslog │ │ │ │ ├── init_windows.go │ │ │ │ ├── log_hijack.go │ │ │ │ ├── init.go │ │ │ │ ├── syslog_formatter.go │ │ │ │ ├── journald_formatter.go │ │ │ │ ├── example │ │ │ │ └── hello_dolly.go │ │ │ │ └── glog_formatter.go │ │ └── bitly │ │ │ └── go-simplejson │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── LICENSE │ │ │ ├── simplejson_go10_test.go │ │ │ ├── simplejson_go10.go │ │ │ ├── simplejson_go11.go │ │ │ └── simplejson_go11_test.go │ │ ├── golang.org │ │ └── x │ │ │ ├── oauth2 │ │ │ ├── google │ │ │ │ ├── testdata │ │ │ │ │ └── gcloud │ │ │ │ │ │ └── properties │ │ │ │ ├── appengine_hook.go │ │ │ │ ├── sdk_test.go │ │ │ │ ├── jwt.go │ │ │ │ ├── appengine.go │ │ │ │ └── google_test.go │ │ │ ├── AUTHORS │ │ │ ├── CONTRIBUTORS │ │ │ ├── .travis.yml │ │ │ ├── vk │ │ │ │ └── vk.go │ │ │ ├── github │ │ │ │ └── github.go │ │ │ ├── facebook │ │ │ │ └── facebook.go │ │ │ ├── linkedin │ │ │ │ └── linkedin.go │ │ │ ├── odnoklassniki │ │ │ │ └── odnoklassniki.go │ │ │ ├── client_appengine.go │ │ │ ├── internal │ │ │ │ ├── token_test.go │ │ │ │ ├── oauth2_test.go │ │ │ │ ├── transport.go │ │ │ │ └── oauth2.go │ │ │ ├── paypal │ │ │ │ └── paypal.go │ │ │ ├── jwt │ │ │ │ └── example_test.go │ │ │ ├── CONTRIBUTING.md │ │ │ ├── example_test.go │ │ │ ├── token_test.go │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── transport_test.go │ │ │ └── net │ │ │ └── context │ │ │ ├── ctxhttp │ │ │ ├── cancelreq.go │ │ │ ├── cancelreq_go14.go │ │ │ ├── ctxhttp_test.go │ │ │ └── ctxhttp.go │ │ │ └── withtimeout_test.go │ │ └── google.golang.org │ │ ├── api │ │ ├── googleapi │ │ │ ├── internal │ │ │ │ └── uritemplates │ │ │ │ │ ├── utils.go │ │ │ │ │ └── LICENSE │ │ │ ├── transport │ │ │ │ └── apikey.go │ │ │ └── types_test.go │ │ └── gensupport │ │ │ └── params.go │ │ └── cloud │ │ └── internal │ │ ├── opts │ │ └── option.go │ │ ├── transport │ │ ├── cancelreq.go │ │ ├── cancelreq_legacy.go │ │ └── proto.go │ │ └── testutil │ │ └── context.go └── Readme ├── version.go ├── test.sh ├── templates_test.go ├── .travis.yml ├── string_array.go ├── watcher_unsupported.go ├── Dockerfile ├── htpasswd_test.go ├── providers ├── provider_default_test.go ├── provider_data.go ├── providers.go ├── gitlab.go ├── myusa.go ├── linkedin.go ├── facebook.go ├── internal_util.go └── session_state_test.go ├── .gitignore ├── env_options_test.go ├── contrib └── oauth2_proxy.service.example ├── dist.sh ├── env_options.go ├── LICENSE ├── cookie └── cookies_test.go ├── validator_watcher_copy_test.go ├── htpasswd.go ├── api └── api.go ├── watcher.go └── validator.go /Godeps/_workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /pkg 2 | /bin 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/NotUsed.xcworkspace: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | const VERSION = "2.2.0-alpha" 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/.gitignore: -------------------------------------------------------------------------------- 1 | [568].out 2 | _go* 3 | _test* 4 | _obj 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/18F/hmacauth/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | .*.swp 4 | coverage.out 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/testdata/gcloud/properties: -------------------------------------------------------------------------------- 1 | [core] 2 | account = bar@example.com -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/session.vim: -------------------------------------------------------------------------------- 1 | au BufWritePost *.go silent!make tags > /dev/null 2>&1 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jonboulle/clockwork/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.3 4 | 5 | sudo: false 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/.gitignore: -------------------------------------------------------------------------------- 1 | TAGS 2 | tags 3 | .*.swp 4 | tomlcheck/tomlcheck 5 | toml.test 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/example/point.go: -------------------------------------------------------------------------------- 1 | package point 2 | 3 | type Point struct { 4 | X, Y int 5 | } 6 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | godep go test -timeout 60s ./... 5 | GOMAXPROCS=4 godep go test -timeout 60s -race ./... 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/.gitignore: -------------------------------------------------------------------------------- 1 | _go_.* 2 | _gotest_.* 3 | _obj 4 | _test 5 | _testmain.go 6 | *.out 7 | *.[568] 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/doc.go: -------------------------------------------------------------------------------- 1 | // Package text provides rudimentary functions for manipulating text in 2 | // paragraphs. 3 | package text 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mreiferson/go-options/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.3 4 | - tip 5 | notifications: 6 | email: false 7 | 8 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oidc/interface.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | type LoginFunc func(ident Identity, sessionKey string) (redirectURL string, err error) 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/COMPATIBLE: -------------------------------------------------------------------------------- 1 | Compatible with TOML version 2 | [v0.2.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.2.0.md) 3 | 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/Readme: -------------------------------------------------------------------------------- 1 | This is a Go package for manipulating paragraphs of text. 2 | 3 | See http://go.pkgdoc.org/github.com/kr/text for full documentation. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.0.3 4 | - 1.1.2 5 | - 1.2 6 | - tip 7 | install: 8 | - go get github.com/bmizerany/assert 9 | notifications: 10 | email: false 11 | -------------------------------------------------------------------------------- /templates_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/bmizerany/assert" 5 | "testing" 6 | ) 7 | 8 | func TestTemplatesCompile(t *testing.T) { 9 | templates := getTemplates() 10 | assert.NotEqual(t, templates, nil) 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/Readme: -------------------------------------------------------------------------------- 1 | package pretty 2 | 3 | import "github.com/kr/pretty" 4 | 5 | Package pretty provides pretty-printing for Go values. 6 | 7 | Documentation 8 | 9 | http://godoc.org/github.com/kr/pretty 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/colwriter/Readme: -------------------------------------------------------------------------------- 1 | Package colwriter provides a write filter that formats 2 | input lines in multiple columns. 3 | 4 | The package is a straightforward translation from 5 | /src/cmd/draw/mc.c in Plan 9 from User Space. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/.gitignore: -------------------------------------------------------------------------------- 1 | # Setup a Global .gitignore for OS and editor generated files: 2 | # https://help.github.com/articles/ignoring-files 3 | # git config --global core.excludesfile ~/.gitignore_global 4 | 5 | .vagrant 6 | *.sublime-project 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/example/point_test.go: -------------------------------------------------------------------------------- 1 | package point 2 | 3 | import ( 4 | "testing" 5 | "assert" 6 | ) 7 | 8 | func TestAsserts(t *testing.T) { 9 | p1 := Point{1, 1} 10 | p2 := Point{2, 1} 11 | 12 | assert.Equal(t, p1, p2) 13 | } 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.5.4 4 | - 1.6.3 5 | script: 6 | - curl -s https://raw.githubusercontent.com/pote/gpm/v1.3.2/bin/gpm > gpm 7 | - chmod +x gpm 8 | - ./gpm install 9 | - ./test.sh 10 | sudo: false 11 | notifications: 12 | email: false 13 | 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.1 4 | - 1.2 5 | - tip 6 | install: 7 | - go install ./... 8 | - go get github.com/BurntSushi/toml-test 9 | script: 10 | - export PATH="$PATH:$HOME/gopath/bin" 11 | - make test 12 | 13 | -------------------------------------------------------------------------------- /string_array.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type StringArray []string 8 | 9 | func (a *StringArray) Set(s string) error { 10 | *a = append(*a, s) 11 | return nil 12 | } 13 | 14 | func (a *StringArray) String() string { 15 | return strings.Join(*a, ",") 16 | } 17 | -------------------------------------------------------------------------------- /watcher_unsupported.go: -------------------------------------------------------------------------------- 1 | // +build !go1.3 plan9 solaris 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | ) 8 | 9 | func WatchForUpdates(filename string, done <-chan bool, action func()) { 10 | log.Printf("file watching not implemented on this platform") 11 | go func() { <-done }() 12 | } 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/httputil/README.md: -------------------------------------------------------------------------------- 1 | httputil 2 | ==== 3 | 4 | Common code for dealing with HTTP. 5 | 6 | Includes: 7 | 8 | * Code for returning JSON responses. 9 | 10 | ### Documentation 11 | 12 | Visit the docs on [gopkgdoc](http://godoc.org/github.com/coreos/pkg/httputil) 13 | 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/timeutil/backoff.go: -------------------------------------------------------------------------------- 1 | package timeutil 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | func ExpBackoff(prev, max time.Duration) time.Duration { 8 | if prev == 0 { 9 | return time.Second 10 | } 11 | if prev > max/2 { 12 | return max 13 | } 14 | return 2 * prev 15 | } 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mreiferson/go-options/README.md: -------------------------------------------------------------------------------- 1 | # go-options 2 | 3 | Provides a way to resolve struct options, flag options, and config files. 4 | 5 | For docs see:http://godoc.org/github.com/mreiferson/go-options 6 | 7 | [![Build Status](https://travis-ci.org/mreiferson/go-nsq.svg?branch=master)](https://travis-ci.org/mreiferson/go-nsq) -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.7-alpine 2 | MAINTAINER colin.hom@coreos.com 3 | 4 | RUN apk add --no-cache git 5 | RUN go get github.com/tools/godep 6 | 7 | ADD . $GOPATH/src/github.com/bitly/oauth2_proxy 8 | 9 | WORKDIR $GOPATH/src/github.com/bitly/oauth2_proxy 10 | 11 | RUN godep go install github.com/bitly/oauth2_proxy 12 | 13 | ENTRYPOINT ["oauth2_proxy"] 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/http/middleware.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type LoggingMiddleware struct { 8 | Next http.Handler 9 | } 10 | 11 | func (l *LoggingMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { 12 | log.Infof("HTTP %s %v", r.Method, r.URL) 13 | l.Next.ServeHTTP(w, r) 14 | } 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.3 5 | - 1.4 6 | 7 | install: 8 | - export GOPATH="$HOME/gopath" 9 | - mkdir -p "$GOPATH/src/golang.org/x" 10 | - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2" 11 | - go get -v -t -d golang.org/x/oauth2/... 12 | 13 | script: 14 | - go test -v golang.org/x/oauth2/... 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | 4 | go: 5 | - 1.4.1 6 | 7 | before_script: 8 | - FIXED=$(go fmt ./... | wc -l); if [ $FIXED -gt 0 ]; then echo "gofmt - $FIXED file(s) not formatted correctly, please run gofmt to fix this." && exit 1; fi 9 | 10 | os: 11 | - linux 12 | - osx 13 | 14 | notifications: 15 | email: false 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build freebsd openbsd netbsd dragonfly 6 | 7 | package fsnotify 8 | 9 | import "syscall" 10 | 11 | const openMode = syscall.O_NONBLOCK | syscall.O_RDONLY 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/open_mode_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin 6 | 7 | package fsnotify 8 | 9 | import "syscall" 10 | 11 | // note: this constant is not defined on BSD 12 | const openMode = syscall.O_EVTONLY 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/assert_test.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestLineNumbers(t *testing.T) { 8 | Equal(t, "foo", "foo", "msg!") 9 | //Equal(t, "foo", "bar", "this should blow up") 10 | } 11 | 12 | func TestNotEqual(t *testing.T) { 13 | NotEqual(t, "foo", "bar", "msg!") 14 | //NotEqual(t, "foo", "foo", "this should blow up") 15 | } 16 | -------------------------------------------------------------------------------- /htpasswd_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "github.com/bmizerany/assert" 6 | "testing" 7 | ) 8 | 9 | func TestHtpasswd(t *testing.T) { 10 | file := bytes.NewBuffer([]byte("testuser:{SHA}PaVBVZkYqAjCQCu6UBL2xgsnZhw=\n")) 11 | h, err := NewHtpasswd(file) 12 | assert.Equal(t, err, nil) 13 | 14 | valid := h.Validate("testuser", "asdf") 15 | assert.Equal(t, valid, true) 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/mc/Readme: -------------------------------------------------------------------------------- 1 | Command mc prints in multiple columns. 2 | 3 | Usage: mc [-] [-N] [file...] 4 | 5 | Mc splits the input into as many columns as will fit in N 6 | print positions. If the output is a tty, the default N is 7 | the number of characters in a terminal line; otherwise the 8 | default N is 80. Under option - each input line ending in 9 | a colon ':' is printed separately. 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/utils.go: -------------------------------------------------------------------------------- 1 | package uritemplates 2 | 3 | func Expand(path string, expansions map[string]string) (string, error) { 4 | template, err := Parse(path) 5 | if err != nil { 6 | return "", err 7 | } 8 | values := make(map[string]interface{}) 9 | for k, v := range expansions { 10 | values[k] = v 11 | } 12 | return template.Expand(values) 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/Makefile: -------------------------------------------------------------------------------- 1 | install: 2 | go install ./... 3 | 4 | test: install 5 | go test -v 6 | toml-test toml-test-decoder 7 | toml-test -encoder toml-test-encoder 8 | 9 | fmt: 10 | gofmt -w *.go */*.go 11 | colcheck *.go */*.go 12 | 13 | tags: 14 | find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS 15 | 16 | push: 17 | git push origin master 18 | git push github master 19 | 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/appengine_hook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine appenginevm 6 | 7 | package google 8 | 9 | import "google.golang.org/appengine" 10 | 11 | func init() { 12 | appengineTokenFunc = appengine.AccessToken 13 | } 14 | -------------------------------------------------------------------------------- /providers/provider_default_test.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/bmizerany/assert" 8 | ) 9 | 10 | func TestRefresh(t *testing.T) { 11 | p := &ProviderData{} 12 | refreshed, err := p.RefreshSessionIfNeeded(&SessionState{ 13 | ExpiresOn: time.Now().Add(time.Duration(-11) * time.Minute), 14 | }) 15 | assert.Equal(t, false, refreshed) 16 | assert.Equal(t, nil, err) 17 | } 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jonboulle/clockwork/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | 25 | *.swp 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/README.md: -------------------------------------------------------------------------------- 1 | ### go-simplejson 2 | 3 | a Go package to interact with arbitrary JSON 4 | 5 | [![Build Status](https://secure.travis-ci.org/bitly/go-simplejson.png)](http://travis-ci.org/bitly/go-simplejson) 6 | 7 | ### Importing 8 | 9 | import github.com/bitly/go-simplejson 10 | 11 | ### Documentation 12 | 13 | Visit the docs on [gopkgdoc](http://godoc.org/github.com/bitly/go-simplejson) 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/example_test.go: -------------------------------------------------------------------------------- 1 | package pretty_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/kr/pretty" 6 | ) 7 | 8 | func Example() { 9 | type myType struct { 10 | a, b int 11 | } 12 | var x = []myType{{1, 2}, {3, 4}, {5, 6}} 13 | fmt.Printf("%# v", pretty.Formatter(x)) 14 | // output: 15 | // []pretty_test.myType{ 16 | // {a:1, b:2}, 17 | // {a:3, b:4}, 18 | // {a:5, b:6}, 19 | // } 20 | } 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/18F/hmacauth/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.4.2 4 | script: 5 | - go test ./... 6 | - go get -u github.com/axw/gocov/gocov 7 | - go get -u github.com/mattn/goveralls 8 | - go get golang.org/x/tools/cmd/cover 9 | - go test -v -covermode=count $pkg -coverprofile=profile.cov 10 | - go tool cover -func profile.cov 11 | - goveralls -coverprofile=profile.cov -service=travis-ci 12 | branches: 13 | only: 14 | - master 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/health/README.md: -------------------------------------------------------------------------------- 1 | health 2 | ==== 3 | 4 | A simple framework for implementing an HTTP health check endpoint on servers. 5 | 6 | Users implement their `health.Checkable` types, and create a `health.Checker`, from which they can get an `http.HandlerFunc` using `health.Checker.MakeHealthHandlerFunc`. 7 | 8 | ### Documentation 9 | 10 | For more details, visit the docs on [gopkgdoc](http://godoc.org/github.com/coreos/pkg/health) 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | google_auth_proxy 2 | oauth2_proxy 3 | # Go.gitignore 4 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 5 | *.o 6 | *.a 7 | *.so 8 | 9 | # Folders 10 | _obj 11 | _test 12 | 13 | # Architecture specific extensions/prefixes 14 | *.[568vq] 15 | [568vq].out 16 | 17 | *.cgo1.go 18 | *.cgo2.c 19 | _cgo_defun.c 20 | _cgo_gotypes.go 21 | _cgo_export.* 22 | 23 | _testmain.go 24 | 25 | *.exe 26 | dist 27 | .godeps 28 | 29 | # Editor swap/temp files 30 | .*.swp 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | func canceler(client *http.Client, req *http.Request) func() { 12 | ch := make(chan struct{}) 13 | req.Cancel = ch 14 | 15 | return func() { 16 | close(ch) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /providers/provider_data.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "net/url" 5 | ) 6 | 7 | type ProviderData struct { 8 | ProviderName string 9 | ClientID string 10 | ClientSecret string 11 | LoginURL *url.URL 12 | RedeemURL *url.URL 13 | ProfileURL *url.URL 14 | ProtectedResource *url.URL 15 | ValidateURL *url.URL 16 | DiscoveryURL *url.URL 17 | Scope string 18 | ApprovalPrompt string 19 | } 20 | 21 | func (p *ProviderData) Data() *ProviderData { return p } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/httputil/cookie.go: -------------------------------------------------------------------------------- 1 | package httputil 2 | 3 | import ( 4 | "net/http" 5 | "time" 6 | ) 7 | 8 | // DeleteCookies effectively deletes all named cookies 9 | // by wiping all data and setting to expire immediately. 10 | func DeleteCookies(w http.ResponseWriter, cookieNames ...string) { 11 | for _, n := range cookieNames { 12 | c := &http.Cookie{ 13 | Name: n, 14 | Value: "", 15 | Path: "/", 16 | MaxAge: -1, 17 | Expires: time.Time{}, 18 | } 19 | http.SetCookie(w, c) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/vk/vk.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package vk provides constants for using OAuth2 to access VK.com. 6 | package vk 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is VK's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://oauth.vk.com/authorize", 15 | TokenURL: "https://oauth.vk.com/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/sig.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type Verifier interface { 9 | ID() string 10 | Alg() string 11 | Verify(sig []byte, data []byte) error 12 | } 13 | 14 | type Signer interface { 15 | Verifier 16 | Sign(data []byte) (sig []byte, err error) 17 | } 18 | 19 | func NewVerifier(jwk JWK) (Verifier, error) { 20 | if strings.ToUpper(jwk.Type) != "RSA" { 21 | return nil, fmt.Errorf("unsupported key type %q", jwk.Type) 22 | } 23 | 24 | return NewVerifierRSA(jwk) 25 | } 26 | -------------------------------------------------------------------------------- /env_options_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/bmizerany/assert" 8 | ) 9 | 10 | type envTest struct { 11 | testField string `cfg:"target_field" env:"TEST_ENV_FIELD"` 12 | } 13 | 14 | func TestLoadEnvForStruct(t *testing.T) { 15 | 16 | cfg := make(EnvOptions) 17 | cfg.LoadEnvForStruct(&envTest{}) 18 | 19 | _, ok := cfg["target_field"] 20 | assert.Equal(t, ok, false) 21 | 22 | os.Setenv("TEST_ENV_FIELD", "1234abcd") 23 | cfg.LoadEnvForStruct(&envTest{}) 24 | v := cfg["target_field"] 25 | assert.Equal(t, v, "1234abcd") 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/github/github.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package github provides constants for using OAuth2 to access Github. 6 | package github 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Github's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://github.com/login/oauth/authorize", 15 | TokenURL: "https://github.com/login/oauth/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/tomlv/COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/facebook/facebook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package facebook provides constants for using OAuth2 to access Facebook. 6 | package facebook 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Facebook's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.facebook.com/dialog/oauth", 15 | TokenURL: "https://graph.facebook.com/oauth/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /contrib/oauth2_proxy.service.example: -------------------------------------------------------------------------------- 1 | # Systemd service file for oauth2_proxy daemon 2 | # 3 | # Date: Feb 9, 2016 4 | # Author: Srdjan Grubor 5 | 6 | [Unit] 7 | Description=oauth2_proxy daemon service 8 | After=syslog.target network.target 9 | 10 | [Service] 11 | # www-data group and user need to be created before using these lines 12 | User=www-data 13 | Group=www-data 14 | 15 | ExecStart=/usr/local/bin/oauth2_proxy -config=/etc/oauth2_proxy.cfg 16 | ExecReload=/bin/kill -HUP $MAINPID 17 | 18 | KillMode=process 19 | Restart=always 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/toml-test-decoder/COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/toml-test-encoder/COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/httputil/json.go: -------------------------------------------------------------------------------- 1 | package httputil 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | const ( 9 | JSONContentType = "application/json" 10 | ) 11 | 12 | func WriteJSONResponse(w http.ResponseWriter, code int, resp interface{}) error { 13 | enc, err := json.Marshal(resp) 14 | if err != nil { 15 | w.WriteHeader(http.StatusInternalServerError) 16 | return err 17 | } 18 | 19 | w.Header().Set("Content-Type", JSONContentType) 20 | w.WriteHeader(code) 21 | 22 | _, err = w.Write(enc) 23 | if err != nil { 24 | return err 25 | } 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/linkedin/linkedin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package linkedin provides constants for using OAuth2 to access LinkedIn. 6 | package linkedin 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is LinkedIn's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.linkedin.com/uas/oauth2/authorization", 15 | TokenURL: "https://www.linkedin.com/uas/oauth2/accessToken", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/cloud/internal/opts/option.go: -------------------------------------------------------------------------------- 1 | // Package opts holds the DialOpts struct, configurable by 2 | // cloud.ClientOptions to set up transports for cloud packages. 3 | // 4 | // This is a separate page to prevent cycles between the core 5 | // cloud packages. 6 | package opts 7 | 8 | import ( 9 | "net/http" 10 | 11 | "golang.org/x/oauth2" 12 | "google.golang.org/grpc" 13 | ) 14 | 15 | type DialOpt struct { 16 | Endpoint string 17 | Scopes []string 18 | UserAgent string 19 | 20 | TokenSource oauth2.TokenSource 21 | 22 | HTTPClient *http.Client 23 | GRPCClient *grpc.ClientConn 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/toml-test-decoder/README.md: -------------------------------------------------------------------------------- 1 | # Implements the TOML test suite interface 2 | 3 | This is an implementation of the interface expected by 4 | [toml-test](https://github.com/BurntSushi/toml-test) for my 5 | [toml parser written in Go](https://github.com/BurntSushi/toml). 6 | In particular, it maps TOML data on `stdin` to a JSON format on `stdout`. 7 | 8 | 9 | Compatible with TOML version 10 | [v0.2.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.2.0.md) 11 | 12 | Compatible with `toml-test` version 13 | [v0.2.0](https://github.com/BurntSushi/toml-test/tree/v0.2.0) 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.5 6 | 7 | package ctxhttp 8 | 9 | import "net/http" 10 | 11 | type requestCanceler interface { 12 | CancelRequest(*http.Request) 13 | } 14 | 15 | func canceler(client *http.Client, req *http.Request) func() { 16 | rc, ok := client.Transport.(requestCanceler) 17 | if !ok { 18 | return func() {} 19 | } 20 | return func() { 21 | rc.CancelRequest(req) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package odnoklassniki provides constants for using OAuth2 to access Odnoklassniki. 6 | package odnoklassniki 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Odnoklassniki's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.odnoklassniki.ru/oauth/authorize", 15 | TokenURL: "https://api.odnoklassniki.ru/oauth/token.do", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/toml-test-encoder/README.md: -------------------------------------------------------------------------------- 1 | # Implements the TOML test suite interface for TOML encoders 2 | 3 | This is an implementation of the interface expected by 4 | [toml-test](https://github.com/BurntSushi/toml-test) for the 5 | [TOML encoder](https://github.com/BurntSushi/toml). 6 | In particular, it maps JSON data on `stdin` to a TOML format on `stdout`. 7 | 8 | 9 | Compatible with TOML version 10 | [v0.2.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.2.0.md) 11 | 12 | Compatible with `toml-test` version 13 | [v0.2.0](https://github.com/BurntSushi/toml-test/tree/v0.2.0) 14 | 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/encoding_types_1.1.go: -------------------------------------------------------------------------------- 1 | // +build !go1.2 2 | 3 | package toml 4 | 5 | // These interfaces were introduced in Go 1.2, so we add them manually when 6 | // compiling for Go 1.1. 7 | 8 | // TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here 9 | // so that Go 1.1 can be supported. 10 | type TextMarshaler interface { 11 | MarshalText() (text []byte, err error) 12 | } 13 | 14 | // TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined here 15 | // so that Go 1.1 can be supported. 16 | type TextUnmarshaler interface { 17 | UnmarshalText(text []byte) error 18 | } 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/encoding_types.go: -------------------------------------------------------------------------------- 1 | // +build go1.2 2 | 3 | package toml 4 | 5 | // In order to support Go 1.1, we define our own TextMarshaler and 6 | // TextUnmarshaler types. For Go 1.2+, we just alias them with the 7 | // standard library interfaces. 8 | 9 | import ( 10 | "encoding" 11 | ) 12 | 13 | // TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here 14 | // so that Go 1.1 can be supported. 15 | type TextMarshaler encoding.TextMarshaler 16 | 17 | // TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined here 18 | // so that Go 1.1 can be supported. 19 | type TextUnmarshaler encoding.TextUnmarshaler 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/tomlv/README.md: -------------------------------------------------------------------------------- 1 | # TOML Validator 2 | 3 | If Go is installed, it's simple to try it out: 4 | 5 | ```bash 6 | go get github.com/BurntSushi/toml/cmd/tomlv 7 | tomlv some-toml-file.toml 8 | ``` 9 | 10 | You can see the types of every key in a TOML file with: 11 | 12 | ```bash 13 | tomlv -types some-toml-file.toml 14 | ``` 15 | 16 | At the moment, only one error message is reported at a time. Error messages 17 | include line numbers. No output means that the files given are valid TOML, or 18 | there is a bug in `tomlv`. 19 | 20 | Compatible with TOML version 21 | [v0.1.0](https://github.com/mojombo/toml/blob/master/versions/toml-v0.1.0.md) 22 | 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/client_appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine appenginevm 6 | 7 | // App Engine hooks. 8 | 9 | package oauth2 10 | 11 | import ( 12 | "net/http" 13 | 14 | "golang.org/x/net/context" 15 | "golang.org/x/oauth2/internal" 16 | "google.golang.org/appengine/urlfetch" 17 | ) 18 | 19 | func init() { 20 | internal.RegisterContextClientFunc(contextClientAppEngine) 21 | } 22 | 23 | func contextClientAppEngine(ctx context.Context) (*http.Client, error) { 24 | return urlfetch.Client(ctx), nil 25 | } 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/circle.yml: -------------------------------------------------------------------------------- 1 | ## OS X build (CircleCI iOS beta) 2 | 3 | # Pretend like it's an Xcode project, at least to get it running. 4 | machine: 5 | environment: 6 | XCODE_WORKSPACE: NotUsed.xcworkspace 7 | XCODE_SCHEME: NotUsed 8 | # This is where the go project is actually checked out to: 9 | CIRCLE_BUILD_DIR: $HOME/.go_project/src/github.com/go-fsnotify/fsnotify 10 | 11 | dependencies: 12 | pre: 13 | - brew upgrade go 14 | 15 | test: 16 | override: 17 | - go test ./... 18 | 19 | # Idealized future config, eventually with cross-platform build matrix :-) 20 | 21 | # machine: 22 | # go: 23 | # version: 1.4 24 | # os: 25 | # - osx 26 | # - linux 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/http/url.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "errors" 5 | "net/url" 6 | ) 7 | 8 | // ParseNonEmptyURL checks that a string is a parsable URL which is also not empty 9 | // since `url.Parse("")` does not return an error. Must contian a scheme and a host. 10 | func ParseNonEmptyURL(u string) (*url.URL, error) { 11 | if u == "" { 12 | return nil, errors.New("url is empty") 13 | } 14 | 15 | ur, err := url.Parse(u) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | if ur.Scheme == "" { 21 | return nil, errors.New("url scheme is empty") 22 | } 23 | 24 | if ur.Host == "" { 25 | return nil, errors.New("url host is empty") 26 | } 27 | 28 | return ur, nil 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package context_test 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | func ExampleWithTimeout() { 15 | // Pass a context with a timeout to tell a blocking function that it 16 | // should abandon its work after the timeout elapses. 17 | ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) 18 | select { 19 | case <-time.After(200 * time.Millisecond): 20 | fmt.Println("overslept") 21 | case <-ctx.Done(): 22 | fmt.Println(ctx.Err()) // prints "context deadline exceeded" 23 | } 24 | // Output: 25 | // context deadline exceeded 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/internal/token_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "fmt" 10 | "testing" 11 | ) 12 | 13 | func Test_providerAuthHeaderWorks(t *testing.T) { 14 | for _, p := range brokenAuthHeaderProviders { 15 | if providerAuthHeaderWorks(p) { 16 | t.Errorf("URL: %s not found in list", p) 17 | } 18 | p := fmt.Sprintf("%ssomesuffix", p) 19 | if providerAuthHeaderWorks(p) { 20 | t.Errorf("URL: %s not found in list", p) 21 | } 22 | } 23 | p := "https://api.not-in-the-list-example.com/" 24 | if !providerAuthHeaderWorks(p) { 25 | t.Errorf("URL: %s found in list", p) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/init_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package capnslog 16 | 17 | import "os" 18 | 19 | func init() { 20 | initHijack() 21 | 22 | // Go `log` package uses os.Stderr. 23 | SetFormatter(NewPrettyFormatter(os.Stderr, false)) 24 | SetGlobalLogLevel(INFO) 25 | } 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/README.md: -------------------------------------------------------------------------------- 1 | # Assert (c) Blake Mizerany and Keith Rarick -- MIT LICENCE 2 | 3 | ## Assertions for Go tests 4 | 5 | ## Install 6 | 7 | $ go get github.com/bmizerany/assert 8 | 9 | ## Use 10 | 11 | **point.go** 12 | 13 | package point 14 | 15 | type Point struct { 16 | x, y int 17 | } 18 | 19 | **point_test.go** 20 | 21 | 22 | package point 23 | 24 | import ( 25 | "testing" 26 | "github.com/bmizerany/assert" 27 | ) 28 | 29 | func TestAsserts(t *testing.T) { 30 | p1 := Point{1, 1} 31 | p2 := Point{2, 1} 32 | 33 | assert.Equal(t, p1, p2) 34 | } 35 | 36 | **output** 37 | $ go test 38 | --- FAIL: TestAsserts (0.00 seconds) 39 | assert.go:15: /Users/flavio.barbosa/dev/stewie/src/point_test.go:12 40 | assert.go:24: ! X: 1 != 2 41 | FAIL 42 | 43 | ## Docs 44 | 45 | http://github.com/bmizerany/assert 46 | -------------------------------------------------------------------------------- /dist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # build binary distributions for linux/amd64 and darwin/amd64 4 | set -e 5 | 6 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | echo "working dir $DIR" 8 | mkdir -p $DIR/dist 9 | mkdir -p $DIR/.godeps 10 | export GOPATH=$DIR/.godeps:$GOPATH 11 | gpm install 12 | 13 | os=$(go env GOOS) 14 | arch=$(go env GOARCH) 15 | version=$(cat $DIR/version.go | grep "const VERSION" | awk '{print $NF}' | sed 's/"//g') 16 | goversion=$(go version | awk '{print $3}') 17 | 18 | echo "... running tests" 19 | ./test.sh || exit 1 20 | 21 | for os in windows linux darwin; do 22 | echo "... building v$version for $os/$arch" 23 | BUILD=$(mktemp -d ${TMPDIR:-/tmp}/oauth2_proxy.XXXXXX) 24 | TARGET="oauth2_proxy-$version.$os-$arch.$goversion" 25 | GOOS=$os GOARCH=$arch CGO_ENABLED=0 go build -o $BUILD/$TARGET/oauth2_proxy || exit 1 26 | pushd $BUILD 27 | tar czvf $TARGET.tar.gz $TARGET 28 | mv $TARGET.tar.gz $DIR/dist 29 | popd 30 | done 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/paypal/paypal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package paypal provides constants for using OAuth2 to access PayPal. 6 | package paypal 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is PayPal's OAuth 2.0 endpoint in live (production) environment. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize", 15 | TokenURL: "https://api.paypal.com/v1/identity/openidconnect/tokenservice", 16 | } 17 | 18 | // SandboxEndpoint is PayPal's OAuth 2.0 endpoint in sandbox (testing) environment. 19 | var SandboxEndpoint = oauth2.Endpoint{ 20 | AuthURL: "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize", 21 | TokenURL: "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice", 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oidc/identity.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | import ( 4 | "errors" 5 | "time" 6 | 7 | "github.com/coreos/go-oidc/jose" 8 | ) 9 | 10 | type Identity struct { 11 | ID string 12 | Name string 13 | Email string 14 | ExpiresAt time.Time 15 | } 16 | 17 | func IdentityFromClaims(claims jose.Claims) (*Identity, error) { 18 | if claims == nil { 19 | return nil, errors.New("nil claim set") 20 | } 21 | 22 | var ident Identity 23 | var err error 24 | var ok bool 25 | 26 | if ident.ID, ok, err = claims.StringClaim("sub"); err != nil { 27 | return nil, err 28 | } else if !ok { 29 | return nil, errors.New("missing required claim: sub") 30 | } 31 | 32 | if ident.Email, _, err = claims.StringClaim("email"); err != nil { 33 | return nil, err 34 | } 35 | 36 | exp, ok, err := claims.TimeClaim("exp") 37 | if err != nil { 38 | return nil, err 39 | } else if ok { 40 | ident.ExpiresAt = exp 41 | } 42 | 43 | return &ident, nil 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !plan9,!solaris 6 | 7 | package fsnotify_test 8 | 9 | import ( 10 | "log" 11 | 12 | "github.com/go-fsnotify/fsnotify" 13 | ) 14 | 15 | func ExampleNewWatcher() { 16 | watcher, err := fsnotify.NewWatcher() 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer watcher.Close() 21 | 22 | done := make(chan bool) 23 | go func() { 24 | for { 25 | select { 26 | case event := <-watcher.Events: 27 | log.Println("event:", event) 28 | if event.Op&fsnotify.Write == fsnotify.Write { 29 | log.Println("modified file:", event.Name) 30 | } 31 | case err := <-watcher.Errors: 32 | log.Println("error:", err) 33 | } 34 | } 35 | }() 36 | 37 | err = watcher.Add("/tmp/foo") 38 | if err != nil { 39 | log.Fatal(err) 40 | } 41 | <-done 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mreiferson/go-options/example_test.go: -------------------------------------------------------------------------------- 1 | package options_test 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "time" 7 | 8 | "github.com/mreiferson/go-options" 9 | ) 10 | 11 | type Options struct { 12 | MaxSize int64 `flag:"max-size" cfg:"max_size"` 13 | Timeout time.Duration `flag:"timeout" cfg:"timeout"` 14 | Description string `flag:"description" cfg:"description"` 15 | } 16 | 17 | func ExampleResolve() { 18 | flagSet := flag.NewFlagSet("example", flag.ExitOnError) 19 | flagSet.Int64("max-size", 1024768, "maximum size") 20 | flagSet.Duration("timeout", 1*time.Hour, "timeout setting") 21 | // parse command line arguments here 22 | // flagSet.Parse(os.Args[1:]) 23 | flagSet.Parse([]string{"-timeout=5s"}) 24 | 25 | opts := &Options{ 26 | MaxSize: 1, 27 | Timeout: time.Second, 28 | } 29 | cfg := map[string]interface{}{ 30 | "timeout": "1h", 31 | } 32 | 33 | fmt.Printf("%#v", opts) 34 | options.Resolve(opts, flagSet, cfg) 35 | fmt.Printf("%#v", opts) 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/key/repo.go: -------------------------------------------------------------------------------- 1 | package key 2 | 3 | import "errors" 4 | 5 | var ErrorNoKeys = errors.New("no keys found") 6 | 7 | type WritableKeySetRepo interface { 8 | Set(KeySet) error 9 | } 10 | 11 | type ReadableKeySetRepo interface { 12 | Get() (KeySet, error) 13 | } 14 | 15 | type PrivateKeySetRepo interface { 16 | WritableKeySetRepo 17 | ReadableKeySetRepo 18 | } 19 | 20 | func NewPrivateKeySetRepo() PrivateKeySetRepo { 21 | return &memPrivateKeySetRepo{} 22 | } 23 | 24 | type memPrivateKeySetRepo struct { 25 | pks PrivateKeySet 26 | } 27 | 28 | func (r *memPrivateKeySetRepo) Set(ks KeySet) error { 29 | pks, ok := ks.(*PrivateKeySet) 30 | if !ok { 31 | return errors.New("unable to cast to PrivateKeySet") 32 | } else if pks == nil { 33 | return errors.New("nil KeySet") 34 | } 35 | 36 | r.pks = *pks 37 | return nil 38 | } 39 | 40 | func (r *memPrivateKeySetRepo) Get() (KeySet, error) { 41 | if r.pks.keys == nil { 42 | return nil, ErrorNoKeys 43 | } 44 | return KeySet(&r.pks), nil 45 | } 46 | -------------------------------------------------------------------------------- /env_options.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "reflect" 6 | "strings" 7 | ) 8 | 9 | type EnvOptions map[string]interface{} 10 | 11 | func (cfg EnvOptions) LoadEnvForStruct(options interface{}) { 12 | val := reflect.ValueOf(options).Elem() 13 | typ := val.Type() 14 | for i := 0; i < typ.NumField(); i++ { 15 | // pull out the struct tags: 16 | // flag - the name of the command line flag 17 | // deprecated - (optional) the name of the deprecated command line flag 18 | // cfg - (optional, defaults to underscored flag) the name of the config file option 19 | field := typ.Field(i) 20 | flagName := field.Tag.Get("flag") 21 | envName := field.Tag.Get("env") 22 | cfgName := field.Tag.Get("cfg") 23 | if cfgName == "" && flagName != "" { 24 | cfgName = strings.Replace(flagName, "-", "_", -1) 25 | } 26 | if envName == "" || cfgName == "" { 27 | // resolvable fields must have the `env` and `cfg` struct tag 28 | continue 29 | } 30 | v := os.Getenv(envName) 31 | if v != "" { 32 | cfg[cfgName] = v 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oauth2/error.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | const ( 9 | ErrorAccessDenied = "access_denied" 10 | ErrorInvalidClient = "invalid_client" 11 | ErrorInvalidGrant = "invalid_grant" 12 | ErrorInvalidRequest = "invalid_request" 13 | ErrorServerError = "server_error" 14 | ErrorUnauthorizedClient = "unauthorized_client" 15 | ErrorUnsupportedGrantType = "unsupported_grant_type" 16 | ErrorUnsupportedResponseType = "unsupported_response_type" 17 | ) 18 | 19 | type Error struct { 20 | Type string `json:"error"` 21 | State string `json:"state,omitempty"` 22 | } 23 | 24 | func (e *Error) Error() string { 25 | return e.Type 26 | } 27 | 28 | func NewError(typ string) *Error { 29 | return &Error{Type: typ} 30 | } 31 | 32 | func unmarshalError(b []byte) error { 33 | var oerr Error 34 | err := json.Unmarshal(b, &oerr) 35 | if err != nil { 36 | return fmt.Errorf("unrecognized error: %s", string(b)) 37 | } 38 | return &oerr 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/cloud/internal/transport/cancelreq.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build go1.5 16 | 17 | package transport 18 | 19 | import "net/http" 20 | 21 | // makeReqCancel returns a closure that cancels the given http.Request 22 | // when called. 23 | func makeReqCancel(req *http.Request) func(http.RoundTripper) { 24 | c := make(chan struct{}) 25 | req.Cancel = c 26 | return func(http.RoundTripper) { 27 | close(c) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/timeutil/backoff_test.go: -------------------------------------------------------------------------------- 1 | package timeutil 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestExpBackoff(t *testing.T) { 9 | tests := []struct { 10 | prev time.Duration 11 | max time.Duration 12 | want time.Duration 13 | }{ 14 | { 15 | prev: time.Duration(0), 16 | max: time.Minute, 17 | want: time.Second, 18 | }, 19 | { 20 | prev: time.Second, 21 | max: time.Minute, 22 | want: 2 * time.Second, 23 | }, 24 | { 25 | prev: 16 * time.Second, 26 | max: time.Minute, 27 | want: 32 * time.Second, 28 | }, 29 | { 30 | prev: 32 * time.Second, 31 | max: time.Minute, 32 | want: time.Minute, 33 | }, 34 | { 35 | prev: time.Minute, 36 | max: time.Minute, 37 | want: time.Minute, 38 | }, 39 | { 40 | prev: 2 * time.Minute, 41 | max: time.Minute, 42 | want: time.Minute, 43 | }, 44 | } 45 | 46 | for i, tt := range tests { 47 | got := ExpBackoff(tt.prev, tt.max) 48 | if tt.want != got { 49 | t.Errorf("case %d: want=%v got=%v", i, tt.want, got) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/api/gensupport/params.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gensupport 6 | 7 | import "net/url" 8 | 9 | // URLParams is a simplified replacement for url.Values 10 | // that safely builds up URL parameters for encoding. 11 | type URLParams map[string][]string 12 | 13 | // Set sets the key to value. 14 | // It replaces any existing values. 15 | func (u URLParams) Set(key, value string) { 16 | u[key] = []string{value} 17 | } 18 | 19 | // SetMulti sets the key to an array of values. 20 | // It replaces any existing values. 21 | // Note that values must not be modified after calling SetMulti 22 | // so the caller is responsible for making a copy if necessary. 23 | func (u URLParams) SetMulti(key string, values []string) { 24 | u[key] = values 25 | } 26 | 27 | // Encode encodes the values into ``URL encoded'' form 28 | // ("bar=baz&foo=quux") sorted by key. 29 | func (u URLParams) Encode() string { 30 | return url.Values(u).Encode() 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mreiferson/go-options/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software and associated documentation files (the "Software"), to deal 3 | in the Software without restriction, including without limitation the rights 4 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 5 | copies of the Software, and to permit persons to whom the Software is 6 | furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in 9 | all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 | THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jonboulle/clockwork/example_test.go: -------------------------------------------------------------------------------- 1 | package clockwork 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // my_func is an example of a time-dependent function, using an 10 | // injected clock 11 | func my_func(clock Clock, i *int) { 12 | clock.Sleep(3 * time.Second) 13 | *i += 1 14 | } 15 | 16 | // assert_state is an example of a state assertion in a test 17 | func assert_state(t *testing.T, i, j int) { 18 | if i != j { 19 | t.Fatalf("i %d, j %d", i, j) 20 | } 21 | } 22 | 23 | // TestMyFunc tests my_func's behaviour with a FakeClock 24 | func TestMyFunc(t *testing.T) { 25 | var i int 26 | c := NewFakeClock() 27 | 28 | var wg sync.WaitGroup 29 | wg.Add(1) 30 | go func() { 31 | my_func(c, &i) 32 | wg.Done() 33 | }() 34 | 35 | // Wait until my_func is actually sleeping on the clock 36 | c.BlockUntil(1) 37 | 38 | // Assert the initial state 39 | assert_state(t, i, 0) 40 | 41 | // Now advance the clock forward in time 42 | c.Advance(1 * time.Hour) 43 | 44 | // Wait until the function completes 45 | wg.Wait() 46 | 47 | // Assert the final state 48 | assert_state(t, i, 1) 49 | } 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/License: -------------------------------------------------------------------------------- 1 | Copyright 2012 Keith Rarick 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /cookie/cookies_test.go: -------------------------------------------------------------------------------- 1 | package cookie 2 | 3 | import ( 4 | "encoding/base64" 5 | "testing" 6 | 7 | "github.com/bmizerany/assert" 8 | ) 9 | 10 | func TestEncodeAndDecodeAccessToken(t *testing.T) { 11 | const secret = "0123456789abcdefghijklmnopqrstuv" 12 | const token = "my access token" 13 | c, err := NewCipher([]byte(secret)) 14 | assert.Equal(t, nil, err) 15 | 16 | encoded, err := c.Encrypt(token) 17 | assert.Equal(t, nil, err) 18 | 19 | decoded, err := c.Decrypt(encoded) 20 | assert.Equal(t, nil, err) 21 | 22 | assert.NotEqual(t, token, encoded) 23 | assert.Equal(t, token, decoded) 24 | } 25 | 26 | func TestEncodeAndDecodeAccessTokenB64(t *testing.T) { 27 | const secret_b64 = "A3Xbr6fu6Al0HkgrP1ztjb-mYiwmxgNPP-XbNsz1WBk=" 28 | const token = "my access token" 29 | 30 | secret, err := base64.URLEncoding.DecodeString(secret_b64) 31 | c, err := NewCipher([]byte(secret)) 32 | assert.Equal(t, nil, err) 33 | 34 | encoded, err := c.Encrypt(token) 35 | assert.Equal(t, nil, err) 36 | 37 | decoded, err := c.Decrypt(encoded) 38 | assert.Equal(t, nil, err) 39 | 40 | assert.NotEqual(t, token, encoded) 41 | assert.Equal(t, token, decoded) 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/jwt/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package jwt_test 6 | 7 | import ( 8 | "golang.org/x/oauth2" 9 | "golang.org/x/oauth2/jwt" 10 | ) 11 | 12 | func ExampleJWTConfig() { 13 | conf := &jwt.Config{ 14 | Email: "xxx@developer.com", 15 | // The contents of your RSA private key or your PEM file 16 | // that contains a private key. 17 | // If you have a p12 file instead, you 18 | // can use `openssl` to export the private key into a pem file. 19 | // 20 | // $ openssl pkcs12 -in key.p12 -out key.pem -nodes 21 | // 22 | // It only supports PEM containers with no passphrase. 23 | PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."), 24 | Subject: "user@example.com", 25 | TokenURL: "https://provider.com/o/oauth2/token", 26 | } 27 | // Initiate an http.Client, the following GET request will be 28 | // authorized and authenticated on the behalf of user@example.com. 29 | client := conf.Client(oauth2.NoContext) 30 | client.Get("...") 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/http/url_test.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "net/url" 5 | "testing" 6 | ) 7 | 8 | func TestParseNonEmptyURL(t *testing.T) { 9 | tests := []struct { 10 | u string 11 | ok bool 12 | }{ 13 | {"", false}, 14 | {"http://", false}, 15 | {"example.com", false}, 16 | {"example", false}, 17 | {"http://example", true}, 18 | {"http://example:1234", true}, 19 | {"http://example.com", true}, 20 | {"http://example.com:1234", true}, 21 | } 22 | 23 | for i, tt := range tests { 24 | u, err := ParseNonEmptyURL(tt.u) 25 | if err != nil { 26 | t.Logf("err: %v", err) 27 | if tt.ok { 28 | t.Errorf("case %d: unexpected error: %v", i, err) 29 | } else { 30 | continue 31 | } 32 | } 33 | 34 | if !tt.ok { 35 | t.Errorf("case %d: expected error but got none", i) 36 | continue 37 | } 38 | 39 | uu, err := url.Parse(tt.u) 40 | if err != nil { 41 | t.Errorf("case %d: unexpected error: %v", i, err) 42 | continue 43 | } 44 | 45 | if uu.String() != u.String() { 46 | t.Errorf("case %d: incorrect url value, want: %q, got: %q", i, uu.String(), u.String()) 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2012 Keith Rarick 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/api/googleapi/internal/uritemplates/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Joshua Tacoma 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/log_hijack.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package capnslog 16 | 17 | import ( 18 | "log" 19 | ) 20 | 21 | func initHijack() { 22 | pkg := NewPackageLogger("log", "") 23 | w := packageWriter{pkg} 24 | log.SetFlags(0) 25 | log.SetPrefix("") 26 | log.SetOutput(w) 27 | } 28 | 29 | type packageWriter struct { 30 | pl *PackageLogger 31 | } 32 | 33 | func (p packageWriter) Write(b []byte) (int, error) { 34 | if p.pl.level < INFO { 35 | return 0, nil 36 | } 37 | p.pl.internalLog(calldepth+2, INFO, string(b)) 38 | return len(b), nil 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/zero.go: -------------------------------------------------------------------------------- 1 | package pretty 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | func nonzero(v reflect.Value) bool { 8 | switch v.Kind() { 9 | case reflect.Bool: 10 | return v.Bool() 11 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 12 | return v.Int() != 0 13 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 14 | return v.Uint() != 0 15 | case reflect.Float32, reflect.Float64: 16 | return v.Float() != 0 17 | case reflect.Complex64, reflect.Complex128: 18 | return v.Complex() != complex(0, 0) 19 | case reflect.String: 20 | return v.String() != "" 21 | case reflect.Struct: 22 | for i := 0; i < v.NumField(); i++ { 23 | if nonzero(getField(v, i)) { 24 | return true 25 | } 26 | } 27 | return false 28 | case reflect.Array: 29 | for i := 0; i < v.Len(); i++ { 30 | if nonzero(v.Index(i)) { 31 | return true 32 | } 33 | } 34 | return false 35 | case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func: 36 | return !v.IsNil() 37 | case reflect.UnsafePointer: 38 | return v.Pointer() != 0 39 | } 40 | return true 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Go 2 | 3 | Go is an open source project. 4 | 5 | It is the work of hundreds of contributors. We appreciate your help! 6 | 7 | 8 | ## Filing issues 9 | 10 | When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: 11 | 12 | 1. What version of Go are you using (`go version`)? 13 | 2. What operating system and processor architecture are you using? 14 | 3. What did you do? 15 | 4. What did you expect to see? 16 | 5. What did you see instead? 17 | 18 | General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. 19 | The gophers there will answer or ask you to file an issue if you've tripped over a bug. 20 | 21 | ## Contributing code 22 | 23 | Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) 24 | before sending patches. 25 | 26 | **We do not accept GitHub pull requests** 27 | (we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). 28 | 29 | Unless otherwise noted, the Go source files are distributed under 30 | the BSD-style license found in the LICENSE file. 31 | 32 | -------------------------------------------------------------------------------- /providers/providers.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "github.com/bitly/oauth2_proxy/cookie" 5 | ) 6 | 7 | type Provider interface { 8 | Data() *ProviderData 9 | GetEmailAddress(*SessionState) (string, error) 10 | Redeem(string, string) (*SessionState, error) 11 | ValidateGroup(string) bool 12 | ValidateSessionState(*SessionState) bool 13 | GetLoginURL(redirectURI, finalRedirect string) string 14 | RefreshSessionIfNeeded(*SessionState) (bool, error) 15 | SessionFromCookie(string, *cookie.Cipher) (*SessionState, error) 16 | CookieForSession(*SessionState, *cookie.Cipher) (string, error) 17 | } 18 | 19 | func New(provider string, p *ProviderData) Provider { 20 | switch provider { 21 | case "myusa": 22 | return NewMyUsaProvider(p) 23 | case "linkedin": 24 | return NewLinkedInProvider(p) 25 | case "facebook": 26 | return NewFacebookProvider(p) 27 | case "github": 28 | return NewGitHubProvider(p) 29 | case "azure": 30 | return NewAzureProvider(p) 31 | case "gitlab": 32 | return NewGitLabProvider(p) 33 | case "oidc": 34 | return NewOIDCProvider(p) 35 | case "google": 36 | return NewGoogleProvider(p) 37 | default: 38 | // TODO(philips): this should error out 39 | return NewGoogleProvider(p) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/api/googleapi/transport/apikey.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package transport contains HTTP transports used to make 6 | // authenticated API requests. 7 | package transport 8 | 9 | import ( 10 | "errors" 11 | "net/http" 12 | ) 13 | 14 | // APIKey is an HTTP Transport which wraps an underlying transport and 15 | // appends an API Key "key" parameter to the URL of outgoing requests. 16 | type APIKey struct { 17 | // Key is the API Key to set on requests. 18 | Key string 19 | 20 | // Transport is the underlying HTTP transport. 21 | // If nil, http.DefaultTransport is used. 22 | Transport http.RoundTripper 23 | } 24 | 25 | func (t *APIKey) RoundTrip(req *http.Request) (*http.Response, error) { 26 | rt := t.Transport 27 | if rt == nil { 28 | rt = http.DefaultTransport 29 | if rt == nil { 30 | return nil, errors.New("googleapi/transport: no Transport specified or available") 31 | } 32 | } 33 | newReq := *req 34 | args := newReq.URL.Query() 35 | args.Set("key", t.Key) 36 | newReq.URL.RawQuery = args.Encode() 37 | return rt.RoundTrip(&newReq) 38 | } 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package toml provides facilities for decoding and encoding TOML configuration 3 | files via reflection. There is also support for delaying decoding with 4 | the Primitive type, and querying the set of keys in a TOML document with the 5 | MetaData type. 6 | 7 | The specification implemented: https://github.com/mojombo/toml 8 | 9 | The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify 10 | whether a file is a valid TOML document. It can also be used to print the 11 | type of each key in a TOML document. 12 | 13 | Testing 14 | 15 | There are two important types of tests used for this package. The first is 16 | contained inside '*_test.go' files and uses the standard Go unit testing 17 | framework. These tests are primarily devoted to holistically testing the 18 | decoder and encoder. 19 | 20 | The second type of testing is used to verify the implementation's adherence 21 | to the TOML specification. These tests have been factored into their own 22 | project: https://github.com/BurntSushi/toml-test 23 | 24 | The reason the tests are in a separate project is so that they can be used by 25 | any implementation of TOML. Namely, it is language agnostic. 26 | */ 27 | package toml 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/api/googleapi/types_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package googleapi 6 | 7 | import ( 8 | "encoding/json" 9 | "reflect" 10 | "testing" 11 | ) 12 | 13 | func TestTypes(t *testing.T) { 14 | type T struct { 15 | I32 Int32s 16 | I64 Int64s 17 | U32 Uint32s 18 | U64 Uint64s 19 | F64 Float64s 20 | } 21 | v := &T{ 22 | I32: Int32s{-1, 2, 3}, 23 | I64: Int64s{-1, 2, 1 << 33}, 24 | U32: Uint32s{1, 2}, 25 | U64: Uint64s{1, 2, 1 << 33}, 26 | F64: Float64s{1.5, 3.33}, 27 | } 28 | got, err := json.Marshal(v) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | want := `{"I32":["-1","2","3"],"I64":["-1","2","8589934592"],"U32":["1","2"],"U64":["1","2","8589934592"],"F64":["1.5","3.33"]}` 33 | if string(got) != want { 34 | t.Fatalf("Marshal mismatch.\n got: %s\nwant: %s\n", got, want) 35 | } 36 | 37 | v2 := new(T) 38 | if err := json.Unmarshal(got, v2); err != nil { 39 | t.Fatalf("Unmarshal: %v", err) 40 | } 41 | if !reflect.DeepEqual(v, v2) { 42 | t.Fatalf("Unmarshal didn't produce same results.\n got: %#v\nwant: %#v\n", v, v2) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/cloud/internal/transport/cancelreq_legacy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build !go1.5 16 | 17 | package transport 18 | 19 | import "net/http" 20 | 21 | // makeReqCancel returns a closure that cancels the given http.Request 22 | // when called. 23 | func makeReqCancel(req *http.Request) func(http.RoundTripper) { 24 | // Go 1.4 and prior do not have a reliable way of cancelling a request. 25 | // Transport.CancelRequest will only work if the request is already in-flight. 26 | return func(r http.RoundTripper) { 27 | if t, ok := r.(*http.Transport); ok { 28 | t.CancelRequest(req) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/http/client.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | "net/http/httptest" 7 | ) 8 | 9 | type Client interface { 10 | Do(*http.Request) (*http.Response, error) 11 | } 12 | 13 | type HandlerClient struct { 14 | Handler http.Handler 15 | } 16 | 17 | func (hc *HandlerClient) Do(r *http.Request) (*http.Response, error) { 18 | w := httptest.NewRecorder() 19 | hc.Handler.ServeHTTP(w, r) 20 | 21 | resp := http.Response{ 22 | StatusCode: w.Code, 23 | Header: w.Header(), 24 | Body: ioutil.NopCloser(w.Body), 25 | } 26 | 27 | return &resp, nil 28 | } 29 | 30 | type RequestRecorder struct { 31 | Response *http.Response 32 | Error error 33 | 34 | Request *http.Request 35 | } 36 | 37 | func (rr *RequestRecorder) Do(req *http.Request) (*http.Response, error) { 38 | rr.Request = req 39 | 40 | if rr.Response == nil && rr.Error == nil { 41 | panic("RequestRecorder Response and Error cannot both be nil") 42 | } else if rr.Response != nil && rr.Error != nil { 43 | panic("RequestRecorder Response and Error cannot both be non-nil") 44 | } 45 | 46 | return rr.Response, rr.Error 47 | } 48 | 49 | func (rr *RequestRecorder) RoundTrip(req *http.Request) (*http.Response, error) { 50 | return rr.Do(req) 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file as 2 | # Name or Organization 3 | # The email address is not required for organizations. 4 | 5 | # You can update this list using the following command: 6 | # 7 | # $ git shortlog -se | awk '{print $2 " " $3 " " $4}' 8 | 9 | # Please keep the list sorted. 10 | 11 | Adrien Bustany 12 | Caleb Spare 13 | Case Nelson 14 | Chris Howey 15 | Christoffer Buchholz 16 | Dave Cheney 17 | Francisco Souza 18 | Hari haran 19 | John C Barstow 20 | Kelvin Fo 21 | Matt Layher 22 | Nathan Youngman 23 | Paul Hammond 24 | Pieter Droogendijk 25 | Pursuit92 26 | Rob Figueiredo 27 | Soge Zhang 28 | Tilak Sharma 29 | Travis Cline 30 | Tudor Golubenco 31 | Yukang 32 | bronze1man 33 | debrando 34 | henrikedwards 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/tomlv/main.go: -------------------------------------------------------------------------------- 1 | // Command tomlv validates TOML documents and prints each key's type. 2 | package main 3 | 4 | import ( 5 | "flag" 6 | "fmt" 7 | "log" 8 | "os" 9 | "path" 10 | "strings" 11 | "text/tabwriter" 12 | 13 | "github.com/BurntSushi/toml" 14 | ) 15 | 16 | var ( 17 | flagTypes = false 18 | ) 19 | 20 | func init() { 21 | log.SetFlags(0) 22 | 23 | flag.BoolVar(&flagTypes, "types", flagTypes, 24 | "When set, the types of every defined key will be shown.") 25 | 26 | flag.Usage = usage 27 | flag.Parse() 28 | } 29 | 30 | func usage() { 31 | log.Printf("Usage: %s toml-file [ toml-file ... ]\n", 32 | path.Base(os.Args[0])) 33 | flag.PrintDefaults() 34 | 35 | os.Exit(1) 36 | } 37 | 38 | func main() { 39 | if flag.NArg() < 1 { 40 | flag.Usage() 41 | } 42 | for _, f := range flag.Args() { 43 | var tmp interface{} 44 | md, err := toml.DecodeFile(f, &tmp) 45 | if err != nil { 46 | log.Fatalf("Error in '%s': %s", f, err) 47 | } 48 | if flagTypes { 49 | printTypes(md) 50 | } 51 | } 52 | } 53 | 54 | func printTypes(md toml.MetaData) { 55 | tabw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) 56 | for _, key := range md.Keys() { 57 | fmt.Fprintf(tabw, "%s%s\t%s\n", 58 | strings.Repeat(" ", len(key)-1), key, md.Type(key...)) 59 | } 60 | tabw.Flush() 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/httputil/cookie_test.go: -------------------------------------------------------------------------------- 1 | package httputil 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestDeleteCookies(t *testing.T) { 11 | tests := []struct { 12 | // cookie names to delete 13 | n []string 14 | }{ 15 | // single 16 | { 17 | n: []string{"foo"}, 18 | }, 19 | // multiple 20 | { 21 | n: []string{"foo", "bar"}, 22 | }, 23 | } 24 | 25 | for i, tt := range tests { 26 | w := httptest.NewRecorder() 27 | DeleteCookies(w, tt.n...) 28 | resp := &http.Response{} 29 | resp.Header = w.Header() 30 | cks := resp.Cookies() 31 | 32 | if len(cks) != len(tt.n) { 33 | t.Errorf("case %d: unexpected number of cookies, want: %d, got: %d", i, len(tt.n), len(cks)) 34 | } 35 | 36 | for _, c := range cks { 37 | if c.Value != "" { 38 | t.Errorf("case %d: unexpected cookie value, want: %q, got: %q", i, "", c.Value) 39 | } 40 | if c.Path != "/" { 41 | t.Errorf("case %d: unexpected cookie path, want: %q, got: %q", i, "/", c.Path) 42 | } 43 | if c.MaxAge != -1 { 44 | t.Errorf("case %d: unexpected cookie max-age, want: %q, got: %q", i, -1, c.MaxAge) 45 | } 46 | if !c.Expires.IsZero() { 47 | t.Errorf("case %d: unexpected cookie expires, want: %q, got: %q", i, time.Time{}, c.MaxAge) 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oidc/key.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "net/http" 7 | "time" 8 | 9 | phttp "github.com/coreos/go-oidc/http" 10 | "github.com/coreos/go-oidc/jose" 11 | "github.com/coreos/go-oidc/key" 12 | ) 13 | 14 | func NewRemotePublicKeyRepo(hc phttp.Client, ep string) *remotePublicKeyRepo { 15 | return &remotePublicKeyRepo{hc: hc, ep: ep} 16 | } 17 | 18 | type remotePublicKeyRepo struct { 19 | hc phttp.Client 20 | ep string 21 | } 22 | 23 | func (r *remotePublicKeyRepo) Get() (key.KeySet, error) { 24 | req, err := http.NewRequest("GET", r.ep, nil) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | resp, err := r.hc.Do(req) 30 | if err != nil { 31 | return nil, err 32 | } 33 | defer resp.Body.Close() 34 | 35 | var d struct { 36 | Keys []jose.JWK `json:"keys"` 37 | } 38 | if err := json.NewDecoder(resp.Body).Decode(&d); err != nil { 39 | return nil, err 40 | } 41 | 42 | if len(d.Keys) == 0 { 43 | return nil, errors.New("zero keys in response") 44 | } 45 | 46 | ttl, ok, err := phttp.Cacheable(resp.Header) 47 | if err != nil { 48 | return nil, err 49 | } 50 | if !ok { 51 | return nil, errors.New("HTTP cache headers not set") 52 | } 53 | 54 | exp := time.Now().UTC().Add(ttl) 55 | ks := key.NewPublicKeySet(d.Keys, exp) 56 | return ks, nil 57 | } 58 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jws.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type JWS struct { 9 | RawHeader string 10 | Header JOSEHeader 11 | RawPayload string 12 | Payload []byte 13 | Signature []byte 14 | } 15 | 16 | // Given a raw encoded JWS token parses it and verifies the structure. 17 | func ParseJWS(raw string) (JWS, error) { 18 | parts := strings.Split(raw, ".") 19 | if len(parts) != 3 { 20 | return JWS{}, fmt.Errorf("malformed JWS, only %d segments", len(parts)) 21 | } 22 | 23 | rawSig := parts[2] 24 | jws := JWS{ 25 | RawHeader: parts[0], 26 | RawPayload: parts[1], 27 | } 28 | 29 | header, err := decodeHeader(jws.RawHeader) 30 | if err != nil { 31 | return JWS{}, fmt.Errorf("malformed JWS, unable to decode header, %s", err) 32 | } 33 | if err = header.Validate(); err != nil { 34 | return JWS{}, fmt.Errorf("malformed JWS, %s", err) 35 | } 36 | jws.Header = header 37 | 38 | payload, err := decodeSegment(jws.RawPayload) 39 | if err != nil { 40 | return JWS{}, fmt.Errorf("malformed JWS, unable to decode payload: %s", err) 41 | } 42 | jws.Payload = payload 43 | 44 | sig, err := decodeSegment(rawSig) 45 | if err != nil { 46 | return JWS{}, fmt.Errorf("malformed JWS, unable to decode signature: %s", err) 47 | } 48 | jws.Signature = sig 49 | 50 | return jws, nil 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/sdk_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import "testing" 8 | 9 | func TestSDKConfig(t *testing.T) { 10 | sdkConfigPath = func() (string, error) { 11 | return "testdata/gcloud", nil 12 | } 13 | 14 | tests := []struct { 15 | account string 16 | accessToken string 17 | err bool 18 | }{ 19 | {"", "bar_access_token", false}, 20 | {"foo@example.com", "foo_access_token", false}, 21 | {"bar@example.com", "bar_access_token", false}, 22 | {"baz@serviceaccount.example.com", "", true}, 23 | } 24 | for _, tt := range tests { 25 | c, err := NewSDKConfig(tt.account) 26 | if got, want := err != nil, tt.err; got != want { 27 | if !tt.err { 28 | t.Errorf("expected no error, got error: %v", tt.err, err) 29 | } else { 30 | t.Errorf("expected error, got none") 31 | } 32 | continue 33 | } 34 | if err != nil { 35 | continue 36 | } 37 | tok := c.initialToken 38 | if tok == nil { 39 | t.Errorf("expected token %q, got: nil", tt.accessToken) 40 | continue 41 | } 42 | if tok.AccessToken != tt.accessToken { 43 | t.Errorf("expected token %q, got: %q", tt.accessToken, tok.AccessToken) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jwk_test.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestDecodeBase64URLPaddingOptional(t *testing.T) { 8 | tests := []struct { 9 | encoded string 10 | decoded string 11 | err bool 12 | }{ 13 | { 14 | // With padding 15 | encoded: "VGVjdG9uaWM=", 16 | decoded: "Tectonic", 17 | }, 18 | { 19 | // Without padding 20 | encoded: "VGVjdG9uaWM", 21 | decoded: "Tectonic", 22 | }, 23 | { 24 | // Even More padding 25 | encoded: "VGVjdG9uaQ==", 26 | decoded: "Tectoni", 27 | }, 28 | { 29 | // And take it away! 30 | encoded: "VGVjdG9uaQ", 31 | decoded: "Tectoni", 32 | }, 33 | { 34 | // Too much padding. 35 | encoded: "VGVjdG9uaWNh=", 36 | decoded: "", 37 | err: true, 38 | }, 39 | { 40 | // Too much padding. 41 | encoded: "VGVjdG9uaWNh=", 42 | decoded: "", 43 | err: true, 44 | }, 45 | } 46 | 47 | for i, tt := range tests { 48 | got, err := decodeBase64URLPaddingOptional(tt.encoded) 49 | if tt.err { 50 | if err == nil { 51 | t.Errorf("case %d: expected non-nil err", i) 52 | } 53 | continue 54 | } 55 | 56 | if err != nil { 57 | t.Errorf("case %d: want nil err, got: %v", i, err) 58 | } 59 | 60 | if string(got) != tt.decoded { 61 | t.Errorf("case %d: want=%q, got=%q", i, tt.decoded, got) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /validator_watcher_copy_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.3,!plan9,!solaris,!windows 2 | 3 | // Turns out you can't copy over an existing file on Windows. 4 | 5 | package main 6 | 7 | import ( 8 | "io/ioutil" 9 | "os" 10 | "testing" 11 | ) 12 | 13 | func (vt *ValidatorTest) UpdateEmailFileViaCopyingOver( 14 | t *testing.T, emails []string) { 15 | orig_file := vt.auth_email_file 16 | var err error 17 | vt.auth_email_file, err = ioutil.TempFile("", "test_auth_emails_") 18 | if err != nil { 19 | t.Fatal("failed to create temp file for copy: " + err.Error()) 20 | } 21 | vt.WriteEmails(t, emails) 22 | err = os.Rename(vt.auth_email_file.Name(), orig_file.Name()) 23 | if err != nil { 24 | t.Fatal("failed to copy over temp file: " + err.Error()) 25 | } 26 | vt.auth_email_file = orig_file 27 | } 28 | 29 | func TestValidatorOverwriteEmailListViaCopyingOver(t *testing.T) { 30 | vt := NewValidatorTest(t) 31 | defer vt.TearDown() 32 | 33 | vt.WriteEmails(t, []string{"xyzzy@example.com"}) 34 | domains := []string(nil) 35 | updated := make(chan bool) 36 | validator := vt.NewValidator(domains, updated) 37 | 38 | if !validator("xyzzy@example.com") { 39 | t.Error("email in list should validate") 40 | } 41 | 42 | vt.UpdateEmailFileViaCopyingOver(t, []string{"plugh@example.com"}) 43 | <-updated 44 | 45 | if validator("xyzzy@example.com") { 46 | t.Error("email removed from list should not validate") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/httputil/json_test.go: -------------------------------------------------------------------------------- 1 | package httputil 2 | 3 | import ( 4 | "net/http/httptest" 5 | "testing" 6 | ) 7 | 8 | func TestWriteJSONResponse(t *testing.T) { 9 | for i, test := range []struct { 10 | code int 11 | resp interface{} 12 | expectedJSON string 13 | expectErr bool 14 | }{ 15 | { 16 | 200, 17 | struct { 18 | A string 19 | B string 20 | }{A: "foo", B: "bar"}, 21 | `{"A":"foo","B":"bar"}`, 22 | false, 23 | }, 24 | { 25 | 500, 26 | // Something that json.Marshal cannot serialize. 27 | make(chan int), 28 | "", 29 | true, 30 | }, 31 | } { 32 | w := httptest.NewRecorder() 33 | err := WriteJSONResponse(w, test.code, test.resp) 34 | 35 | if w.Code != test.code { 36 | t.Errorf("case %d: w.code == %v, want %v", i, w.Code, test.code) 37 | } 38 | 39 | if (err != nil) != test.expectErr { 40 | t.Errorf("case %d: (err != nil) == %v, want %v. err: %v", i, err != nil, test.expectErr, err) 41 | } 42 | 43 | if string(w.Body.Bytes()) != test.expectedJSON { 44 | t.Errorf("case %d: w.Body.Bytes()) == %q, want %q", i, 45 | string(w.Body.Bytes()), test.expectedJSON) 46 | } 47 | 48 | if !test.expectErr { 49 | contentType := w.Header()["Content-Type"][0] 50 | if contentType != JSONContentType { 51 | t.Errorf("case %d: contentType == %v, want %v", i, contentType, JSONContentType) 52 | } 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2_test 6 | 7 | import ( 8 | "fmt" 9 | "log" 10 | 11 | "golang.org/x/oauth2" 12 | ) 13 | 14 | func ExampleConfig() { 15 | conf := &oauth2.Config{ 16 | ClientID: "YOUR_CLIENT_ID", 17 | ClientSecret: "YOUR_CLIENT_SECRET", 18 | Scopes: []string{"SCOPE1", "SCOPE2"}, 19 | Endpoint: oauth2.Endpoint{ 20 | AuthURL: "https://provider.com/o/oauth2/auth", 21 | TokenURL: "https://provider.com/o/oauth2/token", 22 | }, 23 | } 24 | 25 | // Redirect user to consent page to ask for permission 26 | // for the scopes specified above. 27 | url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) 28 | fmt.Printf("Visit the URL for the auth dialog: %v", url) 29 | 30 | // Use the authorization code that is pushed to the redirect URL. 31 | // NewTransportWithCode will do the handshake to retrieve 32 | // an access token and initiate a Transport that is 33 | // authorized and authenticated by the retrieved token. 34 | var code string 35 | if _, err := fmt.Scan(&code); err != nil { 36 | log.Fatal(err) 37 | } 38 | tok, err := conf.Exchange(oauth2.NoContext, code) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | client := conf.Client(oauth2.NoContext, tok) 44 | client.Get("...") 45 | } 46 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/token_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func TestTokenExtra(t *testing.T) { 13 | type testCase struct { 14 | key string 15 | val interface{} 16 | want interface{} 17 | } 18 | const key = "extra-key" 19 | cases := []testCase{ 20 | {key: key, val: "abc", want: "abc"}, 21 | {key: key, val: 123, want: 123}, 22 | {key: key, val: "", want: ""}, 23 | {key: "other-key", val: "def", want: nil}, 24 | } 25 | for _, tc := range cases { 26 | extra := make(map[string]interface{}) 27 | extra[tc.key] = tc.val 28 | tok := &Token{raw: extra} 29 | if got, want := tok.Extra(key), tc.want; got != want { 30 | t.Errorf("Extra(%q) = %q; want %q", key, got, want) 31 | } 32 | } 33 | } 34 | 35 | func TestTokenExpiry(t *testing.T) { 36 | now := time.Now() 37 | cases := []struct { 38 | name string 39 | tok *Token 40 | want bool 41 | }{ 42 | {name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false}, 43 | {name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true}, 44 | } 45 | for _, tc := range cases { 46 | if got, want := tc.tok.expired(), tc.want; got != want { 47 | t.Errorf("expired (%q) = %v; want %v", tc.name, got, want) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /providers/gitlab.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "net/url" 7 | 8 | "github.com/bitly/oauth2_proxy/api" 9 | ) 10 | 11 | type GitLabProvider struct { 12 | *ProviderData 13 | } 14 | 15 | func NewGitLabProvider(p *ProviderData) *GitLabProvider { 16 | p.ProviderName = "GitLab" 17 | if p.LoginURL == nil || p.LoginURL.String() == "" { 18 | p.LoginURL = &url.URL{ 19 | Scheme: "https", 20 | Host: "gitlab.com", 21 | Path: "/oauth/authorize", 22 | } 23 | } 24 | if p.RedeemURL == nil || p.RedeemURL.String() == "" { 25 | p.RedeemURL = &url.URL{ 26 | Scheme: "https", 27 | Host: "gitlab.com", 28 | Path: "/oauth/token", 29 | } 30 | } 31 | if p.ValidateURL == nil || p.ValidateURL.String() == "" { 32 | p.ValidateURL = &url.URL{ 33 | Scheme: "https", 34 | Host: "gitlab.com", 35 | Path: "/api/v3/user", 36 | } 37 | } 38 | if p.Scope == "" { 39 | p.Scope = "api" 40 | } 41 | return &GitLabProvider{ProviderData: p} 42 | } 43 | 44 | func (p *GitLabProvider) GetEmailAddress(s *SessionState) (string, error) { 45 | 46 | req, err := http.NewRequest("GET", 47 | p.ValidateURL.String()+"?access_token="+s.AccessToken, nil) 48 | if err != nil { 49 | log.Printf("failed building request %s", err) 50 | return "", err 51 | } 52 | json, err := api.Request(req) 53 | if err != nil { 54 | log.Printf("failed making request %s", err) 55 | return "", err 56 | } 57 | return json.Get("email").String() 58 | } 59 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jose.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "encoding/base64" 5 | "encoding/json" 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | const ( 11 | HeaderMediaType = "typ" 12 | HeaderKeyAlgorithm = "alg" 13 | HeaderKeyID = "kid" 14 | ) 15 | 16 | type JOSEHeader map[string]string 17 | 18 | func (j JOSEHeader) Validate() error { 19 | if _, exists := j[HeaderKeyAlgorithm]; !exists { 20 | return fmt.Errorf("header missing %q parameter", HeaderKeyAlgorithm) 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func decodeHeader(seg string) (JOSEHeader, error) { 27 | b, err := decodeSegment(seg) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | var h JOSEHeader 33 | err = json.Unmarshal(b, &h) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | return h, nil 39 | } 40 | 41 | func encodeHeader(h JOSEHeader) (string, error) { 42 | b, err := json.Marshal(h) 43 | if err != nil { 44 | return "", err 45 | } 46 | 47 | return encodeSegment(b), nil 48 | } 49 | 50 | // Decode JWT specific base64url encoding with padding stripped 51 | func decodeSegment(seg string) ([]byte, error) { 52 | if l := len(seg) % 4; l != 0 { 53 | seg += strings.Repeat("=", 4-l) 54 | } 55 | return base64.URLEncoding.DecodeString(seg) 56 | } 57 | 58 | // Encode JWT specific base64url encoding with padding stripped 59 | func encodeSegment(seg []byte) string { 60 | return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/wrap_test.go: -------------------------------------------------------------------------------- 1 | package text 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | var text = "The quick brown fox jumps over the lazy dog." 9 | 10 | func TestWrap(t *testing.T) { 11 | exp := [][]string{ 12 | {"The", "quick", "brown", "fox"}, 13 | {"jumps", "over", "the", "lazy", "dog."}, 14 | } 15 | words := bytes.Split([]byte(text), sp) 16 | got := WrapWords(words, 1, 24, defaultPenalty) 17 | if len(exp) != len(got) { 18 | t.Fail() 19 | } 20 | for i := range exp { 21 | if len(exp[i]) != len(got[i]) { 22 | t.Fail() 23 | } 24 | for j := range exp[i] { 25 | if exp[i][j] != string(got[i][j]) { 26 | t.Fatal(i, exp[i][j], got[i][j]) 27 | } 28 | } 29 | } 30 | } 31 | 32 | func TestWrapNarrow(t *testing.T) { 33 | exp := "The\nquick\nbrown\nfox\njumps\nover\nthe\nlazy\ndog." 34 | if Wrap(text, 5) != exp { 35 | t.Fail() 36 | } 37 | } 38 | 39 | func TestWrapOneLine(t *testing.T) { 40 | exp := "The quick brown fox jumps over the lazy dog." 41 | if Wrap(text, 500) != exp { 42 | t.Fail() 43 | } 44 | } 45 | 46 | func TestWrapBug1(t *testing.T) { 47 | cases := []struct { 48 | limit int 49 | text string 50 | want string 51 | }{ 52 | {4, "aaaaa", "aaaaa"}, 53 | {4, "a aaaaa", "a\naaaaa"}, 54 | } 55 | 56 | for _, test := range cases { 57 | got := Wrap(test.text, test.limit) 58 | if got != test.want { 59 | t.Errorf("Wrap(%q, %d) = %q want %q", test.text, test.limit, got, test.want) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /htpasswd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/base64" 6 | "encoding/csv" 7 | "io" 8 | "log" 9 | "os" 10 | ) 11 | 12 | // lookup passwords in a htpasswd file 13 | // The entries must have been created with -s for SHA encryption 14 | 15 | type HtpasswdFile struct { 16 | Users map[string]string 17 | } 18 | 19 | func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) { 20 | r, err := os.Open(path) 21 | if err != nil { 22 | return nil, err 23 | } 24 | defer r.Close() 25 | return NewHtpasswd(r) 26 | } 27 | 28 | func NewHtpasswd(file io.Reader) (*HtpasswdFile, error) { 29 | csv_reader := csv.NewReader(file) 30 | csv_reader.Comma = ':' 31 | csv_reader.Comment = '#' 32 | csv_reader.TrimLeadingSpace = true 33 | 34 | records, err := csv_reader.ReadAll() 35 | if err != nil { 36 | return nil, err 37 | } 38 | h := &HtpasswdFile{Users: make(map[string]string)} 39 | for _, record := range records { 40 | h.Users[record[0]] = record[1] 41 | } 42 | return h, nil 43 | } 44 | 45 | func (h *HtpasswdFile) Validate(user string, password string) bool { 46 | realPassword, exists := h.Users[user] 47 | if !exists { 48 | return false 49 | } 50 | if realPassword[:5] == "{SHA}" { 51 | d := sha1.New() 52 | d.Write([]byte(password)) 53 | if realPassword[5:] == base64.StdEncoding.EncodeToString(d.Sum(nil)) { 54 | return true 55 | } 56 | } else { 57 | log.Printf("Invalid htpasswd entry for %s. Must be a SHA entry.", user) 58 | } 59 | return false 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/sig_hmac.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "bytes" 5 | "crypto" 6 | "crypto/hmac" 7 | _ "crypto/sha256" 8 | "errors" 9 | "fmt" 10 | "strings" 11 | ) 12 | 13 | type VerifierHMAC struct { 14 | KeyID string 15 | Hash crypto.Hash 16 | Secret []byte 17 | } 18 | 19 | type SignerHMAC struct { 20 | VerifierHMAC 21 | } 22 | 23 | func NewVerifierHMAC(jwk JWK) (*VerifierHMAC, error) { 24 | if strings.ToUpper(jwk.Alg) != "HS256" { 25 | return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg) 26 | } 27 | 28 | v := VerifierHMAC{ 29 | KeyID: jwk.ID, 30 | Secret: jwk.Secret, 31 | Hash: crypto.SHA256, 32 | } 33 | 34 | return &v, nil 35 | } 36 | 37 | func (v *VerifierHMAC) ID() string { 38 | return v.KeyID 39 | } 40 | 41 | func (v *VerifierHMAC) Alg() string { 42 | return "HS256" 43 | } 44 | 45 | func (v *VerifierHMAC) Verify(sig []byte, data []byte) error { 46 | h := hmac.New(v.Hash.New, v.Secret) 47 | h.Write(data) 48 | if !bytes.Equal(sig, h.Sum(nil)) { 49 | return errors.New("invalid hmac signature") 50 | } 51 | return nil 52 | } 53 | 54 | func NewSignerHMAC(kid string, secret []byte) *SignerHMAC { 55 | return &SignerHMAC{ 56 | VerifierHMAC: VerifierHMAC{ 57 | KeyID: kid, 58 | Secret: secret, 59 | Hash: crypto.SHA256, 60 | }, 61 | } 62 | } 63 | 64 | func (s *SignerHMAC) Sign(data []byte) ([]byte, error) { 65 | h := hmac.New(s.Hash.New, s.Secret) 66 | h.Write(data) 67 | return h.Sum(nil), nil 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/18F/hmacauth/README.md: -------------------------------------------------------------------------------- 1 | # hmacauth HMAC authentication package for Go 2 | 3 | [![Build Status](https://travis-ci.org/18F/hmacauth.svg?branch=master)](https://travis-ci.org/18F/hmacauth) 4 | 5 | [![Coverage Status](https://coveralls.io/repos/18F/hmacauth/badge.svg?branch=master&service=github)](https://coveralls.io/github/18F/hmacauth?branch=master) 6 | 7 | Signs and authenticates HTTP requests based on a shared-secret HMAC signature. 8 | 9 | Developed in parallel with the following packages for other languages: 10 | - Node.js: [hmac-authentication](https://www.npmjs.com/package/hmac-authentication) 11 | - Ruby: [hmac_authentication](https://rubygems.org/gems/hmac_authentication) 12 | 13 | ## Installation 14 | 15 | ```go 16 | import "github.com/18F/hmacauth" 17 | ``` 18 | 19 | ## Validating incoming requests 20 | 21 | Coming soon... 22 | 23 | ## Signing outgoing requests 24 | 25 | Coming soon... 26 | 27 | ## Public domain 28 | 29 | This project is in the worldwide [public domain](LICENSE.md). As stated in [CONTRIBUTING](CONTRIBUTING.md): 30 | 31 | > This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). 32 | > 33 | > All contributions to this project will be released under the CC0 34 | >dedication. By submitting a pull request, you are agreeing to comply 35 | >with this waiver of copyright interest. 36 | -------------------------------------------------------------------------------- /providers/myusa.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "net/url" 7 | 8 | "github.com/bitly/oauth2_proxy/api" 9 | ) 10 | 11 | type MyUsaProvider struct { 12 | *ProviderData 13 | } 14 | 15 | func NewMyUsaProvider(p *ProviderData) *MyUsaProvider { 16 | const myUsaHost string = "alpha.my.usa.gov" 17 | 18 | p.ProviderName = "MyUSA" 19 | if p.LoginURL.String() == "" { 20 | p.LoginURL = &url.URL{Scheme: "https", 21 | Host: myUsaHost, 22 | Path: "/oauth/authorize"} 23 | } 24 | if p.RedeemURL.String() == "" { 25 | p.RedeemURL = &url.URL{Scheme: "https", 26 | Host: myUsaHost, 27 | Path: "/oauth/token"} 28 | } 29 | if p.ProfileURL.String() == "" { 30 | p.ProfileURL = &url.URL{Scheme: "https", 31 | Host: myUsaHost, 32 | Path: "/api/v1/profile"} 33 | } 34 | if p.ValidateURL.String() == "" { 35 | p.ValidateURL = &url.URL{Scheme: "https", 36 | Host: myUsaHost, 37 | Path: "/api/v1/tokeninfo"} 38 | } 39 | if p.Scope == "" { 40 | p.Scope = "profile.email" 41 | } 42 | return &MyUsaProvider{ProviderData: p} 43 | } 44 | 45 | func (p *MyUsaProvider) GetEmailAddress(s *SessionState) (string, error) { 46 | req, err := http.NewRequest("GET", 47 | p.ProfileURL.String()+"?access_token="+s.AccessToken, nil) 48 | if err != nil { 49 | log.Printf("failed building request %s", err) 50 | return "", err 51 | } 52 | json, err := api.Request(req) 53 | if err != nil { 54 | log.Printf("failed making request %s", err) 55 | return "", err 56 | } 57 | return json.Get("email").String() 58 | } 59 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/internal/oauth2_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "reflect" 10 | "strings" 11 | "testing" 12 | ) 13 | 14 | func TestParseINI(t *testing.T) { 15 | tests := []struct { 16 | ini string 17 | want map[string]map[string]string 18 | }{ 19 | { 20 | `root = toor 21 | [foo] 22 | bar = hop 23 | ini = nin 24 | `, 25 | map[string]map[string]string{ 26 | "": map[string]string{"root": "toor"}, 27 | "foo": map[string]string{"bar": "hop", "ini": "nin"}, 28 | }, 29 | }, 30 | { 31 | `[empty] 32 | [section] 33 | empty= 34 | `, 35 | map[string]map[string]string{ 36 | "": map[string]string{}, 37 | "empty": map[string]string{}, 38 | "section": map[string]string{"empty": ""}, 39 | }, 40 | }, 41 | { 42 | `ignore 43 | [invalid 44 | =stuff 45 | ;comment=true 46 | `, 47 | map[string]map[string]string{ 48 | "": map[string]string{}, 49 | }, 50 | }, 51 | } 52 | for _, tt := range tests { 53 | result, err := ParseINI(strings.NewReader(tt.ini)) 54 | if err != nil { 55 | t.Errorf("ParseINI(%q) error %v, want: no error", tt.ini, err) 56 | continue 57 | } 58 | if !reflect.DeepEqual(result, tt.want) { 59 | t.Errorf("ParseINI(%q) = %#v, want: %#v", tt.ini, result, tt.want) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/mc/mc.go: -------------------------------------------------------------------------------- 1 | // Command mc prints in multiple columns. 2 | // 3 | // Usage: mc [-] [-N] [file...] 4 | // 5 | // Mc splits the input into as many columns as will fit in N 6 | // print positions. If the output is a tty, the default N is 7 | // the number of characters in a terminal line; otherwise the 8 | // default N is 80. Under option - each input line ending in 9 | // a colon ':' is printed separately. 10 | package main 11 | 12 | import ( 13 | "github.com/kr/pty" 14 | "github.com/kr/text/colwriter" 15 | "io" 16 | "log" 17 | "os" 18 | "strconv" 19 | ) 20 | 21 | func main() { 22 | var width int 23 | var flag uint 24 | args := os.Args[1:] 25 | for len(args) > 0 && len(args[0]) > 0 && args[0][0] == '-' { 26 | if len(args[0]) > 1 { 27 | width, _ = strconv.Atoi(args[0][1:]) 28 | } else { 29 | flag |= colwriter.BreakOnColon 30 | } 31 | args = args[1:] 32 | } 33 | if width < 1 { 34 | _, width, _ = pty.Getsize(os.Stdout) 35 | } 36 | if width < 1 { 37 | width = 80 38 | } 39 | 40 | w := colwriter.NewWriter(os.Stdout, width, flag) 41 | if len(args) > 0 { 42 | for _, s := range args { 43 | if f, err := os.Open(s); err == nil { 44 | copyin(w, f) 45 | f.Close() 46 | } else { 47 | log.Println(err) 48 | } 49 | } 50 | } else { 51 | copyin(w, os.Stdin) 52 | } 53 | } 54 | 55 | func copyin(w *colwriter.Writer, r io.Reader) { 56 | if _, err := io.Copy(w, r); err != nil { 57 | log.Println(err) 58 | } 59 | if err := w.Flush(); err != nil { 60 | log.Println(err) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/key/key_test.go: -------------------------------------------------------------------------------- 1 | package key 2 | 3 | import ( 4 | "crypto/rsa" 5 | "math/big" 6 | "reflect" 7 | "testing" 8 | "time" 9 | 10 | "github.com/coreos/go-oidc/jose" 11 | ) 12 | 13 | func TestPrivateRSAKeyJWK(t *testing.T) { 14 | n := big.NewInt(int64(17)) 15 | if n == nil { 16 | panic("NewInt returned nil") 17 | } 18 | 19 | k := &PrivateKey{ 20 | KeyID: "foo", 21 | PrivateKey: &rsa.PrivateKey{ 22 | PublicKey: rsa.PublicKey{N: n, E: 65537}, 23 | }, 24 | } 25 | 26 | want := jose.JWK{ 27 | ID: "foo", 28 | Type: "RSA", 29 | Alg: "RS256", 30 | Use: "sig", 31 | Modulus: n, 32 | Exponent: 65537, 33 | } 34 | 35 | got := k.JWK() 36 | if !reflect.DeepEqual(want, got) { 37 | t.Fatalf("JWK mismatch: want=%#v got=%#v", want, got) 38 | } 39 | } 40 | 41 | func TestPublicKeySetKey(t *testing.T) { 42 | n := big.NewInt(int64(17)) 43 | if n == nil { 44 | panic("NewInt returned nil") 45 | } 46 | 47 | k := jose.JWK{ 48 | ID: "foo", 49 | Type: "RSA", 50 | Alg: "RS256", 51 | Use: "sig", 52 | Modulus: n, 53 | Exponent: 65537, 54 | } 55 | now := time.Now().UTC() 56 | ks := NewPublicKeySet([]jose.JWK{k}, now) 57 | 58 | want := &PublicKey{jwk: k} 59 | got := ks.Key("foo") 60 | if !reflect.DeepEqual(want, got) { 61 | t.Errorf("Unexpected response from PublicKeySet.Key: want=%#v got=%#v", want, got) 62 | } 63 | 64 | got = ks.Key("bar") 65 | if got != nil { 66 | t.Errorf("Expected nil response from PublicKeySet.Key, got %#v", got) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/sig_rsa.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "crypto" 5 | "crypto/rand" 6 | "crypto/rsa" 7 | "fmt" 8 | "strings" 9 | ) 10 | 11 | type VerifierRSA struct { 12 | KeyID string 13 | Hash crypto.Hash 14 | PublicKey rsa.PublicKey 15 | } 16 | 17 | type SignerRSA struct { 18 | PrivateKey rsa.PrivateKey 19 | VerifierRSA 20 | } 21 | 22 | func NewVerifierRSA(jwk JWK) (*VerifierRSA, error) { 23 | if strings.ToUpper(jwk.Alg) != "RS256" { 24 | return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg) 25 | } 26 | 27 | v := VerifierRSA{ 28 | KeyID: jwk.ID, 29 | PublicKey: rsa.PublicKey{ 30 | N: jwk.Modulus, 31 | E: jwk.Exponent, 32 | }, 33 | Hash: crypto.SHA256, 34 | } 35 | 36 | return &v, nil 37 | } 38 | 39 | func NewSignerRSA(kid string, key rsa.PrivateKey) *SignerRSA { 40 | return &SignerRSA{ 41 | PrivateKey: key, 42 | VerifierRSA: VerifierRSA{ 43 | KeyID: kid, 44 | PublicKey: key.PublicKey, 45 | Hash: crypto.SHA256, 46 | }, 47 | } 48 | } 49 | 50 | func (v *VerifierRSA) ID() string { 51 | return v.KeyID 52 | } 53 | 54 | func (v *VerifierRSA) Alg() string { 55 | return "RS256" 56 | } 57 | 58 | func (v *VerifierRSA) Verify(sig []byte, data []byte) error { 59 | h := v.Hash.New() 60 | h.Write(data) 61 | return rsa.VerifyPKCS1v15(&v.PublicKey, v.Hash, h.Sum(nil), sig) 62 | } 63 | 64 | func (s *SignerRSA) Sign(data []byte) ([]byte, error) { 65 | h := s.Hash.New() 66 | h.Write(data) 67 | return rsa.SignPKCS1v15(rand.Reader, &s.PrivateKey, s.Hash, h.Sum(nil)) 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The oauth2 Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | 10 | "github.com/bitly/go-simplejson" 11 | ) 12 | 13 | func Request(req *http.Request) (*simplejson.Json, error) { 14 | resp, err := http.DefaultClient.Do(req) 15 | if err != nil { 16 | log.Printf("%s %s %s", req.Method, req.URL, err) 17 | return nil, err 18 | } 19 | body, err := ioutil.ReadAll(resp.Body) 20 | resp.Body.Close() 21 | log.Printf("%d %s %s %s", resp.StatusCode, req.Method, req.URL, body) 22 | if err != nil { 23 | return nil, err 24 | } 25 | if resp.StatusCode != 200 { 26 | return nil, fmt.Errorf("got %d %s", resp.StatusCode, body) 27 | } 28 | data, err := simplejson.NewJson(body) 29 | if err != nil { 30 | return nil, err 31 | } 32 | return data, nil 33 | } 34 | 35 | func RequestJson(req *http.Request, v interface{}) error { 36 | resp, err := http.DefaultClient.Do(req) 37 | if err != nil { 38 | log.Printf("%s %s %s", req.Method, req.URL, err) 39 | return err 40 | } 41 | body, err := ioutil.ReadAll(resp.Body) 42 | resp.Body.Close() 43 | log.Printf("%d %s %s %s", resp.StatusCode, req.Method, req.URL, body) 44 | if err != nil { 45 | return err 46 | } 47 | if resp.StatusCode != 200 { 48 | return fmt.Errorf("got %d %s", resp.StatusCode, body) 49 | } 50 | return json.Unmarshal(body, v) 51 | } 52 | 53 | func RequestUnparsedResponse(url string, header http.Header) (resp *http.Response, err error) { 54 | req, err := http.NewRequest("GET", url, nil) 55 | if err != nil { 56 | return nil, err 57 | } 58 | req.Header = header 59 | 60 | return http.DefaultClient.Do(req) 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jonboulle/clockwork/README.md: -------------------------------------------------------------------------------- 1 | clockwork 2 | ========= 3 | 4 | [![Build Status](https://travis-ci.org/jonboulle/clockwork.png?branch=master)](https://travis-ci.org/jonboulle/clockwork) 5 | [![godoc](https://godoc.org/github.com/jonboulle/clockwork?status.svg)](http://godoc.org/github.com/jonboulle/clockwork) 6 | 7 | a simple fake clock for golang 8 | 9 | # Usage 10 | 11 | Replace uses of the `time` package with the `clockwork.Clock` interface instead. 12 | 13 | For example, instead of using `time.Sleep` directly: 14 | 15 | ``` 16 | func my_func() { 17 | time.Sleep(3 * time.Second) 18 | do_something() 19 | } 20 | ``` 21 | 22 | inject a clock and use its `Sleep` method instead: 23 | 24 | ``` 25 | func my_func(clock clockwork.Clock) { 26 | clock.Sleep(3 * time.Second) 27 | do_something() 28 | } 29 | ``` 30 | 31 | Now you can easily test `my_func` with a `FakeClock`: 32 | 33 | ``` 34 | func TestMyFunc(t *testing.T) { 35 | c := clockwork.NewFakeClock() 36 | 37 | // Start our sleepy function 38 | my_func(c) 39 | 40 | // Ensure we wait until my_func is sleeping 41 | c.BlockUntil(1) 42 | 43 | assert_state() 44 | 45 | // Advance the FakeClock forward in time 46 | c.Advance(3) 47 | 48 | assert_state() 49 | } 50 | ``` 51 | 52 | and in production builds, simply inject the real clock instead: 53 | ``` 54 | my_func(clockwork.NewRealClock()) 55 | ``` 56 | 57 | See [example_test.go](example_test.go) for a full example. 58 | 59 | # Credits 60 | 61 | clockwork is inspired by @wickman's [threaded fake clock](https://gist.github.com/wickman/3840816), and the [Golang playground](http://blog.golang.org/playground#Faking time) 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. All rights reserved. 2 | Copyright (c) 2012 fsnotify Authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/init.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // +build !windows 16 | 17 | package capnslog 18 | 19 | import ( 20 | "io" 21 | "os" 22 | "syscall" 23 | ) 24 | 25 | // Here's where the opinionation comes in. We need some sensible defaults, 26 | // especially after taking over the log package. Your project (whatever it may 27 | // be) may see things differently. That's okay; there should be no defaults in 28 | // the main package that cannot be controlled or overridden programatically, 29 | // otherwise it's a bug. Doing so is creating your own init_log.go file much 30 | // like this one. 31 | 32 | func init() { 33 | initHijack() 34 | 35 | // Go `log` pacakge uses os.Stderr. 36 | SetFormatter(NewDefaultFormatter(os.Stderr)) 37 | SetGlobalLogLevel(INFO) 38 | } 39 | 40 | func NewDefaultFormatter(out io.Writer) Formatter { 41 | if syscall.Getppid() == 1 { 42 | // We're running under init, which may be systemd. 43 | f, err := NewJournaldFormatter() 44 | if err == nil { 45 | return f 46 | } 47 | } 48 | return NewPrettyFormatter(out, false) 49 | } 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/fsnotify.v1/fsnotify.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !plan9,!solaris 6 | 7 | // Package fsnotify provides a platform-independent interface for file system notifications. 8 | package fsnotify 9 | 10 | import ( 11 | "bytes" 12 | "fmt" 13 | ) 14 | 15 | // Event represents a single file system notification. 16 | type Event struct { 17 | Name string // Relative path to the file or directory. 18 | Op Op // File operation that triggered the event. 19 | } 20 | 21 | // Op describes a set of file operations. 22 | type Op uint32 23 | 24 | // These are the generalized file operations that can trigger a notification. 25 | const ( 26 | Create Op = 1 << iota 27 | Write 28 | Remove 29 | Rename 30 | Chmod 31 | ) 32 | 33 | // String returns a string representation of the event in the form 34 | // "file: REMOVE|WRITE|..." 35 | func (e Event) String() string { 36 | // Use a buffer for efficient string concatenation 37 | var buffer bytes.Buffer 38 | 39 | if e.Op&Create == Create { 40 | buffer.WriteString("|CREATE") 41 | } 42 | if e.Op&Remove == Remove { 43 | buffer.WriteString("|REMOVE") 44 | } 45 | if e.Op&Write == Write { 46 | buffer.WriteString("|WRITE") 47 | } 48 | if e.Op&Rename == Rename { 49 | buffer.WriteString("|RENAME") 50 | } 51 | if e.Op&Chmod == Chmod { 52 | buffer.WriteString("|CHMOD") 53 | } 54 | 55 | // If buffer remains empty, return no event names 56 | if buffer.Len() == 0 { 57 | return fmt.Sprintf("%q: ", e.Name) 58 | } 59 | 60 | // Return a list of event names, with leading pipe character stripped 61 | return fmt.Sprintf("%q: %s", e.Name, buffer.String()[1:]) 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jws_test.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | type testCase struct{ t string } 9 | 10 | var validInput []testCase 11 | 12 | var invalidInput []testCase 13 | 14 | func init() { 15 | validInput = []testCase{ 16 | { 17 | "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", 18 | }, 19 | } 20 | 21 | invalidInput = []testCase{ 22 | // empty 23 | { 24 | "", 25 | }, 26 | // undecodeable 27 | { 28 | "aaa.bbb.ccc", 29 | }, 30 | // missing parts 31 | { 32 | "aaa", 33 | }, 34 | // missing parts 35 | { 36 | "aaa.bbb", 37 | }, 38 | // too many parts 39 | { 40 | "aaa.bbb.ccc.ddd", 41 | }, 42 | // invalid header 43 | // EncodeHeader(map[string]string{"foo": "bar"}) 44 | { 45 | "eyJmb28iOiJiYXIifQ.bbb.ccc", 46 | }, 47 | } 48 | } 49 | 50 | func TestParseJWS(t *testing.T) { 51 | for i, tt := range validInput { 52 | jws, err := ParseJWS(tt.t) 53 | if err != nil { 54 | t.Errorf("test: %d. expected: valid, actual: invalid", i) 55 | } 56 | 57 | expectedHeader := strings.Split(tt.t, ".")[0] 58 | if jws.RawHeader != expectedHeader { 59 | t.Errorf("test: %d. expected: %s, actual: %s", i, expectedHeader, jws.RawHeader) 60 | } 61 | 62 | expectedPayload := strings.Split(tt.t, ".")[1] 63 | if jws.RawPayload != expectedPayload { 64 | t.Errorf("test: %d. expected: %s, actual: %s", i, expectedPayload, jws.RawPayload) 65 | } 66 | } 67 | 68 | for i, tt := range invalidInput { 69 | _, err := ParseJWS(tt.t) 70 | if err == nil { 71 | t.Errorf("test: %d. expected: invalid, actual: valid", i) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/syslog_formatter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // +build !windows 16 | 17 | package capnslog 18 | 19 | import ( 20 | "fmt" 21 | "log/syslog" 22 | ) 23 | 24 | func NewSyslogFormatter(w *syslog.Writer) Formatter { 25 | return &syslogFormatter{w} 26 | } 27 | 28 | func NewDefaultSyslogFormatter(tag string) (Formatter, error) { 29 | w, err := syslog.New(syslog.LOG_DEBUG, tag) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return NewSyslogFormatter(w), nil 34 | } 35 | 36 | type syslogFormatter struct { 37 | w *syslog.Writer 38 | } 39 | 40 | func (s *syslogFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) { 41 | for _, entry := range entries { 42 | str := fmt.Sprint(entry) 43 | switch l { 44 | case CRITICAL: 45 | s.w.Crit(str) 46 | case ERROR: 47 | s.w.Err(str) 48 | case WARNING: 49 | s.w.Warning(str) 50 | case NOTICE: 51 | s.w.Notice(str) 52 | case INFO: 53 | s.w.Info(str) 54 | case DEBUG: 55 | s.w.Debug(str) 56 | case TRACE: 57 | s.w.Debug(str) 58 | default: 59 | panic("Unhandled loglevel") 60 | } 61 | } 62 | } 63 | 64 | func (s *syslogFormatter) Flush() { 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jwt.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import "strings" 4 | 5 | type JWT JWS 6 | 7 | func ParseJWT(token string) (jwt JWT, err error) { 8 | jws, err := ParseJWS(token) 9 | if err != nil { 10 | return 11 | } 12 | 13 | return JWT(jws), nil 14 | } 15 | 16 | func NewJWT(header JOSEHeader, claims Claims) (jwt JWT, err error) { 17 | jwt = JWT{} 18 | 19 | jwt.Header = header 20 | jwt.Header[HeaderMediaType] = "JWT" 21 | 22 | claimBytes, err := marshalClaims(claims) 23 | if err != nil { 24 | return 25 | } 26 | jwt.Payload = claimBytes 27 | 28 | eh, err := encodeHeader(header) 29 | if err != nil { 30 | return 31 | } 32 | jwt.RawHeader = eh 33 | 34 | ec, err := encodeClaims(claims) 35 | if err != nil { 36 | return 37 | } 38 | jwt.RawPayload = ec 39 | 40 | return 41 | } 42 | 43 | func (j *JWT) KeyID() (string, bool) { 44 | kID, ok := j.Header[HeaderKeyID] 45 | return kID, ok 46 | } 47 | 48 | func (j *JWT) Claims() (Claims, error) { 49 | return decodeClaims(j.Payload) 50 | } 51 | 52 | // Encoded data part of the token which may be signed. 53 | func (j *JWT) Data() string { 54 | return strings.Join([]string{j.RawHeader, j.RawPayload}, ".") 55 | } 56 | 57 | // Full encoded JWT token string in format: header.claims.signature 58 | func (j *JWT) Encode() string { 59 | d := j.Data() 60 | s := encodeSegment(j.Signature) 61 | return strings.Join([]string{d, s}, ".") 62 | } 63 | 64 | func NewSignedJWT(claims Claims, s Signer) (*JWT, error) { 65 | header := JOSEHeader{ 66 | HeaderKeyAlgorithm: s.Alg(), 67 | HeaderKeyID: s.ID(), 68 | } 69 | 70 | jwt, err := NewJWT(header, claims) 71 | if err != nil { 72 | return nil, err 73 | } 74 | 75 | sig, err := s.Sign([]byte(jwt.Data())) 76 | if err != nil { 77 | return nil, err 78 | } 79 | jwt.Signature = sig 80 | 81 | return &jwt, nil 82 | } 83 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/indent.go: -------------------------------------------------------------------------------- 1 | package text 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | // Indent inserts prefix at the beginning of each non-empty line of s. The 8 | // end-of-line marker is NL. 9 | func Indent(s, prefix string) string { 10 | return string(IndentBytes([]byte(s), []byte(prefix))) 11 | } 12 | 13 | // IndentBytes inserts prefix at the beginning of each non-empty line of b. 14 | // The end-of-line marker is NL. 15 | func IndentBytes(b, prefix []byte) []byte { 16 | var res []byte 17 | bol := true 18 | for _, c := range b { 19 | if bol && c != '\n' { 20 | res = append(res, prefix...) 21 | } 22 | res = append(res, c) 23 | bol = c == '\n' 24 | } 25 | return res 26 | } 27 | 28 | // Writer indents each line of its input. 29 | type indentWriter struct { 30 | w io.Writer 31 | bol bool 32 | pre [][]byte 33 | sel int 34 | off int 35 | } 36 | 37 | // NewIndentWriter makes a new write filter that indents the input 38 | // lines. Each line is prefixed in order with the corresponding 39 | // element of pre. If there are more lines than elements, the last 40 | // element of pre is repeated for each subsequent line. 41 | func NewIndentWriter(w io.Writer, pre ...[]byte) io.Writer { 42 | return &indentWriter{ 43 | w: w, 44 | pre: pre, 45 | bol: true, 46 | } 47 | } 48 | 49 | // The only errors returned are from the underlying indentWriter. 50 | func (w *indentWriter) Write(p []byte) (n int, err error) { 51 | for _, c := range p { 52 | if w.bol { 53 | var i int 54 | i, err = w.w.Write(w.pre[w.sel][w.off:]) 55 | w.off += i 56 | if err != nil { 57 | return n, err 58 | } 59 | } 60 | _, err = w.w.Write([]byte{c}) 61 | if err != nil { 62 | return n, err 63 | } 64 | n++ 65 | w.bol = c == '\n' 66 | if w.bol { 67 | w.off = 0 68 | if w.sel < len(w.pre)-1 { 69 | w.sel++ 70 | } 71 | } 72 | } 73 | return n, nil 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/pretty/diff_test.go: -------------------------------------------------------------------------------- 1 | package pretty 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | type difftest struct { 8 | a interface{} 9 | b interface{} 10 | exp []string 11 | } 12 | 13 | type S struct { 14 | A int 15 | S *S 16 | I interface{} 17 | C []int 18 | } 19 | 20 | var diffs = []difftest{ 21 | {a: nil, b: nil}, 22 | {a: S{A: 1}, b: S{A: 1}}, 23 | 24 | {0, "", []string{`int != string`}}, 25 | {0, 1, []string{`0 != 1`}}, 26 | {S{}, new(S), []string{`pretty.S != *pretty.S`}}, 27 | {"a", "b", []string{`"a" != "b"`}}, 28 | {S{}, S{A: 1}, []string{`A: 0 != 1`}}, 29 | {new(S), &S{A: 1}, []string{`A: 0 != 1`}}, 30 | {S{S: new(S)}, S{S: &S{A: 1}}, []string{`S.A: 0 != 1`}}, 31 | {S{}, S{I: 0}, []string{`I: nil != 0`}}, 32 | {S{I: 1}, S{I: "x"}, []string{`I: int != string`}}, 33 | {S{}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, 34 | {S{C: []int{}}, S{C: []int{1}}, []string{`C: []int[0] != []int[1]`}}, 35 | {S{C: []int{1, 2, 3}}, S{C: []int{1, 2, 4}}, []string{`C[2]: 3 != 4`}}, 36 | {S{}, S{A: 1, S: new(S)}, []string{`A: 0 != 1`, `S: nil != &{0 []}`}}, 37 | } 38 | 39 | func TestDiff(t *testing.T) { 40 | for _, tt := range diffs { 41 | got := Diff(tt.a, tt.b) 42 | eq := len(got) == len(tt.exp) 43 | if eq { 44 | for i := range got { 45 | eq = eq && got[i] == tt.exp[i] 46 | } 47 | } 48 | if !eq { 49 | t.Errorf("diffing % #v", tt.a) 50 | t.Errorf("with % #v", tt.b) 51 | diffdiff(t, got, tt.exp) 52 | continue 53 | } 54 | } 55 | } 56 | 57 | func diffdiff(t *testing.T, got, exp []string) { 58 | minus(t, "unexpected:", got, exp) 59 | minus(t, "missing:", exp, got) 60 | } 61 | 62 | func minus(t *testing.T, s string, a, b []string) { 63 | var i, j int 64 | for i = 0; i < len(a); i++ { 65 | for j = 0; j < len(b); j++ { 66 | if a[i] == b[j] { 67 | break 68 | } 69 | } 70 | if j == len(b) { 71 | t.Error(s, a[i]) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/colwriter/column_test.go: -------------------------------------------------------------------------------- 1 | package colwriter 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | var src = ` 9 | .git 10 | .gitignore 11 | .godir 12 | Procfile: 13 | README.md 14 | api.go 15 | apps.go 16 | auth.go 17 | darwin.go 18 | data.go 19 | dyno.go: 20 | env.go 21 | git.go 22 | help.go 23 | hkdist 24 | linux.go 25 | ls.go 26 | main.go 27 | plugin.go 28 | run.go 29 | scale.go 30 | ssh.go 31 | tail.go 32 | term 33 | unix.go 34 | update.go 35 | version.go 36 | windows.go 37 | `[1:] 38 | 39 | var tests = []struct { 40 | wid int 41 | flag uint 42 | src string 43 | want string 44 | }{ 45 | {80, 0, "", ""}, 46 | {80, 0, src, ` 47 | .git README.md darwin.go git.go ls.go scale.go unix.go 48 | .gitignore api.go data.go help.go main.go ssh.go update.go 49 | .godir apps.go dyno.go: hkdist plugin.go tail.go version.go 50 | Procfile: auth.go env.go linux.go run.go term windows.go 51 | `[1:]}, 52 | {80, BreakOnColon, src, ` 53 | .git .gitignore .godir 54 | 55 | Procfile: 56 | README.md api.go apps.go auth.go darwin.go data.go 57 | 58 | dyno.go: 59 | env.go hkdist main.go scale.go term version.go 60 | git.go linux.go plugin.go ssh.go unix.go windows.go 61 | help.go ls.go run.go tail.go update.go 62 | `[1:]}, 63 | {20, 0, ` 64 | Hello 65 | Γειά σου 66 | 안녕 67 | 今日は 68 | `[1:], ` 69 | Hello 안녕 70 | Γειά σου 今日は 71 | `[1:]}, 72 | } 73 | 74 | func TestWriter(t *testing.T) { 75 | for _, test := range tests { 76 | b := new(bytes.Buffer) 77 | w := NewWriter(b, test.wid, test.flag) 78 | if _, err := w.Write([]byte(test.src)); err != nil { 79 | t.Error(err) 80 | } 81 | if err := w.Flush(); err != nil { 82 | t.Error(err) 83 | } 84 | if g := b.String(); test.want != g { 85 | t.Log("\n" + test.want) 86 | t.Log("\n" + g) 87 | t.Errorf("%q != %q", test.want, g) 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ctxhttp 6 | 7 | import ( 8 | "io/ioutil" 9 | "net/http" 10 | "net/http/httptest" 11 | "testing" 12 | "time" 13 | 14 | "golang.org/x/net/context" 15 | ) 16 | 17 | const ( 18 | requestDuration = 100 * time.Millisecond 19 | requestBody = "ok" 20 | ) 21 | 22 | func TestNoTimeout(t *testing.T) { 23 | ctx := context.Background() 24 | resp, err := doRequest(ctx) 25 | 26 | if resp == nil || err != nil { 27 | t.Fatalf("error received from client: %v %v", err, resp) 28 | } 29 | } 30 | func TestCancel(t *testing.T) { 31 | ctx, cancel := context.WithCancel(context.Background()) 32 | go func() { 33 | time.Sleep(requestDuration / 2) 34 | cancel() 35 | }() 36 | 37 | resp, err := doRequest(ctx) 38 | 39 | if resp != nil || err == nil { 40 | t.Fatalf("expected error, didn't get one. resp: %v", resp) 41 | } 42 | if err != ctx.Err() { 43 | t.Fatalf("expected error from context but got: %v", err) 44 | } 45 | } 46 | 47 | func TestCancelAfterRequest(t *testing.T) { 48 | ctx, cancel := context.WithCancel(context.Background()) 49 | 50 | resp, err := doRequest(ctx) 51 | 52 | // Cancel before reading the body. 53 | // Request.Body should still be readable after the context is canceled. 54 | cancel() 55 | 56 | b, err := ioutil.ReadAll(resp.Body) 57 | if err != nil || string(b) != requestBody { 58 | t.Fatalf("could not read body: %q %v", b, err) 59 | } 60 | } 61 | 62 | func doRequest(ctx context.Context) (*http.Response, error) { 63 | var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 64 | time.Sleep(requestDuration) 65 | w.Write([]byte(requestBody)) 66 | }) 67 | 68 | serv := httptest.NewServer(okHandler) 69 | defer serv.Close() 70 | 71 | return Get(ctx, nil, serv.URL) 72 | } 73 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/journald_formatter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // +build !windows 16 | 17 | package capnslog 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "os" 23 | "path/filepath" 24 | 25 | "github.com/coreos/go-systemd/journal" 26 | ) 27 | 28 | func NewJournaldFormatter() (Formatter, error) { 29 | if !journal.Enabled() { 30 | return nil, errors.New("No systemd detected") 31 | } 32 | return &journaldFormatter{}, nil 33 | } 34 | 35 | type journaldFormatter struct{} 36 | 37 | func (j *journaldFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) { 38 | var pri journal.Priority 39 | switch l { 40 | case CRITICAL: 41 | pri = journal.PriCrit 42 | case ERROR: 43 | pri = journal.PriErr 44 | case WARNING: 45 | pri = journal.PriWarning 46 | case NOTICE: 47 | pri = journal.PriNotice 48 | case INFO: 49 | pri = journal.PriInfo 50 | case DEBUG: 51 | pri = journal.PriDebug 52 | case TRACE: 53 | pri = journal.PriDebug 54 | default: 55 | panic("Unhandled loglevel") 56 | } 57 | msg := fmt.Sprint(entries...) 58 | tags := map[string]string{ 59 | "PACKAGE": pkg, 60 | "SYSLOG_IDENTIFIER": filepath.Base(os.Args[0]), 61 | } 62 | err := journal.Send(msg, pri, tags) 63 | if err != nil { 64 | fmt.Fprintln(os.Stderr, err) 65 | } 66 | } 67 | 68 | func (j *journaldFormatter) Flush() {} 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bmizerany/assert/assert.go: -------------------------------------------------------------------------------- 1 | package assert 2 | // Testing helpers for doozer. 3 | 4 | import ( 5 | "github.com/kr/pretty" 6 | "reflect" 7 | "testing" 8 | "runtime" 9 | "fmt" 10 | ) 11 | 12 | func assert(t *testing.T, result bool, f func(), cd int) { 13 | if !result { 14 | _, file, line, _ := runtime.Caller(cd + 1) 15 | t.Errorf("%s:%d", file, line) 16 | f() 17 | t.FailNow() 18 | } 19 | } 20 | 21 | func equal(t *testing.T, exp, got interface{}, cd int, args ...interface{}) { 22 | fn := func() { 23 | for _, desc := range pretty.Diff(exp, got) { 24 | t.Error("!", desc) 25 | } 26 | if len(args) > 0 { 27 | t.Error("!", " -", fmt.Sprint(args...)) 28 | } 29 | } 30 | result := reflect.DeepEqual(exp, got) 31 | assert(t, result, fn, cd+1) 32 | } 33 | 34 | func tt(t *testing.T, result bool, cd int, args ...interface{}) { 35 | fn := func() { 36 | t.Errorf("! Failure") 37 | if len(args) > 0 { 38 | t.Error("!", " -", fmt.Sprint(args...)) 39 | } 40 | } 41 | assert(t, result, fn, cd+1) 42 | } 43 | 44 | func T(t *testing.T, result bool, args ...interface{}) { 45 | tt(t, result, 1, args...) 46 | } 47 | 48 | func Tf(t *testing.T, result bool, format string, args ...interface{}) { 49 | tt(t, result, 1, fmt.Sprintf(format, args...)) 50 | } 51 | 52 | func Equal(t *testing.T, exp, got interface{}, args ...interface{}) { 53 | equal(t, exp, got, 1, args...) 54 | } 55 | 56 | func Equalf(t *testing.T, exp, got interface{}, format string, args ...interface{}) { 57 | equal(t, exp, got, 1, fmt.Sprintf(format, args...)) 58 | } 59 | 60 | func NotEqual(t *testing.T, exp, got interface{}, args ...interface{}) { 61 | fn := func() { 62 | t.Errorf("! Unexpected: <%#v>", exp) 63 | if len(args) > 0 { 64 | t.Error("!", " -", fmt.Sprint(args...)) 65 | } 66 | } 67 | result := !reflect.DeepEqual(exp, got) 68 | assert(t, result, fn, 1) 69 | } 70 | 71 | func Panic(t *testing.T, err interface{}, fn func()) { 72 | defer func() { 73 | equal(t, err, recover(), 3) 74 | }() 75 | fn() 76 | } 77 | -------------------------------------------------------------------------------- /providers/linkedin.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net/http" 7 | "net/url" 8 | 9 | "github.com/bitly/oauth2_proxy/api" 10 | ) 11 | 12 | type LinkedInProvider struct { 13 | *ProviderData 14 | } 15 | 16 | func NewLinkedInProvider(p *ProviderData) *LinkedInProvider { 17 | p.ProviderName = "LinkedIn" 18 | if p.LoginURL.String() == "" { 19 | p.LoginURL = &url.URL{Scheme: "https", 20 | Host: "www.linkedin.com", 21 | Path: "/uas/oauth2/authorization"} 22 | } 23 | if p.RedeemURL.String() == "" { 24 | p.RedeemURL = &url.URL{Scheme: "https", 25 | Host: "www.linkedin.com", 26 | Path: "/uas/oauth2/accessToken"} 27 | } 28 | if p.ProfileURL.String() == "" { 29 | p.ProfileURL = &url.URL{Scheme: "https", 30 | Host: "www.linkedin.com", 31 | Path: "/v1/people/~/email-address"} 32 | } 33 | if p.ValidateURL.String() == "" { 34 | p.ValidateURL = p.ProfileURL 35 | } 36 | if p.Scope == "" { 37 | p.Scope = "r_emailaddress r_basicprofile" 38 | } 39 | return &LinkedInProvider{ProviderData: p} 40 | } 41 | 42 | func getLinkedInHeader(access_token string) http.Header { 43 | header := make(http.Header) 44 | header.Set("Accept", "application/json") 45 | header.Set("x-li-format", "json") 46 | header.Set("Authorization", fmt.Sprintf("Bearer %s", access_token)) 47 | return header 48 | } 49 | 50 | func (p *LinkedInProvider) GetEmailAddress(s *SessionState) (string, error) { 51 | if s.AccessToken == "" { 52 | return "", errors.New("missing access token") 53 | } 54 | req, err := http.NewRequest("GET", p.ProfileURL.String()+"?format=json", nil) 55 | if err != nil { 56 | return "", err 57 | } 58 | req.Header = getLinkedInHeader(s.AccessToken) 59 | 60 | json, err := api.Request(req) 61 | if err != nil { 62 | return "", err 63 | } 64 | 65 | email, err := json.String() 66 | if err != nil { 67 | return "", err 68 | } 69 | return email, nil 70 | } 71 | 72 | func (p *LinkedInProvider) ValidateSessionState(s *SessionState) bool { 73 | return validateToken(p, s.AccessToken, getLinkedInHeader(s.AccessToken)) 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oidc/transport.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "sync" 7 | 8 | phttp "github.com/coreos/go-oidc/http" 9 | "github.com/coreos/go-oidc/jose" 10 | ) 11 | 12 | type TokenRefresher interface { 13 | // Verify checks if the provided token is currently valid or not. 14 | Verify(jose.JWT) error 15 | 16 | // Refresh attempts to authenticate and retrieve a new token. 17 | Refresh() (jose.JWT, error) 18 | } 19 | 20 | type ClientCredsTokenRefresher struct { 21 | Issuer string 22 | OIDCClient *Client 23 | } 24 | 25 | func (c *ClientCredsTokenRefresher) Verify(jwt jose.JWT) (err error) { 26 | _, err = VerifyClientClaims(jwt, c.Issuer) 27 | return 28 | } 29 | 30 | func (c *ClientCredsTokenRefresher) Refresh() (jwt jose.JWT, err error) { 31 | if err = c.OIDCClient.Healthy(); err != nil { 32 | err = fmt.Errorf("unable to authenticate, unhealthy OIDC client: %v", err) 33 | return 34 | } 35 | 36 | jwt, err = c.OIDCClient.ClientCredsToken([]string{"openid"}) 37 | if err != nil { 38 | err = fmt.Errorf("unable to verify auth code with issuer: %v", err) 39 | return 40 | } 41 | 42 | return 43 | } 44 | 45 | type AuthenticatedTransport struct { 46 | TokenRefresher 47 | http.RoundTripper 48 | 49 | mu sync.Mutex 50 | jwt jose.JWT 51 | } 52 | 53 | func (t *AuthenticatedTransport) verifiedJWT() (jose.JWT, error) { 54 | t.mu.Lock() 55 | defer t.mu.Unlock() 56 | 57 | if t.TokenRefresher.Verify(t.jwt) == nil { 58 | return t.jwt, nil 59 | } 60 | 61 | jwt, err := t.TokenRefresher.Refresh() 62 | if err != nil { 63 | return jose.JWT{}, fmt.Errorf("unable to acquire valid JWT: %v", err) 64 | } 65 | 66 | t.jwt = jwt 67 | return t.jwt, nil 68 | } 69 | 70 | func (t *AuthenticatedTransport) RoundTrip(r *http.Request) (*http.Response, error) { 71 | jwt, err := t.verifiedJWT() 72 | if err != nil { 73 | return nil, err 74 | } 75 | 76 | req := phttp.CopyRequest(r) 77 | req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt.Encode())) 78 | return t.RoundTripper.RoundTrip(req) 79 | } 80 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/example/hello_dolly.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "flag" 19 | oldlog "log" 20 | 21 | "github.com/coreos/pkg/capnslog" 22 | ) 23 | 24 | var logLevel = capnslog.INFO 25 | var log = capnslog.NewPackageLogger("github.com/coreos/pkg/capnslog/cmd", "main") 26 | var dlog = capnslog.NewPackageLogger("github.com/coreos/pkg/capnslog/cmd", "dolly") 27 | 28 | func init() { 29 | flag.Var(&logLevel, "log-level", "Global log level.") 30 | } 31 | 32 | func main() { 33 | rl := capnslog.MustRepoLogger("github.com/coreos/pkg/capnslog/cmd") 34 | 35 | // We can parse the log level configs from the command line 36 | flag.Parse() 37 | if flag.NArg() > 1 { 38 | cfg, err := rl.ParseLogLevelConfig(flag.Arg(1)) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | rl.SetLogLevel(cfg) 43 | log.Infof("Setting output to %s", flag.Arg(1)) 44 | } 45 | 46 | // Send some messages at different levels to the different packages 47 | dlog.Infof("Hello Dolly") 48 | dlog.Warningf("Well hello, Dolly") 49 | log.Errorf("It's so nice to have you back where you belong") 50 | dlog.Debugf("You're looking swell, Dolly") 51 | dlog.Tracef("I can tell, Dolly") 52 | 53 | // We also have control over the built-in "log" package. 54 | capnslog.SetGlobalLogLevel(logLevel) 55 | oldlog.Println("You're still glowin', you're still crowin', you're still lookin' strong") 56 | log.Fatalf("Dolly'll never go away again") 57 | } 58 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/oauth2/error_test.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestUnmarshalError(t *testing.T) { 10 | tests := []struct { 11 | b []byte 12 | e *Error 13 | o bool 14 | }{ 15 | { 16 | b: []byte("{ \"error\": \"invalid_client\", \"state\": \"foo\" }"), 17 | e: &Error{Type: ErrorInvalidClient, State: "foo"}, 18 | o: true, 19 | }, 20 | { 21 | b: []byte("{ \"error\": \"invalid_grant\", \"state\": \"bar\" }"), 22 | e: &Error{Type: ErrorInvalidGrant, State: "bar"}, 23 | o: true, 24 | }, 25 | { 26 | b: []byte("{ \"error\": \"invalid_request\", \"state\": \"\" }"), 27 | e: &Error{Type: ErrorInvalidRequest, State: ""}, 28 | o: true, 29 | }, 30 | { 31 | b: []byte("{ \"error\": \"server_error\", \"state\": \"elroy\" }"), 32 | e: &Error{Type: ErrorServerError, State: "elroy"}, 33 | o: true, 34 | }, 35 | { 36 | b: []byte("{ \"error\": \"unsupported_grant_type\", \"state\": \"\" }"), 37 | e: &Error{Type: ErrorUnsupportedGrantType, State: ""}, 38 | o: true, 39 | }, 40 | { 41 | b: []byte("{ \"error\": \"unsupported_response_type\", \"state\": \"\" }"), 42 | e: &Error{Type: ErrorUnsupportedResponseType, State: ""}, 43 | o: true, 44 | }, 45 | // Should fail json unmarshal 46 | { 47 | b: nil, 48 | e: nil, 49 | o: false, 50 | }, 51 | { 52 | b: []byte("random string"), 53 | e: nil, 54 | o: false, 55 | }, 56 | } 57 | 58 | for i, tt := range tests { 59 | err := unmarshalError(tt.b) 60 | oerr, ok := err.(*Error) 61 | 62 | if ok != tt.o { 63 | t.Errorf("%v != %v, %v", ok, tt.o, oerr) 64 | t.Errorf("case %d: want=%+v, got=%+v", i, tt.e, oerr) 65 | } 66 | 67 | if ok && !reflect.DeepEqual(tt.e, oerr) { 68 | t.Errorf("case %d: want=%+v, got=%+v", i, tt.e, oerr) 69 | } 70 | 71 | if !ok && tt.e != nil { 72 | want := fmt.Sprintf("unrecognized error: %s", string(tt.b)) 73 | got := tt.e.Error() 74 | if want != got { 75 | t.Errorf("case %d: want=%+v, got=%+v", i, want, got) 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/jwt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "crypto/rsa" 9 | "fmt" 10 | "time" 11 | 12 | "golang.org/x/oauth2" 13 | "golang.org/x/oauth2/internal" 14 | "golang.org/x/oauth2/jws" 15 | ) 16 | 17 | // JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON 18 | // key file to read the credentials that authorize and authenticate the 19 | // requests, and returns a TokenSource that does not use any OAuth2 flow but 20 | // instead creates a JWT and sends that as the access token. 21 | // The audience is typically a URL that specifies the scope of the credentials. 22 | func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) { 23 | cfg, err := JWTConfigFromJSON(jsonKey) 24 | if err != nil { 25 | return nil, fmt.Errorf("google: could not parse JSON key: %v", err) 26 | } 27 | pk, err := internal.ParseKey(cfg.PrivateKey) 28 | if err != nil { 29 | return nil, fmt.Errorf("google: could not parse key: %v", err) 30 | } 31 | ts := &jwtAccessTokenSource{ 32 | email: cfg.Email, 33 | audience: audience, 34 | pk: pk, 35 | } 36 | tok, err := ts.Token() 37 | if err != nil { 38 | return nil, err 39 | } 40 | return oauth2.ReuseTokenSource(tok, ts), nil 41 | } 42 | 43 | type jwtAccessTokenSource struct { 44 | email, audience string 45 | pk *rsa.PrivateKey 46 | } 47 | 48 | func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) { 49 | iat := time.Now() 50 | exp := iat.Add(time.Hour) 51 | cs := &jws.ClaimSet{ 52 | Iss: ts.email, 53 | Sub: ts.email, 54 | Aud: ts.audience, 55 | Iat: iat.Unix(), 56 | Exp: exp.Unix(), 57 | } 58 | hdr := &jws.Header{ 59 | Algorithm: "RS256", 60 | Typ: "JWT", 61 | } 62 | msg, err := jws.Encode(hdr, cs, ts.pk) 63 | if err != nil { 64 | return nil, fmt.Errorf("google: could not encode JWT: %v", err) 65 | } 66 | return &oauth2.Token{AccessToken: msg}, nil 67 | } 68 | -------------------------------------------------------------------------------- /watcher.go: -------------------------------------------------------------------------------- 1 | // +build go1.3,!plan9,!solaris 2 | 3 | package main 4 | 5 | import ( 6 | "log" 7 | "os" 8 | "path/filepath" 9 | "time" 10 | 11 | "gopkg.in/fsnotify.v1" 12 | ) 13 | 14 | func WaitForReplacement(filename string, op fsnotify.Op, 15 | watcher *fsnotify.Watcher) { 16 | const sleep_interval = 50 * time.Millisecond 17 | 18 | // Avoid a race when fsnofity.Remove is preceded by fsnotify.Chmod. 19 | if op&fsnotify.Chmod != 0 { 20 | time.Sleep(sleep_interval) 21 | } 22 | for { 23 | if _, err := os.Stat(filename); err == nil { 24 | if err := watcher.Add(filename); err == nil { 25 | log.Printf("watching resumed for %s", filename) 26 | return 27 | } 28 | } 29 | time.Sleep(sleep_interval) 30 | } 31 | } 32 | 33 | func WatchForUpdates(filename string, done <-chan bool, action func()) { 34 | filename = filepath.Clean(filename) 35 | watcher, err := fsnotify.NewWatcher() 36 | if err != nil { 37 | log.Fatal("failed to create watcher for ", filename, ": ", err) 38 | } 39 | go func() { 40 | defer watcher.Close() 41 | for { 42 | select { 43 | case _ = <-done: 44 | log.Printf("Shutting down watcher for: %s", filename) 45 | break 46 | case event := <-watcher.Events: 47 | // On Arch Linux, it appears Chmod events precede Remove events, 48 | // which causes a race between action() and the coming Remove event. 49 | // If the Remove wins, the action() (which calls 50 | // UserMap.LoadAuthenticatedEmailsFile()) crashes when the file 51 | // can't be opened. 52 | if event.Op&(fsnotify.Remove|fsnotify.Rename|fsnotify.Chmod) != 0 { 53 | log.Printf("watching interrupted on event: %s", event) 54 | watcher.Remove(filename) 55 | WaitForReplacement(filename, event.Op, watcher) 56 | } 57 | log.Printf("reloading after event: %s", event) 58 | action() 59 | case err := <-watcher.Errors: 60 | log.Printf("error watching %s: %s", filename, err) 61 | } 62 | } 63 | }() 64 | if err = watcher.Add(filename); err != nil { 65 | log.Fatal("failed to add ", filename, " to watcher: ", err) 66 | } 67 | log.Printf("watching %s for updates", filename) 68 | } 69 | -------------------------------------------------------------------------------- /providers/facebook.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "net/http" 7 | "net/url" 8 | 9 | "github.com/bitly/oauth2_proxy/api" 10 | ) 11 | 12 | type FacebookProvider struct { 13 | *ProviderData 14 | } 15 | 16 | func NewFacebookProvider(p *ProviderData) *FacebookProvider { 17 | p.ProviderName = "Facebook" 18 | if p.LoginURL.String() == "" { 19 | p.LoginURL = &url.URL{Scheme: "https", 20 | Host: "www.facebook.com", 21 | Path: "/v2.5/dialog/oauth", 22 | // ?granted_scopes=true 23 | } 24 | } 25 | if p.RedeemURL.String() == "" { 26 | p.RedeemURL = &url.URL{Scheme: "https", 27 | Host: "graph.facebook.com", 28 | Path: "/v2.5/oauth/access_token", 29 | } 30 | } 31 | if p.ProfileURL.String() == "" { 32 | p.ProfileURL = &url.URL{Scheme: "https", 33 | Host: "graph.facebook.com", 34 | Path: "/v2.5/me", 35 | } 36 | } 37 | if p.ValidateURL.String() == "" { 38 | p.ValidateURL = p.ProfileURL 39 | } 40 | if p.Scope == "" { 41 | p.Scope = "public_profile email" 42 | } 43 | return &FacebookProvider{ProviderData: p} 44 | } 45 | 46 | func getFacebookHeader(access_token string) http.Header { 47 | header := make(http.Header) 48 | header.Set("Accept", "application/json") 49 | header.Set("x-li-format", "json") 50 | header.Set("Authorization", fmt.Sprintf("Bearer %s", access_token)) 51 | return header 52 | } 53 | 54 | func (p *FacebookProvider) GetEmailAddress(s *SessionState) (string, error) { 55 | if s.AccessToken == "" { 56 | return "", errors.New("missing access token") 57 | } 58 | req, err := http.NewRequest("GET", p.ProfileURL.String()+"?fields=name,email", nil) 59 | if err != nil { 60 | return "", err 61 | } 62 | req.Header = getFacebookHeader(s.AccessToken) 63 | 64 | type result struct { 65 | Email string 66 | } 67 | var r result 68 | err = api.RequestJson(req, &r) 69 | if err != nil { 70 | return "", err 71 | } 72 | if r.Email == "" { 73 | return "", errors.New("no email") 74 | } 75 | return r.Email, nil 76 | } 77 | 78 | func (p *FacebookProvider) ValidateSessionState(s *SessionState) bool { 79 | return validateToken(p, s.AccessToken, getFacebookHeader(s.AccessToken)) 80 | } 81 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/cloud/internal/transport/proto.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package transport 16 | 17 | import ( 18 | "bytes" 19 | "io/ioutil" 20 | "net/http" 21 | 22 | "github.com/golang/protobuf/proto" 23 | "golang.org/x/net/context" 24 | ) 25 | 26 | type ProtoClient struct { 27 | client *http.Client 28 | endpoint string 29 | userAgent string 30 | } 31 | 32 | func (c *ProtoClient) Call(ctx context.Context, method string, req, resp proto.Message) error { 33 | payload, err := proto.Marshal(req) 34 | if err != nil { 35 | return err 36 | } 37 | 38 | httpReq, err := http.NewRequest("POST", c.endpoint+method, bytes.NewReader(payload)) 39 | if err != nil { 40 | return err 41 | } 42 | httpReq.Header.Set("Content-Type", "application/x-protobuf") 43 | if ua := c.userAgent; ua != "" { 44 | httpReq.Header.Set("User-Agent", ua) 45 | } 46 | 47 | errc := make(chan error, 1) 48 | cancel := makeReqCancel(httpReq) 49 | 50 | go func() { 51 | r, err := c.client.Do(httpReq) 52 | if err != nil { 53 | errc <- err 54 | return 55 | } 56 | defer r.Body.Close() 57 | 58 | body, err := ioutil.ReadAll(r.Body) 59 | if r.StatusCode != http.StatusOK { 60 | err = &ErrHTTP{ 61 | StatusCode: r.StatusCode, 62 | Body: body, 63 | err: err, 64 | } 65 | } 66 | if err != nil { 67 | errc <- err 68 | return 69 | } 70 | errc <- proto.Unmarshal(body, resp) 71 | }() 72 | 73 | select { 74 | case <-ctx.Done(): 75 | cancel(c.client.Transport) // Cancel the HTTP request. 76 | return ctx.Err() 77 | case err := <-errc: 78 | return err 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /providers/internal_util.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "net/http" 7 | "net/url" 8 | 9 | "github.com/bitly/oauth2_proxy/api" 10 | ) 11 | 12 | // stripToken is a helper function to obfuscate "access_token" 13 | // query parameters 14 | func stripToken(endpoint string) string { 15 | return stripParam("access_token", endpoint) 16 | } 17 | 18 | // stripParam generalizes the obfuscation of a particular 19 | // query parameter - typically 'access_token' or 'client_secret' 20 | // The parameter's second half is replaced by '...' and returned 21 | // as part of the encoded query parameters. 22 | // If the target parameter isn't found, the endpoint is returned 23 | // unmodified. 24 | func stripParam(param, endpoint string) string { 25 | u, err := url.Parse(endpoint) 26 | if err != nil { 27 | log.Printf("error attempting to strip %s: %s", param, err) 28 | return endpoint 29 | } 30 | 31 | if u.RawQuery != "" { 32 | values, err := url.ParseQuery(u.RawQuery) 33 | if err != nil { 34 | log.Printf("error attempting to strip %s: %s", param, err) 35 | return u.String() 36 | } 37 | 38 | if val := values.Get(param); val != "" { 39 | values.Set(param, val[:(len(val)/2)]+"...") 40 | u.RawQuery = values.Encode() 41 | return u.String() 42 | } 43 | } 44 | 45 | return endpoint 46 | } 47 | 48 | // validateToken returns true if token is valid 49 | func validateToken(p Provider, access_token string, header http.Header) bool { 50 | if access_token == "" || p.Data().ValidateURL == nil { 51 | return false 52 | } 53 | endpoint := p.Data().ValidateURL.String() 54 | if len(header) == 0 { 55 | params := url.Values{"access_token": {access_token}} 56 | endpoint = endpoint + "?" + params.Encode() 57 | } 58 | resp, err := api.RequestUnparsedResponse(endpoint, header) 59 | if err != nil { 60 | log.Printf("GET %s", endpoint) 61 | log.Printf("token validation request failed: %s", err) 62 | return false 63 | } 64 | 65 | body, _ := ioutil.ReadAll(resp.Body) 66 | resp.Body.Close() 67 | log.Printf("%d GET %s %s", resp.StatusCode, stripToken(endpoint), body) 68 | 69 | if resp.StatusCode == 200 { 70 | return true 71 | } 72 | log.Printf("token validation request failed: status %d - %s", resp.StatusCode, body) 73 | return false 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/key/sync.go: -------------------------------------------------------------------------------- 1 | package key 2 | 3 | import ( 4 | "errors" 5 | "time" 6 | 7 | "github.com/jonboulle/clockwork" 8 | 9 | "github.com/coreos/pkg/timeutil" 10 | ) 11 | 12 | func NewKeySetSyncer(r ReadableKeySetRepo, w WritableKeySetRepo) *KeySetSyncer { 13 | return &KeySetSyncer{ 14 | readable: r, 15 | writable: w, 16 | clock: clockwork.NewRealClock(), 17 | } 18 | } 19 | 20 | type KeySetSyncer struct { 21 | readable ReadableKeySetRepo 22 | writable WritableKeySetRepo 23 | clock clockwork.Clock 24 | } 25 | 26 | func (s *KeySetSyncer) Run() chan struct{} { 27 | stop := make(chan struct{}) 28 | go func() { 29 | var failing bool 30 | var next time.Duration 31 | for { 32 | exp, err := sync(s.readable, s.writable, s.clock) 33 | if err != nil || exp == 0 { 34 | if !failing { 35 | failing = true 36 | next = time.Second 37 | } else { 38 | next = timeutil.ExpBackoff(next, time.Minute) 39 | } 40 | if exp == 0 { 41 | log.Errorf("Synced to already expired key set, retrying in %v: %v", next, err) 42 | 43 | } else { 44 | log.Errorf("Failed syncing key set, retrying in %v: %v", next, err) 45 | } 46 | } else { 47 | failing = false 48 | next = exp / 2 49 | log.Infof("Synced key set, checking again in %v", next) 50 | } 51 | 52 | select { 53 | case <-s.clock.After(next): 54 | continue 55 | case <-stop: 56 | return 57 | } 58 | } 59 | }() 60 | 61 | return stop 62 | } 63 | 64 | func Sync(r ReadableKeySetRepo, w WritableKeySetRepo) (time.Duration, error) { 65 | return sync(r, w, clockwork.NewRealClock()) 66 | } 67 | 68 | // sync copies the keyset from r to the KeySet at w and returns the duration in which the KeySet will expire. 69 | // If keyset has already expired, returns a zero duration. 70 | func sync(r ReadableKeySetRepo, w WritableKeySetRepo, clock clockwork.Clock) (exp time.Duration, err error) { 71 | var ks KeySet 72 | ks, err = r.Get() 73 | if err != nil { 74 | return 75 | } 76 | 77 | if ks == nil { 78 | err = errors.New("no source KeySet") 79 | return 80 | } 81 | 82 | if err = w.Set(ks); err != nil { 83 | return 84 | } 85 | 86 | now := clock.Now() 87 | if ks.ExpiresAt().After(now) { 88 | exp = ks.ExpiresAt().Sub(now) 89 | } 90 | return 91 | } 92 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/sig_hmac_test.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "bytes" 5 | "encoding/base64" 6 | "testing" 7 | ) 8 | 9 | var hmacTestCases = []struct { 10 | data string 11 | sig string 12 | jwk JWK 13 | valid bool 14 | desc string 15 | }{ 16 | { 17 | "test", 18 | "Aymga2LNFrM-tnkr6MYLFY2Jou46h2_Omogeu0iMCRQ=", 19 | JWK{ 20 | ID: "fake-key", 21 | Alg: "HS256", 22 | Secret: []byte("secret"), 23 | }, 24 | true, 25 | "valid case", 26 | }, 27 | { 28 | "test", 29 | "Aymga2LNFrM-tnkr6MYLFY2Jou46h2_Omogeu0iMCRQ=", 30 | JWK{ 31 | ID: "different-key", 32 | Alg: "HS256", 33 | Secret: []byte("secret"), 34 | }, 35 | true, 36 | "invalid: different key, should not match", 37 | }, 38 | { 39 | "test sig and non-matching data", 40 | "Aymga2LNFrM-tnkr6MYLFY2Jou46h2_Omogeu0iMCRQ=", 41 | JWK{ 42 | ID: "fake-key", 43 | Alg: "HS256", 44 | Secret: []byte("secret"), 45 | }, 46 | false, 47 | "invalid: sig and data should not match", 48 | }, 49 | } 50 | 51 | func TestVerify(t *testing.T) { 52 | for _, tt := range hmacTestCases { 53 | v, err := NewVerifierHMAC(tt.jwk) 54 | if err != nil { 55 | t.Errorf("should construct hmac verifier. test: %s. err=%v", tt.desc, err) 56 | } 57 | 58 | decSig, _ := base64.URLEncoding.DecodeString(tt.sig) 59 | err = v.Verify(decSig, []byte(tt.data)) 60 | if err == nil && !tt.valid { 61 | t.Errorf("verify failure. test: %s. expected: invalid, actual: valid.", tt.desc) 62 | } 63 | if err != nil && tt.valid { 64 | t.Errorf("verify failure. test: %s. expected: valid, actual: invalid. err=%v", tt.desc, err) 65 | } 66 | } 67 | } 68 | 69 | func TestSign(t *testing.T) { 70 | for _, tt := range hmacTestCases { 71 | s := NewSignerHMAC("test", tt.jwk.Secret) 72 | sig, err := s.Sign([]byte(tt.data)) 73 | if err != nil { 74 | t.Errorf("sign failure. test: %s. err=%v", tt.desc, err) 75 | } 76 | 77 | expSig, _ := base64.URLEncoding.DecodeString(tt.sig) 78 | if tt.valid && !bytes.Equal(sig, expSig) { 79 | t.Errorf("sign failure. test: %s. expected: %s, actual: %s.", tt.desc, tt.sig, base64.URLEncoding.EncodeToString(sig)) 80 | } 81 | if !tt.valid && bytes.Equal(sig, expSig) { 82 | t.Errorf("sign failure. test: %s. expected: invalid signature.", tt.desc) 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/simplejson_go10_test.go: -------------------------------------------------------------------------------- 1 | // +build !go1.1 2 | 3 | package simplejson 4 | 5 | import ( 6 | "bytes" 7 | "github.com/bmizerany/assert" 8 | "strconv" 9 | "testing" 10 | ) 11 | 12 | func TestNewFromReader(t *testing.T) { 13 | buf := bytes.NewBuffer([]byte(`{ 14 | "test": { 15 | "array": [1, "2", 3], 16 | "arraywithsubs": [ 17 | {"subkeyone": 1}, 18 | {"subkeytwo": 2, "subkeythree": 3} 19 | ], 20 | "bignum": 8000000000 21 | } 22 | }`)) 23 | js, err := NewFromReader(buf) 24 | 25 | //Standard Test Case 26 | assert.NotEqual(t, nil, js) 27 | assert.Equal(t, nil, err) 28 | 29 | arr, _ := js.Get("test").Get("array").Array() 30 | assert.NotEqual(t, nil, arr) 31 | for i, v := range arr { 32 | var iv int 33 | switch v.(type) { 34 | case float64: 35 | iv = int(v.(float64)) 36 | case string: 37 | iv, _ = strconv.Atoi(v.(string)) 38 | } 39 | assert.Equal(t, i+1, iv) 40 | } 41 | 42 | ma := js.Get("test").Get("array").MustArray() 43 | assert.Equal(t, ma, []interface{}{float64(1), "2", float64(3)}) 44 | 45 | mm := js.Get("test").Get("arraywithsubs").GetIndex(0).MustMap() 46 | assert.Equal(t, mm, map[string]interface{}{"subkeyone": float64(1)}) 47 | 48 | assert.Equal(t, js.Get("test").Get("bignum").MustInt64(), int64(8000000000)) 49 | } 50 | 51 | func TestSimplejsonGo10(t *testing.T) { 52 | js, err := NewJson([]byte(`{ 53 | "test": { 54 | "array": [1, "2", 3], 55 | "arraywithsubs": [ 56 | {"subkeyone": 1}, 57 | {"subkeytwo": 2, "subkeythree": 3} 58 | ], 59 | "bignum": 8000000000 60 | } 61 | }`)) 62 | 63 | assert.NotEqual(t, nil, js) 64 | assert.Equal(t, nil, err) 65 | 66 | arr, _ := js.Get("test").Get("array").Array() 67 | assert.NotEqual(t, nil, arr) 68 | for i, v := range arr { 69 | var iv int 70 | switch v.(type) { 71 | case float64: 72 | iv = int(v.(float64)) 73 | case string: 74 | iv, _ = strconv.Atoi(v.(string)) 75 | } 76 | assert.Equal(t, i+1, iv) 77 | } 78 | 79 | ma := js.Get("test").Get("array").MustArray() 80 | assert.Equal(t, ma, []interface{}{float64(1), "2", float64(3)}) 81 | 82 | mm := js.Get("test").Get("arraywithsubs").GetIndex(0).MustMap() 83 | assert.Equal(t, mm, map[string]interface{}{"subkeyone": float64(1)}) 84 | 85 | assert.Equal(t, js.Get("test").Get("bignum").MustInt64(), int64(8000000000)) 86 | } 87 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/internal/transport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "net/http" 10 | 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | // HTTPClient is the context key to use with golang.org/x/net/context's 15 | // WithValue function to associate an *http.Client value with a context. 16 | var HTTPClient ContextKey 17 | 18 | // ContextKey is just an empty struct. It exists so HTTPClient can be 19 | // an immutable public variable with a unique type. It's immutable 20 | // because nobody else can create a ContextKey, being unexported. 21 | type ContextKey struct{} 22 | 23 | // ContextClientFunc is a func which tries to return an *http.Client 24 | // given a Context value. If it returns an error, the search stops 25 | // with that error. If it returns (nil, nil), the search continues 26 | // down the list of registered funcs. 27 | type ContextClientFunc func(context.Context) (*http.Client, error) 28 | 29 | var contextClientFuncs []ContextClientFunc 30 | 31 | func RegisterContextClientFunc(fn ContextClientFunc) { 32 | contextClientFuncs = append(contextClientFuncs, fn) 33 | } 34 | 35 | func ContextClient(ctx context.Context) (*http.Client, error) { 36 | for _, fn := range contextClientFuncs { 37 | c, err := fn(ctx) 38 | if err != nil { 39 | return nil, err 40 | } 41 | if c != nil { 42 | return c, nil 43 | } 44 | } 45 | if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok { 46 | return hc, nil 47 | } 48 | return http.DefaultClient, nil 49 | } 50 | 51 | func ContextTransport(ctx context.Context) http.RoundTripper { 52 | hc, err := ContextClient(ctx) 53 | // This is a rare error case (somebody using nil on App Engine). 54 | if err != nil { 55 | return ErrorTransport{err} 56 | } 57 | return hc.Transport 58 | } 59 | 60 | // ErrorTransport returns the specified error on RoundTrip. 61 | // This RoundTripper should be used in rare error cases where 62 | // error handling can be postponed to response handling time. 63 | type ErrorTransport struct{ Err error } 64 | 65 | func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) { 66 | return nil, t.Err 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/README.md: -------------------------------------------------------------------------------- 1 | # OAuth2 for Go 2 | 3 | [![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2) 4 | 5 | oauth2 package contains a client implementation for OAuth 2.0 spec. 6 | 7 | ## Installation 8 | 9 | ~~~~ 10 | go get golang.org/x/oauth2 11 | ~~~~ 12 | 13 | See godoc for further documentation and examples. 14 | 15 | * [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2) 16 | * [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google) 17 | 18 | 19 | ## App Engine 20 | 21 | In change 96e89be (March 2015) we removed the `oauth2.Context2` type in favor 22 | of the [`context.Context`](https://golang.org/x/net/context#Context) type from 23 | the `golang.org/x/net/context` package 24 | 25 | This means its no longer possible to use the "Classic App Engine" 26 | `appengine.Context` type with the `oauth2` package. (You're using 27 | Classic App Engine if you import the package `"appengine"`.) 28 | 29 | To work around this, you may use the new `"google.golang.org/appengine"` 30 | package. This package has almost the same API as the `"appengine"` package, 31 | but it can be fetched with `go get` and used on "Managed VMs" and well as 32 | Classic App Engine. 33 | 34 | See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app) 35 | for information on updating your app. 36 | 37 | If you don't want to update your entire app to use the new App Engine packages, 38 | you may use both sets of packages in parallel, using only the new packages 39 | with the `oauth2` package. 40 | 41 | import ( 42 | "golang.org/x/net/context" 43 | "golang.org/x/oauth2" 44 | "golang.org/x/oauth2/google" 45 | newappengine "google.golang.org/appengine" 46 | newurlfetch "google.golang.org/appengine/urlfetch" 47 | 48 | "appengine" 49 | ) 50 | 51 | func handler(w http.ResponseWriter, r *http.Request) { 52 | var c appengine.Context = appengine.NewContext(r) 53 | c.Infof("Logging a message with the old package") 54 | 55 | var ctx context.Context = newappengine.NewContext(r) 56 | client := &http.Client{ 57 | Transport: &oauth2.Transport{ 58 | Source: google.AppEngineTokenSource(ctx, "scope"), 59 | Base: &newurlfetch.Transport{Context: ctx}, 60 | }, 61 | } 62 | client.Get("...") 63 | } 64 | 65 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/google.golang.org/cloud/internal/testutil/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package testutil contains helper functions for writing tests. 16 | package testutil 17 | 18 | import ( 19 | "io/ioutil" 20 | "log" 21 | "net/http" 22 | "os" 23 | 24 | "golang.org/x/net/context" 25 | "golang.org/x/oauth2" 26 | "golang.org/x/oauth2/google" 27 | "google.golang.org/cloud" 28 | ) 29 | 30 | const ( 31 | envProjID = "GCLOUD_TESTS_GOLANG_PROJECT_ID" 32 | envPrivateKey = "GCLOUD_TESTS_GOLANG_KEY" 33 | ) 34 | 35 | func ProjID() string { 36 | projID := os.Getenv(envProjID) 37 | if projID == "" { 38 | log.Fatal(envProjID + " must be set. See CONTRIBUTING.md for details.") 39 | } 40 | return projID 41 | } 42 | 43 | func TokenSource(ctx context.Context, scopes ...string) oauth2.TokenSource { 44 | key := os.Getenv(envPrivateKey) 45 | if key == "" { 46 | log.Fatal(envPrivateKey + " must be set. See CONTRIBUTING.md for details.") 47 | } 48 | jsonKey, err := ioutil.ReadFile(key) 49 | if err != nil { 50 | log.Fatalf("Cannot read the JSON key file, err: %v", err) 51 | } 52 | conf, err := google.JWTConfigFromJSON(jsonKey, scopes...) 53 | if err != nil { 54 | log.Fatalf("google.JWTConfigFromJSON: %v", err) 55 | } 56 | return conf.TokenSource(ctx) 57 | } 58 | 59 | // TODO(djd): Delete this function when it's no longer used. 60 | func Context(scopes ...string) context.Context { 61 | ctx := oauth2.NoContext 62 | ts := TokenSource(ctx, scopes...) 63 | return cloud.NewContext(ProjID(), oauth2.NewClient(ctx, ts)) 64 | } 65 | 66 | // TODO(djd): Delete this function when it's no longer used. 67 | func NoAuthContext() context.Context { 68 | return cloud.NewContext(ProjID(), &http.Client{Transport: http.DefaultTransport}) 69 | } 70 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/simplejson_go10.go: -------------------------------------------------------------------------------- 1 | // +build !go1.1 2 | 3 | package simplejson 4 | 5 | import ( 6 | "encoding/json" 7 | "errors" 8 | "io" 9 | "reflect" 10 | ) 11 | 12 | // NewFromReader returns a *Json by decoding from an io.Reader 13 | func NewFromReader(r io.Reader) (*Json, error) { 14 | j := new(Json) 15 | dec := json.NewDecoder(r) 16 | err := dec.Decode(&j.data) 17 | return j, err 18 | } 19 | 20 | // Implements the json.Unmarshaler interface. 21 | func (j *Json) UnmarshalJSON(p []byte) error { 22 | return json.Unmarshal(p, &j.data) 23 | } 24 | 25 | // Float64 coerces into a float64 26 | func (j *Json) Float64() (float64, error) { 27 | switch j.data.(type) { 28 | case float32, float64: 29 | return reflect.ValueOf(j.data).Float(), nil 30 | case int, int8, int16, int32, int64: 31 | return float64(reflect.ValueOf(j.data).Int()), nil 32 | case uint, uint8, uint16, uint32, uint64: 33 | return float64(reflect.ValueOf(j.data).Uint()), nil 34 | } 35 | return 0, errors.New("invalid value type") 36 | } 37 | 38 | // Int coerces into an int 39 | func (j *Json) Int() (int, error) { 40 | switch j.data.(type) { 41 | case float32, float64: 42 | return int(reflect.ValueOf(j.data).Float()), nil 43 | case int, int8, int16, int32, int64: 44 | return int(reflect.ValueOf(j.data).Int()), nil 45 | case uint, uint8, uint16, uint32, uint64: 46 | return int(reflect.ValueOf(j.data).Uint()), nil 47 | } 48 | return 0, errors.New("invalid value type") 49 | } 50 | 51 | // Int64 coerces into an int64 52 | func (j *Json) Int64() (int64, error) { 53 | switch j.data.(type) { 54 | case float32, float64: 55 | return int64(reflect.ValueOf(j.data).Float()), nil 56 | case int, int8, int16, int32, int64: 57 | return reflect.ValueOf(j.data).Int(), nil 58 | case uint, uint8, uint16, uint32, uint64: 59 | return int64(reflect.ValueOf(j.data).Uint()), nil 60 | } 61 | return 0, errors.New("invalid value type") 62 | } 63 | 64 | // Uint64 coerces into an uint64 65 | func (j *Json) Uint64() (uint64, error) { 66 | switch j.data.(type) { 67 | case float32, float64: 68 | return uint64(reflect.ValueOf(j.data).Float()), nil 69 | case int, int8, int16, int32, int64: 70 | return uint64(reflect.ValueOf(j.data).Int()), nil 71 | case uint, uint8, uint16, uint32, uint64: 72 | return reflect.ValueOf(j.data).Uint(), nil 73 | } 74 | return 0, errors.New("invalid value type") 75 | } 76 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/internal/oauth2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "bufio" 10 | "crypto/rsa" 11 | "crypto/x509" 12 | "encoding/pem" 13 | "errors" 14 | "fmt" 15 | "io" 16 | "strings" 17 | ) 18 | 19 | // ParseKey converts the binary contents of a private key file 20 | // to an *rsa.PrivateKey. It detects whether the private key is in a 21 | // PEM container or not. If so, it extracts the the private key 22 | // from PEM container before conversion. It only supports PEM 23 | // containers with no passphrase. 24 | func ParseKey(key []byte) (*rsa.PrivateKey, error) { 25 | block, _ := pem.Decode(key) 26 | if block != nil { 27 | key = block.Bytes 28 | } 29 | parsedKey, err := x509.ParsePKCS8PrivateKey(key) 30 | if err != nil { 31 | parsedKey, err = x509.ParsePKCS1PrivateKey(key) 32 | if err != nil { 33 | return nil, fmt.Errorf("private key should be a PEM or plain PKSC1 or PKCS8; parse error: %v", err) 34 | } 35 | } 36 | parsed, ok := parsedKey.(*rsa.PrivateKey) 37 | if !ok { 38 | return nil, errors.New("private key is invalid") 39 | } 40 | return parsed, nil 41 | } 42 | 43 | func ParseINI(ini io.Reader) (map[string]map[string]string, error) { 44 | result := map[string]map[string]string{ 45 | "": map[string]string{}, // root section 46 | } 47 | scanner := bufio.NewScanner(ini) 48 | currentSection := "" 49 | for scanner.Scan() { 50 | line := strings.TrimSpace(scanner.Text()) 51 | if strings.HasPrefix(line, ";") { 52 | // comment. 53 | continue 54 | } 55 | if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { 56 | currentSection = strings.TrimSpace(line[1 : len(line)-1]) 57 | result[currentSection] = map[string]string{} 58 | continue 59 | } 60 | parts := strings.SplitN(line, "=", 2) 61 | if len(parts) == 2 && parts[0] != "" { 62 | result[currentSection][strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) 63 | } 64 | } 65 | if err := scanner.Err(); err != nil { 66 | return nil, fmt.Errorf("error scanning ini: %v", err) 67 | } 68 | return result, nil 69 | } 70 | 71 | func CondVal(v string) []string { 72 | if v == "" { 73 | return nil 74 | } 75 | return []string{v} 76 | } 77 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/transport_test.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | type tokenSource struct{ token *Token } 11 | 12 | func (t *tokenSource) Token() (*Token, error) { 13 | return t.token, nil 14 | } 15 | 16 | func TestTransportTokenSource(t *testing.T) { 17 | ts := &tokenSource{ 18 | token: &Token{ 19 | AccessToken: "abc", 20 | }, 21 | } 22 | tr := &Transport{ 23 | Source: ts, 24 | } 25 | server := newMockServer(func(w http.ResponseWriter, r *http.Request) { 26 | if r.Header.Get("Authorization") != "Bearer abc" { 27 | t.Errorf("Transport doesn't set the Authorization header from the fetched token") 28 | } 29 | }) 30 | defer server.Close() 31 | client := http.Client{Transport: tr} 32 | client.Get(server.URL) 33 | } 34 | 35 | // Test for case-sensitive token types, per https://github.com/golang/oauth2/issues/113 36 | func TestTransportTokenSourceTypes(t *testing.T) { 37 | const val = "abc" 38 | tests := []struct { 39 | key string 40 | val string 41 | want string 42 | }{ 43 | {key: "bearer", val: val, want: "Bearer abc"}, 44 | {key: "mac", val: val, want: "MAC abc"}, 45 | {key: "basic", val: val, want: "Basic abc"}, 46 | } 47 | for _, tc := range tests { 48 | ts := &tokenSource{ 49 | token: &Token{ 50 | AccessToken: tc.val, 51 | TokenType: tc.key, 52 | }, 53 | } 54 | tr := &Transport{ 55 | Source: ts, 56 | } 57 | server := newMockServer(func(w http.ResponseWriter, r *http.Request) { 58 | if got, want := r.Header.Get("Authorization"), tc.want; got != want { 59 | t.Errorf("Authorization header (%q) = %q; want %q", val, got, want) 60 | } 61 | }) 62 | defer server.Close() 63 | client := http.Client{Transport: tr} 64 | client.Get(server.URL) 65 | } 66 | } 67 | 68 | func TestTokenValidNoAccessToken(t *testing.T) { 69 | token := &Token{} 70 | if token.Valid() { 71 | t.Errorf("Token should not be valid with no access token") 72 | } 73 | } 74 | 75 | func TestExpiredWithExpiry(t *testing.T) { 76 | token := &Token{ 77 | Expiry: time.Now().Add(-5 * time.Hour), 78 | } 79 | if token.Valid() { 80 | t.Errorf("Token should not be valid if it expired in the past") 81 | } 82 | } 83 | 84 | func newMockServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server { 85 | return httptest.NewServer(http.HandlerFunc(handler)) 86 | } 87 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/BurntSushi/toml/cmd/toml-test-decoder/main.go: -------------------------------------------------------------------------------- 1 | // Command toml-test-decoder satisfies the toml-test interface for testing 2 | // TOML decoders. Namely, it accepts TOML on stdin and outputs JSON on stdout. 3 | package main 4 | 5 | import ( 6 | "encoding/json" 7 | "flag" 8 | "fmt" 9 | "log" 10 | "os" 11 | "path" 12 | "time" 13 | 14 | "github.com/BurntSushi/toml" 15 | ) 16 | 17 | func init() { 18 | log.SetFlags(0) 19 | 20 | flag.Usage = usage 21 | flag.Parse() 22 | } 23 | 24 | func usage() { 25 | log.Printf("Usage: %s < toml-file\n", path.Base(os.Args[0])) 26 | flag.PrintDefaults() 27 | 28 | os.Exit(1) 29 | } 30 | 31 | func main() { 32 | if flag.NArg() != 0 { 33 | flag.Usage() 34 | } 35 | 36 | var tmp interface{} 37 | if _, err := toml.DecodeReader(os.Stdin, &tmp); err != nil { 38 | log.Fatalf("Error decoding TOML: %s", err) 39 | } 40 | 41 | typedTmp := translate(tmp) 42 | if err := json.NewEncoder(os.Stdout).Encode(typedTmp); err != nil { 43 | log.Fatalf("Error encoding JSON: %s", err) 44 | } 45 | } 46 | 47 | func translate(tomlData interface{}) interface{} { 48 | switch orig := tomlData.(type) { 49 | case map[string]interface{}: 50 | typed := make(map[string]interface{}, len(orig)) 51 | for k, v := range orig { 52 | typed[k] = translate(v) 53 | } 54 | return typed 55 | case []map[string]interface{}: 56 | typed := make([]map[string]interface{}, len(orig)) 57 | for i, v := range orig { 58 | typed[i] = translate(v).(map[string]interface{}) 59 | } 60 | return typed 61 | case []interface{}: 62 | typed := make([]interface{}, len(orig)) 63 | for i, v := range orig { 64 | typed[i] = translate(v) 65 | } 66 | 67 | // We don't really need to tag arrays, but let's be future proof. 68 | // (If TOML ever supports tuples, we'll need this.) 69 | return tag("array", typed) 70 | case time.Time: 71 | return tag("datetime", orig.Format("2006-01-02T15:04:05Z")) 72 | case bool: 73 | return tag("bool", fmt.Sprintf("%v", orig)) 74 | case int64: 75 | return tag("integer", fmt.Sprintf("%d", orig)) 76 | case float64: 77 | return tag("float", fmt.Sprintf("%v", orig)) 78 | case string: 79 | return tag("string", orig) 80 | } 81 | 82 | panic(fmt.Sprintf("Unknown type: %T", tomlData)) 83 | } 84 | 85 | func tag(typeName string, data interface{}) map[string]interface{} { 86 | return map[string]interface{}{ 87 | "type": typeName, 88 | "value": data, 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/key/manager.go: -------------------------------------------------------------------------------- 1 | package key 2 | 3 | import ( 4 | "errors" 5 | "time" 6 | 7 | "github.com/jonboulle/clockwork" 8 | 9 | "github.com/coreos/go-oidc/jose" 10 | "github.com/coreos/pkg/health" 11 | ) 12 | 13 | type PrivateKeyManager interface { 14 | ExpiresAt() time.Time 15 | Signer() (jose.Signer, error) 16 | JWKs() ([]jose.JWK, error) 17 | PublicKeys() ([]PublicKey, error) 18 | 19 | WritableKeySetRepo 20 | health.Checkable 21 | } 22 | 23 | func NewPrivateKeyManager() PrivateKeyManager { 24 | return &privateKeyManager{ 25 | clock: clockwork.NewRealClock(), 26 | } 27 | } 28 | 29 | type privateKeyManager struct { 30 | keySet *PrivateKeySet 31 | clock clockwork.Clock 32 | } 33 | 34 | func (m *privateKeyManager) ExpiresAt() time.Time { 35 | if m.keySet == nil { 36 | return m.clock.Now().UTC() 37 | } 38 | 39 | return m.keySet.ExpiresAt() 40 | } 41 | 42 | func (m *privateKeyManager) Signer() (jose.Signer, error) { 43 | if err := m.Healthy(); err != nil { 44 | return nil, err 45 | } 46 | 47 | return m.keySet.Active().Signer(), nil 48 | } 49 | 50 | func (m *privateKeyManager) JWKs() ([]jose.JWK, error) { 51 | if err := m.Healthy(); err != nil { 52 | return nil, err 53 | } 54 | 55 | keys := m.keySet.Keys() 56 | jwks := make([]jose.JWK, len(keys)) 57 | for i, k := range keys { 58 | jwks[i] = k.JWK() 59 | } 60 | return jwks, nil 61 | } 62 | 63 | func (m *privateKeyManager) PublicKeys() ([]PublicKey, error) { 64 | jwks, err := m.JWKs() 65 | if err != nil { 66 | return nil, err 67 | } 68 | keys := make([]PublicKey, len(jwks)) 69 | for i, jwk := range jwks { 70 | keys[i] = *NewPublicKey(jwk) 71 | } 72 | return keys, nil 73 | } 74 | 75 | func (m *privateKeyManager) Healthy() error { 76 | if m.keySet == nil { 77 | return errors.New("private key manager uninitialized") 78 | } 79 | 80 | if len(m.keySet.Keys()) == 0 { 81 | return errors.New("private key manager zero keys") 82 | } 83 | 84 | if m.keySet.ExpiresAt().Before(m.clock.Now().UTC()) { 85 | return errors.New("private key manager keys expired") 86 | } 87 | 88 | return nil 89 | } 90 | 91 | func (m *privateKeyManager) Set(keySet KeySet) error { 92 | privKeySet, ok := keySet.(*PrivateKeySet) 93 | if !ok { 94 | return errors.New("unable to cast to PrivateKeySet") 95 | } 96 | 97 | m.keySet = privKeySet 98 | return nil 99 | } 100 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "sort" 9 | "strings" 10 | "sync" 11 | "time" 12 | 13 | "golang.org/x/net/context" 14 | "golang.org/x/oauth2" 15 | ) 16 | 17 | // Set at init time by appengine_hook.go. If nil, we're not on App Engine. 18 | var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error) 19 | 20 | // AppEngineTokenSource returns a token source that fetches tokens 21 | // issued to the current App Engine application's service account. 22 | // If you are implementing a 3-legged OAuth 2.0 flow on App Engine 23 | // that involves user accounts, see oauth2.Config instead. 24 | // 25 | // The provided context must have come from appengine.NewContext. 26 | func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { 27 | if appengineTokenFunc == nil { 28 | panic("google: AppEngineTokenSource can only be used on App Engine.") 29 | } 30 | scopes := append([]string{}, scope...) 31 | sort.Strings(scopes) 32 | return &appEngineTokenSource{ 33 | ctx: ctx, 34 | scopes: scopes, 35 | key: strings.Join(scopes, " "), 36 | } 37 | } 38 | 39 | // aeTokens helps the fetched tokens to be reused until their expiration. 40 | var ( 41 | aeTokensMu sync.Mutex 42 | aeTokens = make(map[string]*tokenLock) // key is space-separated scopes 43 | ) 44 | 45 | type tokenLock struct { 46 | mu sync.Mutex // guards t; held while fetching or updating t 47 | t *oauth2.Token 48 | } 49 | 50 | type appEngineTokenSource struct { 51 | ctx context.Context 52 | scopes []string 53 | key string // to aeTokens map; space-separated scopes 54 | } 55 | 56 | func (ts *appEngineTokenSource) Token() (*oauth2.Token, error) { 57 | if appengineTokenFunc == nil { 58 | panic("google: AppEngineTokenSource can only be used on App Engine.") 59 | } 60 | 61 | aeTokensMu.Lock() 62 | tok, ok := aeTokens[ts.key] 63 | if !ok { 64 | tok = &tokenLock{} 65 | aeTokens[ts.key] = tok 66 | } 67 | aeTokensMu.Unlock() 68 | 69 | tok.mu.Lock() 70 | defer tok.mu.Unlock() 71 | if tok.t.Valid() { 72 | return tok.t, nil 73 | } 74 | access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) 75 | if err != nil { 76 | return nil, err 77 | } 78 | tok.t = &oauth2.Token{ 79 | AccessToken: access, 80 | Expiry: exp, 81 | } 82 | return tok.t, nil 83 | } 84 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/wrap.go: -------------------------------------------------------------------------------- 1 | package text 2 | 3 | import ( 4 | "bytes" 5 | "math" 6 | ) 7 | 8 | var ( 9 | nl = []byte{'\n'} 10 | sp = []byte{' '} 11 | ) 12 | 13 | const defaultPenalty = 1e5 14 | 15 | // Wrap wraps s into a paragraph of lines of length lim, with minimal 16 | // raggedness. 17 | func Wrap(s string, lim int) string { 18 | return string(WrapBytes([]byte(s), lim)) 19 | } 20 | 21 | // WrapBytes wraps b into a paragraph of lines of length lim, with minimal 22 | // raggedness. 23 | func WrapBytes(b []byte, lim int) []byte { 24 | words := bytes.Split(bytes.Replace(bytes.TrimSpace(b), nl, sp, -1), sp) 25 | var lines [][]byte 26 | for _, line := range WrapWords(words, 1, lim, defaultPenalty) { 27 | lines = append(lines, bytes.Join(line, sp)) 28 | } 29 | return bytes.Join(lines, nl) 30 | } 31 | 32 | // WrapWords is the low-level line-breaking algorithm, useful if you need more 33 | // control over the details of the text wrapping process. For most uses, either 34 | // Wrap or WrapBytes will be sufficient and more convenient. 35 | // 36 | // WrapWords splits a list of words into lines with minimal "raggedness", 37 | // treating each byte as one unit, accounting for spc units between adjacent 38 | // words on each line, and attempting to limit lines to lim units. Raggedness 39 | // is the total error over all lines, where error is the square of the 40 | // difference of the length of the line and lim. Too-long lines (which only 41 | // happen when a single word is longer than lim units) have pen penalty units 42 | // added to the error. 43 | func WrapWords(words [][]byte, spc, lim, pen int) [][][]byte { 44 | n := len(words) 45 | 46 | length := make([][]int, n) 47 | for i := 0; i < n; i++ { 48 | length[i] = make([]int, n) 49 | length[i][i] = len(words[i]) 50 | for j := i + 1; j < n; j++ { 51 | length[i][j] = length[i][j-1] + spc + len(words[j]) 52 | } 53 | } 54 | 55 | nbrk := make([]int, n) 56 | cost := make([]int, n) 57 | for i := range cost { 58 | cost[i] = math.MaxInt32 59 | } 60 | for i := n - 1; i >= 0; i-- { 61 | if length[i][n-1] <= lim || i == n-1 { 62 | cost[i] = 0 63 | nbrk[i] = n 64 | } else { 65 | for j := i + 1; j < n; j++ { 66 | d := lim - length[i][j-1] 67 | c := d*d + cost[j] 68 | if length[i][j-1] > lim { 69 | c += pen // too-long lines get a worse penalty 70 | } 71 | if c < cost[i] { 72 | cost[i] = c 73 | nbrk[i] = j 74 | } 75 | } 76 | } 77 | } 78 | 79 | var lines [][][]byte 80 | i := 0 81 | for i < n { 82 | lines = append(lines, words[i:nbrk[i]]) 83 | i = nbrk[i] 84 | } 85 | return lines 86 | } 87 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/text/indent_test.go: -------------------------------------------------------------------------------- 1 | package text 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | type T struct { 9 | inp, exp, pre string 10 | } 11 | 12 | var tests = []T{ 13 | { 14 | "The quick brown fox\njumps over the lazy\ndog.\nBut not quickly.\n", 15 | "xxxThe quick brown fox\nxxxjumps over the lazy\nxxxdog.\nxxxBut not quickly.\n", 16 | "xxx", 17 | }, 18 | { 19 | "The quick brown fox\njumps over the lazy\ndog.\n\nBut not quickly.", 20 | "xxxThe quick brown fox\nxxxjumps over the lazy\nxxxdog.\n\nxxxBut not quickly.", 21 | "xxx", 22 | }, 23 | } 24 | 25 | func TestIndent(t *testing.T) { 26 | for _, test := range tests { 27 | got := Indent(test.inp, test.pre) 28 | if got != test.exp { 29 | t.Errorf("mismatch %q != %q", got, test.exp) 30 | } 31 | } 32 | } 33 | 34 | type IndentWriterTest struct { 35 | inp, exp string 36 | pre []string 37 | } 38 | 39 | var ts = []IndentWriterTest{ 40 | { 41 | ` 42 | The quick brown fox 43 | jumps over the lazy 44 | dog. 45 | But not quickly. 46 | `[1:], 47 | ` 48 | xxxThe quick brown fox 49 | xxxjumps over the lazy 50 | xxxdog. 51 | xxxBut not quickly. 52 | `[1:], 53 | []string{"xxx"}, 54 | }, 55 | { 56 | ` 57 | The quick brown fox 58 | jumps over the lazy 59 | dog. 60 | But not quickly. 61 | `[1:], 62 | ` 63 | xxaThe quick brown fox 64 | xxxjumps over the lazy 65 | xxxdog. 66 | xxxBut not quickly. 67 | `[1:], 68 | []string{"xxa", "xxx"}, 69 | }, 70 | { 71 | ` 72 | The quick brown fox 73 | jumps over the lazy 74 | dog. 75 | But not quickly. 76 | `[1:], 77 | ` 78 | xxaThe quick brown fox 79 | xxbjumps over the lazy 80 | xxcdog. 81 | xxxBut not quickly. 82 | `[1:], 83 | []string{"xxa", "xxb", "xxc", "xxx"}, 84 | }, 85 | { 86 | ` 87 | The quick brown fox 88 | jumps over the lazy 89 | dog. 90 | 91 | But not quickly.`[1:], 92 | ` 93 | xxaThe quick brown fox 94 | xxxjumps over the lazy 95 | xxxdog. 96 | xxx 97 | xxxBut not quickly.`[1:], 98 | []string{"xxa", "xxx"}, 99 | }, 100 | } 101 | 102 | func TestIndentWriter(t *testing.T) { 103 | for _, test := range ts { 104 | b := new(bytes.Buffer) 105 | pre := make([][]byte, len(test.pre)) 106 | for i := range test.pre { 107 | pre[i] = []byte(test.pre[i]) 108 | } 109 | w := NewIndentWriter(b, pre...) 110 | if _, err := w.Write([]byte(test.inp)); err != nil { 111 | t.Error(err) 112 | } 113 | if got := b.String(); got != test.exp { 114 | t.Errorf("mismatch %q != %q", got, test.exp) 115 | t.Log(got) 116 | t.Log(test.exp) 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/claims.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | type Claims map[string]interface{} 10 | 11 | func (c Claims) Add(name string, value interface{}) { 12 | c[name] = value 13 | } 14 | 15 | func (c Claims) StringClaim(name string) (string, bool, error) { 16 | cl, ok := c[name] 17 | if !ok { 18 | return "", false, nil 19 | } 20 | 21 | v, ok := cl.(string) 22 | if !ok { 23 | return "", false, fmt.Errorf("unable to parse claim as string: %v", name) 24 | } 25 | 26 | return v, true, nil 27 | } 28 | 29 | func (c Claims) StringsClaim(name string) ([]string, bool, error) { 30 | cl, ok := c[name] 31 | if !ok { 32 | return nil, false, nil 33 | } 34 | 35 | if v, ok := cl.([]string); ok { 36 | return v, true, nil 37 | } 38 | 39 | // When unmarshaled, []string will become []interface{}. 40 | if v, ok := cl.([]interface{}); ok { 41 | var ret []string 42 | for _, vv := range v { 43 | str, ok := vv.(string) 44 | if !ok { 45 | return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name) 46 | } 47 | ret = append(ret, str) 48 | } 49 | return ret, true, nil 50 | } 51 | 52 | return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name) 53 | } 54 | 55 | func (c Claims) Int64Claim(name string) (int64, bool, error) { 56 | cl, ok := c[name] 57 | if !ok { 58 | return 0, false, nil 59 | } 60 | 61 | v, ok := cl.(int64) 62 | if !ok { 63 | vf, ok := cl.(float64) 64 | if !ok { 65 | return 0, false, fmt.Errorf("unable to parse claim as int64: %v", name) 66 | } 67 | v = int64(vf) 68 | } 69 | 70 | return v, true, nil 71 | } 72 | 73 | func (c Claims) TimeClaim(name string) (time.Time, bool, error) { 74 | v, ok, err := c.Int64Claim(name) 75 | if !ok || err != nil { 76 | return time.Time{}, ok, err 77 | } 78 | 79 | return time.Unix(v, 0).UTC(), true, nil 80 | } 81 | 82 | func decodeClaims(payload []byte) (Claims, error) { 83 | var c Claims 84 | if err := json.Unmarshal(payload, &c); err != nil { 85 | return nil, fmt.Errorf("malformed JWT claims, unable to decode: %v", err) 86 | } 87 | return c, nil 88 | } 89 | 90 | func marshalClaims(c Claims) ([]byte, error) { 91 | b, err := json.Marshal(c) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return b, nil 96 | } 97 | 98 | func encodeClaims(c Claims) (string, error) { 99 | b, err := marshalClaims(c) 100 | if err != nil { 101 | return "", err 102 | } 103 | 104 | return encodeSegment(b), nil 105 | } 106 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ctxhttp provides helper functions for performing context-aware HTTP requests. 6 | package ctxhttp 7 | 8 | import ( 9 | "io" 10 | "net/http" 11 | "net/url" 12 | "strings" 13 | 14 | "golang.org/x/net/context" 15 | ) 16 | 17 | // Do sends an HTTP request with the provided http.Client and returns an HTTP response. 18 | // If the client is nil, http.DefaultClient is used. 19 | // If the context is canceled or times out, ctx.Err() will be returned. 20 | func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { 21 | if client == nil { 22 | client = http.DefaultClient 23 | } 24 | 25 | // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. 26 | cancel := canceler(client, req) 27 | 28 | type responseAndError struct { 29 | resp *http.Response 30 | err error 31 | } 32 | result := make(chan responseAndError, 1) 33 | 34 | go func() { 35 | resp, err := client.Do(req) 36 | result <- responseAndError{resp, err} 37 | }() 38 | 39 | select { 40 | case <-ctx.Done(): 41 | cancel() 42 | return nil, ctx.Err() 43 | case r := <-result: 44 | return r.resp, r.err 45 | } 46 | } 47 | 48 | // Get issues a GET request via the Do function. 49 | func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { 50 | req, err := http.NewRequest("GET", url, nil) 51 | if err != nil { 52 | return nil, err 53 | } 54 | return Do(ctx, client, req) 55 | } 56 | 57 | // Head issues a HEAD request via the Do function. 58 | func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { 59 | req, err := http.NewRequest("HEAD", url, nil) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return Do(ctx, client, req) 64 | } 65 | 66 | // Post issues a POST request via the Do function. 67 | func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { 68 | req, err := http.NewRequest("POST", url, body) 69 | if err != nil { 70 | return nil, err 71 | } 72 | req.Header.Set("Content-Type", bodyType) 73 | return Do(ctx, client, req) 74 | } 75 | 76 | // PostForm issues a POST request via the Do function. 77 | func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { 78 | return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) 79 | } 80 | -------------------------------------------------------------------------------- /validator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strings" 9 | "sync/atomic" 10 | "unsafe" 11 | ) 12 | 13 | type UserMap struct { 14 | usersFile string 15 | m unsafe.Pointer 16 | } 17 | 18 | func NewUserMap(usersFile string, done <-chan bool, onUpdate func()) *UserMap { 19 | um := &UserMap{usersFile: usersFile} 20 | m := make(map[string]bool) 21 | atomic.StorePointer(&um.m, unsafe.Pointer(&m)) 22 | if usersFile != "" { 23 | log.Printf("using authenticated emails file %s", usersFile) 24 | WatchForUpdates(usersFile, done, func() { 25 | um.LoadAuthenticatedEmailsFile() 26 | onUpdate() 27 | }) 28 | um.LoadAuthenticatedEmailsFile() 29 | } 30 | return um 31 | } 32 | 33 | func (um *UserMap) IsValid(email string) (result bool) { 34 | m := *(*map[string]bool)(atomic.LoadPointer(&um.m)) 35 | _, result = m[email] 36 | return 37 | } 38 | 39 | func (um *UserMap) LoadAuthenticatedEmailsFile() { 40 | r, err := os.Open(um.usersFile) 41 | if err != nil { 42 | log.Fatalf("failed opening authenticated-emails-file=%q, %s", um.usersFile, err) 43 | } 44 | defer r.Close() 45 | csv_reader := csv.NewReader(r) 46 | csv_reader.Comma = ',' 47 | csv_reader.Comment = '#' 48 | csv_reader.TrimLeadingSpace = true 49 | records, err := csv_reader.ReadAll() 50 | if err != nil { 51 | log.Printf("error reading authenticated-emails-file=%q, %s", um.usersFile, err) 52 | return 53 | } 54 | updated := make(map[string]bool) 55 | for _, r := range records { 56 | address := strings.ToLower(strings.TrimSpace(r[0])) 57 | updated[address] = true 58 | } 59 | atomic.StorePointer(&um.m, unsafe.Pointer(&updated)) 60 | } 61 | 62 | func newValidatorImpl(domains []string, usersFile string, 63 | done <-chan bool, onUpdate func()) func(string) bool { 64 | validUsers := NewUserMap(usersFile, done, onUpdate) 65 | 66 | var allowAll bool 67 | for i, domain := range domains { 68 | if domain == "*" { 69 | allowAll = true 70 | continue 71 | } 72 | domains[i] = fmt.Sprintf("@%s", strings.ToLower(domain)) 73 | } 74 | 75 | validator := func(email string) (valid bool) { 76 | if email == "" { 77 | return 78 | } 79 | email = strings.ToLower(email) 80 | for _, domain := range domains { 81 | valid = valid || strings.HasSuffix(email, domain) 82 | } 83 | if !valid { 84 | valid = validUsers.IsValid(email) 85 | } 86 | if allowAll { 87 | valid = true 88 | } 89 | return valid 90 | } 91 | return validator 92 | } 93 | 94 | func NewValidator(domains []string, usersFile string) func(string) bool { 95 | return newValidatorImpl(domains, usersFile, nil, func() {}) 96 | } 97 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/google_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import ( 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | var webJSONKey = []byte(` 13 | { 14 | "web": { 15 | "auth_uri": "https://google.com/o/oauth2/auth", 16 | "client_secret": "3Oknc4jS_wA2r9i", 17 | "token_uri": "https://google.com/o/oauth2/token", 18 | "client_email": "222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com", 19 | "redirect_uris": ["https://www.example.com/oauth2callback"], 20 | "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/222-nprqovg5k43uum874cs9osjt2koe97g8@developer.gserviceaccount.com", 21 | "client_id": "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com", 22 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 23 | "javascript_origins": ["https://www.example.com"] 24 | } 25 | }`) 26 | 27 | var installedJSONKey = []byte(`{ 28 | "installed": { 29 | "client_id": "222-installed.apps.googleusercontent.com", 30 | "redirect_uris": ["https://www.example.com/oauth2callback"] 31 | } 32 | }`) 33 | 34 | func TestConfigFromJSON(t *testing.T) { 35 | conf, err := ConfigFromJSON(webJSONKey, "scope1", "scope2") 36 | if err != nil { 37 | t.Error(err) 38 | } 39 | if got, want := conf.ClientID, "222-nprqovg5k43uum874cs9osjt2koe97g8.apps.googleusercontent.com"; got != want { 40 | t.Errorf("ClientID = %q; want %q", got, want) 41 | } 42 | if got, want := conf.ClientSecret, "3Oknc4jS_wA2r9i"; got != want { 43 | t.Errorf("ClientSecret = %q; want %q", got, want) 44 | } 45 | if got, want := conf.RedirectURL, "https://www.example.com/oauth2callback"; got != want { 46 | t.Errorf("RedictURL = %q; want %q", got, want) 47 | } 48 | if got, want := strings.Join(conf.Scopes, ","), "scope1,scope2"; got != want { 49 | t.Errorf("Scopes = %q; want %q", got, want) 50 | } 51 | if got, want := conf.Endpoint.AuthURL, "https://google.com/o/oauth2/auth"; got != want { 52 | t.Errorf("AuthURL = %q; want %q", got, want) 53 | } 54 | if got, want := conf.Endpoint.TokenURL, "https://google.com/o/oauth2/token"; got != want { 55 | t.Errorf("TokenURL = %q; want %q", got, want) 56 | } 57 | } 58 | 59 | func TestConfigFromJSON_Installed(t *testing.T) { 60 | conf, err := ConfigFromJSON(installedJSONKey) 61 | if err != nil { 62 | t.Error(err) 63 | } 64 | if got, want := conf.ClientID, "222-installed.apps.googleusercontent.com"; got != want { 65 | t.Errorf("ClientID = %q; want %q", got, want) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/pkg/capnslog/glog_formatter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 CoreOS, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package capnslog 16 | 17 | import ( 18 | "bufio" 19 | "bytes" 20 | "io" 21 | "os" 22 | "runtime" 23 | "strconv" 24 | "strings" 25 | "time" 26 | ) 27 | 28 | var pid = os.Getpid() 29 | 30 | type GlogFormatter struct { 31 | StringFormatter 32 | } 33 | 34 | func NewGlogFormatter(w io.Writer) *GlogFormatter { 35 | g := &GlogFormatter{} 36 | g.w = bufio.NewWriter(w) 37 | return g 38 | } 39 | 40 | func (g GlogFormatter) Format(pkg string, level LogLevel, depth int, entries ...interface{}) { 41 | g.w.Write(GlogHeader(level, depth+1)) 42 | g.StringFormatter.Format(pkg, level, depth+1, entries...) 43 | } 44 | 45 | func GlogHeader(level LogLevel, depth int) []byte { 46 | // Lmmdd hh:mm:ss.uuuuuu threadid file:line] 47 | now := time.Now().UTC() 48 | _, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call. 49 | if !ok { 50 | file = "???" 51 | line = 1 52 | } else { 53 | slash := strings.LastIndex(file, "/") 54 | if slash >= 0 { 55 | file = file[slash+1:] 56 | } 57 | } 58 | if line < 0 { 59 | line = 0 // not a real line number 60 | } 61 | buf := &bytes.Buffer{} 62 | buf.Grow(30) 63 | _, month, day := now.Date() 64 | hour, minute, second := now.Clock() 65 | buf.WriteString(level.Char()) 66 | twoDigits(buf, int(month)) 67 | twoDigits(buf, day) 68 | buf.WriteByte(' ') 69 | twoDigits(buf, hour) 70 | buf.WriteByte(':') 71 | twoDigits(buf, minute) 72 | buf.WriteByte(':') 73 | twoDigits(buf, second) 74 | buf.WriteByte('.') 75 | buf.WriteString(strconv.Itoa(now.Nanosecond() / 1000)) 76 | buf.WriteByte('Z') 77 | buf.WriteByte(' ') 78 | buf.WriteString(strconv.Itoa(pid)) 79 | buf.WriteByte(' ') 80 | buf.WriteString(file) 81 | buf.WriteByte(':') 82 | buf.WriteString(strconv.Itoa(line)) 83 | buf.WriteByte(']') 84 | buf.WriteByte(' ') 85 | return buf.Bytes() 86 | } 87 | 88 | const digits = "0123456789" 89 | 90 | func twoDigits(b *bytes.Buffer, d int) { 91 | c2 := digits[d%10] 92 | d /= 10 93 | c1 := digits[d%10] 94 | b.WriteByte(c1) 95 | b.WriteByte(c2) 96 | } 97 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/coreos/go-oidc/jose/jwt_test.go: -------------------------------------------------------------------------------- 1 | package jose 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestParseJWT(t *testing.T) { 9 | tests := []struct { 10 | r string 11 | h JOSEHeader 12 | c Claims 13 | }{ 14 | { 15 | // Example from JWT spec: 16 | // http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#ExampleJWT 17 | "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", 18 | JOSEHeader{ 19 | HeaderMediaType: "JWT", 20 | HeaderKeyAlgorithm: "HS256", 21 | }, 22 | Claims{ 23 | "iss": "joe", 24 | // NOTE: test numbers must be floats for equality checks to work since values are converted form interface{} to float64 by default. 25 | "exp": 1300819380.0, 26 | "http://example.com/is_root": true, 27 | }, 28 | }, 29 | } 30 | 31 | for i, tt := range tests { 32 | jwt, err := ParseJWT(tt.r) 33 | if err != nil { 34 | t.Errorf("raw token should parse. test: %d. expected: valid, actual: invalid. err=%v", i, err) 35 | } 36 | 37 | if !reflect.DeepEqual(tt.h, jwt.Header) { 38 | t.Errorf("JOSE headers should match. test: %d. expected: %v, actual: %v", i, tt.h, jwt.Header) 39 | } 40 | 41 | claims, err := jwt.Claims() 42 | if err != nil { 43 | t.Errorf("test: %d. expected: valid claim parsing. err=%v", i, err) 44 | } 45 | if !reflect.DeepEqual(tt.c, claims) { 46 | t.Errorf("claims should match. test: %d. expected: %v, actual: %v", i, tt.c, claims) 47 | } 48 | 49 | enc := jwt.Encode() 50 | if enc != tt.r { 51 | t.Errorf("encoded jwt should match raw jwt. test: %d. expected: %v, actual: %v", i, tt.r, enc) 52 | } 53 | } 54 | } 55 | 56 | func TestNewJWTHeaderTyp(t *testing.T) { 57 | jwt, err := NewJWT(JOSEHeader{}, Claims{}) 58 | if err != nil { 59 | t.Fatalf("Unexpected error: %v", err) 60 | } 61 | 62 | want := "JWT" 63 | got := jwt.Header[HeaderMediaType] 64 | if want != got { 65 | t.Fatalf("Header %q incorrect: want=%s got=%s", HeaderMediaType, want, got) 66 | } 67 | 68 | } 69 | 70 | func TestNewJWTHeaderKeyID(t *testing.T) { 71 | jwt, err := NewJWT(JOSEHeader{HeaderKeyID: "foo"}, Claims{}) 72 | if err != nil { 73 | t.Fatalf("Unexpected error: %v", err) 74 | } 75 | 76 | want := "foo" 77 | got, ok := jwt.KeyID() 78 | if !ok { 79 | t.Fatalf("KeyID not set") 80 | } else if want != got { 81 | t.Fatalf("KeyID incorrect: want=%s got=%s", want, got) 82 | } 83 | } 84 | 85 | func TestNewJWTHeaderKeyIDNotSet(t *testing.T) { 86 | jwt, err := NewJWT(JOSEHeader{}, Claims{}) 87 | if err != nil { 88 | t.Fatalf("Unexpected error: %v", err) 89 | } 90 | 91 | if _, ok := jwt.KeyID(); ok { 92 | t.Fatalf("KeyID set, but should not be") 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/simplejson_go11.go: -------------------------------------------------------------------------------- 1 | // +build go1.1 2 | 3 | package simplejson 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "errors" 9 | "io" 10 | "reflect" 11 | "strconv" 12 | ) 13 | 14 | // Implements the json.Unmarshaler interface. 15 | func (j *Json) UnmarshalJSON(p []byte) error { 16 | dec := json.NewDecoder(bytes.NewBuffer(p)) 17 | dec.UseNumber() 18 | return dec.Decode(&j.data) 19 | } 20 | 21 | // NewFromReader returns a *Json by decoding from an io.Reader 22 | func NewFromReader(r io.Reader) (*Json, error) { 23 | j := new(Json) 24 | dec := json.NewDecoder(r) 25 | dec.UseNumber() 26 | err := dec.Decode(&j.data) 27 | return j, err 28 | } 29 | 30 | // Float64 coerces into a float64 31 | func (j *Json) Float64() (float64, error) { 32 | switch j.data.(type) { 33 | case json.Number: 34 | return j.data.(json.Number).Float64() 35 | case float32, float64: 36 | return reflect.ValueOf(j.data).Float(), nil 37 | case int, int8, int16, int32, int64: 38 | return float64(reflect.ValueOf(j.data).Int()), nil 39 | case uint, uint8, uint16, uint32, uint64: 40 | return float64(reflect.ValueOf(j.data).Uint()), nil 41 | } 42 | return 0, errors.New("invalid value type") 43 | } 44 | 45 | // Int coerces into an int 46 | func (j *Json) Int() (int, error) { 47 | switch j.data.(type) { 48 | case json.Number: 49 | i, err := j.data.(json.Number).Int64() 50 | return int(i), err 51 | case float32, float64: 52 | return int(reflect.ValueOf(j.data).Float()), nil 53 | case int, int8, int16, int32, int64: 54 | return int(reflect.ValueOf(j.data).Int()), nil 55 | case uint, uint8, uint16, uint32, uint64: 56 | return int(reflect.ValueOf(j.data).Uint()), nil 57 | } 58 | return 0, errors.New("invalid value type") 59 | } 60 | 61 | // Int64 coerces into an int64 62 | func (j *Json) Int64() (int64, error) { 63 | switch j.data.(type) { 64 | case json.Number: 65 | return j.data.(json.Number).Int64() 66 | case float32, float64: 67 | return int64(reflect.ValueOf(j.data).Float()), nil 68 | case int, int8, int16, int32, int64: 69 | return reflect.ValueOf(j.data).Int(), nil 70 | case uint, uint8, uint16, uint32, uint64: 71 | return int64(reflect.ValueOf(j.data).Uint()), nil 72 | } 73 | return 0, errors.New("invalid value type") 74 | } 75 | 76 | // Uint64 coerces into an uint64 77 | func (j *Json) Uint64() (uint64, error) { 78 | switch j.data.(type) { 79 | case json.Number: 80 | return strconv.ParseUint(j.data.(json.Number).String(), 10, 64) 81 | case float32, float64: 82 | return uint64(reflect.ValueOf(j.data).Float()), nil 83 | case int, int8, int16, int32, int64: 84 | return uint64(reflect.ValueOf(j.data).Int()), nil 85 | case uint, uint8, uint16, uint32, uint64: 86 | return reflect.ValueOf(j.data).Uint(), nil 87 | } 88 | return 0, errors.New("invalid value type") 89 | } 90 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/bitly/go-simplejson/simplejson_go11_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.1 2 | 3 | package simplejson 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "github.com/bmizerany/assert" 9 | "strconv" 10 | "testing" 11 | ) 12 | 13 | func TestNewFromReader(t *testing.T) { 14 | //Use New Constructor 15 | buf := bytes.NewBuffer([]byte(`{ 16 | "test": { 17 | "array": [1, "2", 3], 18 | "arraywithsubs": [ 19 | {"subkeyone": 1}, 20 | {"subkeytwo": 2, "subkeythree": 3} 21 | ], 22 | "bignum": 9223372036854775807, 23 | "uint64": 18446744073709551615 24 | } 25 | }`)) 26 | js, err := NewFromReader(buf) 27 | 28 | //Standard Test Case 29 | assert.NotEqual(t, nil, js) 30 | assert.Equal(t, nil, err) 31 | 32 | arr, _ := js.Get("test").Get("array").Array() 33 | assert.NotEqual(t, nil, arr) 34 | for i, v := range arr { 35 | var iv int 36 | switch v.(type) { 37 | case json.Number: 38 | i64, err := v.(json.Number).Int64() 39 | assert.Equal(t, nil, err) 40 | iv = int(i64) 41 | case string: 42 | iv, _ = strconv.Atoi(v.(string)) 43 | } 44 | assert.Equal(t, i+1, iv) 45 | } 46 | 47 | ma := js.Get("test").Get("array").MustArray() 48 | assert.Equal(t, ma, []interface{}{json.Number("1"), "2", json.Number("3")}) 49 | 50 | mm := js.Get("test").Get("arraywithsubs").GetIndex(0).MustMap() 51 | assert.Equal(t, mm, map[string]interface{}{"subkeyone": json.Number("1")}) 52 | 53 | assert.Equal(t, js.Get("test").Get("bignum").MustInt64(), int64(9223372036854775807)) 54 | assert.Equal(t, js.Get("test").Get("uint64").MustUint64(), uint64(18446744073709551615)) 55 | } 56 | 57 | func TestSimplejsonGo11(t *testing.T) { 58 | js, err := NewJson([]byte(`{ 59 | "test": { 60 | "array": [1, "2", 3], 61 | "arraywithsubs": [ 62 | {"subkeyone": 1}, 63 | {"subkeytwo": 2, "subkeythree": 3} 64 | ], 65 | "bignum": 9223372036854775807, 66 | "uint64": 18446744073709551615 67 | } 68 | }`)) 69 | 70 | assert.NotEqual(t, nil, js) 71 | assert.Equal(t, nil, err) 72 | 73 | arr, _ := js.Get("test").Get("array").Array() 74 | assert.NotEqual(t, nil, arr) 75 | for i, v := range arr { 76 | var iv int 77 | switch v.(type) { 78 | case json.Number: 79 | i64, err := v.(json.Number).Int64() 80 | assert.Equal(t, nil, err) 81 | iv = int(i64) 82 | case string: 83 | iv, _ = strconv.Atoi(v.(string)) 84 | } 85 | assert.Equal(t, i+1, iv) 86 | } 87 | 88 | ma := js.Get("test").Get("array").MustArray() 89 | assert.Equal(t, ma, []interface{}{json.Number("1"), "2", json.Number("3")}) 90 | 91 | mm := js.Get("test").Get("arraywithsubs").GetIndex(0).MustMap() 92 | assert.Equal(t, mm, map[string]interface{}{"subkeyone": json.Number("1")}) 93 | 94 | assert.Equal(t, js.Get("test").Get("bignum").MustInt64(), int64(9223372036854775807)) 95 | assert.Equal(t, js.Get("test").Get("uint64").MustUint64(), uint64(18446744073709551615)) 96 | } 97 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/18F/hmacauth/.about.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # .about.yml project metadata 3 | # 4 | # Short name that acts as the project identifier (required) 5 | name: hmacauth 6 | 7 | # Full proper name of the project (required) 8 | full_name: HMAC Authentication package for Go 9 | 10 | # The type of content in the repo 11 | # values: app, docs, policy 12 | type: app 13 | 14 | # Describes whether a project team, working group/guild, etc. owns the repo (required) 15 | # values: guild, working-group, project 16 | owner_type: project 17 | 18 | # Name of the main project repo if this is a sub-repo; name of the working group/guild repo if this is a working group/guild subproject 19 | #parent: 20 | 21 | # Maturity stage of the project (required) 22 | # values: discovery, alpha, beta, live 23 | stage: discovery 24 | 25 | # Whether or not the project is actively maintained (required) 26 | # values: active, deprecated 27 | status: active 28 | 29 | # Description of the project 30 | description: > 31 | Signs and validates HTTP requests based on a shared-secret HMAC signature 32 | 33 | # Should be 'true' if the project has a continuous build (required) 34 | # values: true, false 35 | testable: true 36 | 37 | # Team members contributing to the project (required) 38 | # Items: 39 | # - github: GitHub user name 40 | # id: Internal team identifier/user name 41 | # role: Team member's role; leads should be designated as 'lead' 42 | team: 43 | - github: mbland 44 | role: lead 45 | 46 | # Partners for whom the project is developed 47 | #partners: 48 | #- 49 | 50 | # Brief descriptions of significant project developments 51 | #milestones: 52 | #- 53 | 54 | # Technologies used to build the project 55 | stack: 56 | - Go 57 | 58 | # Brief description of the project's outcomes 59 | #impact: 60 | 61 | # Services used to supply project status information 62 | # Items: 63 | # - name: Name of the service 64 | # category: Type of the service 65 | # url: URL for detailed information 66 | # badge: URL for the status badge 67 | #services: 68 | #- 69 | 70 | # Licenses that apply to the project and/or its components (required) 71 | # Items by property name pattern: 72 | # .*: 73 | # name: Name of the license from the Software Package Data Exchange (SPDX): https://spdx.org/licenses/ 74 | # url: URL for the text of the license 75 | licenses: 76 | hmacauth: 77 | name: CC0 78 | url: https://github.com/18F/hmacauth/blob/master/LICENSE.md 79 | 80 | # Blogs or websites associated with project development 81 | #blog: 82 | #- 83 | 84 | # Links to project artifacts 85 | # Items: 86 | # - url: URL for the link 87 | # text: Anchor text for the link 88 | #links: 89 | #- url: 90 | # text: 91 | 92 | # Email addresses of points-of-contact 93 | contact: 94 | - url: mailto:michael.bland@acm.org 95 | text: Mike Bland 96 | - url: https://github.com/18F/hmacauth/issues 97 | text: 18F/hmacauth issues 98 | -------------------------------------------------------------------------------- /providers/session_state_test.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | "time" 7 | 8 | "github.com/bitly/oauth2_proxy/cookie" 9 | "github.com/bmizerany/assert" 10 | ) 11 | 12 | const secret = "0123456789abcdefghijklmnopqrstuv" 13 | const altSecret = "0000000000abcdefghijklmnopqrstuv" 14 | 15 | func TestSessionStateSerialization(t *testing.T) { 16 | c, err := cookie.NewCipher([]byte(secret)) 17 | assert.Equal(t, nil, err) 18 | c2, err := cookie.NewCipher([]byte(altSecret)) 19 | assert.Equal(t, nil, err) 20 | s := &SessionState{ 21 | Email: "user@domain.com", 22 | AccessToken: "token1234", 23 | ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour), 24 | RefreshToken: "refresh4321", 25 | } 26 | encoded, err := s.EncodeSessionState(c) 27 | assert.Equal(t, nil, err) 28 | assert.Equal(t, 3, strings.Count(encoded, "|")) 29 | 30 | ss, err := DecodeSessionState(encoded, c) 31 | t.Logf("%#v", ss) 32 | assert.Equal(t, nil, err) 33 | assert.Equal(t, s.Email, ss.Email) 34 | assert.Equal(t, s.AccessToken, ss.AccessToken) 35 | assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix()) 36 | assert.Equal(t, s.RefreshToken, ss.RefreshToken) 37 | 38 | // ensure a different cipher can't decode properly (ie: it gets gibberish) 39 | ss, err = DecodeSessionState(encoded, c2) 40 | t.Logf("%#v", ss) 41 | assert.Equal(t, nil, err) 42 | assert.Equal(t, s.Email, ss.Email) 43 | assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix()) 44 | assert.NotEqual(t, s.AccessToken, ss.AccessToken) 45 | assert.NotEqual(t, s.RefreshToken, ss.RefreshToken) 46 | } 47 | 48 | func TestSessionStateSerializationNoCipher(t *testing.T) { 49 | 50 | s := &SessionState{ 51 | Email: "user@domain.com", 52 | AccessToken: "token1234", 53 | ExpiresOn: time.Now().Add(time.Duration(1) * time.Hour), 54 | RefreshToken: "refresh4321", 55 | } 56 | encoded, err := s.EncodeSessionState(nil) 57 | assert.Equal(t, nil, err) 58 | assert.Equal(t, s.Email, encoded) 59 | 60 | // only email should have been serialized 61 | ss, err := DecodeSessionState(encoded, nil) 62 | assert.Equal(t, nil, err) 63 | assert.Equal(t, s.Email, ss.Email) 64 | assert.Equal(t, "", ss.AccessToken) 65 | assert.Equal(t, "", ss.RefreshToken) 66 | } 67 | 68 | func TestSessionStateUserOrEmail(t *testing.T) { 69 | 70 | s := &SessionState{ 71 | Email: "user@domain.com", 72 | User: "just-user", 73 | } 74 | assert.Equal(t, "user@domain.com", s.userOrEmail()) 75 | s.Email = "" 76 | assert.Equal(t, "just-user", s.userOrEmail()) 77 | } 78 | 79 | func TestExpired(t *testing.T) { 80 | s := &SessionState{ExpiresOn: time.Now().Add(time.Duration(-1) * time.Minute)} 81 | assert.Equal(t, true, s.IsExpired()) 82 | 83 | s = &SessionState{ExpiresOn: time.Now().Add(time.Duration(1) * time.Minute)} 84 | assert.Equal(t, false, s.IsExpired()) 85 | 86 | s = &SessionState{} 87 | assert.Equal(t, false, s.IsExpired()) 88 | } 89 | --------------------------------------------------------------------------------