refactor:
This commit is contained in:
parent
8ac07abb30
commit
73852d3350
35 changed files with 764 additions and 4027 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.env
|
||||
.idea
|
||||
pkg/go/gen
|
20
Dockerfile
20
Dockerfile
|
@ -1,9 +1,15 @@
|
|||
FROM golang:latest
|
||||
FROM golang:1.22-alpine AS base
|
||||
WORKDIR /src
|
||||
RUN --mount=type=cache,target=/go/pkg/mod/ \
|
||||
--mount=type=bind,source=go.sum,target=go.sum \
|
||||
--mount=type=bind,source=go.mod,target=go.mod \
|
||||
go mod download -x
|
||||
|
||||
WORKDIR /app
|
||||
FROM base AS builder
|
||||
RUN --mount=type=cache,target=/go/pkg/mod/ \
|
||||
--mount=type=bind,target=. \
|
||||
go build -o /bin/server .
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go build ./main.go
|
||||
|
||||
CMD ["./main"]
|
||||
FROM scratch AS runner
|
||||
COPY --from=builder /bin/server /bin/
|
||||
ENTRYPOINT [ "/bin/server" ]
|
7
Makefile
Normal file
7
Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
dev:
|
||||
@buf generate proto
|
||||
@go run main.go
|
||||
|
||||
build:
|
||||
@buf generate proto
|
||||
# TODO: build dockerfile
|
|
@ -1,75 +0,0 @@
|
|||
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
|
|
@ -1,35 +0,0 @@
|
|||
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")
|
||||
}
|
|
@ -1,27 +1,11 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ilyakaznacheev/cleanenv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Env string `env:"ENV" env-default:"prod"`
|
||||
Address string `env:"ADDRESS" env-default:":8090"`
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -20,3 +20,7 @@ var (
|
|||
ErrTooShortUsername = errors.New("too short username")
|
||||
ErrTooLongUsername = errors.New("too long username")
|
||||
)
|
||||
|
||||
var (
|
||||
ErrBadSession = errors.New("bad session")
|
||||
)
|
||||
|
|
|
@ -1,32 +1,10 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"net/mail"
|
||||
"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
|
||||
}
|
||||
|
@ -38,3 +16,34 @@ func AsInt32P(v int32) *int32 {
|
|||
func AsStringP(str string) *string {
|
||||
return &str
|
||||
}
|
||||
|
||||
func ValidPassword(str string) error {
|
||||
if len(str) < 5 {
|
||||
return ErrTooShortPassword
|
||||
}
|
||||
if len(str) > 70 {
|
||||
return ErrTooLongPassword
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidEmail(str string) error {
|
||||
emailAddress, err := mail.ParseAddress(str)
|
||||
if err != nil || emailAddress.Address != str {
|
||||
return ErrBadEmail
|
||||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
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
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
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
|
||||
}
|
44
internal/models/role.go
Normal file
44
internal/models/role.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package models
|
||||
|
||||
import "ms-auth/internal/lib"
|
||||
|
||||
type Role int32
|
||||
|
||||
const (
|
||||
RoleSpectator Role = 0
|
||||
RoleParticipant Role = 1
|
||||
RoleModerator Role = 2
|
||||
RoleAdmin Role = 3
|
||||
)
|
||||
|
||||
func (role Role) IsAdmin() bool {
|
||||
return role == RoleAdmin
|
||||
}
|
||||
|
||||
func (role Role) IsModerator() bool {
|
||||
return role == RoleModerator
|
||||
}
|
||||
|
||||
func (role Role) IsParticipant() bool {
|
||||
return role == RoleParticipant
|
||||
}
|
||||
|
||||
func (role Role) IsSpectator() bool {
|
||||
return role == RoleSpectator
|
||||
}
|
||||
|
||||
func (role Role) AtLeast(other Role) bool {
|
||||
return role >= other
|
||||
}
|
||||
|
||||
func (role Role) AtMost(other Role) bool {
|
||||
return role <= other
|
||||
}
|
||||
|
||||
func (role Role) Valid() error {
|
||||
switch role {
|
||||
case RoleSpectator, RoleParticipant, RoleModerator, RoleAdmin:
|
||||
return nil
|
||||
}
|
||||
return lib.ErrBadRole
|
||||
}
|
55
internal/models/session.go
Normal file
55
internal/models/session.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/google/uuid"
|
||||
"ms-auth/internal/lib"
|
||||
)
|
||||
|
||||
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 lib.ErrBadSession
|
||||
}
|
||||
if s.UserId == nil {
|
||||
return lib.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 "", lib.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, lib.ErrBadSession
|
||||
}
|
||||
session := parsedToken.Claims.(*Session)
|
||||
if err = session.Valid(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return session, nil
|
||||
}
|
81
internal/models/user.go
Normal file
81
internal/models/user.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"ms-auth/internal/lib"
|
||||
"time"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id *int32 `db:"id"`
|
||||
Username *string `db:"username"`
|
||||
Password *string `db:"hashed_pwd"`
|
||||
Email *string `db:"email"`
|
||||
ExpiresAt *time.Time `db:"expires_at"`
|
||||
CreatedAt *time.Time `db:"created_at"`
|
||||
UpdatedAt *time.Time `db:"updated_at"`
|
||||
Role *Role `db:"role"`
|
||||
}
|
||||
|
||||
func (user *User) ValidUsername() error {
|
||||
if user.Username == nil {
|
||||
return lib.ErrBadUsername
|
||||
}
|
||||
|
||||
err := lib.ValidUsername(*user.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user *User) ValidPassword() error {
|
||||
if user.Password == nil {
|
||||
return lib.ErrBadHandleOrPassword
|
||||
}
|
||||
|
||||
err := lib.ValidPassword(*user.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user *User) ValidEmail() error {
|
||||
if user.Email == nil {
|
||||
return lib.ErrBadEmail
|
||||
}
|
||||
return lib.ValidEmail(*user.Email)
|
||||
}
|
||||
|
||||
func (user *User) ValidRole() error {
|
||||
if user.Role == nil {
|
||||
return lib.ErrBadRole
|
||||
}
|
||||
return user.Role.Valid()
|
||||
}
|
||||
|
||||
func (user *User) HashPassword() error {
|
||||
if user.Password == nil {
|
||||
return lib.ErrBadHandleOrPassword
|
||||
}
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*user.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return lib.ErrInternal
|
||||
}
|
||||
user.Password = lib.AsStringP(string(hashedPassword))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (user *User) ComparePassword(password string) error {
|
||||
if user.Password == nil {
|
||||
return lib.ErrBadHandleOrPassword
|
||||
}
|
||||
err := bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(password))
|
||||
if err != nil {
|
||||
return lib.ErrBadHandleOrPassword
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package services
|
|
@ -3,35 +3,25 @@ package services
|
|||
import (
|
||||
"context"
|
||||
"ms-auth/internal/lib"
|
||||
"ms-auth/internal/storage"
|
||||
"ms-auth/internal/models"
|
||||
)
|
||||
|
||||
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
|
||||
ReadSessionByToken(ctx context.Context, token string) (*models.Session, error)
|
||||
ReadSessionByUserId(ctx context.Context, userId int32) (*models.Session, error)
|
||||
UpdateSession(ctx context.Context, session *models.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
|
||||
userProvider UserStorage
|
||||
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 {
|
||||
func NewSessionService(sessionProvider SessionProvider, userProvider UserStorage, cfg lib.Config) *SessionService {
|
||||
return &SessionService{
|
||||
sessionProvider: sessionProvider,
|
||||
userProvider: userProvider,
|
||||
|
@ -39,20 +29,10 @@ func NewSessionService(sessionProvider SessionProvider, userProvider UserProvide
|
|||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
user *models.User
|
||||
)
|
||||
|
||||
if lib.ValidUsername(handle) == nil {
|
||||
|
@ -71,12 +51,12 @@ func (s *SessionService) Create(ctx context.Context, handle, password string) (*
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = s.sessionProvider.CreateSession(ctx, user.Id)
|
||||
err = s.sessionProvider.CreateSession(ctx, *user.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session, err := s.sessionProvider.ReadSessionByUserId(ctx, user.Id)
|
||||
session, err := s.sessionProvider.ReadSessionByUserId(ctx, *user.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -89,15 +69,6 @@ func (s *SessionService) Create(ctx context.Context, handle, password string) (*
|
|||
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 {
|
||||
|
@ -106,14 +77,6 @@ func (s *SessionService) Read(ctx context.Context, token string) (*int32, error)
|
|||
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 {
|
||||
|
@ -126,14 +89,6 @@ func (s *SessionService) Update(ctx context.Context, token string) error {
|
|||
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 {
|
||||
|
|
|
@ -3,130 +3,54 @@ package services
|
|||
import (
|
||||
"context"
|
||||
"ms-auth/internal/lib"
|
||||
"ms-auth/internal/storage"
|
||||
"time"
|
||||
"ms-auth/internal/models"
|
||||
)
|
||||
|
||||
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
|
||||
type UserStorage interface {
|
||||
CreateUser(ctx context.Context, user *models.User) (int32, error)
|
||||
ReadUserByEmail(ctx context.Context, email string) (*models.User, error)
|
||||
ReadUserByUsername(ctx context.Context, username string) (*models.User, error)
|
||||
ReadUserById(ctx context.Context, id int32) (*models.User, error)
|
||||
UpdateUser(ctx context.Context, user *models.User) 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
|
||||
userProvider UserStorage
|
||||
sessionProvider SessionProvider
|
||||
confirmationProvider ConfirmationProvider
|
||||
//emailProvider EmailProvider
|
||||
cfg *lib.Config
|
||||
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,
|
||||
userProvider UserStorage,
|
||||
sessionProvider SessionProvider,
|
||||
confirmationProvider ConfirmationProvider,
|
||||
//emailProvider EmailProvider,
|
||||
cfg *lib.Config,
|
||||
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
|
||||
func (u *UserService) CreateUser(ctx context.Context, user *models.User) (int32, error) {
|
||||
me := ctx.Value("user").(*models.User)
|
||||
|
||||
switch *me.Role {
|
||||
case models.RoleAdmin:
|
||||
break
|
||||
case models.RoleModerator:
|
||||
if !user.Role.AtMost(models.RoleParticipant) {
|
||||
return 0, lib.ErrNoPermission
|
||||
}
|
||||
default:
|
||||
return 0, lib.ErrNoPermission
|
||||
}
|
||||
|
||||
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)
|
||||
return u.userProvider.CreateUser(ctx, user)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
func (u *UserService) ReadUserBySessionToken(ctx context.Context, token string) (*models.User, error) {
|
||||
session, err := u.sessionProvider.ReadSessionByToken(ctx, token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -135,69 +59,57 @@ func (u *UserService) ReadUserBySessionToken(ctx context.Context, token string)
|
|||
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
|
||||
}
|
||||
|
||||
func (u *UserService) ReadUser(ctx context.Context, id int32) (*models.User, error) {
|
||||
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
|
||||
}
|
||||
func (u *UserService) ReadUserByEmail(ctx context.Context, email string) (*models.User, error) {
|
||||
return u.userProvider.ReadUserByEmail(ctx, email)
|
||||
}
|
||||
|
||||
user, err := u.userProvider.ReadUserById(ctx, id)
|
||||
func (u *UserService) ReadUserByUsername(ctx context.Context, username string) (*models.User, error) {
|
||||
return u.userProvider.ReadUserByUsername(ctx, username)
|
||||
}
|
||||
|
||||
func (u *UserService) UpdateUser(ctx context.Context, modifiedUser *models.User) error {
|
||||
me := ctx.Value("user").(*models.User)
|
||||
|
||||
user, err := u.userProvider.ReadUserById(ctx, *modifiedUser.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasAccess := func() bool {
|
||||
if me.Id == user.Id {
|
||||
if me.Role.IsAdmin() {
|
||||
return true
|
||||
}
|
||||
if me.Role.IsModerator() {
|
||||
if !user.Role.AtMost(models.RoleParticipant) {
|
||||
return false
|
||||
}
|
||||
if me.IsAdmin() {
|
||||
return true
|
||||
}
|
||||
if me.IsModerator() && (user.IsParticipant() || user.IsSpectator()) {
|
||||
if me.Role.IsParticipant() {
|
||||
if me.Id != user.Id {
|
||||
return false
|
||||
}
|
||||
if modifiedUser.Username != nil {
|
||||
return false
|
||||
}
|
||||
if modifiedUser.Email != nil {
|
||||
return false
|
||||
}
|
||||
if modifiedUser.ExpiresAt != nil {
|
||||
return false
|
||||
}
|
||||
if modifiedUser.Role != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
if me.Role.IsSpectator() {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}()
|
||||
|
||||
|
@ -205,40 +117,15 @@ func (u *UserService) UpdateUser(
|
|||
return lib.ErrNoPermission
|
||||
}
|
||||
|
||||
return u.userProvider.UpdateUser(ctx, id, username, password, email, expiresAt, role)
|
||||
return u.userProvider.UpdateUser(ctx, user)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
func (u *UserService) DeleteUser(ctx context.Context, id int32) error {
|
||||
me := ctx.Value("user").(*models.User)
|
||||
|
||||
if user.Id == id || !user.IsAdmin() {
|
||||
if *me.Id == id || !me.Role.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)
|
||||
}
|
||||
|
|
|
@ -1,267 +0,0 @@
|
|||
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 [60]byte `db:"hashed_pwd"`
|
||||
|
||||
Email *string `db:"email"`
|
||||
|
||||
ExpiresAt time.Time `db:"expires_at"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
|
||||
Role int32 `db:"role"`
|
||||
}
|
||||
|
||||
func (user *User) IsAdmin() bool {
|
||||
return lib.IsAdmin(user.Role)
|
||||
}
|
||||
|
||||
func (user *User) IsModerator() bool {
|
||||
return lib.IsModerator(user.Role)
|
||||
}
|
||||
|
||||
func (user *User) IsParticipant() bool {
|
||||
return lib.IsParticipant(user.Role)
|
||||
}
|
||||
|
||||
func (user *User) IsSpectator() bool {
|
||||
return lib.IsSpectator(user.Role)
|
||||
}
|
||||
|
||||
func (user *User) AtLeast(role int32) bool {
|
||||
return user.Role >= role
|
||||
}
|
||||
|
||||
func (user *User) ComparePassword(password string) error {
|
||||
if bcrypt.CompareHashAndPassword(user.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_pwd, email, expires_at, role)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING id
|
||||
`)
|
||||
|
||||
rows, err := storage.db.QueryxContext(ctx, query, username, hashedPassword, email, expiresAt, 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_pwd = COALESCE(?, hashed_pwd),
|
||||
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
|
||||
}
|
125
internal/storage/session.go
Normal file
125
internal/storage/session.go
Normal file
|
@ -0,0 +1,125 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/valkey-io/valkey-go"
|
||||
"go.uber.org/zap"
|
||||
"ms-auth/internal/lib"
|
||||
"ms-auth/internal/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SessionStorage struct {
|
||||
db valkey.Client
|
||||
cfg lib.Config
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewSessionStorage(db valkey.Client, cfg lib.Config, logger *zap.Logger) *SessionStorage {
|
||||
return &SessionStorage{
|
||||
db: db,
|
||||
cfg: cfg,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
const sessionLifetime = time.Minute * 40
|
||||
|
||||
func (storage *SessionStorage) CreateSession(ctx context.Context, userId int32) error {
|
||||
session := models.NewSession(userId)
|
||||
|
||||
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 {
|
||||
return lib.ErrInternal
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (storage *SessionStorage) ReadSessionByToken(ctx context.Context, token string) (*models.Session, error) {
|
||||
session, err := models.Parse(token, storage.cfg.JWTSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sessionRecord, err := storage.ReadSessionByUserId(ctx, *session.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if *session.Id != *sessionRecord.Id {
|
||||
return nil, lib.ErrInternal
|
||||
}
|
||||
|
||||
return session, err
|
||||
}
|
||||
|
||||
func (storage *SessionStorage) ReadSessionByUserId(ctx context.Context, userId int32) (*models.Session, error) {
|
||||
resp := storage.db.Do(ctx, storage.db.B().Get().Key(string(userId)).Build())
|
||||
if err := resp.Error(); err != nil {
|
||||
return nil, lib.ErrInternal
|
||||
}
|
||||
|
||||
id, err := resp.ToString()
|
||||
if err != nil {
|
||||
return nil, lib.ErrInternal
|
||||
}
|
||||
|
||||
return &models.Session{
|
||||
Id: &id,
|
||||
UserId: &userId,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (storage *SessionStorage) UpdateSession(ctx context.Context, session *models.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 {
|
||||
return lib.ErrInternal
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (storage *SessionStorage) DeleteSessionByToken(ctx context.Context, token string) error {
|
||||
session, err := models.Parse(token, storage.cfg.JWTSecret)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = storage.DeleteSessionByUserId(ctx, *session.UserId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (storage *SessionStorage) DeleteSessionByUserId(ctx context.Context, userId int32) error {
|
||||
resp := storage.db.Do(ctx, storage.db.
|
||||
B().Del().
|
||||
Key(string(userId)).
|
||||
Build(),
|
||||
)
|
||||
|
||||
if err := resp.Error(); err != nil {
|
||||
return lib.ErrInternal
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
178
internal/storage/user.go
Normal file
178
internal/storage/user.go
Normal file
|
@ -0,0 +1,178 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/jackc/pgerrcode"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"go.uber.org/zap"
|
||||
"ms-auth/internal/lib"
|
||||
"ms-auth/internal/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserStorage struct {
|
||||
db *sqlx.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewUserStorage(db *sqlx.DB, logger *zap.Logger) *UserStorage {
|
||||
return &UserStorage{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
const year = time.Hour * 24 * 365
|
||||
|
||||
func (storage *UserStorage) CreateUser(ctx context.Context, user *models.User) (int32, error) {
|
||||
if err := user.ValidUsername(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := user.ValidPassword(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := user.ValidEmail(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := user.ValidRole(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := user.HashPassword(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
query := storage.db.Rebind(`
|
||||
INSERT INTO users
|
||||
(username, hashed_pwd, email, expires_at, role)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
RETURNING id
|
||||
`)
|
||||
|
||||
rows, err := storage.db.QueryxContext(
|
||||
ctx,
|
||||
query,
|
||||
user.Username,
|
||||
user.Password,
|
||||
user.Email,
|
||||
time.Now().Add(100*year),
|
||||
user.Role,
|
||||
)
|
||||
if err != nil {
|
||||
return 0, storage.handlePgErr(err)
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
var id int32
|
||||
err = rows.StructScan(&id)
|
||||
if err != nil {
|
||||
return 0, storage.handlePgErr(err)
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (storage *UserStorage) ReadUserByEmail(ctx context.Context, email string) (*models.User, error) {
|
||||
var user models.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 *UserStorage) ReadUserByUsername(ctx context.Context, username string) (*models.User, error) {
|
||||
var user models.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 *UserStorage) ReadUserById(ctx context.Context, id int32) (*models.User, error) {
|
||||
var user models.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 *UserStorage) UpdateUser(ctx context.Context, user *models.User) error {
|
||||
var err error
|
||||
if user.Username != nil {
|
||||
if err = user.ValidUsername(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if user.Password != nil {
|
||||
if err = user.ValidPassword(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = user.HashPassword(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if user.Email != nil {
|
||||
if err = lib.ValidEmail(*user.Email); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if user.Role != nil {
|
||||
if err = user.Role.Valid(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
query := storage.db.Rebind(`
|
||||
UPDATE users
|
||||
SET username = COALESCE(?, username),
|
||||
hashed_pwd = COALESCE(?, hashed_pwd),
|
||||
email = COALESCE(?, email),
|
||||
expires_at = COALESCE(?, expires_at),
|
||||
role = COALESCE(?, role)
|
||||
WHERE id = ?`)
|
||||
|
||||
_, err = storage.db.ExecContext(
|
||||
ctx,
|
||||
query,
|
||||
user.Username,
|
||||
user.Password,
|
||||
user.Email,
|
||||
user.ExpiresAt,
|
||||
user.Role,
|
||||
user.Id,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return storage.handlePgErr(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (storage *UserStorage) 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 *UserStorage) 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
|
||||
}
|
|
@ -1,332 +0,0 @@
|
|||
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
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
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")
|
||||
}
|
|
@ -1 +1,36 @@
|
|||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type ReqWithToken interface {
|
||||
GetToken() string
|
||||
}
|
||||
|
||||
func (s *AuthServer) AuthInterceptor() grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
reqWithToken, ok := req.(ReqWithToken)
|
||||
if !ok {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "")
|
||||
}
|
||||
token := reqWithToken.GetToken()
|
||||
|
||||
userId, err := s.sessionService.Read(ctx, token)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "")
|
||||
}
|
||||
|
||||
user, err := s.userService.ReadUser(ctx, *userId)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "")
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, "user", user)
|
||||
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ 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"
|
||||
"ms-auth/internal/models"
|
||||
sessionv1 "ms-auth/pkg/go/gen/session/v1"
|
||||
userv1 "ms-auth/pkg/go/gen/user/v1"
|
||||
"net"
|
||||
|
@ -14,81 +13,55 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type SessionServiceI interface {
|
||||
type SessionService 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 UserService interface {
|
||||
CreateUser(ctx context.Context, user *models.User) (int32, error)
|
||||
ReadUser(ctx context.Context, id int32) (*models.User, error)
|
||||
UpdateUser(ctx context.Context, user *models.User) error
|
||||
DeleteUser(ctx context.Context, id int32) error
|
||||
}
|
||||
|
||||
type AuthServer struct {
|
||||
emailv1.UnimplementedEmailServiceServer
|
||||
|
||||
sessionv1.UnimplementedSessionServiceServer
|
||||
sessionService SessionServiceI
|
||||
sessionService SessionService
|
||||
|
||||
userv1.UnimplementedUserServiceServer
|
||||
userService UserServiceI
|
||||
userService UserService
|
||||
|
||||
gRPCServer *grpc.Server
|
||||
GRPCServer *grpc.Server
|
||||
logger *zap.Logger
|
||||
|
||||
ln net.Listener
|
||||
}
|
||||
|
||||
// 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{
|
||||
func NewAuthServer(
|
||||
sessionService SessionService,
|
||||
userService UserService,
|
||||
logger *zap.Logger,
|
||||
ln net.Listener,
|
||||
) *AuthServer {
|
||||
server := &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("")
|
||||
ln: ln,
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
grpcServer := grpc.NewServer(
|
||||
grpc.UnaryInterceptor(server.AuthInterceptor()),
|
||||
)
|
||||
|
||||
// GracefullyStop stops the server gracefully.
|
||||
//
|
||||
// No parameters.
|
||||
// No return values.
|
||||
func (s *AuthServer) GracefullyStop() {
|
||||
s.gRPCServer.GracefulStop()
|
||||
s.logger.Info("server stopped")
|
||||
server.GRPCServer = grpcServer
|
||||
|
||||
sessionv1.RegisterSessionServiceServer(server.GRPCServer, server)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
func AsTimeP(t *timestamppb.Timestamp) *time.Time {
|
||||
|
@ -99,11 +72,8 @@ func AsTimeP(t *timestamppb.Timestamp) *time.Time {
|
|||
return &tt
|
||||
}
|
||||
|
||||
func AsInt32P(v *userv1.Role) *int32 {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
vv := int32(v.Number())
|
||||
func AsMRoleP(v userv1.Role) *models.Role {
|
||||
vv := models.Role(v.Number())
|
||||
return &vv
|
||||
}
|
||||
|
||||
|
@ -114,7 +84,7 @@ func AsTimestampP(t *time.Time) *timestamppb.Timestamp {
|
|||
return timestamppb.New(*t)
|
||||
}
|
||||
|
||||
func AsRoleP(r *int32) *userv1.Role {
|
||||
func AsRoleP(r *models.Role) *userv1.Role {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@ import (
|
|||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
"ms-auth/internal/lib"
|
||||
"ms-auth/internal/models"
|
||||
userv1 "ms-auth/pkg/go/gen/user/v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (s *AuthServer) CreateUser(ctx context.Context, req *userv1.CreateUserRequest) (*userv1.CreateUserResponse, error) {
|
||||
|
@ -16,26 +17,26 @@ func (s *AuthServer) CreateUser(ctx context.Context, req *userv1.CreateUserReque
|
|||
}
|
||||
id, err := s.userService.CreateUser(
|
||||
ctx,
|
||||
req.GetToken(),
|
||||
user.GetUsername(),
|
||||
user.GetPassword(),
|
||||
user.Email,
|
||||
AsTimeP(user.ExpiresAt),
|
||||
AsInt32P(user.Role),
|
||||
&models.User{
|
||||
Username: lib.AsStringP(user.GetUsername()),
|
||||
Password: lib.AsStringP(user.GetPassword()),
|
||||
Email: nil,
|
||||
ExpiresAt: AsTimeP(user.ExpiresAt),
|
||||
Role: AsMRoleP(user.GetRole()),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME
|
||||
}
|
||||
|
||||
return &userv1.CreateUserResponse{
|
||||
Id: *id,
|
||||
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 {
|
||||
|
@ -44,12 +45,11 @@ func (s *AuthServer) ReadUser(ctx context.Context, req *userv1.ReadUserRequest)
|
|||
|
||||
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),
|
||||
Id: *user.Id,
|
||||
Username: *user.Username,
|
||||
ExpiresAt: AsTimestampP(user.ExpiresAt),
|
||||
CreatedAt: AsTimestampP(user.CreatedAt),
|
||||
Role: *AsRoleP(user.Role),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -61,13 +61,14 @@ func (s *AuthServer) UpdateUser(ctx context.Context, req *userv1.UpdateUserReque
|
|||
}
|
||||
err := s.userService.UpdateUser(
|
||||
ctx,
|
||||
req.GetToken(),
|
||||
user.GetId(),
|
||||
user.Username,
|
||||
user.Password,
|
||||
user.Email,
|
||||
AsTimeP(user.ExpiresAt),
|
||||
AsInt32P(user.Role),
|
||||
&models.User{
|
||||
Id: lib.AsInt32P(user.GetId()),
|
||||
Username: lib.AsStringP(user.GetUsername()),
|
||||
Password: lib.AsStringP(user.GetPassword()),
|
||||
Email: nil,
|
||||
ExpiresAt: AsTimeP(user.ExpiresAt),
|
||||
Role: AsMRoleP(user.GetRole()),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unknown, err.Error()) // FIXME
|
||||
|
@ -78,7 +79,6 @@ func (s *AuthServer) UpdateUser(ctx context.Context, req *userv1.UpdateUserReque
|
|||
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 {
|
||||
|
@ -86,39 +86,3 @@ func (s *AuthServer) DeleteUser(ctx context.Context, req *userv1.DeleteUserReque
|
|||
}
|
||||
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
|
||||
}
|
52
main.go
52
main.go
|
@ -2,20 +2,27 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ilyakaznacheev/cleanenv"
|
||||
_ "github.com/jackc/pgx/v5/stdlib"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/valkey-io/valkey-go"
|
||||
"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"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := lib.MustSetupConfig()
|
||||
var cfg lib.Config
|
||||
err := cleanenv.ReadConfig(".env", &cfg)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error reading config: %s", err.Error()))
|
||||
}
|
||||
|
||||
var logger *zap.Logger
|
||||
if cfg.Env == "prod" {
|
||||
|
@ -26,22 +33,45 @@ func main() {
|
|||
panic(fmt.Sprintf(`error reading config: env expected "prod" or "dev", got "%s"`, cfg.Env))
|
||||
}
|
||||
|
||||
postgres := storage.NewUserStorage(cfg.PostgresDSN, logger)
|
||||
db, err := sqlx.Connect("pgx", cfg.PostgresDSN)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
vk := storage.NewValkeyStorage(cfg.RedisDSN, cfg, logger)
|
||||
userStorage := storage.NewUserStorage(db, logger)
|
||||
|
||||
sessionService := services.NewSessionService(vk, postgres, cfg)
|
||||
userService := services.NewUserService(postgres, vk, vk, cfg)
|
||||
opts, err := valkey.ParseURL(cfg.RedisDSN)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
server := transport.NewAuthServer(sessionService, userService, grpc.NewServer(), logger)
|
||||
vk, err := valkey.NewClient(opts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer vk.Close()
|
||||
|
||||
application := app.NewApp(cfg, server)
|
||||
sessionStorage := storage.NewSessionStorage(vk, cfg, logger)
|
||||
|
||||
application.Start()
|
||||
sessionService := services.NewSessionService(sessionStorage, userStorage, cfg)
|
||||
userService := services.NewUserService(userStorage, sessionStorage, cfg)
|
||||
|
||||
ln, err := net.Listen("tcp", cfg.Address)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
server := transport.NewAuthServer(sessionService, userService, logger, ln)
|
||||
|
||||
go func() {
|
||||
if err = server.GRPCServer.Serve(ln); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
<-stop
|
||||
application.GracefullyStop()
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ CREATE TABLE IF NOT EXISTS users
|
|||
username VARCHAR(70) UNIQUE NOT NULL,
|
||||
hashed_pwd VARCHAR(60) NOT NULL,
|
||||
email VARCHAR(70) UNIQUE,
|
||||
role INT NOT NULL,
|
||||
expires_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
role INT NOT NULL DEFAULT 0,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
|
||||
PRIMARY KEY (id),
|
||||
CHECK (length(username) != 0 AND username = lower(username)),
|
||||
CHECK (length(email) != 0 AND email = lower(email)),
|
||||
CHECK (length(username) != 0 AND username = lower(username) AND username = trim(username)),
|
||||
CHECK (length(email) != 0 AND email = lower(email) AND email = trim(email)),
|
||||
CHECK (lower(username) != lower(email)),
|
||||
CHECK (length(hashed_pwd) != 0),
|
||||
CHECK (role BETWEEN 0 AND 3)
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
// 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
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
// 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",
|
||||
}
|
|
@ -1,511 +0,0 @@
|
|||
// 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
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
// 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",
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,394 +0,0 @@
|
|||
// 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",
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
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;
|
||||
}
|
|
@ -10,14 +10,6 @@ service UserService {
|
|||
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 {
|
||||
|
@ -31,9 +23,9 @@ message CreateUserRequest {
|
|||
message User {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
optional string email = 3;
|
||||
reserved 3;
|
||||
optional google.protobuf.Timestamp expires_at = 4;
|
||||
optional Role role = 5;
|
||||
Role role = 5;
|
||||
}
|
||||
|
||||
string token = 1;
|
||||
|
@ -51,7 +43,7 @@ message ReadUserResponse {
|
|||
message User {
|
||||
int32 id = 1;
|
||||
string username = 2;
|
||||
optional string email = 3;
|
||||
reserved 3;
|
||||
string password = 4;
|
||||
google.protobuf.Timestamp expires_at = 5;
|
||||
google.protobuf.Timestamp created_at = 6;
|
||||
|
@ -64,7 +56,7 @@ message UpdateUserRequest {
|
|||
message User {
|
||||
int32 id = 1;
|
||||
optional string username = 2;
|
||||
optional string email = 3;
|
||||
reserved 3;
|
||||
optional string password = 4;
|
||||
optional google.protobuf.Timestamp expires_at = 5;
|
||||
optional Role role = 6;
|
||||
|
@ -78,26 +70,3 @@ 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;
|
||||
}
|
Loading…
Reference in a new issue