This commit is contained in:
royalcat 2025-05-06 02:41:02 +04:00
parent 0614199b5f
commit 6350009fcf
20 changed files with 1256 additions and 54 deletions

10
.vscode/launch.json vendored
View file

@ -10,7 +10,15 @@
"request": "launch",
"mode": "debug",
"env": {
"DB": "postgres://localhost:5432/konfa?sslmode=disable&user=konfa&password=konfa"
"KONFA_HUB_DB": "postgres://localhost:5432/konfa?sslmode=disable&user=konfa&password=konfa",
"KONFA_HUB_AUTHPROVIDERS_0_ID": "konfach-sso",
"KONFA_HUB_AUTHPROVIDERS_0_NAME": "Konfach SSO",
"KONFA_HUB_AUTHPROVIDERS_0_OPENIDCONNECT_ISSUER": "https://sso.konfach.ru/realms/konfach",
"KONFA_HUB_AUTHPROVIDERS_0_OPENIDCONNECT_CLIENTID": "konfa",
"KONFA_HUB_AUTHPROVIDERS_0_OPENIDCONNECT_CLIENTSECRET": "UqeaMowRXcGULkAepr0EAEUfE82OjY72",
"KONFA_HUB_VOICERELAYS_0_ID": "local",
"KONFA_HUB_VOICERELAYS_0_NAME": "Local",
"KONFA_HUB_VOICERELAYS_0_ADDRESS": "localhost:8081"
},
"program": "${workspaceFolder}/cmd/main.go",
}

View file

@ -1,4 +1,4 @@
FROM --platform=${BUILDPLATFORM} golang:1.23 AS builder
FROM --platform=${BUILDPLATFORM} golang:1.24 AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM

View file

