The backend for the project formerly known as signet, now known as beignet.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

77 řádky
1.9 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "time"
  6. "github.com/golang-jwt/jwt/v4"
  7. "github.com/imosed/signet/auth"
  8. . "github.com/imosed/signet/data"
  9. "github.com/rs/zerolog/log"
  10. "github.com/spf13/viper"
  11. )
  12. type LoginResponse struct {
  13. Token *string `json:"token"`
  14. LastLogin *time.Time `json:"lastLogin"`
  15. }
  16. func Login(w http.ResponseWriter, r *http.Request) {
  17. var req AuthenticationRequest
  18. err := json.NewDecoder(r.Body).Decode(&req)
  19. if err != nil {
  20. log.Error().Err(err).Msg("Failed to decode body in login attempt")
  21. return
  22. }
  23. var userData User
  24. var loginTime = time.Now()
  25. var resp LoginResponse
  26. Db.Table("users").Select("id, password, privileges, last_login").
  27. Where("username = ?", req.Username).First(&userData)
  28. var passwordMatches bool
  29. passwordMatches, err = ComparePasswordAndHash(req.Password, userData.Password)
  30. if err != nil {
  31. log.Error().Err(err).Msg("Could not compare password to hash in login attempt")
  32. return
  33. }
  34. if !passwordMatches {
  35. err = json.NewEncoder(w).Encode(resp)
  36. if err != nil {
  37. log.Error().Err(err).Msg("Failed to deliver failed login attempt response")
  38. }
  39. return
  40. }
  41. token := jwt.NewWithClaims(jwt.SigningMethodHS256, &auth.Claims{
  42. ID: userData.ID,
  43. Username: req.Username,
  44. Privileges: userData.Privileges,
  45. RegisteredClaims: jwt.RegisteredClaims{
  46. ExpiresAt: jwt.NewNumericDate(loginTime.Add(10 * time.Hour)),
  47. },
  48. })
  49. secret := viper.GetString("app.secretKey")
  50. tokenString, err := token.SignedString([]byte(secret))
  51. if err != nil {
  52. log.Error().Err(err).Msg("Could not generate JWT token")
  53. return
  54. }
  55. resp.Token = &tokenString
  56. resp.LastLogin = userData.LastLogin
  57. if userData.LastLogin != nil {
  58. // need to set this after the user changes their password
  59. Db.Table("users").Where("id = ?", userData.ID).Update("last_login", loginTime)
  60. }
  61. err = json.NewEncoder(w).Encode(resp)
  62. if err != nil {
  63. log.Error().Err(err).Msg("Could not deliver response in Login call")
  64. }
  65. }