github.com/decred/politeia@v1.4.0/politeiad/client/pdv1.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 client
     6  
     7  import (
     8  	"context"
     9  	"encoding/hex"
    10  	"encoding/json"
    11  	"net/http"
    12  
    13  	pdv1 "github.com/decred/politeia/politeiad/api/v1"
    14  	v1 "github.com/decred/politeia/politeiad/api/v1"
    15  	"github.com/decred/politeia/politeiad/api/v1/identity"
    16  	"github.com/decred/politeia/util"
    17  )
    18  
    19  // Identity sends a Identity request to the politeiad v1 API.
    20  func (c *Client) Identity(ctx context.Context) (*identity.PublicIdentity, error) {
    21  	// Setup request
    22  	challenge, err := util.Random(pdv1.ChallengeSize)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  	i := v1.Identity{
    27  		Challenge: hex.EncodeToString(challenge),
    28  	}
    29  
    30  	// Send request
    31  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
    32  		pdv1.IdentityRoute, i)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	// Decode reply
    38  	var ir v1.IdentityReply
    39  	err = json.Unmarshal(resBody, &ir)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	pid, err := identity.PublicIdentityFromString(ir.PublicKey)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	err = util.VerifyChallenge(pid, challenge, ir.Response)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	return pid, nil
    53  }
    54  
    55  // NewRecord sends a NewRecord request to the politeiad v1 API.
    56  func (c *Client) NewRecord(ctx context.Context, metadata []pdv1.MetadataStream, files []pdv1.File) (*pdv1.CensorshipRecord, error) {
    57  	// Setup request
    58  	challenge, err := util.Random(pdv1.ChallengeSize)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	nr := pdv1.NewRecord{
    63  		Challenge: hex.EncodeToString(challenge),
    64  		Metadata:  metadata,
    65  		Files:     files,
    66  	}
    67  
    68  	// Send request
    69  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
    70  		pdv1.NewRecordRoute, nr)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	// Decode reply
    76  	var nrr pdv1.NewRecordReply
    77  	err = json.Unmarshal(resBody, &nrr)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	err = util.VerifyChallenge(c.pid, challenge, nrr.Response)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	return &nrr.CensorshipRecord, nil
    87  }
    88  
    89  func (c *Client) updateRecord(ctx context.Context, route, token string, mdAppend, mdOverwrite []pdv1.MetadataStream, filesAdd []pdv1.File, filesDel []string) error {
    90  	// Setup request
    91  	challenge, err := util.Random(pdv1.ChallengeSize)
    92  	if err != nil {
    93  		return err
    94  	}
    95  	ur := pdv1.UpdateRecord{
    96  		Token:       token,
    97  		Challenge:   hex.EncodeToString(challenge),
    98  		MDOverwrite: mdOverwrite,
    99  		FilesAdd:    filesAdd,
   100  		FilesDel:    filesDel,
   101  	}
   102  
   103  	// Send request
   104  	resBody, err := c.makeReq(ctx, http.MethodPost, "", route, ur)
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	// Decode reply
   110  	var urr pdv1.UpdateRecordReply
   111  	err = json.Unmarshal(resBody, &urr)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	err = util.VerifyChallenge(c.pid, challenge, urr.Response)
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	return nil
   121  }
   122  
   123  // UpdateUnvetted sends a UpdateRecord request to the unvetted politeiad v1
   124  // API.
   125  func (c *Client) UpdateUnvetted(ctx context.Context, token string, mdAppend, mdOverwrite []pdv1.MetadataStream, filesAdd []pdv1.File, filesDel []string) error {
   126  	return c.updateRecord(ctx, pdv1.UpdateUnvettedRoute, token,
   127  		mdAppend, mdOverwrite, filesAdd, filesDel)
   128  }
   129  
   130  // UpdateVetted sends a UpdateRecord request to the vetted politeiad v1 API.
   131  func (c *Client) UpdateVetted(ctx context.Context, token string, mdAppend, mdOverwrite []pdv1.MetadataStream, filesAdd []pdv1.File, filesDel []string) error {
   132  	return c.updateRecord(ctx, pdv1.UpdateVettedRoute, token,
   133  		mdAppend, mdOverwrite, filesAdd, filesDel)
   134  }
   135  
   136  // UpdateVettedMetadata sends a UpdateVettedMetadata request to the politeiad
   137  // v1 API.
   138  func (c *Client) UpdateVettedMetadata(ctx context.Context, token string, mdAppend, mdOverwrite []pdv1.MetadataStream) error {
   139  	// Setup request
   140  	challenge, err := util.Random(pdv1.ChallengeSize)
   141  	if err != nil {
   142  		return err
   143  	}
   144  	uvm := pdv1.UpdateVettedMetadata{
   145  		Challenge:   hex.EncodeToString(challenge),
   146  		Token:       token,
   147  		MDAppend:    mdAppend,
   148  		MDOverwrite: mdOverwrite,
   149  	}
   150  
   151  	// Send request
   152  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   153  		pdv1.UpdateVettedMetadataRoute, uvm)
   154  	if err != nil {
   155  		return nil
   156  	}
   157  
   158  	// Decode reply
   159  	var uvmr pdv1.UpdateVettedMetadataReply
   160  	err = json.Unmarshal(resBody, &uvmr)
   161  	if err != nil {
   162  		return err
   163  	}
   164  	err = util.VerifyChallenge(c.pid, challenge, uvmr.Response)
   165  	if err != nil {
   166  		return err
   167  	}
   168  
   169  	return nil
   170  }
   171  
   172  // SetUnvettedStatus sends a SetUnvettedStatus request to the politeiad v1
   173  // API.
   174  func (c *Client) SetUnvettedStatus(ctx context.Context, token string, status pdv1.RecordStatusT, mdAppend, mdOverwrite []pdv1.MetadataStream) error {
   175  	// Setup request
   176  	challenge, err := util.Random(pdv1.ChallengeSize)
   177  	if err != nil {
   178  		return err
   179  	}
   180  	sus := pdv1.SetUnvettedStatus{
   181  		Challenge:   hex.EncodeToString(challenge),
   182  		Token:       token,
   183  		Status:      status,
   184  		MDAppend:    mdAppend,
   185  		MDOverwrite: mdOverwrite,
   186  	}
   187  
   188  	// Send request
   189  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   190  		pdv1.SetUnvettedStatusRoute, sus)
   191  	if err != nil {
   192  		return err
   193  	}
   194  
   195  	// Decode reply
   196  	var susr pdv1.SetUnvettedStatusReply
   197  	err = json.Unmarshal(resBody, &susr)
   198  	if err != nil {
   199  		return err
   200  	}
   201  	err = util.VerifyChallenge(c.pid, challenge, susr.Response)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	return nil
   207  }
   208  
   209  // SetVettedStatus sends a SetVettedStatus request to the politeiad v1 API.
   210  func (c *Client) SetVettedStatus(ctx context.Context, token string, status pdv1.RecordStatusT, mdAppend, mdOverwrite []pdv1.MetadataStream) error {
   211  	// Setup request
   212  	challenge, err := util.Random(pdv1.ChallengeSize)
   213  	if err != nil {
   214  		return err
   215  	}
   216  	svs := pdv1.SetVettedStatus{
   217  		Challenge:   hex.EncodeToString(challenge),
   218  		Token:       token,
   219  		Status:      status,
   220  		MDAppend:    mdAppend,
   221  		MDOverwrite: mdOverwrite,
   222  	}
   223  
   224  	// Send request
   225  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   226  		pdv1.SetVettedStatusRoute, svs)
   227  	if err != nil {
   228  		return err
   229  	}
   230  
   231  	// Decode reply
   232  	var svsr pdv1.SetVettedStatusReply
   233  	err = json.Unmarshal(resBody, &svsr)
   234  	if err != nil {
   235  		return err
   236  	}
   237  	err = util.VerifyChallenge(c.pid, challenge, svsr.Response)
   238  	if err != nil {
   239  		return err
   240  	}
   241  
   242  	return nil
   243  }
   244  
   245  // GetUnvetted sends a GetUnvetted request to the politeiad v1 API.
   246  func (c *Client) GetUnvetted(ctx context.Context, token string) (*pdv1.Record, error) {
   247  	// Setup request
   248  	challenge, err := util.Random(pdv1.ChallengeSize)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	gu := pdv1.GetUnvetted{
   253  		Challenge: hex.EncodeToString(challenge),
   254  		Token:     token,
   255  	}
   256  
   257  	// Send request
   258  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   259  		pdv1.GetUnvettedRoute, gu)
   260  	if err != nil {
   261  		return nil, err
   262  	}
   263  
   264  	// Decode reply
   265  	var gur pdv1.GetUnvettedReply
   266  	err = json.Unmarshal(resBody, &gur)
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  	err = util.VerifyChallenge(c.pid, challenge, gur.Response)
   271  	if err != nil {
   272  		return nil, err
   273  	}
   274  
   275  	return &gur.Record, nil
   276  }
   277  
   278  // GetVetted sends a GetVetted request to the politeiad v1 API.
   279  func (c *Client) GetVetted(ctx context.Context, token, version string) (*pdv1.Record, error) {
   280  	// Setup request
   281  	challenge, err := util.Random(pdv1.ChallengeSize)
   282  	if err != nil {
   283  		return nil, err
   284  	}
   285  	gv := pdv1.GetVetted{
   286  		Challenge: hex.EncodeToString(challenge),
   287  		Token:     token,
   288  		Version:   version,
   289  	}
   290  
   291  	// Send request
   292  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   293  		pdv1.GetVettedRoute, gv)
   294  	if err != nil {
   295  		return nil, err
   296  	}
   297  
   298  	// Decode reply
   299  	var gvr pdv1.GetVettedReply
   300  	err = json.Unmarshal(resBody, &gvr)
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  	err = util.VerifyChallenge(c.pid, challenge, gvr.Response)
   305  	if err != nil {
   306  		return nil, err
   307  	}
   308  
   309  	return &gvr.Record, nil
   310  }
   311  
   312  // PluginCommand sends a PluginCommand request to the politeiad v1 API.
   313  func (c *Client) PluginCommand(ctx context.Context, pluginID, cmd, payload string) (string, error) {
   314  	// Setup request
   315  	challenge, err := util.Random(pdv1.ChallengeSize)
   316  	if err != nil {
   317  		return "", err
   318  	}
   319  	pc := pdv1.PluginCommand{
   320  		Challenge: hex.EncodeToString(challenge),
   321  		ID:        pluginID,
   322  		Command:   cmd,
   323  		CommandID: cmd,
   324  		Payload:   payload,
   325  	}
   326  
   327  	// Send request
   328  	resBody, err := c.makeReq(ctx, http.MethodPost, "",
   329  		pdv1.PluginCommandRoute, pc)
   330  	if err != nil {
   331  		return "", err
   332  	}
   333  
   334  	// Decode reply
   335  	var pcr pdv1.PluginCommandReply
   336  	err = json.Unmarshal(resBody, &pcr)
   337  	if err != nil {
   338  		return "", err
   339  	}
   340  	err = util.VerifyChallenge(c.pid, challenge, pcr.Response)
   341  	if err != nil {
   342  		return "", err
   343  	}
   344  
   345  	return pcr.Payload, nil
   346  }