add get user detail

This commit is contained in:
nochill 2023-09-23 15:24:21 +07:00
parent cbf7a41c80
commit 5368e934b6
8 changed files with 176 additions and 54 deletions

View File

@ -149,6 +149,17 @@ func (server *Server) getTopListLocations(ctx *gin.Context) {
} }
ctx.JSON(http.StatusOK, locations) ctx.JSON(http.StatusOK, locations)
// str, err := ctx.Cookie("kek123429")
// if err != nil {
// ctx.JSON(http.StatusUnauthorized, ErrorResponse(err, ""))
// }
// ctx.JSON(http.StatusOK, gin.H{
// "str": str,
// "res": locations,
// })
} }
type getListRecentLocationsWithRatingsReq struct { type getListRecentLocationsWithRatingsReq struct {

View File

@ -38,6 +38,8 @@ func (server *Server) getRoutes() {
router.Use(CORSMiddleware()) router.Use(CORSMiddleware())
router.POST("/user/signup", server.createUser) router.POST("/user/signup", server.createUser)
router.POST("/user/login", server.login)
router.POST("/user/logout", server.logout)
// LOCATION // LOCATION
router.POST("/locations", server.createLocation) router.POST("/locations", server.createLocation)

View File

@ -32,11 +32,9 @@ type createUserResponse struct {
} }
type userTokenResponse struct { type userTokenResponse struct {
SessionID int32 `json:"session_id"` SessionID int32 `json:"session_id"`
AccesToken string `json:"access_token"` AccesToken string `json:"access_token"`
AccessTokenExpiresAt time.Time `json:"access_token_expires_at"` AccessTokenExpiresAt time.Time `json:"access_token_expires_at"`
RefreshToken string `json:"refresh_token"`
RefreshTokenExpiresAt time.Time `json:"refresh_token_expires_at"`
} }
func (server *Server) createUser(ctx *gin.Context) { func (server *Server) createUser(ctx *gin.Context) {
@ -84,19 +82,19 @@ func (server *Server) createUser(ctx *gin.Context) {
return return
} }
refreshToken, refreshTokenPayload, err := server.TokenMaker.CreateToken( // refreshToken, refreshTokenPayload, err := server.TokenMaker.CreateToken(
user.Username, // user.Username,
int(user.ID), // int(user.ID),
server.Config.RefreshTokenDuration, // server.Config.RefreshTokenDuration,
) // )
session, err := server.Store.CreateSession(ctx, db.CreateSessionParams{ session, err := server.Store.CreateSession(ctx, db.CreateSessionParams{
Username: user.Username, Username: user.Username,
RefreshToken: refreshToken, // RefreshToken: refreshToken,
UserAgent: ctx.Request.UserAgent(), UserAgent: ctx.Request.UserAgent(),
ClientIp: ctx.ClientIP(), ClientIp: ctx.ClientIP(),
IsBlocked: false, IsBlocked: false,
ExpiresAt: refreshTokenPayload.ExpiredAt, // ExpiresAt: refreshTokenPayload.ExpiredAt,
}) })
if err != nil { if err != nil {
@ -105,11 +103,9 @@ func (server *Server) createUser(ctx *gin.Context) {
} }
tokenResponse := userTokenResponse{ tokenResponse := userTokenResponse{
SessionID: session.ID, SessionID: session.ID,
AccesToken: accessToken, AccesToken: accessToken,
AccessTokenExpiresAt: accessPayload.ExpiredAt, AccessTokenExpiresAt: accessPayload.ExpiredAt,
RefreshToken: refreshToken,
RefreshTokenExpiresAt: refreshTokenPayload.ExpiredAt,
} }
res := createUserResponse{ res := createUserResponse{
@ -127,8 +123,87 @@ func (server *Server) createUser(ctx *gin.Context) {
UpdatedAt: user.UpdatedAt.Time, UpdatedAt: user.UpdatedAt.Time,
} }
ctx.SetCookie(
"paseto",
accessToken,
accessPayload.ExpiredAt.Second(),
"/",
"localhost",
false,
true,
)
ctx.JSON(http.StatusOK, gin.H{ ctx.JSON(http.StatusOK, gin.H{
"token": tokenResponse, "token": tokenResponse,
"user": res, "user": res,
}) })
} }
func (server *Server) login(ctx *gin.Context) {
var req createUserRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, ValidationErrorResponse(err))
return
}
user, err := server.Store.GetUser(ctx, req.Username)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, ErrorResponse(err, ""))
return
}
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong whlie try to get user"))
return
}
err = util.CheckPassword(req.Password, user.Password)
if err != nil {
ctx.JSON(http.StatusUnauthorized, ErrorResponse(err, "Password not match"))
return
}
accessToken, accessPayload, err := server.TokenMaker.CreateToken(user.Username, int(user.ID), server.Config.TokenDuration)
if err != nil {
ctx.JSON(http.StatusInternalServerError, "Something went wrong while try to create token")
return
}
_, err = server.Store.CreateSession(ctx, db.CreateSessionParams{
Username: user.Username,
UserAgent: ctx.Request.UserAgent(),
ClientIp: ctx.ClientIP(),
IsBlocked: false,
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, ErrorResponse(err, "Something went wrong while try to create session"))
return
}
ctx.SetCookie(
"paseto",
accessToken,
accessPayload.ExpiredAt.Second(),
"",
"localhost",
false,
true,
)
ctx.JSON(http.StatusOK, user)
}
func (server *Server) logout(ctx *gin.Context) {
ctx.SetCookie(
"paseto",
"",
-1,
"/",
"",
false,
true,
)
ctx.Writer.WriteHeader(http.StatusNoContent)
}

