diff --git a/go.mod b/go.mod index b33e9b0..8ee4697 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.14 require ( github.com/SlyMarbo/rss v1.0.1 + github.com/getkin/kin-openapi v0.26.0 github.com/golang/protobuf v1.4.3 github.com/google/uuid v1.1.2 github.com/gosimple/slug v1.9.0 @@ -11,7 +12,7 @@ require ( github.com/micro/dev v0.0.0-20201117163752-d3cfc9788dfa github.com/micro/micro/v3 v3.0.5-0.20201219085254-c8ea24387d19 github.com/miekg/dns v1.1.31 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/stoewer/go-strcase v1.2.0 github.com/stretchr/testify v1.6.1 github.com/ulikunitz/xz v0.5.8 // indirect golang.org/x/crypto v0.0.0-20201002094018-c90954cbb977 diff --git a/invites/.gitignore b/invites/.gitignore new file mode 100644 index 0000000..4f31144 --- /dev/null +++ b/invites/.gitignore @@ -0,0 +1,2 @@ + +invites diff --git a/invites/Dockerfile b/invites/Dockerfile new file mode 100644 index 0000000..718155b --- /dev/null +++ b/invites/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine +ADD invites /invites +ENTRYPOINT [ "/invites" ] diff --git a/invites/Makefile b/invites/Makefile new file mode 100644 index 0000000..6ec921a --- /dev/null +++ b/invites/Makefile @@ -0,0 +1,22 @@ + +GOPATH:=$(shell go env GOPATH) +.PHONY: init +init: + go get -u github.com/golang/protobuf/proto + go get -u github.com/golang/protobuf/protoc-gen-go + go get github.com/micro/micro/v3/cmd/protoc-gen-micro +.PHONY: proto +proto: + protoc --proto_path=. --micro_out=. --go_out=:. proto/invites.proto + +.PHONY: build +build: + go build -o invites *.go + +.PHONY: test +test: + go test -v ./... -cover + +.PHONY: docker +docker: + docker build . -t invites:latest diff --git a/invites/README.md b/invites/README.md new file mode 100644 index 0000000..36c407c --- /dev/null +++ b/invites/README.md @@ -0,0 +1,40 @@ +# Invites Service + +The invites services allows you to create and manage invites. Example usage: + +```bash +> micro invites create --group_id=myawesomegroup --email=john@doe.com +{ + "invite": { + "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", + "group_id": "myawesomegroup", + "email": "john@doe.com", + "code": "86285587" + } +} + +> micro invites list --group_id=fb3a3552-3c7b-4a18-a1f8-08ab56940862 +{ + "invites": [ + { + "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", + "group_id": "myawesomegroup", + "email": "john@doe.com", + "code": "86285587" + } + ] +} + +> micro invites read --code=86285587 +{ + "invite": { + "id": "fb3a3552-3c7b-4a18-a1f8-08ab56940862", + "group_id": "myawesomegroup", + "email": "john@doe.com", + "code": "86285587" + } +} + +> micro invites delete --id=fb3a3552-3c7b-4a18-a1f8-08ab56940862 +{} +``` diff --git a/invites/generate.go b/invites/generate.go new file mode 100644 index 0000000..96f431a --- /dev/null +++ b/invites/generate.go @@ -0,0 +1,2 @@ +package main +//go:generate make proto diff --git a/invites/handler/invites.go b/invites/handler/invites.go new file mode 100644 index 0000000..93e175b --- /dev/null +++ b/invites/handler/invites.go @@ -0,0 +1,165 @@ +package handler + +import ( + "context" + "math/rand" + "regexp" + "strconv" + "strings" + + "github.com/google/uuid" + "github.com/micro/micro/v3/service/errors" + "github.com/micro/micro/v3/service/logger" + pb "github.com/micro/services/invites/proto" + "gorm.io/gorm" +) + +var ( + ErrMissingID = errors.BadRequest("MISSING_ID", "Missing ID") + ErrMissingGroupID = errors.BadRequest("MISSING_GROUP_ID", "Missing GroupID") + ErrInvalidEmail = errors.BadRequest("INVALID_EMAIL", "The email provided was invalid") + ErrMissingEmail = errors.BadRequest("MISSING_EMAIL", "Missing Email") + ErrMissingIDAndCode = errors.BadRequest("ID_OR_CODE_REQUIRED", "An email address code is required to read an invite") + ErrMissingGroupIDAndEmail = errors.BadRequest("GROUP_ID_OR_EMAIL_REQUIRED", "An email address or group id is needed to list invites") + ErrInviteNotFound = errors.NotFound("NOT_FOUND", "Invite not found") + + emailRegex = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") +) + +type Invite struct { + ID string + Email string `gorm:"uniqueIndex:group_email"` + GroupID string `gorm:"uniqueIndex:group_email"` + Code string `gorm:"uniqueIndex"` +} + +func (i *Invite) Serialize() *pb.Invite { + return &pb.Invite{ + Id: i.ID, + Email: i.Email, + GroupId: i.GroupID, + Code: i.Code, + } +} + +type Invites struct { + DB *gorm.DB +} + +// Create an invite +func (i *Invites) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error { + // validate the request + if len(req.GroupId) == 0 { + return ErrMissingGroupID + } + if len(req.Email) == 0 { + return ErrMissingEmail + } + if !isEmailValid(req.Email) { + return ErrInvalidEmail + } + + // construct the invite and write to the db + invite := &Invite{ + ID: uuid.New().String(), + Code: generateCode(), + GroupID: req.GroupId, + Email: req.Email, + } + if err := i.DB.Create(invite).Error; err != nil && strings.Contains(err.Error(), "group_email") { + } else if err != nil { + logger.Errorf("Error writing to the store: %v", err) + return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") + } + + // serialize the response + rsp.Invite = invite.Serialize() + return nil +} + +// Read an invite using ID or code +func (i *Invites) Read(ctx context.Context, req *pb.ReadRequest, rsp *pb.ReadResponse) error { + // validate the request + var query Invite + if req.Id != nil { + query.ID = req.Id.Value + } else if req.Code != nil { + query.Code = req.Code.Value + } else { + return ErrMissingIDAndCode + } + + // query the database + var invite Invite + if err := i.DB.Where(&query).First(&invite).Error; err == gorm.ErrRecordNotFound { + return ErrInviteNotFound + } else if err != nil { + logger.Errorf("Error reading from the store: %v", err) + return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") + } + + // serialize the response + rsp.Invite = invite.Serialize() + return nil +} + +// List invited for a group or specific email +func (i *Invites) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error { + // validate the request + if req.Email == nil && req.GroupId == nil { + return ErrMissingGroupIDAndEmail + } + + // construct the query + var query Invite + if req.GroupId != nil { + query.GroupID = req.GroupId.Value + } + if req.Email != nil { + query.Email = req.Email.Value + } + + // query the database + var invites []Invite + if err := i.DB.Where(&query).Find(&invites).Error; err != nil { + logger.Errorf("Error reading from the store: %v", err) + return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") + } + + // serialize the response + rsp.Invites = make([]*pb.Invite, len(invites)) + for i, inv := range invites { + rsp.Invites[i] = inv.Serialize() + } + return nil +} + +// Delete an invite +func (i *Invites) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error { + // validate the request + if len(req.Id) == 0 { + return ErrMissingID + } + + // delete from the database + if err := i.DB.Where(&Invite{ID: req.Id}).Delete(&Invite{}).Error; err != nil { + logger.Errorf("Error deleting from the store: %v", err) + return errors.InternalServerError("DATABASE_ERROR", "Error connecting to the database") + } + + return nil +} + +// isEmailValid checks if the email provided passes the required structure and length. +func isEmailValid(e string) bool { + if len(e) < 3 && len(e) > 254 { + return false + } + return emailRegex.MatchString(e) +} + +// generateCode generates a random 8 digit code +func generateCode() string { + v := rand.Intn(89999999) + 10000000 + return strconv.Itoa(v) +} diff --git a/invites/handler/invites_test.go b/invites/handler/invites_test.go new file mode 100644 index 0000000..b165052 --- /dev/null +++ b/invites/handler/invites_test.go @@ -0,0 +1,267 @@ +package handler_test + +import ( + "context" + "testing" + + "google.golang.org/protobuf/types/known/wrapperspb" + + "github.com/micro/services/invites/handler" + pb "github.com/micro/services/invites/proto" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +func testHandler(t *testing.T) *handler.Invites { + // connect to the database + db, err := gorm.Open(postgres.Open("postgresql://postgres@localhost:5432/invites?sslmode=disable"), &gorm.Config{}) + if err != nil { + t.Fatalf("Error connecting to database: %v", err) + } + + // migrate the database + if err := db.AutoMigrate(&handler.Invite{}); err != nil { + t.Fatalf("Error migrating database: %v", err) + } + + // clean any data from a previous run + if err := db.Exec("TRUNCATE TABLE invites CASCADE").Error; err != nil { + t.Fatalf("Error cleaning database: %v", err) + } + + return &handler.Invites{DB: db} +} + +func TestCreate(t *testing.T) { + tt := []struct { + Name string + GroupID string + Email string + Error error + }{ + { + Name: "MissingGroupID", + Email: "john@doe.com", + Error: handler.ErrMissingGroupID, + }, + { + Name: "MissingEmail", + GroupID: uuid.New().String(), + Error: handler.ErrMissingEmail, + }, + { + Name: "InvalidEmail", + GroupID: uuid.New().String(), + Email: "foo.foo.foo", + Error: handler.ErrInvalidEmail, + }, + { + Name: "Valid", + GroupID: "thisisavalidgroupid", + Email: "john@doe.com", + }, + { + Name: "Repeat", + GroupID: "thisisavalidgroupid", + Email: "john@doe.com", + }, + } + + h := testHandler(t) + for _, tc := range tt { + t.Run(tc.Name, func(t *testing.T) { + var rsp pb.CreateResponse + err := h.Create(context.TODO(), &pb.CreateRequest{ + GroupId: tc.GroupID, Email: tc.Email, + }, &rsp) + assert.Equal(t, tc.Error, err) + + if tc.Error != nil { + assert.Nil(t, rsp.Invite) + return + } + + if rsp.Invite == nil { + t.Fatalf("Invite was not returned") + return + } + + assert.NotEmpty(t, rsp.Invite.Id) + assert.NotEmpty(t, rsp.Invite.Code) + assert.Equal(t, tc.GroupID, rsp.Invite.GroupId) + assert.Equal(t, tc.Email, rsp.Invite.Email) + }) + } +} + +func TestRead(t *testing.T) { + h := testHandler(t) + + // seed some data + var cRsp pb.CreateResponse + err := h.Create(context.TODO(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) + assert.NoError(t, err) + if cRsp.Invite == nil { + t.Fatal("No invite returned on create") + return + } + + tt := []struct { + Name string + ID *wrapperspb.StringValue + Code *wrapperspb.StringValue + Error error + Invite *pb.Invite + }{ + { + Name: "MissingIDAndCode", + Error: handler.ErrMissingIDAndCode, + }, + { + Name: "NotFoundByID", + ID: &wrapperspb.StringValue{Value: uuid.New().String()}, + Error: handler.ErrInviteNotFound, + }, + { + Name: "NotFoundByCode", + Code: &wrapperspb.StringValue{Value: "12345678"}, + Error: handler.ErrInviteNotFound, + }, + { + Name: "ValidID", + ID: &wrapperspb.StringValue{Value: cRsp.Invite.Id}, + Invite: cRsp.Invite, + }, + { + Name: "ValidCode", + Code: &wrapperspb.StringValue{Value: cRsp.Invite.Code}, + Invite: cRsp.Invite, + }, + } + + for _, tc := range tt { + t.Run(tc.Name, func(t *testing.T) { + var rsp pb.ReadResponse + err := h.Read(context.TODO(), &pb.ReadRequest{Id: tc.ID, Code: tc.Code}, &rsp) + assert.Equal(t, tc.Error, err) + + if tc.Invite == nil { + assert.Nil(t, rsp.Invite) + } else { + assertInvitesMatch(t, tc.Invite, rsp.Invite) + } + }) + } +} + +func TestList(t *testing.T) { + h := testHandler(t) + + // seed some data + var cRsp pb.CreateResponse + err := h.Create(context.TODO(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) + assert.NoError(t, err) + if cRsp.Invite == nil { + t.Fatal("No invite returned on create") + return + } + + tt := []struct { + Name string + GroupID *wrapperspb.StringValue + Email *wrapperspb.StringValue + Error error + Invite *pb.Invite + }{ + { + Name: "MissingIDAndEmail", + Error: handler.ErrMissingGroupIDAndEmail, + }, + { + Name: "NoResultsForEmail", + Email: &wrapperspb.StringValue{Value: "foo@bar.com"}, + }, + { + Name: "NoResultsForGroupID", + GroupID: &wrapperspb.StringValue{Value: uuid.New().String()}, + }, + { + Name: "ValidGroupID", + GroupID: &wrapperspb.StringValue{Value: cRsp.Invite.GroupId}, + Invite: cRsp.Invite, + }, + { + Name: "ValidEmail", + Email: &wrapperspb.StringValue{Value: cRsp.Invite.Email}, + Invite: cRsp.Invite, + }, + { + Name: "EmailAndGroupID", + Email: &wrapperspb.StringValue{Value: cRsp.Invite.Email}, + GroupID: &wrapperspb.StringValue{Value: uuid.New().String()}, + }, + } + + for _, tc := range tt { + t.Run(tc.Name, func(t *testing.T) { + var rsp pb.ListResponse + err := h.List(context.TODO(), &pb.ListRequest{Email: tc.Email, GroupId: tc.GroupID}, &rsp) + assert.Equal(t, tc.Error, err) + + if tc.Invite == nil { + assert.Empty(t, rsp.Invites) + } else { + if len(rsp.Invites) != 1 { + t.Errorf("Incorrect number of invites returned, expected 1 but got %v", len(rsp.Invites)) + return + } + assertInvitesMatch(t, tc.Invite, rsp.Invites[0]) + } + }) + } +} + +func TestDelete(t *testing.T) { + h := testHandler(t) + + t.Run("MissingID", func(t *testing.T) { + err := h.Delete(context.TODO(), &pb.DeleteRequest{}, &pb.DeleteResponse{}) + assert.Equal(t, handler.ErrMissingID, err) + }) + + // seed some data + var cRsp pb.CreateResponse + err := h.Create(context.TODO(), &pb.CreateRequest{Email: "john@doe.com", GroupId: uuid.New().String()}, &cRsp) + assert.NoError(t, err) + if cRsp.Invite == nil { + t.Fatal("No invite returned on create") + return + } + + t.Run("Valid", func(t *testing.T) { + err := h.Delete(context.TODO(), &pb.DeleteRequest{Id: cRsp.Invite.Id}, &pb.DeleteResponse{}) + assert.NoError(t, err) + + err = h.Read(context.TODO(), &pb.ReadRequest{Id: &wrapperspb.StringValue{Value: cRsp.Invite.Id}}, &pb.ReadResponse{}) + assert.Equal(t, handler.ErrInviteNotFound, err) + }) + + t.Run("Repeat", func(t *testing.T) { + err := h.Delete(context.TODO(), &pb.DeleteRequest{Id: cRsp.Invite.Id}, &pb.DeleteResponse{}) + assert.NoError(t, err) + }) +} + +func assertInvitesMatch(t *testing.T, exp, act *pb.Invite) { + if act == nil { + t.Errorf("No invite returned") + return + } + assert.Equal(t, exp.Id, act.Id) + assert.Equal(t, exp.Code, act.Code) + assert.Equal(t, exp.Email, act.Email) + assert.Equal(t, exp.GroupId, act.GroupId) +} diff --git a/invites/main.go b/invites/main.go new file mode 100644 index 0000000..b219769 --- /dev/null +++ b/invites/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "github.com/micro/services/invites/handler" + pb "github.com/micro/services/invites/proto" + + "github.com/micro/micro/v3/service" + "github.com/micro/micro/v3/service/config" + "github.com/micro/micro/v3/service/logger" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +var dbAddress = "postgresql://postgres@localhost:5432/invites?sslmode=disable" + +func main() { + // Create service + srv := service.New( + service.Name("invites"), + service.Version("latest"), + ) + + // Connect to the database + cfg, err := config.Get("invites.database") + if err != nil { + logger.Fatalf("Error loading config: %v", err) + } + addr := cfg.String(dbAddress) + db, err := gorm.Open(postgres.Open(addr), &gorm.Config{}) + if err != nil { + logger.Fatalf("Error connecting to database: %v", err) + } + + // Register handler + pb.RegisterInvitesHandler(srv.Server(), &handler.Invites{DB: db}) + + // Run service + if err := srv.Run(); err != nil { + logger.Fatal(err) + } +} diff --git a/invites/micro.mu b/invites/micro.mu new file mode 100644 index 0000000..7b7931e --- /dev/null +++ b/invites/micro.mu @@ -0,0 +1 @@ +service invites diff --git a/invites/proto/invites.pb.go b/invites/proto/invites.pb.go new file mode 100644 index 0000000..96ea51e --- /dev/null +++ b/invites/proto/invites.pb.go @@ -0,0 +1,737 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.23.0 +// protoc v3.13.0 +// source: proto/invites.proto + +package invites + +import ( + proto "github.com/golang/protobuf/proto" + wrappers "github.com/golang/protobuf/ptypes/wrappers" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type Invite struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + GroupId string `protobuf:"bytes,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` + Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` +} + +func (x *Invite) Reset() { + *x = Invite{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Invite) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Invite) ProtoMessage() {} + +func (x *Invite) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[0] + 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 Invite.ProtoReflect.Descriptor instead. +func (*Invite) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{0} +} + +func (x *Invite) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Invite) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *Invite) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *Invite) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +type CreateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId string `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` +} + +func (x *CreateRequest) Reset() { + *x = CreateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateRequest) ProtoMessage() {} + +func (x *CreateRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[1] + 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 CreateRequest.ProtoReflect.Descriptor instead. +func (*CreateRequest) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateRequest) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *CreateRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +type CreateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Invite *Invite `protobuf:"bytes,1,opt,name=invite,proto3" json:"invite,omitempty"` +} + +func (x *CreateResponse) Reset() { + *x = CreateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateResponse) ProtoMessage() {} + +func (x *CreateResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[2] + 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 CreateResponse.ProtoReflect.Descriptor instead. +func (*CreateResponse) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateResponse) GetInvite() *Invite { + if x != nil { + return x.Invite + } + return nil +} + +type ReadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id *wrappers.StringValue `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Code *wrappers.StringValue `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` +} + +func (x *ReadRequest) Reset() { + *x = ReadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadRequest) ProtoMessage() {} + +func (x *ReadRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[3] + 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 ReadRequest.ProtoReflect.Descriptor instead. +func (*ReadRequest) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{3} +} + +func (x *ReadRequest) GetId() *wrappers.StringValue { + if x != nil { + return x.Id + } + return nil +} + +func (x *ReadRequest) GetCode() *wrappers.StringValue { + if x != nil { + return x.Code + } + return nil +} + +type ReadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Invite *Invite `protobuf:"bytes,1,opt,name=invite,proto3" json:"invite,omitempty"` +} + +func (x *ReadResponse) Reset() { + *x = ReadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResponse) ProtoMessage() {} + +func (x *ReadResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_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 ReadResponse.ProtoReflect.Descriptor instead. +func (*ReadResponse) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{4} +} + +func (x *ReadResponse) GetInvite() *Invite { + if x != nil { + return x.Invite + } + return nil +} + +type ListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId *wrappers.StringValue `protobuf:"bytes,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Email *wrappers.StringValue `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` +} + +func (x *ListRequest) Reset() { + *x = ListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRequest) ProtoMessage() {} + +func (x *ListRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_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 ListRequest.ProtoReflect.Descriptor instead. +func (*ListRequest) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{5} +} + +func (x *ListRequest) GetGroupId() *wrappers.StringValue { + if x != nil { + return x.GroupId + } + return nil +} + +func (x *ListRequest) GetEmail() *wrappers.StringValue { + if x != nil { + return x.Email + } + return nil +} + +type ListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Invites []*Invite `protobuf:"bytes,1,rep,name=invites,proto3" json:"invites,omitempty"` +} + +func (x *ListResponse) Reset() { + *x = ListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResponse) ProtoMessage() {} + +func (x *ListResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[6] + 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 ListResponse.ProtoReflect.Descriptor instead. +func (*ListResponse) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{6} +} + +func (x *ListResponse) GetInvites() []*Invite { + if x != nil { + return x.Invites + } + return nil +} + +type DeleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteRequest) Reset() { + *x = DeleteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRequest) ProtoMessage() {} + +func (x *DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[7] + 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 DeleteRequest.ProtoReflect.Descriptor instead. +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{7} +} + +func (x *DeleteRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteResponse) Reset() { + *x = DeleteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_invites_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResponse) ProtoMessage() {} + +func (x *DeleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_invites_proto_msgTypes[8] + 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 DeleteResponse.ProtoReflect.Descriptor instead. +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return file_proto_invites_proto_rawDescGZIP(), []int{8} +} + +var File_proto_invites_proto protoreflect.FileDescriptor + +var file_proto_invites_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x1a, 0x1e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, + 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x40, 0x0a, + 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, + 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, + 0x39, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x27, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x22, 0x6d, 0x0a, 0x0b, 0x52, 0x65, + 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x02, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x37, 0x0a, 0x0c, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x69, + 0x74, 0x65, 0x22, 0x7a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x37, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x39, + 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, + 0x0a, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x52, 0x07, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x22, 0x1f, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe9, 0x01, 0x0a, + 0x07, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x16, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x69, 0x6e, 0x76, + 0x69, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x14, 0x2e, 0x69, 0x6e, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x15, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x14, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, + 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x17, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0f, 0x5a, 0x0d, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x3b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_proto_invites_proto_rawDescOnce sync.Once + file_proto_invites_proto_rawDescData = file_proto_invites_proto_rawDesc +) + +func file_proto_invites_proto_rawDescGZIP() []byte { + file_proto_invites_proto_rawDescOnce.Do(func() { + file_proto_invites_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_invites_proto_rawDescData) + }) + return file_proto_invites_proto_rawDescData +} + +var file_proto_invites_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_proto_invites_proto_goTypes = []interface{}{ + (*Invite)(nil), // 0: invites.Invite + (*CreateRequest)(nil), // 1: invites.CreateRequest + (*CreateResponse)(nil), // 2: invites.CreateResponse + (*ReadRequest)(nil), // 3: invites.ReadRequest + (*ReadResponse)(nil), // 4: invites.ReadResponse + (*ListRequest)(nil), // 5: invites.ListRequest + (*ListResponse)(nil), // 6: invites.ListResponse + (*DeleteRequest)(nil), // 7: invites.DeleteRequest + (*DeleteResponse)(nil), // 8: invites.DeleteResponse + (*wrappers.StringValue)(nil), // 9: google.protobuf.StringValue +} +var file_proto_invites_proto_depIdxs = []int32{ + 0, // 0: invites.CreateResponse.invite:type_name -> invites.Invite + 9, // 1: invites.ReadRequest.id:type_name -> google.protobuf.StringValue + 9, // 2: invites.ReadRequest.code:type_name -> google.protobuf.StringValue + 0, // 3: invites.ReadResponse.invite:type_name -> invites.Invite + 9, // 4: invites.ListRequest.group_id:type_name -> google.protobuf.StringValue + 9, // 5: invites.ListRequest.email:type_name -> google.protobuf.StringValue + 0, // 6: invites.ListResponse.invites:type_name -> invites.Invite + 1, // 7: invites.Invites.Create:input_type -> invites.CreateRequest + 3, // 8: invites.Invites.Read:input_type -> invites.ReadRequest + 5, // 9: invites.Invites.List:input_type -> invites.ListRequest + 7, // 10: invites.Invites.Delete:input_type -> invites.DeleteRequest + 2, // 11: invites.Invites.Create:output_type -> invites.CreateResponse + 4, // 12: invites.Invites.Read:output_type -> invites.ReadResponse + 6, // 13: invites.Invites.List:output_type -> invites.ListResponse + 8, // 14: invites.Invites.Delete:output_type -> invites.DeleteResponse + 11, // [11:15] is the sub-list for method output_type + 7, // [7:11] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_proto_invites_proto_init() } +func file_proto_invites_proto_init() { + if File_proto_invites_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_invites_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Invite); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_invites_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_invites_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_invites_proto_goTypes, + DependencyIndexes: file_proto_invites_proto_depIdxs, + MessageInfos: file_proto_invites_proto_msgTypes, + }.Build() + File_proto_invites_proto = out.File + file_proto_invites_proto_rawDesc = nil + file_proto_invites_proto_goTypes = nil + file_proto_invites_proto_depIdxs = nil +} diff --git a/invites/proto/invites.pb.micro.go b/invites/proto/invites.pb.micro.go new file mode 100644 index 0000000..b01a1c4 --- /dev/null +++ b/invites/proto/invites.pb.micro.go @@ -0,0 +1,153 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: proto/invites.proto + +package invites + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + _ "github.com/golang/protobuf/ptypes/wrappers" + math "math" +) + +import ( + context "context" + api "github.com/micro/micro/v3/service/api" + client "github.com/micro/micro/v3/service/client" + server "github.com/micro/micro/v3/service/server" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Reference imports to suppress errors if they are not otherwise used. +var _ api.Endpoint +var _ context.Context +var _ client.Option +var _ server.Option + +// Api Endpoints for Invites service + +func NewInvitesEndpoints() []*api.Endpoint { + return []*api.Endpoint{} +} + +// Client API for Invites service + +type InvitesService interface { + // Create an invite + Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) + // Read an invite using ID or code + Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) + // List invited for a group or specific email + List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) + // Delete an invite + Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) +} + +type invitesService struct { + c client.Client + name string +} + +func NewInvitesService(name string, c client.Client) InvitesService { + return &invitesService{ + c: c, + name: name, + } +} + +func (c *invitesService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) { + req := c.c.NewRequest(c.name, "Invites.Create", in) + out := new(CreateResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *invitesService) Read(ctx context.Context, in *ReadRequest, opts ...client.CallOption) (*ReadResponse, error) { + req := c.c.NewRequest(c.name, "Invites.Read", in) + out := new(ReadResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *invitesService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) { + req := c.c.NewRequest(c.name, "Invites.List", in) + out := new(ListResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *invitesService) Delete(ctx context.Context, in *DeleteRequest, opts ...client.CallOption) (*DeleteResponse, error) { + req := c.c.NewRequest(c.name, "Invites.Delete", in) + out := new(DeleteResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Invites service + +type InvitesHandler interface { + // Create an invite + Create(context.Context, *CreateRequest, *CreateResponse) error + // Read an invite using ID or code + Read(context.Context, *ReadRequest, *ReadResponse) error + // List invited for a group or specific email + List(context.Context, *ListRequest, *ListResponse) error + // Delete an invite + Delete(context.Context, *DeleteRequest, *DeleteResponse) error +} + +func RegisterInvitesHandler(s server.Server, hdlr InvitesHandler, opts ...server.HandlerOption) error { + type invites interface { + Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error + Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error + List(ctx context.Context, in *ListRequest, out *ListResponse) error + Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error + } + type Invites struct { + invites + } + h := &invitesHandler{hdlr} + return s.Handle(s.NewHandler(&Invites{h}, opts...)) +} + +type invitesHandler struct { + InvitesHandler +} + +func (h *invitesHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error { + return h.InvitesHandler.Create(ctx, in, out) +} + +func (h *invitesHandler) Read(ctx context.Context, in *ReadRequest, out *ReadResponse) error { + return h.InvitesHandler.Read(ctx, in, out) +} + +func (h *invitesHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error { + return h.InvitesHandler.List(ctx, in, out) +} + +func (h *invitesHandler) Delete(ctx context.Context, in *DeleteRequest, out *DeleteResponse) error { + return h.InvitesHandler.Delete(ctx, in, out) +} diff --git a/invites/proto/invites.proto b/invites/proto/invites.proto new file mode 100644 index 0000000..c46c3e6 --- /dev/null +++ b/invites/proto/invites.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +package invites; +option go_package = "proto;invites"; +import "google/protobuf/wrappers.proto"; + +service Invites { + // Create an invite + rpc Create(CreateRequest) returns (CreateResponse); + // Read an invite using ID or code + rpc Read(ReadRequest) returns (ReadResponse); + // List invited for a group or specific email + rpc List(ListRequest) returns (ListResponse); + // Delete an invite + rpc Delete(DeleteRequest) returns (DeleteResponse); +} + +message Invite { + string id = 1; + string group_id = 2; + string email = 3; + string code = 4; +} + +message CreateRequest { + string group_id = 1; + string email = 2; +} + +message CreateResponse { + Invite invite = 1; +} + +message ReadRequest { + google.protobuf.StringValue id = 1; + google.protobuf.StringValue code = 2; +} + +message ReadResponse { + Invite invite = 1; +} + +message ListRequest { + google.protobuf.StringValue group_id = 1; + google.protobuf.StringValue email = 2; +} + +message ListResponse { + repeated Invite invites = 1; +} + +message DeleteRequest { + string id = 1; +} + +message DeleteResponse {} \ No newline at end of file