2020-11-09 22:17:43 +02:00
package main
import (
"errors"
2021-08-09 16:01:41 +02:00
"fmt"
2020-11-09 22:17:43 +02:00
"os"
2021-08-09 16:01:41 +02:00
"strings"
2020-11-09 22:17:43 +02:00
"time"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
"github.com/spf13/pflag"
)
var _ = Describe ( "Configuration Loading Suite" , func ( ) {
const testLegacyConfig = `
2021-02-14 19:08:04 +02:00
http_address = "127.0.0.1:4180"
2020-11-09 22:17:43 +02:00
upstreams = "http://httpbin"
set_basic_auth = "true"
basic_auth_password = "super-secret-password"
2021-04-03 18:06:30 +02:00
client_id = "oauth2-proxy"
client_secret = "b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK"
2020-11-09 22:17:43 +02:00
`
const testAlphaConfig = `
2021-09-17 13:08:18 +02:00
upstreamConfig :
2021-08-09 16:57:40 +02:00
proxyrawpath : false
2021-09-17 13:08:18 +02:00
upstreams :
2020-11-09 22:17:43 +02:00
- id : /
path : /
uri : http : //httpbin
flushInterval : 1 s
passHostHeader : true
proxyWebSockets : true
2022-05-13 22:36:21 +02:00
timeout : 30 s
2020-11-09 22:17:43 +02:00
injectRequestHeaders :
- name : Authorization
values :
- claim : user
prefix : "Basic "
basicAuthPassword :
value : c3VwZXItc2VjcmV0LXBhc3N3b3Jk
- name : X - Forwarded - Groups
values :
- claim : groups
- name : X - Forwarded - User
values :
- claim : user
- name : X - Forwarded - Email
values :
- claim : email
- name : X - Forwarded - Preferred - Username
values :
- claim : preferred_username
injectResponseHeaders :
- name : Authorization
values :
- claim : user
prefix : "Basic "
basicAuthPassword :
value : c3VwZXItc2VjcmV0LXBhc3N3b3Jk
2021-02-14 19:08:04 +02:00
server :
bindAddress : "127.0.0.1:4180"
2021-04-03 18:06:30 +02:00
providers :
- provider : google
ID : google = oauth2 - proxy
clientSecret : b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK
clientID : oauth2 - proxy
azureConfig :
tenant : common
oidcConfig :
groupsClaim : groups
emailClaim : email
userIDClaim : email
2021-04-21 11:33:27 +02:00
insecureSkipNonce : true
2022-02-15 18:12:22 +02:00
audienceClaims : [ aud ]
extraAudiences : [ ]
2022-02-16 18:18:51 +02:00
loginURLParameters :
- name : approval_prompt
default :
- force
2020-11-09 22:17:43 +02:00
`
const testCoreConfig = `
cookie_secret = "OQINaROshtE9TcZkNAm-5Zs2Pv3xaWytBmc5W7sPX7w="
email_domains = "example.com"
cookie_secure = "false"
redirect_url = "http://localhost:4180/oauth2/callback"
`
boolPtr := func ( b bool ) * bool {
return & b
}
durationPtr := func ( d time . Duration ) * options . Duration {
du := options . Duration ( d )
return & du
}
testExpectedOptions := func ( ) * options . Options {
opts , err := options . NewLegacyOptions ( ) . ToOptions ( )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
opts . Cookie . Secret = "OQINaROshtE9TcZkNAm-5Zs2Pv3xaWytBmc5W7sPX7w="
opts . EmailDomains = [ ] string { "example.com" }
opts . Cookie . Secure = false
opts . RawRedirectURL = "http://localhost:4180/oauth2/callback"
2021-09-17 13:08:18 +02:00
opts . UpstreamServers = options . UpstreamConfig {
Upstreams : [ ] options . Upstream {
2021-08-09 15:32:15 +02:00
{
ID : "/" ,
Path : "/" ,
URI : "http://httpbin" ,
FlushInterval : durationPtr ( options . DefaultUpstreamFlushInterval ) ,
PassHostHeader : boolPtr ( true ) ,
ProxyWebSockets : boolPtr ( true ) ,
2022-05-13 22:36:21 +02:00
Timeout : durationPtr ( options . DefaultUpstreamTimeout ) ,
2021-08-09 15:32:15 +02:00
} ,
2020-11-09 22:17:43 +02:00
} ,
}
authHeader := options . Header {
Name : "Authorization" ,
Values : [ ] options . HeaderValue {
{
ClaimSource : & options . ClaimSource {
Claim : "user" ,
Prefix : "Basic " ,
BasicAuthPassword : & options . SecretSource {
Value : [ ] byte ( "super-secret-password" ) ,
} ,
} ,
} ,
} ,
}
opts . InjectRequestHeaders = append ( [ ] options . Header { authHeader } , opts . InjectRequestHeaders ... )
opts . InjectResponseHeaders = append ( opts . InjectResponseHeaders , authHeader )
2021-04-03 18:06:30 +02:00
opts . Providers = options . Providers {
2021-08-09 15:32:15 +02:00
options . Provider {
2021-04-03 18:06:30 +02:00
ID : "google=oauth2-proxy" ,
Type : "google" ,
ClientSecret : "b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK" ,
ClientID : "oauth2-proxy" ,
AzureConfig : options . AzureOptions {
Tenant : "common" ,
} ,
OIDCConfig : options . OIDCOptions {
2021-04-21 11:33:27 +02:00
GroupsClaim : "groups" ,
EmailClaim : "email" ,
UserIDClaim : "email" ,
2022-02-15 18:12:22 +02:00
AudienceClaims : [ ] string { "aud" } ,
ExtraAudiences : [ ] string { } ,
2021-04-21 11:33:27 +02:00
InsecureSkipNonce : true ,
2021-04-03 18:06:30 +02:00
} ,
2022-02-16 18:18:51 +02:00
LoginURLParameters : [ ] options . LoginURLParameter {
{ Name : "approval_prompt" , Default : [ ] string { "force" } } ,
} ,
2021-04-03 18:06:30 +02:00
} ,
}
2020-11-09 22:17:43 +02:00
return opts
}
type loadConfigurationTableInput struct {
configContent string
alphaConfigContent string
args [ ] string
extraFlags func ( ) * pflag . FlagSet
expectedOptions func ( ) * options . Options
expectedErr error
}
DescribeTable ( "LoadConfiguration" ,
func ( in loadConfigurationTableInput ) {
var configFileName , alphaConfigFileName string
defer func ( ) {
if configFileName != "" {
Expect ( os . Remove ( configFileName ) ) . To ( Succeed ( ) )
}
if alphaConfigFileName != "" {
Expect ( os . Remove ( alphaConfigFileName ) ) . To ( Succeed ( ) )
}
} ( )
if in . configContent != "" {
By ( "Writing the config to a temporary file" , func ( ) {
2022-10-21 12:57:51 +02:00
file , err := os . CreateTemp ( "" , "oauth2-proxy-test-config-XXXX.cfg" )
2020-11-09 22:17:43 +02:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
defer file . Close ( )
configFileName = file . Name ( )
_ , err = file . WriteString ( in . configContent )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
} )
}
if in . alphaConfigContent != "" {
By ( "Writing the config to a temporary file" , func ( ) {
2022-10-21 12:57:51 +02:00
file , err := os . CreateTemp ( "" , "oauth2-proxy-test-alpha-config-XXXX.yaml" )
2020-11-09 22:17:43 +02:00
Expect ( err ) . ToNot ( HaveOccurred ( ) )
defer file . Close ( )
alphaConfigFileName = file . Name ( )
_ , err = file . WriteString ( in . alphaConfigContent )
Expect ( err ) . ToNot ( HaveOccurred ( ) )
} )
}
extraFlags := pflag . NewFlagSet ( "test-flagset" , pflag . ExitOnError )
if in . extraFlags != nil {
extraFlags = in . extraFlags ( )
}
opts , err := loadConfiguration ( configFileName , alphaConfigFileName , extraFlags , in . args )
if in . expectedErr != nil {
Expect ( err ) . To ( MatchError ( in . expectedErr . Error ( ) ) )
} else {
Expect ( err ) . ToNot ( HaveOccurred ( ) )
}
Expect ( in . expectedOptions ) . ToNot ( BeNil ( ) )
Expect ( opts ) . To ( Equal ( in . expectedOptions ( ) ) )
} ,
Entry ( "with legacy configuration" , loadConfigurationTableInput {
configContent : testCoreConfig + testLegacyConfig ,
expectedOptions : testExpectedOptions ,
} ) ,
Entry ( "with alpha configuration" , loadConfigurationTableInput {
configContent : testCoreConfig ,
alphaConfigContent : testAlphaConfig ,
expectedOptions : testExpectedOptions ,
} ) ,
Entry ( "with bad legacy configuration" , loadConfigurationTableInput {
configContent : testCoreConfig + "unknown_field=\"something\"" ,
expectedOptions : func ( ) * options . Options { return nil } ,
expectedErr : errors . New ( "failed to load config: error unmarshalling config: 1 error(s) decoding:\n\n* '' has invalid keys: unknown_field" ) ,
} ) ,
Entry ( "with bad alpha configuration" , loadConfigurationTableInput {
configContent : testCoreConfig ,
alphaConfigContent : testAlphaConfig + ":" ,
expectedOptions : func ( ) * options . Options { return nil } ,
2021-08-09 16:01:41 +02:00
expectedErr : fmt . Errorf ( "failed to load alpha options: error unmarshalling config: error converting YAML to JSON: yaml: line %d: did not find expected key" , strings . Count ( testAlphaConfig , "\n" ) ) ,
2020-11-09 22:17:43 +02:00
} ) ,
Entry ( "with alpha configuration and bad core configuration" , loadConfigurationTableInput {
configContent : testCoreConfig + "unknown_field=\"something\"" ,
alphaConfigContent : testAlphaConfig ,
expectedOptions : func ( ) * options . Options { return nil } ,
expectedErr : errors . New ( "failed to load core options: failed to load config: error unmarshalling config: 1 error(s) decoding:\n\n* '' has invalid keys: unknown_field" ) ,
} ) ,
)
} )