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.

117 lines
2.8 KiB

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