diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a26700..401e0e5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ ## Changes since v5.1.1 +- [#529](https://github.com/oauth2-proxy/oauth2-proxy/pull/529) Add local test environments for testing changes and new features (@JoelSpeed) - [#537](https://github.com/oauth2-proxy/oauth2-proxy/pull/537) Drop Fallback to Email if User not set (@JoelSpeed) - [#535](https://github.com/oauth2-proxy/oauth2-proxy/pull/535) Drop support for pre v3.1 cookies (@JoelSpeed) - [#533](https://github.com/oauth2-proxy/oauth2-proxy/pull/487) Set up code coverage within Travis for Code Climate (@JoelSpeed) diff --git a/Makefile b/Makefile index 55984e60..ba58b354 100644 --- a/Makefile +++ b/Makefile @@ -76,7 +76,7 @@ release: lint test BINARY=${BINARY} VERSION=${VERSION} ./dist.sh .PHONY: validate-go-version -validate-go-version: ## Validates the installed version of go against Mattermost's minimum requirement. +validate-go-version: @if [ $(GO_MAJOR_VERSION) -gt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \ exit 0 ;\ elif [ $(GO_MAJOR_VERSION) -lt $(MINIMUM_SUPPORTED_GO_MAJOR_VERSION) ]; then \ @@ -86,3 +86,13 @@ validate-go-version: ## Validates the installed version of go against Mattermost echo '$(GO_VERSION_VALIDATION_ERR_MSG)';\ exit 1; \ fi + +# local-env can be used to interact with the local development environment +# eg: +# make local-env-up # Bring up a basic test environment +# make local-env-down # Tear down the basic test environment +# make local-env-nginx-up # Bring up an nginx based test environment +# make local-env-nginx-down # Tead down the nginx based test environment +.PHONY: local-env-% +local-env-%: + make -C contrib/local-environment $* diff --git a/contrib/local-environment/Makefile b/contrib/local-environment/Makefile new file mode 100644 index 00000000..0cfeaa66 --- /dev/null +++ b/contrib/local-environment/Makefile @@ -0,0 +1,15 @@ +.PHONY: up +up: + docker-compose up -d + +.PHONY: % +%: + docker-compose $* + +.PHONY: nginx-up +nginx-up: + docker-compose -f docker-compose.yaml -f docker-compose-nginx.yaml up -d + +.PHONY: nginx-% +nginx-%: + docker-compose -f docker-compose.yaml -f docker-compose-nginx.yaml $* diff --git a/contrib/local-environment/dex.yaml b/contrib/local-environment/dex.yaml new file mode 100644 index 00000000..40a8bed0 --- /dev/null +++ b/contrib/local-environment/dex.yaml @@ -0,0 +1,32 @@ +# This configuration is intended to be used with the docker-compose testing +# environment. +# This should configure Dex to run on port 4190 and provides a static login +issuer: http://dex.localhost:4190/dex +storage: + type: etcd + config: + endpoints: + - http://etcd:2379 + namespace: dex/ +web: + http: 0.0.0.0:4190 +oauth2: + skipApprovalScreen: true +expiry: + signingKeys: "4h" + idTokens: "1h" +staticClients: +- id: oauth2-proxy + redirectURIs: + # These redirect URIs point to the `--redirect-url` for OAuth2 proxy. + - 'http://localhost:4180/oauth2/callback' # For basic proxy example. + - 'http://oauth2-proxy.oauth2-proxy.localhost/oauth2/callback' # For nginx example. + name: 'OAuth2 Proxy' + secret: b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK +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/contrib/local-environment/docker-compose-nginx.yaml b/contrib/local-environment/docker-compose-nginx.yaml new file mode 100644 index 00000000..af6c587b --- /dev/null +++ b/contrib/local-environment/docker-compose-nginx.yaml @@ -0,0 +1,43 @@ +# This docker-compose file can be used to bring up an example instance of oauth2-proxy +# for manual testing and exploration of features. +# Alongside OAuth2-Proxy, this file also starts Dex to act as the identity provider, +# etcd for storage for Dex, nginx as a reverse proxy and other http services for upstreams +# +# This file is an extension of the main compose file and must be used with it +# docker-compose -f docker-compose.yaml -f docker-compose-nginx.yaml +# Alternatively: +# make nginx- (eg make nginx-up, make nginx-down) +# +# Access one of the following URLs to initiate a login flow: +# - http://oauth2-proxy.localhost +# - http://httpbin.oauth2-proxy.localhost +# +# The OAuth2 Proxy itself is hosted at http://oauth2-proxy.oauth2-proxy.localhost +# +# Note, the above URLs should work with Chrome, but you may need to add hosts +# entries for other browsers +# 127.0.0.1 oauth2-proxy.localhost +# 127.0.0.1 httpbin.oauth2-proxy.localhost +# 127.0.0.1 oauth2-proxy.oauth2-proxy.localhost +version: '3.0' +services: + oauth2-proxy: + ports: [] + hostname: oauth2-proxy + volumes: + - "./oauth2-proxy-nginx.cfg:/oauth2-proxy.cfg" + networks: + oauth2-proxy: {} + nginx: + container_name: nginx + image: nginx:1.18 + ports: + - 80:80/tcp + hostname: nginx + volumes: + - "./nginx.conf:/etc/nginx/conf.d/default.conf" + networks: + oauth2-proxy: {} + httpbin: {} +networks: + oauth2-proxy: {} diff --git a/contrib/local-environment/docker-compose.yaml b/contrib/local-environment/docker-compose.yaml new file mode 100644 index 00000000..6f57720a --- /dev/null +++ b/contrib/local-environment/docker-compose.yaml @@ -0,0 +1,64 @@ +# This docker-compose file can be used to bring up an example instance of oauth2-proxy +# for manual testing and exploration of features. +# Alongside OAuth2-Proxy, this file also starts Dex to act as the identity provider, +# etcd for storage for Dex and HTTPBin as an example upstream. +# +# This can either be created using docker-compose +# docker-compose -f docker-compose.yaml +# Or: +# make (eg. make up, make down) +# +# Access http://localhost:4180 to initiate a login cycle +version: '3.0' +services: + oauth2-proxy: + container_name: oauth2-proxy + image: quay.io/oauth2-proxy/oauth2-proxy:v5.1.1 + command: --config /oauth2-proxy.cfg + ports: + - 4180:4180/tcp + hostname: oauth2-proxy + volumes: + - "./oauth2-proxy.cfg:/oauth2-proxy.cfg" + restart: unless-stopped + networks: + dex: {} + httpbin: {} + depends_on: + - dex + - httpbin + dex: + container_name: dex + image: quay.io/dexidp/dex:v2.23.0 + command: serve /dex.yaml + ports: + - 4190:4190/tcp + hostname: dex + volumes: + - "./dex.yaml:/dex.yaml" + restart: unless-stopped + networks: + dex: + aliases: + - dex.localhost + etcd: {} + depends_on: + - etcd + httpbin: + container_name: httpbin + image: kennethreitz/httpbin + networks: + httpbin: {} + etcd: + container_name: etcd + image: gcr.io/etcd-development/etcd:v3.4.7 + entrypoint: /usr/local/bin/etcd + command: + - --listen-client-urls=http://0.0.0.0:2379 + - --advertise-client-urls=http://etcd:2379 + networks: + etcd: {} +networks: + dex: {} + etcd: {} + httpbin: {} diff --git a/contrib/local-environment/nginx.conf b/contrib/local-environment/nginx.conf new file mode 100644 index 00000000..877c213e --- /dev/null +++ b/contrib/local-environment/nginx.conf @@ -0,0 +1,84 @@ +# Reverse proxy to oauth2-proxy +server { + listen 80; + server_name oauth2-proxy.oauth2-proxy.localhost; + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + + proxy_pass http://oauth2-proxy:4180/; + } +} + +# Reverse proxy to httpbin +server { + listen 80; + server_name httpbin.oauth2-proxy.localhost; + + auth_request /internal-auth/oauth2/auth; + + # If the auth_request denies the request (401), redirect to the sign_in page + # and include the final rd URL back to the user's original request. + error_page 401 = http://oauth2-proxy.oauth2-proxy.localhost/oauth2/sign_in?rd=$scheme://$host$request_uri; + + # Alternatively send the request to `start` to skip the provider button + # error_page 401 = http://oauth2-proxy.oauth2-proxy.localhost/oauth2/start?rd=$scheme://$host$request_uri; + + location / { + proxy_pass http://httpbin/; + } + + # auth_request must be a URI so this allows an internal path to then proxy to + # the real auth_request path. + # The trailing /'s are required so that nginx strips the prefix before proxying. + location /internal-auth/ { + internal; # Ensure external users can't access this path + + # Make sure the OAuth2 Proxy knows where the original request came from. + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + + proxy_pass http://oauth2-proxy:4180/; + } +} + +# Statically serve the nginx welcome +server { + listen 80; + server_name oauth2-proxy.localhost; + + location / { + auth_request /internal-auth/oauth2/auth; + + # If the auth_request denies the request (401), redirect to the sign_in page + # and include the final rd URL back to the user's original request. + error_page 401 = http://oauth2-proxy.oauth2-proxy.localhost/oauth2/sign_in?rd=$scheme://$host$request_uri; + + # Alternatively send the request to `start` to skip the provider button + # error_page 401 = http://oauth2-proxy.oauth2-proxy.localhost/oauth2/start?rd=$scheme://$host$request_uri; + + + root /usr/share/nginx/html; + index index.html index.htm; + } + + # redirect server error pages to the static page /50x.html + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # auth_request must be a URI so this allows an internal path to then proxy to + # the real auth_request path. + # The trailing /'s are required so that nginx strips the prefix before proxying. + location /internal-auth/ { + internal; # Ensure external users can't access this path + + # Make sure the OAuth2 Proxy knows where the original request came from. + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + + proxy_pass http://oauth2-proxy:4180/; + } +} diff --git a/contrib/local-environment/oauth2-proxy-nginx.cfg b/contrib/local-environment/oauth2-proxy-nginx.cfg new file mode 100644 index 00000000..6ba5623a --- /dev/null +++ b/contrib/local-environment/oauth2-proxy-nginx.cfg @@ -0,0 +1,12 @@ +http_address="0.0.0.0:4180" +cookie_secret="OQINaROshtE9TcZkNAm-5Zs2Pv3xaWytBmc5W7sPX7w=" +provider="oidc" +email_domains="example.com" +oidc_issuer_url="http://dex.localhost:4190/dex" +client_secret="b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK" +client_id="oauth2-proxy" +cookie_secure="false" + +redirect_url="http://oauth2-proxy.oauth2-proxy.localhost/oauth2/callback" +cookie_domain=".oauth2-proxy.localhost" # Required so cookie can be read on all subdomains. +whitelist_domains=".oauth2-proxy.localhost" # Required to allow redirection back to original requested target. diff --git a/contrib/local-environment/oauth2-proxy.cfg b/contrib/local-environment/oauth2-proxy.cfg new file mode 100644 index 00000000..7ee55d8f --- /dev/null +++ b/contrib/local-environment/oauth2-proxy.cfg @@ -0,0 +1,11 @@ +http_address="0.0.0.0:4180" +cookie_secret="OQINaROshtE9TcZkNAm-5Zs2Pv3xaWytBmc5W7sPX7w=" +provider="oidc" +email_domains="example.com" +oidc_issuer_url="http://dex.localhost:4190/dex" +client_secret="b2F1dGgyLXByb3h5LWNsaWVudC1zZWNyZXQK" +client_id="oauth2-proxy" +cookie_secure="false" + +redirect_url="http://localhost:4180/oauth2/callback" +upstreams="http://httpbin"