Skip to content

Commit

Permalink
u
Browse files Browse the repository at this point in the history
  • Loading branch information
zepatrik committed Sep 3, 2020
1 parent 1b5f9ab commit e207a6a
Show file tree
Hide file tree
Showing 21 changed files with 535 additions and 349 deletions.
84 changes: 84 additions & 0 deletions .schema/create_identity_params.schema.json
@@ -0,0 +1,84 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"definitions": {
"verifiable_address": {
"type": "object",
"required": ["id", "value", "verified", "via", "expires_at"],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"value": {
"type": "string"
},
"verified": {
"type": "boolean"
},
"via": {
"type": "string",
"enum": [
"email"
]
},
"verified_at": {
"type": "string",
"format": "date-time"
},
"expires_at": {
"type": "string",
"format": "date-time"
}
}
},
"recovery_address": {
"type": "object",
"required": ["id", "value", "via"],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"value": {
"type": "string"
},
"via": {
"type": "string",
"enum": [
"email"
]
}
}
}
},
"required": ["id", "schema_id", "traits"],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"schema_id": {
"type": "string"
},
"schema_url": {
"type": "string",
"format": "uri"
},
"traits": {
"description": "The traits have to be validated according to \"schema_url\"."
},
"verifiable_addresses": {
"type": "array",
"items": {
"$ref": "#/definitions/verifiable_address"
}
},
"recovery_addresses": {
"type": "array",
"items": {
"$ref": "#/definitions/recovery_address"
}
}
}
}
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -76,7 +76,7 @@ sdk: .bin/swagger .bin/cli
swagger generate spec -m -o .schema/api.swagger.json -x internal/httpclient
cli dev swagger sanitize ./.schema/api.swagger.json
swagger validate ./.schema/api.swagger.json
swagger flatten --with-flatten=remove-unused -o ./.schema/api.swagger.json ./.schema/api.swagger.json
# swagger flatten --with-flatten=remove-unused -o ./.schema/api.swagger.json ./.schema/api.swagger.json
swagger validate ./.schema/api.swagger.json
rm -rf internal/httpclient
mkdir -p internal/httpclient
Expand Down
37 changes: 37 additions & 0 deletions cmd/cliclient/client.go
@@ -0,0 +1,37 @@
package cliclient

import (
"fmt"
"net/url"
"os"

"github.com/spf13/pflag"

"github.com/ory/kratos/internal/httpclient/client"
"github.com/ory/x/cmdx"
)

const (
envKeyEndpoint = "KRATOS_ADMIN_ENDPOINT"
)

var endpoint string

func NewClient() *client.OryKratos {
if endpoint == "" {
endpoint = os.Getenv(envKeyEndpoint)
}

u, err := url.Parse(endpoint)
cmdx.Must(err, `Could not parse the endpoint URL "%s".`, endpoint)

return client.NewHTTPClientWithConfig(nil, &client.TransportConfig{
Host: u.Host,
BasePath: u.Path,
Schemes: []string{u.Scheme},
})
}

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))
}
2 changes: 1 addition & 1 deletion cmd/client/identity.go → cmd/cliclient/identity.go
@@ -1,4 +1,4 @@
package client
package cliclient

