|
| 1 | +# ADR 009: Avoid accidental DTag override |
| 2 | + |
| 3 | +## Changelog |
| 4 | + |
| 5 | +- October 7th, 2021: Proposed |
| 6 | +- October 8th, 2021: First review |
| 7 | +- October 11th, 2021: Finalized ADR |
| 8 | + |
| 9 | +## Status |
| 10 | + |
| 11 | +PROPOSED |
| 12 | + |
| 13 | +## Abstract |
| 14 | + |
| 15 | +We SHOULD edit the behavior of the current `MsgSaveProfile` making the `DTag` an optional flag |
| 16 | +in order to prevent users from accidentally overriding their own DTags. In this way, users will edit |
| 17 | +their DTag only when they specify them with the flag. |
| 18 | + |
| 19 | +## Context |
| 20 | + |
| 21 | +Currently, the `desmos profile tx save` CLI command always requires to specify a DTag when using it. This means that |
| 22 | +users that do not want to edit their DTag need to specify it anyway. This could lead to the situation where a user |
| 23 | +accidentally makes a typo while inserting the DTag triggering its edit. If this happens, and the user doesn't notice it |
| 24 | +immediately, another user can register a profile with the now free DTag, stealing it from the original user. |
| 25 | + |
| 26 | +## Decision |
| 27 | + |
| 28 | +To avoid the situation described above, we need to perform some changes on the logic that handles a `MsgSaveProfile`. |
| 29 | +First, we need to edit the `desmos tx profiles save` CLI command so that the now required `dtag` field becomes |
| 30 | +an optional flag: |
| 31 | +```go |
| 32 | +func GetCmdSaveProfile() *cobra.Command { |
| 33 | + cmd := &cobra.Command{ |
| 34 | + Use: "save", |
| 35 | + Args: cobra.NoArgs, |
| 36 | + Short: "Save your profile", |
| 37 | + Long: fmt.Sprintf(` |
| 38 | +Save a new profile or edit the existing one specifying a DTag, a nickname, biography, profile picture and cover picture. |
| 39 | +Every data given through the flags is optional. |
| 40 | +If you are editing an existing profile you should fill only the fields that you want to edit. |
| 41 | +The empty ones will be filled with a special [do-not-modify] flag that tells the system to not edit them. |
| 42 | +
|
| 43 | +%s tx profiles save |
| 44 | + --%s "LeoDiCaprio" \ |
| 45 | + --%s "Leonardo Di Caprio" \ |
| 46 | + --%s "Hollywood actor. Proud environmentalist" \ |
| 47 | + --%s "https://profilePic.jpg" \ |
| 48 | + --%s "https://profileCover.jpg" |
| 49 | +`, version.AppName, FlagDTag, FlagNickname, FlagBio, FlagProfilePic, FlagCoverPic), |
| 50 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 51 | + clientCtx, err := client.GetClientTxContext(cmd) |
| 52 | + if err != nil { |
| 53 | + return err |
| 54 | + } |
| 55 | + |
| 56 | + dTag, _ := cmd.Flags().GetString(FlagDTag) |
| 57 | + nickname, _ := cmd.Flags().GetString(FlagNickname) |
| 58 | + bio, _ := cmd.Flags().GetString(FlagBio) |
| 59 | + profilePic, _ := cmd.Flags().GetString(FlagProfilePic) |
| 60 | + coverPic, _ := cmd.Flags().GetString(FlagCoverPic) |
| 61 | + |
| 62 | + msg := types.NewMsgSaveProfile(dTag, nickname, bio, profilePic, coverPic, clientCtx.FromAddress.String()) |
| 63 | + if err = msg.ValidateBasic(); err != nil { |
| 64 | + return fmt.Errorf("message validation failed: %w", err) |
| 65 | + } |
| 66 | + |
| 67 | + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) |
| 68 | + }, |
| 69 | + } |
| 70 | + |
| 71 | + cmd.Flags().String(FlagDTag, types.DoNotModify, "DTag to be used") |
| 72 | + cmd.Flags().String(FlagNickname, types.DoNotModify, "Nickname to be used") |
| 73 | + cmd.Flags().String(FlagBio, types.DoNotModify, "Biography to be used") |
| 74 | + cmd.Flags().String(FlagProfilePic, types.DoNotModify, "Profile picture") |
| 75 | + cmd.Flags().String(FlagCoverPic, types.DoNotModify, "Cover picture") |
| 76 | + |
| 77 | + flags.AddTxFlagsToCmd(cmd) |
| 78 | + |
| 79 | + return cmd |
| 80 | +} |
| 81 | +``` |
| 82 | +Second, we need to remove the check on DTag inside `ValidateBasic()` that currently makes it impossible to specify an |
| 83 | +empty DTag inside a `MsgSaveProfile`: |
| 84 | +```go |
| 85 | +func (msg MsgSaveProfile) ValidateBasic() error { |
| 86 | + _, err := sdk.AccAddressFromBech32(msg.Creator) |
| 87 | + if err != nil { |
| 88 | + return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, fmt.Sprintf("invalid creator: %s", msg.Creator)) |
| 89 | + } |
| 90 | + return nil |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +## Consequences |
| 95 | + |
| 96 | +### Backwards Compatibility |
| 97 | + |
| 98 | +There are no backwards compatibility issues related to these changes. |
| 99 | + |
| 100 | +### Positive |
| 101 | + |
| 102 | +* Protect users from accidentally editing their DTag. |
| 103 | + |
| 104 | +### Negative |
| 105 | + |
| 106 | +- None known |
| 107 | + |
| 108 | +### Neutral |
| 109 | + |
| 110 | +- None known |
| 111 | + |
| 112 | +## Further Discussions |
| 113 | + |
| 114 | +## Test Cases [optional] |
| 115 | + |
| 116 | +The following tests cases MUST to be present: |
| 117 | +1. Creating a profile with an empty DTag returns an error; |
| 118 | +2. Creating a profile with DTag `[do-not-modify]` returns an error; |
| 119 | +3. Updating a profile with a different DTag changes its value and returns no error; |
| 120 | +4. Updating a profile with DTag `[do-not-modify]` does not update its value and returns no error. |
| 121 | + |
| 122 | +## References |
| 123 | + |
| 124 | +- Issue [#622](https://github.com/desmos-labs/desmos/issues/622) |
0 commit comments