Compare commits
6 Commits
master
...
config-imp
Author | SHA1 | Date | |
---|---|---|---|
|
765443bc41 | ||
|
8e92e3dc3d | ||
|
6f9db420d5 | ||
|
cf3eac0242 | ||
|
180765e8a6 | ||
|
c9fbf5d3c9 |
99
Gopkg.lock
generated
99
Gopkg.lock
generated
@ -68,6 +68,14 @@
|
|||||||
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
|
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
|
||||||
version = "v3.2.0"
|
version = "v3.2.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:eb53021a8aa3f599d29c7102e65026242bdedce998a54837dc67f14b6a97c5fd"
|
||||||
|
name = "github.com/fsnotify/fsnotify"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
|
||||||
|
version = "v1.4.7"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:8c7410dae63c74bd92db09bf33af7e0698b635ab6a397fd8e9e10dfcce3138ac"
|
digest = "1:8c7410dae63c74bd92db09bf33af7e0698b635ab6a397fd8e9e10dfcce3138ac"
|
||||||
name = "github.com/go-redis/redis"
|
name = "github.com/go-redis/redis"
|
||||||
@ -103,6 +111,25 @@
|
|||||||
revision = "9c11da706d9b7902c6da69c592f75637793fe121"
|
revision = "9c11da706d9b7902c6da69c592f75637793fe121"
|
||||||
version = "v2.0.0"
|
version = "v2.0.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:d14365c51dd1d34d5c79833ec91413bfbb166be978724f15701e17080dc06dec"
|
||||||
|
name = "github.com/hashicorp/hcl"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"hcl/ast",
|
||||||
|
"hcl/parser",
|
||||||
|
"hcl/printer",
|
||||||
|
"hcl/scanner",
|
||||||
|
"hcl/strconv",
|
||||||
|
"hcl/token",
|
||||||
|
"json/parser",
|
||||||
|
"json/scanner",
|
||||||
|
"json/token",
|
||||||
|
]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:b3c5b95e56c06f5aa72cb2500e6ee5f44fcd122872d4fec2023a488e561218bc"
|
digest = "1:b3c5b95e56c06f5aa72cb2500e6ee5f44fcd122872d4fec2023a488e561218bc"
|
||||||
name = "github.com/hpcloud/tail"
|
name = "github.com/hpcloud/tail"
|
||||||
@ -117,6 +144,14 @@
|
|||||||
revision = "a30252cb686a21eb2d0b98132633053ec2f7f1e5"
|
revision = "a30252cb686a21eb2d0b98132633053ec2f7f1e5"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:ae39921edb7f801f7ce1b6b5484f9715a1dd2b52cb645daef095cd10fd6ee774"
|
||||||
|
name = "github.com/magiconair/properties"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "de8848e004dd33dc07a2947b3d76f618a7fc7ef1"
|
||||||
|
version = "v1.8.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:af67386ca553c04c6222f7b5b2f17bc97a5dfb3b81b706882c7fd8c72c30cf8f"
|
digest = "1:af67386ca553c04c6222f7b5b2f17bc97a5dfb3b81b706882c7fd8c72c30cf8f"
|
||||||
name = "github.com/mbland/hmacauth"
|
name = "github.com/mbland/hmacauth"
|
||||||
@ -125,6 +160,14 @@
|
|||||||
revision = "107c17adcc5eccc9935cd67d9bc2feaf5255d2cb"
|
revision = "107c17adcc5eccc9935cd67d9bc2feaf5255d2cb"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:bcc46a0fbd9e933087bef394871256b5c60269575bb661935874729c65bbbf60"
|
||||||
|
name = "github.com/mitchellh/mapstructure"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
|
||||||
|
version = "v1.1.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:15c0562bca5d78ac087fb39c211071dc124e79fb18f8b7c3f8a0bc7ffcb2a38e"
|
digest = "1:15c0562bca5d78ac087fb39c211071dc124e79fb18f8b7c3f8a0bc7ffcb2a38e"
|
||||||
@ -181,6 +224,14 @@
|
|||||||
revision = "90e289841c1ed79b7a598a7cd9959750cb5e89e2"
|
revision = "90e289841c1ed79b7a598a7cd9959750cb5e89e2"
|
||||||
version = "v1.5.0"
|
version = "v1.5.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:3d2c33720d4255686b9f4a7e4d3b94938ee36063f14705c5eb0f73347ed4c496"
|
||||||
|
name = "github.com/pelletier/go-toml"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "728039f679cbcd4f6a54e080d2219a4c4928c546"
|
||||||
|
version = "v1.4.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
|
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
|
||||||
name = "github.com/pmezard/go-difflib"
|
name = "github.com/pmezard/go-difflib"
|
||||||
@ -200,6 +251,49 @@
|
|||||||
pruneopts = ""
|
pruneopts = ""
|
||||||
revision = "0dec1b30a0215bb68605dfc568e8855066c9202d"
|
revision = "0dec1b30a0215bb68605dfc568e8855066c9202d"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:956f655c87b7255c6b1ae6c203ebb0af98cf2a13ef2507e34c9bf1c0332ac0f5"
|
||||||
|
name = "github.com/spf13/afero"
|
||||||
|
packages = [
|
||||||
|
".",
|
||||||
|
"mem",
|
||||||
|
]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "588a75ec4f32903aa5e39a2619ba6a4631e28424"
|
||||||
|
version = "v1.2.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:ae3493c780092be9d576a1f746ab967293ec165e8473425631f06658b6212afc"
|
||||||
|
name = "github.com/spf13/cast"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
|
||||||
|
version = "v1.3.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:cc15ae4fbdb02ce31f3392361a70ac041f4f02e0485de8ffac92bd8033e3d26e"
|
||||||
|
name = "github.com/spf13/jwalterweatherman"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "94f6ae3ed3bceceafa716478c5fbf8d29ca601a1"
|
||||||
|
version = "v1.1.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:cbaf13cdbfef0e4734ed8a7504f57fe893d471d62a35b982bf6fb3f036449a66"
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
|
||||||
|
version = "v1.0.3"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:9b483544fcf4fc0155e566f49ee669c205fba12a36eb18e7f80510796a606db4"
|
||||||
|
name = "github.com/spf13/viper"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = ""
|
||||||
|
revision = "b5bf975e5823809fb22c7644d008757f78a4259e"
|
||||||
|
version = "v1.4.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
digest = "1:3926a4ec9a4ff1a072458451aa2d9b98acd059a45b38f7335d31e06c3d6a0159"
|
digest = "1:3926a4ec9a4ff1a072458451aa2d9b98acd059a45b38f7335d31e06c3d6a0159"
|
||||||
name = "github.com/stretchr/testify"
|
name = "github.com/stretchr/testify"
|
||||||
@ -300,11 +394,14 @@
|
|||||||
"internal/language",
|
"internal/language",
|
||||||
"internal/language/compact",
|
"internal/language/compact",
|
||||||
"internal/tag",
|
"internal/tag",
|
||||||
|
"internal/triegen",
|
||||||
|
"internal/ucd",
|
||||||
"internal/utf8internal",
|
"internal/utf8internal",
|
||||||
"language",
|
"language",
|
||||||
"runes",
|
"runes",
|
||||||
"transform",
|
"transform",
|
||||||
"unicode/cldr",
|
"unicode/cldr",
|
||||||
|
"unicode/norm",
|
||||||
]
|
]
|
||||||
pruneopts = ""
|
pruneopts = ""
|
||||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
||||||
@ -409,6 +506,8 @@
|
|||||||
"github.com/mreiferson/go-options",
|
"github.com/mreiferson/go-options",
|
||||||
"github.com/onsi/ginkgo",
|
"github.com/onsi/ginkgo",
|
||||||
"github.com/onsi/gomega",
|
"github.com/onsi/gomega",
|
||||||
|
"github.com/spf13/pflag",
|
||||||
|
"github.com/spf13/viper",
|
||||||
"github.com/stretchr/testify/assert",
|
"github.com/stretchr/testify/assert",
|
||||||
"github.com/stretchr/testify/require",
|
"github.com/stretchr/testify/require",
|
||||||
"github.com/yhat/wsutil",
|
"github.com/yhat/wsutil",
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
2
http.go
2
http.go
@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server represents an HTTP server
|
// Server represents an HTTP server
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP status
|
// responseLogger is wrapper of http.ResponseWriter that keeps track of its HTTP status
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoggingHandler_ServeHTTP(t *testing.T) {
|
func TestLoggingHandler_ServeHTTP(t *testing.T) {
|
||||||
|
2
main.go
2
main.go
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
options "github.com/mreiferson/go-options"
|
options "github.com/mreiferson/go-options"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -14,9 +14,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mbland/hmacauth"
|
"github.com/mbland/hmacauth"
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
|
||||||
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/pusher/oauth2_proxy/providers"
|
"github.com/pusher/oauth2_proxy/providers"
|
||||||
"github.com/yhat/wsutil"
|
"github.com/yhat/wsutil"
|
||||||
)
|
)
|
||||||
@ -555,7 +555,7 @@ func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
// OAuthStart starts the OAuth2 authentication flow
|
// OAuthStart starts the OAuth2 authentication flow
|
||||||
func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) {
|
func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) {
|
||||||
nonce, err := cookie.Nonce()
|
nonce, err := encryption.Nonce()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("Error obtaining nonce: %s", err.Error())
|
logger.Printf("Error obtaining nonce: %s", err.Error())
|
||||||
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
p.ErrorPage(rw, 500, "Internal Error", err.Error())
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mbland/hmacauth"
|
"github.com/mbland/hmacauth"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
|
"github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
|
||||||
"github.com/pusher/oauth2_proxy/providers"
|
"github.com/pusher/oauth2_proxy/providers"
|
||||||
|
@ -17,10 +17,10 @@ import (
|
|||||||
oidc "github.com/coreos/go-oidc"
|
oidc "github.com/coreos/go-oidc"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/mbland/hmacauth"
|
"github.com/mbland/hmacauth"
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
||||||
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/providers"
|
"github.com/pusher/oauth2_proxy/providers"
|
||||||
"gopkg.in/natefinch/lumberjack.v2"
|
"gopkg.in/natefinch/lumberjack.v2"
|
||||||
@ -268,7 +268,7 @@ func (o *Options) Validate() error {
|
|||||||
}
|
}
|
||||||
msgs = parseProviderInfo(o, msgs)
|
msgs = parseProviderInfo(o, msgs)
|
||||||
|
|
||||||
var cipher *cookie.Cipher
|
var cipher *encryption.Cipher
|
||||||
if o.PassAccessToken || o.SetAuthorization || o.PassAuthorization || (o.CookieRefresh != time.Duration(0)) {
|
if o.PassAccessToken || o.SetAuthorization || o.PassAuthorization || (o.CookieRefresh != time.Duration(0)) {
|
||||||
validCookieSecretSize := false
|
validCookieSecretSize := false
|
||||||
for _, i := range []int{16, 24, 32} {
|
for _, i := range []int{16, 24, 32} {
|
||||||
@ -293,7 +293,7 @@ func (o *Options) Validate() error {
|
|||||||
len(secretBytes(o.CookieSecret)), suffix))
|
len(secretBytes(o.CookieSecret)), suffix))
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
cipher, err = cookie.NewCipher(secretBytes(o.CookieSecret))
|
cipher, err = encryption.NewCipher(secretBytes(o.CookieSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msgs = append(msgs, fmt.Sprintf("cookie-secret error: %v", err))
|
msgs = append(msgs, fmt.Sprintf("cookie-secret error: %v", err))
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,33 @@
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
// CookieOptions contains configuration options relating to Cookie configuration
|
// CookieOptions contains configuration options relating to Cookie configuration
|
||||||
type CookieOptions struct {
|
type CookieOptions struct {
|
||||||
CookieName string `flag:"cookie-name" cfg:"cookie_name" env:"OAUTH2_PROXY_COOKIE_NAME"`
|
Name string `flag:"cookie-name" cfg:"cookie_name" env:"OAUTH2_PROXY_COOKIE_NAME" default:"_oauth2_proxy"`
|
||||||
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"OAUTH2_PROXY_COOKIE_SECRET"`
|
Secret string `flag:"cookie-secret" cfg:"cookie_secret" env:"OAUTH2_PROXY_COOKIE_SECRET"`
|
||||||
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"OAUTH2_PROXY_COOKIE_DOMAIN"`
|
Domain string `flag:"cookie-domain" cfg:"cookie_domain" env:"OAUTH2_PROXY_COOKIE_DOMAIN"`
|
||||||
CookiePath string `flag:"cookie-path" cfg:"cookie_path" env:"OAUTH2_PROXY_COOKIE_PATH"`
|
Path string `flag:"cookie-path" cfg:"cookie_path" env:"OAUTH2_PROXY_COOKIE_PATH" default:"/"`
|
||||||
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"OAUTH2_PROXY_COOKIE_EXPIRE"`
|
Expire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"OAUTH2_PROXY_COOKIE_EXPIRE" default:"604800000000000"`
|
||||||
CookieRefresh time.Duration `flag:"cookie-refresh" cfg:"cookie_refresh" env:"OAUTH2_PROXY_COOKIE_REFRESH"`
|
Refresh time.Duration `flag:"cookie-refresh" cfg:"cookie_refresh" env:"OAUTH2_PROXY_COOKIE_REFRESH" default:"0"`
|
||||||
CookieSecure bool `flag:"cookie-secure" cfg:"cookie_secure" env:"OAUTH2_PROXY_COOKIE_SECURE"`
|
Secure bool `flag:"cookie-secure" cfg:"cookie_secure" env:"OAUTH2_PROXY_COOKIE_SECURE" default:"true"`
|
||||||
CookieHTTPOnly bool `flag:"cookie-httponly" cfg:"cookie_httponly" env:"OAUTH2_PROXY_COOKIE_HTTPONLY"`
|
HTTPOnly bool `flag:"cookie-httponly" cfg:"cookie_httponly" env:"OAUTH2_PROXY_COOKIE_HTTPONLY" default:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// cookieFlagSet contains flags related to Cookie configuration
|
||||||
|
var cookieFlagSet = flag.NewFlagSet("cookie", flag.ExitOnError)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cookieFlagSet.String("cookie-name", "_oauth2_proxy", "the name of the cookie that the oauth_proxy creates")
|
||||||
|
cookieFlagSet.String("cookie-secret", "", "the seed string for secure cookies (optionally base64 encoded)")
|
||||||
|
cookieFlagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
|
||||||
|
cookieFlagSet.String("cookie-path", "/", "an optional cookie path to force cookies to (ie: /poc/)*")
|
||||||
|
cookieFlagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
|
||||||
|
cookieFlagSet.Duration("cookie-refresh", time.Duration(0), "refresh the cookie after this duration; 0 to disable")
|
||||||
|
cookieFlagSet.Bool("cookie-secure", true, "set secure (HTTPS) cookie flag")
|
||||||
|
cookieFlagSet.Bool("cookie-httponly", true, "set HttpOnly cookie flag")
|
||||||
}
|
}
|
||||||
|
68
pkg/apis/options/default.go
Normal file
68
pkg/apis/options/default.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func defaultStruct(s interface{}) error {
|
||||||
|
val := reflect.ValueOf(s)
|
||||||
|
var typ reflect.Type
|
||||||
|
if val.Kind() == reflect.Ptr {
|
||||||
|
typ = val.Elem().Type()
|
||||||
|
} else {
|
||||||
|
typ = val.Type()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
field := typ.Field(i)
|
||||||
|
fieldV := reflect.Indirect(val).Field(i)
|
||||||
|
|
||||||
|
// If the field is a ptr, recurse
|
||||||
|
if field.Type.Kind() == reflect.Ptr {
|
||||||
|
if fieldV.IsNil() {
|
||||||
|
fieldV.Set(reflect.New(fieldV.Type().Elem()))
|
||||||
|
}
|
||||||
|
err := defaultStruct(fieldV.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error defaulting %s: %v", field.Name, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the field is a ptr, recurse
|
||||||
|
if field.Type.Kind() == reflect.Struct {
|
||||||
|
newField := reflect.New(reflect.TypeOf(fieldV.Interface()))
|
||||||
|
err := defaultStruct(newField.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error defaulting %s: %v", field.Name, err)
|
||||||
|
}
|
||||||
|
fieldV.Set(newField.Elem())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultVal := field.Tag.Get("default")
|
||||||
|
|
||||||
|
if defaultVal != "" {
|
||||||
|
switch fieldV.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
fieldV.Set(reflect.ValueOf(defaultVal).Convert(field.Type))
|
||||||
|
case reflect.Bool:
|
||||||
|
boolVal, err := strconv.ParseBool(defaultVal)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("expected default value (%s) to be bool: %v", defaultVal, err)
|
||||||
|
}
|
||||||
|
fieldV.Set(reflect.ValueOf(boolVal).Convert(field.Type))
|
||||||
|
case reflect.Int64:
|
||||||
|
intVal, err := strconv.ParseInt(defaultVal, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("expected default value (%s) to be int: %v", defaultVal, err)
|
||||||
|
}
|
||||||
|
fieldV.Set(reflect.ValueOf(intVal).Convert(field.Type))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
60
pkg/apis/options/default_test.go
Normal file
60
pkg/apis/options/default_test.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("defaultStruct", func() {
|
||||||
|
type InnerTest struct {
|
||||||
|
TestString string `default:"bar"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
TestString string `default:"foo"`
|
||||||
|
TestBool bool `default:"true"`
|
||||||
|
TestDuration time.Duration `default:"60000000000"`
|
||||||
|
TestPtrStruct *InnerTest
|
||||||
|
TestStruct InnerTest
|
||||||
|
}
|
||||||
|
|
||||||
|
var testStruct *Test
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
testStruct = &Test{}
|
||||||
|
err := defaultStruct(testStruct)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a string field", func() {
|
||||||
|
It("reads the correct default", func() {
|
||||||
|
Expect(testStruct.TestString).To(Equal("foo"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a bool field", func() {
|
||||||
|
It("reads the correct default", func() {
|
||||||
|
Expect(testStruct.TestBool).To(Equal(true))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a duration field", func() {
|
||||||
|
It("reads the correct default", func() {
|
||||||
|
Expect(testStruct.TestDuration).To(Equal(time.Minute))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a pointer struct field", func() {
|
||||||
|
It("defaults the values in the struct", func() {
|
||||||
|
Expect(testStruct.TestPtrStruct.TestString).To(Equal("bar"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a struct field", func() {
|
||||||
|
It("defaults the values in the struct", func() {
|
||||||
|
Expect(testStruct.TestStruct.TestString).To(Equal("bar"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
82
pkg/apis/options/options.go
Normal file
82
pkg/apis/options/options.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options contains configuration options for the OAuth2 Proxy
|
||||||
|
type Options struct {
|
||||||
|
Cookie *CookieOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new deafulted copy of the Options struct
|
||||||
|
func New() *Options {
|
||||||
|
options := &Options{}
|
||||||
|
err := defaultStruct(options)
|
||||||
|
if err != nil {
|
||||||
|
// If we get an error here, there must be a code error
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load reads a config file, flag arguments and the environment to set the
|
||||||
|
// correct configuration options
|
||||||
|
func Load(config io.Reader, configType string, args []string) (*Options, error) {
|
||||||
|
flagSet := flag.NewFlagSet("oauth2-proxy", flag.ExitOnError)
|
||||||
|
flagSet.SetNormalizeFunc(wordSepNormalizeFunc)
|
||||||
|
|
||||||
|
// Add FlagSets to main flagSet
|
||||||
|
flagSet.AddFlagSet(cookieFlagSet)
|
||||||
|
|
||||||
|
flagSet.Parse(args)
|
||||||
|
|
||||||
|
// Create a viper for binding config
|
||||||
|
v := viper.New()
|
||||||
|
|
||||||
|
// Bind flags to viper
|
||||||
|
err := v.BindPFlags(flagSet)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure loading of environment variables
|
||||||
|
// All flag options are prefixed by the EnvPrefix
|
||||||
|
v.SetEnvPrefix("OAUTH2_PROXY")
|
||||||
|
// Substitute "-" for "_" so `FOO_BAR` matches the config `foo.bar`
|
||||||
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
v.AutomaticEnv()
|
||||||
|
|
||||||
|
// Read the configuration file
|
||||||
|
if config != nil {
|
||||||
|
if configType == "" {
|
||||||
|
return nil, fmt.Errorf("config-type not set")
|
||||||
|
}
|
||||||
|
v.SetConfigType(configType)
|
||||||
|
v.ReadConfig(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarhsal the config into the Options struct
|
||||||
|
options := New()
|
||||||
|
err = v.Unmarshal(&options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error unmarshalling config: %v", err)
|
||||||
|
}
|
||||||
|
return options, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// wordSepNormalizeFunc replaces "-" in flags entered with "."
|
||||||
|
// This ensures that flags are mapped to the correct values in the Options struct
|
||||||
|
func wordSepNormalizeFunc(f *flag.FlagSet, name string) flag.NormalizedName {
|
||||||
|
from := []string{"-"}
|
||||||
|
to := "."
|
||||||
|
for _, sep := range from {
|
||||||
|
name = strings.Replace(name, sep, to, -1)
|
||||||
|
}
|
||||||
|
return flag.NormalizedName(name)
|
||||||
|
}
|
150
pkg/apis/options/options_test.go
Normal file
150
pkg/apis/options/options_test.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package options
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOptions(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "Options")
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("Load", func() {
|
||||||
|
var opts *Options
|
||||||
|
var err error
|
||||||
|
var config io.Reader
|
||||||
|
var configType string
|
||||||
|
var args []string
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
// Make sure to clear previous test globals
|
||||||
|
opts = nil
|
||||||
|
err = nil
|
||||||
|
config = nil
|
||||||
|
configType = ""
|
||||||
|
args = []string{}
|
||||||
|
})
|
||||||
|
|
||||||
|
JustBeforeEach(func() {
|
||||||
|
opts, err = Load(config, configType, args)
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with no configuration", func() {
|
||||||
|
It("returns no error", func() {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns the default configuration", func() {
|
||||||
|
defaultOpts := New()
|
||||||
|
Expect(opts).To(Equal(defaultOpts))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with a yaml configuration for cookies", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
configType = "yaml"
|
||||||
|
config = bytes.NewBuffer([]byte(`
|
||||||
|
cookie:
|
||||||
|
name: cookie_name
|
||||||
|
secret: 123567890abcdef
|
||||||
|
domain: example.com
|
||||||
|
path: /path
|
||||||
|
expire: 12h
|
||||||
|
refresh: 1h
|
||||||
|
secure: false
|
||||||
|
httpOnly: false
|
||||||
|
`))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns no error", func() {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("sets the correct configuration", func() {
|
||||||
|
expected := &CookieOptions{
|
||||||
|
Name: "cookie_name",
|
||||||
|
Secret: "123567890abcdef",
|
||||||
|
Domain: "example.com",
|
||||||
|
Path: "/path",
|
||||||
|
Expire: time.Duration(12) * time.Hour,
|
||||||
|
Refresh: time.Hour,
|
||||||
|
Secure: false,
|
||||||
|
HTTPOnly: false,
|
||||||
|
}
|
||||||
|
Expect(opts.Cookie).To(Equal(expected))
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with environment configuration", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_NAME", "env_cookie_name")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_SECRET", "env_secret_12345")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_DOMAIN", "env.example.com")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_PATH", "/env")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_EXPIRE", "24h")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_REFRESH", "2h")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_SECURE", "true")
|
||||||
|
os.Setenv("OAUTH2_PROXY_COOKIE_HTTPONLY", "true")
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns no error", func() {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("the environment overrides the config file", func() {
|
||||||
|
expected := &CookieOptions{
|
||||||
|
Name: "env_cookie_name",
|
||||||
|
Secret: "env_secret_12345",
|
||||||
|
Domain: "env.example.com",
|
||||||
|
Path: "/env",
|
||||||
|
Expire: time.Duration(24) * time.Hour,
|
||||||
|
Refresh: time.Duration(2) * time.Hour,
|
||||||
|
Secure: true,
|
||||||
|
HTTPOnly: true,
|
||||||
|
}
|
||||||
|
Expect(opts.Cookie).To(Equal(expected))
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with flag configuration", func() {
|
||||||
|
Context("with hyphens", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
args = []string{
|
||||||
|
"--cookie-name=flag_cookie_name",
|
||||||
|
"--cookie-secret=flag_secret_1234",
|
||||||
|
"--cookie-domain=flag.example.com",
|
||||||
|
"--cookie-path=/flag",
|
||||||
|
"--cookie-expire=48h",
|
||||||
|
"--cookie-refresh=4h",
|
||||||
|
"--cookie-secure=false",
|
||||||
|
"--cookie-httponly=false",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns no error", func() {
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("the environment overrides the config file", func() {
|
||||||
|
expected := &CookieOptions{
|
||||||
|
Name: "flag_cookie_name",
|
||||||
|
Secret: "flag_secret_1234",
|
||||||
|
Domain: "flag.example.com",
|
||||||
|
Path: "/flag",
|
||||||
|
Expire: time.Duration(48) * time.Hour,
|
||||||
|
Refresh: time.Duration(4) * time.Hour,
|
||||||
|
Secure: false,
|
||||||
|
HTTPOnly: false,
|
||||||
|
}
|
||||||
|
Expect(opts.Cookie).To(Equal(expected))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -1,13 +1,11 @@
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import "github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SessionOptions contains configuration options for the SessionStore providers.
|
// SessionOptions contains configuration options for the SessionStore providers.
|
||||||
type SessionOptions struct {
|
type SessionOptions struct {
|
||||||
Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
|
Type string `flag:"session-store-type" cfg:"session_store_type" env:"OAUTH2_PROXY_SESSION_STORE_TYPE"`
|
||||||
Cipher *cookie.Cipher
|
Cipher *encryption.Cipher
|
||||||
CookieStoreOptions
|
CookieStoreOptions
|
||||||
RedisStoreOptions
|
RedisStoreOptions
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SessionState is used to store information about the currently authenticated user session
|
// SessionState is used to store information about the currently authenticated user session
|
||||||
@ -66,7 +66,7 @@ func (s *SessionState) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncodeSessionState returns string representation of the current session
|
// EncodeSessionState returns string representation of the current session
|
||||||
func (s *SessionState) EncodeSessionState(c *cookie.Cipher) (string, error) {
|
func (s *SessionState) EncodeSessionState(c *encryption.Cipher) (string, error) {
|
||||||
var ss SessionState
|
var ss SessionState
|
||||||
if c == nil {
|
if c == nil {
|
||||||
// Store only Email and User when cipher is unavailable
|
// Store only Email and User when cipher is unavailable
|
||||||
@ -133,7 +133,7 @@ func legacyDecodeSessionStatePlain(v string) (*SessionState, error) {
|
|||||||
|
|
||||||
// legacyDecodeSessionState attempts to decode the session state string
|
// legacyDecodeSessionState attempts to decode the session state string
|
||||||
// generated by v3.1.0 or older
|
// generated by v3.1.0 or older
|
||||||
func legacyDecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) {
|
func legacyDecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
|
||||||
chunks := strings.Split(v, "|")
|
chunks := strings.Split(v, "|")
|
||||||
|
|
||||||
if c == nil {
|
if c == nil {
|
||||||
@ -176,7 +176,7 @@ func legacyDecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecodeSessionState decodes the session cookie string into a SessionState
|
// DecodeSessionState decodes the session cookie string into a SessionState
|
||||||
func DecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) {
|
func DecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
|
||||||
var ssj SessionStateJSON
|
var ssj SessionStateJSON
|
||||||
var ss *SessionState
|
var ss *SessionState
|
||||||
err := json.Unmarshal([]byte(v), &ssj)
|
err := json.Unmarshal([]byte(v), &ssj)
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,9 +14,9 @@ const secret = "0123456789abcdefghijklmnopqrstuv"
|
|||||||
const altSecret = "0000000000abcdefghijklmnopqrstuv"
|
const altSecret = "0000000000abcdefghijklmnopqrstuv"
|
||||||
|
|
||||||
func TestSessionStateSerialization(t *testing.T) {
|
func TestSessionStateSerialization(t *testing.T) {
|
||||||
c, err := cookie.NewCipher([]byte(secret))
|
c, err := encryption.NewCipher([]byte(secret))
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
c2, err := cookie.NewCipher([]byte(altSecret))
|
c2, err := encryption.NewCipher([]byte(altSecret))
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
s := &sessions.SessionState{
|
s := &sessions.SessionState{
|
||||||
Email: "user@domain.com",
|
Email: "user@domain.com",
|
||||||
@ -54,9 +54,9 @@ func TestSessionStateSerialization(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSessionStateSerializationWithUser(t *testing.T) {
|
func TestSessionStateSerializationWithUser(t *testing.T) {
|
||||||
c, err := cookie.NewCipher([]byte(secret))
|
c, err := encryption.NewCipher([]byte(secret))
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
c2, err := cookie.NewCipher([]byte(altSecret))
|
c2, err := encryption.NewCipher([]byte(altSecret))
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
s := &sessions.SessionState{
|
s := &sessions.SessionState{
|
||||||
User: "just-user",
|
User: "just-user",
|
||||||
@ -146,7 +146,7 @@ func TestExpired(t *testing.T) {
|
|||||||
type testCase struct {
|
type testCase struct {
|
||||||
sessions.SessionState
|
sessions.SessionState
|
||||||
Encoded string
|
Encoded string
|
||||||
Cipher *cookie.Cipher
|
Cipher *encryption.Cipher
|
||||||
Error bool
|
Error bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ func TestDecodeSessionState(t *testing.T) {
|
|||||||
eString := string(eJSON)
|
eString := string(eJSON)
|
||||||
eUnix := e.Unix()
|
eUnix := e.Unix()
|
||||||
|
|
||||||
c, err := cookie.NewCipher([]byte(secret))
|
c, err := encryption.NewCipher([]byte(secret))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
testCases := []testCase{
|
testCases := []testCase{
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package cookie
|
package encryption
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/aes"
|
"crypto/aes"
|
@ -1,4 +1,4 @@
|
|||||||
package cookie
|
package encryption
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
@ -1,4 +1,4 @@
|
|||||||
package cookie
|
package encryption
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
@ -7,7 +7,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/bitly/go-simplejson"
|
"github.com/bitly/go-simplejson"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Request parses the request body into a simplejson.Json object
|
// Request parses the request body into a simplejson.Json object
|
||||||
|
@ -8,10 +8,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/sessions/utils"
|
"github.com/pusher/oauth2_proxy/pkg/sessions/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ var _ sessions.SessionStore = &SessionStore{}
|
|||||||
// interface that stores sessions in client side cookies
|
// interface that stores sessions in client side cookies
|
||||||
type SessionStore struct {
|
type SessionStore struct {
|
||||||
CookieOptions *options.CookieOptions
|
CookieOptions *options.CookieOptions
|
||||||
CookieCipher *cookie.Cipher
|
CookieCipher *encryption.Cipher
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save takes a sessions.SessionState and stores the information from it
|
// Save takes a sessions.SessionState and stores the information from it
|
||||||
@ -53,7 +53,7 @@ func (s *SessionStore) Load(req *http.Request) (*sessions.SessionState, error) {
|
|||||||
// always http.ErrNoCookie
|
// always http.ErrNoCookie
|
||||||
return nil, fmt.Errorf("Cookie %q not present", s.CookieOptions.CookieName)
|
return nil, fmt.Errorf("Cookie %q not present", s.CookieOptions.CookieName)
|
||||||
}
|
}
|
||||||
val, _, ok := cookie.Validate(c, s.CookieOptions.CookieSecret, s.CookieOptions.CookieExpire)
|
val, _, ok := encryption.Validate(c, s.CookieOptions.CookieSecret, s.CookieOptions.CookieExpire)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("Cookie Signature not valid")
|
return nil, errors.New("Cookie Signature not valid")
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ func (s *SessionStore) setSessionCookie(rw http.ResponseWriter, req *http.Reques
|
|||||||
// authentication details
|
// authentication details
|
||||||
func (s *SessionStore) makeSessionCookie(req *http.Request, value string, now time.Time) []*http.Cookie {
|
func (s *SessionStore) makeSessionCookie(req *http.Request, value string, now time.Time) []*http.Cookie {
|
||||||
if value != "" {
|
if value != "" {
|
||||||
value = cookie.SignedValue(s.CookieOptions.CookieSecret, s.CookieOptions.CookieName, value, now)
|
value = encryption.SignedValue(s.CookieOptions.CookieSecret, s.CookieOptions.CookieName, value, now)
|
||||||
}
|
}
|
||||||
c := s.makeCookie(req, s.CookieOptions.CookieName, value, s.CookieOptions.CookieExpire, now)
|
c := s.makeCookie(req, s.CookieOptions.CookieName, value, s.CookieOptions.CookieExpire, now)
|
||||||
if len(c.Value) > 4096-len(s.CookieOptions.CookieName) {
|
if len(c.Value) > 4096-len(s.CookieOptions.CookieName) {
|
||||||
|
@ -13,10 +13,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-redis/redis"
|
"github.com/go-redis/redis"
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TicketData is a structure representing the ticket used in server session storage
|
// TicketData is a structure representing the ticket used in server session storage
|
||||||
@ -28,7 +28,7 @@ type TicketData struct {
|
|||||||
// SessionStore is an implementation of the sessions.SessionStore
|
// SessionStore is an implementation of the sessions.SessionStore
|
||||||
// interface that stores sessions in redis
|
// interface that stores sessions in redis
|
||||||
type SessionStore struct {
|
type SessionStore struct {
|
||||||
CookieCipher *cookie.Cipher
|
CookieCipher *encryption.Cipher
|
||||||
CookieOptions *options.CookieOptions
|
CookieOptions *options.CookieOptions
|
||||||
Client *redis.Client
|
Client *redis.Client
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ func (store *SessionStore) Load(req *http.Request) (*sessions.SessionState, erro
|
|||||||
return nil, fmt.Errorf("error loading session: %s", err)
|
return nil, fmt.Errorf("error loading session: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("Cookie Signature not valid")
|
return nil, fmt.Errorf("Cookie Signature not valid")
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro
|
|||||||
return fmt.Errorf("error retrieving cookie: %v", err)
|
return fmt.Errorf("error retrieving cookie: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Cookie Signature not valid")
|
return fmt.Errorf("Cookie Signature not valid")
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro
|
|||||||
// makeCookie makes a cookie, signing the value if present
|
// makeCookie makes a cookie, signing the value if present
|
||||||
func (store *SessionStore) makeCookie(req *http.Request, value string, expires time.Duration, now time.Time) *http.Cookie {
|
func (store *SessionStore) makeCookie(req *http.Request, value string, expires time.Duration, now time.Time) *http.Cookie {
|
||||||
if value != "" {
|
if value != "" {
|
||||||
value = cookie.SignedValue(store.CookieOptions.CookieSecret, store.CookieOptions.CookieName, value, now)
|
value = encryption.SignedValue(store.CookieOptions.CookieSecret, store.CookieOptions.CookieName, value, now)
|
||||||
}
|
}
|
||||||
return cookies.MakeCookieFromOptions(
|
return cookies.MakeCookieFromOptions(
|
||||||
req,
|
req,
|
||||||
@ -230,7 +230,7 @@ func (store *SessionStore) getTicket(requestCookie *http.Cookie) (*TicketData, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An existing cookie exists, try to retrieve the ticket
|
// An existing cookie exists, try to retrieve the ticket
|
||||||
val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
val, _, ok := encryption.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Cookie is invalid, create a new ticket
|
// Cookie is invalid, create a new ticket
|
||||||
return newTicket()
|
return newTicket()
|
||||||
|
@ -13,10 +13,10 @@ import (
|
|||||||
"github.com/alicebob/miniredis"
|
"github.com/alicebob/miniredis"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
"github.com/pusher/oauth2_proxy/pkg/apis/options"
|
||||||
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
sessionsapi "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
"github.com/pusher/oauth2_proxy/pkg/cookies"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/sessions"
|
||||||
sessionscookie "github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
|
sessionscookie "github.com/pusher/oauth2_proxy/pkg/sessions/cookie"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/sessions/redis"
|
"github.com/pusher/oauth2_proxy/pkg/sessions/redis"
|
||||||
@ -354,7 +354,7 @@ var _ = Describe("NewSessionStore", func() {
|
|||||||
_, err := rand.Read(secret)
|
_, err := rand.Read(secret)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
cookieOpts.CookieSecret = base64.URLEncoding.EncodeToString(secret)
|
cookieOpts.CookieSecret = base64.URLEncoding.EncodeToString(secret)
|
||||||
cipher, err := cookie.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret))
|
cipher, err := encryption.NewCipher(utils.SecretBytes(cookieOpts.CookieSecret))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(cipher).ToNot(BeNil())
|
Expect(cipher).ToNot(BeNil())
|
||||||
opts.Cipher = cipher
|
opts.Cipher = cipher
|
||||||
|
@ -3,17 +3,17 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CookieForSession serializes a session state for storage in a cookie
|
// CookieForSession serializes a session state for storage in a cookie
|
||||||
func CookieForSession(s *sessions.SessionState, c *cookie.Cipher) (string, error) {
|
func CookieForSession(s *sessions.SessionState, c *encryption.Cipher) (string, error) {
|
||||||
return s.EncodeSessionState(c)
|
return s.EncodeSessionState(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionFromCookie deserializes a session from a cookie value
|
// SessionFromCookie deserializes a session from a cookie value
|
||||||
func SessionFromCookie(v string, c *cookie.Cipher) (s *sessions.SessionState, err error) {
|
func SessionFromCookie(v string, c *encryption.Cipher) (s *sessions.SessionState, err error) {
|
||||||
return sessions.DecodeSessionState(v, c)
|
return sessions.DecodeSessionState(v, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/bitly/go-simplejson"
|
"github.com/bitly/go-simplejson"
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/requests"
|
"github.com/pusher/oauth2_proxy/pkg/requests"
|
||||||
)
|
)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/requests"
|
"github.com/pusher/oauth2_proxy/pkg/requests"
|
||||||
)
|
)
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/google"
|
"golang.org/x/oauth2/google"
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
"github.com/pusher/oauth2_proxy/pkg/requests"
|
"github.com/pusher/oauth2_proxy/pkg/requests"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Redeem provides a default implementation of the OAuth2 token redemption process
|
// Redeem provides a default implementation of the OAuth2 token redemption process
|
||||||
@ -96,12 +96,12 @@ func (p *ProviderData) GetLoginURL(redirectURI, state string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CookieForSession serializes a session state for storage in a cookie
|
// CookieForSession serializes a session state for storage in a cookie
|
||||||
func (p *ProviderData) CookieForSession(s *sessions.SessionState, c *cookie.Cipher) (string, error) {
|
func (p *ProviderData) CookieForSession(s *sessions.SessionState, c *encryption.Cipher) (string, error) {
|
||||||
return s.EncodeSessionState(c)
|
return s.EncodeSessionState(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionFromCookie deserializes a session from a cookie value
|
// SessionFromCookie deserializes a session from a cookie value
|
||||||
func (p *ProviderData) SessionFromCookie(v string, c *cookie.Cipher) (s *sessions.SessionState, err error) {
|
func (p *ProviderData) SessionFromCookie(v string, c *encryption.Cipher) (s *sessions.SessionState, err error) {
|
||||||
return sessions.DecodeSessionState(v, c)
|
return sessions.DecodeSessionState(v, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package providers
|
package providers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pusher/oauth2_proxy/cookie"
|
|
||||||
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
"github.com/pusher/oauth2_proxy/pkg/apis/sessions"
|
||||||
|
"github.com/pusher/oauth2_proxy/pkg/encryption"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider represents an upstream identity provider implementation
|
// Provider represents an upstream identity provider implementation
|
||||||
@ -15,8 +15,8 @@ type Provider interface {
|
|||||||
ValidateSessionState(*sessions.SessionState) bool
|
ValidateSessionState(*sessions.SessionState) bool
|
||||||
GetLoginURL(redirectURI, finalRedirect string) string
|
GetLoginURL(redirectURI, finalRedirect string) string
|
||||||
RefreshSessionIfNeeded(*sessions.SessionState) (bool, error)
|
RefreshSessionIfNeeded(*sessions.SessionState) (bool, error)
|
||||||
SessionFromCookie(string, *cookie.Cipher) (*sessions.SessionState, error)
|
SessionFromCookie(string, *encryption.Cipher) (*sessions.SessionState, error)
|
||||||
CookieForSession(*sessions.SessionState, *cookie.Cipher) (string, error)
|
CookieForSession(*sessions.SessionState, *encryption.Cipher) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New provides a new Provider based on the configured provider string
|
// New provides a new Provider based on the configured provider string
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadTemplates(dir string) *template.Template {
|
func loadTemplates(dir string) *template.Template {
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserMap holds information from the authenticated emails file
|
// UserMap holds information from the authenticated emails file
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pusher/oauth2_proxy/logger"
|
"github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
fsnotify "gopkg.in/fsnotify/fsnotify.v1"
|
fsnotify "gopkg.in/fsnotify/fsnotify.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/pusher/oauth2_proxy/logger"
|
import "github.com/pusher/oauth2_proxy/pkg/logger"
|
||||||
|
|
||||||
func WatchForUpdates(filename string, done <-chan bool, action func()) {
|
func WatchForUpdates(filename string, done <-chan bool, action func()) {
|
||||||
logger.Printf("file watching not implemented on this platform")
|
logger.Printf("file watching not implemented on this platform")
|
||||||
|
Loading…
Reference in New Issue
Block a user