github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/cmd/serve/proxy/proxy_test.go (about) 1 package proxy 2 3 import ( 4 "crypto/rand" 5 "crypto/rsa" 6 "crypto/sha256" 7 "encoding/base64" 8 "log" 9 "strings" 10 "testing" 11 12 _ "github.com/rclone/rclone/backend/local" 13 "github.com/rclone/rclone/fs/config/configmap" 14 "github.com/rclone/rclone/fs/config/obscure" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 "golang.org/x/crypto/ssh" 18 ) 19 20 func TestRun(t *testing.T) { 21 opt := DefaultOpt 22 cmd := "go run proxy_code.go" 23 opt.AuthProxy = cmd 24 p := New(&opt) 25 26 t.Run("Normal", func(t *testing.T) { 27 config, err := p.run(map[string]string{ 28 "type": "ftp", 29 "user": "me", 30 "pass": "pass", 31 "host": "127.0.0.1", 32 }) 33 require.NoError(t, err) 34 assert.Equal(t, configmap.Simple{ 35 "type": "ftp", 36 "user": "me-test", 37 "pass": "pass", 38 "host": "127.0.0.1", 39 "_root": "", 40 }, config) 41 }) 42 43 t.Run("Error", func(t *testing.T) { 44 config, err := p.run(map[string]string{ 45 "error": "potato", 46 }) 47 assert.Nil(t, config) 48 require.Error(t, err) 49 require.Contains(t, err.Error(), "potato") 50 }) 51 52 t.Run("Obscure", func(t *testing.T) { 53 config, err := p.run(map[string]string{ 54 "type": "ftp", 55 "user": "me", 56 "pass": "pass", 57 "host": "127.0.0.1", 58 "_obscure": "pass,user", 59 }) 60 require.NoError(t, err) 61 config["user"] = obscure.MustReveal(config["user"]) 62 config["pass"] = obscure.MustReveal(config["pass"]) 63 assert.Equal(t, configmap.Simple{ 64 "type": "ftp", 65 "user": "me-test", 66 "pass": "pass", 67 "host": "127.0.0.1", 68 "_obscure": "pass,user", 69 "_root": "", 70 }, config) 71 }) 72 73 const testUser = "testUser" 74 const testPass = "testPass" 75 76 t.Run("call w/Password", func(t *testing.T) { 77 // check cache empty 78 assert.Equal(t, 0, p.vfsCache.Entries()) 79 defer p.vfsCache.Clear() 80 81 passwordBytes := []byte(testPass) 82 value, err := p.call(testUser, testPass, false) 83 require.NoError(t, err) 84 entry, ok := value.(cacheEntry) 85 require.True(t, ok) 86 87 // check hash is correct in entry 88 assert.Equal(t, entry.pwHash, sha256.Sum256(passwordBytes)) 89 require.NotNil(t, entry.vfs) 90 f := entry.vfs.Fs() 91 require.NotNil(t, f) 92 assert.Equal(t, "proxy-"+testUser, f.Name()) 93 assert.True(t, strings.HasPrefix(f.String(), "Local file system")) 94 95 // check it is in the cache 96 assert.Equal(t, 1, p.vfsCache.Entries()) 97 cacheValue, ok := p.vfsCache.GetMaybe(testUser) 98 assert.True(t, ok) 99 assert.Equal(t, value, cacheValue) 100 }) 101 102 t.Run("Call w/Password", func(t *testing.T) { 103 // check cache empty 104 assert.Equal(t, 0, p.vfsCache.Entries()) 105 defer p.vfsCache.Clear() 106 107 vfs, vfsKey, err := p.Call(testUser, testPass, false) 108 require.NoError(t, err) 109 require.NotNil(t, vfs) 110 assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name()) 111 assert.Equal(t, testUser, vfsKey) 112 113 // check it is in the cache 114 assert.Equal(t, 1, p.vfsCache.Entries()) 115 cacheValue, ok := p.vfsCache.GetMaybe(testUser) 116 assert.True(t, ok) 117 cacheEntry, ok := cacheValue.(cacheEntry) 118 assert.True(t, ok) 119 assert.Equal(t, vfs, cacheEntry.vfs) 120 121 // Test Get works while we have something in the cache 122 t.Run("Get", func(t *testing.T) { 123 assert.Equal(t, vfs, p.Get(testUser)) 124 assert.Nil(t, p.Get("unknown")) 125 }) 126 127 // now try again from the cache 128 vfs, vfsKey, err = p.Call(testUser, testPass, false) 129 require.NoError(t, err) 130 require.NotNil(t, vfs) 131 assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name()) 132 assert.Equal(t, testUser, vfsKey) 133 134 // check cache is at the same level 135 assert.Equal(t, 1, p.vfsCache.Entries()) 136 137 // now try again from the cache but with wrong password 138 vfs, vfsKey, err = p.Call(testUser, testPass+"wrong", false) 139 require.Error(t, err) 140 require.Contains(t, err.Error(), "incorrect password") 141 require.Nil(t, vfs) 142 require.Equal(t, "", vfsKey) 143 144 // check cache is at the same level 145 assert.Equal(t, 1, p.vfsCache.Entries()) 146 147 }) 148 149 privateKey, privateKeyErr := rsa.GenerateKey(rand.Reader, 2048) 150 if privateKeyErr != nil { 151 log.Fatal("error generating test private key " + privateKeyErr.Error()) 152 } 153 publicKey, publicKeyError := ssh.NewPublicKey(&privateKey.PublicKey) 154 if privateKeyErr != nil { 155 log.Fatal("error generating test public key " + publicKeyError.Error()) 156 } 157 158 publicKeyString := base64.StdEncoding.EncodeToString(publicKey.Marshal()) 159 160 t.Run("Call w/PublicKey", func(t *testing.T) { 161 // check cache empty 162 assert.Equal(t, 0, p.vfsCache.Entries()) 163 defer p.vfsCache.Clear() 164 165 value, err := p.call(testUser, publicKeyString, true) 166 require.NoError(t, err) 167 entry, ok := value.(cacheEntry) 168 require.True(t, ok) 169 170 // check publicKey is correct in entry 171 require.NoError(t, err) 172 require.NotNil(t, entry.vfs) 173 f := entry.vfs.Fs() 174 require.NotNil(t, f) 175 assert.Equal(t, "proxy-"+testUser, f.Name()) 176 assert.True(t, strings.HasPrefix(f.String(), "Local file system")) 177 178 // check it is in the cache 179 assert.Equal(t, 1, p.vfsCache.Entries()) 180 cacheValue, ok := p.vfsCache.GetMaybe(testUser) 181 assert.True(t, ok) 182 assert.Equal(t, value, cacheValue) 183 }) 184 185 t.Run("call w/PublicKey", func(t *testing.T) { 186 // check cache empty 187 assert.Equal(t, 0, p.vfsCache.Entries()) 188 defer p.vfsCache.Clear() 189 190 vfs, vfsKey, err := p.Call( 191 testUser, 192 publicKeyString, 193 true, 194 ) 195 require.NoError(t, err) 196 require.NotNil(t, vfs) 197 assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name()) 198 assert.Equal(t, testUser, vfsKey) 199 200 // check it is in the cache 201 assert.Equal(t, 1, p.vfsCache.Entries()) 202 cacheValue, ok := p.vfsCache.GetMaybe(testUser) 203 assert.True(t, ok) 204 cacheEntry, ok := cacheValue.(cacheEntry) 205 assert.True(t, ok) 206 assert.Equal(t, vfs, cacheEntry.vfs) 207 208 // Test Get works while we have something in the cache 209 t.Run("Get", func(t *testing.T) { 210 assert.Equal(t, vfs, p.Get(testUser)) 211 assert.Nil(t, p.Get("unknown")) 212 }) 213 214 // now try again from the cache 215 vfs, vfsKey, err = p.Call(testUser, publicKeyString, true) 216 require.NoError(t, err) 217 require.NotNil(t, vfs) 218 assert.Equal(t, "proxy-"+testUser, vfs.Fs().Name()) 219 assert.Equal(t, testUser, vfsKey) 220 221 // check cache is at the same level 222 assert.Equal(t, 1, p.vfsCache.Entries()) 223 224 // now try again from the cache but with wrong public key 225 vfs, vfsKey, err = p.Call(testUser, publicKeyString+"wrong", true) 226 require.Error(t, err) 227 require.Contains(t, err.Error(), "incorrect public key") 228 require.Nil(t, vfs) 229 require.Equal(t, "", vfsKey) 230 231 // check cache is at the same level 232 assert.Equal(t, 1, p.vfsCache.Entries()) 233 }) 234 }