Skip to content

Commit 5057772

Browse files
authored
Merge pull request #5 from KunalKumar-1/auth
auth: added Authentication using JWT token
2 parents 02b29ed + d0a92c6 commit 5057772

File tree

6 files changed

+100
-9
lines changed

6 files changed

+100
-9
lines changed

cmd/api/auth.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package main
22

33
import (
44
"net/http"
5+
"time"
56

67
"github.com/gin-gonic/gin"
8+
"github.com/golang-jwt/jwt/v4"
79
"github.com/kunalkumar-1/Evently/internals/database"
810
"golang.org/x/crypto/bcrypt"
911
)
@@ -14,6 +16,15 @@ type registerRequest struct {
1416
Name string `json:"name" binding:"required,min=3,max=50"`
1517
}
1618

19+
type loginRequest struct {
20+
Email string `json:"email" binding:"required,email"`
21+
Password string `json:"password" binding:"required,min=8"`
22+
}
23+
24+
type loginResponse struct {
25+
Token string `json:"token"`
26+
}
27+
1728
func (app *application) registerUser(c *gin.Context) {
1829
var register registerRequest
1930

@@ -49,3 +60,51 @@ func (app *application) registerUser(c *gin.Context) {
4960

5061
c.JSON(http.StatusCreated, user)
5162
}
63+
64+
func (app *application) login(c *gin.Context) {
65+
var auth loginRequest
66+
if err := c.ShouldBindJSON(&auth); err != nil {
67+
c.JSON(http.StatusBadRequest, gin.H{
68+
"error": err.Error(),
69+
})
70+
return
71+
}
72+
73+
existingUser, err := app.models.Users.GetByEmail(auth.Email)
74+
if existingUser == nil {
75+
c.JSON(http.StatusUnauthorized, gin.H{
76+
"error": "Invlid Email or Password",
77+
})
78+
return
79+
}
80+
if err != nil {
81+
c.JSON(http.StatusUnauthorized, gin.H{
82+
"error": err.Error(),
83+
})
84+
return
85+
}
86+
err = bcrypt.CompareHashAndPassword([]byte(existingUser.Password), []byte(auth.Password))
87+
if err != nil {
88+
c.JSON(http.StatusUnauthorized, gin.H{
89+
"error": "Invalid Email or Password",
90+
})
91+
return
92+
}
93+
94+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
95+
"UserId": existingUser.Id,
96+
"expr": time.Now().Add(time.Hour * 72).Unix(),
97+
})
98+
99+
tokenString, err := token.SignedString([]byte(app.jwtSecret))
100+
if err != nil {
101+
c.JSON(http.StatusInternalServerError, gin.H{
102+
"error": "Error Generating token",
103+
})
104+
return
105+
}
106+
107+
c.JSON(http.StatusOK, loginResponse{
108+
Token: tokenString,
109+
})
110+
}

cmd/api/events.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ func (app *application) getAttendeesForEvent(c *gin.Context) {
228228
})
229229
return
230230
}
231-
users, err := app.models.Attendees.GetAttendeeByEvent(id)
231+
232+
events, err := app.models.Attendees.GetAttendeeByEvent(id) //get attendees for event
232233
if err != nil {
233234
c.JSON(http.StatusInternalServerError, gin.H{
234235
"error": "failed to retrieve Attendees for events",
235236
})
236237
return
237238
}
238-
c.JSON(http.StatusOK, users)
239+
240+
c.JSON(http.StatusOK, events)
239241
}
240242

241243
func (app *application) deleteAttendeeFromEvent(c *gin.Context) {

cmd/api/routes.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ func (app *application) routes() http.Handler {
1616
v1.GET("/events/:id", app.getEvent) // get event by id
1717
v1.PUT("/events/:id", app.updateEvent) // update event by id
1818
v1.DELETE("/events/:id", app.deleteEvent) //delete the event by id
19-
v1.GET("/events/:id/attendees/:userId", app.getAttendeesForEvent) // get attendee to event
20-
v1.POST("/events/:id/attendees/:userId", app.addAttendeeToEvent) // add attendee to event
19+
v1.POST("/events/:id/attendees/:userId", app.addAttendeeToEvent) // get attendee to event
20+
v1.GET("/events/:id/attendees/", app.getAttendeesForEvent) // add attendee to event
2121
v1.DELETE("/events/:id/attendees/:userId", app.deleteAttendeeFromEvent) //delete attendee from event
22-
v1.GET("/events/:id/attendees", app.getEventsByAttendee) //get attendees for event
22+
v1.GET("/attendees/:id/events", app.getEventsByAttendee) //get attendees for event
23+
v1.POST("/auth/register", app.registerUser) // register user
24+
v1.POST("/auth/login", app.login)
2325

24-
v1.POST("/auth/register", app.registerUser) // register user
2526
}
2627

2728
return r

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ require (
3838

3939
require (
4040
github.com/gin-gonic/gin v1.10.1
41+
github.com/golang-jwt/jwt/v4 v4.5.2
4142
github.com/hashicorp/errwrap v1.1.0 // indirect
4243
github.com/hashicorp/go-multierror v1.1.1 // indirect
4344
github.com/joho/godotenv v1.5.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
2525
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
2626
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
2727
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
28+
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
29+
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
2830
github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs=
2931
github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY=
3032
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=

internals/database/users.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ func (u *UserModel) Insert(user *User) error {
2727

2828
}
2929

30-
func (u *UserModel) Get(id int) (*User, error) {
30+
func (u *UserModel) getUser(query string, args ...interface{}) (*User, error) {
3131
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
3232
defer cancel()
3333

34-
query := `SELECT * FROM users WHERE id = $1`
3534
var user User
36-
err := u.Db.QueryRowContext(ctx, query, id).Scan(&user.Id, &user.Name, &user.Email, &user.Password)
35+
err := u.Db.QueryRowContext(ctx, query, args...).Scan(&user.Id, &user.Name, &user.Email, &user.Password)
3736
if err != nil {
3837
if err == sql.ErrNoRows {
3938
return nil, nil
@@ -42,3 +41,30 @@ func (u *UserModel) Get(id int) (*User, error) {
4241
}
4342
return &user, nil
4443
}
44+
45+
func (u *UserModel) Get(id int) (*User, error) {
46+
query := `SELECT * FROM users WHERE id = $1`
47+
return u.getUser(query, id)
48+
}
49+
50+
func (u *UserModel) GetByEmail(email string) (*User, error) {
51+
query := `SELECT * FROM users WHERE email = $1`
52+
return u.getUser(query, email)
53+
}
54+
55+
// func (u *UserModel) GetByEmail(email string) (*User, error) {
56+
// ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
57+
// defer cancel()
58+
59+
// query := `SELECT * FROM users WHERE email = $1`
60+
61+
// var user User
62+
// err := u.Db.QueryRowContext(ctx, query, email).Scan(&user.Id, &user.Name, &user.Email, &user.Password)
63+
// if err != nil {
64+
// if err == sql.ErrNoRows {
65+
// return nil, nil
66+
// }
67+
// return nil, err
68+
// }
69+
// return &user, nil
70+
// }

0 commit comments

Comments
 (0)