Files
object-browser/restapi/user_login_test.go
Lenin Alevski 0ba1e76400 centralize errors on a single error function (#266)
prepareError receives an array of errors and return *model.Error object
with a message and error code, we can extend this function to add more
error types/code
2020-09-04 20:32:57 -07:00

198 lines
5.9 KiB
Go

// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package restapi
import (
"context"
"errors"
"testing"
"github.com/minio/console/pkg/auth"
"github.com/minio/console/pkg/auth/idp/oauth2"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio/cmd/config"
"github.com/minio/minio/pkg/madmin"
"github.com/stretchr/testify/assert"
)
// Define a mock struct of ConsoleCredentials interface implementation
type consoleCredentialsMock struct{}
// Common mocks
var consoleCredentialsGetMock func() (credentials.Value, error)
// mock function of Get()
func (ac consoleCredentialsMock) Get() (credentials.Value, error) {
return consoleCredentialsGetMock()
}
func TestLogin(t *testing.T) {
funcAssert := assert.New(t)
consoleCredentials := consoleCredentialsMock{}
// Test Case 1: Valid consoleCredentials
consoleCredentialsGetMock = func() (credentials.Value, error) {
return credentials.Value{
AccessKeyID: "fakeAccessKeyID",
SecretAccessKey: "fakeSecretAccessKey",
SessionToken: "fakeSessionToken",
SignerType: 0,
}, nil
}
jwt, err := login(consoleCredentials, []string{""})
funcAssert.NotEmpty(jwt, "JWT was returned empty")
funcAssert.Nil(err, "error creating a session")
// Test Case 2: Invalid credentials
consoleCredentialsGetMock = func() (credentials.Value, error) {
return credentials.Value{}, errors.New("")
}
_, err = login(consoleCredentials, []string{""})
funcAssert.NotNil(err, "not error returned creating a session")
}
type IdentityProviderClientMock struct{}
var idpVerifyIdentityMock func(ctx context.Context, code, state string) (*oauth2.User, error)
var idpGenerateLoginURLMock func() string
func (ac IdentityProviderClientMock) VerifyIdentity(ctx context.Context, code, state string) (*oauth2.User, error) {
return idpVerifyIdentityMock(ctx, code, state)
}
func (ac IdentityProviderClientMock) GenerateLoginURL() string {
return idpGenerateLoginURLMock()
}
// TestLoginOauth2Auth is the main function that test the Oauth2 Authentication
func TestLoginOauth2Auth(t *testing.T) {
ctx := context.Background()
funcAssert := assert.New(t)
// mock data
mockCode := "EAEAEAE"
mockState := "HUEHUEHUE"
idpClientMock := IdentityProviderClientMock{}
identityProvider := &auth.IdentityProvider{Client: idpClientMock}
// Test-1 : loginOauth2Auth() correctly authenticates the user
idpVerifyIdentityMock = func(ctx context.Context, code, state string) (*oauth2.User, error) {
return &oauth2.User{}, nil
}
function := "loginOauth2Auth()"
_, err := loginOauth2Auth(ctx, identityProvider, mockCode, mockState)
if err != nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
}
// Test-2 : loginOauth2Auth() returns an error
idpVerifyIdentityMock = func(ctx context.Context, code, state string) (*oauth2.User, error) {
return nil, errors.New("error")
}
if _, err := loginOauth2Auth(ctx, identityProvider, mockCode, mockState); funcAssert.Error(err) {
funcAssert.Equal(errInvalidCredentials.Error(), err.Error())
}
}
func Test_getConfiguredRegion(t *testing.T) {
client := adminClientMock{}
type args struct {
client adminClientMock
}
tests := []struct {
name string
args args
want string
mock func()
}{
// If MinIO returns an error, we return empty region name
{
name: "region",
args: args{
client: client,
},
want: "",
mock: func() {
// mock function response from getConfig()
minioGetConfigKVMock = func(key string) ([]byte, error) {
return nil, errors.New("invalid config")
}
// mock function response from listConfig()
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
return madmin.Help{}, errors.New("no help")
}
},
},
// MinIO returns an empty region name
{
name: "region",
args: args{
client: client,
},
want: "",
mock: func() {
// mock function response from getConfig()
minioGetConfigKVMock = func(key string) ([]byte, error) {
return []byte("region name= "), nil
}
// mock function response from listConfig()
minioHelpConfigKVMock = func(subSys, key string, envOnly bool) (madmin.Help, error) {
return madmin.Help{
SubSys: config.RegionSubSys,
Description: "label the location of the server",
MultipleTargets: false,
KeysHelp: []madmin.HelpKV{
{
Key: "name",
Description: "name of the location of the server e.g. \"us-west-rack2\"",
Optional: true,
Type: "string",
MultipleTargets: false,
},
{
Key: "comment",
Description: "optionally add a comment to this setting",
Optional: true,
Type: "sentence",
MultipleTargets: false,
},
},
}, nil
}
},
},
// MinIO returns the asia region
{
name: "region",
args: args{
client: client,
},
want: "asia",
mock: func() {
minioGetConfigKVMock = func(key string) ([]byte, error) {
return []byte("region name=asia "), nil
}
},
},
}
for _, tt := range tests {
tt.mock()
t.Run(tt.name, func(t *testing.T) {
if got, _ := getConfiguredRegionForLogin(tt.args.client); got != tt.want {
t.Errorf("getConfiguredRegionForLogin() = %v, want %v", got, tt.want)
}
})
}
}