⬆️ Upgrade to support the latest version Hydrogen Project standard

This commit is contained in:
2024-06-22 18:05:41 +08:00
parent fa50baf927
commit 9366f6e56e
55 changed files with 603 additions and 385 deletions

View File

@ -1,44 +0,0 @@
package grpc
import (
pcpb "git.solsynth.dev/hydrogen/paperclip/pkg/grpc/proto"
idpb "git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
"google.golang.org/grpc/credentials/insecure"
"github.com/spf13/viper"
"google.golang.org/grpc"
)
var Attachments pcpb.AttachmentsClient
func ConnectPaperclip() error {
addr := viper.GetString("paperclip.grpc_endpoint")
if conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
return err
} else {
Attachments = pcpb.NewAttachmentsClient(conn)
}
return nil
}
var (
Realms idpb.RealmsClient
Friendships idpb.FriendshipsClient
Notify idpb.NotifyClient
Auth idpb.AuthClient
)
func ConnectPassport() error {
addr := viper.GetString("passport.grpc_endpoint")
if conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
return err
} else {
Realms = idpb.NewRealmsClient(conn)
Friendships = idpb.NewFriendshipsClient(conn)
Notify = idpb.NewNotifyClient(conn)
Auth = idpb.NewAuthClient(conn)
}
return nil
}

View File

@ -1,7 +1,7 @@
package database
import (
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"gorm.io/gorm"
)

View File

@ -0,0 +1,12 @@
package gap
import (
"git.solsynth.dev/hydrogen/passport/pkg/hyper"
"github.com/spf13/viper"
)
var H *hyper.HyperConn
func NewHyperClient() {
H = hyper.NewHyperConn(viper.GetString("consul.addr"))
}

15
pkg/internal/gap/net.go Normal file
View File

@ -0,0 +1,15 @@
package gap
import "net"
func GetOutboundIP() (net.IP, error) {
conn, err := net.Dial("udp", "1.1.1.1:80")
if err != nil {
return nil, err
} else {
defer conn.Close()
}
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP, nil
}

View File

@ -0,0 +1,40 @@
package gap
import (
"fmt"
"strconv"
"strings"
"github.com/hashicorp/consul/api"
"github.com/spf13/viper"
)
func Register() error {
cfg := api.DefaultConfig()
cfg.Address = viper.GetString("consul.addr")
client, err := api.NewClient(cfg)
if err != nil {
return err
}
httpBind := strings.SplitN(viper.GetString("bind"), ":", 2)
grpcBind := strings.SplitN(viper.GetString("grpc_bind"), ":", 2)
outboundIp, _ := GetOutboundIP()
port, _ := strconv.Atoi(httpBind[1])
registration := new(api.AgentServiceRegistration)
registration.ID = viper.GetString("id")
registration.Name = "Hydrogen.Messaging"
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",
}
return client.Agent().ServiceRegister(registration)
}

View File

@ -0,0 +1,26 @@
package grpc
import (
"context"
health "google.golang.org/grpc/health/grpc_health_v1"
"time"
)
func (v *Server) Check(ctx context.Context, request *health.HealthCheckRequest) (*health.HealthCheckResponse, error) {
return &health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}, nil
}
func (v *Server) Watch(request *health.HealthCheckRequest, server health.Health_WatchServer) error {
for {
if server.Send(&health.HealthCheckResponse{
Status: health.HealthCheckResponse_SERVING,
}) != nil {
break
}
time.Sleep(1000 * time.Millisecond)
}
return nil
}

View File

@ -0,0 +1,33 @@
package grpc
import (
"git.solsynth.dev/hydrogen/paperclip/pkg/proto"
"github.com/spf13/viper"
"google.golang.org/grpc"
health "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"
"net"
)
type Server struct {
proto.UnimplementedAttachmentsServer
}
var S *grpc.Server
func NewGRPC() {
S = grpc.NewServer()
health.RegisterHealthServer(S, &Server{})
reflection.Register(S)
}
func ListenGRPC() error {
listener, err := net.Listen("tcp", viper.GetString("grpc_bind"))
if err != nil {
return err
}
return S.Serve(listener)
}

