github.com/decred/politeia@v1.4.0/politeiawww/cmd/cmswww/votedcc.go (about)

     1  // Copyright (c) 2020 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  	"fmt"
    11  	"strconv"
    12  
    13  	v1 "github.com/decred/politeia/politeiawww/api/cms/v1"
    14  	"github.com/decred/politeia/politeiawww/cmd/shared"
    15  )
    16  
    17  // VoteDCCCmd allows a user to vote for a DCC proposal during an all contractor vote.
    18  type VoteDCCCmd struct {
    19  	Args struct {
    20  		Vote  string `positional-arg-name:"vote"`
    21  		Token string `positional-arg-name:"token"`
    22  	} `positional-args:"true" required:"true"`
    23  }
    24  
    25  // Execute executes the support DCC command.
    26  func (cmd *VoteDCCCmd) Execute(args []string) error {
    27  	token := cmd.Args.Token
    28  	vote := cmd.Args.Vote
    29  
    30  	voteDetails, err := client.VoteDetailsDCC(v1.VoteDetails{Token: token})
    31  	if err != nil {
    32  		return fmt.Errorf("error retreiving vote details: %v", err)
    33  	}
    34  	var jsonVote v1.Vote
    35  	err = json.Unmarshal([]byte(voteDetails.Vote), &jsonVote)
    36  	if err != nil {
    37  		return fmt.Errorf("error retreiving vote details: %v", err)
    38  	}
    39  
    40  	voteBits := ""
    41  	validChoices := ""
    42  	for i, option := range jsonVote.Options {
    43  		if i != len(jsonVote.Options)-1 {
    44  			validChoices += option.Id + "/"
    45  		} else {
    46  			validChoices += option.Id
    47  		}
    48  		if vote == option.Id {
    49  			voteBits = strconv.FormatUint(option.Bits, 16)
    50  		}
    51  	}
    52  
    53  	if voteBits == "" {
    54  		return fmt.Errorf("invalid request: choose one: %v", validChoices)
    55  	}
    56  
    57  	if token == "" {
    58  		return fmt.Errorf("invalid request: you must specify dcc " +
    59  			"token")
    60  	}
    61  
    62  	// Check for user identity
    63  	if cfg.Identity == nil {
    64  		return shared.ErrUserIdentityNotFound
    65  	}
    66  
    67  	lr, err := client.Me()
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	sig := cfg.Identity.SignMessage([]byte(token + voteBits + lr.UserID))
    73  	sd := v1.CastVote{
    74  		VoteBit:   voteBits,
    75  		Token:     token,
    76  		UserID:    lr.UserID,
    77  		PublicKey: hex.EncodeToString(cfg.Identity.Public.Key[:]),
    78  		Signature: hex.EncodeToString(sig[:]),
    79  	}
    80  
    81  	// Print request details
    82  	err = shared.PrintJSON(sd)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	// Send request
    88  	sdr, err := client.CastVoteDCC(sd)
    89  	if err != nil {
    90  		return fmt.Errorf("VoteDCC: %v", err)
    91  	}
    92  
    93  	// Print response details
    94  	err = shared.PrintJSON(sdr)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	return nil
   100  }