From 8b95bb2b1eb932b7389d87d40b8cbb90a677f81e Mon Sep 17 00:00:00 2001 From: Christopher Baklid Date: Sat, 22 Jul 2023 10:41:49 +0200 Subject: [PATCH] Auth interceptor (#10) --- frontend/src/components/Channels.svelte | 2 - frontend/src/lib/grpc.ts | 16 ++--- frontend/src/lib/proto/chat/v1/chat.ts | 30 ++-------- frontend/src/lib/types.ts | 1 - proto/chat/v1/chat.proto | 2 - relay/internal/proto/chat/v1/chat.pb.go | 80 ++++++++++--------------- relay/internal/relay/relay.go | 33 +++++----- relay/internal/server/interceptors.go | 68 +++++++++++++++++++++ relay/internal/server/server.go | 30 +--------- 9 files changed, 127 insertions(+), 135 deletions(-) create mode 100644 relay/internal/server/interceptors.go diff --git a/frontend/src/components/Channels.svelte b/frontend/src/components/Channels.svelte index a4a4e3c..8742754 100644 --- a/frontend/src/components/Channels.svelte +++ b/frontend/src/components/Channels.svelte @@ -8,7 +8,6 @@ const selectChannel = (e: any, channelName: string) => { e.preventDefault(); - console.log('selectedChannel: ' + channelName); channel.set(channelName); }; @@ -26,7 +25,6 @@ SendMessage({ channelId: 'system', text: `channel_add ${name}`, - jwt: pb.authStore.token, userId: pb.authStore.model?.name || '' }); newChannelActive = false; diff --git a/frontend/src/lib/grpc.ts b/frontend/src/lib/grpc.ts index 93ec787..df85822 100644 --- a/frontend/src/lib/grpc.ts +++ b/frontend/src/lib/grpc.ts @@ -27,7 +27,7 @@ const transport = new GrpcWebFetchTransport({ let controller = new AbortController(); -export const Connect = async (serverId: string, userId: string, timestamp: string, jwt: string) => { +export const Connect = async (serverId: string, userId: string, timestamp: string) => { // While the connection is attempting to open, let the UI show a pending state status.pending(); @@ -37,7 +37,7 @@ export const Connect = async (serverId: string, userId: string, timestamp: strin } // The abort controller is used to signal the server to close the stream - const opts = transport.mergeOptions({ abort: controller.signal }); + const opts = transport.mergeOptions({ abort: controller.signal, meta: { jwt: pb.authStore.token } }); // Get the last timestamp from the cache const lastTs = get(chat_cache).lastTs @@ -47,7 +47,6 @@ export const Connect = async (serverId: string, userId: string, timestamp: strin serverId: serverId, userId: userId, lastTs: timestamp, - jwt: jwt, }, opts); @@ -98,18 +97,16 @@ export const Disconnect = async () => { export const SendMessage = (msg: OutgoingMessage) => { const client = new ChatServiceClient(transport); - + const opts = transport.mergeOptions({ meta: { jwt: pb.authStore.token } }) const request: ChatMessage = { channelId: msg.channelId, userId: msg.userId, text: msg.text, ts: "0", // The server will set the timestamp - jwt: msg.jwt, }; - client.send(request).then((response) => { - - console.log(response.status.code); + client.send(request, opts).then((_) => { + // nothing }).catch((e) => { console.log(e); }); @@ -157,18 +154,15 @@ const filter_system_messages = (msg: ChatMessage): boolean => { // Tell UI to show new channel when another user adds one if (msg.text.startsWith("channel_add") && msg.userId !== pb.authStore.model?.name) { const channel_name = msg.text.split(" ")[1] - console.log(channel_name) channels.add(channel_name); } if (msg.text.startsWith("connected")) { - console.log("connected", msg.userId) const user: User = { name: msg.userId, presence: true } users.upd(user); } if (msg.text.startsWith("disconnected")) { - console.log("disconnected", msg.userId) const user: User = { name: msg.userId, presence: false } users.upd(user); } diff --git a/frontend/src/lib/proto/chat/v1/chat.ts b/frontend/src/lib/proto/chat/v1/chat.ts index a09fdee..6d15f3d 100644 --- a/frontend/src/lib/proto/chat/v1/chat.ts +++ b/frontend/src/lib/proto/chat/v1/chat.ts @@ -30,10 +30,6 @@ export interface ConnectRequest { * @generated from protobuf field: string last_ts = 3; */ lastTs: string; // last timestamp received by the client - /** - * @generated from protobuf field: string jwt = 4; - */ - jwt: string; } /** * Chat server stream after subscribing to a channel @@ -57,10 +53,6 @@ export interface ChatMessage { * @generated from protobuf field: string ts = 4; */ ts: string; // timestamp - /** - * @generated from protobuf field: string jwt = 5; - */ - jwt: string; } /** * The response payload after sending a notification @@ -83,12 +75,11 @@ class ConnectRequest$Type extends MessageType { super("proto.chat.v1.ConnectRequest", [ { no: 1, name: "server_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "user_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 3, name: "last_ts", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 4, name: "jwt", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 3, name: "last_ts", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): ConnectRequest { - const message = { serverId: "", userId: "", lastTs: "", jwt: "" }; + const message = { serverId: "", userId: "", lastTs: "" }; globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== undefined) reflectionMergePartial(this, message, value); @@ -108,9 +99,6 @@ class ConnectRequest$Type extends MessageType { case /* string last_ts */ 3: message.lastTs = reader.string(); break; - case /* string jwt */ 4: - message.jwt = reader.string(); - break; default: let u = options.readUnknownField; if (u === "throw") @@ -132,9 +120,6 @@ class ConnectRequest$Type extends MessageType { /* string last_ts = 3; */ if (message.lastTs !== "") writer.tag(3, WireType.LengthDelimited).string(message.lastTs); - /* string jwt = 4; */ - if (message.jwt !== "") - writer.tag(4, WireType.LengthDelimited).string(message.jwt); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -152,12 +137,11 @@ class ChatMessage$Type extends MessageType { { no: 1, name: "channel_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 2, name: "user_id", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, { no: 3, name: "text", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 4, name: "ts", kind: "scalar", T: 9 /*ScalarType.STRING*/ }, - { no: 5, name: "jwt", kind: "scalar", T: 9 /*ScalarType.STRING*/ } + { no: 4, name: "ts", kind: "scalar", T: 9 /*ScalarType.STRING*/ } ]); } create(value?: PartialMessage): ChatMessage { - const message = { channelId: "", userId: "", text: "", ts: "", jwt: "" }; + const message = { channelId: "", userId: "", text: "", ts: "" }; globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== undefined) reflectionMergePartial(this, message, value); @@ -180,9 +164,6 @@ class ChatMessage$Type extends MessageType { case /* string ts */ 4: message.ts = reader.string(); break; - case /* string jwt */ 5: - message.jwt = reader.string(); - break; default: let u = options.readUnknownField; if (u === "throw") @@ -207,9 +188,6 @@ class ChatMessage$Type extends MessageType { /* string ts = 4; */ if (message.ts !== "") writer.tag(4, WireType.LengthDelimited).string(message.ts); - /* string jwt = 5; */ - if (message.jwt !== "") - writer.tag(5, WireType.LengthDelimited).string(message.jwt); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index e275928..80f2dca 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -9,5 +9,4 @@ export interface OutgoingMessage { channelId: string; userId: string; text: string; - jwt: string; } diff --git a/proto/chat/v1/chat.proto b/proto/chat/v1/chat.proto index aac093a..d958ff9 100644 --- a/proto/chat/v1/chat.proto +++ b/proto/chat/v1/chat.proto @@ -14,7 +14,6 @@ message ConnectRequest { string server_id = 1; string user_id = 2; string last_ts = 3; // last timestamp received by the client - string jwt = 4; } // Chat server stream after subscribing to a channel @@ -23,7 +22,6 @@ message ChatMessage { string user_id = 2; string text = 3; string ts = 4; // timestamp - string jwt = 5; } // The response payload after sending a notification diff --git a/relay/internal/proto/chat/v1/chat.pb.go b/relay/internal/proto/chat/v1/chat.pb.go index 8d85382..db0d81e 100644 --- a/relay/internal/proto/chat/v1/chat.pb.go +++ b/relay/internal/proto/chat/v1/chat.pb.go @@ -29,7 +29,6 @@ type ConnectRequest struct { ServerId string `protobuf:"bytes,1,opt,name=server_id,json=serverId,proto3" json:"server_id,omitempty"` UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` LastTs string `protobuf:"bytes,3,opt,name=last_ts,json=lastTs,proto3" json:"last_ts,omitempty"` // last timestamp received by the client - Jwt string `protobuf:"bytes,4,opt,name=jwt,proto3" json:"jwt,omitempty"` } func (x *ConnectRequest) Reset() { @@ -85,13 +84,6 @@ func (x *ConnectRequest) GetLastTs() string { return "" } -func (x *ConnectRequest) GetJwt() string { - if x != nil { - return x.Jwt - } - return "" -} - // Chat server stream after subscribing to a channel type ChatMessage struct { state protoimpl.MessageState @@ -102,7 +94,6 @@ type ChatMessage struct { UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` Text string `protobuf:"bytes,3,opt,name=text,proto3" json:"text,omitempty"` Ts string `protobuf:"bytes,4,opt,name=ts,proto3" json:"ts,omitempty"` // timestamp - Jwt string `protobuf:"bytes,5,opt,name=jwt,proto3" json:"jwt,omitempty"` } func (x *ChatMessage) Reset() { @@ -165,13 +156,6 @@ func (x *ChatMessage) GetTs() string { return "" } -func (x *ChatMessage) GetJwt() string { - if x != nil { - return x.Jwt - } - return "" -} - // The response payload after sending a notification type SendResponse struct { state protoimpl.MessageState @@ -233,44 +217,42 @@ var File_proto_chat_v1_chat_proto protoreflect.FileDescriptor var file_proto_chat_v1_chat_proto_rawDesc = []byte{ 0x0a, 0x18, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x22, 0x71, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, + 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x22, 0x5f, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x7b, 0x0a, 0x0b, - 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x34, 0x0a, 0x0c, 0x53, 0x65, 0x6e, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, - 0x9a, 0x01, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x48, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x04, 0x53, 0x65, 0x6e, - 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1b, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x87, 0x01, 0x0a, - 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, - 0x76, 0x31, 0x42, 0x09, 0x43, 0x68, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x11, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x68, - 0x61, 0x74, 0xa2, 0x02, 0x03, 0x50, 0x43, 0x58, 0xaa, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x43, 0x68, 0x61, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x5c, 0x43, 0x68, 0x61, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x5c, 0x43, 0x68, 0x61, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x43, 0x68, - 0x61, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x54, 0x73, 0x22, 0x69, 0x0a, 0x0b, 0x43, 0x68, + 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x74, 0x73, 0x22, 0x34, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0x9a, 0x01, 0x0a, 0x0b, + 0x43, 0x68, 0x61, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, + 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, + 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x87, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x09, + 0x43, 0x68, 0x61, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x11, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x68, 0x61, 0x74, 0xa2, 0x02, + 0x03, 0x50, 0x43, 0x58, 0xaa, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, + 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x43, 0x68, 0x61, + 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x43, 0x68, 0x61, + 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x43, 0x68, 0x61, 0x74, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/relay/internal/relay/relay.go b/relay/internal/relay/relay.go index c07a3ef..5364899 100644 --- a/relay/internal/relay/relay.go +++ b/relay/internal/relay/relay.go @@ -4,20 +4,22 @@ import ( "fmt" "log" "net" - "time" + "github.com/inveracity/svelte-grpc-stream/internal/auth" "github.com/inveracity/svelte-grpc-stream/internal/cache" pb "github.com/inveracity/svelte-grpc-stream/internal/proto/chat/v1" "github.com/inveracity/svelte-grpc-stream/internal/server" "github.com/redis/go-redis/v9" "google.golang.org/grpc" - "google.golang.org/grpc/keepalive" ) type Relay struct { - server *server.Server - port int + server *server.Server + port int + pbURL string + pbAdmin string + pbPass string } func NewRelay(port int, natsURL, redisURL, pbURL, pbAdmin, pbPass string) *Relay { @@ -29,10 +31,13 @@ func NewRelay(port int, natsURL, redisURL, pbURL, pbAdmin, pbPass string) *Relay cache := cache.NewCache(redisClient) - grpcServer := server.NewServer(natsURL, pbURL, pbAdmin, pbPass, cache) + grpcServer := server.NewServer(natsURL, cache) return &Relay{ - port: port, - server: grpcServer, + port: port, + server: grpcServer, + pbURL: pbURL, + pbAdmin: pbAdmin, + pbPass: pbPass, } } @@ -42,16 +47,14 @@ func (r *Relay) Run() error { log.Fatalf("failed to listen: %v", err) } + authMgr := auth.New(r.pbURL, r.pbAdmin, r.pbPass) + interceptor := server.NewAuthInterceptor(authMgr) + s := grpc.NewServer( - grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ - MinTime: time.Duration(1 * time.Second), - PermitWithoutStream: true, // Allow pings even when there are no active streams - }), - grpc.KeepaliveParams(keepalive.ServerParameters{ - Time: time.Duration(2 * time.Hour), - Timeout: time.Duration(20 * time.Second), - }), + grpc.UnaryInterceptor(interceptor.Unary()), + grpc.StreamInterceptor(interceptor.Stream()), ) + pb.RegisterChatServiceServer(s, r.server) log.Printf("GRPC: server listening at %v", lis.Addr()) diff --git a/relay/internal/server/interceptors.go b/relay/internal/server/interceptors.go new file mode 100644 index 0000000..e5e3bd0 --- /dev/null +++ b/relay/internal/server/interceptors.go @@ -0,0 +1,68 @@ +package server + +import ( + "context" + "fmt" + + "github.com/inveracity/svelte-grpc-stream/internal/auth" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" +) + +type AuthInterceptor struct { + authMgr *auth.Auth +} + +func NewAuthInterceptor(authMgr *auth.Auth) *AuthInterceptor { + return &AuthInterceptor{ + authMgr: authMgr, + } +} + +func (interceptor *AuthInterceptor) authorize(ctx context.Context) error { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return fmt.Errorf("no metadata found") + } + + token := md.Get("jwt") + + authed, err := interceptor.authMgr.VerifyUserToken(token[0]) + if err != nil || !authed { + return fmt.Errorf("user not authorized") + } + return nil +} + +func (interceptor *AuthInterceptor) Stream() grpc.StreamServerInterceptor { + return func( + srv interface{}, + stream grpc.ServerStream, + info *grpc.StreamServerInfo, + handler grpc.StreamHandler, + ) error { + + err := interceptor.authorize(stream.Context()) + if err != nil { + return err + } + return handler(srv, stream) + } +} + +func (interceptor *AuthInterceptor) Unary() grpc.UnaryServerInterceptor { + return func( + ctx context.Context, + req interface{}, + info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler, + ) (interface{}, error) { + + err := interceptor.authorize(ctx) + if err != nil { + return nil, err + } + + return handler(ctx, req) + } +} diff --git a/relay/internal/server/server.go b/relay/internal/server/server.go index ae96847..d0426a1 100644 --- a/relay/internal/server/server.go +++ b/relay/internal/server/server.go @@ -8,7 +8,6 @@ import ( "github.com/nats-io/nats.go" - "github.com/inveracity/svelte-grpc-stream/internal/auth" "github.com/inveracity/svelte-grpc-stream/internal/cache" pb "github.com/inveracity/svelte-grpc-stream/internal/proto/chat/v1" "github.com/inveracity/svelte-grpc-stream/internal/queue" @@ -22,18 +21,12 @@ type Server struct { queue *queue.Queue streamid string natsURL string - pbURL string - pbAdmin string - pbPass string } -func NewServer(natsURL, pbURL, pbAdmin, pbPass string, cache *cache.Cache) *Server { +func NewServer(natsURL string, cache *cache.Cache) *Server { return &Server{ cache: cache, natsURL: natsURL, - pbURL: pbURL, - pbAdmin: pbAdmin, - pbPass: pbPass, } } @@ -43,19 +36,6 @@ func (s *Server) Connect(in *pb.ConnectRequest, srv pb.ChatService_ConnectServer log.Printf("GRPC %s: user %s connected to server %s", s.streamid, in.UserId, in.ServerId) - auth := auth.New(s.pbURL, s.pbAdmin, s.pbPass) - - authed, err := auth.VerifyUserToken(in.Jwt) - if err != nil { - log.Printf("GRPC %s: error verifying jwt: %v", s.streamid, err) - return fmt.Errorf("error verifying jwt") - } - - if !authed { - log.Printf("GRPC %s: user %s not authorized", s.streamid, in.UserId) - return fmt.Errorf("user not authorized") - } - // Create a NATS queue subscriber for this s.streamid s.queue = queue.NewQueue(s.natsURL, s.streamid) @@ -99,14 +79,6 @@ func (s *Server) Connect(in *pb.ConnectRequest, srv pb.ChatService_ConnectServer // Send: receives a message from the client and publishes it to the NATS server func (s *Server) Send(ctx context.Context, in *pb.ChatMessage) (*pb.SendResponse, error) { - auth := auth.New(s.pbURL, s.pbAdmin, s.pbPass) - - authed, err := auth.VerifyUserToken(in.Jwt) - - if err != nil || !authed { - return nil, fmt.Errorf("user not authorized") - } - q := queue.NewQueue(s.natsURL, "") // Override timstamp in.Ts = fmt.Sprint(time.Now().UnixNano())