import (
"github.com/spf13/cobra"
Expand Down
2 changes: 1 addition & 1 deletion cmd/client/migrate.go → cmd/cliclient/migrate.go
@@ -1,4 +1,4 @@
package client
package cliclient

import (
"bufio"
Expand Down
28 changes: 0 additions & 28 deletions cmd/client/client.go

This file was deleted.

42 changes: 39 additions & 3 deletions cmd/identities/import.go
@@ -1,13 +1,49 @@
package identities

import (
"bytes"
"context"
"encoding/json"

"github.com/spf13/cobra"

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

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

for _, fn := range args {
fc := validateIdentityFile(fn, c)

// 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)

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

//i.Traits = traits
//i.SchemaID = pointerx.String(schemaID.String())

_, err = c.Admin.CreateIdentity(&admin.CreateIdentityParams{
Body: &i,
Context: context.Background(),
})
cmdx.Must(err, "%s: Could not create identity: %s", fn, err)
}
},
}
49 changes: 49 additions & 0 deletions cmd/identities/list.go
@@ -0,0 +1,49 @@
package identities

import (
"context"
"fmt"
"strconv"

"github.com/spf13/cobra"

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

var listCmd = &cobra.Command{
Use: "list [<page> <per-page>]",
Args: func(cmd *cobra.Command, args []string) error {
// zero or exactly two args
if len(args) != 0 && len(args) != 2 {
return fmt.Errorf("expected zero or two args, got %d", len(args))
}
return nil
},
Aliases: []string{"ls"},
Run: func(cmd *cobra.Command, args []string) {
c := cliclient.NewClient()

params := &admin.ListIdentitiesParams{
Context: context.Background(),
}

if len(args) == 2 {
page, err := strconv.ParseInt(args[0], 0, 64)
cmdx.Must(err, "Could not parse page argument\"%s\": %s", args[0], err)
params.Page = &page

perPage, err := strconv.ParseInt(args[1], 0, 64)
cmdx.Must(err, "Could not parse per-page argument\"%s\": %s", args[1], err)
params.PerPage = &perPage
}

resp, err := c.Admin.ListIdentities(params)
cmdx.Must(err, "Could not get the identities: %s", err)

for _, i := range resp.Payload {
fmt.Println(i.ID)
}
},
}
6 changes: 5 additions & 1 deletion cmd/identities/root.go
Expand Up @@ -2,6 +2,8 @@ package identities

import (
"github.com/spf13/cobra"

"github.com/ory/kratos/cmd/cliclient"
)

// identitiesCmd represents the identity command
Expand All @@ -13,8 +15,10 @@ func RegisterCommandRecursive(parent *cobra.Command) {
parent.AddCommand(identitiesCmd)

identitiesCmd.AddCommand(importCmd)
identitiesCmd.AddCommand(validateCmd)
identitiesCmd.AddCommand(listCmd)
}

func init() {
identitiesCmd.PersistentFlags().String("endpoint", "", "Specifies the Ory Kratos Admin URL. Defaults to KRATOS_URLS_ADMIN")
cliclient.RegisterClientFlags(identitiesCmd.PersistentFlags())
}
85 changes: 85 additions & 0 deletions cmd/identities/validate.go
@@ -0,0 +1,85 @@
package identities

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"

"github.com/markbates/pkger"
"github.com/spf13/cobra"
"github.com/tidwall/gjson"

"github.com/ory/jsonschema/v3"
"github.com/ory/kratos/cmd/cliclient"
"github.com/ory/kratos/internal/httpclient/client"
"github.com/ory/kratos/internal/httpclient/client/common"
"github.com/ory/x/cmdx"
"github.com/ory/x/viperx"
)

var validateCmd = &cobra.Command{
Use: "validate <file.json [file-2.json [file-3.json] ...]>",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
c := cliclient.NewClient()

for _, fn := range args {
validateIdentityFile(fn, c)
}

fmt.Println("All identity files are valid.")
},
}

func validateIdentityFile(fn string, c *client.OryKratos) []byte {
fc, err := ioutil.ReadFile(fn)
cmdx.Must(err, `%s: Could not open identity file: %s`, fn, err)

sid := gjson.GetBytes(fc, "schema_id")
if !sid.Exists() {
_, _ = fmt.Fprintf(os.Stderr, "%s: Expected key \"schema_id\" to be defined.\n", fn)
os.Exit(1)
}

f, err := pkger.Open("/.schema/identity.schema.json")
cmdx.Must(err, "%s: Could not open the identity schema: %s", fn, err)

identitySchema, err := ioutil.ReadAll(f)
cmdx.Must(err, "%s: Could not read the identity schema: %s", fn, err)

s, err := jsonschema.CompileString("identity.schema.json", string(identitySchema))
cmdx.Must(err, "%s: Could not compile the identity schema: %s", fn, err)

var foundValidationErrors bool
err = s.Validate(bytes.NewBuffer(fc))
if err != nil {
fmt.Printf("%s: not valid\n", fn)
viperx.PrintHumanReadableValidationErrors(os.Stderr, err)
foundValidationErrors = true
}

ts, err := c.Common.GetSchema(&common.GetSchemaParams{ID: sid.String(), Context: context.Background()})
cmdx.Must(err, `%s: Could not fetch schema with ID "%s": %s`, fn, sid.String(), err)

traitsSchema, err := json.Marshal(ts.Payload)
cmdx.Must(err, "%s: Could not marshal the traits schema: %s", fn, err)

s, err = jsonschema.CompileString("identity_traits.schema.json", string(traitsSchema))
cmdx.Must(err, "%s: Could not compile the traits schema: %s", fn, err)

err = s.Validate(bytes.NewBuffer(fc))
if err != nil {
fmt.Printf("%s: not valid\n", fn)
viperx.PrintHumanReadableValidationErrors(os.Stderr, err)
foundValidationErrors = true
}

if foundValidationErrors {
os.Exit(1)
}

return fc
}

0 comments on commit e207a6a

Please sign in to comment.