Skip to content

Commit

Permalink
[FAB-7812] Fix the APIs to return info correctly
Browse files Browse the repository at this point in the history
APIs corrected to be more RESTful. Also, the response
structure for the affiliations was modified from a linear
view of affiliations to a tree structure.

Change-Id: Ie4e7ff9d1d6a7b4f1120aab0766d11452fd21cd8
Signed-off-by: Saad Karim <skarim@us.ibm.com>
  • Loading branch information
Saad Karim committed Jan 25, 2018
1 parent 0eb83eb commit ca705f6
Show file tree
Hide file tree
Showing 18 changed files with 682 additions and 285 deletions.
94 changes: 48 additions & 46 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,38 +196,46 @@ type GenCRLResponse struct {
// AddIdentityRequest represents the request to add a new identity to the
// fabric-ca-server
type AddIdentityRequest struct {
IdentityInfo `json:"info"`
ID string `json:"id" skip:"true"`
Type string `json:"type" def:"user" help:"Type of identity being registered (e.g. 'peer, app, user')"`
Affiliation string `json:"affiliation" help:"The identity's affiliation"`
Attributes []Attribute `json:"attrs" mapstructure:"attrs" `
MaxEnrollments int `json:"max_enrollments" mapstructure:"max_enrollments" def:"-1" help:"The maximum number of times the secret can be reused to enroll."`
// Secret is an optional password. If not specified,
// a random secret is generated. In both cases, the secret
// is returned in the RegistrationResponse.
Secret string `json:"secret,omitempty" mask:"password" help:"The enrollment secret for the identity being registered"`
Secret string `json:"secret,omitempty" mask:"password" help:"The enrollment secret for the identity being added"`
CAName string `json:"caname,omitempty" skip:"true"`
}

// ModifyIdentityRequest represents the request to modify an existing identity on the
// fabric-ca-server
type ModifyIdentityRequest struct {
ID string `json:"id"`
IdentityInfo `json:"info"`
// Secret is an optional password. If not specified,
// a random secret is generated. In both cases, the secret
// is returned in the RegistrationResponse.a
Secret string `json:"secret,omitempty" mask:"password"`
CAName string `json:"caname,omitempty" skip:"true"`
ID string `skip:"true"`
Type string `json:"type" def:"user" help:"Type of identity being registered (e.g. 'peer, app, user')"`
Affiliation string `json:"affiliation" help:"The identity's affiliation"`
Attributes []Attribute `mapstructure:"attrs" json:"attrs"`
MaxEnrollments int `mapstructure:"max_enrollments" json:"max_enrollments" def:"-1" help:"The maximum number of times the secret can be reused to enroll."`
Secret string `json:"secret,omitempty" mask:"password" help:"The enrollment secret for the identity"`
CAName string `json:"caname,omitempty" skip:"true"`
}

// RemoveIdentityRequest represents the request to remove an existing identity from the
// fabric-ca-server
type RemoveIdentityRequest struct {
ID string `json:"id" skip:"true"`
ID string `skip:"true"`
Force bool `json:"force"`
CAName string `json:"caname,omitempty" skip:"true"`
}

// GetIDResponse is the response from the GetIdentity call
type GetIDResponse struct {
IdentityInfo `mapstructure:",squash"`
CAName string `json:"caname,omitempty"`
ID string `json:"id" skip:"true"`
Type string `json:"type" def:"user"`
Affiliation string `json:"affiliation"`
Attributes []Attribute `json:"attrs" mapstructure:"attrs" `
MaxEnrollments int `json:"max_enrollments" mapstructure:"max_enrollments"`
CAName string `json:"caname,omitempty"`
}

// GetAllIDsResponse is the response from the GetAllIdentities call
Expand All @@ -238,67 +246,61 @@ type GetAllIDsResponse struct {

// IdentityResponse is the response from the any add/modify/remove identity call
type IdentityResponse struct {
IdentityInfo `mapstructure:",squash"`
Secret string `json:"secret,omitempty"`
CAName string `json:"caname,omitempty"`
ID string `json:"id" skip:"true"`
Type string `json:"type,omitempty"`
Affiliation string `json:"affiliation"`
Attributes []Attribute `json:"attrs,omitempty" mapstructure:"attrs"`
MaxEnrollments int `json:"max_enrollments,omitempty" mapstructure:"max_enrollments"`
Secret string `json:"secret,omitempty"`
CAName string `json:"caname,omitempty"`
}

// IdentityInfo contains information about an identity
type IdentityInfo struct {
ID string `json:"id" skip:"true"`
Type string `json:"type" def:"user" help:"Type of identity being registered (e.g. 'peer, app, user')"`
Affiliation string `json:"affiliation" help:"The identity's affiliation"`
Attributes []Attribute `mapstructure:"attrs" json:"attrs"`
MaxEnrollments int `mapstructure:"max_enrollments" json:"max_enrollments" def:"-1" help:"The maximum number of times the secret can be reused to enroll."`
}

// GetAllAffiliationsResponse is the response from the GetAllAffiliations call
type GetAllAffiliationsResponse struct {
Affiliations []AffiliationInfo `json:"affiliations"`
CAName string `json:"caname,omitempty"`
ID string `json:"id"`
Type string `json:"type"`
Affiliation string `json:"affiliation"`
Attributes []Attribute `json:"attrs" mapstructure:"attrs"`
MaxEnrollments int `json:"max_enrollments" mapstructure:"max_enrollments"`
}

// AddAffiliationRequest represents the request to add a new affiliation to the
// fabric-ca-server
type AddAffiliationRequest struct {
Info AffiliationInfo `json:"info"`
Force bool `json:"force"`
CAName string `json:"caname,omitempty"`
Name string `json:"name"`
Force bool `json:"force"`
CAName string `json:"caname,omitempty"`
}

// ModifyAffiliationRequest represents the request to modify an existing affiliation on the
// fabric-ca-server
type ModifyAffiliationRequest struct {
Name string `json:"name"`
Info AffiliationInfo `json:"info"`
Force bool `json:"force"`
CAName string `json:"caname,omitempty"`
Name string
NewName string `json:"name"`
Force bool `json:"force"`
CAName string `json:"caname,omitempty"`
}

// RemoveAffiliationRequest represents the request to remove an existing affiliation from the
// fabric-ca-server
type RemoveAffiliationRequest struct {
Name string `json:"name"`
Name string
Force bool `json:"force"`
CAName string `json:"caname,omitempty"`
}

// AffiliationWithIdentityResponse contains the response from removing an affiliation request
type AffiliationWithIdentityResponse struct {
Affiliations []AffiliationInfo `json:"affiliations"`
Identities []IdentityInfo `json:"identities"`
CAName string `json:"caname,omitempty"`
}

// AffiliationResponse is the response from the any add/modify/remove affiliation call
// AffiliationResponse contains the response for get, add, modify, and remove an affiliation
type AffiliationResponse struct {
Info AffiliationInfo `json:"info"`
CAName string `json:"caname,omitempty"`
AffiliationInfo `mapstructure:",squash"`
CAName string `json:"caname,omitempty"`
}

// AffiliationInfo contains information about the affiliation
// AffiliationInfo contains the affiliation name, child affiliation info, and identities
// associated with this affiliation.
type AffiliationInfo struct {
Name string `json:"name"`
Name string `json:"name"`
Affiliations []AffiliationInfo `json:"affiliations,omitempty"`
Identities []IdentityInfo `json:"identities,omitempty"`
}

// CSRInfo is Certificate Signing Request (CSR) Information
Expand Down
4 changes: 2 additions & 2 deletions api/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ type ModifyIdentityRequestNet struct {

// AddAffiliationRequestNet is a network request for adding a new affiliation
type AddAffiliationRequestNet struct {
Info AffiliationInfo `json:"info"`
AddAffiliationRequest
}

// ModifyAffiliationRequestNet is a network request for modifying an existing affiliation
type ModifyAffiliationRequestNet struct {
Info AffiliationInfo `json:"info"`
ModifyAffiliationRequest
}

// KeySig is a public key, signature, and signature algorithm tuple
Expand Down
37 changes: 30 additions & 7 deletions cmd/fabric-ca-client/affiliation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

"github.com/cloudflare/cfssl/log"
"github.com/hyperledger/fabric-ca/api"
"github.com/hyperledger/fabric-ca/lib"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -93,7 +92,7 @@ func (c *ClientCmd) newModifyAffiliationCommand() *cobra.Command {
}
flags := affiliationModifyCmd.Flags()
flags.StringVarP(
&c.dynamicAffiliation.modify.Info.Name, "name", "", "", "Rename the affiliation")
&c.dynamicAffiliation.modify.NewName, "name", "", "", "Rename the affiliation")
flags.BoolVarP(
&c.dynamicAffiliation.modify.Force, "force", "", false, "Forces identities using old affiliation to use new affiliation")
return affiliationModifyCmd
Expand Down Expand Up @@ -128,15 +127,16 @@ func (c *ClientCmd) runListAffiliation(cmd *cobra.Command, args []string) error
return err
}

fmt.Printf("%+v\n", resp.Info)
printTree(resp)
return nil
}

