github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/api/parse_request.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/qri-io/dataset"
    12  	"github.com/qri-io/qfs"
    13  	"github.com/qri-io/qri/api/util"
    14  	"github.com/qri-io/qri/base/fill"
    15  	"github.com/qri-io/qri/dsref"
    16  	"github.com/qri-io/qri/lib"
    17  	"gopkg.in/yaml.v2"
    18  )
    19  
    20  // parseGetParamsFromRequest parse the form from the request to create `lib.GetParams`
    21  func parseGetParamsFromRequest(r *http.Request, p *lib.GetParams) error {
    22  	log.Debugf("parseGetParams ref:%s", r.FormValue("ref"))
    23  	p.Ref = r.FormValue("ref")
    24  
    25  	ref, err := dsref.Parse(p.Ref)
    26  	if err != nil {
    27  		return err
    28  	}
    29  
    30  	if ref.Username == "me" {
    31  		return fmt.Errorf("username \"me\" not allowed")
    32  	}
    33  
    34  	p.Selector = r.FormValue("selector")
    35  
    36  	p.All = util.ReqParamBool(r, "all", true)
    37  	p.Limit = util.ReqParamInt(r, "limit", 0)
    38  	p.Offset = util.ReqParamInt(r, "offset", 0)
    39  	if !(p.Offset == 0 && p.Limit == 0) {
    40  		p.All = false
    41  	}
    42  
    43  	if p.All && p.Limit == 0 && p.Offset == 0 {
    44  		page := -1
    45  		pageSize := -1
    46  		if i := util.ReqParamInt(r, "page", 0); i != 0 {
    47  			page = i
    48  		}
    49  		if i := util.ReqParamInt(r, "pageSize", 0); i != 0 {
    50  			pageSize = i
    51  		}
    52  		// we don't want the defaults to override this and also only want to
    53  		// set values if they are present
    54  		if page >= 0 && pageSize >= 0 {
    55  			p.Limit = pageSize
    56  			p.Offset = (page - 1) * pageSize
    57  			p.All = false
    58  		}
    59  	}
    60  	return nil
    61  }
    62  
    63  // parseSaveParamsFromRequest parses the form from the request
    64  // it ignores `bodyFile`, `filePaths`, and `secrets`
    65  // `dataset`, if it exists, is expected to be a json string in
    66  // the form of a `dataset.Dataset`
    67  func parseSaveParamsFromRequest(r *http.Request, p *lib.SaveParams) error {
    68  	p.Ref = r.FormValue("ref")
    69  	p.Title = r.FormValue("title")
    70  	p.Message = r.FormValue("message")
    71  	p.Apply = util.ReqParamBool(r, "apply", false)
    72  	p.Replace = util.ReqParamBool(r, "replace", false)
    73  	p.Private = util.ReqParamBool(r, "private", false)
    74  	p.ConvertFormatToPrev = util.ReqParamBool(r, "convertFormatToPrev", false)
    75  	p.Drop = r.FormValue("drop")
    76  	p.Force = util.ReqParamBool(r, "force", false)
    77  	p.ShouldRender = util.ReqParamBool(r, "shouldRender", false)
    78  	p.NewName = util.ReqParamBool(r, "newName", false)
    79  	dsBytes := []byte(r.FormValue("dataset"))
    80  	if len(dsBytes) != 0 {
    81  		p.Dataset = &dataset.Dataset{}
    82  		err := p.Dataset.UnmarshalJSON(dsBytes)
    83  		if err != nil {
    84  			return err
    85  		}
    86  	}
    87  	log.Debugw("parseSaveParamsFromRequest", "params", p)
    88  	return nil
    89  }
    90  
    91  // parseDatasetFromRequest extracts a dataset document from a http Request
    92  func parseDatasetFromRequest(r *http.Request, ds *dataset.Dataset) (err error) {
    93  	datafile, dataHeader, err := r.FormFile("file")
    94  	if err == http.ErrMissingFile {
    95  		// users should be allowed to only upload certain parts of the dataset
    96  		err = nil
    97  	} else if err != nil {
    98  		err = fmt.Errorf("error opening dataset file: %s", err)
    99  		return
   100  	}
   101  	if datafile != nil {
   102  		switch strings.ToLower(filepath.Ext(dataHeader.Filename)) {
   103  		case ".yaml", ".yml":
   104  			var data []byte
   105  			data, err = ioutil.ReadAll(datafile)
   106  			if err != nil {
   107  				err = fmt.Errorf("reading dataset file: %w", err)
   108  				return
   109  			}
   110  			fields := &map[string]interface{}{}
   111  			if err = yaml.Unmarshal(data, fields); err != nil {
   112  				err = fmt.Errorf("deserializing YAML file: %w", err)
   113  				return
   114  			}
   115  			if err = fill.Struct(*fields, ds); err != nil {
   116  				return
   117  			}
   118  		case ".json":
   119  			if err = json.NewDecoder(datafile).Decode(ds); err != nil {
   120  				err = fmt.Errorf("error decoding json file: %w", err)
   121  				return
   122  			}
   123  		}
   124  	}
   125  
   126  	if username := r.FormValue("username"); username != "" {
   127  		ds.Peername = username
   128  	}
   129  	if name := r.FormValue("name"); name != "" {
   130  		ds.Name = name
   131  	}
   132  	if bp := r.FormValue("body_path"); bp != "" {
   133  		ds.BodyPath = bp
   134  	}
   135  
   136  	tfFile, tfHeader, err := r.FormFile("transform")
   137  	if err == http.ErrMissingFile {
   138  		// users should be allowed to only upload certain parts of the dataset
   139  		err = nil
   140  	} else if err != nil {
   141  		err = fmt.Errorf("error opening transform file: %w", err)
   142  		return
   143  	}
   144  	if tfFile != nil {
   145  		if ds.Transform == nil {
   146  			ds.Transform = &dataset.Transform{}
   147  		}
   148  		ds.Transform.SetScriptFile(qfs.NewMemfileReader(tfHeader.Filename, tfFile))
   149  	}
   150  
   151  	vizFile, vizHeader, err := r.FormFile("viz")
   152  	if err == http.ErrMissingFile {
   153  		// users should be allowed to only upload certain parts of the dataset
   154  		err = nil
   155  	} else if err != nil {
   156  		err = fmt.Errorf("error opening viz file: %w", err)
   157  		return
   158  	}
   159  	if vizFile != nil {
   160  		if ds.Viz == nil {
   161  			ds.Viz = &dataset.Viz{}
   162  		}
   163  		ds.Viz.SetScriptFile(qfs.NewMemfileReader(vizHeader.Filename, vizFile))
   164  	}
   165  
   166  	readmeFile, readmeHeader, err := r.FormFile("readme")
   167  	if err == http.ErrMissingFile {
   168  		// users should be allowed to only upload certain parts of the dataset
   169  		err = nil
   170  	} else if err != nil {
   171  		err = fmt.Errorf("error opening readme file: %w", err)
   172  		return
   173  	}
   174  	if readmeFile != nil {
   175  		if ds.Readme == nil {
   176  			ds.Readme = &dataset.Readme{}
   177  			ds.Readme.SetScriptFile(qfs.NewMemfileReader(readmeHeader.Filename, readmeFile))
   178  		}
   179  	}
   180  
   181  	bodyfile, bodyHeader, err := r.FormFile("body")
   182  	if err == http.ErrMissingFile {
   183  		// users should be allowed to only upload certain parts of the dataset
   184  		err = nil
   185  	} else if err != nil {
   186  		err = fmt.Errorf("error opening body file: %w", err)
   187  		return
   188  	}
   189  	if bodyfile != nil {
   190  		ds.SetBodyFile(qfs.NewMemfileReader(bodyHeader.Filename, bodyfile))
   191  	}
   192  
   193  	return
   194  }