mirror of
https://github.com/atmoz/sftp.git
synced 2024-12-22 13:14:42 -05:00
284 lines
6.8 KiB
Bash
Executable file
284 lines
6.8 KiB
Bash
Executable file
#!/bin/bash
|
|
# See: https://github.com/djui/bashunit
|
|
|
|
skipAllTests=false
|
|
|
|
scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
buildDir="$scriptDir/.."
|
|
tmpDir="/tmp/atmoz_sftp_test"
|
|
|
|
sudo="sudo"
|
|
cache="--no-cache"
|
|
|
|
build=${1:-"build"}
|
|
output=${2:-"quiet"}
|
|
cleanup=${3:-"cleanup"}
|
|
sftpImageName="atmoz/sftp_test"
|
|
sftpContainerName="atmoz_sftp_test"
|
|
|
|
if [ "$output" == "quiet" ]; then
|
|
redirect="/dev/null"
|
|
else
|
|
redirect="/dev/stdout"
|
|
fi
|
|
|
|
buildOptions="--tag $sftpImageName"
|
|
|
|
##############################################################################
|
|
|
|
function beforeTest() {
|
|
if [ "$build" == "build" ]; then
|
|
buildOptions="$buildOptions $cache --pull=true"
|
|
fi
|
|
|
|
$sudo docker build $buildOptions "$buildDir"
|
|
if [ $? -gt 0 ]; then
|
|
echo "Build failed"
|
|
exit 1
|
|
fi
|
|
|
|
# Private key can not be read by others
|
|
chmod go-rw "$scriptDir/id_rsa"
|
|
|
|
rm -rf "$tmpDir" # clean state
|
|
mkdir "$tmpDir"
|
|
|
|
echo "test::$(id -u):$(id -g):dir1,dir2" >> "$tmpDir/users"
|
|
echo "" >> "$tmpDir/users" # empty line
|
|
echo "# comments are allowed" >> "$tmpDir/users"
|
|
echo " " >> "$tmpDir/users" # only whitespace
|
|
echo " # with whitespace in front" >> "$tmpDir/users"
|
|
echo "user.with.dot::$(id -u):$(id -g)" >> "$tmpDir/users"
|
|
$sudo docker run \
|
|
-v "$tmpDir/users:/etc/sftp/users.conf:ro" \
|
|
-v "$scriptDir/id_rsa.pub":/home/test/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$scriptDir/id_rsa.pub":/home/user.with.dot/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$tmpDir":/home/test/share \
|
|
--name "$sftpContainerName" \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
> "$redirect"
|
|
|
|
waitForServer $sftpContainerName
|
|
}
|
|
|
|
function afterTest() {
|
|
if [ "$output" != "quiet" ]; then
|
|
echo "Docker logs:"
|
|
$sudo docker logs "$sftpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$sftpContainerName" > "$redirect"
|
|
rm -rf "$tmpDir"
|
|
fi
|
|
}
|
|
|
|
function getSftpIp() {
|
|
$sudo docker inspect -f {{.NetworkSettings.IPAddress}} "$1"
|
|
}
|
|
|
|
function runSftpCommands() {
|
|
ip="$(getSftpIp $1)"
|
|
user="$2"
|
|
shift 2
|
|
|
|
commands=""
|
|
for cmd in "$@"; do
|
|
commands="$commands$cmd"$'\n'
|
|
done
|
|
|
|
echo "$commands" | sftp \
|
|
-i "$scriptDir/id_rsa" \
|
|
-oStrictHostKeyChecking=no \
|
|
-oUserKnownHostsFile=/dev/null \
|
|
-b - $user@$ip \
|
|
> "$redirect" 2>&1
|
|
|
|
status=$?
|
|
sleep 1 # wait for commands to finish
|
|
return $status
|
|
}
|
|
|
|
function waitForServer() {
|
|
containerName="$1"
|
|
echo -n "Waiting for $containerName to open port 22 ..."
|
|
|
|
for i in {1..30}; do
|
|
sleep 1
|
|
ip="$(getSftpIp $containerName)"
|
|
echo -n "."
|
|
if [ -n "$ip" ] && nc -z $ip 22; then
|
|
echo " OPEN"
|
|
return 0;
|
|
fi
|
|
done
|
|
|
|
echo " TIMEOUT"
|
|
return 1
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
function testContainerIsRunning() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
ps="$($sudo docker ps -q -f name="$sftpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ -z "$ps" ]; then
|
|
skipAllTests=true
|
|
fi
|
|
}
|
|
|
|
function testLoginUsingSshKey() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" "exit"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testUserWithDotLogin() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "user.with.dot" "exit"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testWritePermission() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" \
|
|
"cd share" \
|
|
"mkdir test" \
|
|
"exit"
|
|
test -d "$tmpDir/test"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
function testDir() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
runSftpCommands "$sftpContainerName" "test" \
|
|
"cd dir1" \
|
|
"mkdir test-dir1" \
|
|
"get -rf test-dir1 $tmpDir/" \
|
|
"cd ../dir2" \
|
|
"mkdir test-dir2" \
|
|
"get -rf test-dir2 $tmpDir/" \
|
|
"exit"
|
|
test -d "$tmpDir/test-dir1"
|
|
assertReturn $? 0
|
|
test -d "$tmpDir/test-dir2"
|
|
assertReturn $? 0
|
|
}
|
|
|
|
# Smallest user config possible
|
|
function testMinimalContainerStart() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_minimal"
|
|
|
|
$sudo docker run \
|
|
--name "$tmpContainerName" \
|
|
-d "$sftpImageName" \
|
|
m: \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ -z "$ps" ]; then
|
|
skipAllTests=true
|
|
fi
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
function testLegacyConfigPath() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_legacy"
|
|
|
|
echo "test::$(id -u):$(id -g)" >> "$tmpDir/legacy_users"
|
|
$sudo docker run \
|
|
-v "$tmpDir/legacy_users:/etc/sftp-users.conf:ro" \
|
|
--name "$tmpContainerName" \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
|
|
# Bind-mount folder using script in /etc/sftp.d/
|
|
function testCustomContainerStart() {
|
|
$skipAllTests && skip && return 0
|
|
|
|
tmpContainerName="$sftpContainerName""_custom"
|
|
|
|
mkdir -p "$tmpDir/custom/bindmount"
|
|
echo "mkdir -p /home/custom/bindmount && \
|
|
chown custom /home/custom/bindmount && \
|
|
mount --bind /custom /home/custom/bindmount" \
|
|
> "$tmpDir/mount.sh"
|
|
chmod +x "$tmpDir/mount.sh"
|
|
|
|
$sudo docker run \
|
|
--privileged=true \
|
|
--name "$tmpContainerName" \
|
|
-v "$scriptDir/id_rsa.pub":/home/custom/.ssh/keys/id_rsa.pub:ro \
|
|
-v "$tmpDir/custom/bindmount":/custom \
|
|
-v "$tmpDir/mount.sh":/etc/sftp.d/mount.sh \
|
|
--expose 22 \
|
|
-d "$sftpImageName" \
|
|
custom:123 \
|
|
> "$redirect"
|
|
|
|
waitForServer $tmpContainerName
|
|
|
|
ps="$($sudo docker ps -q -f name="$tmpContainerName")"
|
|
assertNotEqual "$ps" ""
|
|
|
|
runSftpCommands "$tmpContainerName" "custom" \
|
|
"cd bindmount" \
|
|
"mkdir test" \
|
|
"exit"
|
|
|
|
test -d "$tmpDir/custom/bindmount/test"
|
|
assertReturn $? 0
|
|
|
|
if [ "$output" != "quiet" ]; then
|
|
$sudo docker logs "$tmpContainerName"
|
|
fi
|
|
|
|
if [ "$cleanup" == "cleanup" ]; then
|
|
$sudo docker rm -fv "$tmpContainerName" > "$redirect"
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
|
|
# Run tests
|
|
source "$scriptDir/bashunit.bash"
|
|
# Nothing happens after this
|