♻️ Basiclly moved to Dealer from Consul
This commit is contained in:
BIN
pkg/internal/.DS_Store
vendored
Normal file
BIN
pkg/internal/.DS_Store
vendored
Normal file
Binary file not shown.
@ -2,51 +2,41 @@ package gap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"github.com/rs/zerolog/log"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
||||
_ "github.com/mbobakov/grpc-consul-resolver"
|
||||
)
|
||||
|
||||
func Register() error {
|
||||
cfg := api.DefaultConfig()
|
||||
cfg.Address = viper.GetString("consul.addr")
|
||||
|
||||
client, err := api.NewClient(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var H *hyper.HyperConn
|
||||
|
||||
func RegisterService() error {
|
||||
grpcBind := strings.SplitN(viper.GetString("grpc_bind"), ":", 2)
|
||||
httpBind := strings.SplitN(viper.GetString("bind"), ":", 2)
|
||||
|
||||
outboundIp, _ := GetOutboundIP()
|
||||
port, _ := strconv.Atoi(grpcBind[1])
|
||||
|
||||
registration := new(api.AgentServiceRegistration)
|
||||
registration.ID = viper.GetString("id")
|
||||
registration.Name = "Hydrogen.Passport"
|
||||
registration.Address = outboundIp.String()
|
||||
registration.Port = port
|
||||
registration.Check = &api.AgentServiceCheck{
|
||||
GRPC: fmt.Sprintf("%s:%s", outboundIp, grpcBind[1]),
|
||||
Timeout: "5s",
|
||||
Interval: "1m",
|
||||
DeregisterCriticalServiceAfter: "3m",
|
||||
grpcOutbound := fmt.Sprintf("%s:%s", outboundIp, grpcBind[1])
|
||||
httpOutbound := fmt.Sprintf("%s:%s", outboundIp, httpBind[1])
|
||||
|
||||
var err error
|
||||
H, err = hyper.NewHyperConn(viper.GetString("dealer.addr"), &proto.ServiceInfo{
|
||||
Id: viper.GetString("id"),
|
||||
Type: hyper.ServiceTypeAuthProvider,
|
||||
Label: "Passport",
|
||||
GrpcAddr: grpcOutbound,
|
||||
HttpAddr: &httpOutbound,
|
||||
})
|
||||
if err == nil {
|
||||
go func() {
|
||||
err := H.KeepRegisterService()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("An error occurred while registering service...")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return client.Agent().ServiceRegister(registration)
|
||||
}
|
||||
|
||||
func DiscoverPaperclip() (*grpc.ClientConn, error) {
|
||||
target := fmt.Sprintf("consul://%s/Hydrogen.Paperclip", viper.GetString("consul.addr"))
|
||||
return grpc.NewClient(
|
||||
target,
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
@ -3,23 +3,22 @@ package grpc
|
||||
import (
|
||||
"context"
|
||||
|
||||
exproto "git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (v *Server) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto.AuthReply, error) {
|
||||
func (v *Server) Authenticate(_ context.Context, in *exproto.AuthRequest) (*exproto.AuthReply, error) {
|
||||
ctx, perms, atk, rtk, err := services.Authenticate(in.GetAccessToken(), in.GetRefreshToken(), 0)
|
||||
if err != nil {
|
||||
return &proto.AuthReply{
|
||||
return &exproto.AuthReply{
|
||||
IsValid: false,
|
||||
}, nil
|
||||
} else {
|
||||
user := ctx.Account
|
||||
rawPerms, _ := jsoniter.Marshal(perms)
|
||||
|
||||
userinfo := &proto.Userinfo{
|
||||
userinfo := &exproto.UserInfo{
|
||||
Id: uint64(user.ID),
|
||||
Name: user.Name,
|
||||
Nick: user.Nick,
|
||||
@ -34,18 +33,20 @@ func (v *Server) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto.
|
||||
userinfo.Banner = *user.GetBanner()
|
||||
}
|
||||
|
||||
return &proto.AuthReply{
|
||||
IsValid: true,
|
||||
AccessToken: &atk,
|
||||
RefreshToken: &rtk,
|
||||
Permissions: rawPerms,
|
||||
TicketId: lo.ToPtr(uint64(ctx.Ticket.ID)),
|
||||
Userinfo: userinfo,
|
||||
return &exproto.AuthReply{
|
||||
IsValid: true,
|
||||
Info: &exproto.AuthInfo{
|
||||
NewAccessToken: &atk,
|
||||
NewRefreshToken: &rtk,
|
||||
Permissions: rawPerms,
|
||||
TicketId: uint64(ctx.Ticket.ID),
|
||||
Info: userinfo,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Server) CheckPerm(_ context.Context, in *proto.CheckPermRequest) (*proto.CheckPermReply, error) {
|
||||
func (v *Server) CheckPerm(_ context.Context, in *exproto.CheckPermRequest) (*exproto.CheckPermReply, error) {
|
||||
claims, err := services.DecodeJwt(in.GetToken())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -64,7 +65,7 @@ func (v *Server) CheckPerm(_ context.Context, in *proto.CheckPermRequest) (*prot
|
||||
perms := services.FilterPermNodes(heldPerms, ctx.Ticket.Claims)
|
||||
valid := services.HasPermNode(perms, in.GetKey(), value)
|
||||
|
||||
return &proto.CheckPermReply{
|
||||
return &exproto.CheckPermReply{
|
||||
IsValid: valid,
|
||||
}, nil
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"google.golang.org/grpc/reflection"
|
||||
"net"
|
||||
|
||||
exproto "git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/proto"
|
||||
"github.com/spf13/viper"
|
||||
"google.golang.org/grpc"
|
||||
@ -12,7 +13,7 @@ import (
|
||||
import health "google.golang.org/grpc/health/grpc_health_v1"
|
||||
|
||||
type Server struct {
|
||||
proto.UnimplementedAuthServer
|
||||
exproto.UnimplementedAuthServer
|
||||
proto.UnimplementedNotifyServer
|
||||
proto.UnimplementedFriendshipsServer
|
||||
proto.UnimplementedRealmsServer
|
||||
@ -26,7 +27,7 @@ func NewServer() *Server {
|
||||
srv: grpc.NewServer(),
|
||||
}
|
||||
|
||||
proto.RegisterAuthServer(server.srv, &Server{})
|
||||
exproto.RegisterAuthServer(server.srv, &Server{})
|
||||
proto.RegisterNotifyServer(server.srv, &Server{})
|
||||
proto.RegisterFriendshipsServer(server.srv, &Server{})
|
||||
proto.RegisterRealmsServer(server.srv, &Server{})
|
||||
|
@ -1,16 +0,0 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var Bundle *i18n.Bundle
|
||||
|
||||
func InitInternationalization() {
|
||||
Bundle = i18n.NewBundle(language.English)
|
||||
Bundle.RegisterUnmarshalFunc("json", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
|
||||
Bundle.LoadMessageFileFS(FS, "locale.en.json")
|
||||
Bundle.LoadMessageFileFS(FS, "locale.zh.json")
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package i18n
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed locale.*.json
|
||||
var FS embed.FS
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"next": "Next",
|
||||
"email": "Email",
|
||||
"username": "Username",
|
||||
"nickname": "Nickname",
|
||||
"password": "Password",
|
||||
"unknown": "Unknown",
|
||||
"apply": "Apply",
|
||||
"back": "Back",
|
||||
"approve": "Approve",
|
||||
"decline": "Decline",
|
||||
"magicToken": "Magic Token",
|
||||
"signinTitle": "Sign In",
|
||||
"signinCaption": "Sign in to Solarpass to explore entire Solar Network. Explore posts, discover communities, talk with your best friends. All these things in the Solar Network!",
|
||||
"signinRequired": "You need to sign in before do that.",
|
||||
"signupTitle": "Sign Up",
|
||||
"signupCaption": "Sign up to create an account on Solarpass, then you can explore the entire Solar Network! Enjoy the next-generation Internet Ecosystem!",
|
||||
"authorizeTitle": "Authorize",
|
||||
"authorizeCaption": "One Solarpass, get entire network.",
|
||||
"mfaTitle": "Multi Factor Authenticate",
|
||||
"mfaCaption": "We need use one more way to verify it is you.",
|
||||
"mfaFactorEmail": "OTP through your email"
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"next": "下一步",
|
||||
"email": "邮件地址",
|
||||
"username": "用户名",
|
||||
"nickname": "昵称",
|
||||
"password": "密码",
|
||||
"unknown": "未知",
|
||||
"apply": "应用",
|
||||
"back": "返回",
|
||||
"approve": "接受",
|
||||
"decline": "拒绝",
|
||||
"magicToken": "魔法令牌",
|
||||
"signinTitle": "登陆",
|
||||
"signinCaption": "登陆 Solarpass 以探索整个 Solar Network,浏览帖子、探索社区、和你的好朋友聊八卦,一切尽在 Solar Network!",
|
||||
"signinRequired": "你需要在那之前登陆",
|
||||
"signupTitle": "注册",
|
||||
"signupCaption": "注册以在 Solarpass 创建一个账号,之后你就可以探索整个 Solar Network,享受下一代互联网生态系统!",
|
||||
"authorizeTitle": "授权",
|
||||
"authorizeCaption": "一个 Solarpass,整个网络。",
|
||||
"mfaTitle": "多因素验证",
|
||||
"mfaCaption": "我们需要另一个方法来确认你是你。",
|
||||
"mfaFactorEmail": "电子邮寄一次性验证码"
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
)
|
||||
|
||||
func I18nMiddleware(c *fiber.Ctx) error {
|
||||
accept := c.Get(fiber.HeaderAcceptLanguage)
|
||||
localizer := i18n.NewLocalizer(Bundle, accept)
|
||||
|
||||
c.Locals("localizer", localizer)
|
||||
|
||||
return c.Next()
|
||||
}
|
@ -21,26 +21,26 @@ type Account struct {
|
||||
SuspendedAt *time.Time `json:"suspended_at"`
|
||||
PermNodes datatypes.JSONMap `json:"perm_nodes"`
|
||||
|
||||
Profile AccountProfile `json:"profile"`
|
||||
Statuses []Status `json:"statuses"`
|
||||
Badges []Badge `json:"badges"`
|
||||
Profile AccountProfile `json:"profile,omitempty"`
|
||||
Statuses []Status `json:"statuses,omitempty"`
|
||||
Badges []Badge `json:"badges,omitempty"`
|
||||
|
||||
Contacts []AccountContact `json:"contacts"`
|
||||
RealmIdentities []RealmMember `json:"realm_identities"`
|
||||
Contacts []AccountContact `json:"contacts,omitempty"`
|
||||
RealmIdentities []RealmMember `json:"realm_identities,omitempty"`
|
||||
|
||||
Tickets []AuthTicket `json:"tickets"`
|
||||
Factors []AuthFactor `json:"factors"`
|
||||
Tickets []AuthTicket `json:"tickets,omitempty"`
|
||||
Factors []AuthFactor `json:"factors,omitempty"`
|
||||
|
||||
Events []ActionEvent `json:"events"`
|
||||
Events []ActionEvent `json:"events,omitempty"`
|
||||
MagicTokens []MagicToken `json:"-"`
|
||||
|
||||
ThirdClients []ThirdClient `json:"clients"`
|
||||
ThirdClients []ThirdClient `json:"clients,omitempty"`
|
||||
|
||||
Notifications []Notification `json:"notifications" gorm:"foreignKey:RecipientID"`
|
||||
NotifySubscribers []NotificationSubscriber `json:"notify_subscribers"`
|
||||
Notifications []Notification `json:"notifications,omitempty" gorm:"foreignKey:RecipientID"`
|
||||
NotifySubscribers []NotificationSubscriber `json:"notify_subscribers,omitempty"`
|
||||
|
||||
Friendships []AccountFriendship `json:"friendships" gorm:"foreignKey:AccountID"`
|
||||
RelatedFriendships []AccountFriendship `json:"related_friendships" gorm:"foreignKey:RelatedID"`
|
||||
Friendships []AccountFriendship `json:"friendships,omitempty" gorm:"foreignKey:AccountID"`
|
||||
RelatedFriendships []AccountFriendship `json:"related_friendships,omitempty" gorm:"foreignKey:RelatedID"`
|
||||
}
|
||||
|
||||
func (v Account) GetAvatar() *string {
|
||||
|
BIN
pkg/internal/server/.DS_Store
vendored
Normal file
BIN
pkg/internal/server/.DS_Store
vendored
Normal file
Binary file not shown.
@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
|
||||
"git.solsynth.dev/hydrogen/paperclip/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/gap"
|
||||
@ -27,7 +28,7 @@ func setAvatar(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pc, err := gap.DiscoverPaperclip()
|
||||
pc, err := gap.H.GetServiceGrpcConn(hyper.ServiceTypeFileProvider)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "attachments services was not available")
|
||||
}
|
||||
@ -63,7 +64,7 @@ func setBanner(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
pc, err := gap.DiscoverPaperclip()
|
||||
pc, err := gap.H.GetServiceGrpcConn(hyper.ServiceTypeFileProvider)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "attachments services was not available")
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
@ -99,13 +97,6 @@ func MapAPIs(app *fiber.App) {
|
||||
developers.Post("/notify", notifyUser)
|
||||
}
|
||||
|
||||
api.Use(func(c *fiber.Ctx) error {
|
||||
if err := exts.EnsureAuthenticated(c); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Next()
|
||||
}).Get("/ws", websocket.New(listenWebsocket))
|
||||
|
||||
api.All("/*", func(c *fiber.Ctx) error {
|
||||
return fiber.ErrNotFound
|
||||
})
|
||||
|
@ -1,82 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func listenWebsocket(c *websocket.Conn) {
|
||||
user := c.Locals("user").(models.Account)
|
||||
|
||||
// Push connection
|
||||
services.ClientRegister(user, c)
|
||||
log.Debug().Uint("user", user.ID).Msg("New websocket connection established...")
|
||||
|
||||
// Event loop
|
||||
var task models.UnifiedCommand
|
||||
|
||||
var messageType int
|
||||
var payload []byte
|
||||
var packet []byte
|
||||
var err error
|
||||
|
||||
for {
|
||||
if messageType, packet, err = c.ReadMessage(); err != nil {
|
||||
break
|
||||
} else if err := jsoniter.Unmarshal(packet, &task); err != nil {
|
||||
_ = c.WriteMessage(messageType, models.UnifiedCommand{
|
||||
Action: "error",
|
||||
Message: "unable to unmarshal your command, requires json request",
|
||||
}.Marshal())
|
||||
continue
|
||||
} else {
|
||||
payload, _ = jsoniter.Marshal(task.Payload)
|
||||
}
|
||||
|
||||
var message *models.UnifiedCommand
|
||||
switch task.Action {
|
||||
case "kex.request":
|
||||
var req struct {
|
||||
RequestID string `json:"request_id"`
|
||||
KeypairID string `json:"keypair_id"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
OwnerID uint `json:"owner_id"`
|
||||
Deadline int64 `json:"deadline"`
|
||||
}
|
||||
_ = jsoniter.Unmarshal(payload, &req)
|
||||
if len(req.RequestID) <= 0 || len(req.KeypairID) <= 0 || req.OwnerID <= 0 {
|
||||
message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("invalid request")))
|
||||
}
|
||||
services.KexRequest(c, req.RequestID, req.KeypairID, req.Algorithm, req.OwnerID, req.Deadline)
|
||||
case "kex.provide":
|
||||
var req struct {
|
||||
RequestID string `json:"request_id"`
|
||||
KeypairID string `json:"keypair_id"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
}
|
||||
_ = jsoniter.Unmarshal(payload, &req)
|
||||
if len(req.RequestID) <= 0 || len(req.KeypairID) <= 0 {
|
||||
message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("invalid request")))
|
||||
}
|
||||
services.KexProvide(user.ID, req.RequestID, req.KeypairID, packet)
|
||||
default:
|
||||
message = lo.ToPtr(models.UnifiedCommandFromError(fmt.Errorf("unknown action")))
|
||||
}
|
||||
|
||||
if message != nil {
|
||||
if err = c.WriteMessage(messageType, message.Marshal()); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pop connection
|
||||
services.ClientUnregister(user, c)
|
||||
log.Debug().Uint("user", user.ID).Msg("A websocket connection disconnected...")
|
||||
}
|
@ -2,7 +2,7 @@ package exts
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/hyper"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
@ -1,7 +1,7 @@
|
||||
package exts
|
||||
|
||||
import (
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/hyper"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/hyper"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/spf13/viper"
|
||||
"time"
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/i18n"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/favicon"
|
||||
@ -59,7 +58,6 @@ func NewServer() *HTTPApp {
|
||||
}))
|
||||
|
||||
app.Use(exts.AuthMiddleware)
|
||||
app.Use(i18n.I18nMiddleware)
|
||||
|
||||
admin.MapAdminAPIs(app)
|
||||
api.MapAPIs(app)
|
||||
|
@ -1,37 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
)
|
||||
|
||||
var (
|
||||
wsMutex sync.Mutex
|
||||
wsConn = make(map[uint]map[*websocket.Conn]bool)
|
||||
)
|
||||
|
||||
func ClientRegister(user models.Account, conn *websocket.Conn) {
|
||||
wsMutex.Lock()
|
||||
if wsConn[user.ID] == nil {
|
||||
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
||||
}
|
||||
wsConn[user.ID][conn] = true
|
||||
wsMutex.Unlock()
|
||||
}
|
||||
|
||||
func ClientUnregister(user models.Account, conn *websocket.Conn) {
|
||||
wsMutex.Lock()
|
||||
if wsConn[user.ID] == nil {
|
||||
wsConn[user.ID] = make(map[*websocket.Conn]bool)
|
||||
}
|
||||
delete(wsConn[user.ID], conn)
|
||||
wsMutex.Unlock()
|
||||
|
||||
if status, err := GetStatus(user.ID); err != nil || !status.IsInvisible {
|
||||
if len(wsConn[user.ID]) == 0 {
|
||||
_ = SetAccountLastSeen(user.ID)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
|
||||
"github.com/gofiber/contrib/websocket"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"time"
|
||||
)
|
||||
|
||||
type kexRequest struct {
|
||||
OwnerID uint
|
||||
Conn *websocket.Conn
|
||||
Deadline time.Time
|
||||
}
|
||||
|
||||
var kexRequests = make(map[string]map[string]kexRequest)
|
||||
|
||||
func KexRequest(conn *websocket.Conn, requestId, keypairId, algorithm string, ownerId uint, deadline int64) {
|
||||
if kexRequests[keypairId] == nil {
|
||||
kexRequests[keypairId] = make(map[string]kexRequest)
|
||||
}
|
||||
|
||||
ddl := time.Now().Add(time.Second * time.Duration(deadline))
|
||||
request := kexRequest{
|
||||
OwnerID: ownerId,
|
||||
Conn: conn,
|
||||
Deadline: ddl,
|
||||
}
|
||||
|
||||
flag := false
|
||||
for c := range wsConn[ownerId] {
|
||||
if c == conn {
|
||||
continue
|
||||
}
|
||||
|
||||
if c.WriteMessage(1, models.UnifiedCommand{
|
||||
Action: "kex.request",
|
||||
Payload: fiber.Map{
|
||||
"request_id": requestId,
|
||||
"keypair_id": keypairId,
|
||||
"algorithm": algorithm,
|
||||
"owner_id": ownerId,
|
||||
"deadline": deadline,
|
||||
},
|
||||
}.Marshal()) == nil {
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
|
||||
if flag {
|
||||
kexRequests[keypairId][requestId] = request
|
||||
}
|
||||
}
|
||||
|
||||
func KexProvide(userId uint, requestId, keypairId string, pkt []byte) {
|
||||
if kexRequests[keypairId] == nil {
|
||||
return
|
||||
}
|
||||
|
||||
val, ok := kexRequests[keypairId][requestId]
|
||||
if !ok {
|
||||
return
|
||||
} else if val.OwnerID != userId {
|
||||
return
|
||||
} else {
|
||||
_ = val.Conn.WriteMessage(1, pkt)
|
||||
}
|
||||
}
|
||||
|
||||
func KexCleanup() {
|
||||
if len(kexRequests) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for kp, data := range kexRequests {
|
||||
for idx, req := range data {
|
||||
if req.Deadline.Unix() <= time.Now().Unix() {
|
||||
delete(kexRequests[kp], idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,11 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/gap"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"firebase.google.com/go/messaging"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
||||
@ -56,15 +60,23 @@ func NewNotification(notification models.Notification) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PushNotification will push the notification what ever it is exists record in the database
|
||||
// Recommend push another goroutine when you need to push a lot of notification
|
||||
// And just use block statement when you just push one notification, the time of create a new sub-process is much more than push notification
|
||||
// PushNotification will push the notification whatever it exists record in the
|
||||
// database Recommend push another goroutine when you need to push a lot of
|
||||
// notifications And just use a block statement when you just push one
|
||||
// notification, the time of create a new subprocess is much more than push
|
||||
// notification
|
||||
func PushNotification(notification models.Notification) error {
|
||||
for conn := range wsConn[notification.RecipientID] {
|
||||
_ = conn.WriteMessage(1, models.UnifiedCommand{
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
_, err := proto.NewStreamControllerClient(gap.H.GetDealerGrpcConn()).PushStream(ctx, &proto.PushStreamRequest{
|
||||
UserId: uint64(notification.RecipientID),
|
||||
Body: models.UnifiedCommand{
|
||||
Action: "notifications.new",
|
||||
Payload: notification,
|
||||
}.Marshal())
|
||||
}.Marshal(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to push via websocket: %v", err)
|
||||
}
|
||||
|
||||
// Skip push notification
|
||||
|
@ -1,7 +1,10 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.solsynth.dev/hydrogen/dealer/pkg/proto"
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/gap"
|
||||
"time"
|
||||
|
||||
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
|
||||
@ -32,7 +35,16 @@ func GetStatus(uid uint) (models.Status, error) {
|
||||
}
|
||||
|
||||
func GetUserOnline(uid uint) bool {
|
||||
return wsConn[uid] != nil && len(wsConn[uid]) > 0
|
||||
pc := proto.NewStreamControllerClient(gap.H.GetDealerGrpcConn())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
resp, err := pc.CountStreamConnection(ctx, &proto.CountConnectionRequest{
|
||||
UserId: uint64(uid),
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return resp.Count > 0
|
||||
}
|
||||
|
||||
func GetStatusDisturbable(uid uint) error {
|
||||
@ -49,7 +61,7 @@ func GetStatusDisturbable(uid uint) error {
|
||||
|
||||
func GetStatusOnline(uid uint) error {
|
||||
status, err := GetStatus(uid)
|
||||
isOnline := wsConn[uid] != nil && len(wsConn[uid]) > 0
|
||||
isOnline := GetUserOnline(uid)
|
||||
if isOnline && err != nil {
|
||||
return nil
|
||||
} else if err == nil && status.IsInvisible {
|
||||
|
Reference in New Issue
Block a user