feat: add register event

This commit is contained in:
Lakhan Samani 2022-07-11 10:42:42 +05:30
parent e91a819067
commit bbb064b939
14 changed files with 173 additions and 34 deletions

View File

@ -80,6 +80,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
existingUser, err := db.Provider.GetUserByEmail(ctx, user.Email) existingUser, err := db.Provider.GetUserByEmail(ctx, user.Email)
log := log.WithField("user", user.Email) log := log.WithField("user", user.Email)
isSignUp := false
if err != nil { if err != nil {
isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp) isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
@ -121,6 +122,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
now := time.Now().Unix() now := time.Now().Unix()
user.EmailVerifiedAt = &now user.EmailVerifiedAt = &now
user, _ = db.Provider.AddUser(ctx, user) user, _ = db.Provider.AddUser(ctx, user)
isSignUp = true
} else { } else {
user = existingUser user = existingUser
if user.RevokedTimestamp != nil { if user.RevokedTimestamp != nil {
@ -215,11 +217,18 @@ func OAuthCallbackHandler() gin.HandlerFunc {
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
} }
go db.Provider.AddSession(ctx, models.Session{ go func() {
UserID: user.ID, if isSignUp {
UserAgent: utils.GetUserAgent(ctx.Request), utils.RegisterEvent(ctx, constants.EnvKeyDisableSignUp, provider, user)
IP: utils.GetIP(ctx.Request), } else {
}) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
}
db.Provider.AddSession(ctx, models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(ctx.Request),
IP: utils.GetIP(ctx.Request),
})
}()
if strings.Contains(redirectURL, "?") { if strings.Contains(redirectURL, "?") {
redirectURL = redirectURL + "&" + params redirectURL = redirectURL + "&" + params
} else { } else {

View File

@ -66,10 +66,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
return return
} }
isSignUp := false
// update email_verified_at in users table // update email_verified_at in users table
if user.EmailVerifiedAt == nil { if user.EmailVerifiedAt == nil {
now := time.Now().Unix() now := time.Now().Unix()
user.EmailVerifiedAt = &now user.EmailVerifiedAt = &now
isSignUp = true
db.Provider.UpdateUser(c, user) db.Provider.UpdateUser(c, user)
} }
// delete from verification table // delete from verification table
@ -131,11 +133,19 @@ func VerifyEmailHandler() gin.HandlerFunc {
redirectURL = redirectURL + "?" + strings.TrimPrefix(params, "&") redirectURL = redirectURL + "?" + strings.TrimPrefix(params, "&")
} }
go db.Provider.AddSession(c, models.Session{ go func() {
UserID: user.ID, if isSignUp {
UserAgent: utils.GetUserAgent(c.Request), utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user)
IP: utils.GetIP(c.Request), } else {
}) utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
}
db.Provider.AddSession(c, models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(c.Request),
IP: utils.GetIP(c.Request),
})
}()
c.Redirect(http.StatusTemporaryRedirect, redirectURL) c.Redirect(http.StatusTemporaryRedirect, redirectURL)
} }

View File

@ -126,11 +126,14 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
} }
go db.Provider.AddSession(ctx, models.Session{ go func() {
UserID: user.ID, utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
UserAgent: utils.GetUserAgent(gc.Request), db.Provider.AddSession(ctx, models.Session{
IP: utils.GetIP(gc.Request), UserID: user.ID,
}) UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
})
}()
return res, nil return res, nil
} }

View File

@ -100,6 +100,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
user.Roles = strings.Join(inputRoles, ",") user.Roles = strings.Join(inputRoles, ",")
user, _ = db.Provider.AddUser(ctx, user) user, _ = db.Provider.AddUser(ctx, user)
go utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMagicLinkLogin, user)
} else { } else {
user = existingUser user = existingUser
// There multiple scenarios with roles here in magic link login // There multiple scenarios with roles here in magic link login

View File

@ -207,7 +207,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
} }
// exec it as go routin so that we can reduce the api latency // exec it as go routin so that we can reduce the api latency
go email.SendVerificationMail(params.Email, verificationToken, hostname) go func() {
email.SendVerificationMail(params.Email, verificationToken, hostname)
utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
}()
res = &model.AuthResponse{ res = &model.AuthResponse{
Message: `Verification email has been sent. Please check your inbox`, Message: `Verification email has been sent. Please check your inbox`,
@ -225,12 +228,6 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
return res, err return res, err
} }
go db.Provider.AddSession(ctx, models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
})
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
if expiresIn <= 0 { if expiresIn <= 0 {
expiresIn = 1 expiresIn = 1
@ -252,6 +249,15 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
} }
go func() {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
db.Provider.AddSession(ctx, models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
})
}()
} }
return res, nil return res, nil

