Skip to content

Commit

Permalink
feat: finish off client cli
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik committed Sep 7, 2020
1 parent e207a6a commit 36d60c7
Show file tree
Hide file tree
Showing 21 changed files with 914 additions and 192 deletions.
315 changes: 271 additions & 44 deletions .schema/api.swagger.json

Large diffs are not rendered by default.

84 changes: 0 additions & 84 deletions .schema/create_identity_params.schema.json

This file was deleted.

10 changes: 7 additions & 3 deletions cmd/cliclient/client.go
Expand Up @@ -5,6 +5,8 @@ import (
"net/url"
"os"

"github.com/spf13/cobra"

"github.com/spf13/pflag"

"github.com/ory/kratos/internal/httpclient/client"
Expand All @@ -13,11 +15,13 @@ import (

const (
envKeyEndpoint = "KRATOS_ADMIN_ENDPOINT"
flagEndpoint = "endpoint"
)

var endpoint string
func NewClient(cmd *cobra.Command) *client.OryKratos {
endpoint, err := cmd.Flags().GetString(flagEndpoint)
cmdx.Must(err, "flag access error: %s", err)

func NewClient() *client.OryKratos {
if endpoint == "" {
endpoint = os.Getenv(envKeyEndpoint)
}
Expand All @@ -33,5 +37,5 @@ func NewClient() *client.OryKratos {
}

func RegisterClientFlags(flags *pflag.FlagSet) {
flags.StringVarP(&endpoint, "endpoint", "e", "", fmt.Sprintf("The upstream admin endpoint URL. Alternatively set using the %s environmental variable.", envKeyEndpoint))
flags.StringP(flagEndpoint, flagEndpoint[:1], "", fmt.Sprintf("The upstream admin endpoint URL. Alternatively set using the %s environmental variable.", envKeyEndpoint))
}
91 changes: 91 additions & 0 deletions cmd/identities/definitions.go
@@ -0,0 +1,91 @@
package identities

import (
"strings"

"github.com/ory/kratos/internal/clihelpers"
"github.com/ory/kratos/internal/httpclient/models"
)

type (
outputIdentity models.Identity
outputIdentityCollection struct {
identities []*models.Identity
}
)

func (_ *outputIdentity) Header() []string {
return []string{"ID", "VERIFIED ADDRESSES", "RECOVERY ADDRESSES", "SCHEMA ID", "SCHEMA URL"}
}

func (i *outputIdentity) Fields() []string {
data := [5]string{
string(i.ID),
clihelpers.None,
clihelpers.None,
clihelpers.None,
i.SchemaURL,
}

addresses := make([]string, 0, len(i.VerifiableAddresses))
for _, a := range i.VerifiableAddresses {
if a.Value != nil {
addresses = append(addresses, *a.Value)
}
}
data[1] = strings.Join(addresses, ", ")

addresses = addresses[:0]
for _, a := range i.RecoveryAddresses {
if a.Value != nil {
addresses = append(addresses, *a.Value)
}
}
data[2] = strings.Join(addresses, ", ")

if i.SchemaID != nil {
data[3] = *i.SchemaID
}

return data[:]
}

func (i *outputIdentity) Interface() interface{} {
return i
}

func (_ *outputIdentityCollection) Header() []string {
return []string{"ID", "VERIFIED ADDRESS 1", "RECOVERY ADDRESS 1", "SCHEMA ID", "SCHEMA URL"}
}

func (c *outputIdentityCollection) Table() [][]string {
rows := make([][]string, len(c.identities))
for i, ident := range c.identities {
data := [5]string{
string(ident.ID),
clihelpers.None,
clihelpers.None,
clihelpers.None,
ident.SchemaURL,
}

if len(ident.VerifiableAddresses) != 0 && ident.VerifiableAddresses[0].Value != nil {
data[1] = *ident.VerifiableAddresses[0].Value
}

if len(ident.RecoveryAddresses) != 0 && ident.RecoveryAddresses[0].Value != nil {
data[2] = *ident.RecoveryAddresses[0].Value
}

if ident.SchemaID != nil {
data[3] = *ident.SchemaID
}

rows[i] = data[:]
}
return rows
}

func (c *outputIdentityCollection) Interface() interface{} {
return c.identities
}
49 changes: 49 additions & 0 deletions cmd/identities/delete.go
@@ -0,0 +1,49 @@
package identities

import (
"context"
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/ory/kratos/cmd/cliclient"
"github.com/ory/kratos/internal/httpclient/client/admin"
)

var deleteCmd = &cobra.Command{
Use: "delete",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cliclient.NewClient(cmd)

var (
deleted = make([]string, 0, len(args))
errs []error
)

for _, a := range args {
_, err := c.Admin.DeleteIdentity(&admin.DeleteIdentityParams{
ID: a,
Context: context.Background(),
})
if err != nil {
errs = append(errs, err)
continue
}
deleted = append(deleted, a)
}

for _, d := range deleted {
fmt.Println(d)
}

for _, err := range errs {
fmt.Fprintln(os.Stderr, err)
}

if len(errs) != 0 {
os.Exit(1)
}
},
}
28 changes: 28 additions & 0 deletions cmd/identities/get.go
@@ -0,0 +1,28 @@
package identities

import (
"context"

"github.com/spf13/cobra"

"github.com/ory/kratos/cmd/cliclient"
"github.com/ory/kratos/internal/clihelpers"
"github.com/ory/kratos/internal/httpclient/client/admin"
"github.com/ory/x/cmdx"
)

var getCmd = &cobra.Command{
Use: "get <id>",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cliclient.NewClient(cmd)

resp, err := c.Admin.GetIdentity(&admin.GetIdentityParams{
ID: args[0],
Context: context.Background(),
})
cmdx.Must(err, "Could not get identity \"%s\": %s", args[0], err)

clihelpers.PrintRow(cmd, (*outputIdentity)(resp.Payload))
},
}
79 changes: 56 additions & 23 deletions cmd/identities/import.go
Expand Up @@ -4,9 +4,13 @@ import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"os"

"github.com/spf13/cobra"

"github.com/ory/kratos/internal/clihelpers"

"github.com/ory/kratos/cmd/cliclient"
"github.com/ory/kratos/internal/httpclient/client/admin"
"github.com/ory/kratos/internal/httpclient/models"
Expand All @@ -15,35 +19,64 @@ import (

// importCmd represents the import command
var importCmd = &cobra.Command{
Use: "import <file.json [file-2.json [file-3.json] ...]>",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cliclient.NewClient()
Use: "import <file.json [file-2.json [file-3.json] ...]>",
Run: importIdentities,
}

for _, fn := range args {
fc := validateIdentityFile(fn, c)
func importIdentities(cmd *cobra.Command, args []string) {
c := cliclient.NewClient(cmd)

// because the model.Identity does not come with the Marshal/Unmarshal
// methods of identity.Identity, we have to work around them
//traits := gjson.GetBytes(fc, "traits")
//schemaID := gjson.GetBytes(fc, "schema_id")
//fc, err := sjson.DeleteBytes(fc, "traits")
//cmdx.Must(err, "%s: Unexpected error removing traits: %s", fn, err)
//fc, err = sjson.DeleteBytes(fc, "schema_id")
//cmdx.Must(err, "%s: Unexpected error removing schema_id: %s", fn, err)
imported := &outputIdentityCollection{
identities: make([]*models.Identity, 0, len(args)),
}
failed := make(map[string]error)

var i models.Identity
err := json.NewDecoder(bytes.NewBuffer(fc)).Decode(&i)
cmdx.Must(err, "%s: Could not parse identity file: %s", fn, fc)
if len(args) == 0 {
fc, err := ioutil.ReadAll(os.Stdin)
cmdx.Must(err, "Could not read from STD_IN: %s", err)

//i.Traits = traits
//i.SchemaID = pointerx.String(schemaID.String())
validateIdentity("STD_IN", fc, c)

_, err = c.Admin.CreateIdentity(&admin.CreateIdentityParams{
Body: &i,
var params models.CreateIdentityRequestPayload
err = json.NewDecoder(bytes.NewBuffer(fc)).Decode(&params)
cmdx.Must(err, "STD_IN: Could not parse identity: %s", err)

resp, err := c.Admin.CreateIdentity(&admin.CreateIdentityParams{
Body: &params,
Context: context.Background(),
})

if err != nil {
failed["STD_IN"] = err
} else {
imported.identities = append(imported.identities, resp.Payload)
}
} else {
for _, fn := range args {
fc := validateIdentityFile(fn, c)

var params models.CreateIdentityRequestPayload
err := json.NewDecoder(bytes.NewBuffer(fc)).Decode(&params)
cmdx.Must(err, "%s: Could not parse identity file: %s", fn, err)

resp, err := c.Admin.CreateIdentity(&admin.CreateIdentityParams{
Body: &params,
Context: context.Background(),
})
cmdx.Must(err, "%s: Could not create identity: %s", fn, err)

if err != nil {
failed[fn] = err
continue
}

imported.identities = append(imported.identities, resp.Payload)
}
},
}

clihelpers.PrintCollection(cmd, imported)
clihelpers.PrintErrors(cmd, failed)

if len(failed) != 0 {
os.Exit(1)
}
}

0 comments on commit 36d60c7

Please sign in to comment.