Skip to content

Commit

Permalink
feat: Add download files signature check (#472)
Browse files Browse the repository at this point in the history
* refactor: Rename GetAddressFromHeaders to CheckSignature

* docs: Update error messages and comments

* feat: Add headers to GET requests

* feat: Add auth to download files route
  • Loading branch information
bgins authored Dec 20, 2024
1 parent 43b5c47 commit 6b880ec
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 27 deletions.
14 changes: 8 additions & 6 deletions pkg/http/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ func AddHeaders(
return nil
}

// this will use the client headers to ensure that a message was signed
// by the holder of a private key for a specific address
// there is a "X-Lilypad-User" header that will contain the address
// there is a "X-Lilypad-Signature" header that will contain the signature
// we use the signature to verify that the message was signed by the private key
func GetAddressFromHeaders(req *http.Request) (string, error) {
// Use the client headers to ensure that a message was signed
// by the holder of a private key for a specific address.
// The "X-Lilypad-User" header contains the address.
// The "X-Lilypad-Signature" header contains the signature.
// We use the signature to verify that the message was signed by the private key.
func CheckSignature(req *http.Request) (string, error) {
userHeader := req.Header.Get(X_LILYPAD_USER_HEADER)
if userHeader == "" {
return "", HTTPError{
Expand Down Expand Up @@ -319,6 +319,8 @@ func GetRequestBuffer(
if err != nil {
return nil, err
}
privateKey, err := web3.ParsePrivateKey(options.PrivateKey)
AddHeaders(req, privateKey, web3.GetAddress(privateKey).String())

resp, err := client.Do(req)
if err != nil {
Expand Down
61 changes: 40 additions & 21 deletions pkg/solver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"archive/tar"
"context"
"encoding/json"
"errors"
"fmt"
"io"
corehttp "net/http"
Expand Down Expand Up @@ -277,12 +278,12 @@ func (solverServer *solverServer) getResult(res corehttp.ResponseWriter, req *co
*
*/
func (solverServer *solverServer) addJobOffer(jobOffer data.JobOffer, res corehttp.ResponseWriter, req *corehttp.Request) (*data.JobOfferContainer, error) {
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the job creator can post a job offer
// Only the job creator can post their job offer
if signerAddress != jobOffer.JobCreator {
return nil, fmt.Errorf("job creator address does not match signer address")
}
Expand All @@ -298,12 +299,12 @@ func (solverServer *solverServer) addResourceOffer(resourceOffer data.ResourceOf
versionHeader, _ := http.GetVersionFromHeaders(req)
log.Debug().Msgf("resource provider adding offer with version header %s", versionHeader)

signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the job creator can post a job offer
// Only the resource provider can post their resource offer
if signerAddress != resourceOffer.ResourceProvider {
return nil, fmt.Errorf("resource provider address does not match signer address")
}
Expand All @@ -326,12 +327,12 @@ func (solverServer *solverServer) addResult(results data.Result, res corehttp.Re
if deal == nil {
return nil, fmt.Errorf("deal not found")
}
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the resource provider can add a result
// Only the resource provider in a deal can add a result
if signerAddress != deal.ResourceProvider {
return nil, fmt.Errorf("resource provider address does not match signer address")
}
Expand Down Expand Up @@ -367,12 +368,12 @@ func (solverServer *solverServer) updateTransactionsResourceProvider(payload dat
log.Error().Err(err).Msgf("deal not found")
return nil, fmt.Errorf("deal not found")
}
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the job creator can post a job offer
// Only the resource provider in a deal can update its transactions
if signerAddress != deal.ResourceProvider {
return nil, fmt.Errorf("resource provider address does not match signer address")
}
Expand All @@ -391,12 +392,12 @@ func (solverServer *solverServer) updateTransactionsJobCreator(payload data.Deal
log.Error().Err(err).Msgf("deal not found")
return nil, fmt.Errorf("deal not found")
}
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the job creator can post a job offer
// Only the job creator in a deal can update its transactions
if signerAddress != deal.JobCreator {
return nil, fmt.Errorf("job creator address does not match signer address")
}
Expand All @@ -415,12 +416,12 @@ func (solverServer *solverServer) updateTransactionsMediator(payload data.DealTr
log.Error().Err(err).Msgf("deal not found")
return nil, fmt.Errorf("deal not found")
}
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return nil, err
}
// only the job creator can post a job offer
// Only the mediator in a deal can update its transactions
if signerAddress != deal.Mediator {
return nil, fmt.Errorf("job creator address does not match mediator address")
}
Expand Down Expand Up @@ -458,6 +459,24 @@ func (solverServer *solverServer) downloadFiles(res corehttp.ResponseWriter, req
StatusCode: corehttp.StatusNotFound,
}
}

signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("error checking signature")
return &http.HTTPError{
Message: errors.New("not authorized").Error(),
StatusCode: corehttp.StatusUnauthorized,
}
}
// Only the job creator in a deal can download job outputs
if signerAddress != deal.JobCreator {
log.Error().Err(err).Msgf("job creator address does not match signer address")
return &http.HTTPError{
Message: errors.New("not authorized").Error(),
StatusCode: corehttp.StatusUnauthorized,
}
}

filesPath := GetDealsFilePath(id)
// check if the filesPath directory exists
if _, err := os.Stat(filesPath); os.IsNotExist(err) {
Expand Down Expand Up @@ -500,12 +519,12 @@ func (solverServer *solverServer) uploadFiles(res corehttp.ResponseWriter, req *
log.Error().Msgf("deal not found")
return err
}
signerAddress, err := http.GetAddressFromHeaders(req)
signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("have error parsing user address")
log.Error().Err(err).Msgf("error checking signature")
return err
}
// only the resource provider can add a result
// Only the resource provider in a deal can upload job outputs
if signerAddress != deal.ResourceProvider {
return fmt.Errorf("resource provider address does not match signer address")
}
Expand Down

0 comments on commit 6b880ec

Please sign in to comment.