github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/cmd/fabric-ca-client/identity.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 22 "github.com/cloudflare/cfssl/log" 23 "github.com/hyperledger/fabric-ca/api" 24 "github.com/hyperledger/fabric-ca/lib" 25 "github.com/hyperledger/fabric-ca/util" 26 "github.com/pkg/errors" 27 "github.com/spf13/cobra" 28 ) 29 30 type identityArgs struct { 31 id string 32 json string 33 add api.AddIdentityRequest 34 modify api.ModifyIdentityRequest 35 remove api.RemoveIdentityRequest 36 } 37 38 func (c *ClientCmd) newIdentityCommand() *cobra.Command { 39 identityCmd := &cobra.Command{ 40 Use: "identity", 41 Short: "Manage identities", 42 Long: "Manage identities", 43 } 44 identityCmd.AddCommand(c.newListIdentityCommand()) 45 identityCmd.AddCommand(c.newAddIdentityCommand()) 46 identityCmd.AddCommand(c.newModifyIdentityCommand()) 47 identityCmd.AddCommand(c.newRemoveIdentityCommand()) 48 return identityCmd 49 } 50 51 func (c *ClientCmd) newListIdentityCommand() *cobra.Command { 52 identityListCmd := &cobra.Command{ 53 Use: "list", 54 Short: "List identities", 55 Long: "List identities visible to caller", 56 PreRunE: func(cmd *cobra.Command, args []string) error { 57 log.Level = log.LevelWarning 58 err := c.configInit() 59 if err != nil { 60 return err 61 } 62 63 log.Debugf("Client configuration settings: %+v", c.clientCfg) 64 65 return nil 66 }, 67 RunE: c.runListIdentity, 68 } 69 flags := identityListCmd.Flags() 70 flags.StringVarP( 71 &c.dynamicIdentity.id, "id", "", "", "Get identity information from the fabric-ca server") 72 return identityListCmd 73 } 74 75 func (c *ClientCmd) newAddIdentityCommand() *cobra.Command { 76 identityAddCmd := &cobra.Command{ 77 Use: "add <id>", 78 Short: "Add identity", 79 Long: "Add an identity", 80 Example: "fabric-ca-client identity add user1 --type peer", 81 PreRunE: c.identityPreRunE, 82 RunE: c.runAddIdentity, 83 } 84 flags := identityAddCmd.Flags() 85 util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.add, nil) 86 flags.StringSliceVarP( 87 &c.cfgAttrs, "attrs", "", nil, "A list of comma-separated attributes of the form <name>=<value> (e.g. foo=foo1,bar=bar1)") 88 flags.StringVarP( 89 &c.dynamicIdentity.json, "json", "", "", "JSON string for adding a new identity") 90 return identityAddCmd 91 } 92 93 func (c *ClientCmd) newModifyIdentityCommand() *cobra.Command { 94 identityModifyCmd := &cobra.Command{ 95 Use: "modify <id>", 96 Short: "Modify identity", 97 Long: "Modify an existing identity", 98 Example: "fabric-ca-client identity modify user1 --type peer", 99 PreRunE: c.identityPreRunE, 100 RunE: c.runModifyIdentity, 101 } 102 flags := identityModifyCmd.Flags() 103 tags := map[string]string{ 104 "skip.id": "true", 105 } 106 util.RegisterFlags(c.myViper, flags, &c.dynamicIdentity.modify, tags) 107 flags.StringSliceVarP( 108 &c.cfgAttrs, "attrs", "", nil, "A list of comma-separated attributes of the form <name>=<value> (e.g. foo=foo1,bar=bar1)") 109 flags.StringVarP( 110 &c.dynamicIdentity.json, "json", "", "", "JSON string for modifying an existing identity") 111 return identityModifyCmd 112 } 113 114 func (c *ClientCmd) newRemoveIdentityCommand() *cobra.Command { 115 identityRemoveCmd := &cobra.Command{ 116 Use: "remove <id>", 117 Short: "Remove identity", 118 Long: "Remove an identity", 119 Example: "fabric-ca-client identity remove user1", 120 PreRunE: c.identityPreRunE, 121 RunE: c.runRemoveIdentity, 122 } 123 flags := identityRemoveCmd.Flags() 124 flags.BoolVarP( 125 &c.dynamicIdentity.remove.Force, "force", "", false, "Forces removing your own identity") 126 return identityRemoveCmd 127 } 128 129 // The client side logic for executing list identity command 130 func (c *ClientCmd) runListIdentity(cmd *cobra.Command, args []string) error { 131 log.Debug("Entered runListIdentity") 132 133 id, err := c.loadMyIdentity() 134 if err != nil { 135 return err 136 } 137 138 if c.dynamicIdentity.id != "" { 139 resp, err := id.GetIdentity(c.dynamicIdentity.id, c.clientCfg.CAName) 140 if err != nil { 141 return err 142 } 143 144 fmt.Printf("Name: %s, Type: %s, Affiliation: %s, Max Enrollments: %d, Attributes: %+v\n", resp.ID, resp.Type, resp.Affiliation, resp.MaxEnrollments, resp.Attributes) 145 return nil 146 } 147 148 err = id.GetAllIdentities(c.clientCfg.CAName, lib.IdentityDecoder) 149 if err != nil { 150 return err 151 } 152 153 return nil 154 } 155 156 // The client side logic for adding an identity 157 func (c *ClientCmd) runAddIdentity(cmd *cobra.Command, args []string) error { 158 log.Debugf("Entered runAddIdentity: %+v", c.dynamicIdentity) 159 if c.dynamicIdentity.json != "" && checkOtherFlags(cmd) { 160 return errors.Errorf("Can't use 'json' flag in conjunction with other flags") 161 } 162 163 id, err := c.loadMyIdentity() 164 if err != nil { 165 return err 166 } 167 168 req := &api.AddIdentityRequest{} 169 170 if c.dynamicIdentity.json != "" { 171 err := util.Unmarshal([]byte(c.dynamicIdentity.json), &req, "addIdentity") 172 if err != nil { 173 return errors.Wrap(err, "Invalid value for --json option") 174 } 175 } else { 176 req = &c.dynamicIdentity.add 177 req.Attributes = c.clientCfg.ID.Attributes 178 } 179 180 req.ID = args[0] 181 req.CAName = c.clientCfg.CAName 182 resp, err := id.AddIdentity(req) 183 if err != nil { 184 return err 185 } 186 187 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) 188 return nil 189 } 190 191 // The client side logic for modifying an identity 192 func (c *ClientCmd) runModifyIdentity(cmd *cobra.Command, args []string) error { 193 log.Debugf("Entered runModifyIdentity: %+v", c.dynamicIdentity) 194 if c.dynamicIdentity.json != "" && checkOtherFlags(cmd) { 195 return errors.Errorf("Can't use 'json' flag in conjunction with other flags") 196 } 197 198 req := &api.ModifyIdentityRequest{} 199 200 id, err := c.loadMyIdentity() 201 if err != nil { 202 return err 203 } 204 205 if c.dynamicIdentity.json != "" { 206 err := util.Unmarshal([]byte(c.dynamicIdentity.json), req, "modifyIdentity") 207 if err != nil { 208 return errors.Wrap(err, "Invalid value for --json option") 209 } 210 } else { 211 req = &c.dynamicIdentity.modify 212 req.Attributes = c.clientCfg.ID.Attributes 213 } 214 215 req.ID = args[0] 216 req.CAName = c.clientCfg.CAName 217 resp, err := id.ModifyIdentity(req) 218 if err != nil { 219 return err 220 } 221 222 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) 223 return nil 224 } 225 226 // The client side logic for removing an identity 227 func (c *ClientCmd) runRemoveIdentity(cmd *cobra.Command, args []string) error { 228 log.Debugf("Entered runRemoveIdentity: %+v", c.dynamicIdentity) 229 230 id, err := c.loadMyIdentity() 231 if err != nil { 232 return err 233 } 234 235 req := &c.dynamicIdentity.remove 236 req.ID = args[0] 237 req.CAName = c.clientCfg.CAName 238 resp, err := id.RemoveIdentity(req) 239 if err != nil { 240 return err 241 } 242 243 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) 244 return nil 245 } 246 247 func (c *ClientCmd) identityPreRunE(cmd *cobra.Command, args []string) error { 248 err := argsCheck(args, "Identity") 249 if err != nil { 250 return err 251 } 252 253 err = c.configInit() 254 if err != nil { 255 return err 256 } 257 258 log.Debugf("Client configuration settings: %+v", c.clientCfg) 259 260 return nil 261 } 262 263 // checkOtherFlags returns true if other flags besides '--json' are set 264 // Viper.IsSet does not work correctly if there are defaults defined for 265 // flags. This is a workaround until this bug is addressed in Viper. 266 // Viper Bug: https://github.com/spf13/viper/issues/276 267 func checkOtherFlags(cmd *cobra.Command) bool { 268 checkFlags := []string{"id", "type", "affiliation", "secret", "maxenrollments", "attrs"} 269 flags := cmd.Flags() 270 for _, checkFlag := range checkFlags { 271 flag := flags.Lookup(checkFlag) 272 if flag != nil { 273 if flag.Changed { 274 return true 275 } 276 } 277 } 278 279 return false 280 } 281 282 func argsCheck(args []string, field string) error { 283 if len(args) == 0 { 284 return errors.Errorf("%s name is required", field) 285 } 286 if len(args) > 1 { 287 return errors.Errorf("Unknown argument '%s', only the identity name should be passed in as non-flag argument", args[1]) 288 } 289 return nil 290 }