Skip to content

Commit

Permalink
Merge pull request #359 from MussieT/feat/sms_confirmation
Browse files Browse the repository at this point in the history
Feat/sms confirmation
  • Loading branch information
lakhansamani authored Jun 13, 2023
2 parents 6c9b359 + 9fb0054 commit 7f47177
Show file tree
Hide file tree
Showing 26 changed files with 1,134 additions and 7 deletions.
9 changes: 9 additions & 0 deletions server/constants/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,13 @@ const (
// EnvKeyDefaultAuthorizeResponseMode key for env variable DEFAULT_AUTHORIZE_RESPONSE_MODE
// This env is used for setting default response mode in authorize handler
EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE"

// Phone verification setting
EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"

// Twilio env variables
EnvKeyTwilioAPIKey = "TWILIO_API_KEY"
EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM"
)
2 changes: 2 additions & 0 deletions server/db/models/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type CollectionList struct {
WebhookLog string
EmailTemplate string
OTP string
SMSVerificationRequest string
}

var (
Expand All @@ -25,5 +26,6 @@ var (
WebhookLog: Prefix + "webhook_logs",
EmailTemplate: Prefix + "email_templates",
OTP: Prefix + "otps",
SMSVerificationRequest: Prefix + "sms_verification_requests",
}
)
11 changes: 11 additions & 0 deletions server/db/models/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models

// SMS verification requests model for database
type SMSVerificationRequest struct {
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"`
Code string `json:"code" bson:"code" cql:"code" dynamo:"code"`
CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
}
23 changes: 23 additions & 0 deletions server/db/providers/arangodb/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package arangodb

import (
"context"

"github.com/authorizerdev/authorizer/server/db/models"

)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}

func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest

return &sms_verification_request, nil
}

func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}
23 changes: 23 additions & 0 deletions server/db/providers/cassandradb/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package cassandradb

import (
"context"

"github.com/authorizerdev/authorizer/server/db/models"

)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}

func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest

return &sms_verification_request, nil
}

func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}
23 changes: 23 additions & 0 deletions server/db/providers/couchbase/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package couchbase

import (
"context"

"github.com/authorizerdev/authorizer/server/db/models"

)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}

func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest

return &sms_verification_request, nil
}

func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}
23 changes: 23 additions & 0 deletions server/db/providers/dynamodb/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dynamodb

import (
"context"

"github.com/authorizerdev/authorizer/server/db/models"

)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}

func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest

return &sms_verification_request, nil
}

func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}
9 changes: 9 additions & 0 deletions server/db/providers/mongodb/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())

mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection())
smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection())
smsCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"phone_number": 1},
Options: options.Index().SetUnique(true).SetSparse(true),
},
}, options.CreateIndexes())

return &provider{
db: mongodb,
}, nil
Expand Down
69 changes: 69 additions & 0 deletions server/db/providers/mongodb/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package mongodb

import (
"context"
"time"

"github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
shouldCreate := false

if smsVerificationRequest == nil {
id := uuid.NewString()

smsVerificationRequest = &models.SMSVerificationRequest{
ID: id,
CreatedAt: time.Now().Unix(),
Code: smsRequest.Code,
PhoneNumber: smsRequest.PhoneNumber,
CodeExpiresAt: smsRequest.CodeExpiresAt,
}
shouldCreate = true
}

smsVerificationRequest.UpdatedAt = time.Now().Unix()
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())

var err error
if shouldCreate {
_, err = smsRequestCollection.InsertOne(ctx, smsVerificationRequest)
} else {
_, err = smsRequestCollection.UpdateOne(ctx, bson.M{"phone_number": bson.M{"$eq": smsRequest.PhoneNumber}}, bson.M{"$set": smsVerificationRequest}, options.MergeUpdateOptions())
}

if err != nil {
return nil, err
}

return smsVerificationRequest, nil
}

func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var smsVerificationRequest models.SMSVerificationRequest

smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
err := smsRequestCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&smsVerificationRequest)

if err != nil {
return nil, err
}

return &smsVerificationRequest, nil
}