View File

@ -1,9 +1,9 @@
package server
package api
import (
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
"github.com/spf13/viper"
)

View File

@ -1,11 +1,12 @@
package server
package api
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
)
@ -60,7 +61,7 @@ func addChannelMember(c *fiber.Ctx) error {
Target string `json:"target" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@ -101,7 +102,7 @@ func removeChannelMember(c *fiber.Ctx) error {
Target string `json:"target" validate:"required"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@ -144,7 +145,7 @@ func editMyChannelMembership(c *fiber.Ctx) error {
NotifyLevel int8 `json:"notify_level"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -1,11 +1,12 @@
package server
package api
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
)
@ -103,7 +104,7 @@ func createChannel(c *fiber.Ctx) error {
IsEncrypted bool `json:"is_encrypted"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
} else if err = services.GetChannelAliasAvailability(data.Alias); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
@ -155,7 +156,7 @@ func editChannel(c *fiber.Ctx) error {
IsEncrypted bool `json:"is_encrypted"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -1,11 +1,12 @@
package server
package api
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
)
@ -20,7 +21,7 @@ func createDirectChannel(c *fiber.Ctx) error {
IsEncrypted bool `json:"is_encrypted"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
} else if err = services.GetChannelAliasAvailability(data.Alias); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())

View File

@ -0,0 +1,49 @@
package api
import (
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)
func MapAPIs(app *fiber.App) {
api := app.Group("/api").Name("API")
{
api.Get("/users/me", getUserinfo)
api.Get("/users/:accountId", getOthersInfo)
channels := api.Group("/channels/:realm").Use(realmMiddleware).Name("Channels API")
{
channels.Get("/", listChannel)
channels.Get("/me", listOwnedChannel)
channels.Get("/me/available", listAvailableChannel)
channels.Get("/:channel", getChannel)
channels.Get("/:channel/me", getChannelIdentity)
channels.Post("/", createChannel)
channels.Post("/dm", createDirectChannel)
channels.Put("/:channelId", editChannel)
channels.Delete("/:channelId", deleteChannel)
channels.Get("/:channel/members", listChannelMembers)
channels.Get("/:channel/members/me", getMyChannelMembership)
channels.Put("/:channel/members/me", editMyChannelMembership)
channels.Post("/:channel/members", addChannelMember)
channels.Post("/:channel/members/me", joinChannel)
channels.Delete("/:channel/members", removeChannelMember)
channels.Delete("/:channel/members/me", leaveChannel)
channels.Get("/:channel/messages", listMessage)
channels.Post("/:channel/messages", newMessage)
channels.Put("/:channel/messages/:messageId", editMessage)
channels.Delete("/:channel/messages/:messageId", deleteMessage)
channels.Get("/:channel/calls", listCall)
channels.Get("/:channel/calls/ongoing", getOngoingCall)
channels.Post("/:channel/calls", startCall)
channels.Delete("/:channel/calls/ongoing", endCall)
channels.Post("/:channel/calls/ongoing/token", exchangeCallToken)
}
api.Get("/ws", websocket.New(messageGateway))
}
}

View File

