pomme/internal/api/zone.go

108 lines
2.2 KiB
Go

package api
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
"strings"
"git.freecumextremist.com/grumbulon/pomme/internal/util"
"github.com/go-chi/jwtauth/v5"
"github.com/miekg/dns"
"gorm.io/gorm"
)
// ZoneRequest represents a Zone file request.
type ZoneRequest struct {
*Zone
User string `json:"user,omitempty" gorm:"foreignKey:username;references:User"`
}
// Zone struct represents a zonefile.
type Zone struct {
gorm.Model
FileName string `json:"name"`
Body string `json:"body"`
}
func RecieveFile(w http.ResponseWriter, r *http.Request) {
_, claims, _ := jwtauth.FromContext(r.Context())
var buf bytes.Buffer
r.Body = http.MaxBytesReader(w, r.Body, .5*1024*1024) // approx 500 kb max upload
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, "request body too large", http.StatusRequestEntityTooLarge)
return
}
defer file.Close() //nolint: errcheck
name := strings.Split(header.Filename, ".")
if _, err = io.Copy(&buf, file); err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
return
}
if err = util.MakeLocal(name[0], claims["username"].(string), buf); err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
return
}
// ugly
zoneReq := newZoneRequest(fmt.Sprintf("tmpfile-%s-%s", name[0], claims["username"].(string)),
claims["username"].(string),
)
buf.Reset()
db, ok := r.Context().Value(keyPrincipalContextID).(*gorm.DB)
if !ok {
http.Error(w, "internal server error", http.StatusInternalServerError)
return
}
db.Create(zoneReq)
err = zoneReq.Parse()
if err != nil {
http.Error(w, "internal server error", http.StatusInternalServerError)
return
}
}
func newZoneRequest(filename string, user string) *ZoneRequest {
return &ZoneRequest{
User: user,
Zone: &Zone{
FileName: filename,
},
}
}
// Parse will be used to parse zonefiles.
func (zone *ZoneRequest) Parse() error {
zp := dns.NewZoneParser(strings.NewReader(zone.Body), "", "")
for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
log.Println(rr)
}
if err := zp.Err(); err != nil {
return fmt.Errorf("unable to parse Zonefile: %w", err)
}
return nil
}