func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
smsVerificationRequests := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
_, err := smsVerificationRequests.DeleteOne(nil, bson.M{"_id": smsRequest.ID}, options.Delete())
if err != nil {
return err
}

return nil
}
7 changes: 7 additions & 0 deletions server/db/providers/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,11 @@ type Provider interface {
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
// DeleteOTP to delete otp
DeleteOTP(ctx context.Context, otp *models.OTP) error

// Upsert SMS code request
UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error)
// Get sms code by phone number
GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error)
// Delete sms
DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error
}
2 changes: 1 addition & 1 deletion server/db/providers/sql/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func NewProvider() (*provider, error) {
logrus.Debug("Failed to drop phone number constraint:", err)
}

err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{})
err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{}, &models.SMSVerificationRequest{})
if err != nil {
return nil, err
}
Expand Down
51 changes: 51 additions & 0 deletions server/db/providers/sql/sms_verification_requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package sql

import (
"context"
"time"

"github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"gorm.io/gorm/clause"
)

// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
if smsRequest.ID == "" {
smsRequest.ID = uuid.New().String()
}

smsRequest.CreatedAt = time.Now().Unix()
smsRequest.UpdatedAt = time.Now().Unix()

res := p.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "phone_number"}},
DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at"}),
}).Create(smsRequest)
if res.Error != nil {
return nil, res.Error
}

return smsRequest, nil
}

// GetOTPByEmail to get otp for a given email address
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest

result := p.db.Where("phone_number = ?", phoneNumber).First(&sms_verification_request)
if result.Error != nil {
return nil, result.Error
}
return &sms_verification_request, nil
}

func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
result := p.db.Delete(&models.SMSVerificationRequest{
ID: smsRequest.ID,
})
if result.Error != nil {
return result.Error
}
return nil
}
43 changes: 42 additions & 1 deletion server/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,15 @@ func InitAllEnv() error {
osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles)
osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles)

// phone verification var
osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)

// twilio vars
osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID)
osTwilioSenderFrom := os.Getenv(constants.EnvKeyTwilioSenderFrom)

ienv, ok := envData[constants.EnvKeyEnv]
if !ok || ienv == "" {
envData[constants.EnvKeyEnv] = osEnv
Expand All @@ -136,6 +145,7 @@ func InitAllEnv() error {
if val, ok := envData[constants.EnvAwsRegion]; !ok || val == "" {
envData[constants.EnvAwsRegion] = osAwsRegion
}

if osAwsRegion != "" && envData[constants.EnvAwsRegion] != osAwsRegion {
envData[constants.EnvAwsRegion] = osAwsRegion
}
Expand Down Expand Up @@ -591,7 +601,7 @@ func InitAllEnv() error {
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin] {
envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
}
}
Expand Down Expand Up @@ -767,6 +777,37 @@ func InitAllEnv() error {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
}

if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret {
envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
}

if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey {
envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
}

if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
}

if osTwilioSenderFrom != "" && envData[constants.EnvKeyTwilioSenderFrom] != osTwilioSenderFrom {
envData[constants.EnvKeyTwilioSenderFrom] = osTwilioSenderFrom
}

if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
}

if osDisablePhoneVerification != "" {
boolValue, err := strconv.ParseBool(osDisablePhoneVerification)

if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisablePhoneVerification] {
envData[constants.EnvKeyDisablePhoneVerification] = boolValue
}
}

err = memorystore.Provider.UpdateEnvStore(envData)
if err != nil {
log.Debug("Error while updating env store: ", err)
Expand Down
2 changes: 1 addition & 1 deletion server/env/persist_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func PersistEnv() error {
envValue := strings.TrimSpace(os.Getenv(key))
if envValue != "" {
switch key {
case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure:
case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification:
if envValueBool, err := strconv.ParseBool(envValue); err == nil {
if value.(bool) != envValueBool {
storeData[key] = envValueBool
Expand Down
1 change: 1 addition & 0 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.0
github.com/twilio/twilio-go v1.7.2
github.com/vektah/gqlparser/v2 v2.5.1
go.mongodb.org/mongo-driver v1.8.1
golang.org/x/crypto v0.4.0
Expand Down
Loading

0 comments on commit 7f47177

Please sign in to comment.