package Auth
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.tovijaeschke.xyz/tovi/Envelope/Backend/Database"
|
|
"git.tovijaeschke.xyz/tovi/Envelope/Backend/Models"
|
|
)
|
|
|
|
type credentials struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type loginResponse struct {
|
|
Status string `json:"status"`
|
|
Message string `json:"message"`
|
|
AsymmetricPublicKey string `json:"asymmetric_public_key"`
|
|
AsymmetricPrivateKey string `json:"asymmetric_private_key"`
|
|
UserID string `json:"user_id"`
|
|
Username string `json:"username"`
|
|
MessageExpiryDefault string `json:"message_expiry_default"`
|
|
}
|
|
|
|
func makeLoginResponse(w http.ResponseWriter, code int, message, pubKey, privKey string, user Models.User) {
|
|
var (
|
|
status = "error"
|
|
messageExpiryRaw driver.Value
|
|
messageExpiry string
|
|
returnJSON []byte
|
|
err error
|
|
)
|
|
if code >= 200 && code <= 300 {
|
|
status = "success"
|
|
}
|
|
|
|
messageExpiryRaw, _ = user.MessageExpiryDefault.Value()
|
|
messageExpiry, _ = messageExpiryRaw.(string)
|
|
|
|
returnJSON, err = json.MarshalIndent(loginResponse{
|
|
Status: status,
|
|
Message: message,
|
|
AsymmetricPublicKey: pubKey,
|
|
AsymmetricPrivateKey: privKey,
|
|
UserID: user.ID.String(),
|
|
Username: user.Username,
|
|
MessageExpiryDefault: messageExpiry,
|
|
}, "", " ")
|
|
if err != nil {
|
|
http.Error(w, "Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Return updated json
|
|
w.WriteHeader(code)
|
|
w.Write(returnJSON)
|
|
}
|
|
|
|
// Login logs the user into the system
|
|
func Login(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
creds credentials
|
|
userData Models.User
|
|
session Models.Session
|
|
expiresAt time.Time
|
|
err error
|
|
)
|
|
|
|
err = json.NewDecoder(r.Body).Decode(&creds)
|
|
if err != nil {
|
|
makeLoginResponse(w, http.StatusInternalServerError, "An error occurred", "", "", userData)
|
|
return
|
|
}
|
|
|
|
userData, err = Database.GetUserByUsername(creds.Username)
|
|
if err != nil {
|
|
makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
|
|
return
|
|
}
|
|
|
|
if !CheckPasswordHash(creds.Password, userData.Password) {
|
|
makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
|
|
return
|
|
}
|
|
|
|
// TODO: Revisit before production
|
|
expiresAt = time.Now().Add(12 * time.Hour)
|
|
|
|
session = Models.Session{
|
|
UserID: userData.ID,
|
|
Expiry: expiresAt,
|
|
}
|
|
|
|
err = Database.CreateSession(&session)
|
|
if err != nil {
|
|
makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
|
|
return
|
|
}
|
|
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "session_token",
|
|
Value: session.ID.String(),
|
|
Expires: expiresAt,
|
|
})
|
|
|
|
makeLoginResponse(
|
|
w,
|
|
http.StatusOK,
|
|
"Successfully logged in",
|
|
userData.AsymmetricPublicKey,
|
|
userData.AsymmetricPrivateKey,
|
|
userData,
|
|
)
|
|
}
|