rclone/fs/config_test.go
klauspost bfd7601cf9 Add configuration file encryption
See #317 for details.

Use `rclone config` to add/change/remove password.

Tests that loads the default configuration will now fail with a better error message, and add a switch that makes it possible to disable password prompts and fail instead.

Make it possible to use the "RCLONE_CONFIG_PASS" environment variable as password for configuration.
2016-02-16 16:32:05 +01:00

213 lines
4.5 KiB
Go

package fs
import (
"bytes"
"reflect"
"testing"
)
func TestSizeSuffixString(t *testing.T) {
for _, test := range []struct {
in float64
want string
}{
{0, "0"},
{102, "0.100k"},
{1024, "1k"},
{1024 * 1024, "1M"},
{1024 * 1024 * 1024, "1G"},
{10 * 1024 * 1024 * 1024, "10G"},
{10.1 * 1024 * 1024 * 1024, "10.100G"},
} {
ss := SizeSuffix(test.in)
got := ss.String()
if test.want != got {
t.Errorf("Want %v got %v", test.want, got)
}
}
}
func TestSizeSuffixSet(t *testing.T) {
for i, test := range []struct {
in string
want int64
err bool
}{
{"0", 0, false},
{"0.1k", 102, false},
{"0.1", 102, false},
{"1K", 1024, false},
{"1", 1024, false},
{"2.5", 1024 * 2.5, false},
{"1M", 1024 * 1024, false},
{"1.g", 1024 * 1024 * 1024, false},
{"10G", 10 * 1024 * 1024 * 1024, false},
{"", 0, true},
{"1p", 0, true},
{"1.p", 0, true},
{"1p", 0, true},
{"-1K", 0, true},
} {
ss := SizeSuffix(0)
err := ss.Set(test.in)
if (err != nil) != test.err {
t.Errorf("%d: Expecting error %v but got error %v", i, test.err, err)
}
got := int64(ss)
if test.want != got {
t.Errorf("%d: Want %v got %v", i, test.want, got)
}
}
}
func TestReveal(t *testing.T) {
for _, test := range []struct {
in string
want string
}{
{"", ""},
{"2sTcyNrA", "potato"},
} {
got := Reveal(test.in)
if got != test.want {
t.Errorf("%q: want %q got %q", test.in, test.want, got)
}
if Obscure(got) != test.in {
t.Errorf("%q: wasn't bidirectional", test.in)
}
}
}
func TestConfigLoad(t *testing.T) {
ConfigPath = "./testdata/plain.conf"
configKey = nil
c, err := loadConfigFile()
if err != nil {
t.Fatal(err)
}
sections := c.GetSectionList()
var expect = []string{"RCLONE_ENCRYPT_V0", "nounc", "unc"}
if !reflect.DeepEqual(sections, expect) {
t.Fatalf("%v != %v", sections, expect)
}
keys := c.GetKeyList("nounc")
expect = []string{"type", "nounc"}
if !reflect.DeepEqual(keys, expect) {
t.Fatalf("%v != %v", keys, expect)
}
}
func TestConfigLoadEncrypted(t *testing.T) {
var err error
ConfigPath = "./testdata/encrypted.conf"
// Set correct password
err = setPassword("asdf")
if err != nil {
t.Fatal(err)
}
c, err := loadConfigFile()
if err != nil {
t.Fatal(err)
}
sections := c.GetSectionList()
var expect = []string{"nounc", "unc"}
if !reflect.DeepEqual(sections, expect) {
t.Fatalf("%v != %v", sections, expect)
}
keys := c.GetKeyList("nounc")
expect = []string{"type", "nounc"}
if !reflect.DeepEqual(keys, expect) {
t.Fatalf("%v != %v", keys, expect)
}
}
func TestConfigLoadEncryptedFailures(t *testing.T) {
var err error
// This file should be too short to be decoded.
ConfigPath = "./testdata/enc-short.conf"
_, err = loadConfigFile()
if err == nil {
t.Fatal("expected error")
}
t.Log("Correctly got:", err)
// This file contains invalid base64 characters.
ConfigPath = "./testdata/enc-invalid.conf"
_, err = loadConfigFile()
if err == nil {
t.Fatal("expected error")
}
t.Log("Correctly got:", err)
// This file contains invalid base64 characters.
ConfigPath = "./testdata/enc-too-new.conf"
_, err = loadConfigFile()
if err == nil {
t.Fatal("expected error")
}
t.Log("Correctly got:", err)
// This file contains invalid base64 characters.
ConfigPath = "./testdata/filenotfound.conf"
c, err := loadConfigFile()
if err != nil {
t.Fatal(err)
}
if len(c.GetSectionList()) != 0 {
t.Fatalf("Expected 0-length section, got %d entries", len(c.GetSectionList()))
}
}
func TestPassword(t *testing.T) {
var err error
// Empty password should give error
err = setPassword(" \t ")
if err == nil {
t.Fatal("expected error")
}
// Test invalid utf8 sequence
err = setPassword(string([]byte{0xff, 0xfe, 0xfd}) + "abc")
if err == nil {
t.Fatal("expected error")
}
// Simple check of wrong passwords
hashedKeyCompare(t, "mis", "match", false)
// Check that passwords match with trimmed whitespace
hashedKeyCompare(t, " abcdef \t", "abcdef", true)
// Check that passwords match after unicode normalization
hashedKeyCompare(t, "ff\u0041\u030A", "ffÅ", true)
// Check that passwords preserves case
hashedKeyCompare(t, "abcdef", "ABCDEF", false)
}
func hashedKeyCompare(t *testing.T, a, b string, shouldMatch bool) {
err := setPassword(a)
if err != nil {
t.Fatal(err)
}
k1 := configKey
err = setPassword(b)
if err != nil {
t.Fatal(err)
}
k2 := configKey
matches := bytes.Equal(k1, k2)
if shouldMatch && !matches {
t.Fatalf("%v != %v", k1, k2)
}
if !shouldMatch && matches {
t.Fatalf("%v == %v", k1, k2)
}
}