err = id.GetAllAffiliations(c.clientCfg.CAName, lib.AffiliationDecoder)
resp, err := id.GetAllAffiliations(c.clientCfg.CAName)
if err != nil {
return err
}

printTree(resp)
return nil
}

Expand All @@ -150,7 +150,7 @@ func (c *ClientCmd) runAddAffiliation(cmd *cobra.Command, args []string) error {
}

req := &api.AddAffiliationRequest{}
req.Info.Name = args[0]
req.Name = args[0]
req.CAName = c.clientCfg.CAName
req.Force = c.dynamicAffiliation.add.Force

Expand All @@ -159,7 +159,7 @@ func (c *ClientCmd) runAddAffiliation(cmd *cobra.Command, args []string) error {
return err
}

fmt.Printf("Successfully added affiliation: %+v\n", resp)
fmt.Printf("Successfully added affiliation: %+v\n", resp.Name)

return nil
}
Expand All @@ -175,7 +175,7 @@ func (c *ClientCmd) runModifyAffiliation(cmd *cobra.Command, args []string) erro

req := &api.ModifyAffiliationRequest{}
req.Name = args[0]
req.Info.Name = c.dynamicAffiliation.modify.Info.Name
req.NewName = c.dynamicAffiliation.modify.NewName
req.CAName = c.clientCfg.CAName
req.Force = c.dynamicAffiliation.modify.Force

