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  `