summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2015-12-19 22:07:08 (GMT)
committerChristian Pointner <equinox@helsinki.at>2015-12-19 22:07:15 (GMT)
commit94eab548c583491912335d58f6442eb952cec5ab (patch)
tree1cfcd618f196343fab14ff2b75e48da60292f3b2
parent5559994f6c1cde34cb806fbc6bcc30e0ac4751f0 (diff)
fetcher now checks for permissions
improved error handling for fetcher
-rw-r--r--src/helsinki.at/rhimport/fetcher.go63
-rw-r--r--src/helsinki.at/rhimportd/ctrlTelnet.go41
-rw-r--r--src/helsinki.at/rhimportd/ctrlWebSimple.go14
3 files changed, 93 insertions, 25 deletions
diff --git a/src/helsinki.at/rhimport/fetcher.go b/src/helsinki.at/rhimport/fetcher.go
index fed51bf..300abef 100644
--- a/src/helsinki.at/rhimport/fetcher.go
+++ b/src/helsinki.at/rhimport/fetcher.go
@@ -29,6 +29,7 @@ import (
"github.com/golang-basic/go-curl"
"io/ioutil"
"mime"
+ "net/http"
"net/url"
"os"
"path"
@@ -36,6 +37,11 @@ import (
"strings"
)
+type FetchResult struct {
+ ResponseCode int
+ ErrorString string
+}
+
type FetcherCurlCBData struct {
basepath string
filename string
@@ -83,7 +89,7 @@ func curlWriteCallback(ptr []byte, userdata interface{}) bool {
return true
}
-func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) {
+func FetchFileCurl(ctx *ImportContext, res *FetchResult, uri *url.URL) (err error) {
rhl.Printf("curl-based fetcher called for '%s'", ctx.SourceUri)
easy := curl.EasyInit()
@@ -116,7 +122,7 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) {
easy.Setopt(curl.OPT_PROGRESSDATA, ctx)
if err = easy.Perform(); err != nil {
- err = fmt.Errorf("fetcher('%s'): %s", ctx.SourceUri, err)
+ err = fmt.Errorf("curl-fetcher('%s'): %s", ctx.SourceUri, err)
return
}
@@ -130,7 +136,7 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) {
return
}
-func FetchFileLocal(ctx *ImportContext, uri *url.URL) (err error) {
+func FetchFileLocal(ctx *ImportContext, res *FetchResult, uri *url.URL) (err error) {
rhl.Printf("Local fetcher called for '%s'", ctx.SourceUri)
if ctx.ProgressCallBack != nil {
ctx.ProgressCallBack(1, "fetching", 1.0, ctx.ProgressCallBackData)
@@ -139,15 +145,17 @@ func FetchFileLocal(ctx *ImportContext, uri *url.URL) (err error) {
ctx.SourceFile = filepath.Join(ctx.Config.LocalFetchDir, path.Clean("/"+uri.Path))
var src *os.File
if src, err = os.Open(ctx.SourceFile); err != nil {
- return
+ res.ResponseCode = http.StatusBadRequest
+ res.ErrorString = fmt.Sprintf("local-file open(): %s", err)
+ return nil
}
- defer src.Close()
+ src.Close()
ctx.DeleteSourceFile = false
ctx.DeleteSourceDir = false
return
}
-type FetchFunc func(*ImportContext, *url.URL) (err error)
+type FetchFunc func(*ImportContext, *FetchResult, *url.URL) (err error)
// TODO: implement fetchers for:
// archiv://
@@ -182,15 +190,52 @@ func fetcher_init() {
}
}
-func FetchFile(ctx *ImportContext) (err error) {
+func checkPassword(ctx *ImportContext, result *FetchResult) (err error) {
+ cached := true
+
+ for {
+ req := getPasswordRequest{}
+ req.username = ctx.UserName
+ req.cached = cached
+ req.response = make(chan getPasswordResult)
+ ctx.RdDb.getPasswordChan <- req
+
+ res := <-req.response
+ if res.err != nil {
+ return res.err
+ }
+ if ctx.Password == res.password {
+ return nil
+ }
+ if cached {
+ cached = false
+ } else {
+ break
+ }
+ }
+ result.ResponseCode = http.StatusUnauthorized
+ result.ErrorString = "invalid username and/or password"
+ return
+}
+
+func FetchFile(ctx *ImportContext) (res *FetchResult, err error) {
+ res = &FetchResult{ResponseCode: http.StatusOK}
var uri *url.URL
if uri, err = url.Parse(ctx.SourceUri); err != nil {
- return
+ res.ResponseCode = http.StatusBadRequest
+ res.ErrorString = fmt.Sprintf("parsing uri: %s", err)
+ return res, nil
+ }
+
+ if !ctx.Trusted {
+ if err = checkPassword(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ return
+ }
}
if fetcher, ok := fetchers[uri.Scheme]; ok {
- err = fetcher(ctx, uri)
+ err = fetcher(ctx, res, uri)
} else {
err = fmt.Errorf("No fetcher for uri scheme '%s' found.", uri.Scheme)
}
diff --git a/src/helsinki.at/rhimportd/ctrlTelnet.go b/src/helsinki.at/rhimportd/ctrlTelnet.go
index eb3c607..65504f4 100644
--- a/src/helsinki.at/rhimportd/ctrlTelnet.go
+++ b/src/helsinki.at/rhimportd/ctrlTelnet.go
@@ -152,11 +152,23 @@ func (c *TelnetClient) handle_cmd_set(args []string) {
}
switch strings.ToLower(args[0]) {
case "username":
- c.ctx.UserName = args[1]
+ if args[1] == "\"\"" || args[1] == "''" {
+ c.ctx.UserName = ""
+ } else {
+ c.ctx.UserName = args[1]
+ }
case "password":
- c.ctx.Password = args[1]
+ if args[1] == "\"\"" || args[1] == "''" {
+ c.ctx.Password = ""
+ } else {
+ c.ctx.Password = args[1]
+ }
case "sourceuri":
- c.ctx.SourceUri = args[1]
+ if args[1] == "\"\"" || args[1] == "''" {
+ c.ctx.SourceUri = ""
+ } else {
+ c.ctx.SourceUri = args[1]
+ }
case "showid":
if id, err := strconv.ParseUint(args[1], 10, 32); err != nil {
c.say("invalid value (must be an positive integer)")
@@ -170,7 +182,11 @@ func (c *TelnetClient) handle_cmd_set(args []string) {
c.ctx.ClearShowCarts = val
}
case "groupname":
- c.ctx.GroupName = args[1]
+ if args[1] == "\"\"" || args[1] == "''" {
+ c.ctx.GroupName = ""
+ } else {
+ c.ctx.GroupName = args[1]
+ }
case "cart":
if cart, err := strconv.ParseUint(args[1], 10, 32); err != nil {
c.say("invalid value (must be an positive integer)")
@@ -263,22 +279,25 @@ func (c *TelnetClient) handle_cmd_run(args []string) {
}
c.say("fetching file from '%s'", ctx.SourceUri)
- if err := rhimport.FetchFile(&ctx); err != nil {
+ if fres, err := rhimport.FetchFile(&ctx); err != nil {
c.say("fetch file error: %s", err)
return
+ } else if fres.ResponseCode != http.StatusOK {
+ c.say("fetch file error: %s", fres.ErrorString)
+ return
}
c.say("importing file '%s'", ctx.SourceFile)
- if result, err := rhimport.ImportFile(&ctx); err != nil {
+ if ires, err := rhimport.ImportFile(&ctx); err != nil {
c.say("import file error: %s", err)
return
} else {
- if result.ResponseCode == http.StatusOK {
- c.say("File got succesfully imported into Cart/Cut %d/%d", result.Cart, result.Cut)
- rhl.Printf("File got succesfully imported into Cart/Cut %d/%d", result.Cart, result.Cut)
+ if ires.ResponseCode == http.StatusOK {
+ c.say("File got succesfully imported into Cart/Cut %d/%d", ires.Cart, ires.Cut)
+ rhl.Printf("File got succesfully imported into Cart/Cut %d/%d", ires.Cart, ires.Cut)
} else {
- c.say("Fileimport has failed (Cart/Cut %d/%d): %s", result.Cart, result.Cut, result.ErrorString)
- rhl.Printf("Fileimport has failed (Cart/Cut %d/%d): %s", result.Cart, result.Cut, result.ErrorString)
+ c.say("Fileimport has failed (Cart/Cut %d/%d): %s", ires.Cart, ires.Cut, ires.ErrorString)
+ rhl.Printf("Fileimport has failed (Cart/Cut %d/%d): %s", ires.Cart, ires.Cut, ires.ErrorString)
}
}
}
diff --git a/src/helsinki.at/rhimportd/ctrlWebSimple.go b/src/helsinki.at/rhimportd/ctrlWebSimple.go
index 2de324f..c5b81ce 100644
--- a/src/helsinki.at/rhimportd/ctrlWebSimple.go
+++ b/src/helsinki.at/rhimportd/ctrlWebSimple.go
@@ -141,22 +141,26 @@ func webSimpleHandler(conf *rhimport.Config, rddb *rhimport.RdDb, trusted bool,
return
}
- if err = rhimport.FetchFile(ctx); err != nil {
+ var fres *rhimport.FetchResult
+ if fres, err = rhimport.FetchFile(ctx); err != nil {
webSimpleErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
+ if fres.ResponseCode != http.StatusOK {
+ webSimpleErrorResponse(w, fres.ResponseCode, fres.ErrorString)
+ }
- var result *rhimport.ImportResult
- if result, err = rhimport.ImportFile(ctx); err != nil {
+ var ires *rhimport.ImportResult
+ if ires, err = rhimport.ImportFile(ctx); err != nil {
webSimpleErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
- if result.ResponseCode == http.StatusOK {
+ if ires.ResponseCode == http.StatusOK {
rhl.Println("ImportFile succesfully imported", ctx.SourceFile)
} else {
rhl.Println("ImportFile import of", ctx.SourceFile, "was unsuccesful")
}
- webSimpleResponse(w, result)
+ webSimpleResponse(w, ires)
return
}