mirror of
https://git.freecumextremist.com/grumbulon/pomme.git
synced 2024-11-25 05:53:47 +00:00
add fs.go to internal, make makeLocal do the majority of lifting for tmp and perm files, made save() call makeLocal
This commit is contained in:
parent
2426a8b393
commit
92100e27a0
4 changed files with 87 additions and 107 deletions
69
internal/api/fs.go
Normal file
69
internal/api/fs.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.freecumextremist.com/grumbulon/pomme/internal"
|
||||
)
|
||||
|
||||
var errEmptyFile = errors.New("will not save empty file to FS")
|
||||
|
||||
// makeLocal takes a type path and then saves a zone file to either tmp or a permanent location
|
||||
func makeLocal(where path, zone *ZoneRequest) error {
|
||||
var (
|
||||
path string
|
||||
file string
|
||||
c *internal.Config
|
||||
err error
|
||||
)
|
||||
|
||||
if _, err := os.Stat(fmt.Sprintf(zone.FileName, zone.User)); !os.IsNotExist(err) {
|
||||
return fmt.Errorf("file %s already exists: %w", zone.FileName, err)
|
||||
}
|
||||
|
||||
if len([]byte(zone.Body)) == 0 {
|
||||
return errEmptyFile
|
||||
}
|
||||
|
||||
switch where {
|
||||
case Tmp:
|
||||
path = fmt.Sprintf("/tmp/tmpfile-%s-%s", zone.RawFileName, zone.User)
|
||||
case Perm:
|
||||
c, err = internal.ReadConfig()
|
||||
if err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "no config file defined"})
|
||||
|
||||
return fmt.Errorf("unable to parse directory: %w", err)
|
||||
}
|
||||
path = fmt.Sprintf("%s/%s/", c.ZoneDir, zone.RawFileName)
|
||||
file = zone.RawFileName
|
||||
if err = os.MkdirAll(path, 0o750); err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to make directory for zone files"})
|
||||
|
||||
return fmt.Errorf("unable to make zone directory: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Clean(path + file)) //nolint: gosec
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write file locally: %w", err)
|
||||
}
|
||||
|
||||
// close and remove the temporary file at the end of the program
|
||||
defer func() {
|
||||
if err = f.Close(); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
err = os.WriteFile(f.Name(), []byte(zone.Body), 0o600)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write file locally: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -6,8 +6,15 @@ const (
|
|||
keyPrincipalContextID key = iota
|
||||
)
|
||||
|
||||
const (
|
||||
Tmp path = iota
|
||||
Perm
|
||||
)
|
||||
|
||||
type key int
|
||||
|
||||
type path int
|
||||
|
||||
// ZoneRequest represents a Zone file request.
|
||||
type ZoneRequest struct {
|
||||
*Zone
|
||||
|
@ -31,7 +38,7 @@ type genericResponseFields map[string]any
|
|||
|
||||
type ndr interface {
|
||||
parse() error
|
||||
save() error
|
||||
save(where path) error
|
||||
}
|
||||
|
||||
var _ ndr = (*ZoneRequest)(nil)
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"git.freecumextremist.com/grumbulon/pomme/internal"
|
||||
"git.freecumextremist.com/grumbulon/pomme/internal/util"
|
||||
"github.com/go-chi/jwtauth/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/miekg/dns"
|
||||
|
@ -64,8 +63,10 @@ func ReceiveFile(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = util.MakeLocal(header.Filename, claims["username"].(string), b); err != nil {
|
||||
APIError(w, r, genericResponseFields{"message": "internal server error", "status": http.StatusInternalServerError, "error": err.Error()})
|
||||
zoneFile := newDNSRequest(header.Filename, claims["username"].(string), b)
|
||||
|
||||
if err := zoneFile.save(Tmp); err != nil {
|
||||
APIError(w, r, genericResponseFields{"message": "Unable to save zonefile", "status": http.StatusInternalServerError, "error": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -86,15 +87,13 @@ func ReceiveFile(w http.ResponseWriter, r *http.Request) {
|
|||
},
|
||||
})
|
||||
|
||||
zoneFile := newDNSRequest(header.Filename, claims["username"].(string))
|
||||
|
||||
if err := zoneFile.parse(); err != nil {
|
||||
APIError(w, r, genericResponseFields{"message": "Unable to parse zonefile", "status": http.StatusInternalServerError, "error": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err := zoneFile.save(); err != nil {
|
||||
if err := zoneFile.save(Perm); err != nil {
|
||||
APIError(w, r, genericResponseFields{"message": "Unable to save zonefile", "status": http.StatusInternalServerError, "error": err.Error()})
|
||||
|
||||
return
|
||||
|
@ -111,12 +110,7 @@ func ReceiveFile(w http.ResponseWriter, r *http.Request) {
|
|||
render.JSON(w, r, resp)
|
||||
}
|
||||
|
||||
func newDNSRequest(filename string, user string) ndr {
|
||||
dat, err := os.ReadFile(fmt.Sprintf("/tmp/tmpfile-%s-%s", filename, user))
|
||||
if err != nil {
|
||||
return &ZoneRequest{}
|
||||
}
|
||||
|
||||
func newDNSRequest(filename string, user string, dat []byte) ndr {
|
||||
return &ZoneRequest{
|
||||
User: user,
|
||||
Zone: &Zone{
|
||||
|
@ -142,61 +136,11 @@ func (zone *ZoneRequest) parse() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (zone *ZoneRequest) save() error {
|
||||
c, err := internal.ReadConfig()
|
||||
if err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "no config file defined"})
|
||||
func (zone *ZoneRequest) save(path) error {
|
||||
// clean up the tmp file
|
||||
defer os.Remove(filepath.Clean("/tmp/" + zone.FileName))
|
||||
|
||||
return fmt.Errorf("unable to parse directory: %w", err)
|
||||
}
|
||||
|
||||
var path string = fmt.Sprintf("%s/%s/", c.ZoneDir, zone.RawFileName)
|
||||
|
||||
var tmpPath string = fmt.Sprintf("/tmp/tmpfile-%s-%s", zone.RawFileName, zone.User)
|
||||
|
||||
if err = os.MkdirAll(path, 0o750); err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to make directory for zone files"})
|
||||
|
||||
return fmt.Errorf("unable to make zone directory: %w", err)
|
||||
}
|
||||
|
||||
if _, err = os.Create(filepath.Clean(path + zone.RawFileName)); err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to save zonefile to directory"})
|
||||
|
||||
return fmt.Errorf("unable to save zonefile to directory: %w", err)
|
||||
}
|
||||
|
||||
f, err := os.Open(filepath.Clean(tmpPath))
|
||||
if err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to save zonefile to directory"})
|
||||
|
||||
return fmt.Errorf("unable to save zonefile to directory: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err = f.Close(); err != nil {
|
||||
logHandler(genericResponseFields{"message": "Error closing file", "error": err.Error()})
|
||||
}
|
||||
|
||||
if err = os.Remove(filepath.Clean(tmpPath)); err != nil {
|
||||
logHandler(genericResponseFields{"message": "Error removing tmp file", "error": err.Error()})
|
||||
}
|
||||
}()
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to save zonefile to directory"})
|
||||
|
||||
return fmt.Errorf("unable to save zonefile to directory: %w", err)
|
||||
}
|
||||
|
||||
if err = os.WriteFile(path+zone.RawFileName, b, 0o600); err != nil {
|
||||
logHandler(genericResponseFields{"error": err.Error(), "message": "unable to save zonefile to directory"})
|
||||
|
||||
return fmt.Errorf("unable to save zonefile to directory: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return makeLocal(Perm, zone)
|
||||
}
|
||||
|
||||
func validateContentType(file io.Reader) bool {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var errEmptyFile = errors.New("will not save empty file to FS")
|
||||
|
||||
func MakeLocal(filename, username string, buf []byte) error {
|
||||
if _, err := os.Stat(fmt.Sprintf("/tmp/tmpfile-%s-%s", filename, username)); !os.IsNotExist(err) {
|
||||
return fmt.Errorf("file %s already exists: %w", filename, err)
|
||||
}
|
||||
|
||||
if len(buf) == 0 {
|
||||
return errEmptyFile
|
||||
}
|
||||
|
||||
f, err := os.Create("/tmp/tmpfile-" + filename + "-" + username) //nolint: gosec
|
||||
// this is set to nolint because I am doing everything os.CreateTemp does but here since I don't like some of the limitations
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write file locally: %w", err)
|
||||
}
|
||||
|
||||
// close and remove the temporary file at the end of the program
|
||||
defer func() {
|
||||
if err = f.Close(); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
err = os.WriteFile(f.Name(), buf, 0o600)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write file locally: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in a new issue