From c4e4ceb041bb82a76fe221b789aed1f5cbf07453 Mon Sep 17 00:00:00 2001 From: fydrah Date: Fri, 13 Jul 2018 20:45:44 +0200 Subject: [PATCH] v2.0.0 major update * Add Apache 2.0 LICENSE * Dependencies management * Code refactoring * Better example files * Cleaner config format * Real CLI (loginapp serve [configfile] * Support loglevel configuration * More debug (ex: middleware logger for incoming requests) * Exponential retry backoff when at startup when setting up provider * /healthz endpoint (for k8s) --> Check: provider is setup, provider availability * Move code to root directory, let keep things simple... * Remove useless alpine Docker image --- .gitignore | 2 + Dockerfile | 16 + Gopkg.lock | 121 + Gopkg.toml | 19 + LICENSE | 201 ++ Makefile | 25 +- README.md | 126 +- config.go | 88 + docker-compose.yml | 19 + dockerfiles/alpine/Dockerfile | 15 - dockerfiles/scratch/Dockerfile | 16 - example/config-dex.yaml | 35 + example/config-loginapp.yaml | 21 + example/config.yml | 10 - example/gencert.sh | 26 + example/ssl/ca-key.pem | 27 + example/ssl/ca.pem | 18 + example/ssl/ca.srl | 1 + example/ssl/cert.pem | 18 + example/ssl/csr.pem | 16 + example/ssl/key.pem | 27 + example/ssl/req.cnf | 13 + main.go | 354 +++ routes.go | 23 + src/loginapp/main.go | 324 -- src/loginapp/templates.go | 144 - templates.go | 108 + util.go | 50 + vendor/github.com/cenkalti/backoff/.gitignore | 22 + .../github.com/cenkalti/backoff/.travis.yml | 10 + vendor/github.com/cenkalti/backoff/LICENSE | 20 + vendor/github.com/cenkalti/backoff/README.md | 30 + vendor/github.com/cenkalti/backoff/backoff.go | 66 + vendor/github.com/cenkalti/backoff/context.go | 60 + .../cenkalti/backoff/exponential.go | 158 + vendor/github.com/cenkalti/backoff/retry.go | 78 + vendor/github.com/cenkalti/backoff/ticker.go | 84 + vendor/github.com/cenkalti/backoff/tries.go | 35 + vendor/github.com/coreos/go-oidc/.gitignore | 2 + vendor/github.com/coreos/go-oidc/.travis.yml | 16 + .../github.com/coreos/go-oidc/CONTRIBUTING.md | 71 + vendor/github.com/coreos/go-oidc/DCO | 36 + vendor/github.com/coreos/go-oidc/LICENSE | 202 ++ vendor/github.com/coreos/go-oidc/MAINTAINERS | 2 + vendor/github.com/coreos/go-oidc/NOTICE | 5 + vendor/github.com/coreos/go-oidc/README.md | 72 + .../coreos/go-oidc/code-of-conduct.md | 61 + vendor/github.com/coreos/go-oidc/jose.go | 20 + vendor/github.com/coreos/go-oidc/jwks.go | 228 ++ vendor/github.com/coreos/go-oidc/oidc.go | 374 +++ vendor/github.com/coreos/go-oidc/test | 16 + vendor/github.com/coreos/go-oidc/verify.go | 243 ++ vendor/github.com/golang/protobuf/AUTHORS | 3 + .../github.com/golang/protobuf/CONTRIBUTORS | 3 + vendor/github.com/golang/protobuf/LICENSE | 31 + .../github.com/golang/protobuf/proto/clone.go | 253 ++ .../golang/protobuf/proto/decode.go | 428 +++ .../golang/protobuf/proto/discard.go | 350 +++ .../golang/protobuf/proto/encode.go | 221 ++ .../github.com/golang/protobuf/proto/equal.go | 300 ++ .../golang/protobuf/proto/extensions.go | 543 ++++ .../github.com/golang/protobuf/proto/lib.go | 921 ++++++ .../golang/protobuf/proto/message_set.go | 314 ++ .../golang/protobuf/proto/pointer_reflect.go | 357 +++ .../golang/protobuf/proto/pointer_unsafe.go | 308 ++ .../golang/protobuf/proto/properties.go | 544 ++++ .../golang/protobuf/proto/table_marshal.go | 2681 ++++++++++++++++ .../golang/protobuf/proto/table_merge.go | 654 ++++ .../golang/protobuf/proto/table_unmarshal.go | 1967 ++++++++++++ .../github.com/golang/protobuf/proto/text.go | 843 +++++ .../golang/protobuf/proto/text_parser.go | 880 ++++++ .../julienschmidt/httprouter/.travis.yml | 8 + .../julienschmidt/httprouter/LICENSE | 24 + .../julienschmidt/httprouter/README.md | 323 ++ .../julienschmidt/httprouter/path.go | 123 + .../julienschmidt/httprouter/router.go | 363 +++ .../julienschmidt/httprouter/tree.go | 555 ++++ .../pquerna/cachecontrol/.travis.yml | 10 + .../github.com/pquerna/cachecontrol/LICENSE | 202 ++ .../github.com/pquerna/cachecontrol/README.md | 107 + vendor/github.com/pquerna/cachecontrol/api.go | 48 + .../cachecontrol/cacheobject/directive.go | 546 ++++ .../pquerna/cachecontrol/cacheobject/lex.go | 93 + .../cachecontrol/cacheobject/object.go | 387 +++ .../cachecontrol/cacheobject/reasons.go | 95 + .../cachecontrol/cacheobject/warning.go | 107 + vendor/github.com/pquerna/cachecontrol/doc.go | 25 + vendor/github.com/sirupsen/logrus/.gitignore | 1 + vendor/github.com/sirupsen/logrus/.travis.yml | 15 + .../github.com/sirupsen/logrus/CHANGELOG.md | 123 + vendor/github.com/sirupsen/logrus/LICENSE | 21 + vendor/github.com/sirupsen/logrus/README.md | 511 +++ vendor/github.com/sirupsen/logrus/alt_exit.go | 64 + .../github.com/sirupsen/logrus/appveyor.yml | 14 + vendor/github.com/sirupsen/logrus/doc.go | 26 + vendor/github.com/sirupsen/logrus/entry.go | 288 ++ vendor/github.com/sirupsen/logrus/exported.go | 193 ++ .../github.com/sirupsen/logrus/formatter.go | 45 + vendor/github.com/sirupsen/logrus/hooks.go | 34 + .../sirupsen/logrus/json_formatter.go | 79 + vendor/github.com/sirupsen/logrus/logger.go | 323 ++ vendor/github.com/sirupsen/logrus/logrus.go | 143 + .../sirupsen/logrus/terminal_bsd.go | 10 + .../logrus/terminal_check_appengine.go | 11 + .../logrus/terminal_check_notappengine.go | 19 + .../sirupsen/logrus/terminal_linux.go | 14 + .../sirupsen/logrus/text_formatter.go | 178 ++ vendor/github.com/sirupsen/logrus/writer.go | 62 + vendor/github.com/urfave/cli/.flake8 | 2 + vendor/github.com/urfave/cli/.gitignore | 2 + vendor/github.com/urfave/cli/.travis.yml | 27 + vendor/github.com/urfave/cli/CHANGELOG.md | 435 +++ vendor/github.com/urfave/cli/LICENSE | 21 + vendor/github.com/urfave/cli/README.md | 1381 ++++++++ vendor/github.com/urfave/cli/app.go | 497 +++ vendor/github.com/urfave/cli/appveyor.yml | 26 + vendor/github.com/urfave/cli/category.go | 44 + vendor/github.com/urfave/cli/cli.go | 22 + vendor/github.com/urfave/cli/command.go | 304 ++ vendor/github.com/urfave/cli/context.go | 278 ++ vendor/github.com/urfave/cli/errors.go | 115 + vendor/github.com/urfave/cli/flag-types.json | 93 + vendor/github.com/urfave/cli/flag.go | 799 +++++ .../github.com/urfave/cli/flag_generated.go | 627 ++++ vendor/github.com/urfave/cli/funcs.go | 28 + .../github.com/urfave/cli/generate-flag-types | 255 ++ vendor/github.com/urfave/cli/help.go | 338 ++ vendor/github.com/urfave/cli/runtests | 122 + vendor/golang.org/x/crypto/AUTHORS | 3 + vendor/golang.org/x/crypto/CONTRIBUTORS | 3 + vendor/golang.org/x/crypto/LICENSE | 27 + vendor/golang.org/x/crypto/PATENTS | 22 + vendor/golang.org/x/crypto/ed25519/ed25519.go | 188 ++ .../ed25519/internal/edwards25519/const.go | 1422 +++++++++ .../internal/edwards25519/edwards25519.go | 1793 +++++++++++ .../x/crypto/ssh/terminal/terminal.go | 951 ++++++ .../golang.org/x/crypto/ssh/terminal/util.go | 114 + .../x/crypto/ssh/terminal/util_bsd.go | 12 + .../x/crypto/ssh/terminal/util_linux.go | 10 + .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_solaris.go | 124 + .../x/crypto/ssh/terminal/util_windows.go | 103 + vendor/golang.org/x/net/AUTHORS | 3 + vendor/golang.org/x/net/CONTRIBUTORS | 3 + vendor/golang.org/x/net/LICENSE | 27 + vendor/golang.org/x/net/PATENTS | 22 + vendor/golang.org/x/net/context/context.go | 56 + .../x/net/context/ctxhttp/ctxhttp.go | 74 + .../x/net/context/ctxhttp/ctxhttp_pre17.go | 147 + vendor/golang.org/x/net/context/go17.go | 72 + vendor/golang.org/x/net/context/go19.go | 20 + vendor/golang.org/x/net/context/pre_go17.go | 300 ++ vendor/golang.org/x/net/context/pre_go19.go | 109 + vendor/golang.org/x/oauth2/.travis.yml | 13 + vendor/golang.org/x/oauth2/AUTHORS | 3 + vendor/golang.org/x/oauth2/CONTRIBUTING.md | 26 + vendor/golang.org/x/oauth2/CONTRIBUTORS | 3 + vendor/golang.org/x/oauth2/LICENSE | 27 + vendor/golang.org/x/oauth2/README.md | 77 + .../x/oauth2/internal/client_appengine.go | 13 + vendor/golang.org/x/oauth2/internal/doc.go | 6 + vendor/golang.org/x/oauth2/internal/oauth2.go | 37 + vendor/golang.org/x/oauth2/internal/token.go | 268 ++ .../golang.org/x/oauth2/internal/transport.go | 34 + vendor/golang.org/x/oauth2/oauth2.go | 353 +++ vendor/golang.org/x/oauth2/token.go | 175 ++ vendor/golang.org/x/oauth2/transport.go | 132 + vendor/golang.org/x/sys/AUTHORS | 3 + vendor/golang.org/x/sys/CONTRIBUTORS | 3 + vendor/golang.org/x/sys/LICENSE | 27 + vendor/golang.org/x/sys/PATENTS | 22 + vendor/golang.org/x/sys/unix/.gitignore | 2 + vendor/golang.org/x/sys/unix/README.md | 173 + .../golang.org/x/sys/unix/affinity_linux.go | 124 + vendor/golang.org/x/sys/unix/asm_darwin_386.s | 29 + .../golang.org/x/sys/unix/asm_darwin_amd64.s | 29 + vendor/golang.org/x/sys/unix/asm_darwin_arm.s | 30 + .../golang.org/x/sys/unix/asm_darwin_arm64.s | 30 + .../x/sys/unix/asm_dragonfly_amd64.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_386.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_freebsd_arm.s | 29 + vendor/golang.org/x/sys/unix/asm_linux_386.s | 65 + .../golang.org/x/sys/unix/asm_linux_amd64.s | 57 + vendor/golang.org/x/sys/unix/asm_linux_arm.s | 56 + .../golang.org/x/sys/unix/asm_linux_arm64.s | 52 + .../golang.org/x/sys/unix/asm_linux_mips64x.s | 56 + .../golang.org/x/sys/unix/asm_linux_mipsx.s | 54 + .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 56 + .../golang.org/x/sys/unix/asm_linux_s390x.s | 56 + vendor/golang.org/x/sys/unix/asm_netbsd_386.s | 29 + .../golang.org/x/sys/unix/asm_netbsd_amd64.s | 29 + vendor/golang.org/x/sys/unix/asm_netbsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_386.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_amd64.s | 29 + .../golang.org/x/sys/unix/asm_openbsd_arm.s | 29 + .../golang.org/x/sys/unix/asm_solaris_amd64.s | 17 + .../golang.org/x/sys/unix/bluetooth_linux.go | 35 + vendor/golang.org/x/sys/unix/cap_freebsd.go | 195 ++ vendor/golang.org/x/sys/unix/constants.go | 13 + vendor/golang.org/x/sys/unix/dev_darwin.go | 24 + vendor/golang.org/x/sys/unix/dev_dragonfly.go | 30 + vendor/golang.org/x/sys/unix/dev_freebsd.go | 30 + vendor/golang.org/x/sys/unix/dev_linux.go | 42 + vendor/golang.org/x/sys/unix/dev_netbsd.go | 29 + vendor/golang.org/x/sys/unix/dev_openbsd.go | 29 + vendor/golang.org/x/sys/unix/dirent.go | 17 + vendor/golang.org/x/sys/unix/endian_big.go | 9 + vendor/golang.org/x/sys/unix/endian_little.go | 9 + vendor/golang.org/x/sys/unix/env_unix.go | 31 + .../x/sys/unix/errors_freebsd_386.go | 227 ++ .../x/sys/unix/errors_freebsd_amd64.go | 227 ++ .../x/sys/unix/errors_freebsd_arm.go | 226 ++ vendor/golang.org/x/sys/unix/fcntl.go | 32 + .../x/sys/unix/fcntl_linux_32bit.go | 13 + vendor/golang.org/x/sys/unix/gccgo.go | 61 + vendor/golang.org/x/sys/unix/gccgo_c.c | 38 + .../x/sys/unix/gccgo_linux_amd64.go | 20 + vendor/golang.org/x/sys/unix/mkall.sh | 188 ++ vendor/golang.org/x/sys/unix/mkerrors.sh | 604 ++++ vendor/golang.org/x/sys/unix/mkpost.go | 98 + vendor/golang.org/x/sys/unix/mksyscall.pl | 341 ++ .../x/sys/unix/mksyscall_solaris.pl | 289 ++ .../golang.org/x/sys/unix/mksysctl_openbsd.pl | 264 ++ .../golang.org/x/sys/unix/mksysnum_darwin.pl | 39 + .../x/sys/unix/mksysnum_dragonfly.pl | 50 + .../golang.org/x/sys/unix/mksysnum_freebsd.pl | 50 + .../golang.org/x/sys/unix/mksysnum_netbsd.pl | 58 + .../golang.org/x/sys/unix/mksysnum_openbsd.pl | 50 + .../golang.org/x/sys/unix/openbsd_pledge.go | 38 + vendor/golang.org/x/sys/unix/pagesize_unix.go | 15 + vendor/golang.org/x/sys/unix/race.go | 30 + vendor/golang.org/x/sys/unix/race0.go | 25 + .../golang.org/x/sys/unix/sockcmsg_linux.go | 36 + vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 104 + vendor/golang.org/x/sys/unix/str.go | 26 + vendor/golang.org/x/sys/unix/syscall.go | 54 + vendor/golang.org/x/sys/unix/syscall_bsd.go | 624 ++++ .../golang.org/x/sys/unix/syscall_darwin.go | 680 ++++ .../x/sys/unix/syscall_darwin_386.go | 68 + .../x/sys/unix/syscall_darwin_amd64.go | 68 + .../x/sys/unix/syscall_darwin_arm.go | 66 + .../x/sys/unix/syscall_darwin_arm64.go | 68 + .../x/sys/unix/syscall_dragonfly.go | 523 ++++ .../x/sys/unix/syscall_dragonfly_amd64.go | 52 + .../golang.org/x/sys/unix/syscall_freebsd.go | 756 +++++ .../x/sys/unix/syscall_freebsd_386.go | 52 + .../x/sys/unix/syscall_freebsd_amd64.go | 52 + .../x/sys/unix/syscall_freebsd_arm.go | 52 + vendor/golang.org/x/sys/unix/syscall_linux.go | 1539 +++++++++ .../x/sys/unix/syscall_linux_386.go | 385 +++ .../x/sys/unix/syscall_linux_amd64.go | 162 + .../x/sys/unix/syscall_linux_amd64_gc.go | 13 + .../x/sys/unix/syscall_linux_arm.go | 259 ++ .../x/sys/unix/syscall_linux_arm64.go | 212 ++ .../golang.org/x/sys/unix/syscall_linux_gc.go | 14 + .../x/sys/unix/syscall_linux_gc_386.go | 16 + .../x/sys/unix/syscall_linux_gccgo_386.go | 30 + .../x/sys/unix/syscall_linux_gccgo_arm.go | 20 + .../x/sys/unix/syscall_linux_mips64x.go | 214 ++ .../x/sys/unix/syscall_linux_mipsx.go | 234 ++ .../x/sys/unix/syscall_linux_ppc64x.go | 131 + .../x/sys/unix/syscall_linux_s390x.go | 324 ++ .../x/sys/unix/syscall_linux_sparc64.go | 146 + .../golang.org/x/sys/unix/syscall_netbsd.go | 568 ++++ .../x/sys/unix/syscall_netbsd_386.go | 33 + .../x/sys/unix/syscall_netbsd_amd64.go | 33 + .../x/sys/unix/syscall_netbsd_arm.go | 33 + .../golang.org/x/sys/unix/syscall_openbsd.go | 368 +++ .../x/sys/unix/syscall_openbsd_386.go | 33 + .../x/sys/unix/syscall_openbsd_amd64.go | 37 + .../x/sys/unix/syscall_openbsd_arm.go | 33 + .../golang.org/x/sys/unix/syscall_solaris.go | 730 +++++ .../x/sys/unix/syscall_solaris_amd64.go | 23 + vendor/golang.org/x/sys/unix/syscall_unix.go | 394 +++ .../golang.org/x/sys/unix/syscall_unix_gc.go | 15 + vendor/golang.org/x/sys/unix/timestruct.go | 82 + vendor/golang.org/x/sys/unix/types_darwin.go | 277 ++ .../golang.org/x/sys/unix/types_dragonfly.go | 280 ++ vendor/golang.org/x/sys/unix/types_freebsd.go | 402 +++ vendor/golang.org/x/sys/unix/types_netbsd.go | 281 ++ vendor/golang.org/x/sys/unix/types_openbsd.go | 282 ++ vendor/golang.org/x/sys/unix/types_solaris.go | 283 ++ .../x/sys/unix/zerrors_darwin_386.go | 1783 +++++++++++ .../x/sys/unix/zerrors_darwin_amd64.go | 1783 +++++++++++ .../x/sys/unix/zerrors_darwin_arm.go | 1783 +++++++++++ .../x/sys/unix/zerrors_darwin_arm64.go | 1783 +++++++++++ .../x/sys/unix/zerrors_dragonfly_amd64.go | 1586 ++++++++++ .../x/sys/unix/zerrors_freebsd_386.go | 1764 +++++++++++ .../x/sys/unix/zerrors_freebsd_amd64.go | 1765 +++++++++++ .../x/sys/unix/zerrors_freebsd_arm.go | 1773 +++++++++++ .../x/sys/unix/zerrors_linux_386.go | 2602 +++++++++++++++ .../x/sys/unix/zerrors_linux_amd64.go | 2602 +++++++++++++++ .../x/sys/unix/zerrors_linux_arm.go | 2608 ++++++++++++++++ .../x/sys/unix/zerrors_linux_arm64.go | 2593 +++++++++++++++ .../x/sys/unix/zerrors_linux_mips.go | 2610 ++++++++++++++++ .../x/sys/unix/zerrors_linux_mips64.go | 2610 ++++++++++++++++ .../x/sys/unix/zerrors_linux_mips64le.go | 2610 ++++++++++++++++ .../x/sys/unix/zerrors_linux_mipsle.go | 2610 ++++++++++++++++ .../x/sys/unix/zerrors_linux_ppc64.go | 2663 ++++++++++++++++ .../x/sys/unix/zerrors_linux_ppc64le.go | 2663 ++++++++++++++++ .../x/sys/unix/zerrors_linux_s390x.go | 2662 ++++++++++++++++ .../x/sys/unix/zerrors_linux_sparc64.go | 2142 +++++++++++++ .../x/sys/unix/zerrors_netbsd_386.go | 1728 ++++++++++ .../x/sys/unix/zerrors_netbsd_amd64.go | 1718 ++++++++++ .../x/sys/unix/zerrors_netbsd_arm.go | 1707 ++++++++++ .../x/sys/unix/zerrors_openbsd_386.go | 1600 ++++++++++ .../x/sys/unix/zerrors_openbsd_amd64.go | 1706 ++++++++++ .../x/sys/unix/zerrors_openbsd_arm.go | 1602 ++++++++++ .../x/sys/unix/zerrors_solaris_amd64.go | 1497 +++++++++ .../golang.org/x/sys/unix/zptrace386_linux.go | 80 + .../golang.org/x/sys/unix/zptracearm_linux.go | 41 + .../x/sys/unix/zptracemips_linux.go | 50 + .../x/sys/unix/zptracemipsle_linux.go | 50 + .../x/sys/unix/zsyscall_darwin_386.go | 1712 ++++++++++ .../x/sys/unix/zsyscall_darwin_amd64.go | 1712 ++++++++++ .../x/sys/unix/zsyscall_darwin_arm.go | 1712 ++++++++++ .../x/sys/unix/zsyscall_darwin_arm64.go | 1712 ++++++++++ .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1508 +++++++++ .../x/sys/unix/zsyscall_freebsd_386.go | 1937 ++++++++++++ .../x/sys/unix/zsyscall_freebsd_amd64.go | 1937 ++++++++++++ .../x/sys/unix/zsyscall_freebsd_arm.go | 1937 ++++++++++++ .../x/sys/unix/zsyscall_linux_386.go | 2010 ++++++++++++ .../x/sys/unix/zsyscall_linux_amd64.go | 2177 +++++++++++++ .../x/sys/unix/zsyscall_linux_arm.go | 2112 +++++++++++++ .../x/sys/unix/zsyscall_linux_arm64.go | 2019 ++++++++++++ .../x/sys/unix/zsyscall_linux_mips.go | 2178 +++++++++++++ .../x/sys/unix/zsyscall_linux_mips64.go | 2161 +++++++++++++ .../x/sys/unix/zsyscall_linux_mips64le.go | 2161 +++++++++++++ .../x/sys/unix/zsyscall_linux_mipsle.go | 2178 +++++++++++++ .../x/sys/unix/zsyscall_linux_ppc64.go | 2224 +++++++++++++ .../x/sys/unix/zsyscall_linux_ppc64le.go | 2224 +++++++++++++ .../x/sys/unix/zsyscall_linux_s390x.go | 1994 ++++++++++++ .../x/sys/unix/zsyscall_linux_sparc64.go | 2172 +++++++++++++ .../x/sys/unix/zsyscall_netbsd_386.go | 1439 +++++++++ .../x/sys/unix/zsyscall_netbsd_amd64.go | 1439 +++++++++ .../x/sys/unix/zsyscall_netbsd_arm.go | 1439 +++++++++ .../x/sys/unix/zsyscall_openbsd_386.go | 1508 +++++++++ .../x/sys/unix/zsyscall_openbsd_amd64.go | 1508 +++++++++ .../x/sys/unix/zsyscall_openbsd_arm.go | 1508 +++++++++ .../x/sys/unix/zsyscall_solaris_amd64.go | 1697 ++++++++++ .../x/sys/unix/zsysctl_openbsd_386.go | 270 ++ .../x/sys/unix/zsysctl_openbsd_amd64.go | 257 ++ .../x/sys/unix/zsysctl_openbsd_arm.go | 270 ++ .../x/sys/unix/zsysnum_darwin_386.go | 436 +++ .../x/sys/unix/zsysnum_darwin_amd64.go | 436 +++ .../x/sys/unix/zsysnum_darwin_arm.go | 436 +++ .../x/sys/unix/zsysnum_darwin_arm64.go | 436 +++ .../x/sys/unix/zsysnum_dragonfly_amd64.go | 315 ++ .../x/sys/unix/zsysnum_freebsd_386.go | 353 +++ .../x/sys/unix/zsysnum_freebsd_amd64.go | 353 +++ .../x/sys/unix/zsysnum_freebsd_arm.go | 353 +++ .../x/sys/unix/zsysnum_linux_386.go | 390 +++ .../x/sys/unix/zsysnum_linux_amd64.go | 342 ++ .../x/sys/unix/zsysnum_linux_arm.go | 362 +++ .../x/sys/unix/zsysnum_linux_arm64.go | 286 ++ .../x/sys/unix/zsysnum_linux_mips.go | 375 +++ .../x/sys/unix/zsysnum_linux_mips64.go | 335 ++ .../x/sys/unix/zsysnum_linux_mips64le.go | 335 ++ .../x/sys/unix/zsysnum_linux_mipsle.go | 375 +++ .../x/sys/unix/zsysnum_linux_ppc64.go | 373 +++ .../x/sys/unix/zsysnum_linux_ppc64le.go | 373 +++ .../x/sys/unix/zsysnum_linux_s390x.go | 335 ++ .../x/sys/unix/zsysnum_linux_sparc64.go | 348 +++ .../x/sys/unix/zsysnum_netbsd_386.go | 274 ++ .../x/sys/unix/zsysnum_netbsd_amd64.go | 274 ++ .../x/sys/unix/zsysnum_netbsd_arm.go | 274 ++ .../x/sys/unix/zsysnum_openbsd_386.go | 207 ++ .../x/sys/unix/zsysnum_openbsd_amd64.go | 217 ++ .../x/sys/unix/zsysnum_openbsd_arm.go | 213 ++ .../x/sys/unix/ztypes_darwin_386.go | 489 +++ .../x/sys/unix/ztypes_darwin_amd64.go | 499 +++ .../x/sys/unix/ztypes_darwin_arm.go | 490 +++ .../x/sys/unix/ztypes_darwin_arm64.go | 499 +++ .../x/sys/unix/ztypes_dragonfly_amd64.go | 486 +++ .../x/sys/unix/ztypes_freebsd_386.go | 553 ++++ .../x/sys/unix/ztypes_freebsd_amd64.go | 556 ++++ .../x/sys/unix/ztypes_freebsd_arm.go | 556 ++++ .../golang.org/x/sys/unix/ztypes_linux_386.go | 1854 +++++++++++ .../x/sys/unix/ztypes_linux_amd64.go | 1874 +++++++++++ .../golang.org/x/sys/unix/ztypes_linux_arm.go | 1843 +++++++++++ .../x/sys/unix/ztypes_linux_arm64.go | 1853 +++++++++++ .../x/sys/unix/ztypes_linux_mips.go | 1848 +++++++++++ .../x/sys/unix/ztypes_linux_mips64.go | 1855 +++++++++++ .../x/sys/unix/ztypes_linux_mips64le.go | 1855 +++++++++++ .../x/sys/unix/ztypes_linux_mipsle.go | 1848 +++++++++++ .../x/sys/unix/ztypes_linux_ppc64.go | 1863 +++++++++++ .../x/sys/unix/ztypes_linux_ppc64le.go | 1863 +++++++++++ .../x/sys/unix/ztypes_linux_s390x.go | 1880 +++++++++++ .../x/sys/unix/ztypes_linux_sparc64.go | 690 ++++ .../x/sys/unix/ztypes_netbsd_386.go | 448 +++ .../x/sys/unix/ztypes_netbsd_amd64.go | 455 +++ .../x/sys/unix/ztypes_netbsd_arm.go | 453 +++ .../x/sys/unix/ztypes_openbsd_386.go | 484 +++ .../x/sys/unix/ztypes_openbsd_amd64.go | 484 +++ .../x/sys/unix/ztypes_openbsd_arm.go | 477 +++ .../x/sys/unix/ztypes_solaris_amd64.go | 459 +++ .../x/sys/windows/asm_windows_386.s | 13 + .../x/sys/windows/asm_windows_amd64.s | 13 + .../golang.org/x/sys/windows/dll_windows.go | 378 +++ .../golang.org/x/sys/windows/env_windows.go | 29 + vendor/golang.org/x/sys/windows/eventlog.go | 20 + .../golang.org/x/sys/windows/exec_windows.go | 97 + .../x/sys/windows/memory_windows.go | 26 + vendor/golang.org/x/sys/windows/mksyscall.go | 7 + vendor/golang.org/x/sys/windows/race.go | 30 + vendor/golang.org/x/sys/windows/race0.go | 25 + .../x/sys/windows/security_windows.go | 478 +++ vendor/golang.org/x/sys/windows/service.go | 183 ++ vendor/golang.org/x/sys/windows/str.go | 22 + vendor/golang.org/x/sys/windows/syscall.go | 74 + .../x/sys/windows/syscall_windows.go | 1153 +++++++ .../golang.org/x/sys/windows/types_windows.go | 1366 ++++++++ .../x/sys/windows/types_windows_386.go | 22 + .../x/sys/windows/types_windows_amd64.go | 22 + .../x/sys/windows/zsyscall_windows.go | 2700 ++++++++++++++++ vendor/google.golang.org/appengine/LICENSE | 202 ++ .../appengine/internal/api.go | 646 ++++ .../appengine/internal/api_classic.go | 159 + .../appengine/internal/api_common.go | 86 + .../appengine/internal/app_id.go | 28 + .../appengine/internal/base/api_base.pb.go | 133 + .../appengine/internal/base/api_base.proto | 33 + .../internal/datastore/datastore_v3.pb.go | 2778 +++++++++++++++++ .../internal/datastore/datastore_v3.proto | 541 ++++ .../appengine/internal/identity.go | 14 + .../appengine/internal/identity_classic.go | 27 + .../appengine/internal/identity_vm.go | 97 + .../appengine/internal/internal.go | 110 + .../appengine/internal/log/log_service.pb.go | 899 ++++++ .../appengine/internal/log/log_service.proto | 150 + .../appengine/internal/main.go | 15 + .../appengine/internal/main_vm.go | 44 + .../appengine/internal/metadata.go | 61 + .../appengine/internal/net.go | 56 + .../appengine/internal/regen.sh | 40 + .../internal/remote_api/remote_api.pb.go | 231 ++ .../internal/remote_api/remote_api.proto | 44 + .../appengine/internal/transaction.go | 107 + .../internal/urlfetch/urlfetch_service.pb.go | 355 +++ .../internal/urlfetch/urlfetch_service.proto | 64 + .../appengine/urlfetch/urlfetch.go | 210 ++ .../square/go-jose.v2/.gitcookies.sh.enc | 1 + vendor/gopkg.in/square/go-jose.v2/.gitignore | 7 + vendor/gopkg.in/square/go-jose.v2/.travis.yml | 48 + .../gopkg.in/square/go-jose.v2/BUG-BOUNTY.md | 10 + .../square/go-jose.v2/CONTRIBUTING.md | 14 + vendor/gopkg.in/square/go-jose.v2/LICENSE | 202 ++ vendor/gopkg.in/square/go-jose.v2/README.md | 120 + .../gopkg.in/square/go-jose.v2/asymmetric.go | 591 ++++ .../square/go-jose.v2/cipher/cbc_hmac.go | 196 ++ .../square/go-jose.v2/cipher/concat_kdf.go | 75 + .../square/go-jose.v2/cipher/ecdh_es.go | 62 + .../square/go-jose.v2/cipher/key_wrap.go | 109 + vendor/gopkg.in/square/go-jose.v2/crypter.go | 510 +++ vendor/gopkg.in/square/go-jose.v2/doc.go | 27 + vendor/gopkg.in/square/go-jose.v2/encoding.go | 178 ++ .../gopkg.in/square/go-jose.v2/json/LICENSE | 27 + .../gopkg.in/square/go-jose.v2/json/README.md | 13 + .../gopkg.in/square/go-jose.v2/json/decode.go | 1183 +++++++ .../gopkg.in/square/go-jose.v2/json/encode.go | 1197 +++++++ .../gopkg.in/square/go-jose.v2/json/indent.go | 141 + .../square/go-jose.v2/json/scanner.go | 623 ++++ .../gopkg.in/square/go-jose.v2/json/stream.go | 480 +++ .../gopkg.in/square/go-jose.v2/json/tags.go | 44 + vendor/gopkg.in/square/go-jose.v2/jwe.go | 291 ++ vendor/gopkg.in/square/go-jose.v2/jwk.go | 549 ++++ vendor/gopkg.in/square/go-jose.v2/jws.go | 321 ++ vendor/gopkg.in/square/go-jose.v2/shared.go | 470 +++ vendor/gopkg.in/square/go-jose.v2/signing.go | 372 +++ .../gopkg.in/square/go-jose.v2/symmetric.go | 360 +++ vendor/gopkg.in/yaml.v2/.travis.yml | 12 + vendor/gopkg.in/yaml.v2/LICENSE | 201 ++ vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 + vendor/gopkg.in/yaml.v2/NOTICE | 13 + vendor/gopkg.in/yaml.v2/README.md | 133 + vendor/gopkg.in/yaml.v2/apic.go | 739 +++++ vendor/gopkg.in/yaml.v2/decode.go | 775 +++++ vendor/gopkg.in/yaml.v2/emitterc.go | 1685 ++++++++++ vendor/gopkg.in/yaml.v2/encode.go | 362 +++ vendor/gopkg.in/yaml.v2/go.mod | 5 + vendor/gopkg.in/yaml.v2/parserc.go | 1095 +++++++ vendor/gopkg.in/yaml.v2/readerc.go | 412 +++ vendor/gopkg.in/yaml.v2/resolve.go | 258 ++ vendor/gopkg.in/yaml.v2/scannerc.go | 2696 ++++++++++++++++ vendor/gopkg.in/yaml.v2/sorter.go | 113 + vendor/gopkg.in/yaml.v2/writerc.go | 26 + vendor/gopkg.in/yaml.v2/yaml.go | 466 +++ vendor/gopkg.in/yaml.v2/yamlh.go | 738 +++++ vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 + 490 files changed, 225302 insertions(+), 531 deletions(-) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml create mode 100644 LICENSE create mode 100644 config.go create mode 100644 docker-compose.yml delete mode 100644 dockerfiles/alpine/Dockerfile delete mode 100644 dockerfiles/scratch/Dockerfile create mode 100644 example/config-dex.yaml create mode 100644 example/config-loginapp.yaml delete mode 100644 example/config.yml create mode 100755 example/gencert.sh create mode 100644 example/ssl/ca-key.pem create mode 100644 example/ssl/ca.pem create mode 100644 example/ssl/ca.srl create mode 100644 example/ssl/cert.pem create mode 100644 example/ssl/csr.pem create mode 100644 example/ssl/key.pem create mode 100644 example/ssl/req.cnf create mode 100644 main.go create mode 100644 routes.go delete mode 100644 src/loginapp/main.go delete mode 100644 src/loginapp/templates.go create mode 100644 templates.go create mode 100644 util.go create mode 100644 vendor/github.com/cenkalti/backoff/.gitignore create mode 100644 vendor/github.com/cenkalti/backoff/.travis.yml create mode 100644 vendor/github.com/cenkalti/backoff/LICENSE create mode 100644 vendor/github.com/cenkalti/backoff/README.md create mode 100644 vendor/github.com/cenkalti/backoff/backoff.go create mode 100644 vendor/github.com/cenkalti/backoff/context.go create mode 100644 vendor/github.com/cenkalti/backoff/exponential.go create mode 100644 vendor/github.com/cenkalti/backoff/retry.go create mode 100644 vendor/github.com/cenkalti/backoff/ticker.go create mode 100644 vendor/github.com/cenkalti/backoff/tries.go create mode 100644 vendor/github.com/coreos/go-oidc/.gitignore create mode 100644 vendor/github.com/coreos/go-oidc/.travis.yml create mode 100644 vendor/github.com/coreos/go-oidc/CONTRIBUTING.md create mode 100644 vendor/github.com/coreos/go-oidc/DCO create mode 100644 vendor/github.com/coreos/go-oidc/LICENSE create mode 100644 vendor/github.com/coreos/go-oidc/MAINTAINERS create mode 100644 vendor/github.com/coreos/go-oidc/NOTICE create mode 100644 vendor/github.com/coreos/go-oidc/README.md create mode 100644 vendor/github.com/coreos/go-oidc/code-of-conduct.md create mode 100644 vendor/github.com/coreos/go-oidc/jose.go create mode 100644 vendor/github.com/coreos/go-oidc/jwks.go create mode 100644 vendor/github.com/coreos/go-oidc/oidc.go create mode 100755 vendor/github.com/coreos/go-oidc/test create mode 100644 vendor/github.com/coreos/go-oidc/verify.go create mode 100644 vendor/github.com/golang/protobuf/AUTHORS create mode 100644 vendor/github.com/golang/protobuf/CONTRIBUTORS create mode 100644 vendor/github.com/golang/protobuf/LICENSE create mode 100644 vendor/github.com/golang/protobuf/proto/clone.go create mode 100644 vendor/github.com/golang/protobuf/proto/decode.go create mode 100644 vendor/github.com/golang/protobuf/proto/discard.go create mode 100644 vendor/github.com/golang/protobuf/proto/encode.go create mode 100644 vendor/github.com/golang/protobuf/proto/equal.go create mode 100644 vendor/github.com/golang/protobuf/proto/extensions.go create mode 100644 vendor/github.com/golang/protobuf/proto/lib.go create mode 100644 vendor/github.com/golang/protobuf/proto/message_set.go create mode 100644 vendor/github.com/golang/protobuf/proto/pointer_reflect.go create mode 100644 vendor/github.com/golang/protobuf/proto/pointer_unsafe.go create mode 100644 vendor/github.com/golang/protobuf/proto/properties.go create mode 100644 vendor/github.com/golang/protobuf/proto/table_marshal.go create mode 100644 vendor/github.com/golang/protobuf/proto/table_merge.go create mode 100644 vendor/github.com/golang/protobuf/proto/table_unmarshal.go create mode 100644 vendor/github.com/golang/protobuf/proto/text.go create mode 100644 vendor/github.com/golang/protobuf/proto/text_parser.go create mode 100644 vendor/github.com/julienschmidt/httprouter/.travis.yml create mode 100644 vendor/github.com/julienschmidt/httprouter/LICENSE create mode 100644 vendor/github.com/julienschmidt/httprouter/README.md create mode 100644 vendor/github.com/julienschmidt/httprouter/path.go create mode 100644 vendor/github.com/julienschmidt/httprouter/router.go create mode 100644 vendor/github.com/julienschmidt/httprouter/tree.go create mode 100644 vendor/github.com/pquerna/cachecontrol/.travis.yml create mode 100644 vendor/github.com/pquerna/cachecontrol/LICENSE create mode 100644 vendor/github.com/pquerna/cachecontrol/README.md create mode 100644 vendor/github.com/pquerna/cachecontrol/api.go create mode 100644 vendor/github.com/pquerna/cachecontrol/cacheobject/directive.go create mode 100644 vendor/github.com/pquerna/cachecontrol/cacheobject/lex.go create mode 100644 vendor/github.com/pquerna/cachecontrol/cacheobject/object.go create mode 100644 vendor/github.com/pquerna/cachecontrol/cacheobject/reasons.go create mode 100644 vendor/github.com/pquerna/cachecontrol/cacheobject/warning.go create mode 100644 vendor/github.com/pquerna/cachecontrol/doc.go create mode 100644 vendor/github.com/sirupsen/logrus/.gitignore create mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml create mode 100644 vendor/github.com/sirupsen/logrus/CHANGELOG.md create mode 100644 vendor/github.com/sirupsen/logrus/LICENSE create mode 100644 vendor/github.com/sirupsen/logrus/README.md create mode 100644 vendor/github.com/sirupsen/logrus/alt_exit.go create mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml create mode 100644 vendor/github.com/sirupsen/logrus/doc.go create mode 100644 vendor/github.com/sirupsen/logrus/entry.go create mode 100644 vendor/github.com/sirupsen/logrus/exported.go create mode 100644 vendor/github.com/sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/logger.go create mode 100644 vendor/github.com/sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_bsd.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_linux.go create mode 100644 vendor/github.com/sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/writer.go create mode 100644 vendor/github.com/urfave/cli/.flake8 create mode 100644 vendor/github.com/urfave/cli/.gitignore create mode 100644 vendor/github.com/urfave/cli/.travis.yml create mode 100644 vendor/github.com/urfave/cli/CHANGELOG.md create mode 100644 vendor/github.com/urfave/cli/LICENSE create mode 100644 vendor/github.com/urfave/cli/README.md create mode 100644 vendor/github.com/urfave/cli/app.go create mode 100644 vendor/github.com/urfave/cli/appveyor.yml create mode 100644 vendor/github.com/urfave/cli/category.go create mode 100644 vendor/github.com/urfave/cli/cli.go create mode 100644 vendor/github.com/urfave/cli/command.go create mode 100644 vendor/github.com/urfave/cli/context.go create mode 100644 vendor/github.com/urfave/cli/errors.go create mode 100644 vendor/github.com/urfave/cli/flag-types.json create mode 100644 vendor/github.com/urfave/cli/flag.go create mode 100644 vendor/github.com/urfave/cli/flag_generated.go create mode 100644 vendor/github.com/urfave/cli/funcs.go create mode 100755 vendor/github.com/urfave/cli/generate-flag-types create mode 100644 vendor/github.com/urfave/cli/help.go create mode 100755 vendor/github.com/urfave/cli/runtests create mode 100644 vendor/golang.org/x/crypto/AUTHORS create mode 100644 vendor/golang.org/x/crypto/CONTRIBUTORS create mode 100644 vendor/golang.org/x/crypto/LICENSE create mode 100644 vendor/golang.org/x/crypto/PATENTS create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_linux.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_windows.go create mode 100644 vendor/golang.org/x/net/AUTHORS create mode 100644 vendor/golang.org/x/net/CONTRIBUTORS create mode 100644 vendor/golang.org/x/net/LICENSE create mode 100644 vendor/golang.org/x/net/PATENTS create mode 100644 vendor/golang.org/x/net/context/context.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go create mode 100644 vendor/golang.org/x/net/context/go17.go create mode 100644 vendor/golang.org/x/net/context/go19.go create mode 100644 vendor/golang.org/x/net/context/pre_go17.go create mode 100644 vendor/golang.org/x/net/context/pre_go19.go create mode 100644 vendor/golang.org/x/oauth2/.travis.yml create mode 100644 vendor/golang.org/x/oauth2/AUTHORS create mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTING.md create mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTORS create mode 100644 vendor/golang.org/x/oauth2/LICENSE create mode 100644 vendor/golang.org/x/oauth2/README.md create mode 100644 vendor/golang.org/x/oauth2/internal/client_appengine.go create mode 100644 vendor/golang.org/x/oauth2/internal/doc.go create mode 100644 vendor/golang.org/x/oauth2/internal/oauth2.go create mode 100644 vendor/golang.org/x/oauth2/internal/token.go create mode 100644 vendor/golang.org/x/oauth2/internal/transport.go create mode 100644 vendor/golang.org/x/oauth2/oauth2.go create mode 100644 vendor/golang.org/x/oauth2/token.go create mode 100644 vendor/golang.org/x/oauth2/transport.go create mode 100644 vendor/golang.org/x/sys/AUTHORS create mode 100644 vendor/golang.org/x/sys/CONTRIBUTORS create mode 100644 vendor/golang.org/x/sys/LICENSE create mode 100644 vendor/golang.org/x/sys/PATENTS create mode 100644 vendor/golang.org/x/sys/unix/.gitignore create mode 100644 vendor/golang.org/x/sys/unix/README.md create mode 100644 vendor/golang.org/x/sys/unix/affinity_linux.go create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_darwin_arm64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_freebsd_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_arm64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mips64x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_mipsx.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_s390x.s create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_netbsd_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/asm_openbsd_arm.s create mode 100644 vendor/golang.org/x/sys/unix/asm_solaris_amd64.s create mode 100644 vendor/golang.org/x/sys/unix/bluetooth_linux.go create mode 100644 vendor/golang.org/x/sys/unix/cap_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/constants.go create mode 100644 vendor/golang.org/x/sys/unix/dev_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/dev_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/dev_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_linux.go create mode 100644 vendor/golang.org/x/sys/unix/dev_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/dev_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/dirent.go create mode 100644 vendor/golang.org/x/sys/unix/endian_big.go create mode 100644 vendor/golang.org/x/sys/unix/endian_little.go create mode 100644 vendor/golang.org/x/sys/unix/env_unix.go create mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/fcntl.go create mode 100644 vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go create mode 100644 vendor/golang.org/x/sys/unix/gccgo.go create mode 100644 vendor/golang.org/x/sys/unix/gccgo_c.c create mode 100644 vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go create mode 100755 vendor/golang.org/x/sys/unix/mkall.sh create mode 100755 vendor/golang.org/x/sys/unix/mkerrors.sh create mode 100644 vendor/golang.org/x/sys/unix/mkpost.go create mode 100755 vendor/golang.org/x/sys/unix/mksyscall.pl create mode 100755 vendor/golang.org/x/sys/unix/mksyscall_solaris.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysnum_darwin.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl create mode 100755 vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl create mode 100644 vendor/golang.org/x/sys/unix/openbsd_pledge.go create mode 100644 vendor/golang.org/x/sys/unix/pagesize_unix.go create mode 100644 vendor/golang.org/x/sys/unix/race.go create mode 100644 vendor/golang.org/x/sys/unix/race0.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_linux.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix.go create mode 100644 vendor/golang.org/x/sys/unix/str.go create mode 100644 vendor/golang.org/x/sys/unix/syscall.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_bsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_unix_gc.go create mode 100644 vendor/golang.org/x/sys/unix/timestruct.go create mode 100644 vendor/golang.org/x/sys/unix/types_darwin.go create mode 100644 vendor/golang.org/x/sys/unix/types_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/types_freebsd.go create mode 100644 vendor/golang.org/x/sys/unix/types_netbsd.go create mode 100644 vendor/golang.org/x/sys/unix/types_openbsd.go create mode 100644 vendor/golang.org/x/sys/unix/types_solaris.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zptrace386_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracearm_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracemips_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zptracemipsle_linux.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysctl_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go create mode 100644 vendor/golang.org/x/sys/windows/asm_windows_386.s create mode 100644 vendor/golang.org/x/sys/windows/asm_windows_amd64.s create mode 100644 vendor/golang.org/x/sys/windows/dll_windows.go create mode 100644 vendor/golang.org/x/sys/windows/env_windows.go create mode 100644 vendor/golang.org/x/sys/windows/eventlog.go create mode 100644 vendor/golang.org/x/sys/windows/exec_windows.go create mode 100644 vendor/golang.org/x/sys/windows/memory_windows.go create mode 100644 vendor/golang.org/x/sys/windows/mksyscall.go create mode 100644 vendor/golang.org/x/sys/windows/race.go create mode 100644 vendor/golang.org/x/sys/windows/race0.go create mode 100644 vendor/golang.org/x/sys/windows/security_windows.go create mode 100644 vendor/golang.org/x/sys/windows/service.go create mode 100644 vendor/golang.org/x/sys/windows/str.go create mode 100644 vendor/golang.org/x/sys/windows/syscall.go create mode 100644 vendor/golang.org/x/sys/windows/syscall_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_386.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_amd64.go create mode 100644 vendor/golang.org/x/sys/windows/zsyscall_windows.go create mode 100644 vendor/google.golang.org/appengine/LICENSE create mode 100644 vendor/google.golang.org/appengine/internal/api.go create mode 100644 vendor/google.golang.org/appengine/internal/api_classic.go create mode 100644 vendor/google.golang.org/appengine/internal/api_common.go create mode 100644 vendor/google.golang.org/appengine/internal/app_id.go create mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.proto create mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go create mode 100755 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto create mode 100644 vendor/google.golang.org/appengine/internal/identity.go create mode 100644 vendor/google.golang.org/appengine/internal/identity_classic.go create mode 100644 vendor/google.golang.org/appengine/internal/identity_vm.go create mode 100644 vendor/google.golang.org/appengine/internal/internal.go create mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.proto create mode 100644 vendor/google.golang.org/appengine/internal/main.go create mode 100644 vendor/google.golang.org/appengine/internal/main_vm.go create mode 100644 vendor/google.golang.org/appengine/internal/metadata.go create mode 100644 vendor/google.golang.org/appengine/internal/net.go create mode 100755 vendor/google.golang.org/appengine/internal/regen.sh create mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto create mode 100644 vendor/google.golang.org/appengine/internal/transaction.go create mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto create mode 100644 vendor/google.golang.org/appengine/urlfetch/urlfetch.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/.gitcookies.sh.enc create mode 100644 vendor/gopkg.in/square/go-jose.v2/.gitignore create mode 100644 vendor/gopkg.in/square/go-jose.v2/.travis.yml create mode 100644 vendor/gopkg.in/square/go-jose.v2/BUG-BOUNTY.md create mode 100644 vendor/gopkg.in/square/go-jose.v2/CONTRIBUTING.md create mode 100644 vendor/gopkg.in/square/go-jose.v2/LICENSE create mode 100644 vendor/gopkg.in/square/go-jose.v2/README.md create mode 100644 vendor/gopkg.in/square/go-jose.v2/asymmetric.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/cipher/concat_kdf.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/cipher/ecdh_es.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/cipher/key_wrap.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/crypter.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/doc.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/encoding.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/LICENSE create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/README.md create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/decode.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/encode.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/indent.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/scanner.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/stream.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/json/tags.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/jwe.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/jwk.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/jws.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/shared.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/signing.go create mode 100644 vendor/gopkg.in/square/go-jose.v2/symmetric.go create mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml create mode 100644 vendor/gopkg.in/yaml.v2/NOTICE create mode 100644 vendor/gopkg.in/yaml.v2/README.md create mode 100644 vendor/gopkg.in/yaml.v2/apic.go create mode 100644 vendor/gopkg.in/yaml.v2/decode.go create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v2/encode.go create mode 100644 vendor/gopkg.in/yaml.v2/go.mod create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81099bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dev.env +bin/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..661125d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:1.8-alpine3.6 AS build +ARG REPO=github.com/fydrah/loginapp + +RUN apk add --no-cache git build-base +ADD . /go/src/${REPO} +WORKDIR /go/src/${REPO} +RUN make build-static + +FROM scratch +ARG REPO=github.com/fydrah/loginapp +LABEL maintainer="Flavien Hardy " + +COPY --from=build /go/src/${REPO}/bin/loginapp-static /loginapp + +ENTRYPOINT ["/loginapp"] +CMD [""] diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..23d7f2e --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,121 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/cenkalti/backoff" + packages = ["."] + revision = "2ea60e5f094469f9e65adb9cd103795b73ae743e" + version = "v2.0.0" + +[[projects]] + name = "github.com/coreos/go-oidc" + packages = ["."] + revision = "1180514eaf4d9f38d0d19eef639a1d695e066e72" + version = "v2.0.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = ["proto"] + revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" + version = "v1.1.0" + +[[projects]] + name = "github.com/julienschmidt/httprouter" + packages = ["."] + revision = "8c199fb6259ffc1af525cc3ad52ee60ba8359669" + version = "v1.1" + +[[projects]] + branch = "master" + name = "github.com/pquerna/cachecontrol" + packages = [ + ".", + "cacheobject" + ] + revision = "1555304b9b35fdd2b425bccf1a5613677705e7d0" + +[[projects]] + name = "github.com/sirupsen/logrus" + packages = ["."] + revision = "c155da19408a8799da419ed3eeb0cb5db0ad5dbc" + version = "v1.0.5" + +[[projects]] + name = "github.com/urfave/cli" + packages = ["."] + revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" + version = "v1.20.0" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "ed25519", + "ed25519/internal/edwards25519", + "ssh/terminal" + ] + revision = "a3beeb748656e13e54256fd2cde19e058f41f60f" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "context/ctxhttp" + ] + revision = "dfa909b99c79129e1100513e5cd36307665e5723" + +[[projects]] + branch = "master" + name = "golang.org/x/oauth2" + packages = [ + ".", + "internal" + ] + revision = "770e5ebd4ab27c4d70b0983674d138217f5e2c72" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows" + ] + revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2" + +[[projects]] + name = "google.golang.org/appengine" + packages = [ + "internal", + "internal/base", + "internal/datastore", + "internal/log", + "internal/remote_api", + "internal/urlfetch", + "urlfetch" + ] + revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" + version = "v1.0.0" + +[[projects]] + name = "gopkg.in/square/go-jose.v2" + packages = [ + ".", + "cipher", + "json" + ] + revision = "76dd09796242edb5b897103a75df2645c028c960" + version = "v2.1.6" + +[[projects]] + name = "gopkg.in/yaml.v2" + packages = ["."] + revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" + version = "v2.2.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "0cfaaf0fd2bd5bf869ce07fe982a96fa178501ffd067e10d3d7a661b1f8f6ddb" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..55e0bf9 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,19 @@ +[[constraint]] + name = "github.com/coreos/go-oidc" + version = "2.0.0" + +[[constraint]] + name = "github.com/julienschmidt/httprouter" + version = "1.1.0" + +[[constraint]] + branch = "master" + name = "golang.org/x/oauth2" + +[[constraint]] + name = "gopkg.in/yaml.v2" + version = "2.2.1" + +[prune] + go-tests = true + unused-packages = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile index 1c5c899..6555071 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,23 @@ -all: - CGO_ENABLED=0 go build -a ./... +BINDIR := bin +GOFLAGS := +LDFLAGS := -w -s +DOCKER_REPOSITORY := quay.io/fydrah/loginapp +GIT_REPOSITORY := github.com/fydrah/loginapp +GIT_COMMIT_ID := $(shell git log -n 1 --pretty=format:%h) +DOCKERFILES := dockerfiles + +.PHONY: all +all: build + +.PHONY: build +build: + go build -o $(BINDIR)/loginapp $(GOFLAGS) -ldflags '$(LDFLAGS)' + +.PHONY: build-static +build-static: LDFLAGS += -extldflags "-static" +build-static: + CGO_ENABLED=0 go build -o $(BINDIR)/loginapp-static $(GOFLAGS) -ldflags '$(LDFLAGS)' + +.PHONY: docker-tmp +docker-tmp: + docker build -t $(DOCKER_REPOSITORY):$(GIT_COMMIT_ID) . diff --git a/README.md b/README.md index 37b207c..3e5c24a 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,125 @@ [![Docker Repository on Quay](https://quay.io/repository/fydrah/loginapp/status "Docker Repository on Quay")](https://quay.io/repository/fydrah/loginapp) -**Simple login application for Kubernetes & Dex** +**Simple login CLI application for Kubernetes & OIDC** Original source code from [coreos/dex repository](https://github.com/coreos/dex/tree/master/cmd/example-app) -## Dockerfiles +## Usage -* From scratch: ([scratch/Dockerfile](./dockerfiles/scratch/Dockerfile)) -* Alpine 3.6: ([alpine/Dockerfile](./dockerfiles/alpine/Dockerfile)) +```shell +NAME: + loginapp - Kube config application for OIDC -The default image available [here](https://quay.io/fydrah/loginapp) is built from scratch. +AUTHOR: + fydrah -## Usage +USAGE: + loginapp [global options] command [command options] -```shell -Usage: - loginapp [flags] +COMMANDS: + serve Run loginapp server + help, h Shows a list of commands or help for one command -Flags: - -h, --help help for loginapp +GLOBAL OPTIONS: + --help, -h show help + --version, -v print the version ``` -* Test: +## Configuration -```shell -# Update example/config.yml -# Test on local -docker run --rm -v $(pwd)/example/:/config/ quay.io/fydrah/loginapp: /config/config.yml +```yaml +# AppName +name: "Kubernetes Auth" +# Enable debug mode +debug: false +# Bind IP and port (format: "IP:PORT") +listen: "0.0.0.0:5555" +# OIDC relative configuration +oidc: + # Client configuration + client: + # Application ID + id: "loginapp" + # Application Secret + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + # Application Redirect URL + redirect_url: "https://127.0.0.1:5555/callback" + # Issuer configuration + issuer: + # Location of issuer root CA certificate + root_ca: "example/ssl/ca.pem" + # Issuer URL + url: "https://dex.example.com:5556" + # Extra scopes + extra_scopes: + - groups + # Enable offline scope + offline_as_scope: true + # Request token on behalf of other clients + cross_clients: [] +# Tls support +tls: + # Enable tls termination + enabled: true + # Certificate location + cert: example/ssl/cert.pem + # Key location + key: example/ssl/key.pem +# Logging configuration +log: + # Loglevel: debug|info|warning|error|fatal|panic + level: debug + # Log format: json|text + format: json ``` -* Kubernetes: +## Kubernetes + +This application is built to run on a Kubernetes cluster. You will find usage examples here: +* Helm: [Helm chart](https://github.com/ObjectifLibre/k8s-ldap/tree/master/charts/k8s-ldap) is available on ObjectifLibre/k8s-ldap repository. + +* Kubernetes: A full example is available on [ObjectifLibre/k8s-ldap repository](https://github.com/ObjectifLibre/k8s-ldap) + +## Dev + +* Setup Dex + +``` + # Configure github oauth secrets if needed. + # You must create an app in your github account before. + cat < dev.env +GITHUB_CLIENT_ID=yourclientid +GITHUB_CLIENT_SECRET=yoursecretid +EOF + # Configure hosts entry + echo "127.0.0.1 dex.example.com" | sudo tee -a /etc/hosts + docker-compose up -d +``` + +User: admin@example.com +Password: password + +* Manage dependencies + +Loginapp uses [golang dep](https://golang.github.io/dep/docs/installation.html). + +``` + # Update dependencies + dep ensure +``` + +* Compile, configure and run + +Configuration files are located in [example directory](./example/) + +``` + make + bin/loginapp serve example/config-loginapp.yaml +``` -A full example is available on [ObjectifLibre/k8s-ldap repository](https://github.com/ObjectifLibre/k8s-ldap) +## Contibutions -* Helm: +Contributions (and issues) are welcomed. -[Helm chart](https://github.com/ObjectifLibre/k8s-ldap/tree/master/charts/k8s-ldap) is also available on ObjectifLibre/k8s-ldap repository. +I started this project to learn golang, so you will surely find some weird stuff. Please let me know if some code could be improved. diff --git a/config.go b/config.go new file mode 100644 index 0000000..57b562e --- /dev/null +++ b/config.go @@ -0,0 +1,88 @@ +/* +Copyright 2018 fydrah + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "fmt" + "gopkg.in/yaml.v2" + "io/ioutil" + "strings" + "github.com/sirupsen/logrus" +) + +type AppConfig struct { + Name string `yaml:"name"` + Listen string `yaml:"listen"` + OIDC struct { + Client struct { + Id string `yaml:"id"` + Secret string `yaml:"secret"` + RedirectURL string `yaml:"redirect_url"` + } `yaml:"client"` + Issuer struct { + Url string `yaml:"url"` + RootCA string `yaml:"root_ca"` + } `yaml:"issuer"` + ExtraScopes []string `yaml:"extra_scopes"` + OfflineAsScope bool `yaml:"offline_as_scope"` + CrossClients []string `yaml:"cross_clients"` + } `yaml:"oidc"` + Tls struct { + Enabled bool `yaml:"enabled"` + Cert string `yaml:"cert"` + Key string `yaml:"key"` + } `yaml:"tls"` + Log struct { + Level string `yaml:"level"` + Format string `yaml:"format"` + } `yaml:"log"` +} + +func (a *AppConfig) Init(config string) error { + configData, err := ioutil.ReadFile(config) + if err != nil { + return fmt.Errorf("failed to read config file %s: %v", config, err) + } + if err := yaml.Unmarshal(configData, &a); err != nil { + return fmt.Errorf("error parse config file %s: %v", config, err) + } + switch f := strings.ToLower(a.Log.Format); f { + case "json": + logger.Formatter = &logrus.JSONFormatter{} + case "text": + logger.Formatter = &logrus.TextFormatter{} + default: + logger.Formatter = &logrus.JSONFormatter{} + logger.Warningf("Format %q not available, use json|text. Using json format", f) + } + logger.Debugf("Using %s log format", a.Log.Format) + switch f := strings.ToLower(a.Log.Level); f { + case "debug": + logger.Level = logrus.DebugLevel + case "info": + logger.Level = logrus.InfoLevel + case "warning": + logger.Level = logrus.WarnLevel + case "error": + logger.Level = logrus.ErrorLevel + default: + logger.Level = logrus.InfoLevel + logger.Warningf("Log level %q not available, use debug|info|warning|error. Using Info log level", f) + } + logger.Debugf("Using %s log level", a.Log.Format) + logger.Debugf("Configuration loaded: %+v", a) + return nil +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..50edbc5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +version: '2' +volumes: + dex: +services: + dex: + image: quay.io/coreos/dex:v2.10.0 + volumes: + - ./example/ssl:/ssl + - ./example/config-dex.yaml:/config.yaml + - dex:/var/dex/ + env_file: + - dev.env + command: + - serve + - /config.yaml + ports: + - 5556:5556 + extra_hosts: + - "dex.example.com:127.0.0.1" diff --git a/dockerfiles/alpine/Dockerfile b/dockerfiles/alpine/Dockerfile deleted file mode 100644 index 6c4fa04..0000000 --- a/dockerfiles/alpine/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM golang:1.8-alpine3.6 AS build - -RUN apk add --no-cache git build-base -ADD . /build/ -WORKDIR /build -RUN go get -d ./... -RUN make - -FROM alpine:3.6 -MAINTAINER Flavien Hardy - -COPY --from=build /build/loginapp / - -ENTRYPOINT ["/loginapp"] -CMD [""] diff --git a/dockerfiles/scratch/Dockerfile b/dockerfiles/scratch/Dockerfile deleted file mode 100644 index 054c52f..0000000 --- a/dockerfiles/scratch/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM golang:1.8-alpine3.6 AS build - -RUN apk add --no-cache git build-base -ADD . /build/ -WORKDIR /build -RUN go get -d ./... -RUN make - - -FROM scratch -MAINTAINER Flavien Hardy - -COPY --from=build /build/loginapp / - -ENTRYPOINT ["/loginapp"] -CMD [""] diff --git a/example/config-dex.yaml b/example/config-dex.yaml new file mode 100644 index 0000000..7f1bf2c --- /dev/null +++ b/example/config-dex.yaml @@ -0,0 +1,35 @@ +issuer: https://dex.example.com:5556 +storage: + type: sqlite3 + config: + file: /var/dex/dex.db +web: + https: 0.0.0.0:5556 + tlsCert: /ssl/cert.pem + tlsKey: /ssl/key.pem +connectors: +#- type: github +# id: github +# name: GitHub +# config: +# clientID: $GITHUB_CLIENT_ID +# clientSecret: $GITHUB_CLIENT_SECRET +# redirectURI: https://dex.example.com:5556/callback +oauth2: + skipApprovalScreen: true + +staticClients: +- id: loginapp + redirectURIs: + - 'https://127.0.0.1:5555/callback/cli' + - 'https://127.0.0.1:5555/callback/dashboard' + name: 'Loginapp' + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + +enablePasswordDB: true +staticPasswords: +- email: "admin@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" diff --git a/example/config-loginapp.yaml b/example/config-loginapp.yaml new file mode 100644 index 0000000..25c427f --- /dev/null +++ b/example/config-loginapp.yaml @@ -0,0 +1,21 @@ +name: "Kubernetes Auth" +listen: "0.0.0.0:5555" +oidc: + client: + id: "loginapp" + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + redirect_url: "https://127.0.0.1:5555/callback" + issuer: + root_ca: "example/ssl/ca.pem" + url: "https://dex.example.com:5556" + extra_scopes: + - groups + offline_as_scope: true + cross_clients: [] +tls: + enabled: true + cert: example/ssl/cert.pem + key: example/ssl/key.pem +log: + level: Debug + format: json diff --git a/example/config.yml b/example/config.yml deleted file mode 100644 index 931f0dd..0000000 --- a/example/config.yml +++ /dev/null @@ -1,10 +0,0 @@ -debug: false -client_id: "login" -client_secret: 4TORGiNV9M54BTk1v7dNuFSaI6hUjfjr -issuer_url: "https://dex.example.local/dex" -#issuer_root_ca: "/certs/ca.pem" -redirect_url: "https://login.example.local/callback" -listen: "http://0.0.0.0:8080" -disable_choices: false -extra_scopes: "groups" -app_name: "Kubernetes Auth" diff --git a/example/gencert.sh b/example/gencert.sh new file mode 100755 index 0000000..2263b6a --- /dev/null +++ b/example/gencert.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +mkdir -p ssl + +cat << EOF > ssl/req.cnf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = dex.example.com +EOF + +openssl genrsa -out ssl/ca-key.pem 2048 +openssl req -x509 -new -nodes -key ssl/ca-key.pem -days 3650 -out ssl/ca.pem -subj "/CN=kube-ca" + +openssl genrsa -out ssl/key.pem 2048 +openssl req -new -key ssl/key.pem -out ssl/csr.pem -subj "/CN=kube-ca" -config ssl/req.cnf +openssl x509 -req -in ssl/csr.pem -CA ssl/ca.pem -CAkey ssl/ca-key.pem -CAcreateserial -out ssl/cert.pem -days 3650 -extensions v3_req -extfile ssl/req.cnf diff --git a/example/ssl/ca-key.pem b/example/ssl/ca-key.pem new file mode 100644 index 0000000..715ebe2 --- /dev/null +++ b/example/ssl/ca-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzqf8QC/lJyGTbbpSS/6YlwERtOECT55s+NAMxv8y8H3QcI9d +vajNW+Kl66WDbwDF2DqLCCx5efaFuuEf/6/pnAF6Ag2iTwe23P2AinvQCiws7y+r +Hc2Tt8vs4sNpVrvxzAjMMoQE6HQEdRo9BE5c+C0trji8jjS/4U7H8DmQbRwuhIgv +ErS4ptIzxv1vA9cJiHLGKsShE5u13/5/Z0+VKF09LJAh0pIEiy7+zOpqn0AXECbo +IbdqoD4bGy+bfGw7YH/b9Bo3cyex7irJUGEgicjeOuW718KjhkWHiEvPQdZ6giBS +KAanxmkxIlMCgzUOgeEB3bT5pf1S/AVFsdSYIwIDAQABAoIBACFosPQjihVYbUAp +BhL5FuwapSUr1zbN8uoKoHYvXanZfTAlTU9TEdgP/SjqeiQg6Ns7I6zvm7fm7dm3 +eXfZlZe9+V6Jm7rREXQKm5RHzetHFwCYIT7RNFdbZXGHi+kUu1Nz/KcSBsUZtHrG +AiVHEeqhSyhGTd1jk722AcbJV5r7z8LZxOg3EodXl1FOx9Nf6JCBNob6SYvo1vY4 +hMwz7jU9cHxRFTIaTp13sx+rkh/glPkyYXoh6E8jegXQBwTwrUFoiF6/zaQYvjHt +lJezpHEIoI5PLcQw346lKsr97dUK+6/qTUAs+Ts5bKB/GmZ3Y6lH9LuOlf75A67L +2fH7dhECgYEA+P/j4AFOny0qfkqLzawTToHqakj8Hj67HcbP8WpoH56pUQIjckOY +YQZbUeKi4NGMyQ9dA3C9QRFznwBhLiIf+vCD01wQ4pD7Hh+7eevisxj0EEhtkh05 +22XVhKbMJypL/5qzj+rVBlqE1NvmVUBl0ZdQxiGHNE9ehk96TPk32DsCgYEA1HdW ++JdhJwUwkpkfSCG4R3JycWHAYT27iD8UuYLRgoJLIxe1jAkOKM3D7nVp4MDBqSYW +NLRf8pZb481v9NsdWQ6K+7uTN3TILQDqVQorWpoZUIvPXPGiFfcaOW+B6G/b11oA +v8NQSGDh4BUjzkDCxGDY6c/1xfosySafTGAMKTkCgYEAnOcaX+BS+6jJWxV8bRje +fZ0N6vWcsS5UWJocFIM5o5smFF7lmS4RCiqoRrwqaMKDFXsx4GYdS7BEjE//7MMi +Jc2DNB+SoEI9iyjxyQ0kKDk0KkKJkQYLnD3aQyGcCZ30j9ebCLgwjjVh+IOs69GN +l3njM0aTXRoadUYFyhVM5FsCgYBO7mLuCXb7Qw9PdvlLF9PZHyhq/NC2j3OK4zx0 +yqfA31zAlb9JXdfXytGeVhpWd+W6TD71p4j5m2hZ0elkwr49Zoy1hnLjqEvxhCSK +ITQH/bWn2bjYo5/+nwUsD0PosR2v/GzI0OuTaAKh99iMeDyjLgOHoU2CFjXrKKEH +g6sg6QKBgHdnTZvaGm93B5Px0s0IZV4f9IxaoOE5+DgQm8GthBunHIOo2hDE/OWy +JJAWjMQuQX8sYvuy/HB4ur1meaLNSS6577bMNjlAtlw5KtYlesroiX1CvOhT0t8G +AiDzZ6GtA6sg9wdDV4A9N6ZQ2otPdAl9g150CI7sk+W0OLVQAwfD +-----END RSA PRIVATE KEY----- diff --git a/example/ssl/ca.pem b/example/ssl/ca.pem new file mode 100644 index 0000000..5ca92bc --- /dev/null +++ b/example/ssl/ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgIJANHsBCXDOF6mMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB2t1YmUtY2EwHhcNMTgwNjA2MjE1NjA3WhcNMjgwNjAzMjE1NjA3WjASMRAw +DgYDVQQDDAdrdWJlLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +zqf8QC/lJyGTbbpSS/6YlwERtOECT55s+NAMxv8y8H3QcI9dvajNW+Kl66WDbwDF +2DqLCCx5efaFuuEf/6/pnAF6Ag2iTwe23P2AinvQCiws7y+rHc2Tt8vs4sNpVrvx +zAjMMoQE6HQEdRo9BE5c+C0trji8jjS/4U7H8DmQbRwuhIgvErS4ptIzxv1vA9cJ +iHLGKsShE5u13/5/Z0+VKF09LJAh0pIEiy7+zOpqn0AXECboIbdqoD4bGy+bfGw7 +YH/b9Bo3cyex7irJUGEgicjeOuW718KjhkWHiEvPQdZ6giBSKAanxmkxIlMCgzUO +geEB3bT5pf1S/AVFsdSYIwIDAQABo1AwTjAdBgNVHQ4EFgQUsXRitS+H/B6NslBB +Z76W5XSGDLcwHwYDVR0jBBgwFoAUsXRitS+H/B6NslBBZ76W5XSGDLcwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAuyRDjl4gKiGdZSfZWd3Trab/IX8C +EbaZUvejrWZ0CVg3o6BUxflw6bt+T4/3dgumf9Er/H9rmdKvpwN83nOLf2xNJV60 +ca2nYB5MLtUAcTRByaNNjKzY/gdhEqucZCrwqyk3GZuUbjb8iHQqxDtoQpb1tErs +l76wnunhQrA1yUgmf9jol2xQwiyOKu7iySC8R0msp4axjC7Vnc1e4Kh7V6g70AP2 +Or2pvl+SJxl+ZBP0uyUzdaEJLwY7BjhgMs6M1469u23ty7BelCTWyrydRcVs0E24 +mMlEwh0legPnKLcH/ahWfowsQhneZzdzsU1JolUZE9aFuuXmMVlbXQsVMw== +-----END CERTIFICATE----- diff --git a/example/ssl/ca.srl b/example/ssl/ca.srl new file mode 100644 index 0000000..a3c8e41 --- /dev/null +++ b/example/ssl/ca.srl @@ -0,0 +1 @@ +C87554A47EC4AD67 diff --git a/example/ssl/cert.pem b/example/ssl/cert.pem new file mode 100644 index 0000000..5d89ef3 --- /dev/null +++ b/example/ssl/cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIJAMh1VKR+xK1nMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV +BAMMB2t1YmUtY2EwHhcNMTgwNjA2MjE1NjA4WhcNMjgwNjAzMjE1NjA4WjASMRAw +DgYDVQQDDAdrdWJlLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +2uZ76YriDeYj5xPczdNwOg9JE2SBNZ1ZkHRD0wOdLOYOCTA2+8IU7c8gETMX3AbG +0CZINK7JfsKVuQVPHq/ajXS255niNmxaMAd5vy1g5HwKi0YJrshzQP3OLu/TNiWQ +HWKvnmTCTz+NnbtCIfSGA/dDlGymzrKlAViTleBtsI0+eHSTn+llSlM/9dutohgy ++V9iYPAXhUTJZwk/cvU2k4ah3xSaiWtYwPP3DAkGITetHFfO0no9a8+Hvxp61DCS +x526y6K0RzTpLHoFK5Dg+91doytLgxxdEtFs97QDBS3JoQ9a4HPc/JRQ78j4+Lo2 +iurRBF4FsbAkp2B6qJZ0UwIDAQABozYwNDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF +4DAaBgNVHREEEzARgg9kZXguZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEB +AL867yBXXI6SKtqrayUHmFlD9VT+iPE5aj0e7zPBNCNlebzmQCseYRfjk+GSF7EF +RRx+XzjMvDQ9k3UVPTAF6luk4DknQS2egm6z6aiNrIzGmB24ZTI0ZbdMp1U0N389 +VnIhR4Pknj9UWwwv6MY8HuA8F3LsDm5anjR/gUSoW5c76oA0KwgBlX4sUhG3v420 +lPDfIp3Hx0IZR+w3LAVVBa6H0yaB1Ov1+cAQgRS154XI3jRvPGTl7V0FFp6opVm1 +QHfhsdZT3TX7wf5AuqeOVYLb7HGTozBBin4qNQJ82YzseRFoGRbGVZeQaAkXgDOA +1TaYR/GK8SndrnDa0kB+dI8= +-----END CERTIFICATE----- diff --git a/example/ssl/csr.pem b/example/ssl/csr.pem new file mode 100644 index 0000000..2bd63cf --- /dev/null +++ b/example/ssl/csr.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICnDCCAYQCAQAwEjEQMA4GA1UEAwwHa3ViZS1jYTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANrme+mK4g3mI+cT3M3TcDoPSRNkgTWdWZB0Q9MDnSzm +DgkwNvvCFO3PIBEzF9wGxtAmSDSuyX7ClbkFTx6v2o10tueZ4jZsWjAHeb8tYOR8 +CotGCa7Ic0D9zi7v0zYlkB1ir55kwk8/jZ27QiH0hgP3Q5Rsps6ypQFYk5XgbbCN +Pnh0k5/pZUpTP/XbraIYMvlfYmDwF4VEyWcJP3L1NpOGod8UmolrWMDz9wwJBiE3 +rRxXztJ6PWvPh78aetQwksedusuitEc06Sx6BSuQ4PvdXaMrS4McXRLRbPe0AwUt +yaEPWuBz3PyUUO/I+Pi6Norq0QReBbGwJKdgeqiWdFMCAwEAAaBFMEMGCSqGSIb3 +DQEJDjE2MDQwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwGgYDVR0RBBMwEYIPZGV4 +LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQCYb0QAzo0GJjP8UciBJEMc +kKyQU72T727v74q2l5bRSZVPJdLsxGK0M0WAcbOfnexwpdzZn95cA1snkAqVOCGz +PDIsIk2aEWwjYRTNu1qCEpHhxZatDembjBRTlip+lS00LvSLgmsbYFGQYkZ3pfhT +kQ5qLIQnrSE12cb6smubd/li/uz0g4Yng70o9ZESEuIXa7ngHmTskJ7E7I8Qkkee +MSpSlbCg8t1mBIxcRjiMXkxLjIEC6lvab/aqfWo+/uoiRd1XJS5DXPVtJZEQ+jUY +yiGsfMKLXA1KIq0hv5od/T6fO4TXq+RU+096Bo4zSrrK7EoQft4pnW4XJ2HLnoSQ +-----END CERTIFICATE REQUEST----- diff --git a/example/ssl/key.pem b/example/ssl/key.pem new file mode 100644 index 0000000..b139fda --- /dev/null +++ b/example/ssl/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA2uZ76YriDeYj5xPczdNwOg9JE2SBNZ1ZkHRD0wOdLOYOCTA2 ++8IU7c8gETMX3AbG0CZINK7JfsKVuQVPHq/ajXS255niNmxaMAd5vy1g5HwKi0YJ +rshzQP3OLu/TNiWQHWKvnmTCTz+NnbtCIfSGA/dDlGymzrKlAViTleBtsI0+eHST +n+llSlM/9dutohgy+V9iYPAXhUTJZwk/cvU2k4ah3xSaiWtYwPP3DAkGITetHFfO +0no9a8+Hvxp61DCSx526y6K0RzTpLHoFK5Dg+91doytLgxxdEtFs97QDBS3JoQ9a +4HPc/JRQ78j4+Lo2iurRBF4FsbAkp2B6qJZ0UwIDAQABAoIBAQCllsUVneHy8a0n +GHdnnBLBWN7GtLipfiZKiCjmb01usXjcqoRtXhvG6XAwkp3x645p1wu4DqCOK1Rn +agS4Cf8iErBp8paU5NI0kvMeE43ASbUQNiMM/MVy3IwkJXd49mFWWVjQURhMKp9O +OmGEnhzi0yFkHezxX2JC6mZ6chOIAWqh7nu3/xHbANyvyUqcYFochmklc0tXcHHM +GjYJc+M5ElaG5ShKSCPVfnSNcjsQ2yHWfExTeKnBgvWy5a3OAUiqubhwDm9Py23S +gVRqV2Y7YmJrEOmrRjJj1YfOWi7RZ1APe2S1a9AkE2c8wplZzoTk4S2wGXt5JSVt +uFHB3mXBAoGBAO0V06QqQjVWYamoTMEkp/KIsGuIBINHWEpsH11uPaJpjy6Ndco3 +n7H+c9753C5SvMwsQE1BLNVR0cHv+MGhGmwKZWdmf5Qu6j6nGCBzwhLFFvG8bsVc +alfYweh4jtfDamUSsuaABzDLf06E3eFhgk3nyQP1JImNDzTiQrPHlIWFAoGBAOxd +QKc3OAL/H/BbKOqPec1dov8MVCGiCltjcwWmenToYOBfJrAEiwKv+0VTsxlPDAd4 +1qz8ZO0xLu+gT0j7UoM2VFvv54SSGgPNo3VeJQ75YoDRR3erwbBn/4L9S+7ClBW+ +A/I+tmyTDURuQUZ0hLYY4ForPLrhP5NYEZfQsG33AoGAG/EynGqOmxKvN/up8CmN +0bvibwn83iwOb9cGa1CO2xFt2qK5ezfLDoNazLDODneZ4MZmXbSMwCeAfUb3HnsK +Til7ghBGgQR2fyPaaBi8itHHvn3i4EfgELJvSCLNUwipBXiKtTfpoQqa2no2XFXN +sbjbrCe8QqnpXOY9zkp7arECgYEAvw0dTkvu5VUsjs5Qg1AXhuzx7DAd7NWag4Ye +GeoXv1l5vMKMdegmKLTwaHggIwvm0D9XXpngRmzj4GL20yn55v9KLsn6nAiwKHTW +c+72C2V+vlrq5osZUyqsuEdfUg1LP0vIyszwDVDLf42TC4zxHHN9HMUoIHIjPkkI +Z2sSwL8CgYEAgrjA2gvC/9EABU/z5NSPt4E5tN1nnN+0XOQ5PCErHTsYnvIp9y+h +8fWu9PNeklW51bXH9PulsCFVSZKhsFIgJVz2sHqVTrRGK4XO26XW+hU7Vxf+0lsH +rYPVbKnPD2Q70lSByryx9LQxDVajzNHvVHnMn8mVrTmJibODqirkxoE= +-----END RSA PRIVATE KEY----- diff --git a/example/ssl/req.cnf b/example/ssl/req.cnf new file mode 100644 index 0000000..60ad627 --- /dev/null +++ b/example/ssl/req.cnf @@ -0,0 +1,13 @@ +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = dex.example.com diff --git a/main.go b/main.go new file mode 100644 index 0000000..6375aa1 --- /dev/null +++ b/main.go @@ -0,0 +1,354 @@ +/* +Copyright 2018 fydrah + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Some code comes from @ericchiang (Dex - CoreOS) +package main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "github.com/coreos/go-oidc" + "github.com/julienschmidt/httprouter" + "golang.org/x/oauth2" + "net/http" + "os" + "github.com/urfave/cli" + "github.com/sirupsen/logrus" + "time" + "strings" + "github.com/cenkalti/backoff" +) + +var logger = logrus.New() + +/** + * Type def + */ +type Server struct { + client *http.Client + config AppConfig + provider *oidc.Provider + router *httprouter.Router + verifier *oidc.IDTokenVerifier + context context.Context +} + +type KubeUserInfo struct { + IDToken string + RefreshToken string + RedirectURL string + Claims interface{} + ClientSecret string +} + +/** + * OpenID + */ +func (s *Server) OAuth2Config(scopes []string, endpoint string) *oauth2.Config { + return &oauth2.Config{ + ClientID: s.config.OIDC.Client.Id, + ClientSecret: s.config.OIDC.Client.Secret, + RedirectURL: s.config.OIDC.Client.RedirectURL + "/" + endpoint, + Endpoint: s.provider.Endpoint(), + Scopes: scopes, + } +} + +func (s *Server) PrepareCallbackUrl(endpoint string) string { + // Prepare scopes + var ( + scopes []string + authCodeURL string + ) + + for _, extra_scope := range s.config.OIDC.ExtraScopes { + scopes = append(scopes, extra_scope) + } + // Prepare cross client auth + // see https://github.com/coreos/dex/blob/master/Documentation/custom-scopes-claims-clients.md + for _, cross_client := range s.config.OIDC.CrossClients { + scopes = append(scopes, "audience:server:client_id:"+cross_client) + } + + scopes = append(scopes, "openid", "profile", "email", "groups") + if s.config.OIDC.OfflineAsScope { + scopes = append(scopes, "offline_access") + authCodeURL = s.OAuth2Config(scopes, endpoint).AuthCodeURL(s.config.Name) + } else if !s.config.OIDC.OfflineAsScope { + authCodeURL = s.OAuth2Config(scopes, endpoint).AuthCodeURL(s.config.Name) + } else { + authCodeURL = s.OAuth2Config(scopes, endpoint).AuthCodeURL(s.config.Name, oauth2.AccessTypeOffline) + } + return authCodeURL +} + +/** + * Handlers + */ +func (s *Server) HandleGetIndex(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + renderTemplate(w, indexTmpl, s.config) +} + +func (s *Server) HandleGetHealthz(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + // Check if provider is setup + if s.provider == nil { + logger.Debug("Provider is not yet setup or anavailable") + w.WriteHeader(http.StatusServiceUnavailable) + return + } + // Check if our application can still contact the provider + wellKnown := strings.TrimSuffix(s.config.OIDC.Issuer.Url, "/") + "/.well-known/openid-configuration" + _, err := s.client.Head(wellKnown) + if err != nil { + logger.Debugf("Error while checking provider access: %v", err) + w.WriteHeader(http.StatusServiceUnavailable) + return + } + // Should we add more checks ? + w.WriteHeader(http.StatusOK) +} + +func (s *Server) HandlePostLogin(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + switch r.FormValue("access") { + case "CLI": + http.Redirect(w, r, s.PrepareCallbackUrl("cli"), http.StatusSeeOther) + } +} + +func (s *Server) HandleGetCallbackCLI(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + k, err := s.ProcessCallback(w, r, "cli") + if err != nil { + logger.Errorf("error handling cli callback: %v", err) + return + } + renderTemplate(w, tokenTmpl, k) +} + +func (s *Server) ProcessCallback(w http.ResponseWriter, r *http.Request, c string) (KubeUserInfo, error) { + var ( + err error + token *oauth2.Token + json_claims map[string]interface{} + ) + oauth2Config := s.OAuth2Config(nil, c) + + // Authorization redirect callback from OAuth2 auth flow. + if errMsg := r.FormValue("error"); errMsg != "" { + msg := fmt.Sprintf("%v: %v", errMsg, r.FormValue("error_description")) + http.Error(w, msg, http.StatusBadRequest) + return KubeUserInfo{}, fmt.Errorf(msg) + } + code := r.FormValue("code") + if code == "" { + msg := fmt.Sprintf("no code in request: %q", r.Form) + http.Error(w, msg, http.StatusBadRequest) + return KubeUserInfo{}, fmt.Errorf(msg) + } + if state := r.FormValue("state"); state != s.config.Name { + msg := fmt.Sprintf("expected state %q got %q", s.config.Name, state) + http.Error(w, msg, http.StatusBadRequest) + return KubeUserInfo{}, fmt.Errorf(msg) + } + token, err = oauth2Config.Exchange(s.context, code) + if err != nil { + msg := fmt.Sprintf("failed to get token: %v", err) + http.Error(w, msg, http.StatusInternalServerError) + return KubeUserInfo{}, fmt.Errorf(msg) + } + rawIDToken, ok := token.Extra("id_token").(string) + if !ok { + msg := "no id_token in token response" + http.Error(w, msg, http.StatusInternalServerError) + return KubeUserInfo{}, fmt.Errorf(msg) + } + idToken, err := s.verifier.Verify(r.Context(), rawIDToken) + if err != nil { + msg := fmt.Sprintf("Failed to verify ID token: %v", err) + http.Error(w, msg, http.StatusInternalServerError) + return KubeUserInfo{}, fmt.Errorf(msg) + } + var claims json.RawMessage + if err := idToken.Claims(&claims); err != nil { + return KubeUserInfo{}, fmt.Errorf("Failed to unmarshal claims from idToken: %v", err) + } + buff := new(bytes.Buffer) + json.Indent(buff, []byte(claims), "", " ") + if err := json.Unmarshal(claims, &json_claims); err != nil { + panic(err) + } + return KubeUserInfo{ + IDToken: rawIDToken, + RefreshToken: token.RefreshToken, + RedirectURL: oauth2Config.RedirectURL, + Claims: json_claims, + ClientSecret: s.config.OIDC.Client.Secret, + }, nil +} + +/** + * Logging middleware + * + * Log every request for Info loglevel only + */ +func loggingHandler(next http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + t1 := time.Now() + next.ServeHTTP(w, r) + t2 := time.Now() + logger.WithFields(logrus.Fields{ + "method": r.Method, + "path": r.URL.String(), + "request_duration": fmt.Sprintf("%s",t2.Sub(t1)), + "protocol": r.Proto, + "remote_address": r.RemoteAddr, + }).Info() + } + return http.HandlerFunc(fn) +} + +/** + * Run + */ +func (s *Server) Run() error { + var ( + provider *oidc.Provider + backoffErr error + ) + // router setup + s.router = httprouter.New() + s.Routes() + // client setup + if s.client == nil { + client, err := httpClientForRootCAs(s.config.OIDC.Issuer.RootCA) + if err != nil { + return err + } + s.client = client + } + // OIDC setup + // Retry with backoff + s.context = oidc.ClientContext(context.Background(), s.client) + setupProvider := func() error { + if provider, backoffErr = oidc.NewProvider(s.context, s.config.OIDC.Issuer.Url); backoffErr != nil { + logger.Errorf("Failed to query provider %q: %v", s.config.OIDC.Issuer.Url, backoffErr) + return backoffErr + } + return nil + } + //provider, err := oidc.NewProvider(s.context, s.config.OIDC.Issuer.Url) + if err := backoff.Retry(setupProvider, backoff.NewExponentialBackOff()); err != nil { + return err + } + var ss struct { + // What scopes does a provider support? + // + // See: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata + ScopesSupported []string `json:"scopes_supported"` + } + if err := provider.Claims(&ss); err != nil { + return fmt.Errorf("Failed to parse provider scopes_supported: %v", err) + } + + if len(ss.ScopesSupported) == 0 { + // scopes_supported is a "RECOMMENDED" discovery claim, not a required + // one. If missing, assume that the provider follows the spec and has + // an "offline_access" scope. + s.config.OIDC.OfflineAsScope = true + } else { + // See if scopes_supported has the "offline_access" scope. + s.config.OIDC.OfflineAsScope = func() bool { + for _, scope := range ss.ScopesSupported { + if scope == oidc.ScopeOfflineAccess { + return true + } + } + return false + }() + } + + s.provider = provider + s.verifier = provider.Verifier(&oidc.Config{ClientID: s.config.OIDC.Client.Id}) + + // Run + if s.config.Tls.Enabled { + logger.Infof("listening on https://%s", s.config.Listen) + if err := fmt.Errorf("%v", http.ListenAndServeTLS(s.config.Listen, s.config.Tls.Cert, s.config.Tls.Key, loggingHandler(s.router))); err != nil { + return err + } + } else { + logger.Infof("listening on http://%s", s.config.Listen) + if err := fmt.Errorf("%v", http.ListenAndServe(s.config.Listen, loggingHandler(s.router))); err != nil { + return err + } + } + return nil +} + +func main() { + app := cli.NewApp() + cli.AppHelpTemplate = ` +NAME: + {{.Name}} - {{.UsageText}} +{{if len .Authors}} +AUTHOR: + {{range .Authors}}{{ . }}{{end}} +{{end}} +USAGE: + {{.HelpName}}{{if .VisibleFlags}} [global options]{{end}}{{if .Commands}} command [command options]{{end}} +{{if .Commands}} +COMMANDS: +{{range .Commands}}{{if not .HideHelp}} {{join .Names ", "}}{{ "\t"}}{{.Usage}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .VisibleFlags}} +GLOBAL OPTIONS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} +` + app.UsageText = "Kube config application for OIDC" + app.Authors = []cli.Author{ + cli.Author{ + Name: "fydrah", + Email: "flav.hardy@gmail.com", + }, + } + app.Commands = []cli.Command{ + { + Name: "serve", + Usage: "Run loginapp server", + SkipFlagParsing: true, + ArgsUsage: "[configuration file]", + Before: func(c *cli.Context) error { + return nil + }, + Action: func(c *cli.Context) error { + if len(c.Args()) == 0 { + cli.ShowCommandHelp(c, c.Command.Name) + return fmt.Errorf("Missing argument") + } + s := &Server{} + if err := s.config.Init(c.Args().First()); err != nil { + return err + } + if err := s.Run(); err != nil { + return err + } + return nil + }, + }, + } + if err := app.Run(os.Args); err != nil { + logger.Fatal(err) + } +} diff --git a/routes.go b/routes.go new file mode 100644 index 0000000..b094945 --- /dev/null +++ b/routes.go @@ -0,0 +1,23 @@ +/* +Copyright 2018 fydrah + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +func (s *Server) Routes() { + s.router.GET("/", s.HandleGetIndex) + s.router.GET("/callback/cli", s.HandleGetCallbackCLI) + s.router.GET("/healthz", s.HandleGetHealthz) + s.router.POST("/login", s.HandlePostLogin) +} diff --git a/src/loginapp/main.go b/src/loginapp/main.go deleted file mode 100644 index 4e0d662..0000000 --- a/src/loginapp/main.go +++ /dev/null @@ -1,324 +0,0 @@ -package main - -import ( - "bytes" - "context" - "crypto/tls" - "crypto/x509" - "encoding/json" - "fmt" - "github.com/coreos/go-oidc" - "github.com/spf13/cobra" - "golang.org/x/oauth2" - "gopkg.in/yaml.v2" - "io/ioutil" - "log" - "net" - "net/http" - "net/http/httputil" - "net/url" - "os" - "strings" - "time" -) - -const appState = "Dex login request" - -type app struct { - ClientID string `yaml:"client_id"` - ClientSecret string `yaml:"client_secret"` - RedirectURI string `yaml:"redirect_url"` - InitExtraScopes string `yaml:"extra_scopes"` - DisableChoices bool `yaml:"disable_choices"` - AppName string `yaml:"app_name"` - IssuerURL string `yaml:"issuer_url"` - RootCAs string `yaml:"issuer_root_ca"` - Listen string `yaml:"listen"` - TlsCert string `yaml:"tls_cert"` - TlsKey string `yaml:"tls_key"` - Debug bool `yaml:"debug"` - - verifier *oidc.IDTokenVerifier - provider *oidc.Provider - - // Does the provider use "offline_access" scope to request a refresh token - // or does it use "access_type=offline" (e.g. Google)? - offlineAsScope bool - - client *http.Client -} - -// return an HTTP client which trusts the provided root CAs. -func httpClientForRootCAs(rootCAs string) (*http.Client, error) { - tlsConfig := tls.Config{RootCAs: x509.NewCertPool()} - rootCABytes, err := ioutil.ReadFile(rootCAs) - if err != nil { - return nil, fmt.Errorf("failed to read root-ca: %v", err) - } - if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { - return nil, fmt.Errorf("no certs found in root CA file %q", rootCAs) - } - return &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tlsConfig, - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - }, - }, nil -} - -type debugTransport struct { - t http.RoundTripper -} - -func (d debugTransport) RoundTrip(req *http.Request) (*http.Response, error) { - reqDump, err := httputil.DumpRequest(req, true) - if err != nil { - return nil, err - } - log.Printf("%s", reqDump) - - resp, err := d.t.RoundTrip(req) - if err != nil { - return nil, err - } - - respDump, err := httputil.DumpResponse(resp, true) - if err != nil { - resp.Body.Close() - return nil, err - } - log.Printf("%s", respDump) - return resp, nil -} - -func cmd() *cobra.Command { - var ( - a app - ) - c := cobra.Command{ - Use: "loginapp ", - Short: "Simple login application for Kubernetes & Dex", - Long: "", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - configData, err := ioutil.ReadFile(args[0]) - if err != nil { - return fmt.Errorf("failed to read config file %s: %v", args[0], err) - } - if err := yaml.Unmarshal(configData, &a); err != nil { - return fmt.Errorf("error parse config file %s: %v", args[0], err) - } - u, err := url.Parse(a.RedirectURI) - if err != nil { - return fmt.Errorf("parse redirect-uri: %v", err) - } - listenURL, err := url.Parse(a.Listen) - if err != nil { - return fmt.Errorf("parse listen address: %v", err) - } - - if a.RootCAs != "" { - client, err := httpClientForRootCAs(a.RootCAs) - if err != nil { - return err - } - a.client = client - } - - if a.Debug { - if a.client == nil { - a.client = &http.Client{ - Transport: debugTransport{http.DefaultTransport}, - } - } else { - a.client.Transport = debugTransport{a.client.Transport} - } - } - - if a.client == nil { - a.client = http.DefaultClient - } - // TODO(ericchiang): Retry with backoff - ctx := oidc.ClientContext(context.Background(), a.client) - provider, err := oidc.NewProvider(ctx, a.IssuerURL) - if err != nil { - return fmt.Errorf("Failed to query provider %q: %v", a.IssuerURL, err) - } - - var s struct { - // What scopes does a provider support? - // - // See: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata - ScopesSupported []string `json:"scopes_supported"` - } - if err := provider.Claims(&s); err != nil { - return fmt.Errorf("Failed to parse provider scopes_supported: %v", err) - } - - if len(s.ScopesSupported) == 0 { - // scopes_supported is a "RECOMMENDED" discovery claim, not a required - // one. If missing, assume that the provider follows the spec and has - // an "offline_access" scope. - a.offlineAsScope = true - } else { - // See if scopes_supported has the "offline_access" scope. - a.offlineAsScope = func() bool { - for _, scope := range s.ScopesSupported { - if scope == oidc.ScopeOfflineAccess { - return true - } - } - return false - }() - } - - a.provider = provider - a.verifier = provider.Verifier(&oidc.Config{ClientID: a.ClientID}) - - http.HandleFunc("/", a.handleIndex) - http.HandleFunc("/login", a.handleLogin) - http.HandleFunc(u.Path, a.handleCallback) - - switch listenURL.Scheme { - case "http": - log.Printf("listening on %s", a.Listen) - return http.ListenAndServe(listenURL.Host, nil) - case "https": - log.Printf("listening on %s", a.Listen) - return http.ListenAndServeTLS(listenURL.Host, a.TlsCert, a.TlsKey, nil) - default: - return fmt.Errorf("listen address %q is not using http or https", a.Listen) - } - }, - } - return &c -} - -func main() { - if err := cmd().Execute(); err != nil { - fmt.Fprintf(os.Stderr, "error: %v\n", err) - os.Exit(2) - } -} - -func (a *app) handleIndex(w http.ResponseWriter, r *http.Request) { - renderIndex(w, a.InitExtraScopes, a.DisableChoices, a.AppName) -} - -func (a *app) oauth2Config(scopes []string) *oauth2.Config { - return &oauth2.Config{ - ClientID: a.ClientID, - ClientSecret: a.ClientSecret, - Endpoint: a.provider.Endpoint(), - Scopes: scopes, - RedirectURL: a.RedirectURI, - } -} - -func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) { - var scopes []string - if a.InitExtraScopes != "" { - for _, scope := range strings.Split(a.InitExtraScopes, ",") { - scopes = append(scopes, scope) - } - } - if extraScopes := r.FormValue("extra_scopes"); extraScopes != "" { - for _, scope := range strings.Split(extraScopes, ",") { - scopes = append(scopes, scope) - } - } - var clients []string - if crossClients := r.FormValue("cross_client"); crossClients != "" { - clients = strings.Split(crossClients, ",") - } - for _, client := range clients { - scopes = append(scopes, "audience:server:client_id:"+client) - } - - authCodeURL := "" - scopes = append(scopes, "openid", "profile", "email", "groups") - if r.FormValue("offline_access") != "yes" { - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState) - } else if a.offlineAsScope { - scopes = append(scopes, "offline_access") - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState) - } else { - authCodeURL = a.oauth2Config(scopes).AuthCodeURL(appState, oauth2.AccessTypeOffline) - } - log.Printf("%s",a.oauth2Config) - http.Redirect(w, r, authCodeURL, http.StatusSeeOther) -} - -func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { - var ( - err error - token *oauth2.Token - ) - - ctx := oidc.ClientContext(r.Context(), a.client) - oauth2Config := a.oauth2Config(nil) - switch r.Method { - case "GET": - // Authorization redirect callback from OAuth2 auth flow. - if errMsg := r.FormValue("error"); errMsg != "" { - http.Error(w, errMsg+": "+r.FormValue("error_description"), http.StatusBadRequest) - return - } - code := r.FormValue("code") - if code == "" { - http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest) - return - } - if state := r.FormValue("state"); state != appState { - http.Error(w, fmt.Sprintf("expected state %q got %q", appState, state), http.StatusBadRequest) - return - } - token, err = oauth2Config.Exchange(ctx, code) - case "POST": - // Form request from frontend to refresh a token. - refresh := r.FormValue("refresh_token") - if refresh == "" { - http.Error(w, fmt.Sprintf("no refresh_token in request: %q", r.Form), http.StatusBadRequest) - return - } - t := &oauth2.Token{ - RefreshToken: refresh, - Expiry: time.Now().Add(-time.Hour), - } - token, err = oauth2Config.TokenSource(ctx, t).Token() - default: - http.Error(w, fmt.Sprintf("method not implemented: %s", r.Method), http.StatusBadRequest) - return - } - - if err != nil { - http.Error(w, fmt.Sprintf("failed to get token: %v", err), http.StatusInternalServerError) - return - } - - rawIDToken, ok := token.Extra("id_token").(string) - if !ok { - http.Error(w, "no id_token in token response", http.StatusInternalServerError) - return - } - - idToken, err := a.verifier.Verify(r.Context(), rawIDToken) - if err != nil { - http.Error(w, fmt.Sprintf("Failed to verify ID token: %v", err), http.StatusInternalServerError) - return - } - var claims json.RawMessage - idToken.Claims(&claims) - - buff := new(bytes.Buffer) - json.Indent(buff, []byte(claims), "", " ") - - renderToken(w, a.RedirectURI, rawIDToken, token.RefreshToken, buff.Bytes(), a.ClientSecret) -} - diff --git a/src/loginapp/templates.go b/src/loginapp/templates.go deleted file mode 100644 index 5f322c1..0000000 --- a/src/loginapp/templates.go +++ /dev/null @@ -1,144 +0,0 @@ -package main - -import ( - "encoding/json" - "html/template" - "log" - "net/http" -) - -var indexTmpl = template.Must(template.New("index.html").Parse(` - - - - - -
-