@ -1,10 +1,11 @@
package server
package api
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
"strings"
)
@ -52,7 +53,7 @@ func newMessage(c *fiber.Ctx) error {
ReplyTo *uint `json:"reply_to"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
} else if len(data.Uuid) < 36 {
return fiber.NewError(fiber.StatusBadRequest, "message uuid was not valid")
@ -131,7 +132,7 @@ func editMessage(c *fiber.Ctx) error {
ReplyTo *uint `json:"reply_to"`
}
if err := BindAndValidate(c, &data); err != nil {
if err := exts.BindAndValidate(c, &data); err != nil {
return err
}

View File

@ -1,8 +1,8 @@
package server
package api
import (
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/contrib/websocket"
jsoniter "github.com/json-iterator/go"
"github.com/rs/zerolog/log"

View File

@ -1,8 +1,8 @@
package server
package api
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/gofiber/fiber/v2"
)

View File

@ -1,8 +1,8 @@
package server
package api
import (
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"github.com/gofiber/fiber/v2"
)

View File

@ -0,0 +1,19 @@
package exts
import (
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"git.solsynth.dev/hydrogen/passport/pkg/proto"
"github.com/gofiber/fiber/v2"
)
func LinkAccountMiddleware(c *fiber.Ctx) error {
if val, ok := c.Locals("p_user").(*proto.Userinfo); ok {
if account, err := services.LinkAccount(val); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else {
c.Locals("user", account)
}
}
return c.Next()
}

View File

@ -1,4 +1,4 @@
package server
package exts
import (
"github.com/go-playground/validator/v10"

View File

@ -0,0 +1,86 @@
package server
import (
"git.solsynth.dev/hydrogen/messaging/pkg/internal"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/gap"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/api"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server/exts"
"net/http"
"strings"
"github.com/gofiber/fiber/v2/middleware/favicon"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/template/html/v2"
jsoniter "github.com/json-iterator/go"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
var A *fiber.App
func NewServer() {
templates := html.NewFileSystem(http.FS(pkg.FS), ".gohtml")
A = fiber.New(fiber.Config{
DisableStartupMessage: true,
EnableIPValidation: true,
ServerHeader: "Hydrogen.Messaging",
AppName: "Hydrogen.Messaging",
ProxyHeader: fiber.HeaderXForwardedFor,
JSONEncoder: jsoniter.ConfigCompatibleWithStandardLibrary.Marshal,
JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal,
BodyLimit: 50 * 1024 * 1024,
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
Views: templates,
ViewsLayout: "views/index",
})
A.Use(idempotency.New())
A.Use(cors.New(cors.Config{
AllowCredentials: true,
AllowMethods: strings.Join([]string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodOptions,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
}, ","),
AllowOriginsFunc: func(origin string) bool {
return true
},
}))
A.Use(logger.New(logger.Config{
Format: "${status} | ${latency} | ${method} ${path}\n",
Output: log.Logger,
}))
A.Use(gap.H.AuthMiddleware)
A.Use(exts.LinkAccountMiddleware)
A.Use(favicon.New(favicon.Config{
FileSystem: http.FS(pkg.FS),
File: "views/favicon.png",
URL: "/favicon.png",
}))
api.MapAPIs(A)
A.Get("/", func(c *fiber.Ctx) error {
return c.Render("views/open", fiber.Map{
"frontend": viper.GetString("frontend"),
})
})
}
func Listen() {
if err := A.Listen(viper.GetString("bind")); err != nil {
log.Fatal().Err(err).Msg("An error occurred when starting server...")
}
}

View File

@ -3,12 +3,12 @@ package services
import (
"context"
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/gap"
"time"
"git.solsynth.dev/hydrogen/messaging/pkg/grpc"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/proto"
"github.com/spf13/viper"
)
@ -25,7 +25,11 @@ func GetAccountFriend(userId, relatedId uint, status int) (*proto.FriendshipResp
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
return grpc.Friendships.GetFriendship(ctx, &proto.FriendshipTwoSideLookupRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return nil, err
}
return proto.NewFriendshipsClient(pc).GetFriendship(ctx, &proto.FriendshipTwoSideLookupRequest{
AccountId: uint64(user.ExternalID),
RelatedId: uint64(related.ExternalID),
Status: uint32(status),
@ -36,7 +40,11 @@ func NotifyAccountMessager(user models.Account, t, s, c string, realtime bool, f
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
_, err := grpc.Notify.NotifyUser(ctx, &proto.NotifyRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return err
}
_, err = proto.NewNotifyClient(pc).NotifyUser(ctx, &proto.NotifyRequest{
ClientId: viper.GetString("passport.client_id"),
ClientSecret: viper.GetString("passport.client_secret"),
Type: fmt.Sprintf("messaging.%s", t),

View File

@ -0,0 +1,22 @@
package services
import (
"context"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/gap"
"git.solsynth.dev/hydrogen/paperclip/pkg/proto"
"github.com/samber/lo"
)
func CheckAttachmentByIDExists(id uint, usage string) bool {
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return false
}
_, err = proto.NewAttachmentsClient(pc).CheckAttachmentExists(context.Background(), &proto.AttachmentLookupRequest{
Id: lo.ToPtr(uint64(id)),
Usage: &usage,
})
return err == nil
}

View File

@ -1,17 +1,13 @@
package services
import (
"context"
"errors"
"fmt"
"reflect"
"time"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/grpc"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/proto"
"gorm.io/gorm"
"reflect"
)
func LinkAccount(userinfo *proto.Userinfo) (models.Account, error) {
@ -53,24 +49,3 @@ func LinkAccount(userinfo *proto.Userinfo) (models.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
reply, err := grpc.Auth.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
}

View File

@ -4,8 +4,8 @@ import (
"context"
"errors"
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
jsoniter "github.com/json-iterator/go"
"github.com/livekit/protocol/auth"
"github.com/livekit/protocol/livekit"

View File

@ -3,8 +3,8 @@ package services
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
)
func ListChannelMember(channelId uint) ([]models.ChannelMember, error) {

View File

@ -4,8 +4,8 @@ import (
"fmt"
"regexp"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"github.com/samber/lo"
"github.com/spf13/viper"
"gorm.io/gorm"

View File

@ -3,7 +3,7 @@ package services
import (
"time"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"github.com/rs/zerolog/log"
)

View File

@ -3,7 +3,7 @@ package services
import (
"sync"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"github.com/gofiber/contrib/websocket"
)

View File

@ -3,8 +3,8 @@ package services
import (
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"github.com/rs/zerolog/log"
"github.com/samber/lo"
)

View File

@ -4,10 +4,10 @@ import (
"context"
"errors"
"fmt"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/grpc"
"git.solsynth.dev/hydrogen/messaging/pkg/models"
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/gap"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/proto"
"github.com/samber/lo"
"gorm.io/gorm"
"reflect"
@ -15,7 +15,11 @@ import (
func GetRealm(id uint) (models.Realm, error) {
var realm models.Realm
response, err := grpc.Realms.GetRealm(context.Background(), &proto.RealmLookupRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return realm, err
}
response, err := proto.NewRealmsClient(pc).GetRealm(context.Background(), &proto.RealmLookupRequest{
Id: lo.ToPtr(uint64(id)),
})
if err != nil {
@ -26,7 +30,11 @@ func GetRealm(id uint) (models.Realm, error) {
func GetRealmWithAlias(alias string) (models.Realm, error) {
var realm models.Realm
response, err := grpc.Realms.GetRealm(context.Background(), &proto.RealmLookupRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return realm, err
}
response, err := proto.NewRealmsClient(pc).GetRealm(context.Background(), &proto.RealmLookupRequest{
Alias: &alias,
})
if err != nil {
@ -36,7 +44,11 @@ func GetRealmWithAlias(alias string) (models.Realm, error) {
}
func GetRealmMember(realmId uint, userId uint) (*proto.RealmMemberResponse, error) {
response, err := grpc.Realms.GetRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return nil, err
}
response, err := proto.NewRealmsClient(pc).GetRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
RealmId: uint64(realmId),
UserId: lo.ToPtr(uint64(userId)),
})
@ -48,7 +60,11 @@ func GetRealmMember(realmId uint, userId uint) (*proto.RealmMemberResponse, erro
}
func ListRealmMember(realmId uint) ([]*proto.RealmMemberResponse, error) {
response, err := grpc.Realms.ListRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
pc, err := gap.H.DiscoverServiceGRPC("Hydrogen.Passport")
if err != nil {
return nil, err
}
response, err := proto.NewRealmsClient(pc).ListRealmMember(context.Background(), &proto.RealmMemberLookupRequest{
RealmId: uint64(realmId),
})
if err != nil {

View File

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -1,18 +1,19 @@
package main
import (
"git.solsynth.dev/hydrogen/messaging/pkg/internal/gap"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/grpc"
"os"
"os/signal"
"syscall"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/services"
"github.com/robfig/cron/v3"
"git.solsynth.dev/hydrogen/messaging/pkg/grpc"
"git.solsynth.dev/hydrogen/messaging/pkg/server"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/server"
messaging "git.solsynth.dev/hydrogen/messaging/pkg"
"git.solsynth.dev/hydrogen/messaging/pkg/database"
"git.solsynth.dev/hydrogen/messaging/pkg/internal"
"git.solsynth.dev/hydrogen/messaging/pkg/internal/database"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
@ -44,30 +45,32 @@ func main() {
// Connect other services
services.SetupLiveKit()
if err := grpc.ConnectPassport(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when connecting to passport...")
}
if err := grpc.ConnectPaperclip(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when connecting to paperclip...")
if err := gap.Register(); err != nil {
log.Fatal().Err(err).Msg("An error occurred when connecting to consul...")
} else {
gap.NewHyperClient()
}
// Server
server.NewServer()
go server.Listen()
grpc.NewGRPC()
go grpc.ListenGRPC()
// Configure timed tasks
quartz := cron.New(cron.WithLogger(cron.VerbosePrintfLogger(&log.Logger)))
quartz.AddFunc("@every 60m", services.DoAutoDatabaseCleanup)
quartz.Start()
// Messages
log.Info().Msgf("Messaging v%s is started...", messaging.AppVersion)
log.Info().Msgf("Messaging v%s is started...", pkg.AppVersion)
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Info().Msgf("Messaging v%s is quitting...", messaging.AppVersion)
log.Info().Msgf("Messaging v%s is quitting...", pkg.AppVersion)
quartz.Stop()
}

View File

@ -1,54 +0,0 @@
package server
import (
"strings"
"git.solsynth.dev/hydrogen/messaging/pkg/services"
"github.com/gofiber/fiber/v2"
)
func authMiddleware(c *fiber.Ctx) error {
var token string
if cookie := c.Cookies(services.CookieAccessKey); len(cookie) > 0 {
token = cookie
}
if header := c.Get(fiber.HeaderAuthorization); len(header) > 0 {
tk := strings.Replace(header, "Bearer", "", 1)
token = strings.TrimSpace(tk)
}
if query := c.Query("tk"); len(query) > 0 {
token = strings.TrimSpace(query)
}
c.Locals("token", token)
if err := authFunc(c); err != nil {
return err
}
return c.Next()
}
func authFunc(c *fiber.Ctx, overrides ...string) error {
var token string
if len(overrides) > 0 {
token = overrides[0]
} else {
if tk, ok := c.Locals("token").(string); !ok {
return fiber.NewError(fiber.StatusUnauthorized)
} else {
token = tk
}
}
rtk := c.Cookies(services.CookieRefreshKey)
if user, atk, rtk, err := services.Authenticate(token, rtk); err == nil {
if atk != token {
services.SetJwtCookieSet(c, atk, rtk)
}
c.Locals("principal", user)
return nil
} else {
return fiber.NewError(fiber.StatusUnauthorized, err.Error())
}
}

View File

@ -1,122 +0,0 @@
package server
import (
"net/http"
"strings"
"git.solsynth.dev/hydrogen/messaging/pkg"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2/middleware/favicon"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/idempotency"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/template/html/v2"
jsoniter "github.com/json-iterator/go"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
var A *fiber.App
func NewServer() {
templates := html.NewFileSystem(http.FS(pkg.FS), ".gohtml")
A = fiber.New(fiber.Config{
DisableStartupMessage: true,
EnableIPValidation: true,
ServerHeader: "Hydrogen.Messaging",
AppName: "Hydrogen.Messaging",
ProxyHeader: fiber.HeaderXForwardedFor,
JSONEncoder: jsoniter.ConfigCompatibleWithStandardLibrary.Marshal,
JSONDecoder: jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal,
BodyLimit: 50 * 1024 * 1024,
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
Views: templates,
ViewsLayout: "views/index",
})
A.Use(idempotency.New())
A.Use(cors.New(cors.Config{
AllowCredentials: true,
AllowMethods: strings.Join([]string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodOptions,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
}, ","),
AllowOriginsFunc: func(origin string) bool {
return true
},
}))
A.Use(logger.New(logger.Config{
Format: "${status} | ${latency} | ${method} ${path}\n",
Output: log.Logger,
}))
A.Get("/.well-known", getMetadata)
api := A.Group("/api").Name("API")
{
api.Get("/users/me", authMiddleware, getUserinfo)
api.Get("/users/:accountId", getOthersInfo)
channels := api.Group("/channels/:realm").Use(realmMiddleware).Name("Channels API")
{
channels.Get("/", listChannel)
channels.Get("/me", authMiddleware, listOwnedChannel)
channels.Get("/me/available", authMiddleware, listAvailableChannel)
channels.Get("/:channel", getChannel)
channels.Get("/:channel/me", authMiddleware, getChannelIdentity)
channels.Post("/", authMiddleware, createChannel)
channels.Post("/dm", authMiddleware, createDirectChannel)
channels.Put("/:channelId", authMiddleware, editChannel)
channels.Delete("/:channelId", authMiddleware, deleteChannel)
channels.Get("/:channel/members", listChannelMembers)
channels.Get("/:channel/members/me", authMiddleware, getMyChannelMembership)
channels.Put("/:channel/members/me", authMiddleware, editMyChannelMembership)
channels.Post("/:channel/members", authMiddleware, addChannelMember)
channels.Post("/:channel/members/me", authMiddleware, joinChannel)
channels.Delete("/:channel/members", authMiddleware, removeChannelMember)
channels.Delete("/:channel/members/me", authMiddleware, leaveChannel)
channels.Get("/:channel/messages", authMiddleware, listMessage)
channels.Post("/:channel/messages", authMiddleware, newMessage)
channels.Put("/:channel/messages/:messageId", authMiddleware, editMessage)
channels.Delete("/:channel/messages/:messageId", authMiddleware, deleteMessage)
channels.Get("/:channel/calls", listCall)
channels.Get("/:channel/calls/ongoing", getOngoingCall)
channels.Post("/:channel/calls", authMiddleware, startCall)
channels.Delete("/:channel/calls/ongoing", authMiddleware, endCall)
channels.Post("/:channel/calls/ongoing/token", authMiddleware, exchangeCallToken)
}
api.Get("/ws", authMiddleware, websocket.New(messageGateway))
}
A.Use(favicon.New(favicon.Config{
FileSystem: http.FS(pkg.FS),
File: "views/favicon.png",
URL: "/favicon.png",
}))
A.Get("/", func(c *fiber.Ctx) error {
return c.Render("views/open", fiber.Map{
"frontend": viper.GetString("frontend"),
})
})
}
func Listen() {
if err := A.Listen(viper.GetString("bind")); err != nil {
log.Fatal().Err(err).Msg("An error occurred when starting server...")
}
}

View File

@ -1,16 +0,0 @@
package server
import (
"github.com/gofiber/fiber/v2"
"github.com/spf13/viper"
)
func getMetadata(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"name": viper.GetString("name"),
"domain": viper.GetString("domain"),
"components": fiber.Map{
"identity": viper.GetString("identity.endpoint"),
},
})
}

View File

@ -1,30 +0,0 @@
package services
import (
"context"
"git.solsynth.dev/hydrogen/messaging/pkg/grpc"
pcpb "git.solsynth.dev/hydrogen/paperclip/pkg/grpc/proto"
"github.com/samber/lo"
)
func GetAttachmentByID(id uint) (*pcpb.Attachment, error) {
return grpc.Attachments.GetAttachment(context.Background(), &pcpb.AttachmentLookupRequest{
Id: lo.ToPtr(uint64(id)),
})
}
func GetAttachmentByUUID(uuid string) (*pcpb.Attachment, error) {
return grpc.Attachments.GetAttachment(context.Background(), &pcpb.AttachmentLookupRequest{
Uuid: &uuid,
})
}
func CheckAttachmentByIDExists(id uint, usage string) bool {
_, err := grpc.Attachments.CheckAttachmentExists(context.Background(), &pcpb.AttachmentLookupRequest{
Id: lo.ToPtr(uint64(id)),
Usage: &usage,
})
return err == nil
}