github.com/nuvolaris/nuv@v0.0.0-20240511174247-a74e3a52bfd8/auth/login_test.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one 2 // or more contributor license agreements. See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership. The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package auth 19 20 import ( 21 "encoding/json" 22 "net/http" 23 "net/http/httptest" 24 "os" 25 "path/filepath" 26 "testing" 27 28 "github.com/mitchellh/go-homedir" 29 "github.com/nuvolaris/nuv/config" 30 "github.com/stretchr/testify/require" 31 "github.com/zalando/go-keyring" 32 ) 33 34 // setupMockServer sets up a new mock HTTP server with the given test data and expected response 35 func setupMockServer(t *testing.T, expectedLogin, expectedPass, expectedRes string) *httptest.Server { 36 t.Helper() 37 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 38 var requestBody map[string]string 39 err := json.NewDecoder(r.Body).Decode(&requestBody) 40 if err != nil { 41 http.Error(w, err.Error(), http.StatusBadRequest) 42 return 43 } 44 45 login, ok := requestBody["login"] 46 require.True(t, ok, "expected login field in request body") 47 require.Equal(t, expectedLogin, login, "expected login %s, got %s", expectedLogin, login) 48 49 password, ok := requestBody["password"] 50 require.True(t, ok, "expected password field in request body") 51 require.Equal(t, expectedPass, password, "expected password %s, got %s", expectedPass, password) 52 53 _, _ = w.Write([]byte(expectedRes)) 54 })) 55 56 return server 57 } 58 func TestLoginCmd(t *testing.T) { 59 keyring.MockInit() 60 61 t.Run("error: returns error when empty password", func(t *testing.T) { 62 oldPwdReader := pwdReader 63 pwdReader = &stubPasswordReader{ 64 Password: "", 65 ReturnError: false, 66 } 67 os.Args = []string{"login", "fakeApiHost", "fakeUser"} 68 res, err := LoginCmd() 69 pwdReader = oldPwdReader 70 if err == nil { 71 t.Error("Expected error, got nil") 72 } 73 if err.Error() != "password is empty" { 74 t.Errorf("Expected error to be 'password is empty', got %s", err.Error()) 75 } 76 if res != nil { 77 t.Errorf("Expected response to be nil, got %v", res) 78 } 79 }) 80 81 t.Run("with only apihost, add received credentials", func(t *testing.T) { 82 mockServer := setupMockServer(t, "nuvolaris", "a password", "{\"AUTH\": \"test\"}") 83 defer mockServer.Close() 84 85 oldPwdReader := pwdReader 86 pwdReader = &stubPasswordReader{ 87 Password: "a password", 88 ReturnError: false, 89 } 90 91 os.Args = []string{"login", mockServer.URL} 92 loginResult, err := LoginCmd() 93 pwdReader = oldPwdReader 94 95 require.NoError(t, err) 96 require.NotNil(t, loginResult) 97 98 // cred, err := keyring.Get(nuvSecretServiceName, "AUTH") 99 nuvHome, err := homedir.Expand("~/.nuv") 100 require.NoError(t, err) 101 102 configMap, err := config.NewConfigMapBuilder(). 103 WithConfigJson(filepath.Join(nuvHome, "config.json")). 104 Build() 105 require.NoError(t, err) 106 107 v, err := configMap.Get("AUTH") 108 require.NoError(t, err) 109 require.Equal(t, "test", v) 110 }) 111 112 t.Run("with apihost and user adds received credentials to secret store", func(t *testing.T) { 113 mockServer := setupMockServer(t, "a user", "a password", "{ \"AUTH\": \"testauth\", \"fakeCred\": \"test\"}") 114 defer mockServer.Close() 115 116 oldPwdReader := pwdReader 117 pwdReader = &stubPasswordReader{ 118 Password: "a password", 119 ReturnError: false, 120 } 121 122 os.Args = []string{"login", mockServer.URL, "a user"} 123 loginResult, err := LoginCmd() 124 pwdReader = oldPwdReader 125 require.NoError(t, err) 126 require.NotNil(t, loginResult) 127 128 // cred, err := keyring.Get(nuvSecretServiceName, "fakeCred") 129 // require.NoError(t, err) 130 // require.Equal(t, "test", cred) 131 132 nuvHome, err := homedir.Expand("~/.nuv") 133 require.NoError(t, err) 134 135 configMap, err := config.NewConfigMapBuilder(). 136 WithConfigJson(filepath.Join(nuvHome, "config.json")). 137 Build() 138 require.NoError(t, err) 139 140 v, err := configMap.Get("AUTH") 141 require.NoError(t, err) 142 require.Equal(t, "testauth", v) 143 144 v, err = configMap.Get("FAKECRED") 145 require.NoError(t, err) 146 require.Equal(t, "test", v) 147 }) 148 149 t.Run("error when response body is invalid", func(t *testing.T) { 150 mockServer := setupMockServer(t, "a user", "a password", "invalid json") 151 defer mockServer.Close() 152 153 oldPwdReader := pwdReader 154 pwdReader = &stubPasswordReader{ 155 Password: "a password", 156 ReturnError: false, 157 } 158 os.Args = []string{"login", mockServer.URL, "a user"} 159 loginResult, err := LoginCmd() 160 pwdReader = oldPwdReader 161 require.Error(t, err) 162 require.Equal(t, "failed to decode response from login request", err.Error()) 163 require.Nil(t, loginResult) 164 }) 165 166 t.Run("error when response body is missing AUTH token", func(t *testing.T) { 167 mockServer := setupMockServer(t, "a user", "a password", "{\"fakeCred\": \"test\"}") 168 defer mockServer.Close() 169 170 oldPwdReader := pwdReader 171 pwdReader = &stubPasswordReader{ 172 Password: "a password", 173 ReturnError: false, 174 } 175 os.Args = []string{"login", mockServer.URL, "a user"} 176 loginResult, err := LoginCmd() 177 pwdReader = oldPwdReader 178 require.Error(t, err) 179 require.Equal(t, "missing AUTH token from login response", err.Error()) 180 require.Nil(t, loginResult) 181 }) 182 } 183 184 func Test_doLogin(t *testing.T) { 185 mockServer := setupMockServer(t, "a user", "a password", "{\"fakeCred\": \"test\"}") 186 defer mockServer.Close() 187 188 cred, err := doLogin(mockServer.URL, "a user", "a password") 189 require.NoError(t, err) 190 require.NotNil(t, cred) 191 require.Equal(t, "test", cred["fakeCred"]) 192 } 193 194 func Test_storeCredentials(t *testing.T) { 195 keyring.MockInit() 196 197 fakeCreds := make(map[string]string) 198 fakeCreds["AUTH"] = "fakeValue" 199 fakeCreds["REDIS_URL"] = "fakeValue" 200 fakeCreds["MONGODB"] = "fakeValue" 201 202 err := storeCredentials(fakeCreds) 203 require.NoError(t, err) 204 require.NotNil(t, fakeCreds) 205 206 for k := range fakeCreds { 207 cred, err := keyring.Get(nuvSecretServiceName, k) 208 require.NoError(t, err) 209 require.Equal(t, fakeCreds[k], cred) 210 } 211 }