blob: a47daabfcae795ad2241b78d21150868905834e1 [file] [log] [blame]
// 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)
}
}