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

     1  // Copyright (c) 2017-2019 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  	"fmt"
     9  	"strconv"
    10  	"strings"
    11  
    12  	cms "github.com/decred/politeia/politeiawww/api/cms/v1"
    13  	"github.com/decred/politeia/politeiawww/cmd/shared"
    14  	"github.com/google/uuid"
    15  )
    16  
    17  // CMSManageUserCmd allows an administrator to update Domain, ContractorType
    18  // and SupervisorID of a given user.
    19  type CMSManageUserCmd struct {
    20  	Args struct {
    21  		UserID string `positional-arg-name:"userid" required:"true"`
    22  	} `positional-args:"true" optional:"true"`
    23  	Domain            string `long:"domain" optional:"true"`
    24  	ContractorType    string `long:"contractortype" optional:"true"`
    25  	SupervisorUserIDs string `long:"supervisoruserids" optional:"true"`
    26  	ProposalsOwned    string `long:"proposalsowned" optional:"true"`
    27  }
    28  
    29  // Execute executes the cms manage user command.
    30  func (cmd *CMSManageUserCmd) Execute(args []string) error {
    31  	domains := map[string]cms.DomainTypeT{
    32  		"developer": cms.DomainTypeDeveloper,
    33  		"marketing": cms.DomainTypeMarketing,
    34  		"research":  cms.DomainTypeResearch,
    35  		"design":    cms.DomainTypeDesign,
    36  	}
    37  	contractorTypes := map[string]cms.ContractorTypeT{
    38  		"direct":     cms.ContractorTypeDirect,
    39  		"supervisor": cms.ContractorTypeSupervisor,
    40  		"contractor": cms.ContractorTypeSubContractor,
    41  		"nominee":    cms.ContractorTypeNominee,
    42  		"revoked":    cms.ContractorTypeRevoked,
    43  	}
    44  
    45  	// Validate user ID
    46  	_, err := uuid.Parse(cmd.Args.UserID)
    47  	if err != nil {
    48  		return fmt.Errorf("invalid user ID: %v", err)
    49  	}
    50  
    51  	// Validate domain. The domain can be either the numeric code
    52  	// or the human readable equivalent.
    53  	var domain cms.DomainTypeT
    54  	if cmd.Domain != "" {
    55  		d, err := strconv.ParseUint(cmd.Domain, 10, 32)
    56  		if err == nil {
    57  			// Numeric code found
    58  			domain = cms.DomainTypeT(d)
    59  		} else if d, ok := domains[cmd.Domain]; ok {
    60  			// Human readable domain found
    61  			domain = d
    62  		} else {
    63  			// Invalid domain
    64  			return fmt.Errorf("invalid domain; use the command " +
    65  				"'cmswww help manageuser' for list of valid domains")
    66  		}
    67  	}
    68  
    69  	// Validate contractor type. The contractor type can be either
    70  	// a numeric code or the human readable equivalent.
    71  	var contractorType cms.ContractorTypeT
    72  	if cmd.ContractorType != "" {
    73  		ct, err := strconv.ParseUint(cmd.ContractorType, 10, 32)
    74  		if err == nil {
    75  			// Numeric code found
    76  			contractorType = cms.ContractorTypeT(ct)
    77  		} else if ct, ok := contractorTypes[cmd.ContractorType]; ok {
    78  			// Human readable contractor type found
    79  			contractorType = ct
    80  		} else {
    81  			// Invalid contrator type
    82  			return fmt.Errorf("invalid contractor type; use the command " +
    83  				"'cmswww help manageuser' for list of valid contractor types")
    84  		}
    85  	}
    86  
    87  	// Validate supervisor user IDs
    88  	supervisorIDs := make([]string, 0, 16)
    89  	if cmd.SupervisorUserIDs != "" {
    90  		supervisorIDs = strings.Split(cmd.SupervisorUserIDs, ",")
    91  		for _, v := range supervisorIDs {
    92  			_, err := uuid.Parse(v)
    93  			if err != nil {
    94  				return fmt.Errorf("invalid supervisor ID '%v': %v", v, err)
    95  			}
    96  		}
    97  	}
    98  
    99  	// Validate supervisor user IDs
   100  	proposalsOwned := make([]string, 0, 16)
   101  	if cmd.ProposalsOwned != "" {
   102  		proposalsOwned = strings.Split(cmd.ProposalsOwned, ",")
   103  	}
   104  
   105  	// Send request
   106  	mu := cms.CMSManageUser{
   107  		UserID:            cmd.Args.UserID,
   108  		Domain:            domain,
   109  		ContractorType:    contractorType,
   110  		SupervisorUserIDs: supervisorIDs,
   111  		ProposalsOwned:    proposalsOwned,
   112  	}
   113  	err = shared.PrintJSON(mu)
   114  	if err != nil {
   115  		return err
   116  	}
   117  	mur, err := client.CMSManageUser(mu)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	err = shared.PrintJSON(mur)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	return nil
   127  }
   128  
   129  const cmsManageUserHelpMsg = `cmsmanageuser [flags] "userid"
   130  
   131  Update the Domain, ContractorType and SupervisorID of the specified user. This
   132  command requires admin privileges.
   133  
   134  Numeric codes or their human readable equivalents can be used to specify the
   135  domain and contractory type. See below for the available options.
   136  
   137  Arguments:
   138  1. userid               (string, required)     ID of the user to manage
   139  
   140  Flags:
   141    --domain              (string, optional)  Domain of the contractor
   142    --contractortype      (string, optional)  Contractor Type
   143    --supervisoruserids   (string, optional)  Supervisor user IDs (comma separated)
   144    --proposalsowned      (string, optional)  Proposals owned (comma separated)
   145  
   146  Domain types:
   147  1. developer
   148  2. marketing
   149  4. research
   150  5. design
   151  6. documentation
   152  
   153  Contractor types:
   154  1. direct
   155  2. supervisor
   156  3. subcontractor
   157  4. nominee
   158  5. revoked
   159  
   160  Request:
   161  {
   162    "userid": "c1261442-dc61-4861-9d6c-f104fd0b076b",
   163    "domain": 1,
   164    "contractortype": 1,
   165    "supervisoruserids": [
   166      "f43a040c-585c-4431-a9dd-6dbdde885bb5",
   167      "914de514-f861-41e3-8fcb-e3ebbb26a333"
   168    ]
   169  }
   170  
   171  Response:
   172  {}`