View File

@ -200,10 +200,10 @@ func (mr *MockStoreMockRecorder) GetTopListLocations(arg0, arg1 interface{}) *go
} }
// GetUser mocks base method. // GetUser mocks base method.
func (m *MockStore) GetUser(arg0 context.Context, arg1 string) (db.User, error) { func (m *MockStore) GetUser(arg0 context.Context, arg1 string) (db.GetUserRow, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUser", arg0, arg1) ret := m.ctrl.Call(m, "GetUser", arg0, arg1)
ret0, _ := ret[0].(db.User) ret0, _ := ret[0].(db.GetUserRow)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }

View File

@ -18,7 +18,6 @@ type Querier interface {
GetLocation(ctx context.Context, id int32) (GetLocationRow, error) GetLocation(ctx context.Context, id int32) (GetLocationRow, error)
GetLocationTag(ctx context.Context, targetID int32) ([]string, error) GetLocationTag(ctx context.Context, targetID int32) ([]string, error)
GetSession(ctx context.Context, id int32) (UserSession, error) GetSession(ctx context.Context, id int32) (UserSession, error)
GetUser(ctx context.Context, username string) (User, error)
UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error UpdatePassword(ctx context.Context, arg UpdatePasswordParams) error
UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error) UpdateUser(ctx context.Context, arg UpdateUserParams) (User, error)
} }

View File

@ -11,6 +11,7 @@ type Store interface {
Querier Querier
GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error) GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error)
GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error) GetImagesByLocation(ctx context.Context, arg GetImagesByLocationParams) ([]GetImagesByLocationRow, error)
GetUser(ctx context.Context, username string) (GetUserRow, error)
} }
type SQLStore struct { type SQLStore struct {

64
db/sqlc/users.go Normal file
View File

@ -0,0 +1,64 @@
package db
import (
"context"
"database/sql"
"github.com/sqlc-dev/pqtype"
)
const getUser = `-- name: GetUser :one
SELECT
id,
COALESCE(email, '') as email,
password,
username,
COALESCE(avatar_picture, '') as avatar_picture,
banned_at,
banned_until,
COALESCE(ban_reason, '') as ban_reason,
is_permaban,
is_admin,
is_critics,
is_verified,
social_media
FROM USERS
WHERE username = $1
`
type GetUserRow struct {
ID int32 `json:"id"`
Email string `json:"email"`
Password string `json:"-"`
Username string `json:"username"`
AvatarPicture string `json:"avatar_picture"`
BannedAt sql.NullTime `json:"banned_at"`
BannedUntil sql.NullTime `json:"banned_until"`
BanReason string `json:"ban_reason"`
IsPermaban bool `json:"is_permaban"`
IsAdmin bool `json:"is_admin"`
IsCritics bool `json:"is_critics"`
IsVerified bool `json:"is_verified"`
SocialMedia pqtype.NullRawMessage `json:"social_media"`
}
func (q *Queries) GetUser(ctx context.Context, username string) (GetUserRow, error) {
row := q.db.QueryRowContext(ctx, getUser, username)
var i GetUserRow
err := row.Scan(
&i.ID,
&i.Email,
&i.Password,
&i.Username,
&i.AvatarPicture,
&i.BannedAt,
&i.BannedUntil,
&i.BanReason,
&i.IsPermaban,
&i.IsAdmin,
&i.IsCritics,
&i.IsVerified,
&i.SocialMedia,
)
return i, err
}

View File

@ -48,36 +48,6 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, e
return i, err return i, err
} }
const getUser = `-- name: GetUser :one
SELECT id, email, username, password, avatar_picture, google_sign_in_payload, banned_at, banned_until, ban_reason, is_permaban, is_admin, is_critics, is_verified, is_active, social_media, created_at, updated_at FROM USERS
WHERE username = $1
`
func (q *Queries) GetUser(ctx context.Context, username string) (User, error) {
row := q.db.QueryRowContext(ctx, getUser, username)
var i User
err := row.Scan(
&i.ID,
&i.Email,
&i.Username,
&i.Password,
&i.AvatarPicture,
&i.GoogleSignInPayload,
&i.BannedAt,
&i.BannedUntil,
&i.BanReason,
&i.IsPermaban,
&i.IsAdmin,
&i.IsCritics,
&i.IsVerified,
&i.IsActive,
&i.SocialMedia,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const updatePassword = `-- name: UpdatePassword :exec const updatePassword = `-- name: UpdatePassword :exec
UPDATE users UPDATE users
SET password = $1 SET password = $1