Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.5 KiB

  1. package Auth
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "time"
  6. "git.tovijaeschke.xyz/tovi/Envelope/Backend/Database"
  7. "git.tovijaeschke.xyz/tovi/Envelope/Backend/Models"
  8. )
  9. type Credentials struct {
  10. Username string `json:"username"`
  11. Password string `json:"password"`
  12. }
  13. type loginResponse struct {
  14. Status string `json:"status"`
  15. Message string `json:"message"`
  16. AsymmetricPublicKey string `json:"asymmetric_public_key"`
  17. AsymmetricPrivateKey string `json:"asymmetric_private_key"`
  18. UserID string `json:"user_id"`
  19. Username string `json:"username"`
  20. }
  21. func makeLoginResponse(w http.ResponseWriter, code int, message, pubKey, privKey string, user Models.User) {
  22. var (
  23. status string = "error"
  24. returnJson []byte
  25. err error
  26. )
  27. if code > 200 && code < 300 {
  28. status = "success"
  29. }
  30. returnJson, err = json.MarshalIndent(loginResponse{
  31. Status: status,
  32. Message: message,
  33. AsymmetricPublicKey: pubKey,
  34. AsymmetricPrivateKey: privKey,
  35. UserID: user.ID.String(),
  36. Username: user.Username,
  37. }, "", " ")
  38. if err != nil {
  39. http.Error(w, "Error", http.StatusInternalServerError)
  40. w.WriteHeader(http.StatusInternalServerError)
  41. return
  42. }
  43. // Return updated json
  44. w.WriteHeader(code)
  45. w.Write(returnJson)
  46. }
  47. func Login(w http.ResponseWriter, r *http.Request) {
  48. var (
  49. creds Credentials
  50. userData Models.User
  51. session Models.Session
  52. expiresAt time.Time
  53. err error
  54. )
  55. err = json.NewDecoder(r.Body).Decode(&creds)
  56. if err != nil {
  57. makeLoginResponse(w, http.StatusInternalServerError, "An error occurred", "", "", userData)
  58. return
  59. }
  60. userData, err = Database.GetUserByUsername(creds.Username)
  61. if err != nil {
  62. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  63. return
  64. }
  65. if !CheckPasswordHash(creds.Password, userData.Password) {
  66. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  67. return
  68. }
  69. // TODO: Revisit before production
  70. expiresAt = time.Now().Add(12 * time.Hour)
  71. session = Models.Session{
  72. UserID: userData.ID,
  73. Expiry: expiresAt,
  74. }
  75. err = Database.CreateSession(&session)
  76. if err != nil {
  77. makeLoginResponse(w, http.StatusUnauthorized, "An error occurred", "", "", userData)
  78. return
  79. }
  80. http.SetCookie(w, &http.Cookie{
  81. Name: "session_token",
  82. Value: session.ID.String(),
  83. Expires: expiresAt,
  84. })
  85. makeLoginResponse(
  86. w,
  87. http.StatusOK,
  88. "Successfully logged in",
  89. userData.AsymmetricPublicKey,
  90. userData.AsymmetricPrivateKey,
  91. userData,
  92. )
  93. }