Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test the Authenticate function #38

Merged
merged 5 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/datasetArchiver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ func main() {
inputdatasetList = args[0:]
}

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
minottic marked this conversation as resolved.
Show resolved Hide resolved
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

archivableDatasets := datasetUtils.GetArchivableDatasets(client, APIServer, ownerGroup, inputdatasetList, user["accessToken"])
if len(archivableDatasets) > 0 {
Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetCleaner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ func main() {
return
}

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

if user["username"] != "archiveManager" {
log.Fatalf("You must be archiveManager to be allowed to delete datasets\n")
Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetGetProposal/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ func main() {
return
}

user, accessGroups := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, accessGroups := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)
proposal := datasetUtils.GetProposal(client, APIServer, ownerGroup, user, accessGroups)
// proposal is of type map[string]interface{}

Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetIngestor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ func main() {
return
}

user, accessGroups := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, accessGroups := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

/* TODO Add info about policy settings and that autoarchive will take place or not */

Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetPublishData/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ func createWebpage(urls []string, title string, doi string, datasetDetails []dat

// set value in publishedData ==============================

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

type PublishedDataPart struct {
DownloadLink string `json:"downloadLink"`
Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetPublishDataRetrieve/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ func main() {
return
}

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

datasetList, _, _ := datasetUtils.GetDatasetsOfPublication(client, APIServer, *publishedDataId)

Expand Down
3 changes: 2 additions & 1 deletion cmd/datasetRetriever/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ func main() {
return
}

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

datasetList := datasetUtils.GetAvailableDatasets(user["username"], RSYNCServer, *datasetId)

Expand Down
3 changes: 2 additions & 1 deletion cmd/waitForJobFinished/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ func main() {
return
}

user, _ := datasetUtils.Authenticate(client, APIServer, token, userpass)
auth := &datasetUtils.RealAuthenticator{}
user, _ := datasetUtils.Authenticate(auth, client, APIServer, token, userpass)

filter := `{"where":{"id":"` + *jobId + `"}}`

Expand Down
27 changes: 24 additions & 3 deletions datasetUtils/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import (
"syscall"
)

func Authenticate(httpClient *http.Client, APIServer string, token *string, userpass *string) (map[string]string, []string) {
// Authenticate handles user authentication by prompting the user for their credentials,
// validating these credentials against the authentication server,
// and returning an authentication token if the credentials are valid.
// This token can then be used for authenticated requests to the server.
// If the credentials are not valid, the function returns an error.
func Authenticate(auth Authenticator, httpClient *http.Client, APIServer string, token *string, userpass *string) (map[string]string, []string) {
user := make(map[string]string)
accessGroups := make([]string, 0)

Expand Down Expand Up @@ -37,9 +42,9 @@ func Authenticate(httpClient *http.Client, APIServer string, token *string, user
}
username = strings.Split(*userpass, ":")[0]
}
user, accessGroups = AuthenticateUser(httpClient, APIServer, username, password)
user, accessGroups = auth.AuthenticateUser(httpClient, APIServer, username, password)
} else {
user, accessGroups = GetUserInfoFromToken(httpClient, APIServer, *token)
user, accessGroups = auth.GetUserInfoFromToken(httpClient, APIServer, *token)
// extract password if defined in userpass value
u := strings.Split(*userpass, ":")
if len(u) == 2 {
Expand All @@ -48,3 +53,19 @@ func Authenticate(httpClient *http.Client, APIServer string, token *string, user
}
return user, accessGroups
}

// An interface with the methods so that we can mock them in tests
type Authenticator interface {
AuthenticateUser(httpClient *http.Client, APIServer string, username string, password string) (map[string]string, []string)
GetUserInfoFromToken(httpClient *http.Client, APIServer string, token string) (map[string]string, []string)
}

type RealAuthenticator struct{}

func (r *RealAuthenticator) AuthenticateUser(httpClient *http.Client, APIServer string, username string, password string) (map[string]string, []string) {
return AuthenticateUser(httpClient, APIServer, username, password)
}

func (r *RealAuthenticator) GetUserInfoFromToken(httpClient *http.Client, APIServer string, token string) (map[string]string, []string) {
return GetUserInfoFromToken(httpClient, APIServer, token)
}
93 changes: 93 additions & 0 deletions datasetUtils/authenticate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package datasetUtils

import (
"net/http"
"net/http/httptest"
"reflect"
"testing"
)

// Create a mock implementation of the interface
type MockAuthenticator struct{}

func (m *MockAuthenticator) AuthenticateUser(httpClient *http.Client, APIServer string, username string, password string) (map[string]string, []string) {
if username == "" && password == "" {
return map[string]string{}, []string{}
}
return map[string]string{"username": "testuser", "password": "testpass"}, []string{"group1", "group2"}
minottic marked this conversation as resolved.
Show resolved Hide resolved
}

func (m *MockAuthenticator) GetUserInfoFromToken(httpClient *http.Client, APIServer string, token string) (map[string]string, []string) {
return map[string]string{"username": "tokenuser", "password": "tokenpass"}, []string{"group3", "group4"}
}

func TestAuthenticate(t *testing.T) {
var auth Authenticator = &MockAuthenticator{}
// Mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`{"username": "testuser", "accessGroups": ["group1", "group2"]}`))
}))
defer server.Close()

// Test cases
tests := []struct {
name string
token string
userpass string
wantUser map[string]string
wantGroup []string
}{
{
name: "Test with token",
token: "testtoken",
userpass: "",
wantUser: map[string]string{
"username": "tokenuser",
"password": "tokenpass",
},
wantGroup: []string{"group3", "group4"},
},
{
name: "Test with empty token and userpass",
token: "",
userpass: "",
wantUser: map[string]string{},
wantGroup: []string{},
},
{
name: "Test with empty token and non-empty userpass",
token: "",
userpass: "testuser:testpass",
wantUser: map[string]string{
"username": "testuser",
"password": "testpass",
},
wantGroup: []string{"group1", "group2"},
},
{
name: "Test with non-empty token and empty userpass",
token: "testtoken",
userpass: "",
wantUser: map[string]string{
"username": "tokenuser",
"password": "tokenpass",
},
wantGroup: []string{"group3", "group4"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpClient := server.Client()
user, group := Authenticate(auth, httpClient, server.URL, &tt.token, &tt.userpass)

if !reflect.DeepEqual(user, tt.wantUser) {
t.Errorf("got %v, want %v", user, tt.wantUser)
}

if !reflect.DeepEqual(group, tt.wantGroup) {
t.Errorf("got %v, want %v", group, tt.wantGroup)
}
})
}
}
Loading