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 }