View File

@ -49,7 +49,9 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
EndPoint: utils.StringValue(webhook.Endpoint), EndPoint: utils.StringValue(webhook.Endpoint),
Enabled: utils.BoolValue(webhook.Enabled), Enabled: utils.BoolValue(webhook.Enabled),
Headers: headersString, Headers: headersString,
CreatedAt: *webhook.CreatedAt,
} }
if webhookDetails.EventName != utils.StringValue(params.EventName) { if webhookDetails.EventName != utils.StringValue(params.EventName) {
if isValid := validators.IsValidWebhookEventName(utils.StringValue(params.EventName)); !isValid { if isValid := validators.IsValidWebhookEventName(utils.StringValue(params.EventName)); !isValid {
log.Debug("invalid event name: ", utils.StringValue(params.EventName)) log.Debug("invalid event name: ", utils.StringValue(params.EventName))

View File

@ -58,13 +58,17 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
return res, err return res, err
} }
// update email_verified_at in users table isSignUp := false
now := time.Now().Unix() if user.EmailVerifiedAt == nil {
user.EmailVerifiedAt = &now isSignUp = true
user, err = db.Provider.UpdateUser(ctx, user) // update email_verified_at in users table
if err != nil { now := time.Now().Unix()
log.Debug("Failed to update user: ", err) user.EmailVerifiedAt = &now
return res, err user, err = db.Provider.UpdateUser(ctx, user)
if err != nil {
log.Debug("Failed to update user: ", err)
return res, err
}
} }
// delete from verification table // delete from verification table
err = db.Provider.DeleteVerificationRequest(gc, verificationRequest) err = db.Provider.DeleteVerificationRequest(gc, verificationRequest)
@ -86,12 +90,19 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
return res, err return res, err
} }
go db.Provider.AddSession(ctx, models.Session{ go func() {
UserID: user.ID, if isSignUp {
UserAgent: utils.GetUserAgent(gc.Request), utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
IP: utils.GetIP(gc.Request), } else {
}) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
}
db.Provider.AddSession(ctx, models.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request),
IP: utils.GetIP(gc.Request),
})
}()
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
if expiresIn <= 0 { if expiresIn <= 0 {
expiresIn = 1 expiresIn = 1

View File

@ -0,0 +1 @@
package test

View File

@ -0,0 +1 @@
package test

View File

@ -0,0 +1 @@
package test

View File

@ -0,0 +1 @@
package test

View File

@ -0,0 +1 @@
package test

View File

@ -0,0 +1 @@
package test

View File

@ -1 +1,92 @@
package utils package utils
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
"time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models"
log "github.com/sirupsen/logrus"
)
func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error {
webhook, err := db.Provider.GetWebhookByEventName(ctx, eventName)
if err != nil {
return err
}
userBytes, err := json.Marshal(user)
if err != nil {
log.Debug("error marshalling user obj: ", err)
return err
}
userMap := map[string]interface{}{}
err = json.Unmarshal(userBytes, &userMap)
if err != nil {
log.Debug("error un-marshalling user obj: ", err)
return err
}
reqBody := map[string]interface{}{
"event_name": eventName,
"user": userMap,
}
if eventName == constants.UserLoginWebhookEvent || eventName == constants.UserSignUpWebhookEvent {
reqBody["auth_recipe"] = authRecipe
}
requestBody, err := json.Marshal(reqBody)
if err != nil {
log.Debug("error marshalling requestBody obj: ", err)
return err
}
requestBytesBuffer := bytes.NewBuffer(requestBody)
req, err := http.NewRequest("POST", StringValue(webhook.Endpoint), requestBytesBuffer)
if err != nil {
log.Debug("error creating webhook post request: ", err)
return err
}
req.Header.Set("Content-Type", "application/json")
if webhook.Headers != nil {
for key, val := range webhook.Headers {
req.Header.Set(key, val.(string))
}
}
client := &http.Client{Timeout: time.Second * 30}
resp, err := client.Do(req)
if err != nil {
log.Debug("error making request: ", err)
return err
}
defer resp.Body.Close()
responseBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Debug("error reading response: ", err)
return err
}
statusCode := int64(resp.StatusCode)
_, err = db.Provider.AddWebhookLog(ctx, models.WebhookLog{
HttpStatus: statusCode,
Request: string(requestBytesBuffer.Bytes()),
Response: string(responseBytes),
WebhookID: webhook.ID,
})
if err != nil {
log.Debug("failed to add webhook log: ", err)
return err
}
return nil
}