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 and refactor GetUserInfoFromToken #70

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
68 changes: 68 additions & 0 deletions datasetUtils/GetUserInfoFromToken_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package datasetUtils

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

func TestGetUserInfoFromToken(t *testing.T) {
// Test case: Valid token and user is found
{
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`{"currentUser": "testUser", "currentUserEmail": "[email protected]", "currentGroups": ["group1", "group2"]}`))
}))
defer server.Close()

client := server.Client()
userInfo, groups, err := GetUserInfoFromToken(client, server.URL, "validToken")
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
if userInfo["username"] != "testUser" || userInfo["mail"] != "[email protected]" || len(groups) != 2 {
t.Errorf("GetUserInfoFromToken failed, expected %v, got %v", "testUser", userInfo["username"])
}
}

// Test case: Server returns valid response but user is not found
{
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`{"currentUser": "", "currentUserEmail": "", "currentGroups": []}`))
}))
defer server.Close()

client := server.Client()
_, _, err := GetUserInfoFromToken(client, server.URL, "validToken")
if err == nil {
t.Errorf("Expected error for user not found, got nil")
}
}

// Test case: Server returns invalid JSON
{
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`invalid JSON`))
}))
defer server.Close()

client := server.Client()
_, _, err := GetUserInfoFromToken(client, server.URL, "validToken")
if err == nil {
t.Errorf("Expected error for invalid JSON, got nil")
}
}

// Test case: Server returns non-200 status code
{
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(http.StatusUnauthorized)
}))
defer server.Close()

client := server.Client()
_, _, err := GetUserInfoFromToken(client, server.URL, "invalidToken")
if err == nil {
t.Errorf("Expected error for non-200 status code, got nil")
}
}
}
7 changes: 6 additions & 1 deletion datasetUtils/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@
}
user, accessGroups = auth.AuthenticateUser(httpClient, APIServer, username, password)
} else {
user, accessGroups = auth.GetUserInfoFromToken(httpClient, APIServer, *token)
var err error
user, accessGroups, err = GetUserInfoFromToken(httpClient, APIServer, *token)
if err != nil {
log.Fatalf("Failed to get user info from token: %v", err)
}

// extract password if defined in userpass value
u := strings.Split(*userpass, ":")
if len(u) == 2 {
Expand All @@ -67,5 +72,5 @@
}

func (r *RealAuthenticator) GetUserInfoFromToken(httpClient *http.Client, APIServer string, token string) (map[string]string, []string) {
return GetUserInfoFromToken(httpClient, APIServer, token)

Check failure on line 75 in datasetUtils/authenticate.go

View workflow job for this annotation

GitHub Actions / test-linux

too many return values

Check failure on line 75 in datasetUtils/authenticate.go

View workflow job for this annotation

GitHub Actions / test-windows

too many return values
}
61 changes: 35 additions & 26 deletions datasetUtils/getUserInfoFromToken.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package datasetUtils

import (
"encoding/json"
"io/ioutil"
"log"
"fmt"
"net/http"
)

Expand All @@ -13,42 +13,51 @@ type UserInfo struct {
CurrentGroups []string `json:"currentGroups"`
}

func GetUserInfoFromToken(client *http.Client, APIServer string, token string) (map[string]string, []string) {
/* GetUserInfoFromToken makes a GET request to the provided APIServer with the provided token to fetch user information.

Parameters: client: An *http.Client object to make the HTTP request. APIServer: A string representing the URL of the API server. token: A string representing the user's access token.

Returns: A map[string]string where the keys are "username", "mail", "displayName", and "accessToken", and the values are the corresponding user information. A slice of strings representing the groups the user is a member of.

If the HTTP request fails or the response status code is not 200, the function will log the error and terminate the program. If the user information cannot be unmarshalled into the UserInfo struct or the user cannot be mapped to the token, the function will log the error and terminate the program. */
func GetUserInfoFromToken(client *http.Client, APIServer string, token string) (map[string]string, []string, error) {
u := make(map[string]string)
accessGroups := make([]string, 0)

url := APIServer + "/Users/userInfos?access_token=" + token
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}

req.Header.Set("Content-Type", "application/json")

resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return nil, nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)

if resp.StatusCode != 200 {
log.Fatalf("Could not login with token:%v, status %v", token, resp.StatusCode)

if resp.StatusCode != http.StatusOK {
return nil, nil, fmt.Errorf("server responded with status code %d", resp.StatusCode)
}

var respObj UserInfo
err = json.Unmarshal(body, &respObj)
if err != nil {
log.Fatal(err)
if err := json.NewDecoder(resp.Body).Decode(&respObj); err != nil {
return nil, nil, fmt.Errorf("failed to decode response: %w", err)
}

if respObj.CurrentUser != "" {
//log.Printf("Found the following user for this token %v", respObj[0])
u["username"] = respObj.CurrentUser
u["mail"] = respObj.CurrentUserEmail
u["displayName"] = respObj.CurrentUser
u["accessToken"] = token
log.Printf("User authenticated: %s %s\n", u["displayName"], u["mail"])
accessGroups = respObj.CurrentGroups
log.Printf("User is member in following groups: %v\n", accessGroups)
} else {
log.Fatalf("Could not map a user to the token %v", token)

if respObj.CurrentUser == "" {
return nil, nil, fmt.Errorf("could not map a user to the token %s", token)
}
return u, accessGroups

u["username"] = respObj.CurrentUser
u["mail"] = respObj.CurrentUserEmail
u["displayName"] = respObj.CurrentUser
u["accessToken"] = token
log.Printf("User authenticated: %s %s\n", u["displayName"], u["mail"])
accessGroups = respObj.CurrentGroups
log.Printf("User is member in following groups: %v\n", accessGroups)

return u, accessGroups, nil
}
Loading