Compare commits

..

9 Commits

Author SHA1 Message Date
Lakhan Samani
e1951bfbe0 fix: restore release 2021-10-29 21:47:28 +05:30
Lakhan Samani
1299ec5f9c fix: enable win release 2021-10-29 21:43:38 +05:30
Lakhan Samani
bc53974d2a fix: use otto instead of v8go 2021-10-29 21:41:47 +05:30
Lakhan Samani
3ed5426467 chore: fix env for release 2021-10-28 07:46:56 +05:30
Lakhan Samani
29251c8c20 fix: use inbuilt actions 2021-10-28 07:41:49 +05:30
Lakhan Samani
08b1f97ccb chore: fix docker build 2021-10-28 07:17:44 +05:30
Lakhan Samani
abc2991e1c Merge branch 'main' of https://github.com/authorizerdev/authorizer 2021-10-27 23:16:15 +05:30
Lakhan Samani
b69d0b8e23 Feat/multiple session (#64)
* fix: disable windows build

* feat: add ability to handle multiple sessions
2021-10-27 23:15:38 +05:30
Lakhan Samani
86d781b210 fix: disable windows build 2021-10-27 12:10:44 +05:30
25 changed files with 310 additions and 72 deletions

View File

@@ -7,7 +7,7 @@ ARG VERSION="latest"
ENV VERSION="$VERSION"
RUN echo "$VERSION"
RUN apk add build-base &&\
RUN apk add build-base nodejs &&\
make clean && make && \
chmod 777 build/server

View File

@@ -95,13 +95,12 @@ binaries are baked with required deployment files and bundled. You can download
- Mac OSX
- Linux
- Windows
### Step 1: Download and unzip bundle
- Download the Bundle for the specific OS from the [release page](https://github.com/authorizerdev/authorizer/releases)
> Note: For windows, it includes `.zip` file. For Linux & MacOS, it includes `.tar.gz` file.
> Note: For windows, we recommend running using docker image to run authorizer.
- Unzip using following command
@@ -111,12 +110,6 @@ binaries are baked with required deployment files and bundled. You can download
tar -zxf AUTHORIZER_VERSION -c authorizer
```
- Windows
```sh
unzip AUTHORIZER_VERSION
```
- Change directory to `authorizer`
```sh
@@ -137,12 +130,6 @@ Required environment variables are pre-configured in `.env` file. But based on t
./build/server
```
- For windows
```sh
./build/server.exe
```
> Note: For mac users, you might have to give binary the permission to execute. Here is the command you can use to grant permission `xattr -d com.apple.quarantine build/server`
## Install instance on Heroku

View File

@@ -1,5 +1,11 @@
# Task List
## Feature Multiple sessions
- Multiple sessions for users to login use hMset from redis for this
user_id access_token1 long_live_token1
user_id access_token2 long_live_token2
# Feature roles
For the first version we will only support setting roles master list via env

View File

@@ -27,6 +27,7 @@ type Manager interface {
GetVerificationByEmail(email string) (VerificationRequest, error)
DeleteUser(email string) error
SaveRoles(roles []Role) error
SaveSession(session Session) error
}
type manager struct {
@@ -56,7 +57,7 @@ func InitDB() {
if err != nil {
log.Fatal("Failed to init db:", err)
} else {
db.AutoMigrate(&User{}, &VerificationRequest{}, &Role{})
db.AutoMigrate(&User{}, &VerificationRequest{}, &Role{}, &Session{})
}
Mgr = &manager{db: db}

39
server/db/session.go Normal file
View File

@@ -0,0 +1,39 @@
package db
import (
"log"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type Session struct {
ID uuid.UUID `gorm:"type:uuid;"`
UserID uuid.UUID `gorm:"type:uuid;"`
User User
UserAgent string
IP string
CreatedAt int64 `gorm:"autoCreateTime"`
UpdatedAt int64 `gorm:"autoUpdateTime"`
}
func (r *Session) BeforeCreate(tx *gorm.DB) (err error) {
r.ID = uuid.New()
return
}
// SaveSession function to save user sessiosn
func (mgr *manager) SaveSession(session Session) error {
res := mgr.db.Clauses(
clause.OnConflict{
DoNothing: true,
}).Create(&session)
if res.Error != nil {
log.Println(`Error saving session`, res.Error)
return res.Error
}
return nil
}

View File

@@ -30,6 +30,7 @@ func (mgr *manager) AddVerification(verification VerificationRequest) (Verificat
Columns: []clause.Column{{Name: "email"}},
DoUpdates: clause.AssignmentColumns([]string{"token", "identifier", "expires_at"}),
}).Create(&verification)
if result.Error != nil {
log.Println(`Error saving verification record`, result.Error)
return verification, result.Error

View File

@@ -16,6 +16,7 @@ require (
github.com/json-iterator/go v1.1.11 // indirect
github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mattn/go-sqlite3 v1.14.7 // indirect
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f // indirect
github.com/ugorji/go v1.2.6 // indirect
github.com/vektah/gqlparser/v2 v2.1.0
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
@@ -28,5 +29,4 @@ require (
gorm.io/driver/postgres v1.1.0
gorm.io/driver/sqlite v1.1.4
gorm.io/gorm v1.21.11
rogchap.com/v8go v0.6.0 // indirect
)

View File

@@ -556,6 +556,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/robertkrimen/otto v0.0.0-20211019175142-5b0d97091c6f h1:wOVoULFf7IVSJ9hl8wnQew/kCpchffRb7a81H9/IcS4=
github.com/robertkrimen/otto v0.0.0-20211019175142-5b0d97091c6f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM=
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=

View File

@@ -147,11 +147,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
provider := c.Param("oauth_provider")
state := c.Request.FormValue("state")
sessionState := session.GetToken(state)
sessionState := session.GetSocailLoginState(state)
if sessionState == "" {
c.JSON(400, gin.H{"error": "invalid oauth state"})
}
session.DeleteToken(sessionState)
session.RemoveSocialLoginState(state)
// contains random token, redirect url, role
sessionSplit := strings.Split(state, "___")
@@ -254,7 +254,16 @@ func OAuthCallbackHandler() gin.HandlerFunc {
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, inputRoles)
utils.SetCookie(c, accessToken)
session.SetToken(userIdStr, refreshToken)
session.SetToken(userIdStr, accessToken, refreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(c.Request),
IP: utils.GetIP(c.Request),
}
db.Mgr.SaveSession(sessionData)
}()
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
}

View File

@@ -51,18 +51,18 @@ func OAuthLoginHandler() gin.HandlerFunc {
switch provider {
case enum.Google.String():
session.SetToken(oauthStateString, enum.Google.String())
session.SetSocailLoginState(oauthStateString, enum.Google.String())
// during the init of OAuthProvider authorizer url might be empty
oauth.OAuthProvider.GoogleConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/google"
url := oauth.OAuthProvider.GoogleConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url)
case enum.Github.String():
session.SetToken(oauthStateString, enum.Github.String())
session.SetSocailLoginState(oauthStateString, enum.Github.String())
oauth.OAuthProvider.GithubConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/github"
url := oauth.OAuthProvider.GithubConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url)
case enum.Facebook.String():
session.SetToken(oauthStateString, enum.Github.String())
session.SetSocailLoginState(oauthStateString, enum.Facebook.String())
oauth.OAuthProvider.FacebookConfig.RedirectURL = constants.AUTHORIZER_URL + "/oauth_callback/facebook"
url := oauth.OAuthProvider.FacebookConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url)

View File

@@ -56,7 +56,16 @@ func VerifyEmailHandler() gin.HandlerFunc {
accessToken, _, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
session.SetToken(userIdStr, refreshToken)
session.SetToken(userIdStr, accessToken, refreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(c.Request),
IP: utils.GetIP(c.Request),
}
db.Mgr.SaveSession(sessionData)
}()
utils.SetCookie(c, accessToken)
c.Redirect(http.StatusTemporaryRedirect, claim.Host)
}

View File

@@ -60,7 +60,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
return res, fmt.Errorf("user with this email address already exists")
}
session.DeleteToken(fmt.Sprintf("%v", user.ID))
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
user.Email = newEmail
@@ -100,7 +100,7 @@ func AdminUpdateUser(ctx context.Context, params model.AdminUpdateUserInput) (*m
rolesToSave = strings.Join(inputRoles, ",")
}
session.DeleteToken(fmt.Sprintf("%v", user.ID))
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
}

View File

@@ -27,7 +27,7 @@ func DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Respo
return res, err
}
session.DeleteToken(fmt.Sprintf("%x", user.ID))
session.DeleteUserSession(fmt.Sprintf("%x", user.ID))
err = db.Mgr.DeleteUser(params.Email)
if err != nil {

View File

@@ -60,7 +60,16 @@ func Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, e
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
session.SetToken(userIdStr, refreshToken)
session.SetToken(userIdStr, accessToken, refreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
}
db.Mgr.SaveSession(sessionData)
}()
res = &model.AuthResponse{
Message: `Logged in successfully`,

View File

@@ -27,7 +27,7 @@ func Logout(ctx context.Context) (*model.Response, error) {
}
userId := fmt.Sprintf("%v", claim["id"])
session.DeleteToken(userId)
session.DeleteToken(userId, token)
res = &model.Response{
Message: "Logged out successfully",
}

View File

@@ -30,7 +30,7 @@ func Profile(ctx context.Context) (*model.User, error) {
userID := fmt.Sprintf("%v", claim["id"])
email := fmt.Sprintf("%v", claim["email"])
sessionToken := session.GetToken(userID)
sessionToken := session.GetToken(userID, token)
if sessionToken == "" {
return res, fmt.Errorf(`unauthorized`)

View File

@@ -127,7 +127,16 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse,
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
session.SetToken(userIdStr, refreshToken)
session.SetToken(userIdStr, accessToken, refreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
}
db.Mgr.SaveSession(sessionData)
}()
res = &model.AuthResponse{
Message: `Signed up successfully.`,
AccessToken: &accessToken,

View File

@@ -37,7 +37,7 @@ func Token(ctx context.Context, roles []string) (*model.AuthResponse, error) {
userIdStr := fmt.Sprintf("%v", user.ID)
sessionToken := session.GetToken(userIdStr)
sessionToken := session.GetToken(userIdStr, token)
if sessionToken == "" {
return res, fmt.Errorf(`unauthorized`)
@@ -63,7 +63,19 @@ func Token(ctx context.Context, roles []string) (*model.AuthResponse, error) {
if accessTokenErr != nil || expiresTimeObj.Sub(currentTimeObj).Minutes() <= 5 {
// if access token has expired and refresh/session token is valid
// generate new accessToken
currentRefreshToken := session.GetToken(userIdStr, token)
session.DeleteToken(userIdStr, token)
token, expiresAt, _ = utils.CreateAuthToken(user, enum.AccessToken, claimRoles)
session.SetToken(userIdStr, token, currentRefreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
}
db.Mgr.SaveSession(sessionData)
}()
}
utils.SetCookie(gc, token)

View File

@@ -33,7 +33,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
}
id := fmt.Sprintf("%v", claim["id"])
sessionToken := session.GetToken(id)
sessionToken := session.GetToken(id, token)
if sessionToken == "" {
return res, fmt.Errorf(`unauthorized`)
@@ -99,7 +99,7 @@ func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model
return res, fmt.Errorf("user with this email address already exists")
}
session.DeleteToken(fmt.Sprintf("%v", user.ID))
session.DeleteUserSession(fmt.Sprintf("%v", user.ID))
utils.DeleteCookie(gc)
user.Email = newEmail

View File

@@ -47,7 +47,16 @@ func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.Aut
accessToken, expiresAt, _ := utils.CreateAuthToken(user, enum.AccessToken, roles)
session.SetToken(userIdStr, refreshToken)
session.SetToken(userIdStr, accessToken, refreshToken)
go func() {
sessionData := db.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
}
db.Mgr.SaveSession(sessionData)
}()
res = &model.AuthResponse{
Message: `Email verified successfully.`,

View File

@@ -1,41 +1,88 @@
package session
import "sync"
import (
"log"
"sync"
)
type InMemoryStore struct {
mu sync.Mutex
store map[string]string
mu sync.Mutex
store map[string]map[string]string
socialLoginState map[string]string
}
func (c *InMemoryStore) AddToken(userId, token string) {
func (c *InMemoryStore) AddToken(userId, accessToken, refreshToken string) {
c.mu.Lock()
// delete sessions > 500 // not recommended for production
if len(c.store) >= 500 {
c.store = make(map[string]string)
c.store = map[string]map[string]string{}
}
c.store[userId] = token
// check if entry exists in map
_, exists := c.store[userId]
if exists {
tempMap := c.store[userId]
tempMap[accessToken] = refreshToken
c.store[userId] = tempMap
} else {
tempMap := map[string]string{
accessToken: refreshToken,
}
c.store[userId] = tempMap
}
log.Println(c.store)
c.mu.Unlock()
}
func (c *InMemoryStore) DeleteToken(userId string) {
func (c *InMemoryStore) DeleteUserSession(userId string) {
c.mu.Lock()
delete(c.store, userId)
c.mu.Unlock()
}
func (c *InMemoryStore) ClearStore() {
func (c *InMemoryStore) DeleteToken(userId, accessToken string) {
c.mu.Lock()
c.store = make(map[string]string)
delete(c.store[userId], accessToken)
c.mu.Unlock()
}
func (c *InMemoryStore) GetToken(userId string) string {
func (c *InMemoryStore) ClearStore() {
c.mu.Lock()
c.store = map[string]map[string]string{}
c.mu.Unlock()
}
func (c *InMemoryStore) GetToken(userId, accessToken string) string {
token := ""
c.mu.Lock()
if val, ok := c.store[userId]; ok {
token = val
if sessionMap, ok := c.store[userId]; ok {
if val, ok := sessionMap[accessToken]; ok {
token = val
}
}
c.mu.Unlock()
return token
}
func (c *InMemoryStore) SetSocialLoginState(key, state string) {
c.mu.Lock()
c.socialLoginState[key] = state
c.mu.Unlock()
}
func (c *InMemoryStore) GetSocialLoginState(key string) string {
state := ""
if stateVal, ok := c.socialLoginState[key]; ok {
state = stateVal
}
return state
}
func (c *InMemoryStore) RemoveSocialLoginState(key string) {
c.mu.Lock()
delete(c.socialLoginState, key)
c.mu.Unlock()
}

View File

@@ -2,6 +2,7 @@ package session
import (
"context"
"fmt"
"log"
"github.com/go-redis/redis/v8"
@@ -12,20 +13,29 @@ type RedisStore struct {
store *redis.Client
}
func (c *RedisStore) AddToken(userId, token string) {
err := c.store.Set(c.ctx, "authorizer_"+userId, token, 0).Err()
func (c *RedisStore) AddToken(userId, accessToken, refreshToken string) {
err := c.store.HMSet(c.ctx, "authorizer_"+userId, map[string]string{
accessToken: refreshToken,
}).Err()
if err != nil {
log.Fatalln("Error saving redis token:", err)
}
}
func (c *RedisStore) DeleteToken(userId string) {
func (c *RedisStore) DeleteUserSession(userId string) {
err := c.store.Del(c.ctx, "authorizer_"+userId).Err()
if err != nil {
log.Fatalln("Error deleting redis token:", err)
}
}
func (c *RedisStore) DeleteToken(userId, accessToken string) {
err := c.store.HDel(c.ctx, "authorizer_"+userId, accessToken).Err()
if err != nil {
log.Fatalln("Error deleting redis token:", err)
}
}
func (c *RedisStore) ClearStore() {
err := c.store.Del(c.ctx, "authorizer_*").Err()
if err != nil {
@@ -33,11 +43,38 @@ func (c *RedisStore) ClearStore() {
}
}
func (c *RedisStore) GetToken(userId string) string {
func (c *RedisStore) GetToken(userId, accessToken string) string {
token := ""
token, err := c.store.Get(c.ctx, "authorizer_"+userId).Result()
res, err := c.store.HMGet(c.ctx, "authorizer_"+userId, accessToken).Result()
if err != nil {
log.Println("Error getting token from redis store:", err)
}
if len(res) > 0 && res[0] != nil {
token = fmt.Sprintf("%v", res[0])
}
return token
}
func (c *RedisStore) SetSocialLoginState(key, state string) {
err := c.store.Set(c.ctx, key, state, 0).Err()
if err != nil {
log.Fatalln("Error saving redis token:", err)
}
}
func (c *RedisStore) GetSocialLoginState(key string) string {
state := ""
state, err := c.store.Get(c.ctx, key).Result()
if err != nil {
log.Println("Error getting token from redis store:", err)
}
return state
}
func (c *RedisStore) RemoveSocialLoginState(key string) {
err := c.store.Del(c.ctx, key).Err()
if err != nil {
log.Fatalln("Error deleting redis token:", err)
}
}

View File

@@ -15,30 +15,42 @@ type SessionStore struct {
var SessionStoreObj SessionStore
func SetToken(userId, token string) {
func SetToken(userId, accessToken, refreshToken string) {
// TODO: Set session information in db for all the sessions that gets generated
// it should async go function
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.AddToken(userId, token)
SessionStoreObj.RedisMemoryStoreObj.AddToken(userId, accessToken, refreshToken)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.AddToken(userId, token)
SessionStoreObj.InMemoryStoreObj.AddToken(userId, accessToken, refreshToken)
}
}
func DeleteToken(userId string) {
func DeleteToken(userId, accessToken string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.DeleteToken(userId)
SessionStoreObj.RedisMemoryStoreObj.DeleteToken(userId, accessToken)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.DeleteToken(userId)
SessionStoreObj.InMemoryStoreObj.DeleteToken(userId, accessToken)
}
}
func GetToken(userId string) string {
func DeleteUserSession(userId string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetToken(userId)
SessionStoreObj.RedisMemoryStoreObj.DeleteUserSession(userId)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetToken(userId)
SessionStoreObj.InMemoryStoreObj.DeleteUserSession(userId)
}
}
func GetToken(userId, accessToken string) string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetToken(userId, accessToken)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetToken(userId, accessToken)
}
return ""
@@ -53,6 +65,35 @@ func ClearStore() {
}
}
func SetSocailLoginState(key, state string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.SetSocialLoginState(key, state)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.SetSocialLoginState(key, state)
}
}
func GetSocailLoginState(key string) string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetSocialLoginState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetSocialLoginState(key)
}
return ""
}
func RemoveSocialLoginState(key string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.RemoveSocialLoginState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.RemoveSocialLoginState(key)
}
}
func InitSession() {
if constants.REDIS_URL != "" {
log.Println("Using redis store to save sessions")
@@ -75,7 +116,8 @@ func InitSession() {
} else {
log.Println("Using in memory store to save sessions")
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
store: make(map[string]string),
store: map[string]map[string]string{},
socialLoginState: map[string]string{},
}
}
}

View File

@@ -13,7 +13,7 @@ import (
"github.com/authorizerdev/authorizer/server/enum"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
v8 "rogchap.com/v8go"
"github.com/robertkrimen/otto"
)
func CreateAuthToken(user db.User, tokenType enum.TokenType, roles []string) (string, int64, error) {
@@ -50,25 +50,25 @@ func CreateAuthToken(user db.User, tokenType enum.TokenType, roles []string) (st
"signUpMethods": strings.Split(user.SignupMethod, ","),
}
ctx, _ := v8.NewContext()
vm := otto.New()
userBytes, _ := json.Marshal(userInfo)
claimBytes, _ := json.Marshal(customClaims)
ctx.RunScript(fmt.Sprintf(`
const user = %s;
const tokenPayload = %s;
const customFunction = %s;
const functionRes = JSON.stringify(customFunction(user, tokenPayload));
`, string(userBytes), string(claimBytes), accessTokenScript), "functionCall.js")
vm.Run(fmt.Sprintf(`
var user = %s;
var tokenPayload = %s;
var customFunction = %s;
var functionRes = JSON.stringify(customFunction(user, tokenPayload));
`, string(userBytes), string(claimBytes), accessTokenScript))
val, err := ctx.RunScript("functionRes", "functionRes.js")
val, err := vm.Get("functionRes")
if err != nil {
log.Println("=> err custom access token script:", err)
} else {
extraPayload := make(map[string]interface{})
err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
log.Println("extra:", extraPayload)
if err != nil {
log.Println("Error converting accessTokenScript response to map:", err)
} else {

View File

@@ -0,0 +1,19 @@
package utils
import "net/http"
func GetIP(r *http.Request) string {
IPAddress := r.Header.Get("X-Real-Ip")
if IPAddress == "" {
IPAddress = r.Header.Get("X-Forwarded-For")
}
if IPAddress == "" {
IPAddress = r.RemoteAddr
}
return IPAddress
}
func GetUserAgent(r *http.Request) string {
return r.UserAgent()
}