{{ .AppName }}

-
    -
  • - - - A comma separated list -
  • -
  • - - - A comma separated list -
  • -
  • - - -
  • -
  • - - Help -
  • -
  • - -
  • -
-
- -`)) - -func renderIndex(w http.ResponseWriter, initScopes string, disableChoices bool, appName string) { - renderTemplate(w, indexTmpl, indexTmplData{ - Scopes: initScopes, - AppName: appName, - DisableChoices: disableChoices, - }) -} - -type indexTmplData struct { - Scopes string - AppName string - DisableChoices bool -} - -type tokenTmplData struct { - IDToken string - RefreshToken string - RedirectURL string - Claims interface{} - ClientSecret string -} - -var tokenTmpl = template.Must(template.New("token.html").Parse(` - - - - - - - -
-

Copy this in your ~/.kube/config file:

-

-- name: {{ .Claims.name }}
-  user:
-    auth-provider:
-      config:
-        client-id: {{ .Claims.aud }}
-        client-secret: {{ .ClientSecret }}
-        id-token: {{ .IDToken }}
-        idp-issuer-url: {{ .Claims.iss }}
-        refresh-token: {{ .RefreshToken }}
-      name: oidc
-  
- - -`)) - -func renderToken(w http.ResponseWriter, redirectURL, idToken, refreshToken string, claims []byte, clientSecret string) { - var json_claims map[string]interface{} - if err := json.Unmarshal(claims, &json_claims); err != nil { - panic(err) - } - renderTemplate(w, tokenTmpl, tokenTmplData{ - IDToken: idToken, - RefreshToken: refreshToken, - RedirectURL: redirectURL, - Claims: json_claims, - ClientSecret: clientSecret, - }) -} - -func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interface{}) { - err := tmpl.Execute(w, data) - if err == nil { - return - } - - switch err := err.(type) { - case *template.Error: - // An ExecError guarantees that Execute has not written to the underlying reader. - log.Printf("Error rendering template %s: %s", tmpl.Name(), err) - - // TODO(ericchiang): replace with better internal server error. - http.Error(w, "Internal server error", http.StatusInternalServerError) - default: - // An error with the underlying write, such as the connection being - // dropped. Ignore for now. - } -} diff --git a/templates.go b/templates.go new file mode 100644 index 0000000..87b9924 --- /dev/null +++ b/templates.go @@ -0,0 +1,108 @@ +/* +Copyright 2018 fydrah + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Some code comes from @ericchiang (Dex - CoreOS) +package main + +import ( + "html/template" + "log" + "net/http" +) + +func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interface{}) { + err := tmpl.Execute(w, data) + if err == nil { + return + } + + switch err := err.(type) { + case *template.Error: + // An ExecError guarantees that Execute has not written to the underlying reader. + log.Printf("Error rendering template %s: %s", tmpl.Name(), err) + + // TODO(ericchiang): replace with better internal server error. + http.Error(w, "Internal server error", http.StatusInternalServerError) + default: + // An error with the underlying write, such as the connection being + // dropped. Ignore for now. + } +} + +var indexTmpl = template.Must(template.New("index.html").Parse(` + + + + + +
+

