github.com/decred/politeia@v1.4.0/politeiawww/cmd/pictl/cmdcommentedit.go (about) 1 // Copyright (c) 2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "encoding/hex" 9 "encoding/json" 10 "strconv" 11 12 cmv1 "github.com/decred/politeia/politeiawww/api/comments/v1" 13 piv1 "github.com/decred/politeia/politeiawww/api/pi/v1" 14 pclient "github.com/decred/politeia/politeiawww/client" 15 "github.com/decred/politeia/politeiawww/cmd/shared" 16 "github.com/pkg/errors" 17 ) 18 19 // cmdCommentEdit edits a new comment. 20 type cmdCommentEdit struct { 21 Args struct { 22 Token string `positional-arg-name:"token" required:"true"` 23 CommentID uint32 `positional-arg-name:"commentid" required:"true"` 24 Comment string `positional-arg-name:"comment" required:"true"` 25 ParentID uint32 `positional-arg-name:"parentid"` 26 } `positional-args:"true"` 27 28 // Unvetted is used to comment on an unvetted record. If this flag 29 // is not used the command assumes the record is vetted. 30 Unvetted bool `long:"unvetted" optional:"true"` 31 32 // UpdateTitle is used to post a new author update. 33 UpdateTitle string `long:"updatetitle" optional:"true"` 34 } 35 36 // Execute executes the cmdCommentEdit command. 37 // 38 // This function satisfies the go-flags Commander interface. 39 func (c *cmdCommentEdit) Execute(args []string) error { 40 // Unpack args 41 var ( 42 token = c.Args.Token 43 commentID = c.Args.CommentID 44 comment = c.Args.Comment 45 parentID = c.Args.ParentID 46 ) 47 48 // Check for user identity. A user identity is required to sign 49 // the comment. 50 if cfg.Identity == nil { 51 return shared.ErrUserIdentityNotFound 52 } 53 54 // Setup client 55 opts := pclient.Opts{ 56 HTTPSCert: cfg.HTTPSCert, 57 Cookies: cfg.Cookies, 58 HeaderCSRF: cfg.CSRF, 59 Verbose: cfg.Verbose, 60 RawJSON: cfg.RawJSON, 61 } 62 pc, err := pclient.New(cfg.Host, opts) 63 if err != nil { 64 return err 65 } 66 67 // Setup state 68 var state cmv1.RecordStateT 69 switch { 70 case c.Unvetted: 71 state = cmv1.RecordStateUnvetted 72 default: 73 state = cmv1.RecordStateVetted 74 } 75 76 // Prepare extra data if it's a new author update 77 var ( 78 extraData, 79 extraDataHint string 80 ) 81 if c.UpdateTitle != "" { 82 extraDataHint = piv1.ProposalUpdateHint 83 pum := piv1.ProposalUpdateMetadata{ 84 Title: c.UpdateTitle, 85 } 86 b, err := json.Marshal(pum) 87 if err != nil { 88 return err 89 } 90 extraData = string(b) 91 } 92 93 // Get user ID of logged in user 94 lr, err := client.Me() 95 if err != nil { 96 if err.Error() == "401" { 97 return errors.Errorf("no logged in user found") 98 } 99 return err 100 } 101 userID := lr.UserID 102 103 // Setup request 104 msg := strconv.FormatUint(uint64(state), 10) + token + 105 strconv.FormatUint(uint64(parentID), 10) + 106 strconv.FormatUint(uint64(commentID), 10) + 107 comment + extraData + extraDataHint 108 sig := cfg.Identity.SignMessage([]byte(msg)) 109 e := cmv1.Edit{ 110 UserID: userID, 111 State: state, 112 Token: token, 113 ParentID: parentID, 114 CommentID: commentID, 115 Comment: comment, 116 Signature: hex.EncodeToString(sig[:]), 117 PublicKey: cfg.Identity.Public.String(), 118 ExtraDataHint: extraDataHint, 119 ExtraData: extraData, 120 } 121 122 // Send request 123 er, err := pc.CommentEdit(e) 124 if err != nil { 125 return err 126 } 127 128 // Verify receipt 129 vr, err := client.Version() 130 if err != nil { 131 return err 132 } 133 err = pclient.CommentEditVerify(er.Comment, vr.PubKey) 134 if err != nil { 135 return err 136 } 137 138 // Print receipt 139 printComment(er.Comment) 140 141 return nil 142 } 143 144 // commentEditHelpMsg is printed to stdout by the help command. 145 const commentEditHelpMsg = `commentedit "token" commentid "comment" parentid 146 147 Edit a comment. Requires the user to be logged in. 148 149 This command assumes the record is a vetted record. 150 151 If the record is unvetted, the --unvetted flag must be used. Commenting on 152 unvetted records requires admin priviledges. 153 154 Proposal's author may edit an author update using the --updatetitle flag. 155 156 Arguments: 157 1. token (string, required) Proposal censorship token. 158 2. commentid (string, required) Comment ID. 159 3. comment (string, required) Comment text. 160 4. parentid (uint32, optional) ID of parent commment. Including a parent ID 161 indicates that the comment is a reply. 162 163 Flags: 164 --unvetted (bool, optional) Record is unvetted. 165 --updatetitle (string, optional) Authour update title. 166 `