User registration
This commit is contained in:
parent
2398d3ebc0
commit
27d7df3d59
35
enshi_back/REST_API_stuff/requestAnswers.go
Normal file
35
enshi_back/REST_API_stuff/requestAnswers.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package rest_api_stuff
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OkAnswer(c *gin.Context, message string) {
|
||||||
|
c.IndentedJSON(
|
||||||
|
http.StatusOK,
|
||||||
|
gin.H{"message": message},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BadRequestAnswer(c *gin.Context, err error) {
|
||||||
|
c.IndentedJSON(
|
||||||
|
http.StatusBadRequest,
|
||||||
|
gin.H{"error": err.Error()},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InternalErrorAnswer(c *gin.Context, err error) {
|
||||||
|
c.IndentedJSON(
|
||||||
|
http.StatusInternalServerError,
|
||||||
|
gin.H{"error": err.Error()},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConflictAnswer(c *gin.Context, err error) {
|
||||||
|
c.IndentedJSON(
|
||||||
|
http.StatusConflict,
|
||||||
|
gin.H{"error": err.Error()},
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -85,9 +85,9 @@ type Tag struct {
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
UserID int64 `json:"user_id"`
|
UserID int64 `json:"user_id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username" validate:"required"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email" validate:"required,email"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password" validate:"required"`
|
||||||
CreatedAt pgtype.Timestamp `json:"created_at"`
|
CreatedAt pgtype.Timestamp `json:"created_at"`
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"is_admin"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,9 +18,9 @@ RETURNING user_id, username, email, password, created_at, is_admin
|
|||||||
|
|
||||||
type CreateUserParams struct {
|
type CreateUserParams struct {
|
||||||
UserID int64 `json:"user_id"`
|
UserID int64 `json:"user_id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username" validate:"required"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email" validate:"required,email"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) {
|
||||||
@ -93,6 +93,29 @@ func (q *Queries) GetAllUsers(ctx context.Context) ([]User, error) {
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUserByEmailOrNickname = `-- name: GetUserByEmailOrNickname :one
|
||||||
|
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE username = $1 OR email = $2 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetUserByEmailOrNicknameParams struct {
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Email string `json:"email" validate:"required,email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetUserByEmailOrNickname(ctx context.Context, arg GetUserByEmailOrNicknameParams) (User, error) {
|
||||||
|
row := q.db.QueryRow(ctx, getUserByEmailOrNickname, arg.Username, arg.Email)
|
||||||
|
var i User
|
||||||
|
err := row.Scan(
|
||||||
|
&i.UserID,
|
||||||
|
&i.Username,
|
||||||
|
&i.Email,
|
||||||
|
&i.Password,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.IsAdmin,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
const getUserById = `-- name: GetUserById :one
|
const getUserById = `-- name: GetUserById :one
|
||||||
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE user_id = $1
|
SELECT user_id, username, email, password, created_at, is_admin FROM users WHERE user_id = $1
|
||||||
`
|
`
|
||||||
@ -137,7 +160,7 @@ RETURNING user_id, username, email, password, created_at, is_admin
|
|||||||
`
|
`
|
||||||
|
|
||||||
type UpdateUserPasswordHashParams struct {
|
type UpdateUserPasswordHashParams struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password" validate:"required"`
|
||||||
UserID int64 `json:"user_id"`
|
UserID int64 `json:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,3 +26,6 @@ WHERE user_id=$1;
|
|||||||
-- name: DeleteUserByUsername :exec
|
-- name: DeleteUserByUsername :exec
|
||||||
DELETE FROM public.users
|
DELETE FROM public.users
|
||||||
WHERE username=$1;
|
WHERE username=$1;
|
||||||
|
|
||||||
|
-- name: GetUserByEmailOrNickname :one
|
||||||
|
SELECT * FROM users WHERE username = $1 OR email = $2 LIMIT 1;
|
||||||
@ -10,6 +10,12 @@ sql:
|
|||||||
out: "./go_queries"
|
out: "./go_queries"
|
||||||
sql_package: "pgx/v5"
|
sql_package: "pgx/v5"
|
||||||
overrides:
|
overrides:
|
||||||
|
- column: users.password
|
||||||
|
go_struct_tag: validate:"required"
|
||||||
|
- column: users.username
|
||||||
|
go_struct_tag: validate:"required"
|
||||||
|
- column: users.email
|
||||||
|
go_struct_tag: validate:"required,email"
|
||||||
- db_type: "uuid"
|
- db_type: "uuid"
|
||||||
go_type:
|
go_type:
|
||||||
import: 'github.com/google/uuid'
|
import: 'github.com/google/uuid'
|
||||||
|
|||||||
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/gin-gonic/gin v1.10.0 // indirect
|
github.com/gin-gonic/gin v1.10.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
github.com/go-playground/validator/v10 v10.22.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
|||||||
@ -21,6 +21,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
||||||
|
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
db_repo "enshi/db/go_queries"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
@ -11,6 +12,7 @@ import (
|
|||||||
// Pgx connection to database
|
// Pgx connection to database
|
||||||
var Dbx *pgxpool.Pool
|
var Dbx *pgxpool.Pool
|
||||||
var Dbx_connection *pgx.Conn
|
var Dbx_connection *pgx.Conn
|
||||||
|
var Sqlc_db = db_repo.New(Dbx)
|
||||||
|
|
||||||
func SetupDatabase() error {
|
func SetupDatabase() error {
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ func SetupDatabase() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Url to connect
|
// Url to connect
|
||||||
url := fmt.Sprintf("postgres://%v:%v@nekiiinkognito.ru:5432/enshi_db", bd_user, bd_pass)
|
url := fmt.Sprintf("postgres://%v:%v@nekiiinkognito.ru:5432/postgres", bd_user, bd_pass)
|
||||||
|
|
||||||
// Connecting to database
|
// Connecting to database
|
||||||
Dbx, err = pgxpool.New(context.Background(), url)
|
Dbx, err = pgxpool.New(context.Background(), url)
|
||||||
|
|||||||
@ -2,13 +2,18 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/binary"
|
||||||
|
rest_api_stuff "enshi/REST_API_stuff"
|
||||||
db_repo "enshi/db/go_queries"
|
db_repo "enshi/db/go_queries"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testCookie(c *gin.Context) {
|
func testCookie(c *gin.Context) {
|
||||||
@ -16,6 +21,80 @@ func testCookie(c *gin.Context) {
|
|||||||
c.IndentedJSON(http.StatusOK, gin.H{"token": "SLESAR' U STASA " + strings.Split(cock, "_")[0]})
|
c.IndentedJSON(http.StatusOK, gin.H{"token": "SLESAR' U STASA " + strings.Split(cock, "_")[0]})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegisterUser(c *gin.Context) {
|
||||||
|
var userParams db_repo.CreateUserParams
|
||||||
|
|
||||||
|
transaction, err := Dbx.Begin(context.Background())
|
||||||
|
defer transaction.Rollback(context.Background())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.InternalErrorAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.BindJSON(&userParams); err != nil {
|
||||||
|
rest_api_stuff.BadRequestAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
validate := validator.New(validator.WithRequiredStructEnabled())
|
||||||
|
err = validate.Struct(userParams)
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.BadRequestAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
query := db_repo.New(Dbx)
|
||||||
|
sameNicknameOrEmailUser, _ := query.GetUserByEmailOrNickname(
|
||||||
|
context.Background(),
|
||||||
|
db_repo.GetUserByEmailOrNicknameParams{
|
||||||
|
Username: userParams.Username,
|
||||||
|
Email: userParams.Email,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if sameNicknameOrEmailUser.Username == userParams.Username {
|
||||||
|
rest_api_stuff.ConflictAnswer(
|
||||||
|
c,
|
||||||
|
fmt.Errorf("username"),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
} else if sameNicknameOrEmailUser.Email == userParams.Email {
|
||||||
|
rest_api_stuff.ConflictAnswer(
|
||||||
|
c,
|
||||||
|
fmt.Errorf("email"),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlc_transaction := Sqlc_db.WithTx(transaction)
|
||||||
|
|
||||||
|
passwordHashSalt, err := Argon2Hasher.HashGen([]byte(userParams.Password), []byte{})
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.InternalErrorAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userParams.Password = passwordHashSalt.StringToStore
|
||||||
|
|
||||||
|
uuid, err := uuid.NewV7()
|
||||||
|
if err != nil {
|
||||||
|
rest_api_stuff.InternalErrorAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userParams.UserID = int64(
|
||||||
|
binary.BigEndian.Uint64(append(uuid[0:4], uuid[12:16]...)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if _, err := sqlc_transaction.CreateUser(context.Background(), userParams); err != nil {
|
||||||
|
rest_api_stuff.InternalErrorAnswer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit(context.Background())
|
||||||
|
rest_api_stuff.OkAnswer(c, "User has been created!")
|
||||||
|
}
|
||||||
|
|
||||||
func SetupRotes(g *gin.Engine) error {
|
func SetupRotes(g *gin.Engine) error {
|
||||||
g.Use(CORSMiddleware())
|
g.Use(CORSMiddleware())
|
||||||
|
|
||||||
@ -25,6 +104,7 @@ func SetupRotes(g *gin.Engine) error {
|
|||||||
|
|
||||||
freeGroup.POST("login", login)
|
freeGroup.POST("login", login)
|
||||||
freeGroup.GET("getCookie", testCookie)
|
freeGroup.GET("getCookie", testCookie)
|
||||||
|
freeGroup.POST("registerUser", RegisterUser)
|
||||||
|
|
||||||
authGroup := g.Group("/")
|
authGroup := g.Group("/")
|
||||||
authGroup.Use(AuthMiddleware())
|
authGroup.Use(AuthMiddleware())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user