* added totp methods in db's providers
* adding totp in login method
This commit is contained in:
lemonScaletech
2023-08-31 19:50:44 +05:30
parent d9bfb74c98
commit 3f5283bf7f
16 changed files with 570 additions and 1 deletions

View File

@@ -0,0 +1,68 @@
package arangodb
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -0,0 +1,68 @@
package cassandradb
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -0,0 +1,68 @@
package couchbase
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -0,0 +1,68 @@
package dynamodb
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -0,0 +1,68 @@
package mongodb
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -0,0 +1,68 @@
package provider_template
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}

View File

@@ -2,7 +2,6 @@ package providers
import (
"context"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/graph/model"
)
@@ -88,4 +87,9 @@ type Provider interface {
GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error)
// DeleteOTP to delete otp
DeleteOTP(ctx context.Context, otp *models.OTP) error
// GenerateTotp to generate totp, store secret into db and returns base64 of QR code image
GenerateTotp(ctx context.Context, id string) (*string, error)
// ValidatePasscode validate user passcode with secret stored in our db
ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error)
}

View File

@@ -0,0 +1,68 @@
package sql
import (
"bytes"
"context"
"fmt"
"image/png"
"time"
"github.com/pquerna/otp/totp"
"github.com/authorizerdev/authorizer/server/crypto"
)
func (p *provider) GenerateTotp(ctx context.Context, id string) (*string, error) {
var buf bytes.Buffer
//get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return nil, fmt.Errorf("error while getting user details")
}
// generate totp, TOTP hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: user.Email,
})
if err != nil {
return nil, fmt.Errorf("error while genrating totp")
}
// get secret for user
secret := key.Secret()
//generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, fmt.Errorf("error while creating qr image for totp")
}
png.Encode(&buf, img)
encodedText := crypto.EncryptB64(buf.String())
// update user totp secret in db
user.UpdatedAt = time.Now().Unix()
user.TotpSecret = &secret
_, err = p.UpdateUser(ctx, user)
if err != nil {
return nil, fmt.Errorf("error while updating user's totp secret")
}
return &encodedText, nil
}
func (p *provider) ValidatePasscode(ctx context.Context, passcode string, id string) (bool, error) {
// get user details
user, err := p.GetUserByID(ctx, id)
if err != nil {
return false, fmt.Errorf("error while getting user details")
}
// validate passcode inputted by user
for {
status := totp.Validate(passcode, *user.TotpSecret)
if status {
return status, nil
}
}
}