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