softplayer-backend/internal/controllers/email.go

117 lines
2.6 KiB
Go
Raw Normal View History

2024-03-21 20:10:56 +00:00
package controllers
import (
"context"
"crypto/rand"
"errors"
"io"
"log"
"git.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/email"
"git.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/kube"
ctrl "sigs.k8s.io/controller-runtime"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
type EmailSvc struct {
Controller ctrl.Manager
Data EmailData
EmailConfig email.EmailConf
}
type EmailData struct {
UserID string
Code string
}
func (svc *EmailSvc) SendVerification(ctx context.Context) error {
client := svc.Controller.GetClient()
userns := &corev1.Namespace{}
if err := client.Get(ctx, types.NamespacedName{
Name: svc.Data.UserID,
}, userns); err != nil {
return err
}
userName, ok := userns.Labels["username"]
if !ok {
return errors.New("user not found")
}
accountData := &corev1.Secret{}
if err := client.Get(ctx, types.NamespacedName{
Namespace: "softplayer-accounts",
Name: userName,
}, accountData); err != nil {
return err
}
number := encodeToString(6)
email := string(accountData.Data["email"])
if err := svc.EmailConfig.SendEmail(email, number); err != nil {
return err
}
emailCode := corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "email-verification-code",
Namespace: svc.Data.UserID,
},
Data: map[string]string{
"code": number,
},
}
if err := kube.Create(ctx, client, &emailCode, true); err != nil {
return err
}
return nil
}
func (svc *EmailSvc) ConfirmVerification(ctx context.Context) error {
client := svc.Controller.GetClient()
emailCode := &corev1.ConfigMap{}
if err := client.Get(ctx, types.NamespacedName{
Namespace: svc.Data.UserID,
Name: "email-verification-code",
}, emailCode); err != nil {
return err
}
if svc.Data.Code != emailCode.Data["code"] {
log.Println(svc.Data.Code)
log.Println(emailCode.Data["code"])
return errors.New("wrong verification code")
}
if err := client.Delete(ctx, emailCode); err != nil {
return err
}
userns := &corev1.Namespace{}
if err := client.Get(ctx, types.NamespacedName{
Name: svc.Data.UserID,
}, userns); err != nil {
return err
}
userns.Labels["email-verified"] = "true"
if err := client.Update(ctx, userns); err != nil {
return err
}
return nil
}
func encodeToString(max int) string {
b := make([]byte, max)
n, err := io.ReadAtLeast(rand.Reader, b, max)
if n != max {
panic(err)
}
for i := 0; i < len(b); i++ {
b[i] = table[int(b[i])%len(table)]
}
return string(b)
}
var table = [...]byte{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}