Expand Down Expand Up @@ -228,3 +228,26 @@ func (c *ClientCmd) affiliationPreRunE(cmd *cobra.Command, args []string) error

return nil
}

func printTree(resp *api.AffiliationResponse) {
root := resp.Name
if root == "" {
root = "."
}
fmt.Printf("affiliation: %s\n", root)
printChildren(resp.Affiliations, 1)
}

func printChildren(children []api.AffiliationInfo, level int) {
if len(children) == 0 {
return
}
for _, child := range children {
spaces := ""
for i := 0; i < level; i++ {
spaces = spaces + " "
}
fmt.Printf("%saffiliation :%s\n", spaces, child.Name)
printChildren(child.Affiliations, level+1)
}
}
37 changes: 12 additions & 25 deletions cmd/fabric-ca-client/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ func (c *ClientCmd) newAddIdentityCommand() *cobra.Command {
RunE: c.runAddIdentity,
}
flags := identityAddCmd.Flags()
util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.add.IdentityInfo, nil)
flags.StringVarP(
&c.dynamicIdentity.add.Secret, "secret", "", "", "The enrollment secret for the identity being registered")
util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.add, nil)
flags.StringSliceVarP(
&c.cfgAttrs, "attrs", "", nil, "A list of comma-separated attributes of the form <name>=<value> (e.g. foo=foo1,bar=bar1)")
flags.StringVarP(
Expand All @@ -105,9 +103,7 @@ func (c *ClientCmd) newModifyIdentityCommand() *cobra.Command {
tags := map[string]string{
"skip.id": "true",
}
util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.modify.IdentityInfo, tags)
flags.StringVarP(
&c.dynamicIdentity.modify.Secret, "secret", "", "", "The enrollment secret for the identity being registered")
util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.modify, tags)
flags.StringSliceVarP(
&c.cfgAttrs, "attrs", "", nil, "A list of comma-separated attributes of the form <name>=<value> (e.g. foo=foo1,bar=bar1)")
flags.StringVarP(
Expand Down Expand Up @@ -145,7 +141,7 @@ func (c *ClientCmd) runListIdentity(cmd *cobra.Command, args []string) error {
return err
}

fmt.Printf("%+v\n", resp.IdentityInfo)
fmt.Printf("Name: %s, Type: %s, Affiliation: %s, Max Enrollments: %d, Attributes: %+v\n", resp.ID, resp.Type, resp.Affiliation, resp.MaxEnrollments, resp.Attributes)
return nil
}

