Paperclip/pkg/internal/services/auth.go
2024-06-22 12:18:54 +08:00

84 lines
2.2 KiB
Go

package services
import (
"context"
"errors"
"fmt"
"reflect"
"time"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/database"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/gap"
"git.solsynth.dev/hydrogen/paperclip/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
"gorm.io/gorm"
)
func LinkAccount(userinfo *proto.Userinfo) (models.Account, error) {
var account models.Account
if userinfo == nil {
return account, fmt.Errorf("remote userinfo was not found")
}
if err := database.C.Where(&models.Account{
ExternalID: uint(userinfo.Id),
}).First(&account).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
account = models.Account{
Name: userinfo.Name,
Nick: userinfo.Nick,
Avatar: userinfo.Avatar,
Banner: userinfo.Banner,
Description: userinfo.GetDescription(),
EmailAddress: userinfo.Email,
PowerLevel: 0,
ExternalID: uint(userinfo.Id),
}
return account, database.C.Save(&account).Error
}
return account, err
}
prev := account
account.Name = userinfo.Name
account.Nick = userinfo.Nick
account.Avatar = userinfo.Avatar
account.Banner = userinfo.Banner
account.Description = userinfo.GetDescription()
account.EmailAddress = userinfo.Email
var err error
if !reflect.DeepEqual(prev, account) {
err = database.C.Save(&account).Error
}
return account, err
}
func Authenticate(atk, rtk string) (models.Account, string, string, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
var err error
var user models.Account
pc, err := gap.DiscoverPassport()
if err != nil {
return user, atk, rtk, fmt.Errorf("authenticate services was not available")
}
reply, err := proto.NewAuthClient(pc).Authenticate(ctx, &proto.AuthRequest{
AccessToken: atk,
RefreshToken: &rtk,
})
if err != nil {
return user, reply.GetAccessToken(), reply.GetRefreshToken(), err
} else if !reply.IsValid {
return user, reply.GetAccessToken(), reply.GetRefreshToken(), fmt.Errorf("invalid authorization context")
}
user, err = LinkAccount(reply.Userinfo)
return user, reply.GetAccessToken(), reply.GetRefreshToken(), err
}