Skip to content

Commit

Permalink
사용자 �아바타 사진 업로드/삭제 API 추가 (#26)
Browse files Browse the repository at this point in the history
* add: 사용자 프로필 업로드 API 데모

* add: 프로필 사진 업로드

* add: 프로필 사진 삭제 API 추가

* add: 프로필 사진 삭제 API 추가

* add: 문서 보강

* add: 용어 하나로 통일
  • Loading branch information
parkgang committed Dec 13, 2021
1 parent 7e8e335 commit 1a04c84
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 2 deletions.
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

0 comments on commit 1a04c84

Please sign in to comment.