* Rework client/server authentication. - Remove Signature from all requests, and instead expect a signature in HTTP header "VSP-Client-Signature". - Remove CommitmentSignatures from the database. - Use a bool flag to indicate when a ticket is missing from the database rather than an error. This commit introduces a lot of duplication into each of the authenticated HTTP handlers. This should be removed in future work which moves the authentication to a dedicated middleware. * Introduce auth and rpc middleware. This removed the duplication added in the previous commit, and also removes the duplication of RPC client error handling.
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package webapi
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/decred/dcrd/chaincfg/v3"
|
|
"github.com/decred/dcrd/dcrutil/v3"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func currentVoteVersion(params *chaincfg.Params) uint32 {
|
|
var latestVersion uint32
|
|
for version := range params.Deployments {
|
|
if latestVersion < version {
|
|
latestVersion = version
|
|
}
|
|
}
|
|
return latestVersion
|
|
}
|
|
|
|
// isValidVoteChoices returns an error if provided vote choices are not valid for
|
|
// the most recent agendas.
|
|
func isValidVoteChoices(params *chaincfg.Params, voteVersion uint32, voteChoices map[string]string) error {
|
|
|
|
agendaLoop:
|
|
for agenda, choice := range voteChoices {
|
|
// Does the agenda exist?
|
|
for _, v := range params.Deployments[voteVersion] {
|
|
if v.Vote.Id == agenda {
|
|
// Agenda exists - does the vote choice exist?
|
|
for _, c := range v.Vote.Choices {
|
|
if c.Id == choice {
|
|
// Valid agenda and choice combo! Check the next one...
|
|
continue agendaLoop
|
|
}
|
|
}
|
|
return fmt.Errorf("choice %q not found for agenda %q", choice, agenda)
|
|
}
|
|
|
|
}
|
|
return fmt.Errorf("agenda %q not found for vote version %d", agenda, voteVersion)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func validateSignature(reqBytes []byte, commitmentAddress string, c *gin.Context) error {
|
|
// Ensure a signature is provided.
|
|
signature := c.GetHeader("VSP-Client-Signature")
|
|
if signature == "" {
|
|
return errors.New("no VSP-Client-Signature header")
|
|
}
|
|
|
|
err := dcrutil.VerifyMessage(commitmentAddress, signature, string(reqBytes), cfg.NetParams)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|