The backend for the project formerly known as signet, now known as beignet.
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.

64 line
1.4 KiB

  1. package endpoints
  2. import (
  3. "encoding/json"
  4. "github.com/golang-jwt/jwt/v4"
  5. "github.com/imosed/signet/auth"
  6. . "github.com/imosed/signet/data"
  7. "github.com/spf13/viper"
  8. "net/http"
  9. "time"
  10. )
  11. type LoginResponse struct {
  12. Token *string `json:"token"`
  13. }
  14. func Login(w http.ResponseWriter, r *http.Request) {
  15. var req AuthenticationRequest
  16. err := json.NewDecoder(r.Body).Decode(&req)
  17. if err != nil {
  18. panic("Could not decode body")
  19. }
  20. var userData struct {
  21. Id uint
  22. Password string
  23. Privileges uint
  24. }
  25. var resp LoginResponse
  26. Db.Table("users").Select("id, password, privileges").
  27. Where("username = ?", req.Username).First(&userData)
  28. var passwordMatches bool
  29. passwordMatches, err = ComparePasswordAndHash(req.Password, userData.Password)
  30. if err != nil {
  31. panic("Could not compare password to hash")
  32. }
  33. if !passwordMatches {
  34. resp.Token = nil
  35. err = json.NewEncoder(w).Encode(resp)
  36. return
  37. }
  38. token := jwt.NewWithClaims(jwt.SigningMethodHS256, &auth.Claims{
  39. Username: req.Username,
  40. Privileges: userData.Privileges,
  41. RegisteredClaims: jwt.RegisteredClaims{
  42. ExpiresAt: jwt.NewNumericDate(time.Now().Add(10 * time.Hour)),
  43. },
  44. })
  45. secret := viper.GetString("app.secretKey")
  46. tokenString, err := token.SignedString([]byte(secret))
  47. if err != nil {
  48. panic("Could not generate JWT token")
  49. }
  50. resp.Token = &tokenString
  51. err = json.NewEncoder(w).Encode(resp)
  52. if err != nil {
  53. panic("Could not deliver response")
  54. }
  55. }