uni/WEB43-diary/internal/routes/helper.go

92 lines
2.5 KiB
Go

package routes
import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"github.com/a-h/templ"
"golang.org/x/crypto/sha3"
"gitea.zokki.net/zokki/uni/web43-diary/context"
"gitea.zokki.net/zokki/uni/web43-diary/internal/models"
"gitea.zokki.net/zokki/uni/web43-diary/web/templates"
)
func render(component func(*context.Context) templ.Component) http.HandlerFunc {
return func(writer http.ResponseWriter, req *http.Request) {
err := component(req.Context().(*context.Context)).Render(req.Context(), writer)
if httpErr, ok := err.(*models.HTTPError); ok {
log.Println(httpErr.String())
templates.Unauthorized(req.Context().(*context.Context)).Render(req.Context(), writer)
} else if err != nil {
log.Println(err)
http.Error(writer, fmt.Sprintf("can't render component: %s", err), http.StatusInternalServerError)
}
}
}
func errorJson(writer http.ResponseWriter, err *models.HTTPError) {
log.Println(err.String())
if err.Code != http.StatusInternalServerError {
header := writer.Header()
header.Del("Content-Length")
header.Set("Content-Type", "application/json; charset=utf-8")
writer.WriteHeader(err.Code)
json.NewEncoder(writer).Encode(err)
} else {
http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}
func hashPassword(password string, salt string) (string, string, *models.HTTPError) {
var saltBytes []byte
var err error
if salt == "" {
saltBytes = make([]byte, 32)
if _, err = io.ReadFull(rand.Reader, saltBytes); err != nil {
return "", "", &models.HTTPError{
Message: "unable to generate salt",
Code: http.StatusInternalServerError,
Data: err,
}
}
} else {
saltBytes, err = base64.StdEncoding.DecodeString(salt)
if err != nil {
return "", "", &models.HTTPError{
Message: "unable to decode provided salt",
Code: http.StatusInternalServerError,
Data: err,
}
}
}
hasher := sha3.New512()
_, err = hasher.Write(saltBytes)
if err != nil {
return "", "", &models.HTTPError{
Message: "unable to write salt to hasher",
Code: http.StatusInternalServerError,
Data: err,
}
}
_, err = hasher.Write([]byte(password))
if err != nil {
return "", "", &models.HTTPError{
Message: "unable to write password to hasher",
Code: http.StatusInternalServerError,
Data: err,
}
}
return base64.StdEncoding.EncodeToString(hasher.Sum(nil)), base64.StdEncoding.EncodeToString(saltBytes), nil
}