cmd/clef: add newaccount command (#20782)
* cmd/clef: add newaccount command * cmd/clef: document clef_New, update API versioning * Update cmd/clef/intapi_changelog.md Co-Authored-By: ligi <ligi@ligi.de> * Update signer/core/uiapi.go Co-Authored-By: ligi <ligi@ligi.de> Co-authored-by: ligi <ligi@ligi.de>
This commit is contained in:
		
							parent
							
								
									8f05cfa122
								
							
						
					
					
						commit
						c56f4fa808
					
				| @ -10,6 +10,17 @@ TL;DR: Given a version number MAJOR.MINOR.PATCH, increment the: | |||||||
| 
 | 
 | ||||||
| Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. | Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. | ||||||
| 
 | 
 | ||||||
|  | ### 7.0.1  | ||||||
|  | 
 | ||||||
|  | Added `clef_New` to the internal API calleable from a UI.  | ||||||
|  | 
 | ||||||
|  | > `New` creates a new password protected Account. The private key is protected with | ||||||
|  | > the given password. Users are responsible to backup the private key that is stored | ||||||
|  | > in the keystore location that was specified when this API was created. | ||||||
|  | > This method is the same as New on the external API, the difference being that | ||||||
|  | > this implementation does not ask for confirmation, since it's initiated by | ||||||
|  | > the user | ||||||
|  | 
 | ||||||
| ### 7.0.0 | ### 7.0.0 | ||||||
| 
 | 
 | ||||||
| - The `message` field was renamed to `messages` in all data signing request methods to better reflect that it's a list, not a value. | - The `message` field was renamed to `messages` in all data signing request methods to better reflect that it's a list, not a value. | ||||||
|  | |||||||
| @ -187,6 +187,21 @@ The setpw command stores a password for a given address (keyfile). | |||||||
| 		Description: ` | 		Description: ` | ||||||
| The delpw command removes a password for a given address (keyfile). | The delpw command removes a password for a given address (keyfile). | ||||||
| `} | `} | ||||||
|  | 	newAccountCommand = cli.Command{ | ||||||
|  | 		Action:    utils.MigrateFlags(newAccount), | ||||||
|  | 		Name:      "newaccount", | ||||||
|  | 		Usage:     "Create a new account", | ||||||
|  | 		ArgsUsage: "", | ||||||
|  | 		Flags: []cli.Flag{ | ||||||
|  | 			logLevelFlag, | ||||||
|  | 			keystoreFlag, | ||||||
|  | 			utils.LightKDFFlag, | ||||||
|  | 		}, | ||||||
|  | 		Description: ` | ||||||
|  | The newaccount command creates a new keystore-backed account. It is a convenience-method | ||||||
|  | which can be used in lieu of an external UI.`, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	gendocCommand = cli.Command{ | 	gendocCommand = cli.Command{ | ||||||
| 		Action: GenDoc, | 		Action: GenDoc, | ||||||
| 		Name:   "gendoc", | 		Name:   "gendoc", | ||||||
| @ -222,7 +237,12 @@ func init() { | |||||||
| 		advancedMode, | 		advancedMode, | ||||||
| 	} | 	} | ||||||
| 	app.Action = signer | 	app.Action = signer | ||||||
| 	app.Commands = []cli.Command{initCommand, attestCommand, setCredentialCommand, delCredentialCommand, gendocCommand} | 	app.Commands = []cli.Command{initCommand, | ||||||
|  | 		attestCommand, | ||||||
|  | 		setCredentialCommand, | ||||||
|  | 		delCredentialCommand, | ||||||
|  | 		newAccountCommand, | ||||||
|  | 		gendocCommand} | ||||||
| 	cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate | 	cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -382,6 +402,31 @@ func removeCredential(ctx *cli.Context) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func newAccount(c *cli.Context) error { | ||||||
|  | 	if err := initialize(c); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	// The newaccount is meant for users using the CLI, since 'real' external
 | ||||||
|  | 	// UIs can use the UI-api instead. So we'll just use the native CLI UI here.
 | ||||||
|  | 	var ( | ||||||
|  | 		ui                        = core.NewCommandlineUI() | ||||||
|  | 		pwStorage storage.Storage = &storage.NoStorage{} | ||||||
|  | 		ksLoc                     = c.GlobalString(keystoreFlag.Name) | ||||||
|  | 		lightKdf                  = c.GlobalBool(utils.LightKDFFlag.Name) | ||||||
|  | 	) | ||||||
|  | 	log.Info("Starting clef", "keystore", ksLoc, "light-kdf", lightKdf) | ||||||
|  | 	am := core.StartClefAccountManager(ksLoc, true, lightKdf, "") | ||||||
|  | 	// This gives is us access to the external API
 | ||||||
|  | 	apiImpl := core.NewSignerAPI(am, 0, true, ui, nil, false, pwStorage) | ||||||
|  | 	// This gives us access to the internal API
 | ||||||
|  | 	internalApi := core.NewUIServerAPI(apiImpl) | ||||||
|  | 	addr, err := internalApi.New(context.Background()) | ||||||
|  | 	if err == nil { | ||||||
|  | 		fmt.Printf("Generated account %v\n", addr.String()) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func initialize(c *cli.Context) error { | func initialize(c *cli.Context) error { | ||||||
| 	// Set up the logger to print everything
 | 	// Set up the logger to print everything
 | ||||||
| 	logOutput := os.Stdout | 	logOutput := os.Stdout | ||||||
| @ -457,7 +502,6 @@ func signer(c *cli.Context) error { | |||||||
| 		api       core.ExternalAPI | 		api       core.ExternalAPI | ||||||
| 		pwStorage storage.Storage = &storage.NoStorage{} | 		pwStorage storage.Storage = &storage.NoStorage{} | ||||||
| 	) | 	) | ||||||
| 
 |  | ||||||
| 	configDir := c.GlobalString(configdirFlag.Name) | 	configDir := c.GlobalString(configdirFlag.Name) | ||||||
| 	if stretchedKey, err := readMasterKey(c, ui); err != nil { | 	if stretchedKey, err := readMasterKey(c, ui); err != nil { | ||||||
| 		log.Warn("Failed to open master, rules disabled", "err", err) | 		log.Warn("Failed to open master, rules disabled", "err", err) | ||||||
|  | |||||||
| @ -43,7 +43,7 @@ const ( | |||||||
| 	// ExternalAPIVersion -- see extapi_changelog.md
 | 	// ExternalAPIVersion -- see extapi_changelog.md
 | ||||||
| 	ExternalAPIVersion = "6.0.0" | 	ExternalAPIVersion = "6.0.0" | ||||||
| 	// InternalAPIVersion -- see intapi_changelog.md
 | 	// InternalAPIVersion -- see intapi_changelog.md
 | ||||||
| 	InternalAPIVersion = "7.0.0" | 	InternalAPIVersion = "7.0.1" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // ExternalAPI defines the external API through which signing requests are made.
 | // ExternalAPI defines the external API through which signing requests are made.
 | ||||||
| @ -395,8 +395,7 @@ func (api *SignerAPI) List(ctx context.Context) ([]common.Address, error) { | |||||||
| // the given password. Users are responsible to backup the private key that is stored
 | // the given password. Users are responsible to backup the private key that is stored
 | ||||||
| // in the keystore location thas was specified when this API was created.
 | // in the keystore location thas was specified when this API was created.
 | ||||||
| func (api *SignerAPI) New(ctx context.Context) (common.Address, error) { | func (api *SignerAPI) New(ctx context.Context) (common.Address, error) { | ||||||
| 	be := api.am.Backends(keystore.KeyStoreType) | 	if be := api.am.Backends(keystore.KeyStoreType); len(be) == 0 { | ||||||
| 	if len(be) == 0 { |  | ||||||
| 		return common.Address{}, errors.New("password based accounts not supported") | 		return common.Address{}, errors.New("password based accounts not supported") | ||||||
| 	} | 	} | ||||||
| 	if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil { | 	if resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)}); err != nil { | ||||||
| @ -404,7 +403,16 @@ func (api *SignerAPI) New(ctx context.Context) (common.Address, error) { | |||||||
| 	} else if !resp.Approved { | 	} else if !resp.Approved { | ||||||
| 		return common.Address{}, ErrRequestDenied | 		return common.Address{}, ErrRequestDenied | ||||||
| 	} | 	} | ||||||
|  | 	return api.newAccount() | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | // newAccount is the internal method to create a new account. It should be used
 | ||||||
|  | // _after_ user-approval has been obtained
 | ||||||
|  | func (api *SignerAPI) newAccount() (common.Address, error) { | ||||||
|  | 	be := api.am.Backends(keystore.KeyStoreType) | ||||||
|  | 	if len(be) == 0 { | ||||||
|  | 		return common.Address{}, errors.New("password based accounts not supported") | ||||||
|  | 	} | ||||||
| 	// Three retries to get a valid password
 | 	// Three retries to get a valid password
 | ||||||
| 	for i := 0; i < 3; i++ { | 	for i := 0; i < 3; i++ { | ||||||
| 		resp, err := api.UI.OnInputRequired(UserInputRequest{ | 		resp, err := api.UI.OnInputRequired(UserInputRequest{ | ||||||
|  | |||||||
| @ -195,6 +195,16 @@ func (api *UIServerAPI) Import(ctx context.Context, keyJSON json.RawMessage, old | |||||||
| 	return be[0].(*keystore.KeyStore).Import(keyJSON, oldPassphrase, newPassphrase) | 	return be[0].(*keystore.KeyStore).Import(keyJSON, oldPassphrase, newPassphrase) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // New creates a new password protected Account. The private key is protected with
 | ||||||
|  | // the given password. Users are responsible to backup the private key that is stored
 | ||||||
|  | // in the keystore location that was specified when this API was created.
 | ||||||
|  | // This method is the same as New on the external API, the difference being that
 | ||||||
|  | // this implementation does not ask for confirmation, since it's initiated by
 | ||||||
|  | // the user
 | ||||||
|  | func (api *UIServerAPI) New(ctx context.Context) (common.Address, error) { | ||||||
|  | 	return api.extApi.newAccount() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Other methods to be added, not yet implemented are:
 | // Other methods to be added, not yet implemented are:
 | ||||||
| // - Ruleset interaction: add rules, attest rulefiles
 | // - Ruleset interaction: add rules, attest rulefiles
 | ||||||
| // - Store metadata about accounts, e.g. naming of accounts
 | // - Store metadata about accounts, e.g. naming of accounts
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user