Kubernetes Loginapp

+
    +
  • + + + Login and retrieve your kubeconfig for CLI authentication +
  • +
+
+ +`)) + +var tokenTmpl = template.Must(template.New("token.html").Parse(` + + + + + + + +
+

Copy this in your ~/.kube/config file:

+

+- name: {{ .Claims.name }}
+  user:
+    auth-provider:
+      config:
+        client-id: {{ .Claims.aud }}
+        client-secret: {{ .ClientSecret }}
+        id-token: {{ .IDToken }}
+        idp-issuer-url: {{ .Claims.iss }}
+        refresh-token: {{ .RefreshToken }}
+      name: oidc
+  
+ + +`)) diff --git a/util.go b/util.go new file mode 100644 index 0000000..f8dbfac --- /dev/null +++ b/util.go @@ -0,0 +1,50 @@ +/* +Copyright 2018 fydrah + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Some code comes from @ericchiang (Dex - CoreOS) +package main + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io/ioutil" + "net" + "net/http" + "time" +) + +func httpClientForRootCAs(rootCAs string) (*http.Client, error) { + tlsConfig := tls.Config{RootCAs: x509.NewCertPool()} + rootCABytes, err := ioutil.ReadFile(rootCAs) + if err != nil { + return nil, fmt.Errorf("failed to read root-ca: %v", err) + } + if !tlsConfig.RootCAs.AppendCertsFromPEM(rootCABytes) { + return nil, fmt.Errorf("no certs found in root CA file %q", rootCAs) + } + return &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tlsConfig, + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + }, + }, nil +} diff --git a/vendor/github.com/cenkalti/backoff/.gitignore b/vendor/github.com/cenkalti/backoff/.gitignore new file mode 100644 index 0000000..0026861 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/cenkalti/backoff/.travis.yml b/vendor/github.com/cenkalti/backoff/.travis.yml new file mode 100644 index 0000000..d6f85ad --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.3.3 + - 1.x + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/cenkalti/backoff/LICENSE b/vendor/github.com/cenkalti/backoff/LICENSE new file mode 100644 index 0000000..89b8179 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cenkalti/backoff/README.md b/vendor/github.com/cenkalti/backoff/README.md new file mode 100644 index 0000000..13b347f --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/README.md @@ -0,0 +1,30 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +See https://godoc.org/github.com/cenkalti/backoff#pkg-examples + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://godoc.org/github.com/cenkalti/backoff +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png +[travis]: https://travis-ci.org/cenkalti/backoff +[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master +[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master +[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master + +[google-http-java-client]: https://github.com/google/google-http-java-client +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ diff --git a/vendor/github.com/cenkalti/backoff/backoff.go b/vendor/github.com/cenkalti/backoff/backoff.go new file mode 100644 index 0000000..3676ee4 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // or backoff. Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/context.go b/vendor/github.com/cenkalti/backoff/context.go new file mode 100644 index 0000000..5d15709 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/context.go @@ -0,0 +1,60 @@ +package backoff + +import ( + "time" + + "golang.org/x/net/context" +) + +// BackOffContext is a backoff policy that stops retrying after the context +// is canceled. +type BackOffContext interface { + BackOff + Context() context.Context +} + +type backOffContext struct { + BackOff + ctx context.Context +} + +// WithContext returns a BackOffContext with context ctx +// +// ctx must not be nil +func WithContext(b BackOff, ctx context.Context) BackOffContext { + if ctx == nil { + panic("nil context") + } + + if b, ok := b.(*backOffContext); ok { + return &backOffContext{ + BackOff: b.BackOff, + ctx: ctx, + } + } + + return &backOffContext{ + BackOff: b, + ctx: ctx, + } +} + +func ensureContext(b BackOff) BackOffContext { + if cb, ok := b.(BackOffContext); ok { + return cb + } + return WithContext(b, context.Background()) +} + +func (b *backOffContext) Context() context.Context { + return b.ctx +} + +func (b *backOffContext) NextBackOff() time.Duration { + select { + case <-b.Context().Done(): + return Stop + default: + return b.BackOff.NextBackOff() + } +} diff --git a/vendor/github.com/cenkalti/backoff/exponential.go b/vendor/github.com/cenkalti/backoff/exponential.go new file mode 100644 index 0000000..d9de15a --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/exponential.go @@ -0,0 +1,158 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. + +The elapsed time can be reset by calling Reset(). + +Example: Given the following default arguments, for 10 tries the sequence will be, +and assuming we go over the MaxElapsedTime on the 10th try: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff stops. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time + random *rand.Rand +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + b := &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Clock: SystemClock, + random: rand.New(rand.NewSource(time.Now().UnixNano())), + } + b.Reset() + return b +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next backoff interval using the formula: +// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { + return Stop + } + defer b.incrementCurrentInterval() + if b.random == nil { + b.random = rand.New(rand.NewSource(time.Now().UnixNano())) + } + return getRandomValueFromInterval(b.RandomizationFactor, b.random.Float64(), b.currentInterval) +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). It is +// safe to call even while the backoff policy is used by a running +// ticker. +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/retry.go b/vendor/github.com/cenkalti/backoff/retry.go new file mode 100644 index 0000000..5dbd825 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/retry.go @@ -0,0 +1,78 @@ +package backoff + +import "time" + +// An Operation is executing by Retry() or RetryNotify(). +// The operation will be retried using a backoff policy if it returns an error. +type Operation func() error + +// Notify is a notify-on-error function. It receives an operation error and +// backoff delay if the operation failed (with an error). +// +// NOTE that if the backoff policy stated to stop retrying, +// the notify function isn't called. +type Notify func(error, time.Duration) + +// Retry the operation o until it does not return error or BackOff stops. +// o is guaranteed to be run at least once. +// It is the caller's responsibility to reset b after Retry returns. +// +// If o returns a *PermanentError, the operation is not retried, and the +// wrapped error is returned. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } + +// RetryNotify calls notify function with the error and wait duration +// for each failed attempt before sleep. +func RetryNotify(operation Operation, b BackOff, notify Notify) error { + var err error + var next time.Duration + + cb := ensureContext(b) + + b.Reset() + for { + if err = operation(); err == nil { + return nil + } + + if permanent, ok := err.(*PermanentError); ok { + return permanent.Err + } + + if next = b.NextBackOff(); next == Stop { + return err + } + + if notify != nil { + notify(err, next) + } + + t := time.NewTimer(next) + + select { + case <-cb.Context().Done(): + t.Stop() + return err + case <-t.C: + } + } +} + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) *PermanentError { + return &PermanentError{ + Err: err, + } +} diff --git a/vendor/github.com/cenkalti/backoff/ticker.go b/vendor/github.com/cenkalti/backoff/ticker.go new file mode 100644 index 0000000..e742512 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/ticker.go @@ -0,0 +1,84 @@ +package backoff + +import ( + "runtime" + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOffContext + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: ensureContext(b), + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + runtime.SetFinalizer(t, (*Ticker).Stop) + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + case <-t.b.Context().Done(): + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + return time.After(next) +} diff --git a/vendor/github.com/cenkalti/backoff/tries.go b/vendor/github.com/cenkalti/backoff/tries.go new file mode 100644 index 0000000..cfeefd9 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/tries.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +/* +WithMaxRetries creates a wrapper around another BackOff, which will +return Stop if NextBackOff() has been called too many times since +the last time Reset() was called + +Note: Implementation is not thread-safe. +*/ +func WithMaxRetries(b BackOff, max uint64) BackOff { + return &backOffTries{delegate: b, maxTries: max} +} + +type backOffTries struct { + delegate BackOff + maxTries uint64 + numTries uint64 +} + +func (b *backOffTries) NextBackOff() time.Duration { + if b.maxTries > 0 { + if b.maxTries <= b.numTries { + return Stop + } + b.numTries++ + } + return b.delegate.NextBackOff() +} + +func (b *backOffTries) Reset() { + b.numTries = 0 + b.delegate.Reset() +} diff --git a/vendor/github.com/coreos/go-oidc/.gitignore b/vendor/github.com/coreos/go-oidc/.gitignore new file mode 100644 index 0000000..c96f2f4 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/.gitignore @@ -0,0 +1,2 @@ +/bin +/gopath diff --git a/vendor/github.com/coreos/go-oidc/.travis.yml b/vendor/github.com/coreos/go-oidc/.travis.yml new file mode 100644 index 0000000..f2f3c9c --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/.travis.yml @@ -0,0 +1,16 @@ +language: go + +go: + - 1.7.5 + - 1.8 + +install: + - go get -v -t github.com/coreos/go-oidc/... + - go get golang.org/x/tools/cmd/cover + - go get github.com/golang/lint/golint + +script: + - ./test + +notifications: + email: false diff --git a/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md b/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md new file mode 100644 index 0000000..6662073 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# How to Contribute + +CoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via +GitHub pull requests. This document outlines some of the conventions on +development workflow, commit message formatting, contact points and other +resources to make it easier to get your contribution accepted. + +# Certificate of Origin + +By contributing to this project you agree to the Developer Certificate of +Origin (DCO). This document was created by the Linux Kernel community and is a +simple statement that you, as a contributor, have the legal right to make the +contribution. See the [DCO](DCO) file for details. + +# Email and Chat + +The project currently uses the general CoreOS email list and IRC channel: +- Email: [coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev) +- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org + +Please avoid emailing maintainers found in the MAINTAINERS file directly. They +are very busy and read the mailing lists. + +## Getting Started + +- Fork the repository on GitHub +- Read the [README](README.md) for build and test instructions +- Play with the project, submit bugs, submit patches! + +## Contribution Flow + +This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work (usually master). +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- Make sure the tests pass, and add any new tests as appropriate. +- Submit a pull request to the original repository. + +Thanks for your contributions! + +### Format of the Commit Message + +We follow a rough convention for commit messages that is designed to answer two +questions: what changed and why. The subject line should feature the what and +the body of the commit should describe the why. + +``` +scripts: add the test-cluster command + +this uses tmux to setup a test cluster that you can easily kill and +start for debugging. + +Fixes #38 +``` + +The format can be described more formally as follows: + +``` +: + + + +