Implement Totp authentication
This commit is contained in:
85
handler/user/totp/setup.go
Normal file
85
handler/user/totp/setup.go
Normal file
@ -0,0 +1,85 @@
|
||||
package userHandlerTotpSetup
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/fossyy/filekeeper/db"
|
||||
"github.com/fossyy/filekeeper/types"
|
||||
"github.com/fossyy/filekeeper/utils"
|
||||
userTotpSetupView "github.com/fossyy/filekeeper/view/user/totp"
|
||||
"github.com/skip2/go-qrcode"
|
||||
"github.com/xlzd/gotp"
|
||||
"image/png"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GET(w http.ResponseWriter, r *http.Request) {
|
||||
secret := gotp.RandomSecret(16)
|
||||
userSession := r.Context().Value("user").(types.User)
|
||||
totp := gotp.NewDefaultTOTP(secret)
|
||||
uri := totp.ProvisioningUri(userSession.Email, utils.Getenv("DOMAIN"))
|
||||
qr, err := qrcode.New(uri, qrcode.Medium)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to generate QR code: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
err = png.Encode(&buffer, qr.Image(256))
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to encode QR code to PNG: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
base64Str := base64.StdEncoding.EncodeToString(buffer.Bytes())
|
||||
|
||||
component := userTotpSetupView.Main("Totp setup page", base64Str, secret)
|
||||
err = component.Render(r.Context(), w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func POST(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
code := r.Form.Get("totp")
|
||||
secret := r.Form.Get("secret")
|
||||
totp := gotp.NewDefaultTOTP(secret)
|
||||
userSession := r.Context().Value("user").(types.User)
|
||||
fmt.Println(userSession)
|
||||
if totp.Verify(code, time.Now().Unix()) {
|
||||
err := db.DB.InitializeTotp(userSession.Email, secret)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "Authentication successful! Access granted.")
|
||||
return
|
||||
} else {
|
||||
uri := totp.ProvisioningUri(userSession.Email, utils.Getenv("DOMAIN"))
|
||||
qr, err := qrcode.New(uri, qrcode.Medium)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to generate QR code: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
err = png.Encode(&buffer, qr.Image(256))
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to encode QR code to PNG: %v", err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
base64Str := base64.StdEncoding.EncodeToString(buffer.Bytes())
|
||||
component := userTotpSetupView.Main("Totp setup page", base64Str, secret)
|
||||
err = component.Render(r.Context(), w)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user