github.com/decred/politeia@v1.4.0/politeiawww/legacy/records/records.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 records 6 7 import ( 8 "encoding/json" 9 "net/http" 10 11 pdclient "github.com/decred/politeia/politeiad/client" 12 v1 "github.com/decred/politeia/politeiawww/api/records/v1" 13 "github.com/decred/politeia/politeiawww/config" 14 "github.com/decred/politeia/politeiawww/legacy/events" 15 "github.com/decred/politeia/politeiawww/legacy/sessions" 16 "github.com/decred/politeia/politeiawww/legacy/user" 17 "github.com/decred/politeia/util" 18 ) 19 20 // Records is the context for the records API. 21 type Records struct { 22 cfg *config.Config 23 politeiad *pdclient.Client 24 userdb user.Database 25 sessions *sessions.Sessions 26 events *events.Manager 27 policy *v1.PolicyReply 28 } 29 30 // HandlePolicy is the request handler for the records v1 Policy route. 31 func (c *Records) HandlePolicy(w http.ResponseWriter, r *http.Request) { 32 log.Tracef("HandlePolicy") 33 34 util.RespondWithJSON(w, http.StatusOK, c.policy) 35 } 36 37 // HandleNew is the request handler for the records v1 New route. 38 func (c *Records) HandleNew(w http.ResponseWriter, r *http.Request) { 39 log.Tracef("HandleNew") 40 41 var n v1.New 42 decoder := json.NewDecoder(r.Body) 43 if err := decoder.Decode(&n); err != nil { 44 respondWithError(w, r, "HandleNew: unmarshal", 45 v1.UserErrorReply{ 46 ErrorCode: v1.ErrorCodeInputInvalid, 47 }) 48 return 49 } 50 51 u, err := c.sessions.GetSessionUser(w, r) 52 if err != nil { 53 respondWithError(w, r, 54 "HandleNew: GetSessionUser: %v", err) 55 return 56 } 57 58 nr, err := c.processNew(r.Context(), n, *u) 59 if err != nil { 60 respondWithError(w, r, 61 "HandleNew: processNew: %v", err) 62 return 63 } 64 65 util.RespondWithJSON(w, http.StatusOK, nr) 66 } 67 68 // HandleEdit is the request handler for the records v1 Edit route. 69 func (c *Records) HandleEdit(w http.ResponseWriter, r *http.Request) { 70 log.Tracef("HandleEdit") 71 72 var e v1.Edit 73 decoder := json.NewDecoder(r.Body) 74 if err := decoder.Decode(&e); err != nil { 75 respondWithError(w, r, "HandleEdit: unmarshal", 76 v1.UserErrorReply{ 77 ErrorCode: v1.ErrorCodeInputInvalid, 78 }) 79 return 80 } 81 82 u, err := c.sessions.GetSessionUser(w, r) 83 if err != nil { 84 respondWithError(w, r, 85 "HandleEdit: GetSessionUser: %v", err) 86 return 87 } 88 89 er, err := c.processEdit(r.Context(), e, *u) 90 if err != nil { 91 respondWithError(w, r, 92 "HandleEdit: processEdit: %v", err) 93 return 94 } 95 96 util.RespondWithJSON(w, http.StatusOK, er) 97 } 98 99 // HandleSetStatus is the request handler for the records v1 SetStatus route. 100 func (c *Records) HandleSetStatus(w http.ResponseWriter, r *http.Request) { 101 log.Tracef("HandleSetStatus") 102 103 var ss v1.SetStatus 104 decoder := json.NewDecoder(r.Body) 105 if err := decoder.Decode(&ss); err != nil { 106 respondWithError(w, r, "HandleSetStatus: unmarshal", 107 v1.UserErrorReply{ 108 ErrorCode: v1.ErrorCodeInputInvalid, 109 }) 110 return 111 } 112 113 u, err := c.sessions.GetSessionUser(w, r) 114 if err != nil { 115 respondWithError(w, r, 116 "HandleSetStatus: GetSessionUser: %v", err) 117 return 118 } 119 120 ssr, err := c.processSetStatus(r.Context(), ss, *u) 121 if err != nil { 122 respondWithError(w, r, 123 "HandleSetStatus: processSetStatus: %v", err) 124 return 125 } 126 127 util.RespondWithJSON(w, http.StatusOK, ssr) 128 } 129 130 // HandleDetails is the request handler for the records v1 Details route. 131 func (c *Records) HandleDetails(w http.ResponseWriter, r *http.Request) { 132 log.Tracef("HandleDetails") 133 134 var d v1.Details 135 decoder := json.NewDecoder(r.Body) 136 if err := decoder.Decode(&d); err != nil { 137 respondWithError(w, r, "HandleDetails: unmarshal", 138 v1.UserErrorReply{ 139 ErrorCode: v1.ErrorCodeInputInvalid, 140 }) 141 return 142 } 143 144 // Lookup session user. This is a public route so a session may not 145 // exist. Ignore any session not found errors. 146 u, err := c.sessions.GetSessionUser(w, r) 147 if err != nil && err != sessions.ErrSessionNotFound { 148 respondWithError(w, r, 149 "HandleDetails: GetSessionUser: %v", err) 150 return 151 } 152 153 dr, err := c.processDetails(r.Context(), d, u) 154 if err != nil { 155 respondWithError(w, r, 156 "HandleDetails: processDetails: %v", err) 157 return 158 } 159 160 util.RespondWithJSON(w, http.StatusOK, dr) 161 } 162 163 // HandleTimestamps is the request handler for the records v1 Timestamps route. 164 func (c *Records) HandleTimestamps(w http.ResponseWriter, r *http.Request) { 165 log.Tracef("HandleTimestamps") 166 167 var t v1.Timestamps 168 decoder := json.NewDecoder(r.Body) 169 if err := decoder.Decode(&t); err != nil { 170 respondWithError(w, r, "HandleTimestamps: unmarshal", 171 v1.UserErrorReply{ 172 ErrorCode: v1.ErrorCodeInputInvalid, 173 }) 174 return 175 } 176 177 // Lookup session user. This is a public route so a session may not 178 // exist. Ignore any session not found errors. 179 u, err := c.sessions.GetSessionUser(w, r) 180 if err != nil && err != sessions.ErrSessionNotFound { 181 respondWithError(w, r, 182 "HandleTimestamps: getSessionUser: %v", err) 183 return 184 } 185 186 isAdmin := u != nil && u.Admin 187 tr, err := c.processTimestamps(r.Context(), t, isAdmin) 188 if err != nil { 189 respondWithError(w, r, 190 "HandleTimestamps: processTimestamps: %v", err) 191 return 192 } 193 194 util.RespondWithJSON(w, http.StatusOK, tr) 195 } 196 197 // HandleRecords is the request handler for the records v1 Records route. 198 func (c *Records) HandleRecords(w http.ResponseWriter, r *http.Request) { 199 log.Tracef("HandleRecords") 200 201 var rs v1.Records 202 decoder := json.NewDecoder(r.Body) 203 if err := decoder.Decode(&rs); err != nil { 204 respondWithError(w, r, "HandleRecords: unmarshal", 205 v1.UserErrorReply{ 206 ErrorCode: v1.ErrorCodeInputInvalid, 207 }) 208 return 209 } 210 211 // Lookup session user. This is a public route so a session may not 212 // exist. Ignore any session not found errors. 213 u, err := c.sessions.GetSessionUser(w, r) 214 if err != nil && err != sessions.ErrSessionNotFound { 215 respondWithError(w, r, 216 "HandleRecords: GetSessionUser: %v", err) 217 return 218 } 219 220 rsr, err := c.processRecords(r.Context(), rs, u) 221 if err != nil { 222 respondWithError(w, r, 223 "HandleRecords: processRecords: %v", err) 224 return 225 } 226 227 util.RespondWithJSON(w, http.StatusOK, rsr) 228 } 229 230 // HandleInventory is the request handler for the records v1 Inventory route. 231 func (c *Records) HandleInventory(w http.ResponseWriter, r *http.Request) { 232 log.Tracef("HandleInventory") 233 234 var i v1.Inventory 235 decoder := json.NewDecoder(r.Body) 236 if err := decoder.Decode(&i); err != nil { 237 respondWithError(w, r, "HandleInventory: unmarshal", 238 v1.UserErrorReply{ 239 ErrorCode: v1.ErrorCodeInputInvalid, 240 }) 241 return 242 } 243 244 // Lookup session user. This is a public route so a session may not 245 // exist. Ignore any session not found errors. 246 u, err := c.sessions.GetSessionUser(w, r) 247 if err != nil && err != sessions.ErrSessionNotFound { 248 respondWithError(w, r, 249 "HandleInventory: GetSessionUser: %v", err) 250 return 251 } 252 253 ir, err := c.processInventory(r.Context(), i, u) 254 if err != nil { 255 respondWithError(w, r, 256 "HandleInventory: processInventory: %v", err) 257 return 258 } 259 260 util.RespondWithJSON(w, http.StatusOK, ir) 261 } 262 263 // HandleInventoryOrdered is the request handler for the records v1 264 // InventoryOrdered route. 265 func (c *Records) HandleInventoryOrdered(w http.ResponseWriter, r *http.Request) { 266 log.Tracef("HandleInventoryOrdered") 267 268 var i v1.InventoryOrdered 269 decoder := json.NewDecoder(r.Body) 270 if err := decoder.Decode(&i); err != nil { 271 respondWithError(w, r, "HandleInventoryOrdered: unmarshal", 272 v1.UserErrorReply{ 273 ErrorCode: v1.ErrorCodeInputInvalid, 274 }) 275 return 276 } 277 278 // Lookup session user. This is a public route so a session may not 279 // exist. Ignore any session not found errors. 280 u, err := c.sessions.GetSessionUser(w, r) 281 if err != nil && err != sessions.ErrSessionNotFound { 282 respondWithError(w, r, 283 "HandleInventoryOrdered: GetSessionUser: %v", err) 284 return 285 } 286 287 ir, err := c.processInventoryOrdered(r.Context(), i, u) 288 if err != nil { 289 respondWithError(w, r, 290 "HandleInventoryOrdered: processInventoryOrdered: %v", err) 291 return 292 } 293 294 util.RespondWithJSON(w, http.StatusOK, ir) 295 } 296 297 // HandleUserRecords is the request handler for the records v1 UserRecords 298 // route. 299 func (c *Records) HandleUserRecords(w http.ResponseWriter, r *http.Request) { 300 log.Tracef("HandleUserRecords") 301 302 var ur v1.UserRecords 303 decoder := json.NewDecoder(r.Body) 304 if err := decoder.Decode(&ur); err != nil { 305 respondWithError(w, r, "HandleUserRecords: unmaurhal", 306 v1.UserErrorReply{ 307 ErrorCode: v1.ErrorCodeInputInvalid, 308 }) 309 return 310 } 311 312 // Lookup session user. This is a public route so a session may not 313 // exist. Ignore any session not found errour. 314 u, err := c.sessions.GetSessionUser(w, r) 315 if err != nil && err != sessions.ErrSessionNotFound { 316 respondWithError(w, r, 317 "HandleUserRecords: GetSessionUser: %v", err) 318 return 319 } 320 321 urr, err := c.processUserRecords(r.Context(), ur, u) 322 if err != nil { 323 respondWithError(w, r, 324 "HandleUserRecords: processsUserRecords: %v", err) 325 return 326 } 327 328 util.RespondWithJSON(w, http.StatusOK, urr) 329 } 330 331 // New returns a new Records context. 332 func New(cfg *config.Config, pdc *pdclient.Client, udb user.Database, s *sessions.Sessions, e *events.Manager) *Records { 333 return &Records{ 334 cfg: cfg, 335 politeiad: pdc, 336 userdb: udb, 337 sessions: s, 338 events: e, 339 policy: &v1.PolicyReply{ 340 RecordsPageSize: v1.RecordsPageSize, 341 InventoryPageSize: v1.InventoryPageSize, 342 }, 343 } 344 }