Expand All @@ -172,28 +168,23 @@ func (c *ClientCmd) runAddIdentity(cmd *cobra.Command, args []string) error {
req := &api.AddIdentityRequest{}

if c.dynamicIdentity.json != "" {
newIdentity := api.IdentityInfo{}
err := util.Unmarshal([]byte(c.dynamicIdentity.json), &newIdentity, "addIdentity")
err := util.Unmarshal([]byte(c.dynamicIdentity.json), &req, "addIdentity")
if err != nil {
return errors.Wrap(err, "Invalid value for --json option")
}
req.IdentityInfo = newIdentity
} else {
req.IdentityInfo = c.dynamicIdentity.add.IdentityInfo
req.IdentityInfo.Attributes = c.clientCfg.ID.Attributes
req = &c.dynamicIdentity.add
req.Attributes = c.clientCfg.ID.Attributes
}

req.ID = args[0]
req.CAName = c.clientCfg.CAName
req.Secret = c.dynamicIdentity.add.Secret
resp, err := id.AddIdentity(req)
if err != nil {
return err
}

fmt.Printf("Successfully added identity: %+v\n", resp.IdentityInfo)
fmt.Printf("Secret: %s\n", resp.Secret)

fmt.Printf("Successfully added identity - Name: %s, Type: %s, Affiliation: %s, Max Enrollments: %d, Secret: %s, Attributes: %+v\n", resp.ID, resp.Type, resp.Affiliation, resp.MaxEnrollments, resp.Secret, resp.Attributes)
return nil
}

Expand All @@ -212,15 +203,13 @@ func (c *ClientCmd) runModifyIdentity(cmd *cobra.Command, args []string) error {
}

if c.dynamicIdentity.json != "" {
modifyIdentity := &api.IdentityInfo{}
err := util.Unmarshal([]byte(c.dynamicIdentity.json), modifyIdentity, "modifyIdentity")
err := util.Unmarshal([]byte(c.dynamicIdentity.json), req, "modifyIdentity")
if err != nil {
return errors.Wrap(err, "Invalid value for --json option")
}
req.IdentityInfo = *modifyIdentity
} else {
req.IdentityInfo = c.dynamicIdentity.modify.IdentityInfo
req.IdentityInfo.Attributes = c.clientCfg.ID.Attributes
req = &c.dynamicIdentity.modify
req.Attributes = c.clientCfg.ID.Attributes
}

req.ID = args[0]
Expand All @@ -230,8 +219,7 @@ func (c *ClientCmd) runModifyIdentity(cmd *cobra.Command, args []string) error {
return err
}

fmt.Printf("Successfully modified identity: %+v\n", resp.IdentityInfo)

fmt.Printf("Successfully modified identity - Name: %s, Type: %s, Affiliation: %s, Max Enrollments: %d, Secret: %s, Attributes: %+v\n", resp.ID, resp.Type, resp.Affiliation, resp.MaxEnrollments, resp.Secret, resp.Attributes)
return nil
}

Expand All @@ -252,8 +240,7 @@ func (c *ClientCmd) runRemoveIdentity(cmd *cobra.Command, args []string) error {
return err
}

fmt.Printf("Successfully removed identity: %+v\n", resp.IdentityInfo)

fmt.Printf("Successfully removed identity - Name: %s, Type: %s, Affiliation: %s, Max Enrollments: %d, Attributes: %+v\n", resp.ID, resp.Type, resp.Affiliation, resp.MaxEnrollments, resp.Attributes)
return nil
}

Expand Down
Loading

0 comments on commit ca705f6

Please sign in to comment.