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

CLI now supports auth tokens filtered by loginId #283

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2ae2cd0
CLI now supports tokens filtered by loginId
aashir21 Sep 13, 2024
676dd21
Implemented the changes requested
aashir21 Sep 18, 2024
906919f
Resolved conflicts
aashir21 Sep 18, 2024
edd8753
Added error msg
aashir21 Sep 18, 2024
89bbd85
CLI now supports tokens filtered by loginId
aashir21 Sep 13, 2024
967d8c8
Implemented the changes requested
aashir21 Sep 18, 2024
364a909
Update runs get to use cursor-based pagination (#273)
eamansour Aug 27, 2024
27454b1
JVM launching -D parameters should be passed before the -jar paramete…
techcobweb Aug 27, 2024
7e0165a
CLI should handle long and multi-line property values better. (#274)
techcobweb Aug 27, 2024
e80f286
Add copyright and remove argo app param
jadecarino Aug 30, 2024
b9e61dc
Disabling gradle cache to avoid build problems
jadecarino Sep 10, 2024
f590606
Change the CLI's base image to ubuntu so it has bash
jadecarino Sep 12, 2024
dca021e
Empty commit for build
jadecarino Sep 12, 2024
ea2126b
Remove maven cache
jadecarino Sep 13, 2024
9e3868e
Signing off commits
aashir21 Sep 18, 2024
1097a3c
Install ca certs into galasactl images
jadecarino Sep 16, 2024
874ef86
change based on comments
jadecarino Sep 16, 2024
2876b32
Remove isolated trigger - now in Tekton pipeline
jadecarino Sep 16, 2024
6b8c585
testing script adjustments
jadecarino Sep 16, 2024
3aef41c
test adjusments to remote cps script
jadecarino Sep 16, 2024
8031bad
uncomment script
jadecarino Sep 16, 2024
8b8b1ec
add new image for testing purposes
jadecarino Sep 16, 2024
a84fbef
install java, maven and gradle into normal galasactl image
jadecarino Sep 16, 2024
b1ecb9d
just install gradle for now
jadecarino Sep 17, 2024
b153c0e
empty for build
jadecarino Sep 17, 2024
1060465
Fix problem with script
jadecarino Sep 17, 2024
fca9a56
add java_home env var to docker image
jadecarino Sep 17, 2024
0faa4f7
Create new testing image
jadecarino Sep 17, 2024
9d9e8ca
Empty commit to trigger rebuild
aashir21 Sep 18, 2024
2271d2a
Merge branch 'Iss1976' of https://github.com/galasa-dev/cli into Iss1976
aashir21 Sep 18, 2024
ec7bdfd
Squashed commits
aashir21 Sep 18, 2024
6248a06
Merge branch 'ash-Iss1976-signed' into Iss1976
aashir21 Sep 18, 2024
6ef959e
Merge branch 'origin/main' into Iss1976
eamansour Sep 18, 2024
ad615a2
Implemented the changes requested
aashir21 Sep 20, 2024
7a33682
Resolved conflicts
aashir21 Sep 20, 2024
28b9976
Merge branch 'main' into Iss1976
aashir21 Sep 20, 2024
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
2 changes: 2 additions & 0 deletions docs/generated/errors-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ The `galasactl` tool can generate the following errors:
- GAL1162E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are: '{}'
- GAL1163E: The run named '{}' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete
- GAL1164E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1165E: '{}' is not supported as a valid value. LoginId should not contain spaces.
- GAL1166E: The loginId provided by the --user field cannot be an empty string.
- GAL1225E: Failed to open file '{}' cause: {}. Check that this file exists, and that you have read permissions.
- GAL1226E: Internal failure. Contents of gzip could be read, but not decoded. New gzip reader failed: file: {} error: {}
- GAL1227E: Internal failure. Contents of gzip could not be decoded. {} error: {}
Expand Down
3 changes: 2 additions & 1 deletion docs/generated/galasactl_auth_tokens_get.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ galasactl auth tokens get [flags]
### Options

```
-h, --help Displays the options for the 'auth tokens get' command.
-h, --help Displays the options for the 'auth tokens get' command.
--user string Optional. Retrieves a list of access tokens for the user with the given username.
```

### Options inherited from parent commands
Expand Down
80 changes: 63 additions & 17 deletions pkg/auth/authTokensGet.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ package auth
import (
"context"
"log"
"net/http"
"strings"

galasaErrors "github.com/galasa-dev/cli/pkg/errors"
"github.com/galasa-dev/cli/pkg/galasaapi"
Expand All @@ -19,38 +21,82 @@ import (
func GetTokens(
apiClient *galasaapi.APIClient,
console spi.Console,
loginId string,
) error {

authTokens, err := getAuthTokensFromRestApi(apiClient)
authTokens, err := getAuthTokensFromRestApi(apiClient, loginId)

if err == nil {
summaryFormatter := tokensformatter.NewTokenSummaryFormatter()
err = formatFetchedTokensAndWriteToConsole(authTokens, console)
}

return err
}

func getAuthTokensFromRestApi(apiClient *galasaapi.APIClient, loginId string) ([]galasaapi.AuthToken, error) {
var context context.Context = nil
var authTokens []galasaapi.AuthToken
var err error

apiCall := apiClient.AuthenticationAPIApi.GetTokens(context)

var outputText string
outputText, err = summaryFormatter.FormatTokens(authTokens)
if loginId != "" {

loginId, err = validateLoginIdFlag(loginId)

if err == nil {
console.WriteString(outputText)
apiCall = apiCall.LoginId(loginId)
}
}

if err == nil {

var tokens *galasaapi.AuthTokens
var resp *http.Response

tokens, resp, err = apiCall.Execute()

if err != nil {
log.Println("getAuthTokensFromRestApi - Failed to retrieve list of tokens from API server")
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_RETRIEVING_TOKEN_LIST_FROM_API_SERVER, err.Error())
} else {
defer resp.Body.Close()
authTokens = tokens.GetTokens()
log.Printf("getAuthTokensFromRestApi - %v tokens collected", len(authTokens))
}
}

return authTokens, err
}

func formatFetchedTokensAndWriteToConsole(authTokens []galasaapi.AuthToken, console spi.Console) error {

summaryFormatter := tokensformatter.NewTokenSummaryFormatter()

outputText, err := summaryFormatter.FormatTokens(authTokens)

if err == nil {
console.WriteString(outputText)
}

return err

}

func getAuthTokensFromRestApi(apiClient *galasaapi.APIClient) ([]galasaapi.AuthToken, error) {
var context context.Context = nil
var authTokens []galasaapi.AuthToken
func validateLoginIdFlag(loginId string) (string, error) {

tokens, resp, err := apiClient.AuthenticationAPIApi.GetTokens(context).Execute()
var err error

if err != nil {
log.Println("getAuthTokensFromRestApi - Failed to retrieve list of tokens from API server")
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_RETRIEVING_TOKEN_LIST_FROM_API_SERVER, err.Error())
} else {
defer resp.Body.Close()
authTokens = tokens.GetTokens()
log.Printf("getAuthTokensFromRestApi - %v tokens collected", len(authTokens))
loginId = strings.TrimSpace(loginId)
hasSpace := strings.Contains(loginId, " ")

if loginId == "" {
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_USER_FLAG_VALUE)
}

return authTokens, err
if hasSpace {
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_LOGIN_ID, loginId)
}

return loginId, err
}
92 changes: 89 additions & 3 deletions pkg/auth/authTokensGet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,33 @@ func mockAuthTokensServlet(t *testing.T, writer http.ResponseWriter, request *ht
body = `{
"tokens":[]
}`
} else if state == "missingLoginIdFlag" {
statusCode = 400
body = `{"error_code": 1155,"error_message": "GAL1155E: The id provided by the --id field cannot be an empty string."}`
} else if state == "invalidLoginIdFlag" {
statusCode = 400
body = `{"error_code": 1157,"error_message": "GAL1157E: '%s' is not supported as a valid value. Valid value should not contain spaces. A value of 'admin' is valid but 'galasa admin' is not."}`
} else if state == "populatedByLoginId" {
body = `{
"tokens":[
{
"token_id":"098234980123-1283182389",
"creation_time":"2023-12-03T18:25:43.511Z",
"owner": {
"login_id":"mcobbett"
},
"description":"So I can access ecosystem1 from my laptop."
},
{
"token_id":"8218971d287s1-dhj32er2323",
"creation_time":"2024-03-03T09:36:50.511Z",
"owner": {
"login_id":"mcobbett"
},
"description":"Automated build of example repo can change CPS properties"
}
]
}`
} else {
statusCode = 500
body = `{"error_code": 5000,"error_message": "GAL5000E: Error occured when trying to access the endpoint. Report the problem to your Galasa Ecosystem owner."}`
Expand All @@ -86,7 +113,7 @@ Total:3
`

//When
err := GetTokens(apiClient, console)
err := GetTokens(apiClient, console, "")

//Then
assert.Nil(t, err)
Expand All @@ -104,7 +131,7 @@ func TestNoTokensPathReturnsOk(t *testing.T) {
expectedOutput := "Total:0\n"

//When
err := GetTokens(apiClient, console)
err := GetTokens(apiClient, console, "")

//Then
assert.Nil(t, err)
Expand All @@ -121,10 +148,69 @@ func TestInvalidPathReturnsError(t *testing.T) {
console := utils.NewMockConsole()

//When
err := GetTokens(apiClient, console)
err := GetTokens(apiClient, console, "admin")

//Then
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "GAL1146E")
assert.Contains(t, err.Error(), "Could not get list of tokens from API server")
}

func TestMissingLoginIdFlagReturnsBadRequest(t *testing.T) {
//Given...
serverState := "missingLoginId"
server := NewAuthTokensServletMock(t, serverState)
apiClient := api.InitialiseAPI(server.URL)
defer server.Close()

console := utils.NewMockConsole()
expectedOutput := `GAL1166E: The loginId provided by the --user field cannot be an empty string.`

//When
err := GetTokens(apiClient, console, " ")

//Then
assert.NotNil(t, err)
assert.Equal(t, expectedOutput, err.Error())
}

func TestLoginIdWithSpacesReturnsBadRequest(t *testing.T) {
//Given...
serverState := "invalidLoginIdFlag"
server := NewAuthTokensServletMock(t, serverState)
apiClient := api.InitialiseAPI(server.URL)
defer server.Close()

console := utils.NewMockConsole()
expectedOutput := `GAL1165E: 'galasa admin' is not supported as a valid value. LoginId should not contain spaces.`

//When
err := GetTokens(apiClient, console, "galasa admin")

//Then
assert.NotNil(t, err)
assert.Equal(t, expectedOutput, err.Error())
}

func TestGetTokensByLoginIdReturnsOK(t *testing.T) {
//Given...
serverState := "populatedByLoginId"
server := NewAuthTokensServletMock(t, serverState)
apiClient := api.InitialiseAPI(server.URL)
defer server.Close()

console := utils.NewMockConsole()
expectedOutput := `tokenid created(YYYY-MM-DD) user description
098234980123-1283182389 2023-12-03 mcobbett So I can access ecosystem1 from my laptop.
8218971d287s1-dhj32er2323 2024-03-03 mcobbett Automated build of example repo can change CPS properties

Total:2
`

//When
err := GetTokens(apiClient, console, "mcobbett")

//Then
assert.Nil(t, err)
assert.Equal(t, expectedOutput, console.ReadText())
}
aashir21 marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions pkg/cmd/authTokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

type AuthTokensCmdValues struct {
bootstrap string
loginId string
}

type AuthTokensCommand struct {
Expand Down Expand Up @@ -76,3 +77,4 @@ func (cmd *AuthTokensCommand) createAuthTokensCobraCmd(

return authTokensCmd, err
}

13 changes: 11 additions & 2 deletions pkg/cmd/authTokensGet.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func (cmd *AuthTokensGetCommand) createCobraCmd(

var err error

authTokensGetCommandValues := authTokensCommand.Values().(*AuthTokensCmdValues)
authGetTokensCobraCmd := &cobra.Command{
Use: "get",
Short: "Get a list of authentication tokens",
Expand All @@ -84,6 +85,7 @@ func (cmd *AuthTokensGetCommand) createCobraCmd(
},
}

addLoginIdFlagToAuthTokensGet(authGetTokensCobraCmd, authTokensGetCommandValues)
authTokensCommand.CobraCommand().AddCommand(authGetTokensCobraCmd)

return authGetTokensCobraCmd, err
Expand Down Expand Up @@ -133,12 +135,19 @@ func (cmd *AuthTokensGetCommand) executeAuthTokensGet(
apiClient, err = authenticator.GetAuthenticatedAPIClient()

if err == nil {
// Call to process the command in a unit-testable way.
err = auth.GetTokens(apiClient, console)
err = auth.GetTokens(apiClient, console, authTokenCmdValues.loginId)
}
}
}
}

return err
}

func addLoginIdFlagToAuthTokensGet(cmd *cobra.Command, authTokensGetCmdValues *AuthTokensCmdValues) {

flagName := "user"
var description string = "Optional. Retrieves a list of access tokens for the user with the given username."

cmd.Flags().StringVar(&authTokensGetCmdValues.loginId, flagName, "", description)
}
18 changes: 10 additions & 8 deletions pkg/errors/errorMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,16 +250,18 @@ var (
GALASA_ERROR_MISSING_USER_LOGIN_ID_FLAG = NewMessageType("GAL1155E: The id provided by the --id field cannot be an empty string.", 1155, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_LOGIN_ID_NOT_SUPPORTED = NewMessageType("GAL1156E: '%s' is not supported as a valid value. Valid values are 'me'.", 1156, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUN_FAILED = NewMessageType("GAL1157E: An attempt to delete a run named '%s' failed. Cause is %s", 1157, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_SERVER_DELETE_RUNS_FAILED = NewMessageType("GAL1158E: An attempt to delete a run named '%s' failed. Sending the delete request to the Galasa service failed. Cause is %v", 1158, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_SERVER_DELETE_RUNS_FAILED = NewMessageType("GAL1158E: An attempt to delete a run named '%s' failed. Sending the delete request to the Galasa service failed. Cause is %v", 1158, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_LOGIN_ID = NewMessageType("GAL1165E: '%s' is not supported as a valid value. LoginId should not contain spaces.", 1165, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_USER_FLAG_VALUE = NewMessageType("GAL1166E: The loginId provided by the --user field cannot be an empty string.", 1166, STACK_TRACE_NOT_WANTED)

// 4 related but slightly different errors, when an HTTP response arrives from the Galasa server, and we can/can't parse the payload to get the message details out.
GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT = NewMessageType("GAL1159E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server.", 1159, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_RESPONSE_PAYLOAD_UNREADABLE = NewMessageType("GAL1160E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server could not be read. Cause: %s", 1160, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_UNPARSEABLE_CONTENT = NewMessageType("GAL1161E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in a valid json format. Cause: '%s'", 1161, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_SERVER_REPORTED_ERROR = NewMessageType("GAL1162E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are: '%s'", 1162, STACK_TRACE_NOT_WANTED)
// 4 related but slightly different errors, when an HTTP response arrives from the Galasa server, and we can/can't parse the payload to get the message details out.
GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT = NewMessageType("GAL1159E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server.", 1159, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_RESPONSE_PAYLOAD_UNREADABLE = NewMessageType("GAL1160E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server could not be read. Cause: %s", 1160, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_UNPARSEABLE_CONTENT = NewMessageType("GAL1161E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in a valid json format. Cause: '%s'", 1161, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_SERVER_REPORTED_ERROR = NewMessageType("GAL1162E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are: '%s'", 1162, STACK_TRACE_NOT_WANTED)

GALASA_ERROR_SERVER_DELETE_RUN_NOT_FOUND = NewMessageType("GAL1163E: The run named '%s' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete", 1163, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_EXPLANATION_NOT_JSON = NewMessageType("GAL1164E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1164, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_SERVER_DELETE_RUN_NOT_FOUND = NewMessageType("GAL1163E: The run named '%s' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete", 1163, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_EXPLANATION_NOT_JSON = NewMessageType("GAL1164E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1164, STACK_TRACE_NOT_WANTED)

// Warnings...
GALASA_WARNING_MAVEN_NO_GALASA_OBR_REPO = NewMessageType("GAL2000W: Warning: Maven configuration file settings.xml should contain a reference to a Galasa repository so that the galasa OBR can be resolved. The official release repository is '%s', and 'pre-release' repository is '%s'", 2000, STACK_TRACE_WANTED)
Expand Down
3 changes: 3 additions & 0 deletions test-galasactl-ecosystem.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ properties_tests
source ${BASEDIR}/test-scripts/resources-tests.sh --bootstrap "${bootstrap}"
resources_tests

source ${BASEDIR}/test-scripts/auth-tests.sh --bootstrap "${bootstrap}"
auth_tests

# Test the hybrid configuration where the local test runs locally, but
# draws it's CPS properties from a remote ecosystem via a REST extension.
source ${BASEDIR}/test-scripts/test-local-run-remote-cps.sh
Expand Down
Loading