diff --git a/api/gen/proto/go/vcs/v1/vcs.pb.go b/api/gen/proto/go/vcs/v1/vcs.pb.go index 3f276f0236..4e980b5e1a 100644 --- a/api/gen/proto/go/vcs/v1/vcs.pb.go +++ b/api/gen/proto/go/vcs/v1/vcs.pb.go @@ -199,6 +199,91 @@ func (x *GithubLoginResponse) GetCookie() string { return "" } +type GithubRefreshRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GithubRefreshRequest) Reset() { + *x = GithubRefreshRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vcs_v1_vcs_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GithubRefreshRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GithubRefreshRequest) ProtoMessage() {} + +func (x *GithubRefreshRequest) ProtoReflect() protoreflect.Message { + mi := &file_vcs_v1_vcs_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GithubRefreshRequest.ProtoReflect.Descriptor instead. +func (*GithubRefreshRequest) Descriptor() ([]byte, []int) { + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{4} +} + +type GithubRefreshResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cookie string `protobuf:"bytes,1,opt,name=cookie,proto3" json:"cookie,omitempty"` +} + +func (x *GithubRefreshResponse) Reset() { + *x = GithubRefreshResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vcs_v1_vcs_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GithubRefreshResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GithubRefreshResponse) ProtoMessage() {} + +func (x *GithubRefreshResponse) ProtoReflect() protoreflect.Message { + mi := &file_vcs_v1_vcs_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GithubRefreshResponse.ProtoReflect.Descriptor instead. +func (*GithubRefreshResponse) Descriptor() ([]byte, []int) { + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{5} +} + +func (x *GithubRefreshResponse) GetCookie() string { + if x != nil { + return x.Cookie + } + return "" +} + type GetFileRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -215,7 +300,7 @@ type GetFileRequest struct { func (x *GetFileRequest) Reset() { *x = GetFileRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vcs_v1_vcs_proto_msgTypes[4] + mi := &file_vcs_v1_vcs_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -228,7 +313,7 @@ func (x *GetFileRequest) String() string { func (*GetFileRequest) ProtoMessage() {} func (x *GetFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_vcs_v1_vcs_proto_msgTypes[4] + mi := &file_vcs_v1_vcs_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -241,7 +326,7 @@ func (x *GetFileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFileRequest.ProtoReflect.Descriptor instead. func (*GetFileRequest) Descriptor() ([]byte, []int) { - return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{4} + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{6} } func (x *GetFileRequest) GetRepositoryURL() string { @@ -279,7 +364,7 @@ type GetFileResponse struct { func (x *GetFileResponse) Reset() { *x = GetFileResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vcs_v1_vcs_proto_msgTypes[5] + mi := &file_vcs_v1_vcs_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -292,7 +377,7 @@ func (x *GetFileResponse) String() string { func (*GetFileResponse) ProtoMessage() {} func (x *GetFileResponse) ProtoReflect() protoreflect.Message { - mi := &file_vcs_v1_vcs_proto_msgTypes[5] + mi := &file_vcs_v1_vcs_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -305,7 +390,7 @@ func (x *GetFileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFileResponse.ProtoReflect.Descriptor instead. func (*GetFileResponse) Descriptor() ([]byte, []int) { - return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{5} + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{7} } func (x *GetFileResponse) GetContent() string { @@ -336,7 +421,7 @@ type GetCommitRequest struct { func (x *GetCommitRequest) Reset() { *x = GetCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vcs_v1_vcs_proto_msgTypes[6] + mi := &file_vcs_v1_vcs_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -349,7 +434,7 @@ func (x *GetCommitRequest) String() string { func (*GetCommitRequest) ProtoMessage() {} func (x *GetCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_vcs_v1_vcs_proto_msgTypes[6] + mi := &file_vcs_v1_vcs_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -362,7 +447,7 @@ func (x *GetCommitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCommitRequest.ProtoReflect.Descriptor instead. func (*GetCommitRequest) Descriptor() ([]byte, []int) { - return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{6} + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{8} } func (x *GetCommitRequest) GetRepositoryURL() string { @@ -399,7 +484,7 @@ type GetCommitResponse struct { func (x *GetCommitResponse) Reset() { *x = GetCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vcs_v1_vcs_proto_msgTypes[7] + mi := &file_vcs_v1_vcs_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -412,7 +497,7 @@ func (x *GetCommitResponse) String() string { func (*GetCommitResponse) ProtoMessage() {} func (x *GetCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_vcs_v1_vcs_proto_msgTypes[7] + mi := &file_vcs_v1_vcs_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -425,7 +510,7 @@ func (x *GetCommitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetCommitResponse.ProtoReflect.Descriptor instead. func (*GetCommitResponse) Descriptor() ([]byte, []int) { - return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{7} + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{9} } func (x *GetCommitResponse) GetMessage() string { @@ -477,7 +562,7 @@ type CommitAuthor struct { func (x *CommitAuthor) Reset() { *x = CommitAuthor{} if protoimpl.UnsafeEnabled { - mi := &file_vcs_v1_vcs_proto_msgTypes[8] + mi := &file_vcs_v1_vcs_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -490,7 +575,7 @@ func (x *CommitAuthor) String() string { func (*CommitAuthor) ProtoMessage() {} func (x *CommitAuthor) ProtoReflect() protoreflect.Message { - mi := &file_vcs_v1_vcs_proto_msgTypes[8] + mi := &file_vcs_v1_vcs_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -503,7 +588,7 @@ func (x *CommitAuthor) ProtoReflect() protoreflect.Message { // Deprecated: Use CommitAuthor.ProtoReflect.Descriptor instead. func (*CommitAuthor) Descriptor() ([]byte, []int) { - return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{8} + return file_vcs_v1_vcs_proto_rawDescGZIP(), []int{10} } func (x *CommitAuthor) GetLogin() string { @@ -536,63 +621,72 @@ var file_vcs_v1_vcs_proto_rawDesc = []byte{ 0x6f, 0x64, 0x65, 0x22, 0x2d, 0x0a, 0x13, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6f, 0x6b, - 0x69, 0x65, 0x22, 0x66, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, - 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x22, 0x3d, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x52, 0x4c, 0x22, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, + 0x69, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x47, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x22, 0x66, 0x0a, 0x0e, 0x47, + 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x72, 0x65, 0x66, 0x22, 0x93, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x52, 0x06, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x52, 0x4c, 0x22, 0x42, 0x0a, 0x0c, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, - 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, - 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x52, 0x4c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x52, 0x4c, 0x32, - 0x9c, 0x02, 0x0a, 0x0a, 0x56, 0x43, 0x53, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, - 0x0a, 0x09, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x12, 0x18, 0x2e, 0x76, 0x63, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, - 0x6e, 0x12, 0x1a, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, - 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, - 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x16, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x17, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x8b, - 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x56, - 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, - 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, - 0x76, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x56, 0x63, - 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x56, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, - 0x56, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x07, 0x56, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, + 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, + 0x61, 0x74, 0x68, 0x22, 0x3d, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, + 0x52, 0x4c, 0x22, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x12, 0x10, 0x0a, 0x03, + 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x65, 0x66, 0x22, 0x93, + 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, + 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x73, 0x68, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, + 0x68, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x55, 0x52, 0x4c, 0x22, 0x42, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x72, 0x55, 0x52, 0x4c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x52, 0x4c, 0x32, 0xec, 0x02, 0x0a, 0x0a, 0x56, 0x43, 0x53, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x41, 0x70, 0x70, 0x12, 0x18, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x47, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1a, 0x2e, 0x76, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0d, 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x1c, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x69, 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x16, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x12, 0x18, 0x2e, 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x8b, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, + 0x76, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x56, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x79, 0x72, 0x6f, 0x73, 0x63, 0x6f, 0x70, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x2f, 0x76, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x56, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x56, 0x63, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, + 0x56, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x56, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x56, 0x63, + 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -607,33 +701,37 @@ func file_vcs_v1_vcs_proto_rawDescGZIP() []byte { return file_vcs_v1_vcs_proto_rawDescData } -var file_vcs_v1_vcs_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_vcs_v1_vcs_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_vcs_v1_vcs_proto_goTypes = []interface{}{ - (*GithubAppRequest)(nil), // 0: vcs.v1.GithubAppRequest - (*GithubAppResponse)(nil), // 1: vcs.v1.GithubAppResponse - (*GithubLoginRequest)(nil), // 2: vcs.v1.GithubLoginRequest - (*GithubLoginResponse)(nil), // 3: vcs.v1.GithubLoginResponse - (*GetFileRequest)(nil), // 4: vcs.v1.GetFileRequest - (*GetFileResponse)(nil), // 5: vcs.v1.GetFileResponse - (*GetCommitRequest)(nil), // 6: vcs.v1.GetCommitRequest - (*GetCommitResponse)(nil), // 7: vcs.v1.GetCommitResponse - (*CommitAuthor)(nil), // 8: vcs.v1.CommitAuthor + (*GithubAppRequest)(nil), // 0: vcs.v1.GithubAppRequest + (*GithubAppResponse)(nil), // 1: vcs.v1.GithubAppResponse + (*GithubLoginRequest)(nil), // 2: vcs.v1.GithubLoginRequest + (*GithubLoginResponse)(nil), // 3: vcs.v1.GithubLoginResponse + (*GithubRefreshRequest)(nil), // 4: vcs.v1.GithubRefreshRequest + (*GithubRefreshResponse)(nil), // 5: vcs.v1.GithubRefreshResponse + (*GetFileRequest)(nil), // 6: vcs.v1.GetFileRequest + (*GetFileResponse)(nil), // 7: vcs.v1.GetFileResponse + (*GetCommitRequest)(nil), // 8: vcs.v1.GetCommitRequest + (*GetCommitResponse)(nil), // 9: vcs.v1.GetCommitResponse + (*CommitAuthor)(nil), // 10: vcs.v1.CommitAuthor } var file_vcs_v1_vcs_proto_depIdxs = []int32{ - 8, // 0: vcs.v1.GetCommitResponse.author:type_name -> vcs.v1.CommitAuthor - 0, // 1: vcs.v1.VCSService.GithubApp:input_type -> vcs.v1.GithubAppRequest - 2, // 2: vcs.v1.VCSService.GithubLogin:input_type -> vcs.v1.GithubLoginRequest - 4, // 3: vcs.v1.VCSService.GetFile:input_type -> vcs.v1.GetFileRequest - 6, // 4: vcs.v1.VCSService.GetCommit:input_type -> vcs.v1.GetCommitRequest - 1, // 5: vcs.v1.VCSService.GithubApp:output_type -> vcs.v1.GithubAppResponse - 3, // 6: vcs.v1.VCSService.GithubLogin:output_type -> vcs.v1.GithubLoginResponse - 5, // 7: vcs.v1.VCSService.GetFile:output_type -> vcs.v1.GetFileResponse - 7, // 8: vcs.v1.VCSService.GetCommit:output_type -> vcs.v1.GetCommitResponse - 5, // [5:9] is the sub-list for method output_type - 1, // [1:5] 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 + 10, // 0: vcs.v1.GetCommitResponse.author:type_name -> vcs.v1.CommitAuthor + 0, // 1: vcs.v1.VCSService.GithubApp:input_type -> vcs.v1.GithubAppRequest + 2, // 2: vcs.v1.VCSService.GithubLogin:input_type -> vcs.v1.GithubLoginRequest + 4, // 3: vcs.v1.VCSService.GithubRefresh:input_type -> vcs.v1.GithubRefreshRequest + 6, // 4: vcs.v1.VCSService.GetFile:input_type -> vcs.v1.GetFileRequest + 8, // 5: vcs.v1.VCSService.GetCommit:input_type -> vcs.v1.GetCommitRequest + 1, // 6: vcs.v1.VCSService.GithubApp:output_type -> vcs.v1.GithubAppResponse + 3, // 7: vcs.v1.VCSService.GithubLogin:output_type -> vcs.v1.GithubLoginResponse + 5, // 8: vcs.v1.VCSService.GithubRefresh:output_type -> vcs.v1.GithubRefreshResponse + 7, // 9: vcs.v1.VCSService.GetFile:output_type -> vcs.v1.GetFileResponse + 9, // 10: vcs.v1.VCSService.GetCommit:output_type -> vcs.v1.GetCommitResponse + 6, // [6:11] is the sub-list for method output_type + 1, // [1:6] 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_vcs_v1_vcs_proto_init() } @@ -691,7 +789,7 @@ func file_vcs_v1_vcs_proto_init() { } } file_vcs_v1_vcs_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFileRequest); i { + switch v := v.(*GithubRefreshRequest); i { case 0: return &v.state case 1: @@ -703,7 +801,7 @@ func file_vcs_v1_vcs_proto_init() { } } file_vcs_v1_vcs_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetFileResponse); i { + switch v := v.(*GithubRefreshResponse); i { case 0: return &v.state case 1: @@ -715,7 +813,7 @@ func file_vcs_v1_vcs_proto_init() { } } file_vcs_v1_vcs_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCommitRequest); i { + switch v := v.(*GetFileRequest); i { case 0: return &v.state case 1: @@ -727,7 +825,7 @@ func file_vcs_v1_vcs_proto_init() { } } file_vcs_v1_vcs_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetCommitResponse); i { + switch v := v.(*GetFileResponse); i { case 0: return &v.state case 1: @@ -739,6 +837,30 @@ func file_vcs_v1_vcs_proto_init() { } } file_vcs_v1_vcs_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetCommitRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vcs_v1_vcs_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetCommitResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vcs_v1_vcs_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CommitAuthor); i { case 0: return &v.state @@ -757,7 +879,7 @@ func file_vcs_v1_vcs_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vcs_v1_vcs_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/api/gen/proto/go/vcs/v1/vcs_vtproto.pb.go b/api/gen/proto/go/vcs/v1/vcs_vtproto.pb.go index 83d74f89d9..7f45d2ff76 100644 --- a/api/gen/proto/go/vcs/v1/vcs_vtproto.pb.go +++ b/api/gen/proto/go/vcs/v1/vcs_vtproto.pb.go @@ -93,6 +93,40 @@ func (m *GithubLoginResponse) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *GithubRefreshRequest) CloneVT() *GithubRefreshRequest { + if m == nil { + return (*GithubRefreshRequest)(nil) + } + r := &GithubRefreshRequest{} + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GithubRefreshRequest) CloneMessageVT() proto.Message { + return m.CloneVT() +} + +func (m *GithubRefreshResponse) CloneVT() *GithubRefreshResponse { + if m == nil { + return (*GithubRefreshResponse)(nil) + } + r := &GithubRefreshResponse{ + Cookie: m.Cookie, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *GithubRefreshResponse) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *GetFileRequest) CloneVT() *GetFileRequest { if m == nil { return (*GetFileRequest)(nil) @@ -265,6 +299,41 @@ func (this *GithubLoginResponse) EqualMessageVT(thatMsg proto.Message) bool { } return this.EqualVT(that) } +func (this *GithubRefreshRequest) EqualVT(that *GithubRefreshRequest) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *GithubRefreshRequest) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*GithubRefreshRequest) + if !ok { + return false + } + return this.EqualVT(that) +} +func (this *GithubRefreshResponse) EqualVT(that *GithubRefreshResponse) bool { + if this == that { + return true + } else if this == nil || that == nil { + return false + } + if this.Cookie != that.Cookie { + return false + } + return string(this.unknownFields) == string(that.unknownFields) +} + +func (this *GithubRefreshResponse) EqualMessageVT(thatMsg proto.Message) bool { + that, ok := thatMsg.(*GithubRefreshResponse) + if !ok { + return false + } + return this.EqualVT(that) +} func (this *GetFileRequest) EqualVT(that *GetFileRequest) bool { if this == that { return true @@ -399,6 +468,7 @@ const _ = grpc.SupportPackageIsVersion7 type VCSServiceClient interface { GithubApp(ctx context.Context, in *GithubAppRequest, opts ...grpc.CallOption) (*GithubAppResponse, error) GithubLogin(ctx context.Context, in *GithubLoginRequest, opts ...grpc.CallOption) (*GithubLoginResponse, error) + GithubRefresh(ctx context.Context, in *GithubRefreshRequest, opts ...grpc.CallOption) (*GithubRefreshResponse, error) GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileResponse, error) GetCommit(ctx context.Context, in *GetCommitRequest, opts ...grpc.CallOption) (*GetCommitResponse, error) } @@ -429,6 +499,15 @@ func (c *vCSServiceClient) GithubLogin(ctx context.Context, in *GithubLoginReque return out, nil } +func (c *vCSServiceClient) GithubRefresh(ctx context.Context, in *GithubRefreshRequest, opts ...grpc.CallOption) (*GithubRefreshResponse, error) { + out := new(GithubRefreshResponse) + err := c.cc.Invoke(ctx, "/vcs.v1.VCSService/GithubRefresh", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vCSServiceClient) GetFile(ctx context.Context, in *GetFileRequest, opts ...grpc.CallOption) (*GetFileResponse, error) { out := new(GetFileResponse) err := c.cc.Invoke(ctx, "/vcs.v1.VCSService/GetFile", in, out, opts...) @@ -453,6 +532,7 @@ func (c *vCSServiceClient) GetCommit(ctx context.Context, in *GetCommitRequest, type VCSServiceServer interface { GithubApp(context.Context, *GithubAppRequest) (*GithubAppResponse, error) GithubLogin(context.Context, *GithubLoginRequest) (*GithubLoginResponse, error) + GithubRefresh(context.Context, *GithubRefreshRequest) (*GithubRefreshResponse, error) GetFile(context.Context, *GetFileRequest) (*GetFileResponse, error) GetCommit(context.Context, *GetCommitRequest) (*GetCommitResponse, error) mustEmbedUnimplementedVCSServiceServer() @@ -468,6 +548,9 @@ func (UnimplementedVCSServiceServer) GithubApp(context.Context, *GithubAppReques func (UnimplementedVCSServiceServer) GithubLogin(context.Context, *GithubLoginRequest) (*GithubLoginResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GithubLogin not implemented") } +func (UnimplementedVCSServiceServer) GithubRefresh(context.Context, *GithubRefreshRequest) (*GithubRefreshResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GithubRefresh not implemented") +} func (UnimplementedVCSServiceServer) GetFile(context.Context, *GetFileRequest) (*GetFileResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetFile not implemented") } @@ -523,6 +606,24 @@ func _VCSService_GithubLogin_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _VCSService_GithubRefresh_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GithubRefreshRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VCSServiceServer).GithubRefresh(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vcs.v1.VCSService/GithubRefresh", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VCSServiceServer).GithubRefresh(ctx, req.(*GithubRefreshRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _VCSService_GetFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetFileRequest) if err := dec(in); err != nil { @@ -574,6 +675,10 @@ var VCSService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GithubLogin", Handler: _VCSService_GithubLogin_Handler, }, + { + MethodName: "GithubRefresh", + Handler: _VCSService_GithubRefresh_Handler, + }, { MethodName: "GetFile", Handler: _VCSService_GetFile_Handler, @@ -740,6 +845,79 @@ func (m *GithubLoginResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *GithubRefreshRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GithubRefreshRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GithubRefreshRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *GithubRefreshResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GithubRefreshResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *GithubRefreshResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Cookie) > 0 { + i -= len(m.Cookie) + copy(dAtA[i:], m.Cookie) + i = encodeVarint(dAtA, i, uint64(len(m.Cookie))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *GetFileRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -1069,6 +1247,30 @@ func (m *GithubLoginResponse) SizeVT() (n int) { return n } +func (m *GithubRefreshRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *GithubRefreshResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Cookie) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func (m *GetFileRequest) SizeVT() (n int) { if m == nil { return 0 @@ -1481,6 +1683,140 @@ func (m *GithubLoginResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *GithubRefreshRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GithubRefreshRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GithubRefreshRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GithubRefreshResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GithubRefreshResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GithubRefreshResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cookie", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cookie = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *GetFileRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.go b/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.go index d8c727421f..1176a6bb5b 100644 --- a/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.go +++ b/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.go @@ -37,6 +37,9 @@ const ( VCSServiceGithubAppProcedure = "/vcs.v1.VCSService/GithubApp" // VCSServiceGithubLoginProcedure is the fully-qualified name of the VCSService's GithubLogin RPC. VCSServiceGithubLoginProcedure = "/vcs.v1.VCSService/GithubLogin" + // VCSServiceGithubRefreshProcedure is the fully-qualified name of the VCSService's GithubRefresh + // RPC. + VCSServiceGithubRefreshProcedure = "/vcs.v1.VCSService/GithubRefresh" // VCSServiceGetFileProcedure is the fully-qualified name of the VCSService's GetFile RPC. VCSServiceGetFileProcedure = "/vcs.v1.VCSService/GetFile" // VCSServiceGetCommitProcedure is the fully-qualified name of the VCSService's GetCommit RPC. @@ -45,17 +48,19 @@ const ( // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - vCSServiceServiceDescriptor = v1.File_vcs_v1_vcs_proto.Services().ByName("VCSService") - vCSServiceGithubAppMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GithubApp") - vCSServiceGithubLoginMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GithubLogin") - vCSServiceGetFileMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GetFile") - vCSServiceGetCommitMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GetCommit") + vCSServiceServiceDescriptor = v1.File_vcs_v1_vcs_proto.Services().ByName("VCSService") + vCSServiceGithubAppMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GithubApp") + vCSServiceGithubLoginMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GithubLogin") + vCSServiceGithubRefreshMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GithubRefresh") + vCSServiceGetFileMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GetFile") + vCSServiceGetCommitMethodDescriptor = vCSServiceServiceDescriptor.Methods().ByName("GetCommit") ) // VCSServiceClient is a client for the vcs.v1.VCSService service. type VCSServiceClient interface { GithubApp(context.Context, *connect.Request[v1.GithubAppRequest]) (*connect.Response[v1.GithubAppResponse], error) GithubLogin(context.Context, *connect.Request[v1.GithubLoginRequest]) (*connect.Response[v1.GithubLoginResponse], error) + GithubRefresh(context.Context, *connect.Request[v1.GithubRefreshRequest]) (*connect.Response[v1.GithubRefreshResponse], error) GetFile(context.Context, *connect.Request[v1.GetFileRequest]) (*connect.Response[v1.GetFileResponse], error) GetCommit(context.Context, *connect.Request[v1.GetCommitRequest]) (*connect.Response[v1.GetCommitResponse], error) } @@ -82,6 +87,12 @@ func NewVCSServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... connect.WithSchema(vCSServiceGithubLoginMethodDescriptor), connect.WithClientOptions(opts...), ), + githubRefresh: connect.NewClient[v1.GithubRefreshRequest, v1.GithubRefreshResponse]( + httpClient, + baseURL+VCSServiceGithubRefreshProcedure, + connect.WithSchema(vCSServiceGithubRefreshMethodDescriptor), + connect.WithClientOptions(opts...), + ), getFile: connect.NewClient[v1.GetFileRequest, v1.GetFileResponse]( httpClient, baseURL+VCSServiceGetFileProcedure, @@ -99,10 +110,11 @@ func NewVCSServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... // vCSServiceClient implements VCSServiceClient. type vCSServiceClient struct { - githubApp *connect.Client[v1.GithubAppRequest, v1.GithubAppResponse] - githubLogin *connect.Client[v1.GithubLoginRequest, v1.GithubLoginResponse] - getFile *connect.Client[v1.GetFileRequest, v1.GetFileResponse] - getCommit *connect.Client[v1.GetCommitRequest, v1.GetCommitResponse] + githubApp *connect.Client[v1.GithubAppRequest, v1.GithubAppResponse] + githubLogin *connect.Client[v1.GithubLoginRequest, v1.GithubLoginResponse] + githubRefresh *connect.Client[v1.GithubRefreshRequest, v1.GithubRefreshResponse] + getFile *connect.Client[v1.GetFileRequest, v1.GetFileResponse] + getCommit *connect.Client[v1.GetCommitRequest, v1.GetCommitResponse] } // GithubApp calls vcs.v1.VCSService.GithubApp. @@ -115,6 +127,11 @@ func (c *vCSServiceClient) GithubLogin(ctx context.Context, req *connect.Request return c.githubLogin.CallUnary(ctx, req) } +// GithubRefresh calls vcs.v1.VCSService.GithubRefresh. +func (c *vCSServiceClient) GithubRefresh(ctx context.Context, req *connect.Request[v1.GithubRefreshRequest]) (*connect.Response[v1.GithubRefreshResponse], error) { + return c.githubRefresh.CallUnary(ctx, req) +} + // GetFile calls vcs.v1.VCSService.GetFile. func (c *vCSServiceClient) GetFile(ctx context.Context, req *connect.Request[v1.GetFileRequest]) (*connect.Response[v1.GetFileResponse], error) { return c.getFile.CallUnary(ctx, req) @@ -129,6 +146,7 @@ func (c *vCSServiceClient) GetCommit(ctx context.Context, req *connect.Request[v type VCSServiceHandler interface { GithubApp(context.Context, *connect.Request[v1.GithubAppRequest]) (*connect.Response[v1.GithubAppResponse], error) GithubLogin(context.Context, *connect.Request[v1.GithubLoginRequest]) (*connect.Response[v1.GithubLoginResponse], error) + GithubRefresh(context.Context, *connect.Request[v1.GithubRefreshRequest]) (*connect.Response[v1.GithubRefreshResponse], error) GetFile(context.Context, *connect.Request[v1.GetFileRequest]) (*connect.Response[v1.GetFileResponse], error) GetCommit(context.Context, *connect.Request[v1.GetCommitRequest]) (*connect.Response[v1.GetCommitResponse], error) } @@ -151,6 +169,12 @@ func NewVCSServiceHandler(svc VCSServiceHandler, opts ...connect.HandlerOption) connect.WithSchema(vCSServiceGithubLoginMethodDescriptor), connect.WithHandlerOptions(opts...), ) + vCSServiceGithubRefreshHandler := connect.NewUnaryHandler( + VCSServiceGithubRefreshProcedure, + svc.GithubRefresh, + connect.WithSchema(vCSServiceGithubRefreshMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) vCSServiceGetFileHandler := connect.NewUnaryHandler( VCSServiceGetFileProcedure, svc.GetFile, @@ -169,6 +193,8 @@ func NewVCSServiceHandler(svc VCSServiceHandler, opts ...connect.HandlerOption) vCSServiceGithubAppHandler.ServeHTTP(w, r) case VCSServiceGithubLoginProcedure: vCSServiceGithubLoginHandler.ServeHTTP(w, r) + case VCSServiceGithubRefreshProcedure: + vCSServiceGithubRefreshHandler.ServeHTTP(w, r) case VCSServiceGetFileProcedure: vCSServiceGetFileHandler.ServeHTTP(w, r) case VCSServiceGetCommitProcedure: @@ -190,6 +216,10 @@ func (UnimplementedVCSServiceHandler) GithubLogin(context.Context, *connect.Requ return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vcs.v1.VCSService.GithubLogin is not implemented")) } +func (UnimplementedVCSServiceHandler) GithubRefresh(context.Context, *connect.Request[v1.GithubRefreshRequest]) (*connect.Response[v1.GithubRefreshResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vcs.v1.VCSService.GithubRefresh is not implemented")) +} + func (UnimplementedVCSServiceHandler) GetFile(context.Context, *connect.Request[v1.GetFileRequest]) (*connect.Response[v1.GetFileResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vcs.v1.VCSService.GetFile is not implemented")) } diff --git a/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.mux.go b/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.mux.go index 601b1fcd5b..51ade2586d 100644 --- a/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.mux.go +++ b/api/gen/proto/go/vcs/v1/vcsv1connect/vcs.connect.mux.go @@ -29,6 +29,11 @@ func RegisterVCSServiceHandler(mux *mux.Router, svc VCSServiceHandler, opts ...c svc.GithubLogin, opts..., )) + mux.Handle("/vcs.v1.VCSService/GithubRefresh", connect.NewUnaryHandler( + "/vcs.v1.VCSService/GithubRefresh", + svc.GithubRefresh, + opts..., + )) mux.Handle("/vcs.v1.VCSService/GetFile", connect.NewUnaryHandler( "/vcs.v1.VCSService/GetFile", svc.GetFile, diff --git a/api/openapiv2/gen/phlare.swagger.json b/api/openapiv2/gen/phlare.swagger.json index e2bb139201..b48cd981c2 100644 --- a/api/openapiv2/gen/phlare.swagger.json +++ b/api/openapiv2/gen/phlare.swagger.json @@ -760,6 +760,14 @@ } } }, + "v1GithubRefreshResponse": { + "type": "object", + "properties": { + "cookie": { + "type": "string" + } + } + }, "v1Hints": { "type": "object", "properties": { diff --git a/api/vcs/v1/vcs.proto b/api/vcs/v1/vcs.proto index b0e8e79be3..a691241886 100644 --- a/api/vcs/v1/vcs.proto +++ b/api/vcs/v1/vcs.proto @@ -5,6 +5,7 @@ package vcs.v1; service VCSService { rpc GithubApp(GithubAppRequest) returns (GithubAppResponse) {} rpc GithubLogin(GithubLoginRequest) returns (GithubLoginResponse) {} + rpc GithubRefresh(GithubRefreshRequest) returns (GithubRefreshResponse) {} rpc GetFile(GetFileRequest) returns (GetFileResponse) {} rpc GetCommit(GetCommitRequest) returns (GetCommitResponse) {} } @@ -22,6 +23,12 @@ message GithubLoginResponse { string cookie = 1; } +message GithubRefreshRequest {} + +message GithubRefreshResponse { + string cookie = 1; +} + message GetFileRequest { // the full path to the repository string repositoryURL = 1; diff --git a/docs/sources/configure-server/reference-configuration-parameters/index.md b/docs/sources/configure-server/reference-configuration-parameters/index.md index 32c32f05ac..b81a9c1af5 100644 --- a/docs/sources/configure-server/reference-configuration-parameters/index.md +++ b/docs/sources/configure-server/reference-configuration-parameters/index.md @@ -620,10 +620,6 @@ lifecycler: # values: # # Secure Ciphers: - # - TLS_RSA_WITH_AES_128_CBC_SHA - # - TLS_RSA_WITH_AES_256_CBC_SHA - # - TLS_RSA_WITH_AES_128_GCM_SHA256 - # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_AES_256_GCM_SHA384 # - TLS_CHACHA20_POLY1305_SHA256 @@ -641,7 +637,11 @@ lifecycler: # Insecure Ciphers: # - TLS_RSA_WITH_RC4_128_SHA # - TLS_RSA_WITH_3DES_EDE_CBC_SHA + # - TLS_RSA_WITH_AES_128_CBC_SHA + # - TLS_RSA_WITH_AES_256_CBC_SHA # - TLS_RSA_WITH_AES_128_CBC_SHA256 + # - TLS_RSA_WITH_AES_128_GCM_SHA256 + # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA @@ -977,10 +977,6 @@ sharding_ring: # values: # # Secure Ciphers: - # - TLS_RSA_WITH_AES_128_CBC_SHA - # - TLS_RSA_WITH_AES_256_CBC_SHA - # - TLS_RSA_WITH_AES_128_GCM_SHA256 - # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_AES_256_GCM_SHA384 # - TLS_CHACHA20_POLY1305_SHA256 @@ -998,7 +994,11 @@ sharding_ring: # Insecure Ciphers: # - TLS_RSA_WITH_RC4_128_SHA # - TLS_RSA_WITH_3DES_EDE_CBC_SHA + # - TLS_RSA_WITH_AES_128_CBC_SHA + # - TLS_RSA_WITH_AES_256_CBC_SHA # - TLS_RSA_WITH_AES_128_CBC_SHA256 + # - TLS_RSA_WITH_AES_128_GCM_SHA256 + # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA @@ -1326,10 +1326,6 @@ sharding_ring: # values: # # Secure Ciphers: - # - TLS_RSA_WITH_AES_128_CBC_SHA - # - TLS_RSA_WITH_AES_256_CBC_SHA - # - TLS_RSA_WITH_AES_128_GCM_SHA256 - # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_AES_256_GCM_SHA384 # - TLS_CHACHA20_POLY1305_SHA256 @@ -1347,7 +1343,11 @@ sharding_ring: # Insecure Ciphers: # - TLS_RSA_WITH_RC4_128_SHA # - TLS_RSA_WITH_3DES_EDE_CBC_SHA + # - TLS_RSA_WITH_AES_128_CBC_SHA + # - TLS_RSA_WITH_AES_256_CBC_SHA # - TLS_RSA_WITH_AES_128_CBC_SHA256 + # - TLS_RSA_WITH_AES_128_GCM_SHA256 + # - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA @@ -1534,10 +1534,6 @@ backoff_config: # Override the default cipher suite list (separated by commas). Allowed values: # # Secure Ciphers: -# - TLS_RSA_WITH_AES_128_CBC_SHA -# - TLS_RSA_WITH_AES_256_CBC_SHA -# - TLS_RSA_WITH_AES_128_GCM_SHA256 -# - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_AES_256_GCM_SHA384 # - TLS_CHACHA20_POLY1305_SHA256 @@ -1555,7 +1551,11 @@ backoff_config: # Insecure Ciphers: # - TLS_RSA_WITH_RC4_128_SHA # - TLS_RSA_WITH_3DES_EDE_CBC_SHA +# - TLS_RSA_WITH_AES_128_CBC_SHA +# - TLS_RSA_WITH_AES_256_CBC_SHA # - TLS_RSA_WITH_AES_128_CBC_SHA256 +# - TLS_RSA_WITH_AES_128_GCM_SHA256 +# - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA @@ -1747,10 +1747,6 @@ The `memberlist` block configures the Gossip memberlist. # Override the default cipher suite list (separated by commas). Allowed values: # # Secure Ciphers: -# - TLS_RSA_WITH_AES_128_CBC_SHA -# - TLS_RSA_WITH_AES_256_CBC_SHA -# - TLS_RSA_WITH_AES_128_GCM_SHA256 -# - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_AES_256_GCM_SHA384 # - TLS_CHACHA20_POLY1305_SHA256 @@ -1768,7 +1764,11 @@ The `memberlist` block configures the Gossip memberlist. # Insecure Ciphers: # - TLS_RSA_WITH_RC4_128_SHA # - TLS_RSA_WITH_3DES_EDE_CBC_SHA +# - TLS_RSA_WITH_AES_128_CBC_SHA +# - TLS_RSA_WITH_AES_256_CBC_SHA # - TLS_RSA_WITH_AES_128_CBC_SHA256 +# - TLS_RSA_WITH_AES_128_GCM_SHA256 +# - TLS_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_RC4_128_SHA # - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA diff --git a/pkg/frontend/frontend_vcs.go b/pkg/frontend/frontend_vcs.go index 0a0b730493..c74a86ff05 100644 --- a/pkg/frontend/frontend_vcs.go +++ b/pkg/frontend/frontend_vcs.go @@ -17,6 +17,10 @@ func (f *Frontend) GithubLogin(ctx context.Context, req *connect.Request[vcsv1.G return connectgrpc.RoundTripUnary[vcsv1.GithubLoginRequest, vcsv1.GithubLoginResponse](ctx, f, req) } +func (f *Frontend) GithubRefresh(ctx context.Context, req *connect.Request[vcsv1.GithubRefreshRequest]) (*connect.Response[vcsv1.GithubRefreshResponse], error) { + return connectgrpc.RoundTripUnary[vcsv1.GithubRefreshRequest, vcsv1.GithubRefreshResponse](ctx, f, req) +} + func (f *Frontend) GetFile(ctx context.Context, req *connect.Request[vcsv1.GetFileRequest]) (*connect.Response[vcsv1.GetFileResponse], error) { return connectgrpc.RoundTripUnary[vcsv1.GetFileRequest, vcsv1.GetFileResponse](ctx, f, req) } diff --git a/pkg/querier/vcs/client/github.go b/pkg/querier/vcs/client/github.go index 06d791772b..263bc6d92a 100644 --- a/pkg/querier/vcs/client/github.go +++ b/pkg/querier/vcs/client/github.go @@ -5,102 +5,22 @@ import ( "errors" "fmt" "net/http" - "os" "time" "connectrpc.com/connect" "github.com/google/go-github/v58/github" "golang.org/x/oauth2" - o2endpoints "golang.org/x/oauth2/endpoints" vcsv1 "github.com/grafana/pyroscope/api/gen/proto/go/vcs/v1" ) -var ( - GithubAppClientID = os.Getenv("GITHUB_CLIENT_ID") - githubAppClientSecret = os.Getenv("GITHUB_CLIENT_SECRET") - githubSessionSecret = []byte(os.Getenv("GITHUB_SESSION_SECRET")) -) - -const ( - gitHubCookieName = "GitSession" -) - -// githubOAuth returns a github oauth2 config. -// Returns an error if the environment variables are not set. -func githubOAuth() (*oauth2.Config, error) { - if GithubAppClientID == "" { - return nil, errors.New("missing GITHUB_CLIENT_ID environment variable") - } - if githubAppClientSecret == "" { - return nil, errors.New("missing GITHUB_CLIENT_SECRET environment variable") - } - return &oauth2.Config{ - ClientID: GithubAppClientID, - ClientSecret: githubAppClientSecret, - Endpoint: o2endpoints.GitHub, - }, nil -} - -// GithubClient returns a github client for the given request headers. -func GithubClient(ctx context.Context, requestHeaders http.Header) (*githubClient, error) { - auth, err := githubOAuth() - if err != nil { - return nil, err - } - cookie, err := (&http.Request{Header: requestHeaders}).Cookie(gitHubCookieName) - if err != nil { - return nil, err - } - token, err := decryptToken(cookie.Value, githubSessionSecret) - if err != nil { - return nil, unAuthorizeError(err, cookie) - } - if !token.Valid() { - return nil, unAuthorizeError(errors.New("invalid or expired token"), cookie) - } +// GithubClient returns a github client. +func GithubClient(ctx context.Context, token *oauth2.Token) (*githubClient, error) { return &githubClient{ - client: github.NewClient(auth.Client(ctx, token)), + client: github.NewClient(nil).WithAuthToken(token.AccessToken), }, nil } -func unAuthorizeError(err error, cookie *http.Cookie) error { - connectErr := connect.NewError( - connect.CodeUnauthenticated, - err, - ) - cookie.Value = "" - cookie.MaxAge = -1 - connectErr.Meta().Set("Set-Cookie", cookie.String()) - return connectErr -} - -func AuthorizeGithub(ctx context.Context, authorizationCode string) (string, error) { - auth, err := githubOAuth() - if err != nil { - return "", err - } - token, err := auth.Exchange(ctx, authorizationCode) - if err != nil { - return "", err - } - cookieValue, err := encryptToken(token, githubSessionSecret) - if err != nil { - return "", err - } - // Sets a cookie with the encrypted token. - // Only the server can decrypt the cookie. - cookie := http.Cookie{ - Name: gitHubCookieName, - Value: cookieValue, - Expires: token.Expiry.Add(-10 * time.Second), - HttpOnly: false, - Secure: true, - SameSite: http.SameSiteLaxMode, - } - return cookie.String(), nil -} - type githubClient struct { client *github.Client } diff --git a/pkg/querier/vcs/client/encryption.go b/pkg/querier/vcs/encryption.go similarity index 92% rename from pkg/querier/vcs/client/encryption.go rename to pkg/querier/vcs/encryption.go index a3f9696363..b5152efd9a 100644 --- a/pkg/querier/vcs/client/encryption.go +++ b/pkg/querier/vcs/encryption.go @@ -1,14 +1,16 @@ -package client +package vcs import ( "encoding/base64" "encoding/json" "errors" - encryption "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption" "golang.org/x/oauth2" ) +const gcmNonceSize = 12 + func encryptToken(token *oauth2.Token, key []byte) (string, error) { cipher, err := encryption.NewGCMCipher(key) if err != nil { @@ -25,8 +27,6 @@ func encryptToken(token *oauth2.Token, key []byte) (string, error) { return base64.StdEncoding.EncodeToString(enc), nil } -const gcmNonceSize = 12 - func decryptToken(encodedText string, key []byte) (*oauth2.Token, error) { encryptedData, err := base64.StdEncoding.DecodeString(encodedText) if err != nil { diff --git a/pkg/querier/vcs/client/encryption_test.go b/pkg/querier/vcs/encryption_test.go similarity index 98% rename from pkg/querier/vcs/client/encryption_test.go rename to pkg/querier/vcs/encryption_test.go index 901989e532..5964e38ce7 100644 --- a/pkg/querier/vcs/client/encryption_test.go +++ b/pkg/querier/vcs/encryption_test.go @@ -1,4 +1,4 @@ -package client +package vcs import ( "testing" diff --git a/pkg/querier/vcs/github.go b/pkg/querier/vcs/github.go new file mode 100644 index 0000000000..b256a11fd7 --- /dev/null +++ b/pkg/querier/vcs/github.go @@ -0,0 +1,153 @@ +package vcs + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "os" + "time" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/endpoints" +) + +const ( + githubRefreshURL = "https://github.com/login/oauth/access_token" + + // Duration of a GitHub refresh token. The original OAuth flow doesn't + // return the refresh token expiry, so we need to store it separately. + // GitHub docs state this value will never change: + // + // https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens + githubRefreshExpiryDuration = 15897600 * time.Second +) + +var ( + githubAppClientID = os.Getenv("GITHUB_CLIENT_ID") + githubAppClientSecret = os.Getenv("GITHUB_CLIENT_SECRET") +) + +type githubAuthToken struct { + AccessToken string `json:"access_token"` + ExpiresIn time.Duration `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + RefreshTokenExpiresIn time.Duration `json:"refresh_token_expires_in"` + Scope string `json:"scope"` + TokenType string `json:"token_type"` +} + +// toOAuthToken converts a githubAuthToken to an OAuth token. +func (t githubAuthToken) toOAuthToken() *oauth2.Token { + return &oauth2.Token{ + AccessToken: t.AccessToken, + TokenType: t.TokenType, + RefreshToken: t.RefreshToken, + Expiry: time.Now().Add(t.ExpiresIn), + } +} + +// githubOAuthConfig creates a GitHub OAuth config. +func githubOAuthConfig() (*oauth2.Config, error) { + if githubAppClientID == "" { + return nil, fmt.Errorf("missing GITHUB_CLIENT_ID environment variable") + } + if githubAppClientSecret == "" { + return nil, fmt.Errorf("missing GITHUB_CLIENT_SECRET environment variable") + } + return &oauth2.Config{ + ClientID: githubAppClientID, + ClientSecret: githubAppClientSecret, + Endpoint: endpoints.GitHub, + }, nil +} + +// refreshGithubToken sends a request configured for the GitHub API and marshals +// the response into a githubAuthToken. +func refreshGithubToken(req *http.Request) (*githubAuthToken, error) { + client := http.Client{ + Timeout: 10 * time.Second, + } + res, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to make request: %w", err) + } + defer res.Body.Close() + + bytes, err := io.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %w", err) + } + + // The response body is application/x-www-form-urlencoded, so we parse it + // via url.ParseQuery. + payload, err := url.ParseQuery(string(bytes)) + if err != nil { + return nil, fmt.Errorf("failed to parse response body: %w", err) + } + + githubToken, err := githubAuthTokenFromFormURLEncoded(payload) + if err != nil { + return nil, err + } + + return githubToken, nil +} + +// buildGithubRefreshRequest builds a cancelable http.Request which is +// configured to hit the GitHub API's token refresh endpoint. +func buildGithubRefreshRequest(ctx context.Context, oldToken *oauth2.Token) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, "POST", githubRefreshURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + + query := req.URL.Query() + query.Add("client_id", githubAppClientID) + query.Add("client_secret", githubAppClientSecret) + query.Add("grant_type", "refresh_token") + query.Add("refresh_token", oldToken.RefreshToken) + + req.URL.RawQuery = query.Encode() + return req, nil +} + +// githubAuthTokenFromFormURLEncoded converts a url-encoded form to a +// githubAuthToken. +func githubAuthTokenFromFormURLEncoded(values url.Values) (*githubAuthToken, error) { + token := &githubAuthToken{} + var err error + + token.AccessToken, err = getStringValueFrom(values, "access_token") + if err != nil { + return nil, err + } + + token.ExpiresIn, err = getDurationValueFrom(values, "expires_in", time.Second) + if err != nil { + return nil, err + } + + token.RefreshToken, err = getStringValueFrom(values, "refresh_token") + if err != nil { + return nil, err + } + + token.RefreshTokenExpiresIn, err = getDurationValueFrom(values, "refresh_token_expires_in", time.Second) + if err != nil { + return nil, err + } + + token.Scope, err = getStringValueFrom(values, "scope") + if err != nil { + return nil, err + } + + token.TokenType, err = getStringValueFrom(values, "token_type") + if err != nil { + return nil, err + } + + return token, nil +} diff --git a/pkg/querier/vcs/github_test.go b/pkg/querier/vcs/github_test.go new file mode 100644 index 0000000000..9fecf16dfd --- /dev/null +++ b/pkg/querier/vcs/github_test.go @@ -0,0 +1,234 @@ +package vcs + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/oauth2" +) + +func Test_githubAuthToken_toOAuthToken(t *testing.T) { + gat := githubAuthToken{ + AccessToken: "my_access_token", + ExpiresIn: 60 * time.Second, // 1 minute + RefreshToken: "my_refresh_token", + RefreshTokenExpiresIn: 120 * time.Second, // 2 minutes + Scope: "refresh_token", + TokenType: "bearer", + } + + want := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "bearer", + RefreshToken: "my_refresh_token", + Expiry: time.Now().Add(gat.ExpiresIn), + } + + got := gat.toOAuthToken() + + require.GreaterOrEqual(t, got.Expiry.UnixMilli(), want.Expiry.UnixMilli()) + got.Expiry = want.Expiry + + require.Equal(t, want, got) +} + +func Test_refreshGithubToken(t *testing.T) { + want := githubAuthToken{ + AccessToken: "my_access_token", + ExpiresIn: 60 * time.Second, // 1 minute + RefreshToken: "my_refresh_token", + RefreshTokenExpiresIn: 120 * time.Second, // 2 minutes + Scope: "refresh_token", + TokenType: "bearer", + } + fakeGithubAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + query := (&url.URL{}).Query() + query.Add("access_token", want.AccessToken) + query.Add("expires_in", fmt.Sprintf("%d", int(want.ExpiresIn.Seconds()))) + query.Add("refresh_token", want.RefreshToken) + query.Add("refresh_token_expires_in", fmt.Sprintf("%d", int(want.RefreshTokenExpiresIn.Seconds()))) + query.Add("scope", want.Scope) + query.Add("token_type", want.TokenType) + + _, err := w.Write([]byte(query.Encode())) + require.NoError(t, err) + })) + defer fakeGithubAPI.Close() + + req, err := http.NewRequest("POST", fakeGithubAPI.URL, nil) + require.NoError(t, err) + + got, err := refreshGithubToken(req) + require.NoError(t, err) + require.Equal(t, want, *got) +} + +func Test_buildGithubRefreshRequest(t *testing.T) { + oldToken := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "my_token_type", + RefreshToken: "my_refresh_token", + Expiry: time.Unix(1713298947, 0), // 2024-04-16T20:22:27.346Z + } + + // Override env vars. + githubAppClientID = "my_github_client_id" + githubAppClientSecret = "my_github_client_secret" + + got, err := buildGithubRefreshRequest(context.Background(), oldToken) + require.NoError(t, err) + + wantQuery := url.Values{ + "client_id": {githubAppClientID}, + "client_secret": {githubAppClientSecret}, + "grant_type": {"refresh_token"}, + "refresh_token": {oldToken.RefreshToken}, + } + require.Equal(t, nil, got.Body) + require.Equal(t, wantQuery, got.URL.Query()) + + wantURL, err := url.Parse(githubRefreshURL) + require.NoError(t, err) + require.Equal(t, wantURL.Host, got.URL.Host) + require.Equal(t, wantURL.Path, got.URL.Path) +} + +func Test_githubAuthTokenFromFormURLEncoded(t *testing.T) { + tests := []struct { + Name string + Query url.Values + Want *githubAuthToken + WantErrMsg string + }{ + { + Name: "valid query", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + Want: &githubAuthToken{ + AccessToken: "my_access_token", + ExpiresIn: 60 * time.Second, + RefreshToken: "my_refresh_token", + RefreshTokenExpiresIn: 120 * time.Second, + Scope: "refresh_token", + TokenType: "bearer", + }, + }, + { + Name: "missing access_token", + Query: url.Values{ + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "missing key: access_token", + }, + { + Name: "missing expires_in", + Query: url.Values{ + "access_token": {"my_access_token"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "missing key: expires_in", + }, + { + Name: "missing refresh_token", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "missing key: refresh_token", + }, + { + Name: "missing refresh_token_expires_in", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "missing key: refresh_token_expires_in", + }, + { + Name: "missing scope", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "missing key: scope", + }, + { + Name: "missing token_type", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + }, + WantErrMsg: "missing key: token_type", + }, + { + Name: "invalid expires_in", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"not_a_number"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"120"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "failed to parse expires_in: strconv.Atoi: parsing \"not_a_number\": invalid syntax", + }, + { + Name: "invalid refresh_token_expires_in", + Query: url.Values{ + "access_token": {"my_access_token"}, + "expires_in": {"60"}, + "refresh_token": {"my_refresh_token"}, + "refresh_token_expires_in": {"not_a_number"}, + "scope": {"refresh_token"}, + "token_type": {"bearer"}, + }, + WantErrMsg: "failed to parse refresh_token_expires_in: strconv.Atoi: parsing \"not_a_number\": invalid syntax", + }, + } + + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + gat, err := githubAuthTokenFromFormURLEncoded(tt.Query) + if tt.WantErrMsg != "" { + require.Error(t, err) + require.EqualError(t, err, tt.WantErrMsg) + } else { + require.NoError(t, err) + require.Equal(t, tt.Want, gat) + } + }) + } +} diff --git a/pkg/querier/vcs/service.go b/pkg/querier/vcs/service.go index ade3e65017..d4277c7ba3 100644 --- a/pkg/querier/vcs/service.go +++ b/pkg/querier/vcs/service.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "net/http" + "time" "connectrpc.com/connect" "github.com/go-kit/log" giturl "github.com/kubescape/go-git-url" "github.com/kubescape/go-git-url/apis" + "golang.org/x/oauth2" vcsv1 "github.com/grafana/pyroscope/api/gen/proto/go/vcs/v1" vcsv1connect "github.com/grafana/pyroscope/api/gen/proto/go/vcs/v1/vcsv1connect" @@ -31,44 +33,104 @@ func New(logger log.Logger) *Service { func (q *Service) GithubApp(ctx context.Context, req *connect.Request[vcsv1.GithubAppRequest]) (*connect.Response[vcsv1.GithubAppResponse], error) { return connect.NewResponse(&vcsv1.GithubAppResponse{ - ClientID: client.GithubAppClientID, + ClientID: githubAppClientID, }), nil } func (q *Service) GithubLogin(ctx context.Context, req *connect.Request[vcsv1.GithubLoginRequest]) (*connect.Response[vcsv1.GithubLoginResponse], error) { - resp := connect.NewResponse(&vcsv1.GithubLoginResponse{}) - cookie, err := client.AuthorizeGithub(ctx, req.Msg.AuthorizationCode) + cfg, err := githubOAuthConfig() if err != nil { - return nil, fmt.Errorf("failed to authorize github: %w", err) + q.logger.Log("err", err, "msg", "failed to get GitHub OAuth config") + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to authorize with GitHub")) } - resp.Msg.Cookie = cookie - return resp, nil + + token, err := cfg.Exchange(ctx, req.Msg.AuthorizationCode) + if err != nil { + q.logger.Log("err", err, "msg", "failed to exchange authorization code with GitHub") + return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("failed to authorize with GitHub")) + } + + cookie, err := encodeToken(token) + if err != nil { + q.logger.Log("err", err, "msg", "failed to encode GitHub OAuth token") + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to authorize with GitHub")) + } + + res := &vcsv1.GithubLoginResponse{ + Cookie: cookie.String(), + } + return connect.NewResponse(res), nil +} + +func (q *Service) GithubRefresh(ctx context.Context, req *connect.Request[vcsv1.GithubRefreshRequest]) (*connect.Response[vcsv1.GithubRefreshResponse], error) { + token, err := tokenFromRequest(req) + if err != nil { + q.logger.Log("err", err, "msg", "failed to extract token from request") + return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("invalid token")) + } + + githubRequest, err := buildGithubRefreshRequest(ctx, token) + if err != nil { + q.logger.Log("err", err, "msg", "failed to extract token from request") + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to refresh token")) + } + + githubToken, err := refreshGithubToken(githubRequest) + if err != nil { + q.logger.Log("err", err, "msg", "failed to refresh token with GitHub") + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to refresh token")) + } + + newToken := githubToken.toOAuthToken() + + cookie, err := encodeToken(newToken) + if err != nil { + q.logger.Log("err", err, "msg", "failed to encode GitHub OAuth token") + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to refresh token")) + } + + res := &vcsv1.GithubRefreshResponse{ + Cookie: cookie.String(), + } + return connect.NewResponse(res), nil } func (q *Service) GetFile(ctx context.Context, req *connect.Request[vcsv1.GetFileRequest]) (*connect.Response[vcsv1.GetFileResponse], error) { + token, err := tokenFromRequest(req) + if err != nil { + q.logger.Log("err", err, "msg", "failed to extract token from request") + return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("invalid token")) + } + + err = rejectExpiredToken(token) + if err != nil { + return nil, err + } + // initialize and parse the git repo URL gitURL, err := giturl.NewGitURL(req.Msg.RepositoryURL) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, err) } + if gitURL.GetProvider() != apis.ProviderGitHub.String() { return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("only GitHub repositories are supported")) } // todo: we can support multiple provider: bitbucket, gitlab, etc. - ghClient, err := client.GithubClient(ctx, req.Header()) + ghClient, err := client.GithubClient(ctx, token) if err != nil { return nil, err } - file, err := source. - NewFileFinder( - ghClient, - gitURL, - req.Msg.LocalPath, - req.Msg.Ref, - http.DefaultClient, - log.With(q.logger, "repo", gitURL.GetRepoName())). - Find(ctx) + + file, err := source.NewFileFinder( + ghClient, + gitURL, + req.Msg.LocalPath, + req.Msg.Ref, + http.DefaultClient, + log.With(q.logger, "repo", gitURL.GetRepoName()), + ).Find(ctx) if err != nil { if errors.Is(err, client.ErrNotFound) { return nil, connect.NewError(connect.CodeNotFound, err) @@ -79,20 +141,41 @@ func (q *Service) GetFile(ctx context.Context, req *connect.Request[vcsv1.GetFil } func (q *Service) GetCommit(ctx context.Context, req *connect.Request[vcsv1.GetCommitRequest]) (*connect.Response[vcsv1.GetCommitResponse], error) { + token, err := tokenFromRequest(req) + if err != nil { + q.logger.Log("err", err, "msg", "failed to extract token from request") + return nil, connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("invalid token")) + } + + err = rejectExpiredToken(token) + if err != nil { + return nil, err + } + gitURL, err := giturl.NewGitURL(req.Msg.RepositoryURL) if err != nil { return nil, connect.NewError(connect.CodeInvalidArgument, err) } + if gitURL.GetProvider() != apis.ProviderGitHub.String() { return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("only GitHub repositories are supported")) } - ghClient, err := client.GithubClient(ctx, req.Header()) + + ghClient, err := client.GithubClient(ctx, token) if err != nil { return nil, err } + commit, err := ghClient.GetCommit(ctx, gitURL.GetOwnerName(), gitURL.GetRepoName(), req.Msg.Ref) if err != nil { return nil, err } return connect.NewResponse(commit), nil } + +func rejectExpiredToken(token *oauth2.Token) error { + if time.Now().After(token.Expiry) { + return connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("token is expired")) + } + return nil +} diff --git a/pkg/querier/vcs/token.go b/pkg/querier/vcs/token.go new file mode 100644 index 0000000000..2ef71d50eb --- /dev/null +++ b/pkg/querier/vcs/token.go @@ -0,0 +1,130 @@ +package vcs + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "net/url" + "os" + "strconv" + "time" + + "connectrpc.com/connect" + "golang.org/x/oauth2" +) + +const ( + sessionCookieName = "GitSession" +) + +var ( + gitSessionSecret = []byte(os.Getenv("GITHUB_SESSION_SECRET")) +) + +type gitSessionTokenCookie struct { + Metadata string `json:"metadata"` + ExpiryTimestamp int64 `json:"expiry"` +} + +// getStringValueFrom gets a string value from url.Values. It will fail if the +// key is missing or the key's value is an empty string. +func getStringValueFrom(values url.Values, key string) (string, error) { + value := values.Get(key) + if value == "" { + return "", fmt.Errorf("missing key: %s", key) + } + return value, nil +} + +// getDurationValueFrom gets a duration value from url.Values. It will fail if +// the key is missing, the key's value is an empty string, or the key's value +// cannot be parsed into a duration. +func getDurationValueFrom(values url.Values, key string, scalar time.Duration) (time.Duration, error) { + if scalar < 1 { + return 0, fmt.Errorf("cannot use scalar less than 1") + } + + value, err := getStringValueFrom(values, key) + if err != nil { + return 0, err + } + + n, err := strconv.Atoi(value) + if err != nil { + return 0, fmt.Errorf("failed to parse %s: %w", key, err) + } + + return time.Duration(n) * scalar, nil +} + +// tokenFromRequest decodes an OAuth token from a request. +func tokenFromRequest(req connect.AnyRequest) (*oauth2.Token, error) { + cookie, err := (&http.Request{Header: req.Header()}).Cookie(sessionCookieName) + if err != nil { + return nil, fmt.Errorf("failed to read cookie %s: %w", sessionCookieName, err) + } + + token, err := decodeToken(cookie.Value) + if err != nil { + return nil, err + } + return token, nil +} + +// encodeToken encrypts then base64 encodes an OAuth token. +func encodeToken(token *oauth2.Token) (*http.Cookie, error) { + encrypted, err := encryptToken(token, gitSessionSecret) + if err != nil { + return nil, err + } + + bytes, err := json.Marshal(gitSessionTokenCookie{ + Metadata: encrypted, + ExpiryTimestamp: token.Expiry.UnixMilli(), + }) + if err != nil { + return nil, err + } + + encoded := base64.StdEncoding.EncodeToString(bytes) + cookie := &http.Cookie{ + Name: sessionCookieName, + Value: encoded, + Expires: time.Now().Add(githubRefreshExpiryDuration), + HttpOnly: false, + Secure: true, + SameSite: http.SameSiteLaxMode, + } + return cookie, nil +} + +// decodeToken base64 decodes and decrypts a OAuth token. +func decodeToken(value string) (*oauth2.Token, error) { + var token *oauth2.Token + + decoded, err := base64.StdEncoding.DecodeString(value) + if err != nil { + return nil, err + } + + sessionToken := gitSessionTokenCookie{} + err = json.Unmarshal(decoded, &sessionToken) + if err != nil { + // This may be a legacy cookie. Legacy cookies aren't base64 encoded + // JSON objects, but rather a base64 encoded crypto hash. + var innerErr error + token, innerErr = decryptToken(value, gitSessionSecret) + if innerErr != nil { + // Legacy fallback failed, return the original error. + return nil, err + } + return token, nil + } + + token, err = decryptToken(sessionToken.Metadata, gitSessionSecret) + if err != nil { + return nil, err + } + return token, nil +} diff --git a/pkg/querier/vcs/token_test.go b/pkg/querier/vcs/token_test.go new file mode 100644 index 0000000000..50f4ed7567 --- /dev/null +++ b/pkg/querier/vcs/token_test.go @@ -0,0 +1,256 @@ +package vcs + +import ( + "encoding/base64" + "net/http" + "net/url" + "testing" + "time" + + "connectrpc.com/connect" + "github.com/stretchr/testify/require" + "golang.org/x/oauth2" + + vcsv1 "github.com/grafana/pyroscope/api/gen/proto/go/vcs/v1" +) + +func Test_getStringValueFrom(t *testing.T) { + tests := []struct { + Name string + Query url.Values + Key string + Want string + WantErrMsg string + }{ + { + Name: "key exists", + Query: url.Values{ + "my_key": {"my_value"}, + }, + Key: "my_key", + Want: "my_value", + }, + { + Name: "key exists with multiple values", + Query: url.Values{ + "my_key": {"my_value1", "my_value2"}, + }, + Key: "my_key", + Want: "my_value1", + }, + { + Name: "key is missing", + Query: url.Values{ + "my_key": {"my_value"}, + }, + Key: "my_missing_key", + WantErrMsg: "missing key: my_missing_key", + }, + } + + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + got, err := getStringValueFrom(tt.Query, tt.Key) + if tt.WantErrMsg != "" { + require.Error(t, err) + require.EqualError(t, err, tt.WantErrMsg) + } else { + require.NoError(t, err) + require.Equal(t, tt.Want, got) + } + }) + } +} + +func Test_getDurationValueFrom(t *testing.T) { + tests := []struct { + Name string + Query url.Values + Key string + Scalar time.Duration + Want time.Duration + WantErrMsg string + }{ + { + Name: "key exists", + Query: url.Values{ + "my_key": {"100"}, + }, + Key: "my_key", + Scalar: time.Second, + Want: 100 * time.Second, + }, + { + Name: "key exists with multiple values", + Query: url.Values{ + "my_key": {"100", "200"}, + }, + Key: "my_key", + Scalar: time.Second, + Want: 100 * time.Second, + }, + { + Name: "scalar less than 1", + Query: url.Values{ + "my_key": {"100"}, + }, + Key: "my_key", + Scalar: 0, + WantErrMsg: "cannot use scalar less than 1", + }, + { + Name: "value is not a duration", + Query: url.Values{ + "my_key": {"not_a_number"}, + }, + Key: "my_key", + Scalar: time.Second, + WantErrMsg: "failed to parse my_key: strconv.Atoi: parsing \"not_a_number\": invalid syntax", + }, + { + Name: "key is missing", + Query: url.Values{ + "my_key": {"my_value"}, + }, + Scalar: time.Second, + Key: "my_missing_key", + WantErrMsg: "missing key: my_missing_key", + }, + } + + for _, tt := range tests { + t.Run(tt.Name, func(t *testing.T) { + got, err := getDurationValueFrom(tt.Query, tt.Key, tt.Scalar) + if tt.WantErrMsg != "" { + require.Error(t, err) + require.EqualError(t, err, tt.WantErrMsg) + } else { + require.NoError(t, err) + require.Equal(t, tt.Want, got) + } + }) + } +} + +func Test_tokenFromRequest(t *testing.T) { + t.Run("token exists in request", func(t *testing.T) { + gitSessionSecret = []byte("16_byte_key_XXXX") + wantToken := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "my_token_type", + RefreshToken: "my_refresh_token", + Expiry: time.Unix(1713298947, 0).UTC(), // 2024-04-16T20:22:27.346Z + } + + // The type of request here doesn't matter. + req := connect.NewRequest(&vcsv1.GetFileRequest{}) + req.Header().Add("Cookie", testEncodeCookie(t, wantToken).String()) + + gotToken, err := tokenFromRequest(req) + require.NoError(t, err) + require.Equal(t, *wantToken, *gotToken) + }) + + t.Run("token does not exist in request", func(t *testing.T) { + gitSessionSecret = []byte("16_byte_key_XXXX") + wantErr := "failed to read cookie GitSession: http: named cookie not present" + + // The type of request here doesn't matter. + req := connect.NewRequest(&vcsv1.GetFileRequest{}) + + _, err := tokenFromRequest(req) + require.Error(t, err) + require.EqualError(t, err, wantErr) + }) +} + +func Test_encodeToken(t *testing.T) { + gitSessionSecret = []byte("16_byte_key_XXXX") + token := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "my_token_type", + RefreshToken: "my_refresh_token", + Expiry: time.Unix(1713298947, 0).UTC(), // 2024-04-16T20:22:27.346Z + } + + got, err := encodeToken(token) + require.NoError(t, err) + require.Equal(t, sessionCookieName, got.Name) + require.NotEmpty(t, got.Value) + require.NotZero(t, got.Expires) + require.True(t, got.Secure) + require.Equal(t, http.SameSiteLaxMode, got.SameSite) +} + +func Test_decodeToken(t *testing.T) { + gitSessionSecret = []byte("16_byte_key_XXXX") + + t.Run("valid token", func(t *testing.T) { + want := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "my_token_type", + RefreshToken: "my_refresh_token", + Expiry: time.Unix(1713298947, 0).UTC(), // 2024-04-16T20:22:27.346Z + } + cookie := testEncodeCookie(t, want) + + got, err := decodeToken(cookie.Value) + require.NoError(t, err) + require.Equal(t, want, got) + }) + + t.Run("valid legacy token", func(t *testing.T) { + want := &oauth2.Token{ + AccessToken: "my_access_token", + TokenType: "my_token_type", + RefreshToken: "my_refresh_token", + Expiry: time.Unix(1713298947, 0).UTC(), // 2024-04-16T20:22:27.346Z + } + cookie := testEncodeLegacyCookie(t, want) + + got, err := decodeToken(cookie.Value) + require.NoError(t, err) + require.Equal(t, want, got) + }) + + t.Run("invalid base64 encoding", func(t *testing.T) { + illegalBase64Encoding := "xx===" + + _, err := decodeToken(illegalBase64Encoding) + require.Error(t, err) + require.EqualError(t, err, "illegal base64 data at input byte 4") + }) + + t.Run("invalid json encoding", func(t *testing.T) { + illegalJSON := base64.StdEncoding.EncodeToString([]byte("illegal json value")) + + _, err := decodeToken(illegalJSON) + require.Error(t, err) + require.EqualError(t, err, "invalid character 'i' looking for beginning of value") + }) +} + +func testEncodeCookie(t *testing.T, token *oauth2.Token) *http.Cookie { + t.Helper() + + encoded, err := encodeToken(token) + require.NoError(t, err) + + return encoded +} + +func testEncodeLegacyCookie(t *testing.T, token *oauth2.Token) *http.Cookie { + t.Helper() + + encrypted, err := encryptToken(token, gitSessionSecret) + require.NoError(t, err) + + return &http.Cookie{ + Name: sessionCookieName, + Value: encrypted, + Expires: token.Expiry, + HttpOnly: false, + Secure: true, + SameSite: http.SameSiteLaxMode, + } +}