github.com/decred/politeia@v1.4.0/politeiawww/cmd/pictl/cmdcommentcensor.go (about) 1 // Copyright (c) 2020-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 "strconv" 10 11 cmv1 "github.com/decred/politeia/politeiawww/api/comments/v1" 12 pclient "github.com/decred/politeia/politeiawww/client" 13 "github.com/decred/politeia/politeiawww/cmd/shared" 14 ) 15 16 // cmdCommentCensor censors a proposal comment. 17 type cmdCommentCensor struct { 18 Args struct { 19 Token string `positional-arg-name:"token"` 20 CommentID uint32 `positional-arg-name:"commentid"` 21 Reason string `positional-arg-name:"reason"` 22 } `positional-args:"true" required:"true"` 23 24 // Unvetted is used to censor the comment on an unvetted record. If 25 // this flag is not used the command assumes the record is vetted. 26 Unvetted bool `long:"unvetted" optional:"true"` 27 } 28 29 // Execute executes the cmdCommentCensor command. 30 // 31 // This function satisfies the go-flags Commander interface. 32 func (c *cmdCommentCensor) Execute(args []string) error { 33 // Unpack args 34 var ( 35 token = c.Args.Token 36 commentID = c.Args.CommentID 37 reason = c.Args.Reason 38 ) 39 40 // Check for user identity. A user identity is required to sign 41 // the censor request. 42 if cfg.Identity == nil { 43 return shared.ErrUserIdentityNotFound 44 } 45 46 // Setup state 47 var state cmv1.RecordStateT 48 switch { 49 case c.Unvetted: 50 state = cmv1.RecordStateUnvetted 51 default: 52 state = cmv1.RecordStateVetted 53 } 54 55 // Setup client 56 opts := pclient.Opts{ 57 HTTPSCert: cfg.HTTPSCert, 58 Cookies: cfg.Cookies, 59 HeaderCSRF: cfg.CSRF, 60 Verbose: cfg.Verbose, 61 RawJSON: cfg.RawJSON, 62 } 63 pc, err := pclient.New(cfg.Host, opts) 64 if err != nil { 65 return err 66 } 67 68 // Setup request 69 msg := strconv.FormatUint(uint64(state), 10) + token + 70 strconv.FormatUint(uint64(commentID), 10) + reason 71 sig := cfg.Identity.SignMessage([]byte(msg)) 72 d := cmv1.Del{ 73 State: state, 74 Token: token, 75 CommentID: commentID, 76 Reason: reason, 77 Signature: hex.EncodeToString(sig[:]), 78 PublicKey: cfg.Identity.Public.String(), 79 } 80 81 // Send request 82 dr, err := pc.CommentDel(d) 83 if err != nil { 84 return err 85 } 86 87 // Verify receipt 88 vr, err := client.Version() 89 if err != nil { 90 return err 91 } 92 err = pclient.CommentVerify(dr.Comment, vr.PubKey) 93 if err != nil { 94 return err 95 } 96 97 // Print comment 98 printComment(dr.Comment) 99 100 return nil 101 } 102 103 // commentCensorHelpMsg is printed to stdout by the help command. 104 const commentCensorHelpMsg = `commentcensor "token" "commentID" "reason" 105 106 Censor a comment. 107 108 If the record is unvetted, the --unvetted flag must be used. This command 109 requires admin priviledges. 110 111 Arguments: 112 1. token (string, required) Proposal censorship token 113 2. commentid (string, required) ID of the comment 114 3. reason (string, required) Reason for censoring the comment 115 116 Flags: 117 --unvetted (bool, optional) Record is unvetted. 118 `