Merge branch 'linting' of fastpastebin/fastpastebin into master
This commit is contained in:
commit
02cea49fc4
18
.drone.yml
18
.drone.yml
@ -5,7 +5,7 @@ name: build
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: notify-start
|
- name: notify-start
|
||||||
image: appleboy/drone-discord
|
image: pztrn/discordrone
|
||||||
settings:
|
settings:
|
||||||
webhook_id:
|
webhook_id:
|
||||||
from_secret: discord_webhook_id
|
from_secret: discord_webhook_id
|
||||||
@ -20,20 +20,23 @@ steps:
|
|||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
commands:
|
commands:
|
||||||
- golangci-lint run
|
- golangci-lint run
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
image: golang:1.13.1-alpine
|
image: golang:1.13.5-alpine
|
||||||
environment:
|
environment:
|
||||||
GOFLAGS: -mod=vendor
|
GOFLAGS: -mod=vendor
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
commands:
|
commands:
|
||||||
- go test ./...
|
- go test ./...
|
||||||
|
depends_on:
|
||||||
|
- notify-start
|
||||||
|
|
||||||
- name: docker
|
- name: docker
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
when:
|
when:
|
||||||
branch:
|
branch: master
|
||||||
master
|
|
||||||
settings:
|
settings:
|
||||||
username:
|
username:
|
||||||
from_secret: dockerhub_user
|
from_secret: dockerhub_user
|
||||||
@ -41,13 +44,16 @@ steps:
|
|||||||
from_secret: dockerhub_password
|
from_secret: dockerhub_password
|
||||||
repo: pztrn/fastpastebin
|
repo: pztrn/fastpastebin
|
||||||
auto_tag: true
|
auto_tag: true
|
||||||
|
depends_on:
|
||||||
|
- lint
|
||||||
|
- test
|
||||||
|
|
||||||
- name: notify-end
|
- name: notify-end
|
||||||
when:
|
when:
|
||||||
status:
|
status:
|
||||||
- success
|
- success
|
||||||
- failure
|
- failure
|
||||||
image: appleboy/drone-discord
|
image: pztrn/discordrone
|
||||||
settings:
|
settings:
|
||||||
webhook_id:
|
webhook_id:
|
||||||
from_secret: discord_webhook_id
|
from_secret: discord_webhook_id
|
||||||
@ -59,3 +65,5 @@ steps:
|
|||||||
{{ else }}
|
{{ else }}
|
||||||
**{{repo.name}}#{{build.number}}@{{build.commit}}** failed. See {{build.link}}.
|
**{{repo.name}}#{{build.number}}@{{build.commit}}** failed. See {{build.link}}.
|
||||||
{{/success}}"
|
{{/success}}"
|
||||||
|
depends_on:
|
||||||
|
- docker
|
||||||
|
18
.golangci.yml
Normal file
18
.golangci.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
run:
|
||||||
|
deadline: 5m
|
||||||
|
linters:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
# Because globals might exist, but according to our codestyle they
|
||||||
|
# should be lowercased and considered as unexported.
|
||||||
|
- gochecknoglobals
|
||||||
|
# While it might be useful it'll create more problems that will solve.
|
||||||
|
- gocritic
|
||||||
|
# Complains about main() lengths, which isn't an issue.
|
||||||
|
- funlen
|
||||||
|
linters-settings:
|
||||||
|
lll:
|
||||||
|
line-length: 420
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 40
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/domains/database_not_available"
|
"go.dev.pztrn.name/fastpastebin/domains/dbnotavailable"
|
||||||
"go.dev.pztrn.name/fastpastebin/domains/indexpage"
|
"go.dev.pztrn.name/fastpastebin/domains/indexpage"
|
||||||
"go.dev.pztrn.name/fastpastebin/domains/pastes"
|
"go.dev.pztrn.name/fastpastebin/domains/pastes"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/captcha"
|
"go.dev.pztrn.name/fastpastebin/internal/captcha"
|
||||||
@ -61,14 +61,16 @@ func main() {
|
|||||||
|
|
||||||
captcha.New(c)
|
captcha.New(c)
|
||||||
|
|
||||||
database_not_available.New(c)
|
dbnotavailable.New(c)
|
||||||
indexpage.New(c)
|
indexpage.New(c)
|
||||||
pastes.New(c)
|
pastes.New(c)
|
||||||
|
|
||||||
// CTRL+C handler.
|
// CTRL+C handler.
|
||||||
signalHandler := make(chan os.Signal, 1)
|
signalHandler := make(chan os.Signal, 1)
|
||||||
shutdownDone := make(chan bool, 1)
|
shutdownDone := make(chan bool, 1)
|
||||||
|
|
||||||
signal.Notify(signalHandler, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(signalHandler, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-signalHandler
|
<-signalHandler
|
||||||
c.Shutdown()
|
c.Shutdown()
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
package database_not_available
|
package dbnotavailable
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
@ -22,7 +22,7 @@
|
|||||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
package database_not_available
|
package dbnotavailable
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
@ -33,7 +33,7 @@ var (
|
|||||||
c *context.Context
|
c *context.Context
|
||||||
)
|
)
|
||||||
|
|
||||||
// New initializes pastes package and adds neccessary HTTP and API
|
// New initializes pastes package and adds necessary HTTP and API
|
||||||
// endpoints.
|
// endpoints.
|
||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
@ -33,7 +33,7 @@ var (
|
|||||||
c *context.Context
|
c *context.Context
|
||||||
)
|
)
|
||||||
|
|
||||||
// New initializes pastes package and adds neccessary HTTP and API
|
// New initializes pastes package and adds necessary HTTP and API
|
||||||
// endpoints.
|
// endpoints.
|
||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
|
@ -40,7 +40,7 @@ var (
|
|||||||
c *context.Context
|
c *context.Context
|
||||||
)
|
)
|
||||||
|
|
||||||
// New initializes pastes package and adds neccessary HTTP and API
|
// New initializes pastes package and adds necessary HTTP and API
|
||||||
// endpoints.
|
// endpoints.
|
||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
|
@ -34,12 +34,6 @@ const (
|
|||||||
// for some cases, e.g. public paste won't check for timestamp and cookie
|
// for some cases, e.g. public paste won't check for timestamp and cookie
|
||||||
// value (they both will be ignored), but private will.
|
// value (they both will be ignored), but private will.
|
||||||
func pasteGetData(pasteID int, timestamp int64, cookieValue string) (*structs.Paste, string) {
|
func pasteGetData(pasteID int, timestamp int64, cookieValue string) (*structs.Paste, string) {
|
||||||
// We should check if database connection available.
|
|
||||||
//dbConn := c.Database.GetDatabaseConnection()
|
|
||||||
//if c.Config.Database.Type != "flatfiles" && dbConn == nil {
|
|
||||||
// return ec.Redirect(http.StatusFound, "/database_not_available")
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Get paste.
|
// Get paste.
|
||||||
paste, err1 := c.Database.GetPaste(pasteID)
|
paste, err1 := c.Database.GetPaste(pasteID)
|
||||||
if err1 != nil {
|
if err1 != nil {
|
||||||
@ -91,21 +85,25 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
// If passed timestamp is invalid (isn't a real UNIX timestamp) we
|
// If passed timestamp is invalid (isn't a real UNIX timestamp) we
|
||||||
// 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 := ec.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(ec, "Paste #"+pasteIDStr+" not found")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
} else {
|
|
||||||
timestamp = tsProvided
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timestamp = tsProvided
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have "PASTE-PASTEID" cookie defined. It is required
|
// Check if we have "PASTE-PASTEID" cookie defined. It is required
|
||||||
// for private pastes.
|
// for private pastes.
|
||||||
var cookieValue string
|
var cookieValue string
|
||||||
|
|
||||||
cookie, err1 := ec.Cookie("PASTE-" + pasteIDStr)
|
cookie, err1 := ec.Cookie("PASTE-" + pasteIDStr)
|
||||||
if err1 == nil {
|
if err1 == nil {
|
||||||
cookieValue = cookie.Value
|
cookieValue = cookie.Value
|
||||||
@ -137,6 +135,7 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
if paste.KeepFor != 0 && paste.KeepForUnitType != 0 {
|
if paste.KeepFor != 0 && paste.KeepForUnitType != 0 {
|
||||||
pasteExpirationString = paste.GetExpirationTime().Format("2006-01-02 @ 15:04:05") + " UTC"
|
pasteExpirationString = paste.GetExpirationTime().Format("2006-01-02 @ 15:04:05") + " UTC"
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteData["pasteExpiration"] = pasteExpirationString
|
pasteData["pasteExpiration"] = pasteExpirationString
|
||||||
|
|
||||||
if paste.Private {
|
if paste.Private {
|
||||||
@ -170,10 +169,12 @@ func pasteGETWebInterface(ec echo.Context) error {
|
|||||||
}
|
}
|
||||||
// Create buffer and format into it.
|
// Create buffer and format into it.
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
err4 := formatter.Format(buf, style, lexered)
|
err4 := formatter.Format(buf, style, lexered)
|
||||||
if err4 != nil {
|
if err4 != nil {
|
||||||
c.Logger.Error().Err(err4).Msg("Failed to format paste data")
|
c.Logger.Error().Err(err4).Msg("Failed to format paste data")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteData["pastedata"] = buf.String()
|
pasteData["pastedata"] = buf.String()
|
||||||
|
|
||||||
// Get template and format it.
|
// Get template and format it.
|
||||||
@ -194,7 +195,9 @@ func pastePasswordedVerifyGet(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 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(ec, "Paste #"+pasteIDRaw+" not found")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +232,7 @@ func pastePasswordedVerifyGet(ec echo.Context) error {
|
|||||||
func pastePasswordedVerifyPost(ec echo.Context) error {
|
func pastePasswordedVerifyPost(ec 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()
|
||||||
|
// nolint
|
||||||
if c.Config.Database.Type != "flatfiles" && dbConn == nil {
|
if c.Config.Database.Type != "flatfiles" && dbConn == nil {
|
||||||
return ec.Redirect(http.StatusFound, "/database_not_available")
|
return ec.Redirect(http.StatusFound, "/database_not_available")
|
||||||
}
|
}
|
||||||
@ -245,13 +249,16 @@ func pastePasswordedVerifyPost(ec echo.Context) error {
|
|||||||
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(ec, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err2 := ec.FormParams()
|
params, err2 := ec.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(ec, "Paste #"+strconv.Itoa(pasteID)+" not found")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +275,8 @@ func pastePasswordedVerifyPost(ec echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errtpl := templater.GetErrorTemplate(ec, "Invalid password. Please, try again.")
|
errtpl := templater.GetErrorTemplate(ec, "Invalid password. Please, try again.")
|
||||||
return ec.HTML(http.StatusBadRequest, string(errtpl))
|
|
||||||
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET for "/pastes/:id/raw", raw paste output.
|
// GET for "/pastes/:id/raw", raw paste output.
|
||||||
@ -301,18 +309,23 @@ func pasteRawGETWebInterface(ec echo.Context) error {
|
|||||||
// 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 := ec.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")
|
||||||
|
|
||||||
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteTs := paste.CreatedAt.Unix()
|
pasteTs := paste.CreatedAt.Unix()
|
||||||
if tsProvided != pasteTs {
|
if tsProvided != pasteTs {
|
||||||
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")
|
||||||
|
|
||||||
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
return ec.String(http.StatusBadRequest, "Paste #"+pasteIDRaw+" not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
// ToDo: figure out how to handle passworded pastes here.
|
// ToDo: figure out how to handle passworded pastes here.
|
||||||
// Return error for now.
|
// Return error for now.
|
||||||
if paste.Password != "" {
|
if paste.Password != "" {
|
||||||
|
@ -31,28 +31,37 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
params, err := ec.FormParams()
|
params, err := ec.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(ec, "Cannot create empty paste")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug().Msgf("Received parameters: %+v", params)
|
c.Logger.Debug().Msgf("Received parameters: %+v", params)
|
||||||
|
|
||||||
// Do nothing if paste contents is empty.
|
// Do nothing if paste contents is empty.
|
||||||
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(ec, "Empty pastes aren't allowed.")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") && params["paste-keep-for"][0] != "forever" {
|
if !strings.ContainsAny(params["paste-keep-for"][0], "Mmhd") && params["paste-keep-for"][0] != "forever" {
|
||||||
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(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.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(ec, "Invalid captcha solution.")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,26 +79,33 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
// Defaulting to "forever".
|
// Defaulting to "forever".
|
||||||
keepFor := 0
|
keepFor := 0
|
||||||
keepForUnit := 0
|
keepForUnit := 0
|
||||||
|
|
||||||
if params["paste-keep-for"][0] != "forever" {
|
if params["paste-keep-for"][0] != "forever" {
|
||||||
keepForUnitRegex := regexp.MustCompile("[Mmhd]")
|
keepForUnitRegex := regexp.MustCompile("[Mmhd]")
|
||||||
|
|
||||||
keepForRaw := regexInts.FindAllString(params["paste-keep-for"][0], 1)[0]
|
keepForRaw := regexInts.FindAllString(params["paste-keep-for"][0], 1)[0]
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
keepFor, err = strconv.Atoi(keepForRaw)
|
keepFor, err = strconv.Atoi(keepForRaw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if params["paste-keep-for"][0] == "forever" {
|
if params["paste-keep-for"][0] == "forever" {
|
||||||
c.Logger.Debug().Msg("Keeping paste forever!")
|
c.Logger.Debug().Msg("Keeping paste forever!")
|
||||||
|
|
||||||
keepFor = 0
|
keepFor = 0
|
||||||
} 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(ec, "Invalid 'Paste should be available for' parameter passed. Please do not try to hack us ;).")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keepForUnitRaw := keepForUnitRegex.FindAllString(params["paste-keep-for"][0], 1)[0]
|
keepForUnitRaw := keepForUnitRegex.FindAllString(params["paste-keep-for"][0], 1)[0]
|
||||||
keepForUnit = structs.PASTE_KEEPS_CORELLATION[keepForUnitRaw]
|
keepForUnit = structs.PasteKeepsCorellation[keepForUnitRaw]
|
||||||
}
|
}
|
||||||
|
|
||||||
paste.KeepFor = keepFor
|
paste.KeepFor = keepFor
|
||||||
paste.KeepForUnitType = keepForUnit
|
paste.KeepForUnitType = keepForUnit
|
||||||
|
|
||||||
@ -107,6 +123,7 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
paste.Private = false
|
paste.Private = false
|
||||||
privateCheckbox, privateCheckboxFound := params["paste-private"]
|
privateCheckbox, privateCheckboxFound := params["paste-private"]
|
||||||
pastePassword, pastePasswordFound := params["paste-password"]
|
pastePassword, pastePasswordFound := params["paste-password"]
|
||||||
|
|
||||||
if privateCheckboxFound && privateCheckbox[0] == "on" || pastePasswordFound && pastePassword[0] != "" {
|
if privateCheckboxFound && privateCheckbox[0] == "on" || pastePasswordFound && pastePassword[0] != "" {
|
||||||
paste.Private = true
|
paste.Private = true
|
||||||
}
|
}
|
||||||
@ -118,7 +135,9 @@ func pastePOSTWebInterface(ec echo.Context) error {
|
|||||||
id, err2 := c.Database.SavePaste(paste)
|
id, 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(ec, "Failed to save paste. Please, try again later.")
|
||||||
|
|
||||||
return ec.HTML(http.StatusBadRequest, errtpl)
|
return ec.HTML(http.StatusBadRequest, errtpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GET for "/pastes/", a list of publicly available pastes.
|
// GET for "/pastes/", a list of publicly available pastes.
|
||||||
// Web inteface version.
|
// Web interface version.
|
||||||
func pastesGET(ec echo.Context) error {
|
func pastesGET(ec 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()
|
||||||
@ -48,7 +48,9 @@ func pastesGET(ec echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pageFromParamRaw := ec.Param("page")
|
pageFromParamRaw := ec.Param("page")
|
||||||
|
|
||||||
var page = 1
|
var page = 1
|
||||||
|
|
||||||
if pageFromParamRaw != "" {
|
if pageFromParamRaw != "" {
|
||||||
pageRaw := regexInts.FindAllString(pageFromParamRaw, 1)[0]
|
pageRaw := regexInts.FindAllString(pageFromParamRaw, 1)[0]
|
||||||
page, _ = strconv.Atoi(pageRaw)
|
page, _ = strconv.Atoi(pageRaw)
|
||||||
@ -65,12 +67,15 @@ func pastesGET(ec echo.Context) error {
|
|||||||
// Show "No pastes to show" on any error for now.
|
// Show "No pastes to show" on any error for now.
|
||||||
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(ec, "No pastes to show.")
|
||||||
|
|
||||||
return ec.HTML(http.StatusOK, noPastesToShowTpl)
|
return ec.HTML(http.StatusOK, noPastesToShowTpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pastes) > 0 {
|
if len(pastes) > 0 {
|
||||||
pastesString = ""
|
pastesString = ""
|
||||||
|
|
||||||
for i := range pastes {
|
for i := range pastes {
|
||||||
pasteDataMap := make(map[string]string)
|
pasteDataMap := make(map[string]string)
|
||||||
pasteDataMap["pasteID"] = strconv.Itoa(pastes[i].ID)
|
pasteDataMap["pasteID"] = strconv.Itoa(pastes[i].ID)
|
||||||
@ -79,7 +84,9 @@ func pastesGET(ec echo.Context) error {
|
|||||||
|
|
||||||
// Get max 4 lines of each paste.
|
// Get max 4 lines of each paste.
|
||||||
pasteDataSplitted := strings.Split(pastes[i].Data, "\n")
|
pasteDataSplitted := strings.Split(pastes[i].Data, "\n")
|
||||||
|
|
||||||
var pasteData string
|
var pasteData string
|
||||||
|
|
||||||
if len(pasteDataSplitted) < 4 {
|
if len(pasteDataSplitted) < 4 {
|
||||||
pasteData = pastes[i].Data
|
pasteData = pastes[i].Data
|
||||||
} else {
|
} else {
|
||||||
@ -100,5 +107,5 @@ func pastesGET(ec echo.Context) error {
|
|||||||
|
|
||||||
pasteListTpl := templater.GetTemplate(ec, "pastelist_list.html", map[string]string{"pastes": pastesString, "pagination": paginationHTML})
|
pasteListTpl := templater.GetTemplate(ec, "pastelist_list.html", map[string]string{"pastes": pastesString, "pagination": paginationHTML})
|
||||||
|
|
||||||
return ec.HTML(http.StatusOK, string(pasteListTpl))
|
return ec.HTML(http.StatusOK, pasteListTpl)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ var (
|
|||||||
log zerolog.Logger
|
log zerolog.Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
// New initializes captcha package and adds neccessary HTTP and API
|
// New initializes captcha package and adds necessary HTTP and API
|
||||||
// endpoints.
|
// endpoints.
|
||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
@ -53,6 +53,7 @@ func New(cc *context.Context) {
|
|||||||
func NewCaptcha() string {
|
func NewCaptcha() string {
|
||||||
s := captcha.New()
|
s := captcha.New()
|
||||||
log.Debug().Str("captcha string", s).Msg("Created new captcha string")
|
log.Debug().Str("captcha string", s).Msg("Created new captcha string")
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
// ConfigDatabase describes database configuration.
|
// Database describes database configuration.
|
||||||
type ConfigDatabase struct {
|
type Database struct {
|
||||||
Type string `yaml:"type"`
|
Type string `yaml:"type"`
|
||||||
Path string `yaml:"path"`
|
Path string `yaml:"path"`
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
// ConfigHTTP describes HTTP server configuration.
|
// HTTP describes HTTP server configuration.
|
||||||
type ConfigHTTP struct {
|
type HTTP struct {
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
Port string `yaml:"port"`
|
Port string `yaml:"port"`
|
||||||
AllowInsecure bool `yaml:"allow_insecure"`
|
AllowInsecure bool `yaml:"allow_insecure"`
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
// ConfigLogging describes logger configuration.
|
// Logging describes logger configuration.
|
||||||
type ConfigLogging struct {
|
type Logging struct {
|
||||||
LogToFile bool `yaml:"log_to_file"`
|
LogToFile bool `yaml:"log_to_file"`
|
||||||
FileName string `yaml:"filename"`
|
FileName string `yaml:"filename"`
|
||||||
LogLevel string `yaml:"loglevel"`
|
LogLevel string `yaml:"loglevel"`
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
// ConfigPastes describes pastes subsystem configuration.
|
// Pastes describes pastes subsystem configuration.
|
||||||
type ConfigPastes struct {
|
type Pastes struct {
|
||||||
Pagination int `yaml:"pagination"`
|
Pagination int `yaml:"pagination"`
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
|
|
||||||
package config
|
package config
|
||||||
|
|
||||||
// ConfigStruct describes whole configuration.
|
// Struct describes whole configuration.
|
||||||
type ConfigStruct struct {
|
type Struct struct {
|
||||||
Database ConfigDatabase `yaml:"database"`
|
Database Database `yaml:"database"`
|
||||||
Logging ConfigLogging `yaml:"logging"`
|
Logging Logging `yaml:"logging"`
|
||||||
HTTP ConfigHTTP `yaml:"http"`
|
HTTP HTTP `yaml:"http"`
|
||||||
Pastes ConfigPastes `yaml:"pastes"`
|
Pastes Pastes `yaml:"pastes"`
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ import (
|
|||||||
// contains everything every part of application need, like configuration
|
// contains everything every part of application need, like configuration
|
||||||
// access, logger, etc.
|
// access, logger, etc.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
Config *config.ConfigStruct
|
Config *config.Struct
|
||||||
Database databaseinterface.Interface
|
Database databaseinterface.Interface
|
||||||
Echo *echo.Echo
|
Echo *echo.Echo
|
||||||
Flagger *flagger.Flagger
|
Flagger *flagger.Flagger
|
||||||
@ -104,7 +104,7 @@ func (c *Context) LoadConfiguration() {
|
|||||||
|
|
||||||
c.Logger.Debug().Msgf("Configuration file path: %s", configPath)
|
c.Logger.Debug().Msgf("Configuration file path: %s", configPath)
|
||||||
|
|
||||||
c.Config = &config.ConfigStruct{}
|
c.Config = &config.Struct{}
|
||||||
|
|
||||||
// Read configuration file.
|
// Read configuration file.
|
||||||
fileData, err2 := ioutil.ReadFile(normalizedConfigPath)
|
fileData, err2 := ioutil.ReadFile(normalizedConfigPath)
|
||||||
|
@ -15,6 +15,7 @@ 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(e *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))
|
e.Str("memalloc", fmt.Sprintf("%dMB", m.Alloc/1024/1024))
|
||||||
@ -28,6 +29,7 @@ func (c *Context) initializeLogger() {
|
|||||||
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(i interface{}) string {
|
||||||
var v string
|
var v string
|
||||||
|
|
||||||
if ii, ok := i.(string); ok {
|
if ii, ok := i.(string); ok {
|
||||||
ii = strings.ToUpper(ii)
|
ii = strings.ToUpper(ii)
|
||||||
switch ii {
|
switch ii {
|
||||||
@ -47,6 +49,7 @@ func (c *Context) initializeLogger() {
|
|||||||
v = ii
|
v = ii
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("| %s |", v)
|
return fmt.Sprintf("| %s |", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +62,7 @@ func (c *Context) initializeLogger() {
|
|||||||
func (c *Context) initializeLoggerPost() {
|
func (c *Context) initializeLoggerPost() {
|
||||||
// Set log level.
|
// Set log level.
|
||||||
c.Logger.Info().Msgf("Setting logger level: %s", c.Config.Logging.LogLevel)
|
c.Logger.Info().Msgf("Setting logger level: %s", c.Config.Logging.LogLevel)
|
||||||
|
|
||||||
switch c.Config.Logging.LogLevel {
|
switch c.Config.Logging.LogLevel {
|
||||||
case "DEBUG":
|
case "DEBUG":
|
||||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
|
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/flatfiles"
|
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/flatfiles"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/mysql"
|
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/mysql"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/postgresql"
|
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/postgresql"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
||||||
|
@ -27,7 +27,7 @@ package flatfiles
|
|||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -38,5 +38,6 @@ var (
|
|||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
f = &FlatFiles{}
|
f = &FlatFiles{}
|
||||||
|
|
||||||
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||||
}
|
}
|
||||||
|
@ -54,15 +54,18 @@ func (ff *FlatFiles) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
ff.writeMutex.Lock()
|
ff.writeMutex.Lock()
|
||||||
pastePath := filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json")
|
pastePath := filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json")
|
||||||
c.Logger.Debug().Msgf("Trying to load paste data from '%s'...", pastePath)
|
c.Logger.Debug().Msgf("Trying to load paste data from '%s'...", pastePath)
|
||||||
|
|
||||||
pasteInBytes, err := ioutil.ReadFile(pastePath)
|
pasteInBytes, err := ioutil.ReadFile(pastePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Debug().Msgf("Failed to read paste from storage: %s", err.Error())
|
c.Logger.Debug().Msgf("Failed to read paste from storage: %s", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug().Msgf("Loaded %d bytes: %s", len(pasteInBytes), string(pasteInBytes))
|
c.Logger.Debug().Msgf("Loaded %d bytes: %s", len(pasteInBytes), string(pasteInBytes))
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
|
|
||||||
paste := &structs.Paste{}
|
paste := &structs.Paste{}
|
||||||
|
|
||||||
err = json.Unmarshal(pasteInBytes, paste)
|
err = json.Unmarshal(pasteInBytes, paste)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Msgf("Failed to parse paste: %s", err.Error())
|
c.Logger.Error().Msgf("Failed to parse paste: %s", err.Error())
|
||||||
@ -83,6 +86,7 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
|||||||
|
|
||||||
// Iteration one - get only public pastes.
|
// Iteration one - get only public pastes.
|
||||||
var publicPastes []*Index
|
var publicPastes []*Index
|
||||||
|
|
||||||
for _, paste := range ff.pastesIndex {
|
for _, paste := range ff.pastesIndex {
|
||||||
if !paste.Private {
|
if !paste.Private {
|
||||||
publicPastes = append(publicPastes, paste)
|
publicPastes = append(publicPastes, paste)
|
||||||
@ -92,7 +96,9 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
|||||||
c.Logger.Debug().Msgf("%+v", publicPastes)
|
c.Logger.Debug().Msgf("%+v", publicPastes)
|
||||||
|
|
||||||
// Iteration two - get paginated pastes.
|
// Iteration two - get paginated pastes.
|
||||||
|
// nolint
|
||||||
var pastesData []structs.Paste
|
var pastesData []structs.Paste
|
||||||
|
|
||||||
for idx, paste := range publicPastes {
|
for idx, paste := range publicPastes {
|
||||||
if len(pastesData) == c.Config.Pastes.Pagination {
|
if len(pastesData) == c.Config.Pastes.Pagination {
|
||||||
break
|
break
|
||||||
@ -107,10 +113,12 @@ func (ff *FlatFiles) GetPagedPastes(page int) ([]structs.Paste, error) {
|
|||||||
c.Logger.Debug().Msgf("Paste with index %d isn't in pagination query: too high index", idx)
|
c.Logger.Debug().Msgf("Paste with index %d isn't in pagination query: too high index", idx)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Debug().Msgf("Getting paste data (ID: %d, index: %d)", paste.ID, idx)
|
c.Logger.Debug().Msgf("Getting paste data (ID: %d, index: %d)", paste.ID, idx)
|
||||||
|
|
||||||
// Get paste data.
|
// Get paste data.
|
||||||
pasteData := &structs.Paste{}
|
pasteData := &structs.Paste{}
|
||||||
|
|
||||||
pasteRawData, err := ioutil.ReadFile(filepath.Join(ff.path, "pastes", strconv.Itoa(paste.ID)+".json"))
|
pasteRawData, err := ioutil.ReadFile(filepath.Join(ff.path, "pastes", strconv.Itoa(paste.ID)+".json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Msgf("Failed to read paste data: %s", err.Error())
|
c.Logger.Error().Msgf("Failed to read paste data: %s", err.Error())
|
||||||
@ -160,13 +168,16 @@ func (ff *FlatFiles) Initialize() {
|
|||||||
curUser, err := user.Current()
|
curUser, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Msg("Failed to get current user. Will replace '~' for '/' in storage path!")
|
c.Logger.Error().Msg("Failed to get current user. Will replace '~' for '/' in storage path!")
|
||||||
|
|
||||||
path = strings.Replace(path, "~", "/", -1)
|
path = strings.Replace(path, "~", "/", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
path = strings.Replace(path, "~", curUser.HomeDir, -1)
|
path = strings.Replace(path, "~", curUser.HomeDir, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
path, _ = filepath.Abs(path)
|
path, _ = filepath.Abs(path)
|
||||||
ff.path = path
|
ff.path = path
|
||||||
|
|
||||||
c.Logger.Debug().Msgf("Storage path is now: %s", ff.path)
|
c.Logger.Debug().Msgf("Storage path is now: %s", ff.path)
|
||||||
|
|
||||||
// Create directory if necessary.
|
// Create directory if necessary.
|
||||||
@ -209,29 +220,35 @@ func (ff *FlatFiles) SavePaste(p *structs.Paste) (int64, error) {
|
|||||||
// 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
|
||||||
c.Logger.Debug().Msgf("Writing paste to disk, ID will be " + strconv.Itoa(pasteID))
|
|
||||||
p.ID = pasteID
|
p.ID = pasteID
|
||||||
|
|
||||||
|
c.Logger.Debug().Msgf("Writing paste to disk, ID will be " + strconv.Itoa(pasteID))
|
||||||
|
|
||||||
data, err := json.Marshal(p)
|
data, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(ff.path, "pastes", strconv.Itoa(pasteID)+".json"), data, 0644)
|
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()
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add it to cache.
|
// Add it to cache.
|
||||||
indexData := &Index{}
|
indexData := &Index{}
|
||||||
indexData.ID = pasteID
|
indexData.ID = pasteID
|
||||||
indexData.Private = p.Private
|
indexData.Private = p.Private
|
||||||
ff.pastesIndex = append(ff.pastesIndex, indexData)
|
ff.pastesIndex = append(ff.pastesIndex, indexData)
|
||||||
ff.writeMutex.Unlock()
|
ff.writeMutex.Unlock()
|
||||||
|
|
||||||
return int64(pasteID), nil
|
return int64(pasteID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ff *FlatFiles) Shutdown() {
|
func (ff *FlatFiles) Shutdown() {
|
||||||
c.Logger.Info().Msg("Saving indexes...")
|
c.Logger.Info().Msg("Saving indexes...")
|
||||||
|
|
||||||
indexData, err := json.Marshal(ff.pastesIndex)
|
indexData, err := json.Marshal(ff.pastesIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error().Msgf("Failed to encode index data into JSON: %s", err.Error())
|
c.Logger.Error().Msgf("Failed to encode index data into JSON: %s", err.Error())
|
||||||
|
@ -27,7 +27,7 @@ package mysql
|
|||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -38,5 +38,6 @@ var (
|
|||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
d = &Database{}
|
d = &Database{}
|
||||||
|
|
||||||
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func InitialUp(tx *sql.Tx) error {
|
func InitialUp(tx *sql.Tx) error {
|
||||||
|
// nolint
|
||||||
_, err := tx.Exec("CREATE TABLE `pastes` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Paste ID', `title` text NOT NULL COMMENT 'Paste title', `data` longtext NOT NULL COMMENT 'Paste data', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Paste creation timestamp', `keep_for` int(4) NOT NULL DEFAULT 1 COMMENT 'Keep for integer. 0 - forever.', `keep_for_unit_type` int(1) NOT NULL DEFAULT 1 COMMENT 'Keep for unit type. 1 - minutes, 2 - hours, 3 - days, 4 - months.', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Pastes';")
|
_, err := tx.Exec("CREATE TABLE `pastes` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Paste ID', `title` text NOT NULL COMMENT 'Paste title', `data` longtext NOT NULL COMMENT 'Paste data', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Paste creation timestamp', `keep_for` int(4) NOT NULL DEFAULT 1 COMMENT 'Keep for integer. 0 - forever.', `keep_for_unit_type` int(1) NOT NULL DEFAULT 1 COMMENT 'Keep for unit type. 1 - minutes, 2 - hours, 3 - days, 4 - months.', PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Pastes';")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -69,7 +69,9 @@ func (db *Database) GetDatabaseConnection() *sql.DB {
|
|||||||
// GetPaste returns a single paste by ID.
|
// GetPaste returns a single paste by ID.
|
||||||
func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
p := &structs.Paste{}
|
p := &structs.Paste{}
|
||||||
|
|
||||||
err := db.db.Get(p, db.db.Rebind("SELECT * FROM `pastes` WHERE id=?"), pasteID)
|
err := db.db.Get(p, db.db.Rebind("SELECT * FROM `pastes` WHERE id=?"), pasteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -80,8 +82,11 @@ func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
|
|
||||||
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||||
db.check()
|
db.check()
|
||||||
var pastesRaw []structs.Paste
|
|
||||||
var pastes []structs.Paste
|
var (
|
||||||
|
pastesRaw []structs.Paste
|
||||||
|
pastes []structs.Paste
|
||||||
|
)
|
||||||
|
|
||||||
// Pagination.
|
// Pagination.
|
||||||
var startPagination = 0
|
var startPagination = 0
|
||||||
@ -105,8 +110,12 @@ func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
|||||||
|
|
||||||
func (db *Database) GetPastesPages() int {
|
func (db *Database) GetPastesPages() int {
|
||||||
db.check()
|
db.check()
|
||||||
var pastesRaw []structs.Paste
|
|
||||||
var pastes []structs.Paste
|
var (
|
||||||
|
pastesRaw []structs.Paste
|
||||||
|
pastes []structs.Paste
|
||||||
|
)
|
||||||
|
|
||||||
err := db.db.Get(&pastesRaw, "SELECT * FROM `pastes` WHERE private != true")
|
err := db.db.Get(&pastesRaw, "SELECT * FROM `pastes` WHERE private != true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 1
|
return 1
|
||||||
@ -155,6 +164,7 @@ func (db *Database) Initialize() {
|
|||||||
_ = dbConn.MustExec("SET @@session.time_zone='+00:00';")
|
_ = dbConn.MustExec("SET @@session.time_zone='+00:00';")
|
||||||
|
|
||||||
c.Logger.Info().Msg("Database connection established")
|
c.Logger.Info().Msg("Database connection established")
|
||||||
|
|
||||||
db.db = dbConn
|
db.db = dbConn
|
||||||
|
|
||||||
// Perform migrations.
|
// Perform migrations.
|
||||||
@ -164,6 +174,7 @@ func (db *Database) Initialize() {
|
|||||||
|
|
||||||
func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
result, err := db.db.NamedExec("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)", p)
|
result, err := db.db.NamedExec("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)", p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -27,7 +27,7 @@ package postgresql
|
|||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -38,5 +38,6 @@ var (
|
|||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
d = &Database{}
|
d = &Database{}
|
||||||
|
|
||||||
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
c.Database.RegisterDialect(dialectinterface.Interface(Handler{}))
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
|
|
||||||
// other
|
// other
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
// postgresql adapter
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +71,9 @@ func (db *Database) GetDatabaseConnection() *sql.DB {
|
|||||||
// GetPaste returns a single paste by ID.
|
// GetPaste returns a single paste by ID.
|
||||||
func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
||||||
db.check()
|
db.check()
|
||||||
|
|
||||||
p := &structs.Paste{}
|
p := &structs.Paste{}
|
||||||
|
|
||||||
err := db.db.Get(p, db.db.Rebind("SELECT * FROM pastes WHERE id=$1"), pasteID)
|
err := db.db.Get(p, db.db.Rebind("SELECT * FROM pastes WHERE id=$1"), pasteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -88,8 +91,11 @@ func (db *Database) GetPaste(pasteID int) (*structs.Paste, error) {
|
|||||||
|
|
||||||
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
||||||
db.check()
|
db.check()
|
||||||
var pastesRaw []structs.Paste
|
|
||||||
var pastes []structs.Paste
|
var (
|
||||||
|
pastesRaw []structs.Paste
|
||||||
|
pastes []structs.Paste
|
||||||
|
)
|
||||||
|
|
||||||
// Pagination.
|
// Pagination.
|
||||||
var startPagination = 0
|
var startPagination = 0
|
||||||
@ -119,8 +125,12 @@ func (db *Database) GetPagedPastes(page int) ([]structs.Paste, error) {
|
|||||||
|
|
||||||
func (db *Database) GetPastesPages() int {
|
func (db *Database) GetPastesPages() int {
|
||||||
db.check()
|
db.check()
|
||||||
var pastesRaw []structs.Paste
|
|
||||||
var pastes []structs.Paste
|
var (
|
||||||
|
pastesRaw []structs.Paste
|
||||||
|
pastes []structs.Paste
|
||||||
|
)
|
||||||
|
|
||||||
err := db.db.Get(&pastesRaw, "SELECT * FROM pastes WHERE private != true")
|
err := db.db.Get(&pastesRaw, "SELECT * FROM pastes WHERE private != true")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 1
|
return 1
|
||||||
@ -164,6 +174,7 @@ func (db *Database) Initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.Logger.Info().Msg("Database connection established")
|
c.Logger.Info().Msg("Database connection established")
|
||||||
|
|
||||||
db.db = dbConn
|
db.db = dbConn
|
||||||
|
|
||||||
// Perform migrations.
|
// Perform migrations.
|
||||||
@ -173,12 +184,14 @@ func (db *Database) Initialize() {
|
|||||||
|
|
||||||
func (db *Database) SavePaste(p *structs.Paste) (int64, error) {
|
func (db *Database) SavePaste(p *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")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var id int64
|
var id int64
|
||||||
|
|
||||||
err = stmt.Get(&id, p)
|
err = stmt.Get(&id, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -27,7 +27,7 @@ package database
|
|||||||
import (
|
import (
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/context"
|
"go.dev.pztrn.name/fastpastebin/internal/context"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/interface"
|
databaseinterface "go.dev.pztrn.name/fastpastebin/internal/database/interface"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -39,5 +39,6 @@ var (
|
|||||||
func New(cc *context.Context) {
|
func New(cc *context.Context) {
|
||||||
c = cc
|
c = cc
|
||||||
d = &Database{}
|
d = &Database{}
|
||||||
|
|
||||||
c.RegisterDatabaseInterface(databaseinterface.Interface(Handler{}))
|
c.RegisterDatabaseInterface(databaseinterface.Interface(Handler{}))
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
|
||||||
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
// local
|
// local
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
dialectinterface "go.dev.pztrn.name/fastpastebin/internal/database/dialects/interface"
|
||||||
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
"go.dev.pztrn.name/fastpastebin/internal/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// CreateHTML creates pagination HTML based on passed parameters.
|
// CreateHTML creates pagination HTML based on passed parameters.
|
||||||
|
// nolint
|
||||||
func CreateHTML(currentPage int, pages int, linksBase string) string {
|
func CreateHTML(currentPage int, pages int, linksBase string) string {
|
||||||
// Load templates.
|
// Load templates.
|
||||||
paginationHTMLRaw, err := static.ReadFile("pagination.html")
|
paginationHTMLRaw, err := static.ReadFile("pagination.html")
|
||||||
@ -38,12 +39,15 @@ func CreateHTML(currentPage int, pages int, linksBase string) string {
|
|||||||
paginationString = strings.Replace(string(paginationLinkCurrentRaw), "{pageNum}", strconv.Itoa(currentPage), -1)
|
paginationString = strings.Replace(string(paginationLinkCurrentRaw), "{pageNum}", strconv.Itoa(currentPage), -1)
|
||||||
} else {
|
} else {
|
||||||
paginationString = strings.Replace(string(paginationLinkRaw), "{pageNum}", "1", -1)
|
paginationString = strings.Replace(string(paginationLinkRaw), "{pageNum}", "1", -1)
|
||||||
paginationString = strings.Replace(string(paginationString), "{paginationLink}", linksBase+"1", -1)
|
paginationString = strings.Replace(paginationString, "{paginationLink}", linksBase+"1", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ellipsisStartAdded = false
|
var (
|
||||||
var ellipsisEndAdded = false
|
ellipsisStartAdded = false
|
||||||
i := 2
|
ellipsisEndAdded = false
|
||||||
|
i = 2
|
||||||
|
)
|
||||||
|
|
||||||
for i <= pages {
|
for i <= pages {
|
||||||
if pages > 5 {
|
if pages > 5 {
|
||||||
if currentPage-3 < i && currentPage+3 > i || i == pages {
|
if currentPage-3 < i && currentPage+3 > i || i == pages {
|
||||||
|
@ -36,22 +36,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PASTE_KEEP_FOREVER = 0
|
PasteKeepForever = 0
|
||||||
PASTE_KEEP_FOR_MINUTES = 1
|
PasteKeepForMinutes = 1
|
||||||
PASTE_KEEP_FOR_HOURS = 2
|
PasteKeepForHours = 2
|
||||||
PASTE_KEEP_FOR_DAYS = 3
|
PasteKeepForDays = 3
|
||||||
PASTE_KEEP_FOR_MONTHS = 4
|
PasteKeepForMonths = 4
|
||||||
|
|
||||||
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
PASTE_KEEPS_CORELLATION = map[string]int{
|
PasteKeepsCorellation = map[string]int{
|
||||||
"M": PASTE_KEEP_FOR_MINUTES,
|
"M": PasteKeepForMinutes,
|
||||||
"h": PASTE_KEEP_FOR_HOURS,
|
"h": PasteKeepForHours,
|
||||||
"d": PASTE_KEEP_FOR_DAYS,
|
"d": PasteKeepForDays,
|
||||||
"m": PASTE_KEEP_FOR_MONTHS,
|
"m": PasteKeepForMonths,
|
||||||
"forever": PASTE_KEEP_FOREVER,
|
"forever": PasteKeepForever,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -74,6 +74,7 @@ func (p *Paste) CreatePassword(password string) error {
|
|||||||
// Create salt - random string.
|
// Create salt - random string.
|
||||||
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
|
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
saltBytes := make([]byte, 64)
|
saltBytes := make([]byte, 64)
|
||||||
|
|
||||||
for i := range saltBytes {
|
for i := range saltBytes {
|
||||||
saltBytes[i] = charset[seededRand.Intn(len(charset))]
|
saltBytes[i] = charset[seededRand.Intn(len(charset))]
|
||||||
}
|
}
|
||||||
@ -86,6 +87,7 @@ func (p *Paste) CreatePassword(password string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordHashBytes := sha256.Sum256(passwordCrypted)
|
passwordHashBytes := sha256.Sum256(passwordCrypted)
|
||||||
p.Password = fmt.Sprintf("%x", passwordHashBytes)
|
p.Password = fmt.Sprintf("%x", passwordHashBytes)
|
||||||
|
|
||||||
@ -100,16 +102,17 @@ func (p *Paste) GenerateCryptedCookieValue() string {
|
|||||||
|
|
||||||
func (p *Paste) GetExpirationTime() time.Time {
|
func (p *Paste) GetExpirationTime() time.Time {
|
||||||
var expirationTime time.Time
|
var expirationTime time.Time
|
||||||
|
|
||||||
switch p.KeepForUnitType {
|
switch p.KeepForUnitType {
|
||||||
case PASTE_KEEP_FOREVER:
|
case PasteKeepForever:
|
||||||
expirationTime = time.Now().UTC().Add(time.Hour * 1)
|
expirationTime = time.Now().UTC().Add(time.Hour * 1)
|
||||||
case PASTE_KEEP_FOR_MINUTES:
|
case PasteKeepForMinutes:
|
||||||
expirationTime = p.CreatedAt.Add(time.Minute * time.Duration(p.KeepFor))
|
expirationTime = p.CreatedAt.Add(time.Minute * time.Duration(p.KeepFor))
|
||||||
case PASTE_KEEP_FOR_HOURS:
|
case PasteKeepForHours:
|
||||||
expirationTime = p.CreatedAt.Add(time.Hour * time.Duration(p.KeepFor))
|
expirationTime = p.CreatedAt.Add(time.Hour * time.Duration(p.KeepFor))
|
||||||
case PASTE_KEEP_FOR_DAYS:
|
case PasteKeepForDays:
|
||||||
expirationTime = p.CreatedAt.Add(time.Hour * 24 * time.Duration(p.KeepFor))
|
expirationTime = p.CreatedAt.Add(time.Hour * 24 * time.Duration(p.KeepFor))
|
||||||
case PASTE_KEEP_FOR_MONTHS:
|
case PasteKeepForMonths:
|
||||||
expirationTime = p.CreatedAt.Add(time.Hour * 24 * 30 * time.Duration(p.KeepFor))
|
expirationTime = p.CreatedAt.Add(time.Hour * 24 * 30 * time.Duration(p.KeepFor))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +124,7 @@ func (p *Paste) IsExpired() bool {
|
|||||||
curTime := time.Now().UTC()
|
curTime := time.Now().UTC()
|
||||||
expirationTime := p.GetExpirationTime()
|
expirationTime := p.GetExpirationTime()
|
||||||
|
|
||||||
if curTime.Sub(expirationTime).Seconds() > 0 {
|
return curTime.Sub(expirationTime).Seconds() > 0
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyPassword verifies that provided password is valid.
|
// VerifyPassword verifies that provided password is valid.
|
||||||
@ -135,12 +134,9 @@ func (p *Paste) VerifyPassword(password string) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordHashBytes := sha256.Sum256(passwordCrypted)
|
passwordHashBytes := sha256.Sum256(passwordCrypted)
|
||||||
providedPassword := fmt.Sprintf("%x", passwordHashBytes)
|
providedPassword := fmt.Sprintf("%x", passwordHashBytes)
|
||||||
|
|
||||||
if providedPassword == p.Password {
|
return providedPassword == p.Password
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user