92 lines
2.5 KiB
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
|
|
}
|