Skip to content

Commit abc2991

Browse files
committed
2 parents 86d781b + b69d0b8 commit abc2991

20 files changed

+294
-45
lines changed

TODO.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Task List
22

3+
## Feature Multiple sessions
4+
5+
- Multiple sessions for users to login use hMset from redis for this
6+
user_id access_token1 long_live_token1
7+
user_id access_token2 long_live_token2
8+
39
# Feature roles
410

511
For the first version we will only support setting roles master list via env

server/db/db.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Manager interface {
2727
GetVerificationByEmail(email string) (VerificationRequest, error)
2828
DeleteUser(email string) error
2929
SaveRoles(roles []Role) error
30+
SaveSession(session Session) error
3031
}
3132

3233
type manager struct {
@@ -56,7 +57,7 @@ func InitDB() {
5657
if err != nil {
5758
log.Fatal("Failed to init db:", err)
5859
} else {
59-
db.AutoMigrate(&User{}, &VerificationRequest{}, &Role{})
60+
db.AutoMigrate(&User{}, &VerificationRequest{}, &Role{}, &Session{})
6061
}
6162

6263
Mgr = &manager{db: db}

server/db/session.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package db
2+
3+
import (
4+
"log"
5+
6+
"github.com/google/uuid"
7+
"gorm.io/gorm"
8+
"gorm.io/gorm/clause"
9+
)
10+
11+
type Session struct {
12+
ID uuid.UUID `gorm:"type:uuid;"`
13+
UserID uuid.UUID `gorm:"type:uuid;"`
14+
User User
15+
UserAgent string
16+
IP string
17+
CreatedAt int64 `gorm:"autoCreateTime"`
18+
UpdatedAt int64 `gorm:"autoUpdateTime"`
19+
}
20+
21+
func (r *Session) BeforeCreate(tx *gorm.DB) (err error) {
22+
r.ID = uuid.New()
23+
24+
return
25+
}
26+
27+
// SaveSession function to save user sessiosn
28+
func (mgr *manager) SaveSession(session Session) error {
29+
res := mgr.db.Clauses(
30+
clause.OnConflict{
31+
DoNothing: true,
32+
}).Create(&session)
33+
if res.Error != nil {
34+
log.Println(`Error saving session`, res.Error)
35+
return res.Error
36+
}
37+
38+
return nil
39+
}

server/db/verificationRequests.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func (mgr *manager) AddVerification(verification VerificationRequest) (Verificat
3030
Columns: []clause.Column{{Name: "email"}},
3131
DoUpdates: clause.AssignmentColumns([]string{"token", "identifier", "expires_at"}),
3232
}).Create(&verification)
33+
3334
if result.Error != nil {
3435
log.Println(`Error saving verification record`, result.Error)
3536
return verification, result.Error

server/handlers/oauthCallback.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
147147
provider := c.Param("oauth_provider")
148148
state := c.Request.FormValue("state")
149149

150-
sessionState := session.GetToken(state)
150+
sessionState := session.GetSocailLoginState(state)
151151
if sessionState == "" {
152152
c.JSON(400, gin.H{"error": "invalid oauth state"})
153153
}
154-
session.DeleteToken(sessionState)
154+
session.RemoveSocialLoginState(state)
155155
// contains random token, redirect url, role
156156
sessionSplit := strings.Split(state, "___")
157157

@@ -254,7 +254,16 @@ func OAuthCallbackHandler() gin.HandlerFunc {
254254

255255
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, inputRoles)
256256
utils.SetCookie(c, accessToken)
257-
session.SetToken(userIdStr, refreshToken)
257+
session.SetToken(userIdStr, accessToken, refreshToken)
258+
go func() {
259+
sessionData := db.Session{
260+
UserID: user.ID,
261+
UserAgent: utils.GetUserAgent(c.Request),
262+
IP: utils.GetIP(c.Request),
263+
}
264+
265+
db.Mgr.SaveSession(sessionData)
266+
}()
258267

259268
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
260269
}

server/handlers/oauthLogin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ func OAuthLoginHandler() gin.HandlerFunc {
5151

5252
switch provider {
5353
case enum.Google.String():
54-
session.SetToken(oauthStateString, enum.Google.String())
54+
session.SetSocailLoginState(oauthStateString, enum.Google.String())
5555
// during the init of OAuthProvider authorizer url might be empty
5656
oauth.OAuthProvider.GoogleConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/google"
5757
url := oauth.OAuthProvider.GoogleConfig.AuthCodeURL(oauthStateString)
5858
c.Redirect(http.StatusTemporaryRedirect, url)
5959
case enum.Github.String():
60-
session.SetToken(oauthStateString, enum.Github.String())
60+
session.SetSocailLoginState(oauthStateString, enum.Github.String())
6161
oauth.OAuthProvider.GithubConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/github"
6262
url := oauth.OAuthProvider.GithubConfig.AuthCodeURL(oauthStateString)
6363
c.Redirect(http.StatusTemporaryRedirect, url)
6464
case enum.Facebook.String():
65-
session.SetToken(oauthStateString, enum.Github.String())
65+
session.SetSocailLoginState(oauthStateString, enum.Facebook.String())
6666
oauth.OAuthProvider.FacebookConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/facebook"
6767
url := oauth.OAuthProvider.FacebookConfig.AuthCodeURL(oauthStateString)
6868
c.Redirect(http.StatusTemporaryRedirect, url)

server/handlers/verifyEmail.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,16 @@ func VerifyEmailHandler() gin.HandlerFunc {
5656

5757
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
5858

59-
session.SetToken(userIdStr, refreshToken)
59+
session.SetToken(userIdStr, accessToken, refreshToken)
60+
go func() {
61+
sessionData := db.Session{
62+
UserID: user.ID,
63+
UserAgent: utils.GetUserAgent(c.Request),
64+
IP: utils.GetIP(c.Request),
65+
}
66+
67+
db.Mgr.SaveSession(sessionData)
68+
}()
6069
utils.SetCookie(c, accessToken)
6170
c.Redirect(http.StatusTemporaryRedirect, claim.Host)
6271
}

server/resolvers/adminUpdateUser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
6060
return res, fmt.Errorf("user with this email address already exists")
6161
}
6262

63-
session.DeleteToken(fmt.Sprintf("%v", user.ID))
63+
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
6464
utils.DeleteCookie(gc)
6565

6666
user.Email = newEmail
@@ -100,7 +100,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
100100
rolesToSave = strings.Join(inputRoles, ",")
101101
}
102102

103-
session.DeleteToken(fmt.Sprintf("%v", user.ID))
103+
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
104104
utils.DeleteCookie(gc)
105105
}
106106

server/resolvers/deleteUser.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Respo
2727
return res, err
2828
}
2929

30-
session.DeleteToken(fmt.Sprintf("%x", user.ID))
30+
session.DeleteUserSession(fmt.Sprintf("%x", user.ID))
3131

3232
err = db.Mgr.DeleteUser(params.Email)
3333
if err != nil {

server/resolvers/login.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,16 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
6060

6161
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
6262

63-
session.SetToken(userIdStr, refreshToken)
63+
session.SetToken(userIdStr, accessToken, refreshToken)
64+
go func() {
65+
sessionData := db.Session{
66+
UserID: user.ID,
67+
UserAgent: utils.GetUserAgent(gc.Request),
68+
IP: utils.GetIP(gc.Request),
69+
}
70+
71+
db.Mgr.SaveSession(sessionData)
72+
}()
6473

6574
res = &model.AuthResponse{
6675
Message: `Logged in successfully`,

0 commit comments

Comments
 (0)