@ -2,32 +2,35 @@ package main
import (
"context"
"flag"
"fmt"
"log"
"net"
"github.com/ilyakaznacheev/cleanenv"
"github.com/konfa-chat/hub/pkg/uuid"
"github.com/konfa-chat/hub/src/auth"
"github.com/konfa-chat/hub/src/config"
"github.com/konfa-chat/hub/src/konfa"
"github.com/konfa-chat/hub/src/proto"
chatv1 "github.com/konfa-chat/hub/src/proto/konfa/chat/v1"
hubv1 "github.com/konfa-chat/hub/src/proto/konfa/hub/v1"
serverv1 "github.com/konfa-chat/hub/src/proto/konfa/server/v1"
"github.com/konfa-chat/hub/src/store"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
type Config struct {
DB string `env:"DB"`
}
func main() {
// Parse command line flags
configFilePath := flag.String("config", "", "Path to YAML configuration file")
flag.Parse()
ctx := context.Background()
var cfg Config
err := cleanenv.ReadEnv(&cfg)
// Load configuration passing the config file path directly
cfg, err := config.Load(*configFilePath)
if err != nil {
panic(err)
log.Fatalf("error loading config: %v", err)
}
db, dbpool, err := store.ConnectPostgres(ctx, cfg.DB)
@ -35,13 +38,23 @@ func main() {
panic(err)
}
srv := konfa.NewService(db, dbpool)
// Pass the entire config object to the service
srv := konfa.NewService(db, dbpool, cfg)
authen, err := auth.NewAuthenticator(ctx, db, auth.AuthenticatorConfig{
Issuer: "https://sso.konfach.ru/realms/konfach",
ClientID: "konfa",
ClientSecret: "UqeaMowRXcGULkAepr0EAEUfE82OjY72",
})
// Use the first auth provider for the authenticator
// In a more robust implementation, this might be configurable
provider := cfg.AuthProviders[0]
authen, err := auth.NewAuthenticator(ctx, db,
auth.AuthenticatorConfig{
Issuer: provider.OpenIDConnect.Issuer,
ClientID: provider.OpenIDConnect.ClientID,
ClientSecret: provider.OpenIDConnect.ClientSecret,
},
[]string{
"/grpc.reflection.v1alpha.ServerReflection",
"/" + hubv1.HubService_ServiceDesc.ServiceName,
},
)
if err != nil {
panic(err)
}
@ -52,6 +65,9 @@ func main() {
)
chatv1.RegisterChatServiceServer(grpcServer, proto.NewChatService(srv))
serverv1.RegisterServerServiceServer(grpcServer, proto.NewServerService(srv))
hubv1.RegisterHubServiceServer(grpcServer, proto.NewHubService(srv))
reflection.Register(grpcServer)
serverID, chanID, err := createKonfach(ctx, srv)
if err != nil {

13
go.mod
View file

@ -9,8 +9,11 @@ require (
github.com/cskr/pubsub/v2 v2.0.2
github.com/gofrs/uuid/v5 v5.3.2
github.com/golang-migrate/migrate/v4 v4.18.3
github.com/ilyakaznacheev/cleanenv v1.5.0
github.com/jackc/pgx/v5 v5.7.4
github.com/knadh/koanf/parsers/yaml v1.0.0
github.com/knadh/koanf/providers/env v1.1.0
github.com/knadh/koanf/providers/file v1.2.0
github.com/knadh/koanf/v2 v2.2.0
github.com/pressly/goose/v3 v3.24.2
github.com/uptrace/bun v1.2.11
github.com/uptrace/bun/dialect/pgdialect v1.2.11
@ -24,11 +27,12 @@ require (
)
require (
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
@ -37,13 +41,15 @@ require (
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mfridman/interpolate v0.0.2 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/muhlemmer/gu v0.3.1 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/sethvargo/go-retry v0.3.0 // indirect
@ -68,5 +74,4 @@ require (
golang.org/x/text v0.24.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
)

27
go.sum
View file

@ -1,8 +1,5 @@
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
@ -30,6 +27,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
@ -39,6 +38,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@ -60,8 +61,6 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
@ -76,8 +75,16 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=
github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=
github.com/knadh/koanf/parsers/yaml v1.0.0 h1:PXyeHCRhAMKyfLJaoTWsqUTxIFeDMmdAKz3XVEslZV4=
github.com/knadh/koanf/parsers/yaml v1.0.0/go.mod h1:Q63VAOh/s6XaQs6a0TB2w9GFUuuPGvfYrCSWb9eWAQU=
github.com/knadh/koanf/providers/env v1.1.0 h1:U2VXPY0f+CsNDkvdsG8GcsnK4ah85WwWyJgef9oQMSc=
github.com/knadh/koanf/providers/env v1.1.0/go.mod h1:QhHHHZ87h9JxJAn2czdEl6pdkNnDh/JS1Vtsyt65hTY=
github.com/knadh/koanf/providers/file v1.2.0 h1:hrUJ6Y9YOA49aNu/RSYzOTFlqzXSCpmYIDXI7OJU6+U=
github.com/knadh/koanf/providers/file v1.2.0/go.mod h1:bp1PM5f83Q+TOUu10J/0ApLBd9uIzg+n9UgthfY+nRA=
github.com/knadh/koanf/v2 v2.2.0 h1:FZFwd9bUjpb8DyCWARUBy5ovuhDs1lI87dOEn2K8UVU=
github.com/knadh/koanf/v2 v2.2.0/go.mod h1:PSFru3ufQgTsI7IF+95rf9s8XA1+aHxKuO/W+dPoHEY=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@ -94,6 +101,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
@ -216,5 +227,3 @@ modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g=
modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.36.2 h1:vjcSazuoFve9Wm0IVNHgmJECoOXLZM1KfMXbcX2axHA=
modernc.org/sqlite v1.36.2/go.mod h1:ADySlx7K4FdY5MaJcEv86hTJ0PjedAloTUuif0YS3ws=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=

View file

@ -7,21 +7,21 @@ option go_package = "/channelv1";
// import "google/protobuf/timestamp.proto";
message Channel {
oneof channel {
TextChannel text_channel = 1;
VoiceChannel voice_channel = 2;
}
oneof channel {
TextChannel text_channel = 1;
VoiceChannel voice_channel = 2;
}
}
message TextChannel {
string server_id = 1;
string channel_id = 2;
string name = 3;
string server_id = 1;
string channel_id = 2;
string name = 3;
}
message VoiceChannel {
string server_id = 1;
string channel_id = 2;
string name = 3;
string server_id = 1;
string channel_id = 2;
string name = 3;
string voice_relay_id = 4;
}

View file

@ -0,0 +1,16 @@
syntax = "proto3";
package konfa.hub.v1;
message AuthProvider {
string id = 1;
string name = 2;
oneof protocol { OpenIDConnect openid_connect = 101; }
}
message OpenIDConnect {
string issuer = 1;
string client_id = 2;
string client_secret = 3;
}

View file

@ -0,0 +1,30 @@
syntax = "proto3";
import "konfa/hub/v1/auth_provider.proto";
package konfa.hub.v1;
service HubService {
rpc ListServerIDs(ListServersRequest) returns (ListServersResponse);
rpc ListVoiceRelays(ListVoiceRelaysRequest) returns (ListVoiceRelaysResponse);
rpc ListAuthProviders(ListAuthProvidersRequest)
returns (ListAuthProvidersResponse);
}
message ListServersRequest {}
message ListServersResponse { repeated string server_ids = 1; }
message ListVoiceRelaysRequest {}
message VoiceRelay {
string id = 1;
string name = 2;
string address = 3;
}
message ListVoiceRelaysResponse { repeated VoiceRelay voice_relays = 1; }
message ListAuthProvidersRequest {}
message ListAuthProvidersResponse { repeated AuthProvider auth_providers = 1; }

View file

@ -26,11 +26,13 @@ type AuthenticatorConfig struct {
}
type Authenticator struct {
skipAuthMethods []string
provider rs.ResourceServer
db *bun.DB
}
func NewAuthenticator(ctx context.Context, db *bun.DB, acfg AuthenticatorConfig) (*Authenticator, error) {
func NewAuthenticator(ctx context.Context, db *bun.DB, acfg AuthenticatorConfig, skipAuthMethods []string) (*Authenticator, error) {
provider, err := rs.NewResourceServerClientCredentials(ctx, acfg.Issuer, acfg.ClientID, acfg.ClientSecret)
if err != nil {
@ -38,8 +40,9 @@ func NewAuthenticator(ctx context.Context, db *bun.DB, acfg AuthenticatorConfig)
}
return &Authenticator{
provider: provider,
db: db,
skipAuthMethods: skipAuthMethods,
provider: provider,
db: db,
}, nil
}

View file

@ -8,7 +8,20 @@ import (
"google.golang.org/grpc/metadata"
)
func (a *Authenticator) UnaryAuthenticate(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
func (a *Authenticator) isNeedAuth(method string) bool {
for _, noAuthMethod := range a.skipAuthMethods {
if strings.HasPrefix(method, noAuthMethod) {
return false
}
}
return true
}
func (a *Authenticator) UnaryAuthenticate(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
if !a.isNeedAuth(info.FullMethod) {
return handler(ctx, req)
}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, errMissingMetadata
@ -28,6 +41,10 @@ func (a *Authenticator) UnaryAuthenticate(ctx context.Context, req any, _ *grpc.
}
func (a *Authenticator) StreamAuthenticate(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
if !a.isNeedAuth(info.FullMethod) {
return handler(srv, ss)
}
ctx := ss.Context()
md, ok := metadata.FromIncomingContext(ctx)

194
src/config/config.go Normal file
View file

@ -0,0 +1,194 @@
// Package config provides configuration management for the Konfa Hub application
package config
import (
"fmt"
"log"
"strconv"
"strings"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2"
hubv1 "github.com/konfa-chat/hub/src/proto/konfa/hub/v1"
)
// AuthProviderOpenIDConnect contains OpenID Connect configuration
type AuthProviderOpenIDConnect struct {
Issuer string `koanf:"issuer"`
ClientID string `koanf:"clientid"`
ClientSecret string `koanf:"clientsecret"`
}
// AuthProvider represents an authentication provider configuration
type AuthProvider struct {
ID string `koanf:"id"`
Name string `koanf:"name"`
OpenIDConnect AuthProviderOpenIDConnect `koanf:"openidconnect"`
}
// VoiceRelay represents a voice relay service configuration
type VoiceRelay struct {
ID string `koanf:"id"`
Name string `koanf:"name"`
Address string `koanf:"address"`
}
// Config represents the application configuration
type Config struct {
DB string `koanf:"db"`
AuthProviders []AuthProvider `koanf:"authproviders"`
VoiceRelays []VoiceRelay `koanf:"voicerelays"`
}
// Load loads configuration from YAML file and environment variables
// Environment variables take precedence over the YAML configuration
func Load(configFile string) (*Config, error) {
k := koanf.New(".")
// Load from YAML file if provided
if configFile != "" {
if err := k.Load(file.Provider(configFile), yaml.Parser()); err != nil {
return nil, fmt.Errorf("error loading config from file %s: %w", configFile, err)
}
}
// Load environment variables (these take precedence over the YAML config)
err := k.Load(env.Provider("KONFA_HUB_", ".", func(s string) string {
s = strings.TrimPrefix(s, "KONFA_HUB_")
s = strings.ToLower(s)
s = strings.ReplaceAll(s, "_", ".")
return s
}), nil)
if err != nil {
return nil, fmt.Errorf("error loading config from environment: %w", err)
}
err = parseMapToSlice(k, "authproviders")
if err != nil {
log.Printf("warning failed to parse auth providers: %v", err)
}
err = parseMapToSlice(k, "voicerelays")
if err != nil {
log.Printf("warning failed to parse voice relays: %v", err)
}
var cfg Config
// Unmarshal the config
if err := k.Unmarshal("", &cfg); err != nil {
return nil, fmt.Errorf("error unmarshalling config: %w", err)
}
// Validate the configuration
if err := validateConfig(&cfg); err != nil {
return nil, err
}
log.Printf("Loaded configuration: %+v\n", cfg)
return &cfg, nil
}
func parseMapToSlice(k *koanf.Koanf, key string) error {
m, ok := k.Get(key).(map[string]any)
if !ok {
return nil
}
s := make([]any, len(m))
for k, v := range m {
i, err := strconv.Atoi(k)
if err != nil {
return fmt.Errorf("key %s is not an integer: %w", k, err)
}
if i > len(s) {
return fmt.Errorf("key %s is out of range: %d", k, i)
}
s[i] = v
}
return k.Set(key, s)
}
// validateConfig validates the configuration values
func validateConfig(cfg *Config) error {
// Check if AuthProviders slice is populated
if len(cfg.AuthProviders) == 0 {
return fmt.Errorf("no auth providers configured")
}
for _, v := range cfg.AuthProviders {
if v.ID == "" {
return fmt.Errorf("auth provider ID is required")
}
if v.Name == "" {
return fmt.Errorf("auth provider name is required")
}
if v.OpenIDConnect.Issuer == "" {
return fmt.Errorf("auth provider issuer is required")
}
if v.OpenIDConnect.ClientID == "" {
return fmt.Errorf("auth provider client ID is required")
}
if v.OpenIDConnect.ClientSecret == "" {
return fmt.Errorf("auth provider client secret is required")
}
}
// If no voice relays are configured, add a default one
if len(cfg.VoiceRelays) == 0 {
return fmt.Errorf("no voice relays configured")
}
for _, v := range cfg.VoiceRelays {
if v.ID == "" {
return fmt.Errorf("voice relay ID is required")
}
if v.Name == "" {
return fmt.Errorf("voice relay name is required")
}
if v.Address == "" {
return fmt.Errorf("voice relay address is required")
}
}
return nil
}
// GetHubAuthProviders converts configuration AuthProviders to hubv1.AuthProvider format
func (c *Config) GetHubAuthProviders() []*hubv1.AuthProvider {
providers := make([]*hubv1.AuthProvider, 0, len(c.AuthProviders))
for _, provider := range c.AuthProviders {
providers = append(providers, &hubv1.AuthProvider{
Id: provider.ID,
Name: provider.Name,
Protocol: &hubv1.AuthProvider_OpenidConnect{
OpenidConnect: &hubv1.OpenIDConnect{
Issuer: provider.OpenIDConnect.Issuer,
ClientId: provider.OpenIDConnect.ClientID,
ClientSecret: provider.OpenIDConnect.ClientSecret,
},
},
})
}
return providers
}
// GetHubVoiceRelays converts configuration VoiceRelays to hubv1.VoiceRelay format
func (c *Config) GetHubVoiceRelays() []*hubv1.VoiceRelay {
relays := make([]*hubv1.VoiceRelay, 0, len(c.VoiceRelays))
for _, relay := range c.VoiceRelays {
relays = append(relays, &hubv1.VoiceRelay{
Id: relay.ID,
Name: relay.Name,
Address: relay.Address,
})
}
return relays
}

View file

@ -4,6 +4,7 @@ import (
"github.com/cskr/pubsub/v2"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/konfa-chat/hub/pkg/uuid"
"github.com/konfa-chat/hub/src/config"
"github.com/uptrace/bun"
)
@ -12,12 +13,15 @@ type Service struct {
dbpool *pgxpool.Pool
msgBroker *pubsub.PubSub[uuid.UUID, uuid.UUID]
Config *config.Config
}
func NewService(db *bun.DB, dbpool *pgxpool.Pool) *Service {
func NewService(db *bun.DB, dbpool *pgxpool.Pool, cfg *config.Config) *Service {
return &Service{
db: db,
dbpool: dbpool,
msgBroker: pubsub.New[uuid.UUID, uuid.UUID](10),
Config: cfg,
}
}

49
src/proto/hub.go Normal file
View file

@ -0,0 +1,49 @@
package proto
import (
"context"
"github.com/konfa-chat/hub/src/konfa"
hubv1 "github.com/konfa-chat/hub/src/proto/konfa/hub/v1"
)
func NewHubService(srv *konfa.Service) *HubService {
return &HubService{srv: srv}
}
type HubService struct {
srv *konfa.Service
}
var _ hubv1.HubServiceServer = (*HubService)(nil)
// ListAuthProviders implements hubv1.HubServiceServer.
func (h *HubService) ListAuthProviders(context.Context, *hubv1.ListAuthProvidersRequest) (*hubv1.ListAuthProvidersResponse, error) {
// Return the auth providers from the config instead of directly from the service
return &hubv1.ListAuthProvidersResponse{
AuthProviders: h.srv.Config.GetHubAuthProviders(),
}, nil
}
// ListVoiceRelays implements hubv1.HubServiceServer.
func (h *HubService) ListVoiceRelays(context.Context, *hubv1.ListVoiceRelaysRequest) (*hubv1.ListVoiceRelaysResponse, error) {
// Return the voice relays from the config instead of hardcoded values
return &hubv1.ListVoiceRelaysResponse{
VoiceRelays: h.srv.Config.GetHubVoiceRelays(),
}, nil
}
// ListServers implements hubv1.HubServiceServer.
func (h *HubService) ListServerIDs(ctx context.Context, req *hubv1.ListServersRequest) (*hubv1.ListServersResponse, error) {
servers, err := h.srv.ListServers(ctx)
if err != nil {
return nil, err
}
serverIds := make([]string, 0, len(servers))
for _, server := range servers {
serverIds = append(serverIds, server.ID.String())
}
return &hubv1.ListServersResponse{
ServerIds: serverIds,
}, nil
}

View file

@ -168,6 +168,7 @@ type VoiceChannel struct {
ServerId string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty"`
ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
VoiceRelayId string `protobuf:"bytes,4,opt,name=voice_relay_id,json=voiceRelayId,proto3" json:"voice_relay_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@ -223,6 +224,13 @@ func (x *VoiceChannel) GetName() string {
return ""
}
func (x *VoiceChannel) GetVoiceRelayId() string {
if x != nil {
return x.VoiceRelayId
}
return ""
}
var File_konfa_channel_v1_channels_proto protoreflect.FileDescriptor
const file_konfa_channel_v1_channels_proto_rawDesc = "" +
@ -236,13 +244,14 @@ const file_konfa_channel_v1_channels_proto_rawDesc = "" +
"\tserver_id\x18\x01 \x01(\tR\bserverId\x12\x1d\n" +
"\n" +
"channel_id\x18\x02 \x01(\tR\tchannelId\x12\x12\n" +
"\x04name\x18\x03 \x01(\tR\x04name\"^\n" +
"\x04name\x18\x03 \x01(\tR\x04name\"\x84\x01\n" +
"\fVoiceChannel\x12\x1b\n" +
"\tserver_id\x18\x01 \x01(\tR\bserverId\x12\x1d\n" +
"\n" +
"channel_id\x18\x02 \x01(\tR\tchannelId\x12\x12\n" +
"\x04name\x18\x03 \x01(\tR\x04nameB\xce\x01\n" +
"\x14com.konfa.channel.v1B\rChannelsProtoP\x01ZEgithub.com/konfa-chat/hub/src/proto/konfa/channel/v1;channelv1\xa2\x02\x03KCX\xaa\x02\x10Konfa.Channel.V1\xca\x02\x10Konfa\\Channel\\V1\xe2\x02\x1cKonfa\\Channel\\V1\\GPBMetadata\xea\x02\x12Konfa::Channel::V1b\x06proto3"
"\x04name\x18\x03 \x01(\tR\x04name\x12$\n" +
"\x0evoice_relay_id\x18\x04 \x01(\tR\fvoiceRelayIdB\xc7\x01\n" +
"\x14com.konfa.channel.v1B\rChannelsProtoP\x01Z>github.com/konfa-chat/hub/src/proto/konfa/channel/v1;channelv1\xa2\x02\x03KCX\xaa\x02\x10Konfa.Channel.V1\xca\x02\x10Konfa\\Channel\\V1\xe2\x02\x1cKonfa\\Channel\\V1\\GPBMetadata\xea\x02\x12Konfa::Channel::V1b\x06proto3"
var (
file_konfa_channel_v1_channels_proto_rawDescOnce sync.Once

View file

@ -748,8 +748,8 @@ const file_konfa_chat_v1_service_proto_rawDesc = "" +
"\n" +
"GetMessage\x12 .konfa.chat.v1.GetMessageRequest\x1a!.konfa.chat.v1.GetMessageResponse\"\x00\x12j\n" +
"\x11StreamNewMessages\x12'.konfa.chat.v1.StreamNewMessagesRequest\x1a(.konfa.chat.v1.StreamNewMessagesResponse\"\x000\x01\x12g\n" +
"\x10UploadAttachment\x12&.konfa.chat.v1.UploadAttachmentRequest\x1a'.konfa.chat.v1.UploadAttachmentResponse\"\x00(\x01B\xb8\x01\n" +
"\x11com.konfa.chat.v1B\fServiceProtoP\x01Z?github.com/konfa-chat/hub/src/proto/konfa/chat/v1;chatv1\xa2\x02\x03KCX\xaa\x02\rKonfa.Chat.V1\xca\x02\rKonfa\\Chat\\V1\xe2\x02\x19Konfa\\Chat\\V1\\GPBMetadata\xea\x02\x0fKonfa::Chat::V1b\x06proto3"
"\x10UploadAttachment\x12&.konfa.chat.v1.UploadAttachmentRequest\x1a'.konfa.chat.v1.UploadAttachmentResponse\"\x00(\x01B\xb1\x01\n" +
"\x11com.konfa.chat.v1B\fServiceProtoP\x01Z8github.com/konfa-chat/hub/src/proto/konfa/chat/v1;chatv1\xa2\x02\x03KCX\xaa\x02\rKonfa.Chat.V1\xca\x02\rKonfa\\Chat\\V1\xe2\x02\x19Konfa\\Chat\\V1\\GPBMetadata\xea\x02\x0fKonfa::Chat::V1b\x06proto3"
var (
file_konfa_chat_v1_service_proto_rawDescOnce sync.Once

View file

@ -0,0 +1,234 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: konfa/hub/v1/auth_provider.proto
package hubv1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type AuthProvider struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Types that are valid to be assigned to Protocol:
//
// *AuthProvider_OpenidConnect
Protocol isAuthProvider_Protocol `protobuf_oneof:"protocol"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AuthProvider) Reset() {
*x = AuthProvider{}
mi := &file_konfa_hub_v1_auth_provider_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AuthProvider) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthProvider) ProtoMessage() {}
func (x *AuthProvider) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_auth_provider_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthProvider.ProtoReflect.Descriptor instead.
func (*AuthProvider) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_auth_provider_proto_rawDescGZIP(), []int{0}
}
func (x *AuthProvider) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *AuthProvider) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *AuthProvider) GetProtocol() isAuthProvider_Protocol {
if x != nil {
return x.Protocol
}
return nil
}
func (x *AuthProvider) GetOpenidConnect() *OpenIDConnect {
if x != nil {
if x, ok := x.Protocol.(*AuthProvider_OpenidConnect); ok {
return x.OpenidConnect
}
}
return nil
}
type isAuthProvider_Protocol interface {
isAuthProvider_Protocol()
}
type AuthProvider_OpenidConnect struct {
OpenidConnect *OpenIDConnect `protobuf:"bytes,101,opt,name=openid_connect,json=openidConnect,proto3,oneof"`
}
func (*AuthProvider_OpenidConnect) isAuthProvider_Protocol() {}
type OpenIDConnect struct {
state protoimpl.MessageState `protogen:"open.v1"`
Issuer string `protobuf:"bytes,1,opt,name=issuer,proto3" json:"issuer,omitempty"`
ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"`
ClientSecret string `protobuf:"bytes,3,opt,name=client_secret,json=clientSecret,proto3" json:"client_secret,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *OpenIDConnect) Reset() {
*x = OpenIDConnect{}
mi := &file_konfa_hub_v1_auth_provider_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *OpenIDConnect) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OpenIDConnect) ProtoMessage() {}
func (x *OpenIDConnect) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_auth_provider_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OpenIDConnect.ProtoReflect.Descriptor instead.
func (*OpenIDConnect) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_auth_provider_proto_rawDescGZIP(), []int{1}
}
func (x *OpenIDConnect) GetIssuer() string {
if x != nil {
return x.Issuer
}
return ""
}
func (x *OpenIDConnect) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
func (x *OpenIDConnect) GetClientSecret() string {
if x != nil {
return x.ClientSecret
}
return ""
}
var File_konfa_hub_v1_auth_provider_proto protoreflect.FileDescriptor
const file_konfa_hub_v1_auth_provider_proto_rawDesc = "" +
"\n" +
" konfa/hub/v1/auth_provider.proto\x12\fkonfa.hub.v1\"\x84\x01\n" +
"\fAuthProvider\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\x12D\n" +
"\x0eopenid_connect\x18e \x01(\v2\x1b.konfa.hub.v1.OpenIDConnectH\x00R\ropenidConnectB\n" +
"\n" +
"\bprotocol\"i\n" +
"\rOpenIDConnect\x12\x16\n" +
"\x06issuer\x18\x01 \x01(\tR\x06issuer\x12\x1b\n" +
"\tclient_id\x18\x02 \x01(\tR\bclientId\x12#\n" +
"\rclient_secret\x18\x03 \x01(\tR\fclientSecretB\xaf\x01\n" +
"\x10com.konfa.hub.v1B\x11AuthProviderProtoP\x01Z6github.com/konfa-chat/hub/src/proto/konfa/hub/v1;hubv1\xa2\x02\x03KHX\xaa\x02\fKonfa.Hub.V1\xca\x02\fKonfa\\Hub\\V1\xe2\x02\x18Konfa\\Hub\\V1\\GPBMetadata\xea\x02\x0eKonfa::Hub::V1b\x06proto3"
var (
file_konfa_hub_v1_auth_provider_proto_rawDescOnce sync.Once
file_konfa_hub_v1_auth_provider_proto_rawDescData []byte
)
func file_konfa_hub_v1_auth_provider_proto_rawDescGZIP() []byte {
file_konfa_hub_v1_auth_provider_proto_rawDescOnce.Do(func() {
file_konfa_hub_v1_auth_provider_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_konfa_hub_v1_auth_provider_proto_rawDesc), len(file_konfa_hub_v1_auth_provider_proto_rawDesc)))
})
return file_konfa_hub_v1_auth_provider_proto_rawDescData
}
var file_konfa_hub_v1_auth_provider_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_konfa_hub_v1_auth_provider_proto_goTypes = []any{
(*AuthProvider)(nil), // 0: konfa.hub.v1.AuthProvider
(*OpenIDConnect)(nil), // 1: konfa.hub.v1.OpenIDConnect
}
var file_konfa_hub_v1_auth_provider_proto_depIdxs = []int32{
1, // 0: konfa.hub.v1.AuthProvider.openid_connect:type_name -> konfa.hub.v1.OpenIDConnect
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_konfa_hub_v1_auth_provider_proto_init() }
func file_konfa_hub_v1_auth_provider_proto_init() {
if File_konfa_hub_v1_auth_provider_proto != nil {
return
}
file_konfa_hub_v1_auth_provider_proto_msgTypes[0].OneofWrappers = []any{
(*AuthProvider_OpenidConnect)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_konfa_hub_v1_auth_provider_proto_rawDesc), len(file_konfa_hub_v1_auth_provider_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_konfa_hub_v1_auth_provider_proto_goTypes,
DependencyIndexes: file_konfa_hub_v1_auth_provider_proto_depIdxs,
MessageInfos: file_konfa_hub_v1_auth_provider_proto_msgTypes,
}.Build()
File_konfa_hub_v1_auth_provider_proto = out.File
file_konfa_hub_v1_auth_provider_proto_goTypes = nil
file_konfa_hub_v1_auth_provider_proto_depIdxs = nil
}

View file

@ -0,0 +1,413 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: konfa/hub/v1/service.proto
package hubv1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ListServersRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListServersRequest) Reset() {
*x = ListServersRequest{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListServersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListServersRequest) ProtoMessage() {}
func (x *ListServersRequest) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListServersRequest.ProtoReflect.Descriptor instead.
func (*ListServersRequest) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{0}
}
type ListServersResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
ServerIds []string `protobuf:"bytes,1,rep,name=server_ids,json=serverIds,proto3" json:"server_ids,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListServersResponse) Reset() {
*x = ListServersResponse{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListServersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListServersResponse) ProtoMessage() {}
func (x *ListServersResponse) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListServersResponse.ProtoReflect.Descriptor instead.
func (*ListServersResponse) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{1}
}
func (x *ListServersResponse) GetServerIds() []string {
if x != nil {
return x.ServerIds
}
return nil
}
type ListVoiceRelaysRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListVoiceRelaysRequest) Reset() {
*x = ListVoiceRelaysRequest{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListVoiceRelaysRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListVoiceRelaysRequest) ProtoMessage() {}
func (x *ListVoiceRelaysRequest) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListVoiceRelaysRequest.ProtoReflect.Descriptor instead.
func (*ListVoiceRelaysRequest) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{2}
}
type VoiceRelay struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *VoiceRelay) Reset() {
*x = VoiceRelay{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *VoiceRelay) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*VoiceRelay) ProtoMessage() {}
func (x *VoiceRelay) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use VoiceRelay.ProtoReflect.Descriptor instead.
func (*VoiceRelay) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{3}
}
func (x *VoiceRelay) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *VoiceRelay) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *VoiceRelay) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
type ListVoiceRelaysResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
VoiceRelays []*VoiceRelay `protobuf:"bytes,1,rep,name=voice_relays,json=voiceRelays,proto3" json:"voice_relays,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListVoiceRelaysResponse) Reset() {
*x = ListVoiceRelaysResponse{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListVoiceRelaysResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListVoiceRelaysResponse) ProtoMessage() {}
func (x *ListVoiceRelaysResponse) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListVoiceRelaysResponse.ProtoReflect.Descriptor instead.
func (*ListVoiceRelaysResponse) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{4}
}
func (x *ListVoiceRelaysResponse) GetVoiceRelays() []*VoiceRelay {
if x != nil {
return x.VoiceRelays
}
return nil
}
type ListAuthProvidersRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListAuthProvidersRequest) Reset() {
*x = ListAuthProvidersRequest{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListAuthProvidersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListAuthProvidersRequest) ProtoMessage() {}
func (x *ListAuthProvidersRequest) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListAuthProvidersRequest.ProtoReflect.Descriptor instead.
func (*ListAuthProvidersRequest) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{5}
}
type ListAuthProvidersResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
AuthProviders []*AuthProvider `protobuf:"bytes,1,rep,name=auth_providers,json=authProviders,proto3" json:"auth_providers,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListAuthProvidersResponse) Reset() {
*x = ListAuthProvidersResponse{}
mi := &file_konfa_hub_v1_service_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListAuthProvidersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListAuthProvidersResponse) ProtoMessage() {}
func (x *ListAuthProvidersResponse) ProtoReflect() protoreflect.Message {
mi := &file_konfa_hub_v1_service_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListAuthProvidersResponse.ProtoReflect.Descriptor instead.
func (*ListAuthProvidersResponse) Descriptor() ([]byte, []int) {
return file_konfa_hub_v1_service_proto_rawDescGZIP(), []int{6}
}
func (x *ListAuthProvidersResponse) GetAuthProviders() []*AuthProvider {
if x != nil {
return x.AuthProviders
}
return nil
}
var File_konfa_hub_v1_service_proto protoreflect.FileDescriptor
const file_konfa_hub_v1_service_proto_rawDesc = "" +
"\n" +
"\x1akonfa/hub/v1/service.proto\x12\fkonfa.hub.v1\x1a konfa/hub/v1/auth_provider.proto\"\x14\n" +
"\x12ListServersRequest\"4\n" +
"\x13ListServersResponse\x12\x1d\n" +
"\n" +
"server_ids\x18\x01 \x03(\tR\tserverIds\"\x18\n" +
"\x16ListVoiceRelaysRequest\"J\n" +
"\n" +
"VoiceRelay\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\x12\x18\n" +
"\aaddress\x18\x03 \x01(\tR\aaddress\"V\n" +
"\x17ListVoiceRelaysResponse\x12;\n" +
"\fvoice_relays\x18\x01 \x03(\v2\x18.konfa.hub.v1.VoiceRelayR\vvoiceRelays\"\x1a\n" +
"\x18ListAuthProvidersRequest\"^\n" +
"\x19ListAuthProvidersResponse\x12A\n" +
"\x0eauth_providers\x18\x01 \x03(\v2\x1a.konfa.hub.v1.AuthProviderR\rauthProviders2\xa8\x02\n" +
"\n" +
"HubService\x12T\n" +
"\rListServerIDs\x12 .konfa.hub.v1.ListServersRequest\x1a!.konfa.hub.v1.ListServersResponse\x12^\n" +
"\x0fListVoiceRelays\x12$.konfa.hub.v1.ListVoiceRelaysRequest\x1a%.konfa.hub.v1.ListVoiceRelaysResponse\x12d\n" +
"\x11ListAuthProviders\x12&.konfa.hub.v1.ListAuthProvidersRequest\x1a'.konfa.hub.v1.ListAuthProvidersResponseB\xaa\x01\n" +
"\x10com.konfa.hub.v1B\fServiceProtoP\x01Z6github.com/konfa-chat/hub/src/proto/konfa/hub/v1;hubv1\xa2\x02\x03KHX\xaa\x02\fKonfa.Hub.V1\xca\x02\fKonfa\\Hub\\V1\xe2\x02\x18Konfa\\Hub\\V1\\GPBMetadata\xea\x02\x0eKonfa::Hub::V1b\x06proto3"
var (
file_konfa_hub_v1_service_proto_rawDescOnce sync.Once
file_konfa_hub_v1_service_proto_rawDescData []byte
)
func file_konfa_hub_v1_service_proto_rawDescGZIP() []byte {
file_konfa_hub_v1_service_proto_rawDescOnce.Do(func() {
file_konfa_hub_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_konfa_hub_v1_service_proto_rawDesc), len(file_konfa_hub_v1_service_proto_rawDesc)))
})
return file_konfa_hub_v1_service_proto_rawDescData
}
var file_konfa_hub_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_konfa_hub_v1_service_proto_goTypes = []any{
(*ListServersRequest)(nil), // 0: konfa.hub.v1.ListServersRequest
(*ListServersResponse)(nil), // 1: konfa.hub.v1.ListServersResponse
(*ListVoiceRelaysRequest)(nil), // 2: konfa.hub.v1.ListVoiceRelaysRequest
(*VoiceRelay)(nil), // 3: konfa.hub.v1.VoiceRelay
(*ListVoiceRelaysResponse)(nil), // 4: konfa.hub.v1.ListVoiceRelaysResponse
(*ListAuthProvidersRequest)(nil), // 5: konfa.hub.v1.ListAuthProvidersRequest
(*ListAuthProvidersResponse)(nil), // 6: konfa.hub.v1.ListAuthProvidersResponse
(*AuthProvider)(nil), // 7: konfa.hub.v1.AuthProvider
}
var file_konfa_hub_v1_service_proto_depIdxs = []int32{
3, // 0: konfa.hub.v1.ListVoiceRelaysResponse.voice_relays:type_name -> konfa.hub.v1.VoiceRelay
7, // 1: konfa.hub.v1.ListAuthProvidersResponse.auth_providers:type_name -> konfa.hub.v1.AuthProvider
0, // 2: konfa.hub.v1.HubService.ListServerIDs:input_type -> konfa.hub.v1.ListServersRequest
2, // 3: konfa.hub.v1.HubService.ListVoiceRelays:input_type -> konfa.hub.v1.ListVoiceRelaysRequest
5, // 4: konfa.hub.v1.HubService.ListAuthProviders:input_type -> konfa.hub.v1.ListAuthProvidersRequest
1, // 5: konfa.hub.v1.HubService.ListServerIDs:output_type -> konfa.hub.v1.ListServersResponse
4, // 6: konfa.hub.v1.HubService.ListVoiceRelays:output_type -> konfa.hub.v1.ListVoiceRelaysResponse
6, // 7: konfa.hub.v1.HubService.ListAuthProviders:output_type -> konfa.hub.v1.ListAuthProvidersResponse
5, // [5:8] is the sub-list for method output_type
2, // [2:5] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_konfa_hub_v1_service_proto_init() }
func file_konfa_hub_v1_service_proto_init() {
if File_konfa_hub_v1_service_proto != nil {
return
}
file_konfa_hub_v1_auth_provider_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_konfa_hub_v1_service_proto_rawDesc), len(file_konfa_hub_v1_service_proto_rawDesc)),
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_konfa_hub_v1_service_proto_goTypes,
DependencyIndexes: file_konfa_hub_v1_service_proto_depIdxs,
MessageInfos: file_konfa_hub_v1_service_proto_msgTypes,
}.Build()
File_konfa_hub_v1_service_proto = out.File
file_konfa_hub_v1_service_proto_goTypes = nil
file_konfa_hub_v1_service_proto_depIdxs = nil
}

