commit 5af1a98b49962733c8f93f9b80243e3c0edfb386 Author: Vyacheslav1557 Date: Mon Jul 15 02:26:34 2024 +0500 feat: init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..451fb35 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +.idea \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..78e7a26 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:latest + +WORKDIR /app + +COPY . . + +RUN go build ./main.go + +CMD ["./main"] \ No newline at end of file diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..d5b53a4 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,12 @@ +version: v1 +managed: + enabled: true + go_package_prefix: + default: ms-auth/pkg/go/gen +plugins: + - name: go + out: pkg/go/gen + opt: paths=source_relative + - name: go-grpc + out: pkg/go/gen + opt: paths=source_relative diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 0000000..1a51945 --- /dev/null +++ b/buf.yaml @@ -0,0 +1,7 @@ +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d3a96e9 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,75 @@ +version: '3' + +networks: + local: + +volumes: + db: + +services: + auth-service: + build: + dockerfile: ./Dockerfile + env_file: + - .env + ports: + - "8090:8090" + depends_on: + # postgres: + # condition: service_healthy + # valkey: + # condition: service_healthy + migrate: + condition: service_completed_successfully + networks: + - local + + postgres: + image: postgres:14.1-alpine + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: supersecretpassword + networks: + - local + ports: + - '5432:5432' + volumes: + - db:/var/lib/postgresql/data + healthcheck: + test: pg_isready -U postgres -d postgres + interval: 10s + timeout: 3s + retries: 5 + + migrate: + image: ghcr.io/kukymbr/goose-docker:latest + networks: + - local + volumes: + - ./migrations:/migrations + environment: + GOOSE_DRIVER: "postgres" + GOOSE_DBSTRING: "host=postgres user=postgres password=supersecretpassword dbname=postgres port=5432 sslmode=disable" + depends_on: + postgres: + condition: service_healthy + + valkey: + container_name: valkey + hostname: valkey + image: valkey/valkey:latest + build: . + volumes: + - ./conf/valkey.conf:/usr/local/etc/valkey/valkey.conf + - ./data:/data + command: ["valkey-server", "/usr/local/etc/valkey/valkey.conf"] + healthcheck: + test: ["CMD-SHELL", "valkey-cli ping | grep PONG"] + interval: 1s + timeout: 3s + retries: 5 + ports: + - 6379:6379 + networks: + - local diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f066882 --- /dev/null +++ b/go.mod @@ -0,0 +1,37 @@ +module ms-auth + +go 1.21.3 + +require ( + github.com/google/uuid v1.6.0 + github.com/ilyakaznacheev/cleanenv v1.5.0 + github.com/valkey-io/valkey-go v1.0.38 + golang.org/x/crypto v0.24.0 + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.1 +) + +require ( + github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect +) + +require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible + github.com/jackc/pgx/v5 v5.6.0 + github.com/jmoiron/sqlx v1.4.0 + github.com/joho/godotenv v1.5.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3c1c147 --- /dev/null +++ b/go.sum @@ -0,0 +1,80 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4= +github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 h1:Dj0L5fhJ9F82ZJyVOmBx6msDp/kfd1t9GRfny/mfJA0= +github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= +github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/valkey-io/valkey-go v1.0.38 h1:0g+ozx+WUGmu18h8SVGoIyxdWp820utVLlFkGnQ3h0c= +github.com/valkey-io/valkey-go v1.0.38/go.mod h1:LXqAbjygRuA1YRocojTslAGx2dQB4p8feaseGviWka4= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ= +olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw= diff --git a/internal/app/app.go b/internal/app/app.go new file mode 100644 index 0000000..d97d15e --- /dev/null +++ b/internal/app/app.go @@ -0,0 +1,35 @@ +package app + +import ( + "log/slog" + "ms-auth/internal/lib" + + _ "github.com/jackc/pgx/v5/stdlib" +) + +type Server interface { + Start() + GracefullyStop() +} + +type App struct { + server Server + cfg *lib.Config +} + +func NewApp(cfg *lib.Config, server Server) *App { + return &App{ + server: server, + cfg: cfg, + } +} + +func (app *App) Start() { + app.server.Start() + slog.Info("app started") +} + +func (app *App) GracefullyStop() { + app.server.GracefullyStop() + slog.Info("app stopped") +} diff --git a/internal/lib/config.go b/internal/lib/config.go new file mode 100644 index 0000000..443f158 --- /dev/null +++ b/internal/lib/config.go @@ -0,0 +1,27 @@ +package lib + +import ( + "fmt" + "github.com/ilyakaznacheev/cleanenv" +) + +type Config struct { + Env string `env:"ENV" env-default:"prod"` + + PostgresDSN string `env:"POSTGRES_DSN" required:"true"` + RedisDSN string `env:"REDIS_DSN" required:"true"` + + Email string `env:"EMAIL" required:"true"` + Password string `env:"PASSWORD" required:"true"` + + JWTSecret string `env:"JWT_SECRET" required:"true"` +} + +func MustSetupConfig() *Config { + var cfg Config + err := cleanenv.ReadConfig(".env", &cfg) + if err != nil { + panic(fmt.Sprintf("error reading config: %s", err.Error())) + } + return &cfg +} diff --git a/internal/lib/errors.go b/internal/lib/errors.go new file mode 100644 index 0000000..f63a456 --- /dev/null +++ b/internal/lib/errors.go @@ -0,0 +1,22 @@ +package lib + +import ( + "errors" +) + +var ( + ErrInternal = errors.New("internal") + ErrUnexpected = errors.New("unexpected") + ErrNoPermission = errors.New("no permission") +) + +var ( + ErrBadHandleOrPassword = errors.New("bad handle or password") + ErrBadRole = errors.New("bad role") + ErrTooShortPassword = errors.New("too short password") + ErrTooLongPassword = errors.New("too long password") + ErrBadEmail = errors.New("bad email") + ErrBadUsername = errors.New("bad username") + ErrTooShortUsername = errors.New("too short username") + ErrTooLongUsername = errors.New("too long username") +) diff --git a/internal/lib/lib.go b/internal/lib/lib.go new file mode 100644 index 0000000..744d091 --- /dev/null +++ b/internal/lib/lib.go @@ -0,0 +1,40 @@ +package lib + +import ( + "time" +) + +const ( + RoleSpectator int32 = 0 + RoleParticipant int32 = 1 + RoleModerator int32 = 2 + RoleAdmin int32 = 3 +) + +func IsAdmin(role int32) bool { + return role == RoleAdmin +} + +func IsModerator(role int32) bool { + return role == RoleModerator +} + +func IsParticipant(role int32) bool { + return role == RoleParticipant +} + +func IsSpectator(role int32) bool { + return role == RoleSpectator +} + +func AsTimeP(t time.Time) *time.Time { + return &t +} + +func AsInt32P(v int32) *int32 { + return &v +} + +func AsStringP(str string) *string { + return &str +} diff --git a/internal/lib/mail.go b/internal/lib/mail.go new file mode 100644 index 0000000..bac4b82 --- /dev/null +++ b/internal/lib/mail.go @@ -0,0 +1,19 @@ +package lib + +import ( + "fmt" + "net/smtp" +) + +func SendMail(cfg Config, to []string, subject, body string) error { + auth := smtp.PlainAuth("", cfg.Email, cfg.Password, "smtp.gmail.com") + + msg := fmt.Sprintf("From: %s\nTo: %s\nSubject: %s\n%s", cfg.Email, "", subject, body) + + err := smtp.SendMail("smtp.gmail.com:587", auth, cfg.Email, to, []byte(msg)) + if err != nil { + return err // FIXME + } + + return nil +} diff --git a/internal/lib/validation.go b/internal/lib/validation.go new file mode 100644 index 0000000..e1848e3 --- /dev/null +++ b/internal/lib/validation.go @@ -0,0 +1,44 @@ +package lib + +import ( + "net/mail" +) + +func ValidPassword(str string) error { + if len(str) < 5 { + return ErrTooShortPassword + } + if len(str) > 70 { + return ErrTooLongPassword + } + return nil +} + +func ValidUsername(str string) error { + if len(str) < 5 { + return ErrTooShortUsername + } + if len(str) > 70 { + return ErrTooLongUsername + } + if err := ValidEmail(str); err == nil { + return ErrBadUsername + } + return nil +} + +func ValidEmail(str string) error { + emailAddress, err := mail.ParseAddress(str) + if err != nil || emailAddress.Address != str { + return ErrBadEmail + } + return nil +} + +func ValidRole(role int32) error { + switch role { + case RoleSpectator, RoleParticipant, RoleModerator, RoleAdmin: + return nil + } + return ErrBadRole +} diff --git a/internal/services/email.go b/internal/services/email.go new file mode 100644 index 0000000..5e568ea --- /dev/null +++ b/internal/services/email.go @@ -0,0 +1 @@ +package services diff --git a/internal/services/session.go b/internal/services/session.go new file mode 100644 index 0000000..7db7bbe --- /dev/null +++ b/internal/services/session.go @@ -0,0 +1,147 @@ +package services + +import ( + "context" + "ms-auth/internal/lib" + "ms-auth/internal/storage" +) + +type SessionProvider interface { + CreateSession(ctx context.Context, userId int32) error + ReadSessionByToken(ctx context.Context, token string) (*storage.Session, error) + ReadSessionByUserId(ctx context.Context, userId int32) (*storage.Session, error) + UpdateSession(ctx context.Context, session *storage.Session) error + DeleteSessionByToken(ctx context.Context, token string) error + DeleteSessionByUserId(ctx context.Context, userId int32) error +} + +// SessionService represents a service for managing sessions. +type SessionService struct { + sessionProvider SessionProvider + userProvider UserProvider + cfg *lib.Config +} + +// NewSessionService creates a new SessionService instance. +// +// Parameters: +// - sessionProvider: The SessionProvider implementation used by the SessionService. +// - userProvider: The UserProvider implementation used by the SessionService. +// - cfg: The lib.Config object used by the SessionService. +// +// Returns: +// - *SessionService: A pointer to the SessionService instance. +func NewSessionService(sessionProvider SessionProvider, userProvider UserProvider, cfg *lib.Config) *SessionService { + return &SessionService{ + sessionProvider: sessionProvider, + userProvider: userProvider, + cfg: cfg, + } +} + +// Create creates a new session for a user with the given handle and password. +// +// Parameters: +// - ctx: The context.Context object for the request. +// - handle: The handle (username or email) of the user. +// - password: The password of the user. +// +// Returns: +// - *string: A pointer to the token of the newly created session, or nil if there was an error. +// - error: An error if the creation of the session or the retrieval of the session's token failed. +func (s *SessionService) Create(ctx context.Context, handle, password string) (*string, error) { + var ( + err error + user *storage.User + ) + + if lib.ValidUsername(handle) == nil { + user, err = s.userProvider.ReadUserByUsername(ctx, handle) + } else if lib.ValidEmail(handle) == nil { + user, err = s.userProvider.ReadUserByEmail(ctx, handle) + } else { + return nil, lib.ErrBadHandleOrPassword + } + if err != nil { + return nil, err + } + + err = user.ComparePassword(password) + if err != nil { + return nil, err + } + + err = s.sessionProvider.CreateSession(ctx, user.Id) + if err != nil { + return nil, err + } + + session, err := s.sessionProvider.ReadSessionByUserId(ctx, user.Id) + if err != nil { + return nil, err + } + + token, err := session.Token(s.cfg.JWTSecret) + if err != nil { + return nil, err + } + + return &token, nil +} + +// Read retrieves the user ID associated with the given session token. +// +// Parameters: +// - ctx: The context.Context object for the request. +// - token: The session token. +// +// Returns: +// - *int32: The user ID associated with the session token, or nil if an error occurs. +// - error: An error object if any error occurs during the retrieval process. +func (s *SessionService) Read(ctx context.Context, token string) (*int32, error) { + session, err := s.sessionProvider.ReadSessionByToken(ctx, token) + if err != nil { + return nil, err + } + return session.UserId, nil +} + +// Update updates the session associated with the given token. +// +// Parameters: +// - ctx: The context.Context object for the request. +// - token: The session token. +// +// Returns: +// - error: An error object if any error occurs during the update process. +func (s *SessionService) Update(ctx context.Context, token string) error { + session, err := s.sessionProvider.ReadSessionByToken(ctx, token) + if err != nil { + return err + } + err = s.sessionProvider.UpdateSession(ctx, session) + if err != nil { + return err + } + return nil +} + +// Delete deletes the session associated with the given token. +// +// Parameters: +// - ctx: The context.Context object for the request. +// - token: The session token. +// +// Returns: +// - error: An error object if any error occurs during the deletion process. +func (s *SessionService) Delete(ctx context.Context, token string) error { + session, err := s.sessionProvider.ReadSessionByToken(ctx, token) + if err != nil { + return err + } + err = s.sessionProvider.DeleteSessionByUserId(ctx, *session.UserId) + if err != nil { + return err + } + return nil +} diff --git a/internal/services/user.go b/internal/services/user.go new file mode 100644 index 0000000..6915560 --- /dev/null +++ b/internal/services/user.go @@ -0,0 +1,235 @@ +package services + +import ( + "context" + "ms-auth/internal/lib" + "ms-auth/internal/storage" + "time" +) + +type UserProvider interface { + CreateUser( + ctx context.Context, + username string, + password string, + email *string, + expiresAt *time.Time, + role *int32, + ) (*int32, error) + ReadUserByEmail(ctx context.Context, email string) (*storage.User, error) + ReadUserByUsername(ctx context.Context, username string) (*storage.User, error) + ReadUserById(ctx context.Context, id int32) (*storage.User, error) + UpdateUser( + ctx context.Context, + id int32, + username *string, + password *string, + email *string, + expiresAt *time.Time, + role *int32, + ) error + DeleteUser(ctx context.Context, id int32) error +} + +type ConfirmationProvider interface { + CreateConfirmation(ctx context.Context, conf *storage.Confirmation) error + ReadConfirmation(ctx context.Context, confId string) (*storage.Confirmation, error) + DeleteConfirmation(ctx context.Context, confId string) error +} + +type EmailProvider interface { + SendMail(ctx context.Context, to []string, subject string, body string) error +} + +// UserService represents a service for managing users. +type UserService struct { + userProvider UserProvider + sessionProvider SessionProvider + confirmationProvider ConfirmationProvider + //emailProvider EmailProvider + cfg *lib.Config +} + +// NewUserService creates a new UserService instance. +// +// Parameters: +// - userProvider: The UserProvider implementation used by the UserService. +// - sessionProvider: The SessionProvider implementation used by the UserService. +// - confirmationProvider: The ConfirmationProvider implementation used by the UserService. +// - emailProvider: The EmailProvider implementation used by the UserService. +// - cfg: The lib.Config object used by the UserService. +// +// Returns: +// - *UserService: A pointer to the newly created UserService instance. +func NewUserService( + userProvider UserProvider, + sessionProvider SessionProvider, + confirmationProvider ConfirmationProvider, + //emailProvider EmailProvider, + cfg *lib.Config, +) *UserService { + return &UserService{ + userProvider: userProvider, + sessionProvider: sessionProvider, + confirmationProvider: confirmationProvider, + //emailProvider: emailProvider, + cfg: cfg, + } +} + +// CreateUser creates a new user with the provided information. +// +// Parameters: +// - ctx: The context for the operation. +// - token: The token associated with the session. +// - username: The username of the new user. +// - password: The password of the new user. +// - email: The email of the new user (can be nil). +// - expiresAt: The expiration time for the user account (can be nil). +// - role: The role of the new user. +// +// Returns: +// - *int32: The ID of the created user. +// - error: An error if the operation fails. +func (u *UserService) CreateUser(ctx context.Context, token, username, password string, email *string, expiresAt *time.Time, role *int32) (*int32, error) { + user, err := u.ReadUserBySessionToken(ctx, token) + if err != nil { + return nil, err + } + + canCreate := func() bool { + if !user.IsAdmin() && !user.IsModerator() { + return false + } + + if role != nil && user.IsModerator() { + if lib.IsModerator(*role) || lib.IsAdmin(*role) { + return false + } + } + return true + }() + + if !canCreate { + return nil, lib.ErrNoPermission + } + + return u.userProvider.CreateUser(ctx, username, password, email, expiresAt, role) +} + +// ReadUserBySessionToken reads a user by session token. +// +// Parameters: +// - ctx: The context of the request. +// - token: The session token to identify the user. +// +// Returns: +// - *storage.User: The user information. +// - error: An error if the operation fails. +func (u *UserService) ReadUserBySessionToken(ctx context.Context, token string) (*storage.User, error) { + session, err := u.sessionProvider.ReadSessionByToken(ctx, token) + if err != nil { + return nil, err + } + + return u.userProvider.ReadUserById(ctx, *session.UserId) +} + +// ReadUser reads a user by ID. +// +// Parameters: +// - ctx: The context of the request. +// - token: The session token to identify the user. +// - id: The ID of the user to read. +// +// Returns: +// - *storage.User: The user information. +// - error: An error if the operation fails. +func (u *UserService) ReadUser(ctx context.Context, token string, id int32) (*storage.User, error) { + _, err := u.ReadUserBySessionToken(ctx, token) + if err != nil { + return nil, err + } + + return u.userProvider.ReadUserById(ctx, id) +} + +// UpdateUser updates a user's information. +// +// Parameters: +// - ctx: The context of the request. +// - token: The session token to identify the user. +// - id: The ID of the user to update. +// - username: The new username (can be nil). +// - password: The new password (can be nil). +// - email: The new email (can be nil). +// - expiresAt: The new expiration time (can be nil). +// - role: The new role (can be nil). +// +// Returns: +// - error: An error if the operation fails. +func (u *UserService) UpdateUser(ctx context.Context, token string, id int32, username *string, password *string, email *string, expiresAt *time.Time, role *int32) error { + me, err := u.ReadUserBySessionToken(ctx, token) + if err != nil { + return err + } + + user, err := u.userProvider.ReadUserById(ctx, id) + if err != nil { + return err + } + + hasAccess := func() bool { + if me.Id == user.Id { + return false + } + if me.IsAdmin() { + return true + } + if me.IsModerator() && (user.IsParticipant() || user.IsSpectator()) { + return true + } + return false + }() + + if !hasAccess { + return lib.ErrNoPermission + } + + return u.userProvider.UpdateUser(ctx, id, username, password, email, expiresAt, role) +} + +// DeleteUser deletes a user by id. +// +// Parameters: +// - ctx: The context of the request. +// - token: The session token to identify the authenticated user. +// - id: The ID of the user to delete. +// +// Returns: +// - error: An error if the operation fails. +func (u *UserService) DeleteUser(ctx context.Context, token string, id int32) error { + user, err := u.ReadUserBySessionToken(ctx, token) + if err != nil { + return err + } + + if user.Id == id || !user.IsAdmin() { + return lib.ErrNoPermission + } + + return u.userProvider.DeleteUser(ctx, id) +} + +// ReadUserByEmail reads a user by email. +// +// Parameters: +// - ctx: The context of the request. +// - email: The email of the user to read. +// +// Returns: +// - *storage.User: The user information. +// - error: An error if the operation fails. +func (u *UserService) ReadUserByEmail(ctx context.Context, email string) (*storage.User, error) { + return u.userProvider.ReadUserByEmail(ctx, email) +} diff --git a/internal/storage/postgresql.go b/internal/storage/postgresql.go new file mode 100644 index 0000000..ffe3bca --- /dev/null +++ b/internal/storage/postgresql.go @@ -0,0 +1,263 @@ +package storage + +import ( + "context" + "errors" + "github.com/jackc/pgerrcode" + "github.com/jackc/pgx/v5/pgconn" + "go.uber.org/zap" + "golang.org/x/crypto/bcrypt" + "ms-auth/internal/lib" + "strings" + "time" + + "github.com/jmoiron/sqlx" +) + +type PostgresqlStorage struct { + db *sqlx.DB + logger *zap.Logger +} + +func NewUserStorage(dsn string, logger *zap.Logger) *PostgresqlStorage { + db, err := sqlx.Connect("pgx", dsn) + if err != nil { + panic(err.Error()) + } + + return &PostgresqlStorage{db: db, logger: logger} +} + +func (storage *PostgresqlStorage) Stop() error { + return storage.db.Close() +} + +const ( + shortUserLifetime = time.Hour * 24 * 30 + defaultUserLifetime = time.Hour * 24 * 365 * 100 +) + +type User struct { + Id int32 `db:"id"` + + Username string `db:"username"` + HashedPassword []byte `db:"hashed_password"` + + Email *string `db:"email"` + + ExpiresAt time.Time `db:"expires_at"` + CreatedAt time.Time `db:"created_at"` + + Role int32 `db:"role"` +} + +func (hashedUser *User) IsAdmin() bool { + return lib.IsAdmin(hashedUser.Role) +} + +func (hashedUser *User) IsModerator() bool { + return lib.IsModerator(hashedUser.Role) +} + +func (hashedUser *User) IsParticipant() bool { + return lib.IsParticipant(hashedUser.Role) +} + +func (hashedUser *User) IsSpectator() bool { + return lib.IsSpectator(hashedUser.Role) +} + +func (hashedUser *User) ComparePassword(password string) error { + if bcrypt.CompareHashAndPassword(hashedUser.HashedPassword, []byte(password)) != nil { + return lib.ErrBadHandleOrPassword + } + return nil +} + +func (storage *PostgresqlStorage) CreateUser( + ctx context.Context, + username string, + password string, + email *string, + expiresAt *time.Time, + role *int32, +) (*int32, error) { + if err := lib.ValidUsername(username); err != nil { + return nil, err + } + if err := lib.ValidPassword(password); err != nil { + return nil, err + } + if email != nil { + if err := lib.ValidEmail(*email); err != nil { + return nil, err + } + } + if role != nil { + if err := lib.ValidRole(*role); err != nil { + return nil, err + } + } + + username = strings.ToLower(username) + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + now := time.Now() + username = strings.ToLower(username) + if email != nil { + *email = strings.ToLower(*email) + } + if role == nil { + role = lib.AsInt32P(lib.RoleSpectator) + } + if expiresAt == nil { + if email == nil { + expiresAt = lib.AsTimeP(now.Add(shortUserLifetime)) + } else { + expiresAt = lib.AsTimeP(now.Add(defaultUserLifetime)) + } + } + + query := storage.db.Rebind(` +INSERT INTO users + (username, hashed_password, email, expires_at, created_at, role) +VALUES (?, ?, ?, ?, ?, ?) +RETURNING id +`) + + rows, err := storage.db.QueryxContext(ctx, query, username, hashedPassword, email, expiresAt, now, role) + if err != nil { + return nil, storage.handlePgErr(err) + } + defer rows.Close() + var id int32 + err = rows.StructScan(&id) + if err != nil { + return nil, storage.handlePgErr(err) + } + return &id, nil +} +func (storage *PostgresqlStorage) ReadUserByEmail(ctx context.Context, email string) (*User, error) { + if err := lib.ValidEmail(email); err != nil { + return nil, err + } + + email = strings.ToLower(email) + + var user User + query := storage.db.Rebind("SELECT * from users WHERE email=? LIMIT 1") + err := storage.db.GetContext(ctx, &user, query, email) + if err != nil { + return nil, storage.handlePgErr(err) + } + return &user, nil +} +func (storage *PostgresqlStorage) ReadUserByUsername(ctx context.Context, username string) (*User, error) { + if err := lib.ValidUsername(username); err != nil { + return nil, err + } + + username = strings.ToLower(username) + + var user User + query := storage.db.Rebind("SELECT * from users WHERE username=? LIMIT 1") + err := storage.db.GetContext(ctx, &user, query, username) + if err != nil { + return nil, storage.handlePgErr(err) + } + return &user, nil +} +func (storage *PostgresqlStorage) ReadUserById(ctx context.Context, id int32) (*User, error) { + var user User + query := storage.db.Rebind("SELECT * from users WHERE id=? LIMIT 1") + err := storage.db.GetContext(ctx, &user, query, id) + if err != nil { + return nil, storage.handlePgErr(err) + } + return &user, nil +} + +func (storage *PostgresqlStorage) UpdateUser( + ctx context.Context, + id int32, + username *string, + password *string, + email *string, + expiresAt *time.Time, + role *int32, +) error { + var err error + if username != nil { + if err = lib.ValidUsername(*username); err != nil { + return err + } + } + var hashedPassword []byte + if password != nil { + if err = lib.ValidPassword(*password); err != nil { + return err + } + hashedPassword, err = bcrypt.GenerateFromPassword([]byte(*password), bcrypt.DefaultCost) + if err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + } + if email != nil { + if err = lib.ValidEmail(*email); err != nil { + return err + } + } + if role != nil { + if err = lib.ValidRole(*role); err != nil { + return err + } + } + + if username != nil { + *username = strings.ToLower(*username) + } + if email != nil { + *email = strings.ToLower(*email) + } + + query := storage.db.Rebind(` +UPDATE users +SET username = COALESCE(?, username), + hashed_password = COALESCE(?, hashed_password), + email = COALESCE(?, email), + expires_at = COALESCE(?, expires_at), + role = COALESCE(?, role) +WHERE id = ?`) + + _, err = storage.db.ExecContext(ctx, query, username, hashedPassword, email, expiresAt, role, id) + if err != nil { + return storage.handlePgErr(err) + } + return nil +} +func (storage *PostgresqlStorage) DeleteUser(ctx context.Context, id int32) error { + query := storage.db.Rebind("UPDATE users SET expired_at=NOW() WHERE id = ?") + _, err := storage.db.ExecContext(ctx, query, id) + if err != nil { + return storage.handlePgErr(err) + } + + return nil +} + +func (storage *PostgresqlStorage) handlePgErr(err error) error { + var pgErr *pgconn.PgError + if !errors.As(err, &pgErr) { + storage.logger.DPanic("unexpected error from postgres", zap.String("err", err.Error())) + return lib.ErrUnexpected + } + if pgerrcode.IsIntegrityConstraintViolation(pgErr.Code) { + return errors.New("unique key violation") // FIXME + } + storage.logger.DPanic("unexpected internal error from postgres", zap.String("err", err.Error())) + return lib.ErrInternal +} diff --git a/internal/storage/valkey.go b/internal/storage/valkey.go new file mode 100644 index 0000000..c6e8142 --- /dev/null +++ b/internal/storage/valkey.go @@ -0,0 +1,332 @@ +package storage + +import ( + "context" + "encoding/json" + "errors" + "go.uber.org/zap" + "time" + + "ms-auth/internal/lib" + + "github.com/golang-jwt/jwt" + "github.com/google/uuid" + "github.com/valkey-io/valkey-go" + "github.com/valkey-io/valkey-go/valkeylock" +) + +type ValkeyStorage struct { + db valkey.Client + locker valkeylock.Locker + cfg *lib.Config + logger *zap.Logger +} + +func NewValkeyStorage(dsn string, cfg *lib.Config, logger *zap.Logger) *ValkeyStorage { + opts, err := valkey.ParseURL(dsn) + if err != nil { + panic(err.Error()) + } + + db, err := valkey.NewClient(opts) + if err != nil { + panic(err.Error()) + } + + locker, err := valkeylock.NewLocker(valkeylock.LockerOption{ + ClientOption: opts, + KeyMajority: 1, + NoLoopTracking: true, + }) + if err != nil { + panic(err.Error()) + } + + return &ValkeyStorage{ + db: db, + locker: locker, + cfg: cfg, + logger: logger, + } +} + +func (storage *ValkeyStorage) Stop() error { + storage.db.Close() + storage.locker.Close() + return nil +} + +const ( + sessionLifetime = time.Minute * 40 + confirmationLifetime = time.Hour * 5 +) + +func (storage *ValkeyStorage) CreateSession( + ctx context.Context, + user_id int32, +) error { + session := NewSession(user_id) + + resp := storage.db.Do(ctx, storage.db. + B().Set(). + Key(string(*session.UserId)). + Value(*session.Id). + Nx(). + Exat(time.Now().Add(sessionLifetime)). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + + return nil +} + +func (storage *ValkeyStorage) ReadSessionByToken(ctx context.Context, token string) (*Session, error) { + session, err := Parse(token, storage.cfg.JWTSecret) + if err != nil { + storage.logger.Error(err.Error()) + return nil, err + } + + real_session, err := storage.ReadSessionByUserId(ctx, *session.UserId) + if err != nil { + storage.logger.Error(err.Error()) + return nil, err + } + + if *session.Id != *real_session.Id { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + return session, err +} + +func (storage *ValkeyStorage) ReadSessionByUserId(ctx context.Context, user_id int32) (*Session, error) { + resp := storage.db.Do(ctx, storage.db.B().Get().Key(string(user_id)).Build()) + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + id, err := resp.ToString() + if err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + return &Session{ + Id: &id, + UserId: &user_id, + }, err +} + +func (storage *ValkeyStorage) UpdateSession(ctx context.Context, session *Session) error { + resp := storage.db.Do(ctx, storage.db. + B().Set(). + Key(string(*session.UserId)). + Value(*session.Id). + Xx(). + Exat(time.Now().Add(sessionLifetime)). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + + return nil +} + +func (storage *ValkeyStorage) DeleteSessionByToken(ctx context.Context, token string) error { + session, err := Parse(token, storage.cfg.JWTSecret) + if err != nil { + storage.logger.Error(err.Error()) + return err + } + + err = storage.DeleteSessionByUserId(ctx, *session.UserId) + if err != nil { + storage.logger.Error(err.Error()) + return err + } + + return nil +} + +func (storage *ValkeyStorage) DeleteSessionByUserId(ctx context.Context, user_id int32) error { + resp := storage.db.Do(ctx, storage.db. + B().Del(). + Key(string(user_id)). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + + return nil +} + +func (storage *ValkeyStorage) CreateConfirmation(ctx context.Context, conf *Confirmation) error { + resp := storage.db.Do(ctx, storage.db. + B().Set(). + Key(*conf.Id). + Value(string(conf.JSON())). + Exat(time.Now().Add(confirmationLifetime)). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + + return nil +} + +func (storage *ValkeyStorage) ReadConfirmation(ctx context.Context, conf_id string) (*Confirmation, error) { + resp := storage.db.Do(ctx, storage.db. + B().Get(). + Key(conf_id). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + b, err := resp.AsBytes() + if err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + var conf Confirmation + err = json.Unmarshal(b, &conf) + if err != nil { + storage.logger.Error(err.Error()) + return nil, lib.ErrInternal + } + + return &conf, nil +} + +func (storage *ValkeyStorage) DeleteConfirmation(ctx context.Context, conf_id string) error { + resp := storage.db.Do(ctx, storage.db. + B().Del(). + Key(conf_id). + Build(), + ) + + if err := resp.Error(); err != nil { + storage.logger.Error(err.Error()) + return lib.ErrInternal + } + + return nil +} + +var ( + ErrBadSession = errors.New("bad session") + ErrBadConfirmation = errors.New("bad confirmation") +) + +type Confirmation struct { + Id *string `json:"id"` + UserId *int32 `json:"user_id,omitempty"` + Email *string `json:"email"` +} + +func NewConfirmation(userId *int32, email string) (*Confirmation, error) { + c := &Confirmation{ + Id: lib.AsStringP(uuid.NewString()), + UserId: userId, + Email: &email, + } + + if err := c.Valid(); err != nil { + return nil, err + } + + return c, nil +} + +func (c *Confirmation) Valid() error { + if c.Id == nil { + return ErrBadConfirmation + } + // FIXME + // if c.userId == nil { + // return ErrBadConfirmation + // } + if c.Email == nil { + return ErrBadConfirmation + } + if err := lib.ValidEmail(*c.Email); err != nil { + return err + } + return nil +} + +func (c *Confirmation) JSON() []byte { + b, err := json.Marshal(c) + if err != nil { + panic(err.Error()) + } + return b +} + +type Session struct { + Id *string + UserId *int32 +} + +func NewSession(userId int32) *Session { + return &Session{ + Id: lib.AsStringP(uuid.NewString()), + UserId: &userId, + } +} + +func (s Session) Valid() error { + if s.Id == nil { + return ErrBadSession + } + if s.UserId == nil { + return ErrBadSession + } + return nil +} + +func (s Session) Token(secret string) (string, error) { + if err := s.Valid(); err != nil { + return "", err + } + refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, s) + str, err := refreshToken.SignedString([]byte(secret)) + if err != nil { + return "", ErrBadSession + } + return str, nil +} + +func Parse(tkn string, secret string) (*Session, error) { + parsedToken, err := jwt.ParseWithClaims(tkn, &Session{}, func(token *jwt.Token) (interface{}, error) { + return []byte(secret), nil + }) + if err != nil { + return nil, ErrBadSession + } + session := parsedToken.Claims.(*Session) + if err := session.Valid(); err != nil { + return nil, err + } + return session, nil +} diff --git a/internal/transport/email_server.go b/internal/transport/email_server.go new file mode 100644 index 0000000..bbc926c --- /dev/null +++ b/internal/transport/email_server.go @@ -0,0 +1,11 @@ +package transport + +import ( + "context" + "google.golang.org/protobuf/types/known/emptypb" + emailv1 "ms-auth/pkg/go/gen/email/v1" +) + +func (s *AuthServer) SendEmail(ctx context.Context, req *emailv1.SendEmailRequest) (*emptypb.Empty, error) { + panic("not implemented") +} diff --git a/internal/transport/interceptors.go b/internal/transport/interceptors.go new file mode 100644 index 0000000..d11d0be --- /dev/null +++ b/internal/transport/interceptors.go @@ -0,0 +1 @@ +package transport diff --git a/internal/transport/server.go b/internal/transport/server.go new file mode 100644 index 0000000..0a887a3 --- /dev/null +++ b/internal/transport/server.go @@ -0,0 +1,123 @@ +package transport + +import ( + "context" + "go.uber.org/zap" + "google.golang.org/protobuf/types/known/timestamppb" + "ms-auth/internal/storage" + emailv1 "ms-auth/pkg/go/gen/email/v1" + sessionv1 "ms-auth/pkg/go/gen/session/v1" + userv1 "ms-auth/pkg/go/gen/user/v1" + "net" + "time" + + "google.golang.org/grpc" +) + +type SessionServiceI interface { + Create(ctx context.Context, handle, password string) (*string, error) + Read(ctx context.Context, token string) (*int32, error) + Update(ctx context.Context, token string) error + Delete(ctx context.Context, token string) error +} + +type UserServiceI interface { + CreateUser(ctx context.Context, token, username, password string, email *string, expiresAt *time.Time, role *int32) (*int32, error) + ReadUser(ctx context.Context, token string, id int32) (*storage.User, error) + UpdateUser(ctx context.Context, token string, id int32, username *string, password *string, email *string, expiresAt *time.Time, role *int32) error + DeleteUser(ctx context.Context, token string, id int32) error +} + +type AuthServer struct { + emailv1.UnimplementedEmailServiceServer + + sessionv1.UnimplementedSessionServiceServer + sessionService SessionServiceI + + userv1.UnimplementedUserServiceServer + userService UserServiceI + + gRPCServer *grpc.Server + logger *zap.Logger +} + +// NewAuthServer creates a new instance of the AuthServer struct. +// +// Parameters: +// - sessionService: A pointer to the SessionServiceI interface. +// - gRPCServer: A pointer to the grpc.Server struct. +// - logger: A pointer to the zap.Logger struct. +// +// Returns: +// - *AuthServer: A pointer to the AuthServer struct. +func NewAuthServer(sessionService SessionServiceI, userService UserServiceI, gRPCServer *grpc.Server, logger *zap.Logger) *AuthServer { + return &AuthServer{ + sessionService: sessionService, + userService: userService, + gRPCServer: gRPCServer, + logger: logger, + } +} + +// Start starts the AuthServer and listens on port :8090. +// +// It creates a listener on the specified address and starts serving incoming requests. +// It also logs the server start and any errors that occur during serving. +// +// No parameters. +// No return values. +func (s *AuthServer) Start() { + lis, err := net.Listen("tcp", ":8090") + if err != nil { + s.logger.Fatal("") + } + + sessionv1.RegisterSessionServiceServer(s.gRPCServer, s) + go func() { + s.logger.Info("Listening on :8090") + if err := s.gRPCServer.Serve(lis); err != nil { + panic(err.Error()) + } + }() + s.logger.Info("server started") +} + +// GracefullyStop stops the server gracefully. +// +// No parameters. +// No return values. +func (s *AuthServer) GracefullyStop() { + s.gRPCServer.GracefulStop() + s.logger.Info("server stopped") +} + +func AsTimeP(t *timestamppb.Timestamp) *time.Time { + if t == nil { + return nil + } + tt := t.AsTime() + return &tt +} + +func AsInt32P(v *userv1.Role) *int32 { + if v == nil { + return nil + } + vv := int32(v.Number()) + return &vv +} + +func AsTimestampP(t *time.Time) *timestamppb.Timestamp { + if t == nil { + return nil + } + return timestamppb.New(*t) +} + +func AsRoleP(r *int32) *userv1.Role { + if r == nil { + return nil + } + rr := userv1.Role(*r) + return &rr +} diff --git a/internal/transport/session_server.go b/internal/transport/session_server.go new file mode 100644 index 0000000..4cc2560 --- /dev/null +++ b/internal/transport/session_server.go @@ -0,0 +1,45 @@ +package transport + +import ( + "context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" + sessionv1 "ms-auth/pkg/go/gen/session/v1" +) + +func (s *AuthServer) Create(ctx context.Context, req *sessionv1.CreateSessionRequest) (*sessionv1.CreateSessionResponse, error) { + token, err := s.sessionService.Create(ctx, req.GetHandle(), req.GetPassword()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &sessionv1.CreateSessionResponse{ + Token: *token, + }, nil +} + +func (s *AuthServer) Read(ctx context.Context, req *sessionv1.ReadSessionRequest) (*sessionv1.ReadSessionResponse, error) { + id, err := s.sessionService.Read(ctx, req.GetToken()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &sessionv1.ReadSessionResponse{ + UserId: *id, + }, nil +} + +func (s *AuthServer) Update(ctx context.Context, req *sessionv1.UpdateSessionRequest) (*emptypb.Empty, error) { + err := s.sessionService.Update(ctx, req.GetToken()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &emptypb.Empty{}, nil +} + +func (s *AuthServer) Delete(ctx context.Context, req *sessionv1.DeleteSessionRequest) (*emptypb.Empty, error) { + err := s.sessionService.Delete(ctx, req.GetToken()) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &emptypb.Empty{}, nil +} diff --git a/internal/transport/user_server.go b/internal/transport/user_server.go new file mode 100644 index 0000000..8d39245 --- /dev/null +++ b/internal/transport/user_server.go @@ -0,0 +1,124 @@ +package transport + +import ( + "context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" + userv1 "ms-auth/pkg/go/gen/user/v1" + "strings" +) + +func (s *AuthServer) CreateUser(ctx context.Context, req *userv1.CreateUserRequest) (*userv1.CreateUserResponse, error) { + user := req.GetUser() + if user == nil { + return nil, status.Errorf(codes.Unknown, "") // FIXME + } + id, err := s.userService.CreateUser( + ctx, + req.GetToken(), + user.GetUsername(), + user.GetPassword(), + user.Email, + AsTimeP(user.ExpiresAt), + AsInt32P(user.Role), + ) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + + return &userv1.CreateUserResponse{ + Id: *id, + }, nil +} + +func (s *AuthServer) ReadUser(ctx context.Context, req *userv1.ReadUserRequest) (*userv1.ReadUserResponse, error) { + user, err := s.userService.ReadUser( + ctx, + req.GetToken(), + req.GetId(), + ) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + + return &userv1.ReadUserResponse{ + User: &userv1.ReadUserResponse_User{ + Id: user.Id, + Username: user.Username, + Email: user.Email, + ExpiresAt: AsTimestampP(&user.ExpiresAt), + CreatedAt: AsTimestampP(&user.CreatedAt), + Role: *AsRoleP(&user.Role), + }, + }, nil +} + +func (s *AuthServer) UpdateUser(ctx context.Context, req *userv1.UpdateUserRequest) (*emptypb.Empty, error) { + user := req.GetUser() + if user == nil { + return nil, status.Errorf(codes.Unknown, "") // FIXME + } + err := s.userService.UpdateUser( + ctx, + req.GetToken(), + user.GetId(), + user.Username, + user.Password, + user.Email, + AsTimeP(user.ExpiresAt), + AsInt32P(user.Role), + ) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &emptypb.Empty{}, nil +} + +func (s *AuthServer) DeleteUser(ctx context.Context, req *userv1.DeleteUserRequest) (*emptypb.Empty, error) { + err := s.userService.DeleteUser( + ctx, + req.GetToken(), + req.GetId(), + ) + if err != nil { + return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME + } + return &emptypb.Empty{}, nil +} + +func (s *AuthServer) ConfirmEmail(ctx context.Context, req *userv1.ConfirmEmailRequest) (*emptypb.Empty, error) { + panic("not implemented") +} + +func (s *AuthServer) RegisterUser(ctx context.Context, req *userv1.RegisterUserRequest) (*emptypb.Empty, error) { + panic("not implemented") +} + +func (s *AuthServer) ConfirmRegisterUser(ctx context.Context, req *userv1.ConfirmRegisterUserRequest) (*emptypb.Empty, error) { + panic("not implemented") +} + +func (s *AuthServer) ResetPassword(ctx context.Context, req *userv1.ResetPasswordRequest) (*emptypb.Empty, error) { + panic("not implemented") +} + +func (s *AuthServer) ConfirmResetPassword(ctx context.Context, req *userv1.ConfirmResetPasswordRequest) (*emptypb.Empty, error) { + panic("not implemented") +} + +func shortenEmail(email *string) *string { + if email == nil { + return nil + } + parts := strings.Split(*email, "@") + p1 := parts[0] + p2 := parts[1] + a := "****" + if len(p1) <= 4 { + e := a + "@" + p2 + return &e + } + e := p1[:len(p1)-4] + a + "@" + p2 + return &e +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..22a5e79 --- /dev/null +++ b/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "go.uber.org/zap" + "google.golang.org/grpc" + "ms-auth/internal/app" + "ms-auth/internal/lib" + "ms-auth/internal/services" + "ms-auth/internal/storage" + "ms-auth/internal/transport" + "os" + "os/signal" + "syscall" +) + +func main() { + cfg := lib.MustSetupConfig() + + var logger *zap.Logger + if cfg.Env == "prod" { + logger = zap.Must(zap.NewProduction()) + } else if cfg.Env == "dev" { + logger = zap.Must(zap.NewDevelopment()) + } else { + panic(fmt.Sprintf(`error reading config: env expected "prod" or "dev", got "%s"`, cfg.Env)) + } + + postgres := storage.NewUserStorage(cfg.PostgresDSN, logger) + + vk := storage.NewValkeyStorage(cfg.RedisDSN, cfg, logger) + + sessionService := services.NewSessionService(vk, postgres, cfg) + userService := services.NewUserService(postgres, vk, vk, cfg) + + server := transport.NewAuthServer(sessionService, userService, grpc.NewServer(), logger) + + application := app.NewApp(cfg, server) + + application.Start() + + stop := make(chan os.Signal, 1) + signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT) + + <-stop + application.GracefullyStop() +} diff --git a/migrations/20240608163806_initial.sql b/migrations/20240608163806_initial.sql new file mode 100644 index 0000000..08fc7e1 --- /dev/null +++ b/migrations/20240608163806_initial.sql @@ -0,0 +1,20 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS users ( + id serial NOT NULL, + username VARCHAR(70) UNIQUE NOT NULL CHECK (length(username) != 0 AND username = lower(username)), + hashed_password BYTEA NOT NULL CHECK (length(hashed_password) != 0), + email VARCHAR(70) UNIQUE CHECK (length(email) != 0 AND email = lower(email)), + expires_at TIMESTAMP NOT NULL, + created_at TIMESTAMP NOT NULL, + role INT NOT NULL CHECK (role BETWEEN 0 AND 3), + PRIMARY KEY (id) +); + +CREATE INDEX ON users (id); + +CREATE INDEX ON users (username); + +CREATE INDEX ON users (email); + +-- +goose Down +DROP TABLE IF EXISTS users; \ No newline at end of file diff --git a/pkg/go/gen/email/v1/email.pb.go b/pkg/go/gen/email/v1/email.pb.go new file mode 100644 index 0000000..84d7c0e --- /dev/null +++ b/pkg/go/gen/email/v1/email.pb.go @@ -0,0 +1,192 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: email/v1/email.proto + +package emailv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + 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) +) + +type SendEmailRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + UserIds []int32 `protobuf:"varint,2,rep,packed,name=user_ids,json=userIds,proto3" json:"user_ids,omitempty"` + Subject string `protobuf:"bytes,3,opt,name=subject,proto3" json:"subject,omitempty"` + Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *SendEmailRequest) Reset() { + *x = SendEmailRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_email_v1_email_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendEmailRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendEmailRequest) ProtoMessage() {} + +func (x *SendEmailRequest) ProtoReflect() protoreflect.Message { + mi := &file_email_v1_email_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 SendEmailRequest.ProtoReflect.Descriptor instead. +func (*SendEmailRequest) Descriptor() ([]byte, []int) { + return file_email_v1_email_proto_rawDescGZIP(), []int{0} +} + +func (x *SendEmailRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *SendEmailRequest) GetUserIds() []int32 { + if x != nil { + return x.UserIds + } + return nil +} + +func (x *SendEmailRequest) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *SendEmailRequest) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +var File_email_v1_email_proto protoreflect.FileDescriptor + +var file_email_v1_email_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x71, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, + 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x32, 0x55, 0x0a, 0x0c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x9f, 0x01, + 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x23, 0x6d, 0x73, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, + 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x2f, 0x76, 0x31, 0x3b, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x45, 0x58, 0xaa, 0x02, 0x0e, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x0e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x1a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x10, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_email_v1_email_proto_rawDescOnce sync.Once + file_email_v1_email_proto_rawDescData = file_email_v1_email_proto_rawDesc +) + +func file_email_v1_email_proto_rawDescGZIP() []byte { + file_email_v1_email_proto_rawDescOnce.Do(func() { + file_email_v1_email_proto_rawDescData = protoimpl.X.CompressGZIP(file_email_v1_email_proto_rawDescData) + }) + return file_email_v1_email_proto_rawDescData +} + +var file_email_v1_email_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_email_v1_email_proto_goTypes = []interface{}{ + (*SendEmailRequest)(nil), // 0: proto.email.v1.SendEmailRequest + (*emptypb.Empty)(nil), // 1: google.protobuf.Empty +} +var file_email_v1_email_proto_depIdxs = []int32{ + 0, // 0: proto.email.v1.EmailService.SendEmail:input_type -> proto.email.v1.SendEmailRequest + 1, // 1: proto.email.v1.EmailService.SendEmail:output_type -> google.protobuf.Empty + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_email_v1_email_proto_init() } +func file_email_v1_email_proto_init() { + if File_email_v1_email_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_email_v1_email_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendEmailRequest); 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_email_v1_email_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_email_v1_email_proto_goTypes, + DependencyIndexes: file_email_v1_email_proto_depIdxs, + MessageInfos: file_email_v1_email_proto_msgTypes, + }.Build() + File_email_v1_email_proto = out.File + file_email_v1_email_proto_rawDesc = nil + file_email_v1_email_proto_goTypes = nil + file_email_v1_email_proto_depIdxs = nil +} diff --git a/pkg/go/gen/email/v1/email_grpc.pb.go b/pkg/go/gen/email/v1/email_grpc.pb.go new file mode 100644 index 0000000..c70a645 --- /dev/null +++ b/pkg/go/gen/email/v1/email_grpc.pb.go @@ -0,0 +1,106 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: email/v1/email.proto + +package emailv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// EmailServiceClient is the client API for EmailService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type EmailServiceClient interface { + SendEmail(ctx context.Context, in *SendEmailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type emailServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewEmailServiceClient(cc grpc.ClientConnInterface) EmailServiceClient { + return &emailServiceClient{cc} +} + +func (c *emailServiceClient) SendEmail(ctx context.Context, in *SendEmailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.email.v1.EmailService/SendEmail", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// EmailServiceServer is the server API for EmailService service. +// All implementations must embed UnimplementedEmailServiceServer +// for forward compatibility +type EmailServiceServer interface { + SendEmail(context.Context, *SendEmailRequest) (*emptypb.Empty, error) + mustEmbedUnimplementedEmailServiceServer() +} + +// UnimplementedEmailServiceServer must be embedded to have forward compatible implementations. +type UnimplementedEmailServiceServer struct { +} + +func (UnimplementedEmailServiceServer) SendEmail(context.Context, *SendEmailRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendEmail not implemented") +} +func (UnimplementedEmailServiceServer) mustEmbedUnimplementedEmailServiceServer() {} + +// UnsafeEmailServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to EmailServiceServer will +// result in compilation errors. +type UnsafeEmailServiceServer interface { + mustEmbedUnimplementedEmailServiceServer() +} + +func RegisterEmailServiceServer(s grpc.ServiceRegistrar, srv EmailServiceServer) { + s.RegisterService(&EmailService_ServiceDesc, srv) +} + +func _EmailService_SendEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendEmailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(EmailServiceServer).SendEmail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.email.v1.EmailService/SendEmail", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(EmailServiceServer).SendEmail(ctx, req.(*SendEmailRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// EmailService_ServiceDesc is the grpc.ServiceDesc for EmailService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var EmailService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.email.v1.EmailService", + HandlerType: (*EmailServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendEmail", + Handler: _EmailService_SendEmail_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "email/v1/email.proto", +} diff --git a/pkg/go/gen/session/v1/session.pb.go b/pkg/go/gen/session/v1/session.pb.go new file mode 100644 index 0000000..c096b51 --- /dev/null +++ b/pkg/go/gen/session/v1/session.pb.go @@ -0,0 +1,511 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: session/v1/session.proto + +package sessionv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + 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) +) + +type CreateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Handle string `protobuf:"bytes,1,opt,name=handle,proto3" json:"handle,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *CreateSessionRequest) Reset() { + *x = CreateSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSessionRequest) ProtoMessage() {} + +func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 CreateSessionRequest.ProtoReflect.Descriptor instead. +func (*CreateSessionRequest) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateSessionRequest) GetHandle() string { + if x != nil { + return x.Handle + } + return "" +} + +func (x *CreateSessionRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type CreateSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *CreateSessionResponse) Reset() { + *x = CreateSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSessionResponse) ProtoMessage() {} + +func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 CreateSessionResponse.ProtoReflect.Descriptor instead. +func (*CreateSessionResponse) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateSessionResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ReadSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *ReadSessionRequest) Reset() { + *x = ReadSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadSessionRequest) ProtoMessage() {} + +func (x *ReadSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 ReadSessionRequest.ProtoReflect.Descriptor instead. +func (*ReadSessionRequest) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{2} +} + +func (x *ReadSessionRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ReadSessionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId int32 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *ReadSessionResponse) Reset() { + *x = ReadSessionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadSessionResponse) ProtoMessage() {} + +func (x *ReadSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 ReadSessionResponse.ProtoReflect.Descriptor instead. +func (*ReadSessionResponse) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{3} +} + +func (x *ReadSessionResponse) GetUserId() int32 { + if x != nil { + return x.UserId + } + return 0 +} + +type UpdateSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *UpdateSessionRequest) Reset() { + *x = UpdateSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionRequest) ProtoMessage() {} + +func (x *UpdateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 UpdateSessionRequest.ProtoReflect.Descriptor instead. +func (*UpdateSessionRequest) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateSessionRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type DeleteSessionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *DeleteSessionRequest) Reset() { + *x = DeleteSessionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_session_v1_session_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteSessionRequest) ProtoMessage() {} + +func (x *DeleteSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_session_v1_session_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 DeleteSessionRequest.ProtoReflect.Descriptor instead. +func (*DeleteSessionRequest) Descriptor() ([]byte, []int) { + return file_session_v1_session_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteSessionRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +var File_session_v1_session_proto protoreflect.FileDescriptor + +var file_session_v1_session_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4a, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x2d, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x2a, 0x0a, 0x12, 0x52, 0x65, 0x61, 0x64, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x2e, 0x0a, 0x13, 0x52, 0x65, 0x61, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, + 0x22, 0x2c, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x2c, + 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xd4, 0x02, 0x0a, + 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x59, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x04, 0x52, 0x65, + 0x61, 0x64, 0x12, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x48, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x06, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x42, 0xaf, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x6d, 0x73, + 0x2d, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50, 0x53, 0x58, 0xaa, 0x02, 0x10, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x10, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x1c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x12, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_session_v1_session_proto_rawDescOnce sync.Once + file_session_v1_session_proto_rawDescData = file_session_v1_session_proto_rawDesc +) + +func file_session_v1_session_proto_rawDescGZIP() []byte { + file_session_v1_session_proto_rawDescOnce.Do(func() { + file_session_v1_session_proto_rawDescData = protoimpl.X.CompressGZIP(file_session_v1_session_proto_rawDescData) + }) + return file_session_v1_session_proto_rawDescData +} + +var file_session_v1_session_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_session_v1_session_proto_goTypes = []interface{}{ + (*CreateSessionRequest)(nil), // 0: proto.session.v1.CreateSessionRequest + (*CreateSessionResponse)(nil), // 1: proto.session.v1.CreateSessionResponse + (*ReadSessionRequest)(nil), // 2: proto.session.v1.ReadSessionRequest + (*ReadSessionResponse)(nil), // 3: proto.session.v1.ReadSessionResponse + (*UpdateSessionRequest)(nil), // 4: proto.session.v1.UpdateSessionRequest + (*DeleteSessionRequest)(nil), // 5: proto.session.v1.DeleteSessionRequest + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty +} +var file_session_v1_session_proto_depIdxs = []int32{ + 0, // 0: proto.session.v1.SessionService.Create:input_type -> proto.session.v1.CreateSessionRequest + 2, // 1: proto.session.v1.SessionService.Read:input_type -> proto.session.v1.ReadSessionRequest + 4, // 2: proto.session.v1.SessionService.Update:input_type -> proto.session.v1.UpdateSessionRequest + 5, // 3: proto.session.v1.SessionService.Delete:input_type -> proto.session.v1.DeleteSessionRequest + 1, // 4: proto.session.v1.SessionService.Create:output_type -> proto.session.v1.CreateSessionResponse + 3, // 5: proto.session.v1.SessionService.Read:output_type -> proto.session.v1.ReadSessionResponse + 6, // 6: proto.session.v1.SessionService.Update:output_type -> google.protobuf.Empty + 6, // 7: proto.session.v1.SessionService.Delete:output_type -> google.protobuf.Empty + 4, // [4:8] is the sub-list for method output_type + 0, // [0:4] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_session_v1_session_proto_init() } +func file_session_v1_session_proto_init() { + if File_session_v1_session_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_session_v1_session_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_v1_session_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_v1_session_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_v1_session_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadSessionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_v1_session_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSessionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_session_v1_session_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteSessionRequest); 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_session_v1_session_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_session_v1_session_proto_goTypes, + DependencyIndexes: file_session_v1_session_proto_depIdxs, + MessageInfos: file_session_v1_session_proto_msgTypes, + }.Build() + File_session_v1_session_proto = out.File + file_session_v1_session_proto_rawDesc = nil + file_session_v1_session_proto_goTypes = nil + file_session_v1_session_proto_depIdxs = nil +} diff --git a/pkg/go/gen/session/v1/session_grpc.pb.go b/pkg/go/gen/session/v1/session_grpc.pb.go new file mode 100644 index 0000000..f58193a --- /dev/null +++ b/pkg/go/gen/session/v1/session_grpc.pb.go @@ -0,0 +1,214 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: session/v1/session.proto + +package sessionv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// SessionServiceClient is the client API for SessionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type SessionServiceClient interface { + Create(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) + Read(ctx context.Context, in *ReadSessionRequest, opts ...grpc.CallOption) (*ReadSessionResponse, error) + Update(ctx context.Context, in *UpdateSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + Delete(ctx context.Context, in *DeleteSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type sessionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewSessionServiceClient(cc grpc.ClientConnInterface) SessionServiceClient { + return &sessionServiceClient{cc} +} + +func (c *sessionServiceClient) Create(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) { + out := new(CreateSessionResponse) + err := c.cc.Invoke(ctx, "/proto.session.v1.SessionService/Create", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) Read(ctx context.Context, in *ReadSessionRequest, opts ...grpc.CallOption) (*ReadSessionResponse, error) { + out := new(ReadSessionResponse) + err := c.cc.Invoke(ctx, "/proto.session.v1.SessionService/Read", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) Update(ctx context.Context, in *UpdateSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.session.v1.SessionService/Update", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *sessionServiceClient) Delete(ctx context.Context, in *DeleteSessionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.session.v1.SessionService/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// SessionServiceServer is the server API for SessionService service. +// All implementations must embed UnimplementedSessionServiceServer +// for forward compatibility +type SessionServiceServer interface { + Create(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) + Read(context.Context, *ReadSessionRequest) (*ReadSessionResponse, error) + Update(context.Context, *UpdateSessionRequest) (*emptypb.Empty, error) + Delete(context.Context, *DeleteSessionRequest) (*emptypb.Empty, error) + mustEmbedUnimplementedSessionServiceServer() +} + +// UnimplementedSessionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedSessionServiceServer struct { +} + +func (UnimplementedSessionServiceServer) Create(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") +} +func (UnimplementedSessionServiceServer) Read(context.Context, *ReadSessionRequest) (*ReadSessionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Read not implemented") +} +func (UnimplementedSessionServiceServer) Update(context.Context, *UpdateSessionRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") +} +func (UnimplementedSessionServiceServer) Delete(context.Context, *DeleteSessionRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedSessionServiceServer) mustEmbedUnimplementedSessionServiceServer() {} + +// UnsafeSessionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to SessionServiceServer will +// result in compilation errors. +type UnsafeSessionServiceServer interface { + mustEmbedUnimplementedSessionServiceServer() +} + +func RegisterSessionServiceServer(s grpc.ServiceRegistrar, srv SessionServiceServer) { + s.RegisterService(&SessionService_ServiceDesc, srv) +} + +func _SessionService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.session.v1.SessionService/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).Create(ctx, req.(*CreateSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).Read(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.session.v1.SessionService/Read", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).Read(ctx, req.(*ReadSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.session.v1.SessionService/Update", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).Update(ctx, req.(*UpdateSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SessionService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteSessionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SessionServiceServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.session.v1.SessionService/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SessionServiceServer).Delete(ctx, req.(*DeleteSessionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// SessionService_ServiceDesc is the grpc.ServiceDesc for SessionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SessionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.session.v1.SessionService", + HandlerType: (*SessionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Create", + Handler: _SessionService_Create_Handler, + }, + { + MethodName: "Read", + Handler: _SessionService_Read_Handler, + }, + { + MethodName: "Update", + Handler: _SessionService_Update_Handler, + }, + { + MethodName: "Delete", + Handler: _SessionService_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "session/v1/session.proto", +} diff --git a/pkg/go/gen/user/v1/user.pb.go b/pkg/go/gen/user/v1/user.pb.go new file mode 100644 index 0000000..5f6686a --- /dev/null +++ b/pkg/go/gen/user/v1/user.pb.go @@ -0,0 +1,1350 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: user/v1/user.proto + +package userv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + 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) +) + +type Role int32 + +const ( + Role_ROLE_SPECTATOR_UNSPECIFIED Role = 0 + Role_ROLE_PARTICIPANT Role = 1 + Role_ROLE_MODERATOR Role = 2 + Role_ROLE_ADMIN Role = 3 +) + +// Enum value maps for Role. +var ( + Role_name = map[int32]string{ + 0: "ROLE_SPECTATOR_UNSPECIFIED", + 1: "ROLE_PARTICIPANT", + 2: "ROLE_MODERATOR", + 3: "ROLE_ADMIN", + } + Role_value = map[string]int32{ + "ROLE_SPECTATOR_UNSPECIFIED": 0, + "ROLE_PARTICIPANT": 1, + "ROLE_MODERATOR": 2, + "ROLE_ADMIN": 3, + } +) + +func (x Role) Enum() *Role { + p := new(Role) + *p = x + return p +} + +func (x Role) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Role) Descriptor() protoreflect.EnumDescriptor { + return file_user_v1_user_proto_enumTypes[0].Descriptor() +} + +func (Role) Type() protoreflect.EnumType { + return &file_user_v1_user_proto_enumTypes[0] +} + +func (x Role) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Role.Descriptor instead. +func (Role) EnumDescriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{0} +} + +type CreateUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + User *CreateUserRequest_User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *CreateUserRequest) Reset() { + *x = CreateUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserRequest) ProtoMessage() {} + +func (x *CreateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 CreateUserRequest.ProtoReflect.Descriptor instead. +func (*CreateUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateUserRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *CreateUserRequest) GetUser() *CreateUserRequest_User { + if x != nil { + return x.User + } + return nil +} + +type CreateUserResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *CreateUserResponse) Reset() { + *x = CreateUserResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserResponse) ProtoMessage() {} + +func (x *CreateUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 CreateUserResponse.ProtoReflect.Descriptor instead. +func (*CreateUserResponse) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateUserResponse) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ReadUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ReadUserRequest) Reset() { + *x = ReadUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadUserRequest) ProtoMessage() {} + +func (x *ReadUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 ReadUserRequest.ProtoReflect.Descriptor instead. +func (*ReadUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{2} +} + +func (x *ReadUserRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ReadUserRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ReadUserResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *ReadUserResponse_User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *ReadUserResponse) Reset() { + *x = ReadUserResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadUserResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadUserResponse) ProtoMessage() {} + +func (x *ReadUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 ReadUserResponse.ProtoReflect.Descriptor instead. +func (*ReadUserResponse) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{3} +} + +func (x *ReadUserResponse) GetUser() *ReadUserResponse_User { + if x != nil { + return x.User + } + return nil +} + +type UpdateUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + User *UpdateUserRequest_User `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *UpdateUserRequest) Reset() { + *x = UpdateUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserRequest) ProtoMessage() {} + +func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 UpdateUserRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{4} +} + +func (x *UpdateUserRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *UpdateUserRequest) GetUser() *UpdateUserRequest_User { + if x != nil { + return x.User + } + return nil +} + +type DeleteUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteUserRequest) Reset() { + *x = DeleteUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserRequest) ProtoMessage() {} + +func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 DeleteUserRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{5} +} + +func (x *DeleteUserRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *DeleteUserRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ConfirmEmailRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConfToken string `protobuf:"bytes,1,opt,name=conf_token,json=confToken,proto3" json:"conf_token,omitempty"` +} + +func (x *ConfirmEmailRequest) Reset() { + *x = ConfirmEmailRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmEmailRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmEmailRequest) ProtoMessage() {} + +func (x *ConfirmEmailRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 ConfirmEmailRequest.ProtoReflect.Descriptor instead. +func (*ConfirmEmailRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{6} +} + +func (x *ConfirmEmailRequest) GetConfToken() string { + if x != nil { + return x.ConfToken + } + return "" +} + +type RegisterUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` +} + +func (x *RegisterUserRequest) Reset() { + *x = RegisterUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RegisterUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterUserRequest) ProtoMessage() {} + +func (x *RegisterUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 RegisterUserRequest.ProtoReflect.Descriptor instead. +func (*RegisterUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{7} +} + +func (x *RegisterUserRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +type ConfirmRegisterUserRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConfToken string `protobuf:"bytes,1,opt,name=conf_token,json=confToken,proto3" json:"conf_token,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *ConfirmRegisterUserRequest) Reset() { + *x = ConfirmRegisterUserRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmRegisterUserRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmRegisterUserRequest) ProtoMessage() {} + +func (x *ConfirmRegisterUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_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 ConfirmRegisterUserRequest.ProtoReflect.Descriptor instead. +func (*ConfirmRegisterUserRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{8} +} + +func (x *ConfirmRegisterUserRequest) GetConfToken() string { + if x != nil { + return x.ConfToken + } + return "" +} + +func (x *ConfirmRegisterUserRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *ConfirmRegisterUserRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type ResetPasswordRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` +} + +func (x *ResetPasswordRequest) Reset() { + *x = ResetPasswordRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResetPasswordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetPasswordRequest) ProtoMessage() {} + +func (x *ResetPasswordRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[9] + 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 ResetPasswordRequest.ProtoReflect.Descriptor instead. +func (*ResetPasswordRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{9} +} + +func (x *ResetPasswordRequest) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +type ConfirmResetPasswordRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConfToken string `protobuf:"bytes,1,opt,name=conf_token,json=confToken,proto3" json:"conf_token,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *ConfirmResetPasswordRequest) Reset() { + *x = ConfirmResetPasswordRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfirmResetPasswordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfirmResetPasswordRequest) ProtoMessage() {} + +func (x *ConfirmResetPasswordRequest) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[10] + 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 ConfirmResetPasswordRequest.ProtoReflect.Descriptor instead. +func (*ConfirmResetPasswordRequest) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{10} +} + +func (x *ConfirmResetPasswordRequest) GetConfToken() string { + if x != nil { + return x.ConfToken + } + return "" +} + +func (x *ConfirmResetPasswordRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type CreateUserRequest_User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + Role *Role `protobuf:"varint,5,opt,name=role,proto3,enum=proto.user.v1.Role,oneof" json:"role,omitempty"` +} + +func (x *CreateUserRequest_User) Reset() { + *x = CreateUserRequest_User{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserRequest_User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserRequest_User) ProtoMessage() {} + +func (x *CreateUserRequest_User) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[11] + 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 CreateUserRequest_User.ProtoReflect.Descriptor instead. +func (*CreateUserRequest_User) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *CreateUserRequest_User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *CreateUserRequest_User) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *CreateUserRequest_User) GetEmail() string { + if x != nil && x.Email != nil { + return *x.Email + } + return "" +} + +func (x *CreateUserRequest_User) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *CreateUserRequest_User) GetRole() Role { + if x != nil && x.Role != nil { + return *x.Role + } + return Role_ROLE_SPECTATOR_UNSPECIFIED +} + +type ReadUserResponse_User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"` + Password string `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Role Role `protobuf:"varint,7,opt,name=role,proto3,enum=proto.user.v1.Role" json:"role,omitempty"` +} + +func (x *ReadUserResponse_User) Reset() { + *x = ReadUserResponse_User{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadUserResponse_User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadUserResponse_User) ProtoMessage() {} + +func (x *ReadUserResponse_User) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[12] + 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 ReadUserResponse_User.ProtoReflect.Descriptor instead. +func (*ReadUserResponse_User) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *ReadUserResponse_User) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *ReadUserResponse_User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *ReadUserResponse_User) GetEmail() string { + if x != nil && x.Email != nil { + return *x.Email + } + return "" +} + +func (x *ReadUserResponse_User) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *ReadUserResponse_User) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *ReadUserResponse_User) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ReadUserResponse_User) GetRole() Role { + if x != nil { + return x.Role + } + return Role_ROLE_SPECTATOR_UNSPECIFIED +} + +type UpdateUserRequest_User struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Username *string `protobuf:"bytes,2,opt,name=username,proto3,oneof" json:"username,omitempty"` + Email *string `protobuf:"bytes,3,opt,name=email,proto3,oneof" json:"email,omitempty"` + Password *string `protobuf:"bytes,4,opt,name=password,proto3,oneof" json:"password,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` + Role *Role `protobuf:"varint,6,opt,name=role,proto3,enum=proto.user.v1.Role,oneof" json:"role,omitempty"` +} + +func (x *UpdateUserRequest_User) Reset() { + *x = UpdateUserRequest_User{} + if protoimpl.UnsafeEnabled { + mi := &file_user_v1_user_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserRequest_User) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserRequest_User) ProtoMessage() {} + +func (x *UpdateUserRequest_User) ProtoReflect() protoreflect.Message { + mi := &file_user_v1_user_proto_msgTypes[13] + 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 UpdateUserRequest_User.ProtoReflect.Descriptor instead. +func (*UpdateUserRequest_User) Descriptor() ([]byte, []int) { + return file_user_v1_user_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *UpdateUserRequest_User) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UpdateUserRequest_User) GetUsername() string { + if x != nil && x.Username != nil { + return *x.Username + } + return "" +} + +func (x *UpdateUserRequest_User) GetEmail() string { + if x != nil && x.Email != nil { + return *x.Email + } + return "" +} + +func (x *UpdateUserRequest_User) GetPassword() string { + if x != nil && x.Password != nil { + return *x.Password + } + return "" +} + +func (x *UpdateUserRequest_User) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *UpdateUserRequest_User) GetRole() Role { + if x != nil && x.Role != nil { + return *x.Role + } + return Role_ROLE_SPECTATOR_UNSPECIFIED +} + +var File_user_v1_user_proto protoreflect.FileDescriptor + +var file_user_v1_user_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0xd0, 0x02, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x39, 0x0a, + 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x1a, 0xe9, 0x01, 0x0a, 0x04, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x48, 0x02, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x88, + 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x0d, 0x0a, 0x0b, + 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, + 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x24, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x37, 0x0a, 0x0f, 0x52, 0x65, + 0x61, 0x64, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x02, 0x69, 0x64, 0x22, 0xe1, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x61, 0x64, 0x55, 0x73, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, + 0x65, 0x72, 0x1a, 0x92, 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, + 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x88, + 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x39, + 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x42, 0x08, 0x0a, + 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x84, 0x03, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x39, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x1a, 0x9d, + 0x02, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x48, 0x03, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x48, 0x04, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x88, + 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42, + 0x08, 0x0a, 0x06, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x73, 0x5f, 0x61, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x39, + 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x34, 0x0a, 0x13, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0x2b, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x73, 0x0a, 0x1a, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x66, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x22, 0x2c, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, + 0x58, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, + 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2a, 0x60, 0x0a, 0x04, 0x52, 0x6f, 0x6c, + 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x53, 0x50, 0x45, 0x43, 0x54, 0x41, + 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, + 0x49, 0x50, 0x41, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x4f, 0x4c, 0x45, 0x5f, + 0x4d, 0x4f, 0x44, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, + 0x4f, 0x4c, 0x45, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x03, 0x32, 0xd9, 0x05, 0x0a, 0x0b, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x0a, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, + 0x0a, 0x08, 0x52, 0x65, 0x61, 0x64, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0a, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x22, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4a, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x58, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x12, 0x29, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, + 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x23, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x5a, 0x0a, 0x14, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x12, 0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x97, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x55, + 0x73, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x21, 0x6d, 0x73, 0x2d, 0x61, + 0x75, 0x74, 0x68, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x75, + 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, + 0x50, 0x55, 0x58, 0xaa, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x55, 0x73, 0x65, 0x72, + 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5c, 0x55, 0x73, 0x65, 0x72, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x3a, 0x55, 0x73, 0x65, 0x72, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_user_v1_user_proto_rawDescOnce sync.Once + file_user_v1_user_proto_rawDescData = file_user_v1_user_proto_rawDesc +) + +func file_user_v1_user_proto_rawDescGZIP() []byte { + file_user_v1_user_proto_rawDescOnce.Do(func() { + file_user_v1_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_v1_user_proto_rawDescData) + }) + return file_user_v1_user_proto_rawDescData +} + +var file_user_v1_user_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_user_v1_user_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_user_v1_user_proto_goTypes = []interface{}{ + (Role)(0), // 0: proto.user.v1.Role + (*CreateUserRequest)(nil), // 1: proto.user.v1.CreateUserRequest + (*CreateUserResponse)(nil), // 2: proto.user.v1.CreateUserResponse + (*ReadUserRequest)(nil), // 3: proto.user.v1.ReadUserRequest + (*ReadUserResponse)(nil), // 4: proto.user.v1.ReadUserResponse + (*UpdateUserRequest)(nil), // 5: proto.user.v1.UpdateUserRequest + (*DeleteUserRequest)(nil), // 6: proto.user.v1.DeleteUserRequest + (*ConfirmEmailRequest)(nil), // 7: proto.user.v1.ConfirmEmailRequest + (*RegisterUserRequest)(nil), // 8: proto.user.v1.RegisterUserRequest + (*ConfirmRegisterUserRequest)(nil), // 9: proto.user.v1.ConfirmRegisterUserRequest + (*ResetPasswordRequest)(nil), // 10: proto.user.v1.ResetPasswordRequest + (*ConfirmResetPasswordRequest)(nil), // 11: proto.user.v1.ConfirmResetPasswordRequest + (*CreateUserRequest_User)(nil), // 12: proto.user.v1.CreateUserRequest.User + (*ReadUserResponse_User)(nil), // 13: proto.user.v1.ReadUserResponse.User + (*UpdateUserRequest_User)(nil), // 14: proto.user.v1.UpdateUserRequest.User + (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp + (*emptypb.Empty)(nil), // 16: google.protobuf.Empty +} +var file_user_v1_user_proto_depIdxs = []int32{ + 12, // 0: proto.user.v1.CreateUserRequest.user:type_name -> proto.user.v1.CreateUserRequest.User + 13, // 1: proto.user.v1.ReadUserResponse.user:type_name -> proto.user.v1.ReadUserResponse.User + 14, // 2: proto.user.v1.UpdateUserRequest.user:type_name -> proto.user.v1.UpdateUserRequest.User + 15, // 3: proto.user.v1.CreateUserRequest.User.expires_at:type_name -> google.protobuf.Timestamp + 0, // 4: proto.user.v1.CreateUserRequest.User.role:type_name -> proto.user.v1.Role + 15, // 5: proto.user.v1.ReadUserResponse.User.expires_at:type_name -> google.protobuf.Timestamp + 15, // 6: proto.user.v1.ReadUserResponse.User.created_at:type_name -> google.protobuf.Timestamp + 0, // 7: proto.user.v1.ReadUserResponse.User.role:type_name -> proto.user.v1.Role + 15, // 8: proto.user.v1.UpdateUserRequest.User.expires_at:type_name -> google.protobuf.Timestamp + 0, // 9: proto.user.v1.UpdateUserRequest.User.role:type_name -> proto.user.v1.Role + 1, // 10: proto.user.v1.UserService.CreateUser:input_type -> proto.user.v1.CreateUserRequest + 3, // 11: proto.user.v1.UserService.ReadUser:input_type -> proto.user.v1.ReadUserRequest + 5, // 12: proto.user.v1.UserService.UpdateUser:input_type -> proto.user.v1.UpdateUserRequest + 6, // 13: proto.user.v1.UserService.DeleteUser:input_type -> proto.user.v1.DeleteUserRequest + 7, // 14: proto.user.v1.UserService.ConfirmEmail:input_type -> proto.user.v1.ConfirmEmailRequest + 8, // 15: proto.user.v1.UserService.RegisterUser:input_type -> proto.user.v1.RegisterUserRequest + 9, // 16: proto.user.v1.UserService.ConfirmRegisterUser:input_type -> proto.user.v1.ConfirmRegisterUserRequest + 10, // 17: proto.user.v1.UserService.ResetPassword:input_type -> proto.user.v1.ResetPasswordRequest + 11, // 18: proto.user.v1.UserService.ConfirmResetPassword:input_type -> proto.user.v1.ConfirmResetPasswordRequest + 2, // 19: proto.user.v1.UserService.CreateUser:output_type -> proto.user.v1.CreateUserResponse + 4, // 20: proto.user.v1.UserService.ReadUser:output_type -> proto.user.v1.ReadUserResponse + 16, // 21: proto.user.v1.UserService.UpdateUser:output_type -> google.protobuf.Empty + 16, // 22: proto.user.v1.UserService.DeleteUser:output_type -> google.protobuf.Empty + 16, // 23: proto.user.v1.UserService.ConfirmEmail:output_type -> google.protobuf.Empty + 16, // 24: proto.user.v1.UserService.RegisterUser:output_type -> google.protobuf.Empty + 16, // 25: proto.user.v1.UserService.ConfirmRegisterUser:output_type -> google.protobuf.Empty + 16, // 26: proto.user.v1.UserService.ResetPassword:output_type -> google.protobuf.Empty + 16, // 27: proto.user.v1.UserService.ConfirmResetPassword:output_type -> google.protobuf.Empty + 19, // [19:28] is the sub-list for method output_type + 10, // [10:19] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_user_v1_user_proto_init() } +func file_user_v1_user_proto_init() { + if File_user_v1_user_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_user_v1_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadUserResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmEmailRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegisterUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmRegisterUserRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResetPasswordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConfirmResetPasswordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserRequest_User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadUserResponse_User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_user_v1_user_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserRequest_User); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_user_v1_user_proto_msgTypes[11].OneofWrappers = []interface{}{} + file_user_v1_user_proto_msgTypes[12].OneofWrappers = []interface{}{} + file_user_v1_user_proto_msgTypes[13].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_user_v1_user_proto_rawDesc, + NumEnums: 1, + NumMessages: 14, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_user_v1_user_proto_goTypes, + DependencyIndexes: file_user_v1_user_proto_depIdxs, + EnumInfos: file_user_v1_user_proto_enumTypes, + MessageInfos: file_user_v1_user_proto_msgTypes, + }.Build() + File_user_v1_user_proto = out.File + file_user_v1_user_proto_rawDesc = nil + file_user_v1_user_proto_goTypes = nil + file_user_v1_user_proto_depIdxs = nil +} diff --git a/pkg/go/gen/user/v1/user_grpc.pb.go b/pkg/go/gen/user/v1/user_grpc.pb.go new file mode 100644 index 0000000..65d78ab --- /dev/null +++ b/pkg/go/gen/user/v1/user_grpc.pb.go @@ -0,0 +1,394 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc (unknown) +// source: user/v1/user.proto + +package userv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserServiceClient interface { + CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) + ReadUser(ctx context.Context, in *ReadUserRequest, opts ...grpc.CallOption) (*ReadUserResponse, error) + UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + ConfirmEmail(ctx context.Context, in *ConfirmEmailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + RegisterUser(ctx context.Context, in *RegisterUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + ConfirmRegisterUser(ctx context.Context, in *ConfirmRegisterUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + ResetPassword(ctx context.Context, in *ResetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + ConfirmResetPassword(ctx context.Context, in *ConfirmResetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) { + out := new(CreateUserResponse) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/CreateUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ReadUser(ctx context.Context, in *ReadUserRequest, opts ...grpc.CallOption) (*ReadUserResponse, error) { + out := new(ReadUserResponse) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/ReadUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/UpdateUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/DeleteUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ConfirmEmail(ctx context.Context, in *ConfirmEmailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/ConfirmEmail", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) RegisterUser(ctx context.Context, in *RegisterUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/RegisterUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ConfirmRegisterUser(ctx context.Context, in *ConfirmRegisterUserRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/ConfirmRegisterUser", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ResetPassword(ctx context.Context, in *ResetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/ResetPassword", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) ConfirmResetPassword(ctx context.Context, in *ConfirmResetPasswordRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/proto.user.v1.UserService/ConfirmResetPassword", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility +type UserServiceServer interface { + CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) + ReadUser(context.Context, *ReadUserRequest) (*ReadUserResponse, error) + UpdateUser(context.Context, *UpdateUserRequest) (*emptypb.Empty, error) + DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) + ConfirmEmail(context.Context, *ConfirmEmailRequest) (*emptypb.Empty, error) + RegisterUser(context.Context, *RegisterUserRequest) (*emptypb.Empty, error) + ConfirmRegisterUser(context.Context, *ConfirmRegisterUserRequest) (*emptypb.Empty, error) + ResetPassword(context.Context, *ResetPasswordRequest) (*emptypb.Empty, error) + ConfirmResetPassword(context.Context, *ConfirmResetPasswordRequest) (*emptypb.Empty, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have forward compatible implementations. +type UnimplementedUserServiceServer struct { +} + +func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUser not implemented") +} +func (UnimplementedUserServiceServer) ReadUser(context.Context, *ReadUserRequest) (*ReadUserResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadUser not implemented") +} +func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented") +} +func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented") +} +func (UnimplementedUserServiceServer) ConfirmEmail(context.Context, *ConfirmEmailRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmEmail not implemented") +} +func (UnimplementedUserServiceServer) RegisterUser(context.Context, *RegisterUserRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterUser not implemented") +} +func (UnimplementedUserServiceServer) ConfirmRegisterUser(context.Context, *ConfirmRegisterUserRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmRegisterUser not implemented") +} +func (UnimplementedUserServiceServer) ResetPassword(context.Context, *ResetPasswordRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetPassword not implemented") +} +func (UnimplementedUserServiceServer) ConfirmResetPassword(context.Context, *ConfirmResetPasswordRequest) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfirmResetPassword not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_CreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).CreateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/CreateUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).CreateUser(ctx, req.(*CreateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ReadUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReadUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ReadUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/ReadUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ReadUser(ctx, req.(*ReadUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).UpdateUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/UpdateUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).UpdateUser(ctx, req.(*UpdateUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).DeleteUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/DeleteUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ConfirmEmail_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmEmailRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ConfirmEmail(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/ConfirmEmail", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ConfirmEmail(ctx, req.(*ConfirmEmailRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_RegisterUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).RegisterUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/RegisterUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).RegisterUser(ctx, req.(*RegisterUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ConfirmRegisterUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmRegisterUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ConfirmRegisterUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/ConfirmRegisterUser", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ConfirmRegisterUser(ctx, req.(*ConfirmRegisterUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ResetPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetPasswordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ResetPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/ResetPassword", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ResetPassword(ctx, req.(*ResetPasswordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_ConfirmResetPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfirmResetPasswordRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ConfirmResetPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.user.v1.UserService/ConfirmResetPassword", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ConfirmResetPassword(ctx, req.(*ConfirmResetPasswordRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.user.v1.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateUser", + Handler: _UserService_CreateUser_Handler, + }, + { + MethodName: "ReadUser", + Handler: _UserService_ReadUser_Handler, + }, + { + MethodName: "UpdateUser", + Handler: _UserService_UpdateUser_Handler, + }, + { + MethodName: "DeleteUser", + Handler: _UserService_DeleteUser_Handler, + }, + { + MethodName: "ConfirmEmail", + Handler: _UserService_ConfirmEmail_Handler, + }, + { + MethodName: "RegisterUser", + Handler: _UserService_RegisterUser_Handler, + }, + { + MethodName: "ConfirmRegisterUser", + Handler: _UserService_ConfirmRegisterUser_Handler, + }, + { + MethodName: "ResetPassword", + Handler: _UserService_ResetPassword_Handler, + }, + { + MethodName: "ConfirmResetPassword", + Handler: _UserService_ConfirmResetPassword_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "user/v1/user.proto", +} diff --git a/proto/email/v1/email.proto b/proto/email/v1/email.proto new file mode 100644 index 0000000..89f44d8 --- /dev/null +++ b/proto/email/v1/email.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package proto.email.v1; + +import "google/protobuf/empty.proto"; + +service EmailService { + rpc SendEmail (SendEmailRequest) returns (google.protobuf.Empty); +} + +message SendEmailRequest { + string token = 1; + repeated int32 user_ids = 2; + string subject = 3; + string body = 4; +} diff --git a/proto/session/v1/session.proto b/proto/session/v1/session.proto new file mode 100644 index 0000000..d9f09eb --- /dev/null +++ b/proto/session/v1/session.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package proto.session.v1; + +import "google/protobuf/empty.proto"; + +service SessionService { + rpc Create (CreateSessionRequest) returns (CreateSessionResponse); + rpc Read (ReadSessionRequest) returns (ReadSessionResponse); + rpc Update (UpdateSessionRequest) returns (google.protobuf.Empty); + rpc Delete (DeleteSessionRequest) returns (google.protobuf.Empty); +} + +message CreateSessionRequest { + string handle = 1; + string password = 2; +} +message CreateSessionResponse { + string token = 1; +} + +message ReadSessionRequest { + string token = 1; +} +message ReadSessionResponse { + int32 user_id = 2; +} + +message UpdateSessionRequest { + string token = 1; +} + +message DeleteSessionRequest { + string token = 1; +} \ No newline at end of file diff --git a/proto/user/v1/user.proto b/proto/user/v1/user.proto new file mode 100644 index 0000000..c51995b --- /dev/null +++ b/proto/user/v1/user.proto @@ -0,0 +1,103 @@ +syntax = "proto3"; + +package proto.user.v1; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/empty.proto"; + +service UserService { + rpc CreateUser (CreateUserRequest) returns (CreateUserResponse); + rpc ReadUser (ReadUserRequest) returns (ReadUserResponse); + rpc UpdateUser (UpdateUserRequest) returns (google.protobuf.Empty); + rpc DeleteUser (DeleteUserRequest) returns (google.protobuf.Empty); + + rpc ConfirmEmail (ConfirmEmailRequest) returns (google.protobuf.Empty); + + rpc RegisterUser (RegisterUserRequest) returns (google.protobuf.Empty); + rpc ConfirmRegisterUser (ConfirmRegisterUserRequest) returns (google.protobuf.Empty); + + rpc ResetPassword (ResetPasswordRequest) returns (google.protobuf.Empty); + rpc ConfirmResetPassword (ConfirmResetPasswordRequest) returns (google.protobuf.Empty); +} + +enum Role { + ROLE_SPECTATOR_UNSPECIFIED = 0; + ROLE_PARTICIPANT = 1; + ROLE_MODERATOR = 2; + ROLE_ADMIN = 3; +} + +message CreateUserRequest { + message User { + string username = 1; + string password = 2; + optional string email = 3; + optional google.protobuf.Timestamp expires_at = 4; + optional Role role = 5; + } + + string token = 1; + User user = 2; +} +message CreateUserResponse { + int32 id = 1; +} + +message ReadUserRequest { + string token = 1; + int32 id = 2; +} +message ReadUserResponse { + message User { + int32 id = 1; + string username = 2; + optional string email = 3; + string password = 4; + google.protobuf.Timestamp expires_at = 5; + google.protobuf.Timestamp created_at = 6; + Role role = 7; + } + User user = 1; +} + +message UpdateUserRequest { + message User { + int32 id = 1; + optional string username = 2; + optional string email = 3; + optional string password = 4; + optional google.protobuf.Timestamp expires_at = 5; + optional Role role = 6; + } + + string token = 1; + User user = 2; +} + +message DeleteUserRequest { + string token = 1; + int32 id = 2; +} + +message ConfirmEmailRequest { + string conf_token = 1; +} + +message RegisterUserRequest { + string email = 1; +} + +message ConfirmRegisterUserRequest { + string conf_token = 1; + string username = 2; + string password = 3; +} + +message ResetPasswordRequest { + string email = 1; +} + +message ConfirmResetPasswordRequest { + string conf_token = 1; + string password = 2; +} \ No newline at end of file