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 }