View file

@ -0,0 +1,195 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: konfa/hub/v1/service.proto
package hubv1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
HubService_ListServerIDs_FullMethodName = "/konfa.hub.v1.HubService/ListServerIDs"
HubService_ListVoiceRelays_FullMethodName = "/konfa.hub.v1.HubService/ListVoiceRelays"
HubService_ListAuthProviders_FullMethodName = "/konfa.hub.v1.HubService/ListAuthProviders"
)
// HubServiceClient is the client API for HubService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type HubServiceClient interface {
ListServerIDs(ctx context.Context, in *ListServersRequest, opts ...grpc.CallOption) (*ListServersResponse, error)
ListVoiceRelays(ctx context.Context, in *ListVoiceRelaysRequest, opts ...grpc.CallOption) (*ListVoiceRelaysResponse, error)
ListAuthProviders(ctx context.Context, in *ListAuthProvidersRequest, opts ...grpc.CallOption) (*ListAuthProvidersResponse, error)
}
type hubServiceClient struct {
cc grpc.ClientConnInterface
}
func NewHubServiceClient(cc grpc.ClientConnInterface) HubServiceClient {
return &hubServiceClient{cc}
}
func (c *hubServiceClient) ListServerIDs(ctx context.Context, in *ListServersRequest, opts ...grpc.CallOption) (*ListServersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListServersResponse)
err := c.cc.Invoke(ctx, HubService_ListServerIDs_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *hubServiceClient) ListVoiceRelays(ctx context.Context, in *ListVoiceRelaysRequest, opts ...grpc.CallOption) (*ListVoiceRelaysResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListVoiceRelaysResponse)
err := c.cc.Invoke(ctx, HubService_ListVoiceRelays_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *hubServiceClient) ListAuthProviders(ctx context.Context, in *ListAuthProvidersRequest, opts ...grpc.CallOption) (*ListAuthProvidersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ListAuthProvidersResponse)
err := c.cc.Invoke(ctx, HubService_ListAuthProviders_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// HubServiceServer is the server API for HubService service.
// All implementations should embed UnimplementedHubServiceServer
// for forward compatibility.
type HubServiceServer interface {
ListServerIDs(context.Context, *ListServersRequest) (*ListServersResponse, error)
ListVoiceRelays(context.Context, *ListVoiceRelaysRequest) (*ListVoiceRelaysResponse, error)
ListAuthProviders(context.Context, *ListAuthProvidersRequest) (*ListAuthProvidersResponse, error)
}
// UnimplementedHubServiceServer should be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedHubServiceServer struct{}
func (UnimplementedHubServiceServer) ListServerIDs(context.Context, *ListServersRequest) (*ListServersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListServerIDs not implemented")
}
func (UnimplementedHubServiceServer) ListVoiceRelays(context.Context, *ListVoiceRelaysRequest) (*ListVoiceRelaysResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListVoiceRelays not implemented")
}
func (UnimplementedHubServiceServer) ListAuthProviders(context.Context, *ListAuthProvidersRequest) (*ListAuthProvidersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListAuthProviders not implemented")
}
func (UnimplementedHubServiceServer) testEmbeddedByValue() {}
// UnsafeHubServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to HubServiceServer will
// result in compilation errors.
type UnsafeHubServiceServer interface {
mustEmbedUnimplementedHubServiceServer()
}
func RegisterHubServiceServer(s grpc.ServiceRegistrar, srv HubServiceServer) {
// If the following call pancis, it indicates UnimplementedHubServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&HubService_ServiceDesc, srv)
}
func _HubService_ListServerIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListServersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HubServiceServer).ListServerIDs(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: HubService_ListServerIDs_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HubServiceServer).ListServerIDs(ctx, req.(*ListServersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _HubService_ListVoiceRelays_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListVoiceRelaysRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HubServiceServer).ListVoiceRelays(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: HubService_ListVoiceRelays_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HubServiceServer).ListVoiceRelays(ctx, req.(*ListVoiceRelaysRequest))
}
return interceptor(ctx, in, info, handler)
}
func _HubService_ListAuthProviders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListAuthProvidersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HubServiceServer).ListAuthProviders(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: HubService_ListAuthProviders_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HubServiceServer).ListAuthProviders(ctx, req.(*ListAuthProvidersRequest))
}
return interceptor(ctx, in, info, handler)
}
// HubService_ServiceDesc is the grpc.ServiceDesc for HubService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var HubService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "konfa.hub.v1.HubService",
HandlerType: (*HubServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "ListServerIDs",
Handler: _HubService_ListServerIDs_Handler,
},
{
MethodName: "ListVoiceRelays",
Handler: _HubService_ListVoiceRelays_Handler,
},
{
MethodName: "ListAuthProviders",
Handler: _HubService_ListAuthProviders_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "konfa/hub/v1/service.proto",
}

