Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

사용자 아바타 사진 업로드/삭제 API 추가 #26

Merged
merged 6 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,99 @@ var doc = `{
}
}
},
"/users/avatar": {
"post": {
"description": "사용자 아바타(프로필) 사진을 업로드 합니다.",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "사용자 아바타 사진 업로드",
"parameters": [
{
"type": "string",
"description": "Bearer {AccessToken}",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "file",
"description": "아바타 사진",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"201": {
"description": ""
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
}
}
},
"delete": {
"description": "사용자 아바타(프로필) 사진을 삭제합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "사용자 아바타 사진 삭제",
"parameters": [
{
"type": "string",
"description": "Bearer {AccessToken}",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"204": {
"description": ""
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
}
}
}
},
"/users/login": {
"post": {
"description": "로그인을 성공 시 JWT token이 발급됩니다.",
Expand Down
93 changes: 93 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,99 @@
}
}
},
"/users/avatar": {
"post": {
"description": "사용자 아바타(프로필) 사진을 업로드 합니다.",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "사용자 아바타 사진 업로드",
"parameters": [
{
"type": "string",
"description": "Bearer {AccessToken}",
"name": "Authorization",
"in": "header",
"required": true
},
{
"type": "file",
"description": "아바타 사진",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"201": {
"description": ""
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
}
}
},
"delete": {
"description": "사용자 아바타(프로필) 사진을 삭제합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "사용자 아바타 사진 삭제",
"parameters": [
{
"type": "string",
"description": "Bearer {AccessToken}",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"204": {
"description": ""
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/models.ErrResponse"
}
}
}
}
},
"/users/login": {
"post": {
"description": "로그인을 성공 시 JWT token이 발급됩니다.",
Expand Down
62 changes: 62 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,68 @@ paths:
summary: Email로 사용자 정보 조회
tags:
- User
/users/avatar:
delete:
consumes:
- application/json
description: 사용자 아바타(프로필) 사진을 삭제합니다.
parameters:
- description: Bearer {AccessToken}
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"204":
description: ""
"401":
description: Unauthorized
schema:
$ref: '#/definitions/models.ErrResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/models.ErrResponse'
summary: 사용자 아바타 사진 삭제
tags:
- User
post:
consumes:
- multipart/form-data
description: 사용자 아바타(프로필) 사진을 업로드 합니다.
parameters:
- description: Bearer {AccessToken}
in: header
name: Authorization
required: true
type: string
- description: 아바타 사진
in: formData
name: file
required: true
type: file
produces:
- application/json
responses:
"201":
description: ""
"400":
description: Bad Request
schema:
$ref: '#/definitions/models.ErrResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/models.ErrResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/models.ErrResponse'
summary: 사용자 아바타 사진 업로드
tags:
- User
/users/login:
post:
consumes:
Expand Down
85 changes: 85 additions & 0 deletions internal/app/handlers/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,88 @@ func UserTokenRefresh(c *gin.Context) {
})
}
}

// @Summary 사용자 아바타 사진 업로드
// @Description 사용자 아바타(프로필) 사진을 업로드 합니다.
// @Tags User
// @Accept mpfd
// @Produce json
// @Param Authorization header string true "Bearer {AccessToken}"
// @Param file formData file true "아바타 사진"
// @Success 201
// @Failure 400 {object} models.ErrResponse
// @Failure 401 {object} models.ErrResponse
// @Failure 500 {object} models.ErrResponse
// @Router /users/avatar [post]
func UploadAvatar(c *gin.Context) {
au, err := auth.ExtractTokenMetadata(c.Request)
if err != nil {
c.JSON(http.StatusUnauthorized, models.ErrResponse{
Message: err.Error(),
})
return
}

file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrResponse{
Message: err.Error(),
})
return
}

fileContent, err := file.Open()
if err != nil {
c.JSON(http.StatusInternalServerError, models.ErrResponse{
Message: err.Error(),
})
return
}
defer fileContent.Close()

fileData, err := ioutil.ReadAll(fileContent)
if err != nil {
c.JSON(http.StatusInternalServerError, models.ErrResponse{
Message: err.Error(),
})
return
}

if err := orm.Client.Model(&entitys.User{}).Where("id = ?", au.UserId).Update("AvatarImage", fileData).Error; err != nil {
c.JSON(http.StatusInternalServerError, models.ErrResponse{
Message: err.Error(),
})
return
}

c.Status(http.StatusCreated)
}

// @Summary 사용자 아바타 사진 삭제
// @Description 사용자 아바타(프로필) 사진을 삭제합니다.
// @Tags User
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer {AccessToken}"
// @Success 204
// @Failure 401 {object} models.ErrResponse
// @Failure 500 {object} models.ErrResponse
// @Router /users/avatar [delete]
func DeleteAvatar(c *gin.Context) {
au, err := auth.ExtractTokenMetadata(c.Request)
if err != nil {
c.JSON(http.StatusUnauthorized, models.ErrResponse{
Message: err.Error(),
})
return
}

if err := orm.Client.Model(&entitys.User{}).Where("id = ?", au.UserId).Update("AvatarImage", nil).Error; err != nil {
c.JSON(http.StatusInternalServerError, models.ErrResponse{
Message: err.Error(),
})
return
}

c.Status(http.StatusNoContent)
}
8 changes: 6 additions & 2 deletions internal/app/routers/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ func Use(api *gin.RouterGroup) {
users.POST("/signup", handlers.UserSignup)
users.POST("/login", handlers.UserLogin)
users.GET("/login/kakao", handlers.UserKakaoLoginCallBack)
users.GET("", middlewares.TokenAuthMiddleware(), handlers.UserInfoTokenQuey)
users.GET(":userEmail", handlers.UserInfoEmailQuey)
users.POST("/logout", middlewares.TokenAuthMiddleware(), handlers.UserLogout)

users.GET("/token/valid", middlewares.TokenAuthMiddleware(), handlers.UserTokenValid)
users.POST("/token/refresh", handlers.UserTokenRefresh)

users.GET("", middlewares.TokenAuthMiddleware(), handlers.UserInfoTokenQuey)
users.GET(":userEmail", handlers.UserInfoEmailQuey)
users.POST("/avatar", middlewares.TokenAuthMiddleware(), handlers.UploadAvatar)
users.DELETE("/avatar", middlewares.TokenAuthMiddleware(), handlers.DeleteAvatar)
}
configs := api.Group("/configs")
{
Expand Down