Ada
8968046b11
/ can now read body and create paste, for curl like client, web create with full settings is move to /create
192 lines
4.1 KiB
Go
192 lines
4.1 KiB
Go
package plak
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.gnous.eu/gnouseu/plakken/internal/constant"
|
|
"git.gnous.eu/gnouseu/plakken/internal/database"
|
|
"git.gnous.eu/gnouseu/plakken/internal/utils"
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
"html/template"
|
|
)
|
|
|
|
var ctx = context.Background()
|
|
|
|
type WebConfig struct {
|
|
DB *redis.Client
|
|
UrlLength uint8
|
|
Templates embed.FS
|
|
}
|
|
|
|
// Plak "Object" for plak
|
|
type Plak struct {
|
|
Key string
|
|
Content string
|
|
Expiration time.Duration
|
|
DB *redis.Client
|
|
}
|
|
|
|
// Create manage POST request for create Plak
|
|
func (config WebConfig) Create(w http.ResponseWriter, r *http.Request) {
|
|
content := r.FormValue("content")
|
|
if content == "" {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
dbConf := database.DBConfig{
|
|
DB: config.DB,
|
|
}
|
|
|
|
filename := r.FormValue("filename")
|
|
var key string
|
|
if len(filename) == 0 {
|
|
key = utils.GenerateUrl(config.UrlLength)
|
|
} else {
|
|
if !utils.ValidKey(filename) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
if dbConf.UrlExist(filename) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
key = filename
|
|
}
|
|
|
|
secret := utils.GenerateSecret()
|
|
rawExpiration := r.FormValue("exp")
|
|
|
|
expiration, err := utils.ParseExpiration(rawExpiration)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
} else if expiration == 0 {
|
|
dbConf.InsertPaste(key, content, secret, -1)
|
|
} else {
|
|
dbConf.InsertPaste(key, content, secret, time.Duration(expiration*int(time.Second)))
|
|
}
|
|
|
|
http.Redirect(w, r, "/"+key, http.StatusSeeOther)
|
|
}
|
|
|
|
// CurlCreate Create plak with minimum param, ideal for curl. Force 7 day expiration
|
|
func (config WebConfig) CurlCreate(w http.ResponseWriter, r *http.Request) {
|
|
if r.ContentLength == 0 {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
content, _ := io.ReadAll(r.Body)
|
|
err := r.Body.Close()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
key := utils.GenerateUrl(config.UrlLength)
|
|
secret := utils.GenerateSecret()
|
|
dbConf := database.DBConfig{
|
|
DB: config.DB,
|
|
}
|
|
dbConf.InsertPaste(key, string(content), secret, constant.ExpirationCurlCreate)
|
|
|
|
var baseURL string
|
|
if r.TLS == nil {
|
|
baseURL = "http://" + r.Host + "/" + key
|
|
} else {
|
|
baseURL = "https://" + r.Host + "/" + key
|
|
}
|
|
|
|
message := baseURL + "\n" + "Delete with : 'curl -X DELETE " + baseURL + "?secret\\=" + secret + "'" + "\n"
|
|
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
_, err = io.WriteString(w, message)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
// View for plak
|
|
func (config WebConfig) View(w http.ResponseWriter, r *http.Request) {
|
|
dbConf := database.DBConfig{
|
|
DB: config.DB,
|
|
}
|
|
var plak Plak
|
|
key := r.PathValue("key")
|
|
|
|
if dbConf.UrlExist(key) {
|
|
plak = Plak{
|
|
Key: key,
|
|
DB: config.DB,
|
|
}
|
|
plak = plak.GetContent()
|
|
if r.PathValue("settings") == "raw" {
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
_, err := io.WriteString(w, plak.Content)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
} else {
|
|
t, err := template.ParseFS(config.Templates, "templates/paste.html")
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
log.Println(err)
|
|
}
|
|
err = t.Execute(w, plak)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
} else {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
}
|
|
|
|
// Delete manage plak deletion endpoint
|
|
func (config WebConfig) Delete(w http.ResponseWriter, r *http.Request) {
|
|
dbConf := database.DBConfig{
|
|
DB: config.DB,
|
|
}
|
|
key := r.PathValue("key")
|
|
|
|
if dbConf.UrlExist(key) {
|
|
secret := r.URL.Query().Get("secret")
|
|
if dbConf.VerifySecret(key, secret) {
|
|
plak := Plak{
|
|
Key: key,
|
|
DB: config.DB,
|
|
}
|
|
err := plak.deletePlak()
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
return
|
|
} else {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
return
|
|
}
|
|
}
|
|
w.WriteHeader(http.StatusNotFound)
|
|
}
|
|
|
|
// deletePlak Delete plak from database
|
|
func (plak Plak) deletePlak() error {
|
|
err := plak.DB.Del(ctx, plak.Key).Err()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return &DeletePlakError{Name: plak.Key, Err: err}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetContent get plak content
|
|
func (plak Plak) GetContent() Plak {
|
|
plak.Content = plak.DB.HGet(ctx, plak.Key, "content").Val()
|
|
return plak
|
|
}
|