View file

@ -391,8 +391,8 @@ const file_konfa_server_v1_service_proto_rawDesc = "" +
"\x12ListServerChannels\x12*.konfa.server.v1.ListServerChannelsRequest\x1a+.konfa.server.v1.ListServerChannelsResponse\"\x00\x12f\n" +
"\x0fListServerUsers\x12'.konfa.server.v1.ListServerUsersRequest\x1a(.konfa.server.v1.ListServerUsersResponse\"\x00\x12N\n" +
"\aGetUser\x12\x1f.konfa.server.v1.GetUserRequest\x1a .konfa.server.v1.GetUserResponse\"\x00\x12Z\n" +
"\vCurrentUser\x12#.konfa.server.v1.CurrentUserRequest\x1a$.konfa.server.v1.CurrentUserResponse\"\x00B\xc6\x01\n" +
"\x13com.konfa.server.v1B\fServiceProtoP\x01ZCgithub.com/konfa-chat/hub/src/proto/konfa/server/v1;serverv1\xa2\x02\x03KSX\xaa\x02\x0fKonfa.Server.V1\xca\x02\x0fKonfa\\Server\\V1\xe2\x02\x1bKonfa\\Server\\V1\\GPBMetadata\xea\x02\x11Konfa::Server::V1b\x06proto3"
"\vCurrentUser\x12#.konfa.server.v1.CurrentUserRequest\x1a$.konfa.server.v1.CurrentUserResponse\"\x00B\xbf\x01\n" +
"\x13com.konfa.server.v1B\fServiceProtoP\x01Z<github.com/konfa-chat/hub/src/proto/konfa/server/v1;serverv1\xa2\x02\x03KSX\xaa\x02\x0fKonfa.Server.V1\xca\x02\x0fKonfa\\Server\\V1\xe2\x02\x1bKonfa\\Server\\V1\\GPBMetadata\xea\x02\x11Konfa::Server::V1b\x06proto3"
var (
file_konfa_server_v1_service_proto_rawDescOnce sync.Once

View file

@ -80,8 +80,8 @@ const file_konfa_user_v1_user_proto_rawDesc = "" +
"\x18konfa/user/v1/user.proto\x12\rkonfa.user.v1\"2\n" +
"\x04User\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busernameB\xb5\x01\n" +
"\x11com.konfa.user.v1B\tUserProtoP\x01Z?github.com/konfa-chat/hub/src/proto/konfa/user/v1;userv1\xa2\x02\x03KUX\xaa\x02\rKonfa.User.V1\xca\x02\rKonfa\\User\\V1\xe2\x02\x19Konfa\\User\\V1\\GPBMetadata\xea\x02\x0fKonfa::User::V1b\x06proto3"
"\busername\x18\x02 \x01(\tR\busernameB\xae\x01\n" +
"\x11com.konfa.user.v1B\tUserProtoP\x01Z8github.com/konfa-chat/hub/src/proto/konfa/user/v1;userv1\xa2\x02\x03KUX\xaa\x02\rKonfa.User.V1\xca\x02\rKonfa\\User\\V1\xe2\x02\x19Konfa\\User\\V1\\GPBMetadata\xea\x02\x0fKonfa::User::V1b\x06proto3"
var (
file_konfa_user_v1_user_proto_rawDescOnce sync.Once