♻️ Refactored relation system
⬆️ Support new realm & relation api
This commit is contained in:
@ -2,23 +2,24 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
|
||||
exproto "git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func (v *Server) Authenticate(_ context.Context, in *exproto.AuthRequest) (*exproto.AuthReply, error) {
|
||||
func (v *Server) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto.AuthReply, error) {
|
||||
ctx, perms, atk, rtk, err := services.Authenticate(in.GetAccessToken(), in.GetRefreshToken(), 0)
|
||||
if err != nil {
|
||||
return &exproto.AuthReply{
|
||||
return &proto.AuthReply{
|
||||
IsValid: false,
|
||||
}, nil
|
||||
} else {
|
||||
user := ctx.Account
|
||||
rawPerms, _ := jsoniter.Marshal(perms)
|
||||
|
||||
userinfo := &exproto.UserInfo{
|
||||
userinfo := &proto.UserInfo{
|
||||
Id: uint64(user.ID),
|
||||
Name: user.Name,
|
||||
Nick: user.Nick,
|
||||
@ -33,9 +34,9 @@ func (v *Server) Authenticate(_ context.Context, in *exproto.AuthRequest) (*expr
|
||||
userinfo.Banner = *user.GetBanner()
|
||||
}
|
||||
|
||||
return &exproto.AuthReply{
|
||||
return &proto.AuthReply{
|
||||
IsValid: true,
|
||||
Info: &exproto.AuthInfo{
|
||||
Info: &proto.AuthInfo{
|
||||
NewAccessToken: &atk,
|
||||
NewRefreshToken: &rtk,
|
||||
Permissions: rawPerms,
|
||||
@ -46,7 +47,7 @@ func (v *Server) Authenticate(_ context.Context, in *exproto.AuthRequest) (*expr
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Server) EnsurePermGranted(_ context.Context, in *exproto.CheckPermRequest) (*exproto.CheckPermReply, error) {
|
||||
func (v *Server) EnsurePermGranted(_ context.Context, in *proto.CheckPermRequest) (*proto.CheckPermResponse, error) {
|
||||
claims, err := services.DecodeJwt(in.GetToken())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -65,7 +66,26 @@ func (v *Server) EnsurePermGranted(_ context.Context, in *exproto.CheckPermReque
|
||||
perms := services.FilterPermNodes(heldPerms, ctx.Ticket.Claims)
|
||||
valid := services.HasPermNode(perms, in.GetKey(), value)
|
||||
|
||||
return &exproto.CheckPermReply{
|
||||
return &proto.CheckPermResponse{
|
||||
IsValid: valid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) EnsureUserPermGranted(_ context.Context, in *proto.CheckUserPermRequest) (*proto.CheckUserPermResponse, error) {
|
||||
relation, err := services.GetRelationWithTwoNode(uint(in.GetUserId()), uint(in.GetOtherId()))
|
||||
if err != nil {
|
||||
return &proto.CheckUserPermResponse{
|
||||
IsValid: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
defaultPerm := relation.Status == models.RelationshipFriend
|
||||
|
||||
var value any
|
||||
_ = jsoniter.Unmarshal(in.GetValue(), &value)
|
||||
valid := services.HasPermNodeWithDefault(relation.PermNodes, in.GetKey(), value, defaultPerm)
|
||||
|
||||
return &proto.CheckUserPermResponse{
|
||||
IsValid: valid,
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (v *Server) ListFriendship(_ context.Context, request *proto.FriendshipLookupRequest) (*proto.ListFriendshipResponse, error) {
|
||||
account, err := services.GetAccount(uint(request.GetAccountId()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
friends, err := services.ListFriend(account, models.FriendshipStatus(request.GetStatus()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.ListFriendshipResponse{
|
||||
Data: lo.Map(friends, func(item models.AccountFriendship, index int) *proto.FriendshipResponse {
|
||||
return &proto.FriendshipResponse{
|
||||
AccountId: uint64(item.AccountID),
|
||||
RelatedId: uint64(item.RelatedID),
|
||||
Status: uint32(item.Status),
|
||||
}
|
||||
}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) GetFriendship(ctx context.Context, request *proto.FriendshipTwoSideLookupRequest) (*proto.FriendshipResponse, error) {
|
||||
friend, err := services.GetFriendWithTwoSides(uint(request.GetAccountId()), uint(request.GetRelatedId()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if friend.Status != models.FriendshipStatus(request.GetStatus()) {
|
||||
return nil, fmt.Errorf("status mismatch")
|
||||
}
|
||||
|
||||
return &proto.FriendshipResponse{
|
||||
AccountId: uint64(friend.AccountID),
|
||||
RelatedId: uint64(friend.RelatedID),
|
||||
Status: uint32(friend.Status),
|
||||
}, nil
|
||||
}
|
47
pkg/internal/grpc/notifier.go
Normal file
47
pkg/internal/grpc/notifier.go
Normal file
@ -0,0 +1,47 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
)
|
||||
|
||||
func (v *Server) NotifyUser(_ context.Context, in *proto.NotifyUserRequest) (*proto.NotifyResponse, error) {
|
||||
var err error
|
||||
var user models.Account
|
||||
if user, err = services.GetAccount(uint(in.GetUserId())); err != nil {
|
||||
return nil, fmt.Errorf("unable to get account: %v", err)
|
||||
}
|
||||
|
||||
var metadata map[string]any
|
||||
_ = jsoniter.Unmarshal(in.GetNotify().GetMetadata(), &metadata)
|
||||
|
||||
notification := models.Notification{
|
||||
Topic: in.GetNotify().GetTopic(),
|
||||
Title: in.GetNotify().GetTitle(),
|
||||
Subtitle: in.GetNotify().Subtitle,
|
||||
Body: in.GetNotify().GetBody(),
|
||||
Metadata: metadata,
|
||||
IsRealtime: in.GetNotify().GetIsRealtime(),
|
||||
IsForcePush: in.GetNotify().GetIsForcePush(),
|
||||
UserID: user.ID,
|
||||
}
|
||||
|
||||
if notification.IsRealtime {
|
||||
if err := services.PushNotification(notification); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := services.NewNotification(notification); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &proto.NotifyResponse{
|
||||
IsSuccess: true,
|
||||
}, nil
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (v *Server) NotifyUser(_ context.Context, in *proto.NotifyRequest) (*proto.NotifyReply, error) {
|
||||
client, err := services.GetThirdClientWithSecret(in.GetClientId(), in.GetClientSecret())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var user models.Account
|
||||
if user, err = services.GetAccount(uint(in.GetRecipientId())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var metadata map[string]any
|
||||
_ = jsoniter.Unmarshal(in.GetMetadata(), &metadata)
|
||||
|
||||
links := lo.Map(in.GetLinks(), func(item *proto.NotifyLink, index int) models.NotificationLink {
|
||||
return models.NotificationLink{
|
||||
Label: item.Label,
|
||||
Url: item.Url,
|
||||
}
|
||||
})
|
||||
|
||||
notification := models.Notification{
|
||||
Type: lo.Ternary(len(in.GetType()) > 0, in.GetType(), "common"),
|
||||
Subject: in.GetSubject(),
|
||||
Content: in.GetContent(),
|
||||
Metadata: metadata,
|
||||
Links: links,
|
||||
IsRealtime: in.GetIsRealtime(),
|
||||
IsForcePush: in.GetIsForcePush(),
|
||||
RecipientID: user.ID,
|
||||
SenderID: &client.ID,
|
||||
}
|
||||
|
||||
if in.GetIsRealtime() {
|
||||
if err := services.PushNotification(notification); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := services.NewNotification(notification); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &proto.NotifyReply{IsSent: true}, nil
|
||||
}
|
@ -3,23 +3,22 @@ package grpc
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
"github.com/samber/lo"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
func (v *Server) ListCommunityRealm(ctx context.Context, empty *emptypb.Empty) (*proto.ListRealmResponse, error) {
|
||||
func (v *Server) ListCommunityRealm(ctx context.Context, empty *proto.ListRealmRequest) (*proto.ListRealmResponse, error) {
|
||||
realms, err := services.ListCommunityRealm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.ListRealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
||||
return &proto.RealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||
return &proto.RealmInfo{
|
||||
Id: uint64(item.ID),
|
||||
Alias: item.Alias,
|
||||
Name: item.Name,
|
||||
@ -31,7 +30,7 @@ func (v *Server) ListCommunityRealm(ctx context.Context, empty *emptypb.Empty) (
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) ListAvailableRealm(ctx context.Context, request *proto.RealmLookupWithUserRequest) (*proto.ListRealmResponse, error) {
|
||||
func (v *Server) ListAvailableRealm(ctx context.Context, request *proto.LookupUserRealmRequest) (*proto.ListRealmResponse, error) {
|
||||
account, err := services.GetAccount(uint(request.GetUserId()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find target account: %v", err)
|
||||
@ -42,8 +41,8 @@ func (v *Server) ListAvailableRealm(ctx context.Context, request *proto.RealmLoo
|
||||
}
|
||||
|
||||
return &proto.ListRealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
||||
return &proto.RealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||
return &proto.RealmInfo{
|
||||
Id: uint64(item.ID),
|
||||
Alias: item.Alias,
|
||||
Name: item.Name,
|
||||
@ -55,7 +54,7 @@ func (v *Server) ListAvailableRealm(ctx context.Context, request *proto.RealmLoo
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) ListOwnedRealm(ctx context.Context, request *proto.RealmLookupWithUserRequest) (*proto.ListRealmResponse, error) {
|
||||
func (v *Server) ListOwnedRealm(ctx context.Context, request *proto.LookupUserRealmRequest) (*proto.ListRealmResponse, error) {
|
||||
account, err := services.GetAccount(uint(request.GetUserId()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find target account: %v", err)
|
||||
@ -66,8 +65,8 @@ func (v *Server) ListOwnedRealm(ctx context.Context, request *proto.RealmLookupW
|
||||
}
|
||||
|
||||
return &proto.ListRealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmResponse {
|
||||
return &proto.RealmResponse{
|
||||
Data: lo.Map(realms, func(item models.Realm, index int) *proto.RealmInfo {
|
||||
return &proto.RealmInfo{
|
||||
Id: uint64(item.ID),
|
||||
Alias: item.Alias,
|
||||
Name: item.Name,
|
||||
@ -79,7 +78,7 @@ func (v *Server) ListOwnedRealm(ctx context.Context, request *proto.RealmLookupW
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) GetRealm(ctx context.Context, request *proto.RealmLookupRequest) (*proto.RealmResponse, error) {
|
||||
func (v *Server) GetRealm(ctx context.Context, request *proto.LookupRealmRequest) (*proto.RealmInfo, error) {
|
||||
var realm models.Realm
|
||||
|
||||
tx := database.C.Model(&models.Realm{})
|
||||
@ -100,7 +99,7 @@ func (v *Server) GetRealm(ctx context.Context, request *proto.RealmLookupRequest
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.RealmResponse{
|
||||
return &proto.RealmInfo{
|
||||
Id: uint64(realm.ID),
|
||||
Alias: realm.Alias,
|
||||
Name: realm.Name,
|
||||
@ -122,8 +121,8 @@ func (v *Server) ListRealmMember(ctx context.Context, request *proto.RealmMember
|
||||
}
|
||||
|
||||
return &proto.ListRealmMemberResponse{
|
||||
Data: lo.Map(members, func(item models.RealmMember, index int) *proto.RealmMemberResponse {
|
||||
return &proto.RealmMemberResponse{
|
||||
Data: lo.Map(members, func(item models.RealmMember, index int) *proto.MemberInfo {
|
||||
return &proto.MemberInfo{
|
||||
RealmId: uint64(item.RealmID),
|
||||
UserId: uint64(item.AccountID),
|
||||
PowerLevel: int32(item.PowerLevel),
|
||||
@ -132,7 +131,7 @@ func (v *Server) ListRealmMember(ctx context.Context, request *proto.RealmMember
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) GetRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.RealmMemberResponse, error) {
|
||||
func (v *Server) GetRealmMember(ctx context.Context, request *proto.RealmMemberLookupRequest) (*proto.MemberInfo, error) {
|
||||
var member models.RealmMember
|
||||
tx := database.C.Where("realm_id = ?", request.GetRealmId())
|
||||
if request.UserId != nil {
|
||||
@ -143,9 +142,26 @@ func (v *Server) GetRealmMember(ctx context.Context, request *proto.RealmMemberL
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &proto.RealmMemberResponse{
|
||||
return &proto.MemberInfo{
|
||||
RealmId: uint64(member.RealmID),
|
||||
UserId: uint64(member.AccountID),
|
||||
PowerLevel: int32(member.PowerLevel),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *Server) CheckRealmMemberPerm(ctx context.Context, request *proto.CheckRealmPermRequest) (*proto.CheckRealmPermResponse, error) {
|
||||
var member models.RealmMember
|
||||
tx := database.C.
|
||||
Where("realm_id = ?", request.GetRealmId()).
|
||||
Where("account_id = ?", request.GetUserId())
|
||||
|
||||
if err := tx.First(&member).Error; err != nil {
|
||||
return &proto.CheckRealmPermResponse{
|
||||
IsSuccess: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &proto.CheckRealmPermResponse{
|
||||
IsSuccess: member.PowerLevel >= int(request.GetPowerLevel()),
|
||||
}, nil
|
||||
}
|
||||
|
@ -4,8 +4,7 @@ import (
|
||||
"google.golang.org/grpc/reflection"
|
||||
"net"
|
||||
|
||||
exproto "git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@ -13,10 +12,9 @@ import (
|
||||
import health "google.golang.org/grpc/health/grpc_health_v1"
|
||||
|
||||
type Server struct {
|
||||
exproto.UnimplementedAuthServer
|
||||
proto.UnimplementedNotifyServer
|
||||
proto.UnimplementedFriendshipsServer
|
||||
proto.UnimplementedRealmsServer
|
||||
proto.UnimplementedAuthServer
|
||||
proto.UnimplementedNotifierServer
|
||||
proto.UnimplementedRealmServer
|
||||
health.UnimplementedHealthServer
|
||||
|
||||
srv *grpc.Server
|
||||
@ -27,11 +25,10 @@ func NewServer() *Server {
|
||||
srv: grpc.NewServer(),
|
||||
}
|
||||
|
||||
exproto.RegisterAuthServer(server.srv, &Server{})
|
||||
proto.RegisterNotifyServer(server.srv, &Server{})
|
||||
proto.RegisterFriendshipsServer(server.srv, &Server{})
|
||||
proto.RegisterRealmsServer(server.srv, &Server{})
|
||||
health.RegisterHealthServer(server.srv, &Server{})
|
||||
proto.RegisterAuthServer(server.srv, server)
|
||||
proto.RegisterNotifierServer(server.srv, server)
|
||||
proto.RegisterRealmServer(server.srv, server)
|
||||
health.RegisterHealthServer(server.srv, server)
|
||||
|
||||
reflection.Register(server.srv)
|
||||
|
||||
|
Reference in New Issue
Block a user