Skip to content

Commit

Permalink
refactor: rename hydra clients list command
Browse files Browse the repository at this point in the history
Renames the command to `hydra list client` and changes CLI flags.

BREAKING CHANGE: Command `hydra clients list` is now `hydra list client`. Please notice that the pagination flags have changed to `--page-token` and `page-size`!
  • Loading branch information
aeneasr committed Sep 7, 2022
1 parent dea2fdd commit 1c0f971
Show file tree
Hide file tree
Showing 29 changed files with 718 additions and 180 deletions.
40 changes: 0 additions & 40 deletions cmd/cli/handler_client.go
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/ory/hydra/internal/httpclient/models"
"github.com/ory/x/cmdx"
"github.com/ory/x/flagx"
"github.com/ory/x/pointerx"
)

type ClientHandler struct{}
Expand Down Expand Up @@ -152,42 +151,3 @@ func (h *ClientHandler) DeleteClient(cmd *cobra.Command, args []string) {

fmt.Println("OAuth 2.0 Client(s) deleted")
}

func (h *ClientHandler) ListClients(cmd *cobra.Command, args []string) {
m := ConfigureClient(cmd)

limit := flagx.MustGetInt(cmd, "limit")
page := flagx.MustGetInt(cmd, "page")
offset := (limit * page) - limit

response, err := m.Admin.ListOAuth2Clients(admin.NewListOAuth2ClientsParams().WithLimit(pointerx.Int64(int64(limit))).WithOffset(pointerx.Int64(int64(offset))))
cmdx.Must(err, "The request failed with the following error message:\n%s", FormatSwaggerError(err))
cls := response.Payload

table := newTable()
table.SetHeader([]string{
"Client ID",
"Name",
"Response Types",
"Scope",
"Redirect Uris",
"Grant Types",
"Token Endpoint Auth Method",
})

data := make([][]string, len(cls))
for i, cl := range cls {
data[i] = []string{
cl.ClientID,
cl.ClientName,
strings.Join(cl.ResponseTypes, ","),
cl.Scope,
strings.Join(cl.RedirectUris, "\n"),
strings.Join(cl.GrantTypes, ","),
cl.TokenEndpointAuthMethod,
}
}

table.AppendBulk(data)
table.Render()
}
22 changes: 0 additions & 22 deletions cmd/clients_list.go

This file was deleted.

4 changes: 3 additions & 1 deletion cmd/cmd_delete_client.go
Expand Up @@ -22,9 +22,11 @@ package cmd

import (
"fmt"

"github.com/spf13/cobra"

"github.com/ory/hydra/cmd/cliclient"
"github.com/ory/x/cmdx"
"github.com/spf13/cobra"
)

func NewDeleteClientCmd(root *cobra.Command) *cobra.Command {
Expand Down
12 changes: 7 additions & 5 deletions cmd/cmd_delete_client_test.go
Expand Up @@ -4,16 +4,18 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ory/hydra/cmd"
"github.com/ory/x/assertx"
"github.com/ory/x/cmdx"
"github.com/ory/x/snapshotx"
"github.com/ory/x/sqlcon"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"strings"
"testing"
)

