github.com/decred/politeia@v1.4.0/politeiawww/legacy/pi/process.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 pi
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  
    11  	"github.com/decred/politeia/politeiad/plugins/pi"
    12  	v1 "github.com/decred/politeia/politeiawww/api/pi/v1"
    13  	"github.com/decred/politeia/politeiawww/legacy/user"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // processSetBillingStatus processes a pi v1 setbillingstatus request.
    18  func (p *Pi) processSetBillingStatus(ctx context.Context, sbs v1.SetBillingStatus, u user.User) (*v1.SetBillingStatusReply, error) {
    19  	log.Tracef("processSetBillingStatus: %v", sbs.Token)
    20  
    21  	// Sanity check
    22  	if !u.Admin {
    23  		return nil, errors.Errorf("user is not an admin")
    24  	}
    25  
    26  	// Verify user signed with their active identity
    27  	if u.PublicKey() != sbs.PublicKey {
    28  		return nil, v1.UserErrorReply{
    29  			ErrorCode:    v1.ErrorCodePublicKeyInvalid,
    30  			ErrorContext: "not active identity",
    31  		}
    32  	}
    33  
    34  	// Send plugin command
    35  	psbs := convertSetBillingStatusToPlugin(sbs)
    36  	psbsr, err := p.politeiad.PiSetBillingStatus(ctx, psbs)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	return &v1.SetBillingStatusReply{
    42  		Timestamp: psbsr.Timestamp,
    43  		Receipt:   psbsr.Receipt,
    44  	}, nil
    45  }
    46  
    47  // processBillingStatusChanges processes a pi v1 billingstatuschanges request.
    48  func (p *Pi) processBillingStatusChanges(ctx context.Context, bscs v1.BillingStatusChanges) (*v1.BillingStatusChangesReply, error) {
    49  	log.Tracef("processBillingStatusChanges: %v", bscs.Tokens)
    50  
    51  	// Verify request size
    52  	if len(bscs.Tokens) > int(p.policy.BillingStatusChangesPageSize) {
    53  		return nil, v1.UserErrorReply{
    54  			ErrorCode: v1.ErrorCodePageSizeExceeded,
    55  			ErrorContext: fmt.Sprintf("max page size is %v",
    56  				p.policy.BillingStatusChangesPageSize),
    57  		}
    58  	}
    59  
    60  	reply, err := p.politeiad.PiBillingStatusChanges(ctx, bscs.Tokens)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	// Convert reply to API.
    66  	r := make(map[string][]v1.BillingStatusChange, len(reply))
    67  	// For each token, convert slice of billing status changes.
    68  	for t, bscs := range reply {
    69  		statusChanges := make([]v1.BillingStatusChange, 0, len(reply))
    70  		for _, bsc := range bscs.BillingStatusChanges {
    71  			statusChanges = append(statusChanges,
    72  				convertBillingStatusChangeToAPI(bsc))
    73  		}
    74  		r[t] = statusChanges
    75  	}
    76  
    77  	return &v1.BillingStatusChangesReply{
    78  		BillingStatusChanges: r,
    79  	}, nil
    80  }
    81  
    82  // processSummaries processes a pi v1 summaries request.
    83  func (p *Pi) processSummaries(ctx context.Context, s v1.Summaries) (*v1.SummariesReply, error) {
    84  	log.Tracef("processSummaries: %v", s.Tokens)
    85  
    86  	// Verify request size
    87  	if len(s.Tokens) > int(p.policy.SummariesPageSize) {
    88  		return nil, v1.UserErrorReply{
    89  			ErrorCode: v1.ErrorCodePageSizeExceeded,
    90  			ErrorContext: fmt.Sprintf("max page size is %v",
    91  				p.policy.SummariesPageSize),
    92  		}
    93  	}
    94  
    95  	psr, err := p.politeiad.PiSummaries(ctx, s.Tokens)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	// Convert reply to API
   101  	ss := make(map[string]v1.Summary, len(psr))
   102  	for token, s := range psr {
   103  		ss[token] = v1.Summary{
   104  			Status: string(s.Summary.Status),
   105  		}
   106  	}
   107  
   108  	return &v1.SummariesReply{
   109  		Summaries: ss,
   110  	}, nil
   111  }
   112  
   113  func convertBillingStatusChangeToAPI(bsc pi.BillingStatusChange) v1.BillingStatusChange {
   114  	return v1.BillingStatusChange{
   115  		Token:     bsc.Token,
   116  		Status:    convertBillingStatusToAPI(bsc.Status),
   117  		Reason:    bsc.Reason,
   118  		PublicKey: bsc.PublicKey,
   119  		Signature: bsc.Signature,
   120  		Receipt:   bsc.Receipt,
   121  		Timestamp: bsc.Timestamp,
   122  	}
   123  }
   124  
   125  func convertBillingStatusToAPI(bs pi.BillingStatusT) v1.BillingStatusT {
   126  	switch bs {
   127  	case pi.BillingStatusActive:
   128  		return v1.BillingStatusActive
   129  	case pi.BillingStatusClosed:
   130  		return v1.BillingStatusClosed
   131  	case pi.BillingStatusCompleted:
   132  		return v1.BillingStatusCompleted
   133  	}
   134  	return v1.BillingStatusInvalid
   135  }
   136  
   137  func convertSetBillingStatusToPlugin(sbs v1.SetBillingStatus) pi.SetBillingStatus {
   138  	return pi.SetBillingStatus{
   139  		Token:     sbs.Token,
   140  		Status:    convertBillingStatusToPlugin(sbs.Status),
   141  		Reason:    sbs.Reason,
   142  		PublicKey: sbs.PublicKey,
   143  		Signature: sbs.Signature,
   144  	}
   145  }
   146  
   147  func convertBillingStatusToPlugin(bs v1.BillingStatusT) pi.BillingStatusT {
   148  	switch bs {
   149  	case v1.BillingStatusActive:
   150  		return pi.BillingStatusActive
   151  	case v1.BillingStatusClosed:
   152  		return pi.BillingStatusClosed
   153  	case v1.BillingStatusCompleted:
   154  		return pi.BillingStatusCompleted
   155  	}
   156  	return pi.BillingStatusInvalid
   157  }