| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package auth |
| |
| import ( |
| "encoding/json" |
| "net/http" |
| "net/http/httptest" |
| "os" |
| "path/filepath" |
| "testing" |
| |
| "github.com/apache/openserverless-cli/config" |
| "github.com/mitchellh/go-homedir" |
| "github.com/stretchr/testify/require" |
| "github.com/zalando/go-keyring" |
| ) |
| |
| // setupMockServer sets up a new mock HTTP server with the given test data and expected response |
| func setupMockServer(t *testing.T, expectedLogin, expectedPass, expectedRes string) *httptest.Server { |
| t.Helper() |
| server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| var requestBody map[string]string |
| err := json.NewDecoder(r.Body).Decode(&requestBody) |
| if err != nil { |
| http.Error(w, err.Error(), http.StatusBadRequest) |
| return |
| } |
| |
| login, ok := requestBody["login"] |
| require.True(t, ok, "expected login field in request body") |
| require.Equal(t, expectedLogin, login, "expected login %s, got %s", expectedLogin, login) |
| |
| password, ok := requestBody["password"] |
| require.True(t, ok, "expected password field in request body") |
| require.Equal(t, expectedPass, password, "expected password %s, got %s", expectedPass, password) |
| |
| _, _ = w.Write([]byte(expectedRes)) |
| })) |
| |
| return server |
| } |
| func TestLoginCmd(t *testing.T) { |
| homeDir, _ := homedir.Expand("~/.ops") |
| os.MkdirAll(homeDir, 0755) |
| os.Setenv("OPS_HOME", homeDir) |
| |
| keyring.MockInit() |
| |
| t.Run("error: returns error when empty password", func(t *testing.T) { |
| oldPwdReader := pwdReader |
| pwdReader = &stubPasswordReader{ |
| Password: "", |
| ReturnError: false, |
| } |
| os.Args = []string{"login", "fakeApiHost", "fakeUser"} |
| res, err := LoginCmd() |
| pwdReader = oldPwdReader |
| if err == nil { |
| t.Error("Expected error, got nil") |
| } |
| if err.Error() != "password is empty" { |
| t.Errorf("Expected error to be 'password is empty', got %s", err.Error()) |
| } |
| if res != nil { |
| t.Errorf("Expected response to be nil, got %v", res) |
| } |
| }) |
| |
| t.Run("with only apihost, add received credentials", func(t *testing.T) { |
| mockServer := setupMockServer(t, "nuvolaris", "a password", "{\"AUTH\": \"test\"}") |
| defer mockServer.Close() |
| |
| oldPwdReader := pwdReader |
| pwdReader = &stubPasswordReader{ |
| Password: "a password", |
| ReturnError: false, |
| } |
| |
| os.Args = []string{"login", mockServer.URL} |
| loginResult, err := LoginCmd() |
| pwdReader = oldPwdReader |
| |
| require.NoError(t, err) |
| require.NotNil(t, loginResult) |
| |
| // cred, err := keyring.Get(opsSecretServiceName, "AUTH") |
| opsHome, err := homedir.Expand("~/.ops") |
| require.NoError(t, err) |
| |
| configMap, err := config.NewConfigMapBuilder(). |
| WithConfigJson(filepath.Join(opsHome, "config.json")). |
| Build() |
| require.NoError(t, err) |
| |
| v, err := configMap.Get("AUTH") |
| require.NoError(t, err) |
| require.Equal(t, "test", v) |
| }) |
| |
| t.Run("with apihost and user adds received credentials to secret store", func(t *testing.T) { |
| mockServer := setupMockServer(t, "a user", "a password", "{ \"AUTH\": \"testauth\", \"fakeCred\": \"test\"}") |
| defer mockServer.Close() |
| |
| oldPwdReader := pwdReader |
| pwdReader = &stubPasswordReader{ |
| Password: "a password", |
| ReturnError: false, |
| } |
| |
| os.Args = []string{"login", mockServer.URL, "a user"} |
| loginResult, err := LoginCmd() |
| pwdReader = oldPwdReader |
| require.NoError(t, err) |
| require.NotNil(t, loginResult) |
| |
| // cred, err := keyring.Get(opsSecretServiceName, "fakeCred") |
| // require.NoError(t, err) |
| // require.Equal(t, "test", cred) |
| |
| opsHome, err := homedir.Expand("~/.ops") |
| require.NoError(t, err) |
| |
| configMap, err := config.NewConfigMapBuilder(). |
| WithConfigJson(filepath.Join(opsHome, "config.json")). |
| Build() |
| require.NoError(t, err) |
| |
| v, err := configMap.Get("AUTH") |
| require.NoError(t, err) |
| require.Equal(t, "testauth", v) |
| |
| v, err = configMap.Get("FAKECRED") |
| require.NoError(t, err) |
| require.Equal(t, "test", v) |
| }) |
| |
| t.Run("error when response body is invalid", func(t *testing.T) { |
| mockServer := setupMockServer(t, "a user", "a password", "invalid json") |
| defer mockServer.Close() |
| |
| oldPwdReader := pwdReader |
| pwdReader = &stubPasswordReader{ |
| Password: "a password", |
| ReturnError: false, |
| } |
| os.Args = []string{"login", mockServer.URL, "a user"} |
| loginResult, err := LoginCmd() |
| pwdReader = oldPwdReader |
| require.Error(t, err) |
| require.Equal(t, "failed to decode response from login request", err.Error()) |
| require.Nil(t, loginResult) |
| }) |
| |
| t.Run("error when response body is missing AUTH token", func(t *testing.T) { |
| mockServer := setupMockServer(t, "a user", "a password", "{\"fakeCred\": \"test\"}") |
| defer mockServer.Close() |
| |
| oldPwdReader := pwdReader |
| pwdReader = &stubPasswordReader{ |
| Password: "a password", |
| ReturnError: false, |
| } |
| os.Args = []string{"login", mockServer.URL, "a user"} |
| loginResult, err := LoginCmd() |
| pwdReader = oldPwdReader |
| require.Error(t, err) |
| require.Equal(t, "missing AUTH token from login response", err.Error()) |
| require.Nil(t, loginResult) |
| }) |
| } |
| |
| func Test_doLogin(t *testing.T) { |
| mockServer := setupMockServer(t, "a user", "a password", "{\"fakeCred\": \"test\"}") |
| defer mockServer.Close() |
| |
| cred, err := doLogin(mockServer.URL, "a user", "a password") |
| require.NoError(t, err) |
| require.NotNil(t, cred) |
| require.Equal(t, "test", cred["fakeCred"]) |
| } |
| |
| func Test_storeCredentials(t *testing.T) { |
| keyring.MockInit() |
| |
| fakeCreds := make(map[string]string) |
| fakeCreds["AUTH"] = "fakeValue" |
| fakeCreds["REDIS_URL"] = "fakeValue" |
| fakeCreds["MONGODB"] = "fakeValue" |
| |
| err := storeCredentials(fakeCreds) |
| require.NoError(t, err) |
| require.NotNil(t, fakeCreds) |
| |
| for k := range fakeCreds { |
| cred, err := keyring.Get(opsSecretServiceName, k) |
| require.NoError(t, err) |
| require.Equal(t, fakeCreds[k], cred) |
| } |
| } |