func TestDeleteClient(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion cmd/cmd_get_client.go
Expand Up @@ -22,10 +22,12 @@ package cmd

import (
"fmt"

"github.com/spf13/cobra"

hydra "github.com/ory/hydra-client-go"
"github.com/ory/hydra/cmd/cliclient"
"github.com/ory/x/cmdx"
"github.com/spf13/cobra"
)

func NewGetClientsCmd(root *cobra.Command) *cobra.Command {
Expand Down
10 changes: 6 additions & 4 deletions cmd/cmd_get_client_test.go
Expand Up @@ -3,14 +3,16 @@ package cmd_test
import (
"context"
"encoding/json"
"github.com/ory/hydra/cmd"
"github.com/ory/x/cmdx"
"github.com/ory/x/snapshotx"
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"testing"

"github.com/ory/hydra/cmd"
"github.com/ory/x/cmdx"
"github.com/ory/x/snapshotx"
)

func TestGetClient(t *testing.T) {
Expand Down
10 changes: 6 additions & 4 deletions cmd/cmd_helper_test.go
Expand Up @@ -3,6 +3,12 @@ package cmd_test
import (
"context"
"encoding/base64"
"io/ioutil"
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/require"

"github.com/ory/hydra/client"
"github.com/ory/hydra/cmd/cliclient"
"github.com/ory/hydra/driver"
Expand All @@ -11,10 +17,6 @@ import (
"github.com/ory/x/cmdx"
"github.com/ory/x/contextx"
"github.com/ory/x/snapshotx"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
"io/ioutil"
"testing"
)

func base64EncodedPGPPublicKey(t *testing.T) string {
Expand Down
20 changes: 20 additions & 0 deletions cmd/cmd_list.go
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/spf13/cobra"

"github.com/ory/hydra/cmd/cliclient"
"github.com/ory/x/cmdx"
)

func NewListCmd(root *cobra.Command) *cobra.Command {
var cmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Short: "List resources",
}
cmd.AddCommand(NewListClientsCmd(root))
cliclient.RegisterClientFlags(cmd.PersistentFlags())
cmdx.RegisterFormatFlags(cmd.PersistentFlags())
return cmd
}
54 changes: 54 additions & 0 deletions cmd/cmd_list_clients.go
@@ -0,0 +1,54 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"

"github.com/ory/hydra/cmd/cliclient"
"github.com/ory/x/cmdx"
)

func NewListClientsCmd(root *cobra.Command) *cobra.Command {
cmd := &cobra.Command{
Use: "clients",
Short: "List OAuth 2.0 Clients",
Long: `This command list an OAuth 2.0 Clients.`,
Args: cobra.NoArgs,
Example: fmt.Sprintf("%s ls identities --%s eyJwYWdlIjoxfQ --%s 10", root.Use, cmdx.FlagPageToken, cmdx.FlagPageSize),
RunE: func(cmd *cobra.Command, args []string) error {
m, err := cliclient.NewClient(cmd)
if err != nil {
return err
}

pageToken, pageSize, err := cmdx.ParseTokenPaginationArgs(cmd)
if err != nil {
return err
}

list, resp, err := m.AdminApi.ListOAuth2Clients(cmd.Context()).PageSize(int64(pageSize)).PageToken(pageToken).Execute()
if err != nil {
return cmdx.PrintOpenAPIError(cmd, err)
}

var collection outputOAuth2ClientCollection
for k := range list {
collection.clients = append(collection.clients, list[k])
}

interfaceList := make([]interface{}, len(list))
for k := range collection.clients {
interfaceList[k] = interface{}(&list[k])
}

result := &cmdx.PaginatedList{Items: interfaceList, Collection: collection}
result.NextPageToken = getPageToken(resp)
result.IsLastPage = result.NextPageToken == ""
cmdx.PrintTable(cmd, result)
return nil
},
}
cmdx.RegisterTokenPaginationFlags(cmd)
return cmd
}
45 changes: 45 additions & 0 deletions cmd/cmd_list_clients_test.go
@@ -0,0 +1,45 @@
package cmd_test

import (
"github.com/ory/hydra/client"
"github.com/stretchr/testify/require"
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"

"github.com/ory/hydra/cmd"
"github.com/ory/x/cmdx"
)

func TestListClient(t *testing.T) {
c := cmd.NewListClientsCmd(new(cobra.Command))
reg := setup(t, c)

expected1 := createClient(t, reg, nil)
expected2 := createClient(t, reg, nil)

t.Run("case=lists both clients", func(t *testing.T) {
actual := gjson.Parse(cmdx.ExecNoErr(t, c))
assert.Len(t, actual.Get("items").Array(), 2)

for _, e := range []*client.Client{expected1, expected2} {
assert.Contains(t, actual.Raw, e.GetID())
}
})

t.Run("case=lists both clients with pagination", func(t *testing.T) {
actualFirst := gjson.Parse(cmdx.ExecNoErr(t, c, "--format", "json", "--page-size", "1"))
assert.Len(t, actualFirst.Get("items").Array(), 1)

require.NotEmpty(t, actualFirst.Get("next_page_token").String(), actualFirst.Raw)
assert.False(t, actualFirst.Get("is_last_page").Bool(), actualFirst.Raw)

actualSecond := gjson.Parse(cmdx.ExecNoErr(t, c, "--format", "json", "--page-size", "1", "--page-token", actualFirst.Get("next_page_token").String()))
assert.Len(t, actualSecond.Array(), 1)

assert.NotEmpty(t, actualFirst.Get("items.0.client_id").String())
assert.NotEqualValues(t, actualFirst.Get("items.0.client_id").String(), actualSecond.Get("items.0.client_id").String())
})
}
22 changes: 22 additions & 0 deletions cmd/helper.go
Expand Up @@ -22,6 +22,9 @@ package cmd

import (
"fmt"
"github.com/tomnomnom/linkheader"
"net/http"
"net/url"
"os"
)

Expand All @@ -31,3 +34,22 @@ func fatal(message string, args ...interface{}) {
fmt.Printf(message+"\n", args...)
osExit(1)
}

func getPageToken(resp *http.Response) string {
for _, link := range linkheader.Parse(resp.Header.Get("Link")) {
if link.Rel != "next" {
continue
}

parsed, err := url.Parse(link.URL)
if err != nil {
continue
}

if pageToken := parsed.Query().Get("page_token"); len(pageToken) > 0 {
return pageToken
}
}

return ""
}
11 changes: 11 additions & 0 deletions cmd/helper_test.go
@@ -1,6 +1,10 @@
package cmd

import (
"github.com/ory/x/pagination/tokenpagination"
"github.com/stretchr/testify/assert"
"net/http/httptest"
"net/url"
"testing"
)

Expand All @@ -19,3 +23,10 @@ func TestFatal(t *testing.T) {
t.Errorf("Expected exit code: %d, got: %d", exp, got)
}
}

func TestGetPageToken(t *testing.T) {
u, _ := url.Parse("https://example.com/foobar")
rec := httptest.NewRecorder()
tokenpagination.PaginationHeader(rec, u, 100, 3, 10)
assert.Equal(t, `eyJwYWdlIjoiNDAiLCJ2IjoxfQ`, getPageToken(rec.Result()), rec.Result().Header.Get("Link"))
}
8 changes: 8 additions & 0 deletions cmd/output_client.go
Expand Up @@ -54,3 +54,11 @@ func (c outputOAuth2ClientCollection) Interface() interface{} {
func (c outputOAuth2ClientCollection) Len() int {
return len(c.clients)
}

func (c outputOAuth2ClientCollection) IDs() []string {
ids := make([]string, len(c.clients))
for i, client := range c.clients {
ids[i] = fmt.Sprintf("%v", client.ClientId)
}
return ids
}
6 changes: 4 additions & 2 deletions cmd/root.go
Expand Up @@ -50,14 +50,16 @@ func RegisterCommandRecursive(parent *cobra.Command) {
parent.AddCommand(deleteCmd)
getCmd.AddCommand(NewDeleteClientCmd(parent))

listCmd := NewListCmd(parent)
parent.AddCommand(listCmd)
getCmd.AddCommand(NewListClientsCmd(parent))

// Clients
clientCmd := NewClientsCmd()
parent.AddCommand(clientCmd)
clientCmd.AddCommand(NewClientsImportCmd())
clientCmd.AddCommand(NewClientsListCmd())
clientCmd.AddCommand(NewKeysImportCmd())
clientCmd.AddCommand(NewClientsUpdateCmd())

parent.AddCommand(NewJanitorCmd())

keyCmd := NewKeysCmd()
Expand Down
2 changes: 1 addition & 1 deletion cmd/token_user.go
Expand Up @@ -82,7 +82,7 @@ var tokenUserResult = template.Must(template.New("").Parse(`<html>
<li>ID Token: <code>{{ .IDToken }}</code></li>
</ul>
{{ if .DisplayBackButton }}
<a href="{{ .BackURL }}">Back to Welcome Page</a>
<a href="{{ .BackURL }}">Back to Welcome PageToken</a>
{{ end }}
</body>
</html>`))
Expand Down

0 comments on commit 1c0f971

Please sign in to comment.