From af6b96ab749df20daf394a84f745df5cecba6413 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 9 Sep 2023 14:54:35 -0700 Subject: [PATCH] Add e2e for username/password over HTTP --- _test_tools/httpd/Dockerfile | 49 +++++++++++++++++++++++++ _test_tools/httpd/README.md | 34 +++++++++++++++++ _test_tools/httpd/nginx.conf | 38 +++++++++++++++++++ _test_tools/httpd/run.sh | 21 +++++++++++ test_e2e.sh | 71 ++++++++++++++++++++++++++++++++++++ 5 files changed, 213 insertions(+) create mode 100644 _test_tools/httpd/Dockerfile create mode 100644 _test_tools/httpd/README.md create mode 100644 _test_tools/httpd/nginx.conf create mode 100755 _test_tools/httpd/run.sh diff --git a/_test_tools/httpd/Dockerfile b/_test_tools/httpd/Dockerfile new file mode 100644 index 0000000..2838d49 --- /dev/null +++ b/_test_tools/httpd/Dockerfile @@ -0,0 +1,49 @@ +# Copyright 2023 The Kubernetes Authors. +# +# 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. + +# Stolen from https://github.com/linuxkit/linuxkit/tree/master/pkg/sshd/ + +FROM alpine AS base + +RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/ +RUN apk add --no-cache --initdb -p /out \ + alpine-baselayout \ + apk-tools \ + busybox \ + git \ + git-daemon \ + nginx \ + fcgiwrap \ + apache2-utils \ + tini \ + && true + +############### + +FROM scratch + +ENTRYPOINT [] +WORKDIR / + +COPY --from=base /out/ / + +RUN htpasswd -b -c /etc/htpasswd testuser testpass + +# Callers should mount a directory with git repos here. +VOLUME /git + +COPY nginx.conf /etc/nginx/ +COPY run.sh / + +CMD ["/sbin/tini", "/run.sh"] diff --git a/_test_tools/httpd/README.md b/_test_tools/httpd/README.md new file mode 100644 index 0000000..638cabf --- /dev/null +++ b/_test_tools/httpd/README.md @@ -0,0 +1,34 @@ +# A server for tests git-over-http + +DO NOT USE THIS FOR ANYTHING BUT TESTING GIT OVER HTTP!!! + +## How to use it + +Build yourself a test image. We use example.com so you can't accidentally push +it. + +``` +$ docker build -t example.com/test/test-httpd . +...lots of output... +Successfully tagged example.com/test/test-httpd:latest +``` + +Run it. + +``` +$ docker run -d -v /tmp/repo:/git/repo:ro example.com/test/test-httpd +60d5b41110bc669037031e3cd758763f0e4fb6c50fac33c4a8a28432b448ae +``` + +Find your IP. + +``` +$ docker inspect 60d5b41110bc669037031e3cd758763f0e4fb6c50fac33c4a8a28432b448ae7 | jq -r .[0].NetworkSettings.IPAddress +192.168.1.2 +``` + +Now you can git clone from it. + +``` +$ git clone testuser:testpass@192.168.9.2/repo +``` diff --git a/_test_tools/httpd/nginx.conf b/_test_tools/httpd/nginx.conf new file mode 100644 index 0000000..51fd7ce --- /dev/null +++ b/_test_tools/httpd/nginx.conf @@ -0,0 +1,38 @@ +# /etc/nginx/nginx.conf + +user root; +worker_processes 1; +daemon off; +error_log /dev/stdout info; + +events { +} + +http { + access_log /dev/stdout; + + server { + listen 80 default_server; + listen [::]:80 default_server; + + # Everything is a 404 + location / { + # First attempt to serve request as file, then + # as directory, then fall back to displaying a 404. + try_files $uri $uri/ =404; + } + + location ~ (/.*) { + client_max_body_size 0; # Git pushes can be massive, just to make sure nginx doesn't suddenly cut the connection add this. + auth_basic "Git Login"; # Whatever text will do. + auth_basic_user_file "/etc/htpasswd"; + include /etc/nginx/fastcgi_params; # Include the default fastcgi configs + fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; # Tells fastcgi to pass the request to the git http backend executable + fastcgi_param GIT_HTTP_EXPORT_ALL ""; + fastcgi_param GIT_PROJECT_ROOT /git; # the location of all of your git repositories. + fastcgi_param REMOTE_USER $remote_user; + fastcgi_param PATH_INFO $1; # Takes the capture group from our location directive and gives git that. + fastcgi_pass unix:/var/run/fcgiwrap.socket; # Pass the request to fastcgi + } + } +} diff --git a/_test_tools/httpd/run.sh b/_test_tools/httpd/run.sh new file mode 100755 index 0000000..7d259e8 --- /dev/null +++ b/_test_tools/httpd/run.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Copyright 2023 The Kubernetes Authors. +# +# 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. + +SOCKET="/var/run/fcgiwrap.socket" +rm -f "$SOCKET" +fcgiwrap -s "unix:$SOCKET" & + +exec nginx diff --git a/test_e2e.sh b/test_e2e.sh index 28cdff8..9f15711 100755 --- a/test_e2e.sh +++ b/test_e2e.sh @@ -2697,6 +2697,77 @@ function e2e::submodule_sync_relative() { rm -rf $SUBMODULE } +############################################## +# Test HTTP with password +############################################## +function e2e::auth_http_password() { + # Run a git-over-HTTP server. + CTR=$(docker_run \ + -v "$DOT_SSH/server/3":/dot_ssh:ro \ + -v "$REPO":/git/repo:ro \ + e2e/test/httpd) + IP=$(docker_ip "$CTR") + + # Try with wrong username + GIT_SYNC \ + --one-time \ + --repo="http://$IP/repo" \ + --root="$ROOT" \ + --link="link" \ + --username="wrong" \ + --password="testpass" \ + || true + assert_file_absent "$ROOT/link/file" + + # Try with wrong password + GIT_SYNC \ + --one-time \ + --repo="http://$IP/repo" \ + --root="$ROOT" \ + --link="link" \ + --username="testuser" \ + --password="wrong" \ + || true + assert_file_absent "$ROOT/link/file" + + # Configure the repo. + echo "$FUNCNAME 1" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 1" + + GIT_SYNC \ + --period=100ms \ + --repo="http://$IP/repo" \ + --root="$ROOT" \ + --link="link" \ + --username="testuser" \ + --password="testpass" \ + & + + # First sync + wait_for_sync "${MAXWAIT}" + assert_link_exists "$ROOT/link" + assert_file_exists "$ROOT/link/file" + assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 1 + + # Move HEAD forward + echo "$FUNCNAME 2" > "$REPO/file" + git -C "$REPO" commit -qam "$FUNCNAME 2" + wait_for_sync "${MAXWAIT}" + assert_link_exists "$ROOT/link" + assert_file_exists "$ROOT/link/file" + assert_file_eq "$ROOT/link/file" "$FUNCNAME 2" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 2 + + # Move HEAD backward + git -C "$REPO" reset -q --hard HEAD^ + wait_for_sync "${MAXWAIT}" + assert_link_exists "$ROOT/link" + assert_file_exists "$ROOT/link/file" + assert_file_eq "$ROOT/link/file" "$FUNCNAME 1" + assert_metric_eq "${METRIC_GOOD_SYNC_COUNT}" 3 +} + ############################################## # Test SSH with bad key ##############################################