The Great Linting Fixes, Drone configuration fix (again) and flatfile changes.
Great linting fixes has been applied, thanks to golangci-lint for extensive reporting. Fixed Drone configuration to use array for when-branch statement in Docker plugin. Flatfile storage from now will write files with 0600 permission for greater security.
This commit is contained in:
parent
218e0bf667
commit
2b44a60ee7
@ -21,7 +21,7 @@ steps:
|
|||||||
- name: docker
|
- name: docker
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
when:
|
when:
|
||||||
branch: master
|
branch: ["master"]
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: dockerhub_user
|
from_secret: dockerhub_user
|
||||||
|
@ -39,29 +39,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
c := context.New()
|
appCtx := context.New()
|
||||||
c.Initialize()
|
appCtx.Initialize()
|
||||||
|
|
||||||
c.Logger.Info().Msg("Starting Fast Pastebin...")
|
appCtx.Logger.Info().Msg("Starting Fast Pastebin...")
|
||||||
|
|
||||||
// Here goes initial initialization for packages that want CLI flags
|
// Here goes initial initialization for packages that want CLI flags
|
||||||
// to be added.
|
// to be added.
|
||||||
|
|
||||||
// Parse flags.
|
// Parse flags.
|
||||||
c.Flagger.Parse()
|
appCtx.Flagger.Parse()
|
||||||
|
|
||||||
// Continue loading.
|
// Continue loading.
|
||||||
c.LoadConfiguration()
|
appCtx.LoadConfiguration()
|
||||||
c.InitializePost()
|
appCtx.InitializePost()
|
||||||
database.New(c)
|
database.New(appCtx)
|
||||||
c.Database.Initialize()
|
appCtx.Database.Initialize()
|
||||||
templater.Initialize(c)
|
templater.Initialize(appCtx)
|
||||||
|
|
||||||
captcha.New(c)
|
captcha.New(appCtx)
|
||||||
|
|
||||||
dbnotavailable.New(c)
|
dbnotavailable.New(appCtx)
|
||||||
indexpage.New(c)
|
indexpage.New(appCtx)
|
||||||
pastes.New(c)
|
pastes.New(appCtx)
|
||||||
|
|
||||||
// CTRL+C handler.
|
// CTRL+C handler.
|
||||||
signalHandler := make(chan os.Signal, 1)
|
signalHandler := make(chan os.Signal, 1)
|
||||||
@ -71,7 +71,7 @@ func main() {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-signalHandler
|
<-signalHandler
|
||||||
c.Shutdown()
|
appCtx.Shutdown()
|
||||||
shutdownDone <- true
|
shutdownDone <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Index of this site.
|
// Index of this site.
|
||||||
func indexGet(ec echo.Context) error {
|
func indexGet(ectx echo.Context) error {
|
||||||
// We should check if database connection available.
|
// We should check if database connection available.
|
||||||
dbConn := c.Database.GetDatabaseConnection()
|
dbConn := c.Database.GetDatabaseConnection()
|
||||||
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available")
|
return ectx.Redirect(http.StatusFound, "/database_not_available")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate list of available languages to highlight.
|
// Generate list of available languages to highlight.
|
||||||
@ -54,8 +54,8 @@ func indexGet(ec echo.Context) error {
|
|||||||
// Captcha.
|
// Captcha.
|
||||||
captchaString := captcha.NewCaptcha()
|
captchaString := captcha.NewCaptcha()
|
||||||
|
|
||||||
htmlData := templater.GetTemplate(ec, "index.html", map[string]string{"lexers": availableLexersSelectOpts, "captchaString": captchaString})
|
htmlData := templater.GetTemplate(ectx, "index.html", map[string]string{"lexers": availableLexersSelectOpts, "captchaString": captchaString})
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusOK, htmlData)
|
return ectx.HTML(http.StatusOK, htmlData)
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ func pasteGetData(pasteID int, timestamp int64, cookieValue string) (*structs.Pa
|
|||||||
|
|
||||||
// GET for "/paste/PASTE_ID" and "/paste/PASTE_ID/TIMESTAMP" (private pastes).
|
// GET for "/paste/PASTE_ID" and "/paste/PASTE_ID/TIMESTAMP" (private pastes).
|
||||||
// Web interface version.
|
// Web interface version.
|
||||||
func pasteGETWebInterface(ec echo.Context) error {
|
func pasteGETWebInterface(ectx echo.Context) error {
|
||||||
pasteIDRaw := ec.Param("id")
|
pasteIDRaw := ectx.Param("id")
|
||||||
// We already get numbers from string, so we will not check strconv.Atoi()
|
// We already get numbers from string, so we will not check strconv.Atoi()
|
||||||
// error.
|
// error.
|
||||||
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
||||||
@ -85,16 +85,16 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
// will show 404 Not Found error and spam about that in logs.
|
// will show 404 Not Found error and spam about that in logs.
|
||||||
var timestamp int64
|
var timestamp int64
|
||||||
|
|
||||||
tsProvidedStr := ec.Param("timestamp")
|
tsProvidedStr := ectx.Param("timestamp")
|
||||||
if tsProvidedStr != "" {
|
if tsProvidedStr != "" {
|
||||||
tsProvided, err := strconv.ParseInt(tsProvidedStr, 10, 64)
|
tsProvided, err := strconv.ParseInt(tsProvidedStr, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Err(err).Int("paste ID", pasteID).Int64("provided timestamp", tsProvided).Msg("Invalid timestamp provided for getting private paste")
|
c.Logger.Error().Err(err).Int("paste ID", pasteID).Int64("provided timestamp", tsProvided).Msg("Invalid timestamp provided for getting private paste")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Paste #"+pasteIDStr+" not found")
|
errtpl := templater.GetErrorTemplate(ectx, "Paste #"+pasteIDStr+" not found")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = tsProvided
|
timestamp = tsProvided
|
||||||
@ -104,7 +104,7 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
// for private pastes.
|
// for private pastes.
|
||||||
var cookieValue string
|
var cookieValue string
|
||||||
|
|
||||||
cookie, err1 := ec.Cookie("PASTE-" + pasteIDStr)
|
cookie, err1 := ectx.Cookie("PASTE-" + pasteIDStr)
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
cookieValue = cookie.Value
|
cookieValue = cookie.Value
|
||||||
}
|
}
|
||||||
@ -113,10 +113,10 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
|
|
||||||
// For these cases we should return 404 Not Found page.
|
// For these cases we should return 404 Not Found page.
|
||||||
if err == pasteExpired || err == pasteNotFound || err == pasteTimestampInvalid {
|
if err == pasteExpired || err == pasteNotFound || err == pasteTimestampInvalid {
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Paste #"+pasteIDRaw+" not found")
|
errtpl := templater.GetErrorTemplate(ectx, "Paste #"+pasteIDRaw+" not found")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusNotFound, errtpl)
|
return ectx.HTML(http.StatusNotFound, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If passed cookie value was invalid - go to paste authorization
|
// If passed cookie value was invalid - go to paste authorization
|
||||||
@ -125,7 +125,7 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
c.Logger.Info().Int("paste ID", pasteID).Msg("Invalid cookie, redirecting to auth page")
|
c.Logger.Info().Int("paste ID", pasteID).Msg("Invalid cookie, redirecting to auth page")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusMovedPermanently, "/paste/"+pasteIDStr+"/"+ec.Param("timestamp")+"/verify")
|
return ectx.Redirect(http.StatusMovedPermanently, "/paste/"+pasteIDStr+"/"+ectx.Param("timestamp")+"/verify")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format paste data map.
|
// Format paste data map.
|
||||||
@ -180,16 +180,16 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
pasteData["pastedata"] = buf.String()
|
pasteData["pastedata"] = buf.String()
|
||||||
|
|
||||||
// Get template and format it.
|
// Get template and format it.
|
||||||
pasteHTML := templater.GetTemplate(ec, "paste.html", pasteData)
|
pasteHTML := templater.GetTemplate(ectx, "paste.html", pasteData)
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusOK, pasteHTML)
|
return ectx.HTML(http.StatusOK, pasteHTML)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET for "/paste/PASTE_ID/TIMESTAMP/verify" - a password verify page.
|
// GET for "/paste/PASTE_ID/TIMESTAMP/verify" - a password verify page.
|
||||||
func pastePasswordedVerifyGet(ec echo.Context) error {
|
func pastePasswordedVerifyGet(ectx echo.Context) error {
|
||||||
pasteIDRaw := ec.Param("id")
|
pasteIDRaw := ectx.Param("id")
|
||||||
timestampRaw := ec.Param("timestamp")
|
timestampRaw := ectx.Param("timestamp")
|
||||||
// We already get numbers from string, so we will not check strconv.Atoi()
|
// We already get numbers from string, so we will not check strconv.Atoi()
|
||||||
// error.
|
// error.
|
||||||
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
||||||
@ -199,14 +199,14 @@ func pastePasswordedVerifyGet(ec echo.Context) error {
|
|||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste data")
|
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste data")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Paste #"+pasteIDRaw+" not found")
|
errtpl := templater.GetErrorTemplate(ectx, "Paste #"+pasteIDRaw+" not found")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for auth cookie. If present - redirect to paste.
|
// Check for auth cookie. If present - redirect to paste.
|
||||||
cookie, err := ec.Cookie("PASTE-" + strconv.Itoa(pasteID))
|
cookie, err := ectx.Cookie("PASTE-" + strconv.Itoa(pasteID))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// No cookie, redirect to auth page.
|
// No cookie, redirect to auth page.
|
||||||
c.Logger.Debug().Msg("Paste cookie found, checking it...")
|
c.Logger.Debug().Msg("Paste cookie found, checking it...")
|
||||||
@ -218,7 +218,7 @@ func pastePasswordedVerifyGet(ec echo.Context) error {
|
|||||||
c.Logger.Info().Msg("Valid cookie, redirecting to paste page...")
|
c.Logger.Info().Msg("Valid cookie, redirecting to paste page...")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusMovedPermanently, "/paste/"+pasteIDRaw+"/"+ec.Param("timestamp"))
|
return ectx.Redirect(http.StatusMovedPermanently, "/paste/"+pasteIDRaw+"/"+ectx.Param("timestamp"))
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug().Msg("Invalid cookie, showing auth page")
|
c.Logger.Debug().Msg("Invalid cookie, showing auth page")
|
||||||
@ -229,24 +229,24 @@ func pastePasswordedVerifyGet(ec echo.Context) error {
|
|||||||
htmlData["pasteID"] = strconv.Itoa(pasteID)
|
htmlData["pasteID"] = strconv.Itoa(pasteID)
|
||||||
htmlData["pasteTimestamp"] = timestampRaw
|
htmlData["pasteTimestamp"] = timestampRaw
|
||||||
|
|
||||||
verifyHTML := templater.GetTemplate(ec, "passworded_paste_verify.html", htmlData)
|
verifyHTML := templater.GetTemplate(ectx, "passworded_paste_verify.html", htmlData)
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusOK, verifyHTML)
|
return ectx.HTML(http.StatusOK, verifyHTML)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST for "/paste/PASTE_ID/TIMESTAMP/verify" - a password verify page.
|
// POST for "/paste/PASTE_ID/TIMESTAMP/verify" - a password verify page.
|
||||||
func pastePasswordedVerifyPost(ec echo.Context) error {
|
func pastePasswordedVerifyPost(ectx echo.Context) error {
|
||||||
// We should check if database connection available.
|
// We should check if database connection available.
|
||||||
dbConn := c.Database.GetDatabaseConnection()
|
dbConn := c.Database.GetDatabaseConnection()
|
||||||
|
|
||||||
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available")
|
return ectx.Redirect(http.StatusFound, "/database_not_available")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteIDRaw := ec.Param("id")
|
pasteIDRaw := ectx.Param("id")
|
||||||
timestampRaw := ec.Param("timestamp")
|
timestampRaw := ectx.Param("timestamp")
|
||||||
// We already get numbers from string, so we will not check strconv.Atoi()
|
// We already get numbers from string, so we will not check strconv.Atoi()
|
||||||
// error.
|
// error.
|
||||||
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
||||||
@ -256,20 +256,20 @@ func pastePasswordedVerifyPost(ec echo.Context) error {
|
|||||||
paste, err1 := c.Database.GetPaste(pasteID)
|
paste, err1 := c.Database.GetPaste(pasteID)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste")
|
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste")
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
errtpl := templater.GetErrorTemplate(ectx, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err2 := ec.FormParams()
|
params, err2 := ectx.FormParams()
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
c.Logger.Debug().Msg("No form parameters passed")
|
c.Logger.Debug().Msg("No form parameters passed")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
errtpl := templater.GetErrorTemplate(ectx, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if paste.VerifyPassword(params["paste-password"][0]) {
|
if paste.VerifyPassword(params["paste-password"][0]) {
|
||||||
@ -279,29 +279,29 @@ func pastePasswordedVerifyPost(ec echo.Context) error {
|
|||||||
cookie.Name = "PASTE-" + strconv.Itoa(pasteID)
|
cookie.Name = "PASTE-" + strconv.Itoa(pasteID)
|
||||||
cookie.Value = paste.GenerateCryptedCookieValue()
|
cookie.Value = paste.GenerateCryptedCookieValue()
|
||||||
cookie.Expires = time.Now().Add(24 * time.Hour)
|
cookie.Expires = time.Now().Add(24 * time.Hour)
|
||||||
ec.SetCookie(cookie)
|
ectx.SetCookie(cookie)
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/paste/"+strconv.Itoa(pasteID)+"/"+timestampRaw)
|
return ectx.Redirect(http.StatusFound, "/paste/"+strconv.Itoa(pasteID)+"/"+timestampRaw)
|
||||||
}
|
}
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Invalid password. Please, try again.")
|
errtpl := templater.GetErrorTemplate(ectx, "Invalid password. Please, try again.")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET for "/pastes/:id/raw", raw paste output.
|
// GET for "/pastes/:id/raw", raw paste output.
|
||||||
// Web interface version.
|
// Web interface version.
|
||||||
func pasteRawGETWebInterface(ec echo.Context) error {
|
func pasteRawGETWebInterface(ectx echo.Context) error {
|
||||||
// We should check if database connection available.
|
// We should check if database connection available.
|
||||||
dbConn := c.Database.GetDatabaseConnection()
|
dbConn := c.Database.GetDatabaseConnection()
|
||||||
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available/raw")
|
return ectx.Redirect(http.StatusFound, "/database_not_available/raw")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteIDRaw := ec.Param("id")
|
pasteIDRaw := ectx.Param("id")
|
||||||
// We already get numbers from string, so we will not check strconv.Atoi()
|
// We already get numbers from string, so we will not check strconv.Atoi()
|
||||||
// error.
|
// error.
|
||||||
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
pasteID, _ := strconv.Atoi(regexInts.FindAllString(pasteIDRaw, 1)[0])
|
||||||
@ -313,26 +313,26 @@ func pasteRawGETWebInterface(ec echo.Context) error {
|
|||||||
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste from database")
|
c.Logger.Error().Err(err1).Int("paste ID", pasteID).Msg("Failed to get paste from database")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, "Paste #"+pasteIDRaw+" does not exist.")
|
return ectx.HTML(http.StatusBadRequest, "Paste #"+pasteIDRaw+" does not exist.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if paste.IsExpired() {
|
if paste.IsExpired() {
|
||||||
c.Logger.Error().Int("paste ID", pasteID).Msg("Paste is expired")
|
c.Logger.Error().Int("paste ID", pasteID).Msg("Paste is expired")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, "Paste #"+pasteIDRaw+" does not exist.")
|
return ectx.HTML(http.StatusBadRequest, "Paste #"+pasteIDRaw+" does not exist.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have a private paste and it's parameters are correct.
|
// Check if we have a private paste and it's parameters are correct.
|
||||||
if paste.Private {
|
if paste.Private {
|
||||||
tsProvidedStr := ec.Param("timestamp")
|
tsProvidedStr := ectx.Param("timestamp")
|
||||||
|
|
||||||
tsProvided, err2 := strconv.ParseInt(tsProvidedStr, 10, 64)
|
tsProvided, err2 := strconv.ParseInt(tsProvidedStr, 10, 64)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
c.Logger.Error().Err(err2).Int("paste ID", pasteID).Str("provided timestamp", tsProvidedStr).Msg("Invalid timestamp provided for getting private paste")
|
c.Logger.Error().Err(err2).Int("paste ID", pasteID).Str("provided timestamp", tsProvidedStr).Msg("Invalid timestamp provided for getting private paste")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
return ectx.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteTS := paste.CreatedAt.Unix()
|
pasteTS := paste.CreatedAt.Unix()
|
||||||
@ -340,7 +340,7 @@ func pasteRawGETWebInterface(ec echo.Context) error {
|
|||||||
c.Logger.Error().Int("paste ID", pasteID).Int64("provided timestamp", tsProvided).Int64("paste timestamp", pasteTS).Msg("Incorrect timestamp provided for private paste")
|
c.Logger.Error().Int("paste ID", pasteID).Int64("provided timestamp", tsProvided).Int64("paste timestamp", pasteTS).Msg("Incorrect timestamp provided for private paste")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
return ectx.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,9 +349,9 @@ func pasteRawGETWebInterface(ec echo.Context) error {
|
|||||||
// Return error for now.
|
// Return error for now.
|
||||||
if paste.Password != "" {
|
if paste.Password != "" {
|
||||||
c.Logger.Error().Int("paste ID", pasteID).Msg("Cannot render paste as raw: passworded paste. Patches welcome!")
|
c.Logger.Error().Int("paste ID", pasteID).Msg("Cannot render paste as raw: passworded paste. Patches welcome!")
|
||||||
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
return ectx.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.String(http.StatusOK, paste.Data)
|
return ectx.String(http.StatusOK, paste.Data)
|
||||||
}
|
}
|
||||||
|
@ -20,22 +20,22 @@ const KeepPastesForever = "forever"
|
|||||||
// POST for "/paste/" which will create new paste and redirect to
|
// POST for "/paste/" which will create new paste and redirect to
|
||||||
// "/pastes/CREATED_PASTE_ID". This handler will do all the job for
|
// "/pastes/CREATED_PASTE_ID". This handler will do all the job for
|
||||||
// requests comes from browsers via web interface.
|
// requests comes from browsers via web interface.
|
||||||
func pastePOSTWebInterface(ec echo.Context) error {
|
func pastePOSTWebInterface(ectx echo.Context) error {
|
||||||
// We should check if database connection available.
|
// We should check if database connection available.
|
||||||
dbConn := c.Database.GetDatabaseConnection()
|
dbConn := c.Database.GetDatabaseConnection()
|
||||||
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available")
|
return ectx.Redirect(http.StatusFound, "/database_not_available")
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err := ec.FormParams()
|
params, err := ectx.FormParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Msg("Passed paste form is empty")
|
c.Logger.Error().Msg("Passed paste form is empty")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Cannot create empty paste")
|
errtpl := templater.GetErrorTemplate(ectx, "Cannot create empty paste")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug().Msgf("Received parameters: %+v", params)
|
c.Logger.Debug().Msgf("Received parameters: %+v", params)
|
||||||
@ -44,29 +44,29 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
if len(params["paste-contents"][0]) == 0 {
|
if len(params["paste-contents"][0]) == 0 {
|
||||||
c.Logger.Debug().Msg("Empty paste submitted, ignoring")
|
c.Logger.Debug().Msg("Empty paste submitted, ignoring")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Empty pastes aren't allowed.")
|
errtpl := templater.GetErrorTemplate(ectx, "Empty pastes aren't allowed.")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") && params["paste-keep-for"][0] != KeepPastesForever {
|
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") && params["paste-keep-for"][0] != KeepPastesForever {
|
||||||
c.Logger.Debug().Str("field value", params["paste-keep-for"][0]).Msg("'Keep paste for' field have invalid value")
|
c.Logger.Debug().Str("field value", params["paste-keep-for"][0]).Msg("'Keep paste for' field have invalid value")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
errtpl := templater.GetErrorTemplate(ectx, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify captcha.
|
// Verify captcha.
|
||||||
if !captcha.Verify(params["paste-captcha-id"][0], params["paste-captcha-solution"][0]) {
|
if !captcha.Verify(params["paste-captcha-id"][0], params["paste-captcha-solution"][0]) {
|
||||||
c.Logger.Debug().Str("captcha ID", params["paste-captcha-id"][0]).Str("captcha solution", params["paste-captcha-solution"][0]).Msg("Invalid captcha solution")
|
c.Logger.Debug().Str("captcha ID", params["paste-captcha-id"][0]).Str("captcha solution", params["paste-captcha-solution"][0]).Msg("Invalid captcha solution")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Invalid captcha solution.")
|
errtpl := templater.GetErrorTemplate(ectx, "Invalid captcha solution.")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:exhaustivestruct
|
// nolint:exhaustivestruct
|
||||||
@ -101,10 +101,10 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
c.Logger.Debug().Err(err).Msg("Failed to parse 'Keep for' integer")
|
c.Logger.Debug().Err(err).Msg("Failed to parse 'Keep for' integer")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
errtpl := templater.GetErrorTemplate(ectx, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,25 +138,25 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
_ = paste.CreatePassword(pastePassword[0])
|
_ = paste.CreatePassword(pastePassword[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err2 := c.Database.SavePaste(paste)
|
pasteID, err2 := c.Database.SavePaste(paste)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
c.Logger.Error().Err(err2).Msg("Failed to save paste")
|
c.Logger.Error().Err(err2).Msg("Failed to save paste")
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Failed to save paste. Please, try again later.")
|
errtpl := templater.GetErrorTemplate(ectx, "Failed to save paste. Please, try again later.")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ectx.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
newPasteIDAsString := strconv.FormatInt(id, 10)
|
newPasteIDAsString := strconv.FormatInt(pasteID, 10)
|
||||||
c.Logger.Debug().Msg("Paste saved, URL: /paste/" + newPasteIDAsString)
|
c.Logger.Debug().Msg("Paste saved, URL: /paste/" + newPasteIDAsString)
|
||||||
|
|
||||||
// Private pastes have it's timestamp in URL.
|
// Private pastes have it's timestamp in URL.
|
||||||
if paste.Private {
|
if paste.Private {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString+"/"+strconv.FormatInt(paste.CreatedAt.Unix(), 10))
|
return ectx.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString+"/"+strconv.FormatInt(paste.CreatedAt.Unix(), 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString)
|
return ectx.Redirect(http.StatusFound, "/paste/"+newPasteIDAsString)
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,15 @@ import (
|
|||||||
|
|
||||||
// GET for "/pastes/", a list of publicly available pastes.
|
// GET for "/pastes/", a list of publicly available pastes.
|
||||||
// Web interface version.
|
// Web interface version.
|
||||||
func pastesGET(ec echo.Context) error {
|
func pastesGET(ectx echo.Context) error {
|
||||||
// We should check if database connection available.
|
// We should check if database connection available.
|
||||||
dbConn := c.Database.GetDatabaseConnection()
|
dbConn := c.Database.GetDatabaseConnection()
|
||||||
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
if c.Config.Database.Type != flatfiles.FlatFileDialect && dbConn == nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available")
|
return ectx.Redirect(http.StatusFound, "/database_not_available")
|
||||||
}
|
}
|
||||||
|
|
||||||
pageFromParamRaw := ec.Param("page")
|
pageFromParamRaw := ectx.Param("page")
|
||||||
|
|
||||||
page := 1
|
page := 1
|
||||||
|
|
||||||
@ -66,34 +66,34 @@ func pastesGET(ec echo.Context) error {
|
|||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
c.Logger.Error().Err(err3).Msg("Failed to get pastes list from database")
|
c.Logger.Error().Err(err3).Msg("Failed to get pastes list from database")
|
||||||
|
|
||||||
noPastesToShowTpl := templater.GetErrorTemplate(ec, "No pastes to show.")
|
noPastesToShowTpl := templater.GetErrorTemplate(ectx, "No pastes to show.")
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusOK, noPastesToShowTpl)
|
return ectx.HTML(http.StatusOK, noPastesToShowTpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pastes) > 0 {
|
if len(pastes) > 0 {
|
||||||
pastesString = ""
|
pastesString = ""
|
||||||
|
|
||||||
for i := range pastes {
|
for _, paste := range pastes {
|
||||||
pasteDataMap := make(map[string]string)
|
pasteDataMap := make(map[string]string)
|
||||||
pasteDataMap["pasteID"] = strconv.Itoa(pastes[i].ID)
|
pasteDataMap["pasteID"] = strconv.Itoa(paste.ID)
|
||||||
pasteDataMap["pasteTitle"] = pastes[i].Title
|
pasteDataMap["pasteTitle"] = paste.Title
|
||||||
pasteDataMap["pasteDate"] = pastes[i].CreatedAt.Format("2006-01-02 @ 15:04:05") + " UTC"
|
pasteDataMap["pasteDate"] = paste.CreatedAt.Format("2006-01-02 @ 15:04:05") + " UTC"
|
||||||
|
|
||||||
// Get max 4 lines of each paste.
|
// Get max 4 lines of each paste.
|
||||||
pasteDataSplitted := strings.Split(pastes[i].Data, "\n")
|
pasteDataSplitted := strings.Split(paste.Data, "\n")
|
||||||
|
|
||||||
var pasteData string
|
var pasteData string
|
||||||
|
|
||||||
if len(pasteDataSplitted) < 4 {
|
if len(pasteDataSplitted) < 4 {
|
||||||
pasteData = pastes[i].Data
|
pasteData = paste.Data
|
||||||
} else {
|
} else {
|
||||||
pasteData = strings.Join(pasteDataSplitted[0:4], "\n")
|
pasteData = strings.Join(pasteDataSplitted[0:4], "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteDataMap["pasteData"] = pasteData
|
pasteDataMap["pasteData"] = pasteData
|
||||||
pasteTpl := templater.GetRawTemplate(ec, "pastelist_paste.html", pasteDataMap)
|
pasteTpl := templater.GetRawTemplate(ectx, "pastelist_paste.html", pasteDataMap)
|
||||||
|
|
||||||
pastesString += pasteTpl
|
pastesString += pasteTpl
|
||||||
}
|
}
|
||||||
@ -104,8 +104,8 @@ func pastesGET(ec echo.Context) error {
|
|||||||
c.Logger.Debug().Int("total pages", pages).Int("current page", page).Msg("Paging data")
|
c.Logger.Debug().Int("total pages", pages).Int("current page", page).Msg("Paging data")
|
||||||
paginationHTML := pagination.CreateHTML(page, pages, "/pastes/")
|
paginationHTML := pagination.CreateHTML(page, pages, "/pastes/")
|
||||||
|
|
||||||
pasteListTpl := templater.GetTemplate(ec, "pastelist_list.html", map[string]string{"pastes": pastesString, "pagination": paginationHTML})
|
pasteListTpl := templater.GetTemplate(ectx, "pastelist_list.html", map[string]string{"pastes": pastesString, "pagination": paginationHTML})
|
||||||
|
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return ec.HTML(http.StatusOK, pasteListTpl)
|
return ectx.HTML(http.StatusOK, pasteListTpl)
|
||||||
}
|
}
|
||||||
|
@ -31,16 +31,16 @@ func (c *Context) initializeHTTPServer() {
|
|||||||
// Wrapper around previous function.
|
// Wrapper around previous function.
|
||||||
func (c *Context) echoReqLogger() echo.MiddlewareFunc {
|
func (c *Context) echoReqLogger() echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(ec echo.Context) error {
|
return func(ectx echo.Context) error {
|
||||||
c.Logger.Info().
|
c.Logger.Info().
|
||||||
Str("IP", ec.RealIP()).
|
Str("IP", ectx.RealIP()).
|
||||||
Str("Host", ec.Request().Host).
|
Str("Host", ectx.Request().Host).
|
||||||
Str("Method", ec.Request().Method).
|
Str("Method", ectx.Request().Method).
|
||||||
Str("Path", ec.Request().URL.Path).
|
Str("Path", ectx.Request().URL.Path).
|
||||||
Str("UA", ec.Request().UserAgent()).
|
Str("UA", ectx.Request().UserAgent()).
|
||||||
Msg("HTTP request")
|
Msg("HTTP request")
|
||||||
|
|
||||||
return next(ec)
|
return next(ectx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Puts memory usage into log lines.
|
// Puts memory usage into log lines.
|
||||||
func (c *Context) getMemoryUsage(e *zerolog.Event, level zerolog.Level, message string) {
|
func (c *Context) getMemoryUsage(event *zerolog.Event, level zerolog.Level, message string) {
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
|
|
||||||
runtime.ReadMemStats(&m)
|
runtime.ReadMemStats(&m)
|
||||||
|
|
||||||
e.Str("memalloc", fmt.Sprintf("%dMB", m.Alloc/1024/1024))
|
event.Str("memalloc", fmt.Sprintf("%dMB", m.Alloc/1024/1024))
|
||||||
e.Str("memsys", fmt.Sprintf("%dMB", m.Sys/1024/1024))
|
event.Str("memsys", fmt.Sprintf("%dMB", m.Sys/1024/1024))
|
||||||
e.Str("numgc", fmt.Sprintf("%d", m.NumGC))
|
event.Str("numgc", fmt.Sprintf("%d", m.NumGC))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes logger.
|
// Initializes logger.
|
||||||
@ -26,26 +26,26 @@ func (c *Context) initializeLogger() {
|
|||||||
// Устанавливаем форматирование логгера.
|
// Устанавливаем форматирование логгера.
|
||||||
// nolint:exhaustivestruct
|
// nolint:exhaustivestruct
|
||||||
output := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false, TimeFormat: time.RFC3339}
|
output := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false, TimeFormat: time.RFC3339}
|
||||||
output.FormatLevel = func(i interface{}) string {
|
output.FormatLevel = func(lvlRaw interface{}) string {
|
||||||
var v string
|
var v string
|
||||||
|
|
||||||
if ii, ok := i.(string); ok {
|
if lvl, ok := lvlRaw.(string); ok {
|
||||||
ii = strings.ToUpper(ii)
|
lvl = strings.ToUpper(lvl)
|
||||||
switch ii {
|
switch lvl {
|
||||||
case "DEBUG":
|
case "DEBUG":
|
||||||
v = fmt.Sprintf("\x1b[30m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[30m%-5s\x1b[0m", lvl)
|
||||||
case "ERROR":
|
case "ERROR":
|
||||||
v = fmt.Sprintf("\x1b[31m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[31m%-5s\x1b[0m", lvl)
|
||||||
case "FATAL":
|
case "FATAL":
|
||||||
v = fmt.Sprintf("\x1b[35m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[35m%-5s\x1b[0m", lvl)
|
||||||
case "INFO":
|
case "INFO":
|
||||||
v = fmt.Sprintf("\x1b[32m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[32m%-5s\x1b[0m", lvl)
|
||||||
case "PANIC":
|
case "PANIC":
|
||||||
v = fmt.Sprintf("\x1b[36m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[36m%-5s\x1b[0m", lvl)
|
||||||
case "WARN":
|
case "WARN":
|
||||||
v = fmt.Sprintf("\x1b[33m%-5s\x1b[0m", ii)
|
v = fmt.Sprintf("\x1b[33m%-5s\x1b[0m", lvl)
|
||||||
default:
|
default:
|
||||||
v = ii
|
v = lvl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,16 +250,16 @@ func (ff *FlatFiles) Initialize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ff *FlatFiles) SavePaste(p *structs.Paste) (int64, error) {
|
func (ff *FlatFiles) SavePaste(paste *structs.Paste) (int64, error) {
|
||||||
ff.writeMutex.Lock()
|
ff.writeMutex.Lock()
|
||||||
// Write paste data on disk.
|
// Write paste data on disk.
|
||||||
filesOnDisk, _ := ioutil.ReadDir(filepath.Join(ff.path, "pastes"))
|
filesOnDisk, _ := ioutil.ReadDir(filepath.Join(ff.path, "pastes"))
|
||||||
pasteID := len(filesOnDisk) + 1
|
pasteID := len(filesOnDisk) + 1
|
||||||
p.ID = pasteID
|
paste.ID = pasteID
|
||||||
|
|
||||||
c.Logger.Debug().Int("new paste ID", pasteID).Msg("Writing paste to disk")
|
c.Logger.Debug().Int("new paste ID", pasteID).Msg("Writing paste to disk")
|
||||||
|
|
||||||
data, err := json.Marshal(p)
|
data, err := json.Marshal(paste)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
|
|
||||||
@ -267,8 +267,7 @@ func (ff *FlatFiles) SavePaste(p *structs.Paste) (int64, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:gosec
|
err = ioutil.WriteFile(filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json"), data, 0o600)
|
||||||
err = ioutil.WriteFile(filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json"), data, 0644)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
|
|
||||||
@ -280,7 +279,7 @@ func (ff *FlatFiles) SavePaste(p *structs.Paste) (int64, error) {
|
|||||||
// nolint:exhaustivestruct
|
// nolint:exhaustivestruct
|
||||||
indexData := Index{}
|
indexData := Index{}
|
||||||
indexData.ID = pasteID
|
indexData.ID = pasteID
|
||||||
indexData.Private = p.Private
|
indexData.Private = paste.Private
|
||||||
ff.pastesIndex = append(ff.pastesIndex, indexData)
|
ff.pastesIndex = append(ff.pastesIndex, indexData)
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
|
|
||||||
@ -297,8 +296,7 @@ func (ff *FlatFiles) Shutdown() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:gosec
|
err1 := ioutil.WriteFile(filepath.Join(ff.path, "pastes", "index.json"), indexData, 0o600)
|
||||||
err1 := ioutil.WriteFile(filepath.Join(ff.path, "pastes", "index.json"), indexData, 0644)
|
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
c.Logger.Error().Err(err1).Msg("Failed to write index data to file. Pretty sure that you've lost your pastes.")
|
c.Logger.Error().Err(err1).Msg("Failed to write index data to file. Pretty sure that you've lost your pastes.")
|
||||||
|
|
||||||
|
@ -28,14 +28,14 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PasswordedPastesUp(tx *sql.Tx) error {
|
func PasswordedPastesUp(txn *sql.Tx) error {
|
||||||
_, err := tx.Exec("ALTER TABLE `pastes` ADD `password` varchar(64) NOT NULL DEFAULT '' COMMENT 'Password for paste (scrypted and sha256ed).'")
|
_, err := txn.Exec("ALTER TABLE `pastes` ADD `password` varchar(64) NOT NULL DEFAULT '' COMMENT 'Password for paste (scrypted and sha256ed).'")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err1 := tx.Exec("ALTER TABLE `pastes` ADD `password_salt` varchar(64) NOT NULL DEFAULT '' COMMENT 'Password salt (sha256ed).'")
|
_, err1 := txn.Exec("ALTER TABLE `pastes` ADD `password_salt` varchar(64) NOT NULL DEFAULT '' COMMENT 'Password salt (sha256ed).'")
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err1
|
return err1
|
||||||
@ -44,14 +44,14 @@ func PasswordedPastesUp(tx *sql.Tx) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordedPastesDown(tx *sql.Tx) error {
|
func PasswordedPastesDown(txn *sql.Tx) error {
|
||||||
_, err := tx.Exec("ALTER TABLE `pastes` DROP COLUMN `password`")
|
_, err := txn.Exec("ALTER TABLE `pastes` DROP COLUMN `password`")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err1 := tx.Exec("ALTER TABLE `pastes` DROP COLUMN `password_salt`")
|
_, err1 := txn.Exec("ALTER TABLE `pastes` DROP COLUMN `password_salt`")
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err1
|
return err1
|
||||||
|
@ -81,15 +81,15 @@ func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
// nolint:exhaustivestruct
|
// nolint:exhaustivestruct
|
||||||
p := &structs.Paste{}
|
paste := &structs.Paste{}
|
||||||
|
|
||||||
err := db.db.Get(p, db.db.Rebind("SELECT * FROM `pastes` WHERE id=?"), pasteID)
|
err := db.db.Get(paste, db.db.Rebind("SELECT * FROM `pastes` WHERE id=?"), pasteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p, nil
|
return paste, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||||
@ -195,13 +195,13 @@ func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ID, err1 := result.LastInsertId()
|
lastInsertID, err1 := result.LastInsertId()
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ID, nil
|
return lastInsertID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) Shutdown() {
|
func (db *Database) Shutdown() {
|
||||||
|
@ -28,14 +28,14 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PasswordedPastesUp(tx *sql.Tx) error {
|
func PasswordedPastesUp(txn *sql.Tx) error {
|
||||||
_, err := tx.Exec("ALTER TABLE pastes ADD COLUMN password VARCHAR(64) NOT NULL DEFAULT ''; COMMENT ON COLUMN pastes.password IS 'Password for paste (scrypted and sha256ed).';")
|
_, err := txn.Exec("ALTER TABLE pastes ADD COLUMN password VARCHAR(64) NOT NULL DEFAULT ''; COMMENT ON COLUMN pastes.password IS 'Password for paste (scrypted and sha256ed).';")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err1 := tx.Exec("ALTER TABLE pastes ADD COLUMN password_salt VARCHAR(64) NOT NULL DEFAULT ''; COMMENT ON COLUMN pastes.password_salt IS 'Password salt (sha256ed).';")
|
_, err1 := txn.Exec("ALTER TABLE pastes ADD COLUMN password_salt VARCHAR(64) NOT NULL DEFAULT ''; COMMENT ON COLUMN pastes.password_salt IS 'Password salt (sha256ed).';")
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err1
|
return err1
|
||||||
@ -44,14 +44,14 @@ func PasswordedPastesUp(tx *sql.Tx) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PasswordedPastesDown(tx *sql.Tx) error {
|
func PasswordedPastesDown(txn *sql.Tx) error {
|
||||||
_, err := tx.Exec("ALTER TABLE pastes DROP COLUMN password")
|
_, err := txn.Exec("ALTER TABLE pastes DROP COLUMN password")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err1 := tx.Exec("ALTER TABLE pastes DROP COLUMN password_salt")
|
_, err1 := txn.Exec("ALTER TABLE pastes DROP COLUMN password_salt")
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return err1
|
return err1
|
||||||
|
@ -84,9 +84,9 @@ func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
// nolint:exhaustivestruct
|
// nolint:exhaustivestruct
|
||||||
p := &structs.Paste{}
|
paste := &structs.Paste{}
|
||||||
|
|
||||||
err := db.db.Get(p, db.db.Rebind("SELECT * FROM pastes WHERE id=$1"), pasteID)
|
err := db.db.Get(paste, db.db.Rebind("SELECT * FROM pastes WHERE id=$1"), pasteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -96,10 +96,10 @@ func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
// timestamps in server's local timezone. We should convert them.
|
// timestamps in server's local timezone. We should convert them.
|
||||||
loc, _ := time.LoadLocation("UTC")
|
loc, _ := time.LoadLocation("UTC")
|
||||||
|
|
||||||
utcCreatedAt := p.CreatedAt.In(loc)
|
utcCreatedAt := paste.CreatedAt.In(loc)
|
||||||
p.CreatedAt = &utcCreatedAt
|
paste.CreatedAt = &utcCreatedAt
|
||||||
|
|
||||||
return p, nil
|
return paste, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||||
@ -197,7 +197,7 @@ func (db *Database) Initialize() {
|
|||||||
migrations.Migrate()
|
migrations.Migrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
func (db *Database) SavePaste(paste *structs.Paste) (int64, error) {
|
||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
stmt, err := db.db.PrepareNamed("INSERT INTO pastes (title, data, created_at, keep_for, keep_for_unit_type, language, private, password, password_salt) VALUES (:title, :data, :created_at, :keep_for, :keep_for_unit_type, :language, :private, :password, :password_salt) RETURNING id")
|
stmt, err := db.db.PrepareNamed("INSERT INTO pastes (title, data, created_at, keep_for, keep_for_unit_type, language, private, password, password_salt) VALUES (:title, :data, :created_at, :keep_for, :keep_for_unit_type, :language, :private, :password, :password_salt) RETURNING id")
|
||||||
@ -208,7 +208,7 @@ func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
|||||||
|
|
||||||
var id int64
|
var id int64
|
||||||
|
|
||||||
err = stmt.Get(&id, p)
|
err = stmt.Get(&id, paste)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// nolint:wrapcheck
|
// nolint:wrapcheck
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -50,11 +50,11 @@ func GetErrorTemplate(ec echo.Context, errorText string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTemplate returns only raw template data.
|
// GetRawTemplate returns only raw template data.
|
||||||
func GetRawTemplate(ec echo.Context, templateName string, data map[string]string) string {
|
func GetRawTemplate(ectx echo.Context, templateName string, data map[string]string) string {
|
||||||
// Getting main template.
|
// Getting main template.
|
||||||
tplRaw, err := assets.Data.ReadFile(templateName)
|
tplRaw, err := assets.Data.ReadFile(templateName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = ec.String(http.StatusBadRequest, templateName+" not found.")
|
_ = ectx.String(http.StatusBadRequest, templateName+" not found.")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -69,13 +69,13 @@ func GetRawTemplate(ec echo.Context, templateName string, data map[string]string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetTemplate returns formatted template that can be outputted to client.
|
// GetTemplate returns formatted template that can be outputted to client.
|
||||||
func GetTemplate(ec echo.Context, name string, data map[string]string) string {
|
func GetTemplate(ectx echo.Context, name string, data map[string]string) string {
|
||||||
log.Debug().Str("name", name).Msg("Requested template")
|
log.Debug().Str("name", name).Msg("Requested template")
|
||||||
|
|
||||||
// Getting main template.
|
// Getting main template.
|
||||||
mainhtml, err := assets.Data.ReadFile("main.html")
|
mainhtml, err := assets.Data.ReadFile("main.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = ec.String(http.StatusBadRequest, "main.html not found.")
|
_ = ectx.String(http.StatusBadRequest, "main.html not found.")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ func GetTemplate(ec echo.Context, name string, data map[string]string) string {
|
|||||||
// Getting navigation.
|
// Getting navigation.
|
||||||
navhtml, err1 := assets.Data.ReadFile("navigation.html")
|
navhtml, err1 := assets.Data.ReadFile("navigation.html")
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
_ = ec.String(http.StatusBadRequest, "navigation.html not found.")
|
_ = ectx.String(http.StatusBadRequest, "navigation.html not found.")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ func GetTemplate(ec echo.Context, name string, data map[string]string) string {
|
|||||||
// Getting footer.
|
// Getting footer.
|
||||||
footerhtml, err2 := assets.Data.ReadFile("footer.html")
|
footerhtml, err2 := assets.Data.ReadFile("footer.html")
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
_ = ec.String(http.StatusBadRequest, "footer.html not found.")
|
_ = ectx.String(http.StatusBadRequest, "footer.html not found.")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ func GetTemplate(ec echo.Context, name string, data map[string]string) string {
|
|||||||
// Get requested template.
|
// Get requested template.
|
||||||
reqhtml, err3 := assets.Data.ReadFile(name)
|
reqhtml, err3 := assets.Data.ReadFile(name)
|
||||||
if err3 != nil {
|
if err3 != nil {
|
||||||
_ = ec.String(http.StatusBadRequest, name+" not found.")
|
_ = ectx.String(http.StatusBadRequest, name+" not found.")
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user