Logout
This commit is contained in:
		@@ -1,10 +1,10 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	BASE_URL     = "https://cslms-api.jongyeob.com"
 | 
					  MODE         = "debug"
 | 
				
			||||||
	PORT         = ":3030"
 | 
						BASE_URL     = "https://codingschool.co.kr"
 | 
				
			||||||
  DATABASE_URL = "cslms:atobot2013!#%@tcp(ma.codingschool.co.kr:3306)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
						PORT         = ":30303"
 | 
				
			||||||
	//DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
 | 
					  DATABASE_URL = "cslms:atobot2013!#%@tcp(localhost:3306)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	KAKAO_CLIENT_ID     = "986830"
 | 
						KAKAO_CLIENT_ID     = "986830"
 | 
				
			||||||
	KAKAO_CLIENT_SECRET = "14f63a8e91c4e0fe88bc40e3ff348233"
 | 
						KAKAO_CLIENT_SECRET = "14f63a8e91c4e0fe88bc40e3ff348233"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
					  MODE         = "debug"
 | 
				
			||||||
	BASE_URL     = "http://localhost:3030"
 | 
						BASE_URL     = "http://localhost:3030"
 | 
				
			||||||
	PORT         = ":3030"
 | 
						PORT         = ":3030"
 | 
				
			||||||
	DATABASE_URL = "cslms:atobot2013!#%@tcp(localhost:33061)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
						DATABASE_URL = "cslms:atobot2013!#%@tcp(localhost:33061)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
					  MODE         = "debug"
 | 
				
			||||||
	BASE_URL     = "http://localhost:3030"
 | 
						BASE_URL     = "http://localhost:3030"
 | 
				
			||||||
	PORT         = ":3030"
 | 
						PORT         = ":3030"
 | 
				
			||||||
	DATABASE_URL = "cslms:atobot2013!#%@tcp(localhost:33061)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
						DATABASE_URL = "cslms:atobot2013!#%@tcp(localhost:33061)/cslms5?charset=utf8&parseTime=True&loc=Local"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	BASE_URL     = "https://cslms-api.jongyeob.com"
 | 
						MODE         = "release"
 | 
				
			||||||
	PORT         = ":3030"
 | 
						BASE_URL     = "https://cslms-api.codingschool.co.kr"
 | 
				
			||||||
 | 
						PORT         = ":30303"
 | 
				
			||||||
	DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
 | 
						DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	KAKAO_CLIENT_ID     = "986830"
 | 
						KAKAO_CLIENT_ID     = "986830"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ WORKDIR /app
 | 
				
			|||||||
RUN apk add --no-cache sqlite-libs mariadb-connector-c libgcc
 | 
					RUN apk add --no-cache sqlite-libs mariadb-connector-c libgcc
 | 
				
			||||||
COPY --from=builder /app/bootstrap .
 | 
					COPY --from=builder /app/bootstrap .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 3030
 | 
					EXPOSE 30303
 | 
				
			||||||
ENV PORT 3030
 | 
					ENV PORT 30303
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMD ["sh", "-c", "./bootstrap"]
 | 
					CMD ["sh", "-c", "./bootstrap"]
 | 
				
			||||||
@@ -7,4 +7,6 @@ services:
 | 
				
			|||||||
      dockerfile: docker/dev/Dockerfile
 | 
					      dockerfile: docker/dev/Dockerfile
 | 
				
			||||||
    image: learnsteam/cslms-api:dev
 | 
					    image: learnsteam/cslms-api:dev
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - "3030:3030"
 | 
					      - "30303:30303"
 | 
				
			||||||
 | 
					    network_mode: "host"
 | 
				
			||||||
 | 
					    restart: on-failure
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,3 +8,5 @@ services:
 | 
				
			|||||||
    image: learnsteam/cslms-api:local
 | 
					    image: learnsteam/cslms-api:local
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - "3030:3030"
 | 
					      - "3030:3030"
 | 
				
			||||||
 | 
					    network_mode: "host"
 | 
				
			||||||
 | 
					    restart: on-failure
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ WORKDIR /app
 | 
				
			|||||||
RUN apk add --no-cache sqlite-libs mariadb-connector-c libgcc
 | 
					RUN apk add --no-cache sqlite-libs mariadb-connector-c libgcc
 | 
				
			||||||
COPY --from=builder /app/bootstrap .
 | 
					COPY --from=builder /app/bootstrap .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 3030
 | 
					EXPOSE 30303
 | 
				
			||||||
ENV PORT 3030
 | 
					ENV PORT 30303
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMD ["sh", "-c", "./bootstrap"]
 | 
					CMD ["sh", "-c", "./bootstrap"]
 | 
				
			||||||
@@ -7,4 +7,6 @@ services:
 | 
				
			|||||||
      dockerfile: docker/prod/Dockerfile
 | 
					      dockerfile: docker/prod/Dockerfile
 | 
				
			||||||
    image: learnsteam/cslms-api
 | 
					    image: learnsteam/cslms-api
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      - "3030:3030"
 | 
					      - "30303:30303"
 | 
				
			||||||
 | 
					    network_mode: "host"
 | 
				
			||||||
 | 
					    restart: on-failure
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										59
									
								
								docs/docs.go
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								docs/docs.go
									
									
									
									
									
								
							@@ -52,6 +52,27 @@ const docTemplate = `{
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "/auth/logout": {
 | 
				
			||||||
 | 
					            "post": {
 | 
				
			||||||
 | 
					                "security": [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        "Bearer": []
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "description": "로그아웃하고 Token, Cookie 삭제",
 | 
				
			||||||
 | 
					                "consumes": [
 | 
				
			||||||
 | 
					                    "application/json"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "produces": [
 | 
				
			||||||
 | 
					                    "application/json"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "tags": [
 | 
				
			||||||
 | 
					                    "로그아웃"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "summary": "로그아웃",
 | 
				
			||||||
 | 
					                "responses": {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "/auth/register": {
 | 
					        "/auth/register": {
 | 
				
			||||||
            "post": {
 | 
					            "post": {
 | 
				
			||||||
                "description": "회원가입",
 | 
					                "description": "회원가입",
 | 
				
			||||||
@@ -1319,7 +1340,7 @@ const docTemplate = `{
 | 
				
			|||||||
                "data": {
 | 
					                "data": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "$ref": "#/definitions/learnsteam_cslms-api_internal_models.Quiz"
 | 
					                        "$ref": "#/definitions/learnsteam_cslms-api_internal_models.QuizResponse"
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "page": {
 | 
					                "page": {
 | 
				
			||||||
@@ -1459,8 +1480,14 @@ const docTemplate = `{
 | 
				
			|||||||
                "tag": {
 | 
					                "tag": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "string"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "Python",
 | 
				
			||||||
 | 
					                        "AI",
 | 
				
			||||||
 | 
					                        "Robot",
 | 
				
			||||||
 | 
					                        "파이썬"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "title": {
 | 
					                "title": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
@@ -1498,8 +1525,14 @@ const docTemplate = `{
 | 
				
			|||||||
                "tag": {
 | 
					                "tag": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "string"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "Python",
 | 
				
			||||||
 | 
					                        "AI",
 | 
				
			||||||
 | 
					                        "Robot",
 | 
				
			||||||
 | 
					                        "파이썬"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "title": {
 | 
					                "title": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
@@ -1867,7 +1900,13 @@ const docTemplate = `{
 | 
				
			|||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "integer"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        1000001,
 | 
				
			||||||
 | 
					                        1000002,
 | 
				
			||||||
 | 
					                        1000003,
 | 
				
			||||||
 | 
					                        1000004
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -1975,6 +2014,10 @@ const docTemplate = `{
 | 
				
			|||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "choice"
 | 
					                    "example": "choice"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                "quiz_id": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "example": 1000001
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                "quiz_paper_id": {
 | 
					                "quiz_paper_id": {
 | 
				
			||||||
                    "type": "integer",
 | 
					                    "type": "integer",
 | 
				
			||||||
                    "example": 1000001
 | 
					                    "example": 1000001
 | 
				
			||||||
@@ -2037,6 +2080,10 @@ const docTemplate = `{
 | 
				
			|||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "check"
 | 
					                    "example": "check"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                "quiz_id": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "example": 1000001
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                "result": {
 | 
					                "result": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "success"
 | 
					                    "example": "success"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,27 @@
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "/auth/logout": {
 | 
				
			||||||
 | 
					            "post": {
 | 
				
			||||||
 | 
					                "security": [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        "Bearer": []
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "description": "로그아웃하고 Token, Cookie 삭제",
 | 
				
			||||||
 | 
					                "consumes": [
 | 
				
			||||||
 | 
					                    "application/json"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "produces": [
 | 
				
			||||||
 | 
					                    "application/json"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "tags": [
 | 
				
			||||||
 | 
					                    "로그아웃"
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                "summary": "로그아웃",
 | 
				
			||||||
 | 
					                "responses": {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "/auth/register": {
 | 
					        "/auth/register": {
 | 
				
			||||||
            "post": {
 | 
					            "post": {
 | 
				
			||||||
                "description": "회원가입",
 | 
					                "description": "회원가입",
 | 
				
			||||||
@@ -1311,7 +1332,7 @@
 | 
				
			|||||||
                "data": {
 | 
					                "data": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "$ref": "#/definitions/learnsteam_cslms-api_internal_models.Quiz"
 | 
					                        "$ref": "#/definitions/learnsteam_cslms-api_internal_models.QuizResponse"
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "page": {
 | 
					                "page": {
 | 
				
			||||||
@@ -1451,8 +1472,14 @@
 | 
				
			|||||||
                "tag": {
 | 
					                "tag": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "string"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "Python",
 | 
				
			||||||
 | 
					                        "AI",
 | 
				
			||||||
 | 
					                        "Robot",
 | 
				
			||||||
 | 
					                        "파이썬"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "title": {
 | 
					                "title": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
@@ -1490,8 +1517,14 @@
 | 
				
			|||||||
                "tag": {
 | 
					                "tag": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "string"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "Python",
 | 
				
			||||||
 | 
					                        "AI",
 | 
				
			||||||
 | 
					                        "Robot",
 | 
				
			||||||
 | 
					                        "파이썬"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "title": {
 | 
					                "title": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
@@ -1859,7 +1892,13 @@
 | 
				
			|||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "integer"
 | 
					                        "type": "integer"
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        1000001,
 | 
				
			||||||
 | 
					                        1000002,
 | 
				
			||||||
 | 
					                        1000003,
 | 
				
			||||||
 | 
					                        1000004
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -1967,6 +2006,10 @@
 | 
				
			|||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "choice"
 | 
					                    "example": "choice"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                "quiz_id": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "example": 1000001
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                "quiz_paper_id": {
 | 
					                "quiz_paper_id": {
 | 
				
			||||||
                    "type": "integer",
 | 
					                    "type": "integer",
 | 
				
			||||||
                    "example": 1000001
 | 
					                    "example": 1000001
 | 
				
			||||||
@@ -2029,6 +2072,10 @@
 | 
				
			|||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "check"
 | 
					                    "example": "check"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                "quiz_id": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "example": 1000001
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                "result": {
 | 
					                "result": {
 | 
				
			||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "example": "success"
 | 
					                    "example": "success"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,7 +146,7 @@ definitions:
 | 
				
			|||||||
    properties:
 | 
					    properties:
 | 
				
			||||||
      data:
 | 
					      data:
 | 
				
			||||||
        items:
 | 
					        items:
 | 
				
			||||||
          $ref: '#/definitions/learnsteam_cslms-api_internal_models.Quiz'
 | 
					          $ref: '#/definitions/learnsteam_cslms-api_internal_models.QuizResponse'
 | 
				
			||||||
        type: array
 | 
					        type: array
 | 
				
			||||||
      page:
 | 
					      page:
 | 
				
			||||||
        example: 1
 | 
					        example: 1
 | 
				
			||||||
@@ -244,8 +244,13 @@ definitions:
 | 
				
			|||||||
        example: "on"
 | 
					        example: "on"
 | 
				
			||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
      tag:
 | 
					      tag:
 | 
				
			||||||
 | 
					        example:
 | 
				
			||||||
 | 
					        - Python
 | 
				
			||||||
 | 
					        - AI
 | 
				
			||||||
 | 
					        - Robot
 | 
				
			||||||
 | 
					        - 파이썬
 | 
				
			||||||
        items:
 | 
					        items:
 | 
				
			||||||
          type: integer
 | 
					          type: string
 | 
				
			||||||
        type: array
 | 
					        type: array
 | 
				
			||||||
      title:
 | 
					      title:
 | 
				
			||||||
        example: 퀴즈 시트 제목
 | 
					        example: 퀴즈 시트 제목
 | 
				
			||||||
@@ -272,8 +277,13 @@ definitions:
 | 
				
			|||||||
        example: "on"
 | 
					        example: "on"
 | 
				
			||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
      tag:
 | 
					      tag:
 | 
				
			||||||
 | 
					        example:
 | 
				
			||||||
 | 
					        - Python
 | 
				
			||||||
 | 
					        - AI
 | 
				
			||||||
 | 
					        - Robot
 | 
				
			||||||
 | 
					        - 파이썬
 | 
				
			||||||
        items:
 | 
					        items:
 | 
				
			||||||
          type: integer
 | 
					          type: string
 | 
				
			||||||
        type: array
 | 
					        type: array
 | 
				
			||||||
      title:
 | 
					      title:
 | 
				
			||||||
        example: 퀴즈 시트 제목
 | 
					        example: 퀴즈 시트 제목
 | 
				
			||||||
@@ -533,6 +543,11 @@ definitions:
 | 
				
			|||||||
        example: 1000002
 | 
					        example: 1000002
 | 
				
			||||||
        type: integer
 | 
					        type: integer
 | 
				
			||||||
      users:
 | 
					      users:
 | 
				
			||||||
 | 
					        example:
 | 
				
			||||||
 | 
					        - 1000001
 | 
				
			||||||
 | 
					        - 1000002
 | 
				
			||||||
 | 
					        - 1000003
 | 
				
			||||||
 | 
					        - 1000004
 | 
				
			||||||
        items:
 | 
					        items:
 | 
				
			||||||
          type: integer
 | 
					          type: integer
 | 
				
			||||||
        type: array
 | 
					        type: array
 | 
				
			||||||
@@ -612,6 +627,9 @@ definitions:
 | 
				
			|||||||
      question_type:
 | 
					      question_type:
 | 
				
			||||||
        example: choice
 | 
					        example: choice
 | 
				
			||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
 | 
					      quiz_id:
 | 
				
			||||||
 | 
					        example: 1000001
 | 
				
			||||||
 | 
					        type: integer
 | 
				
			||||||
      quiz_paper_id:
 | 
					      quiz_paper_id:
 | 
				
			||||||
        example: 1000001
 | 
					        example: 1000001
 | 
				
			||||||
        type: integer
 | 
					        type: integer
 | 
				
			||||||
@@ -657,6 +675,9 @@ definitions:
 | 
				
			|||||||
      question_type:
 | 
					      question_type:
 | 
				
			||||||
        example: check
 | 
					        example: check
 | 
				
			||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
 | 
					      quiz_id:
 | 
				
			||||||
 | 
					        example: 1000001
 | 
				
			||||||
 | 
					        type: integer
 | 
				
			||||||
      result:
 | 
					      result:
 | 
				
			||||||
        example: success
 | 
					        example: success
 | 
				
			||||||
        type: string
 | 
					        type: string
 | 
				
			||||||
@@ -706,6 +727,19 @@ paths:
 | 
				
			|||||||
      summary: 사용자 로그인 로그인
 | 
					      summary: 사용자 로그인 로그인
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
      - 로그인
 | 
					      - 로그인
 | 
				
			||||||
 | 
					  /auth/logout:
 | 
				
			||||||
 | 
					    post:
 | 
				
			||||||
 | 
					      consumes:
 | 
				
			||||||
 | 
					      - application/json
 | 
				
			||||||
 | 
					      description: 로그아웃하고 Token, Cookie 삭제
 | 
				
			||||||
 | 
					      produces:
 | 
				
			||||||
 | 
					      - application/json
 | 
				
			||||||
 | 
					      responses: {}
 | 
				
			||||||
 | 
					      security:
 | 
				
			||||||
 | 
					      - Bearer: []
 | 
				
			||||||
 | 
					      summary: 로그아웃
 | 
				
			||||||
 | 
					      tags:
 | 
				
			||||||
 | 
					      - 로그아웃
 | 
				
			||||||
  /auth/register:
 | 
					  /auth/register:
 | 
				
			||||||
    post:
 | 
					    post:
 | 
				
			||||||
      consumes:
 | 
					      consumes:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							@@ -14,6 +14,7 @@ require (
 | 
				
			|||||||
	golang.org/x/crypto v0.15.0
 | 
						golang.org/x/crypto v0.15.0
 | 
				
			||||||
	gorm.io/datatypes v1.2.0
 | 
						gorm.io/datatypes v1.2.0
 | 
				
			||||||
	gorm.io/driver/mysql v1.5.2
 | 
						gorm.io/driver/mysql v1.5.2
 | 
				
			||||||
 | 
						gorm.io/driver/sqlite v1.5.4
 | 
				
			||||||
	gorm.io/gorm v1.25.5
 | 
						gorm.io/gorm v1.25.5
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,6 +44,7 @@ require (
 | 
				
			|||||||
	github.com/leodido/go-urn v1.2.4 // indirect
 | 
						github.com/leodido/go-urn v1.2.4 // indirect
 | 
				
			||||||
	github.com/mailru/easyjson v0.7.7 // indirect
 | 
						github.com/mailru/easyjson v0.7.7 // indirect
 | 
				
			||||||
	github.com/mattn/go-isatty v0.0.20 // indirect
 | 
						github.com/mattn/go-isatty v0.0.20 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-sqlite3 v1.14.17 // indirect
 | 
				
			||||||
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
	github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
						github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
 | 
						github.com/pelletier/go-toml/v2 v2.1.0 // indirect
 | 
				
			||||||
@@ -56,11 +58,11 @@ require (
 | 
				
			|||||||
	golang.org/x/tools v0.15.0 // indirect
 | 
						golang.org/x/tools v0.15.0 // indirect
 | 
				
			||||||
	google.golang.org/protobuf v1.31.0 // indirect
 | 
						google.golang.org/protobuf v1.31.0 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
	gorm.io/driver/sqlite v1.5.4 // indirect
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/aws/aws-lambda-go v1.17.0 // indirect
 | 
						github.com/aws/aws-lambda-go v1.17.0 // indirect
 | 
				
			||||||
	github.com/gin-gonic/gin v1.9.1
 | 
						github.com/gin-gonic/gin v1.9.1
 | 
				
			||||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
						github.com/pkg/errors v0.9.1 // indirect
 | 
				
			||||||
 | 
						github.com/tj/assert v0.0.3
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,9 @@
 | 
				
			|||||||
package controllers
 | 
					package controllers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"learnsteam/cslms-api/internal/models"
 | 
						"learnsteam/cslms-api/internal/models"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/services"
 | 
						"learnsteam/cslms-api/internal/services"
 | 
				
			||||||
@@ -12,6 +14,7 @@ import (
 | 
				
			|||||||
type AuthController interface {
 | 
					type AuthController interface {
 | 
				
			||||||
	Register(*gin.Context)
 | 
						Register(*gin.Context)
 | 
				
			||||||
	Login(*gin.Context)
 | 
						Login(*gin.Context)
 | 
				
			||||||
 | 
						Logout(*gin.Context)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type authController struct {
 | 
					type authController struct {
 | 
				
			||||||
@@ -98,25 +101,47 @@ func (controller *authController) Login(c *gin.Context) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Logout
 | 
					// Logout 로그아웃
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// @Summary       로그아웃
 | 
				
			||||||
 | 
					// @Description   로그아웃하고 Token, Cookie 삭제
 | 
				
			||||||
 | 
					// @Tags          로그아웃
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// @Accept        json
 | 
				
			||||||
 | 
					// @Produce       json
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// @Security Bearer
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// @Router        /auth/logout [post]
 | 
				
			||||||
func (controller *authController) Logout(c *gin.Context) {
 | 
					func (controller *authController) Logout(c *gin.Context) {
 | 
				
			||||||
	token := c.GetHeader("Authorization")
 | 
						token, err := func() (*string, error) {
 | 
				
			||||||
	if token == "" {
 | 
							authorization := c.GetHeader("Authorization")
 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
 | 
							strArr := strings.Split(authorization, " ")
 | 
				
			||||||
		return
 | 
							if len(strArr) == 2 {
 | 
				
			||||||
 | 
								return &strArr[1], nil
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("invalid authorization header")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := controller.tokenService.Delete(token)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						user_id := c.GetInt64("sub")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = controller.tokenService.Invalid(user_id, *token)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.SetCookie("Authorization", "", -1, "/", "localhost", false, true)
 | 
						c.SetCookie("Authorization", "", -1, "/", "localhost", false, true)
 | 
				
			||||||
	c.SetCookie("RefreshToken", "", -1, "/", "localhost", false, true)
 | 
						c.SetCookie("RefreshToken", "", -1, "/", "localhost", false, true)
 | 
				
			||||||
	c.SetCookie("ExpiresAt", "", -1, "/", "localhost", false, true)
 | 
						c.SetCookie("ExpiresAt", "", -1, "/", "localhost", false, true)
 | 
				
			||||||
	c.SetCookie("RefreshExpiresAt", "", -1, "/", "localhost", false, true)
 | 
						c.SetCookie("RefreshExpiresAt", "", -1, "/", "localhost", false, true)
 | 
				
			||||||
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
 | 
						c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
 | 
				
			||||||
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
 | 
					
 | 
				
			||||||
	c.SetCookie("RefreshTokenExpiresAt", "", -1, "/", "localhost", false, true)
 | 
					 | 
				
			||||||
	c.JSON(http.StatusOK, gin.H{"message": "logout"})
 | 
						c.JSON(http.StatusOK, gin.H{"message": "logout"})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package controllers
 | 
					package controllers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@@ -11,6 +12,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
 | 
						"gorm.io/datatypes"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type QuizPaperController interface {
 | 
					type QuizPaperController interface {
 | 
				
			||||||
@@ -147,6 +149,12 @@ func (controller *quizPaperController) Create(c *gin.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	user_id := c.GetInt64("sub")
 | 
						user_id := c.GetInt64("sub")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var tag datatypes.JSON
 | 
				
			||||||
 | 
						tag, err := json.Marshal(request.Tag)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	quizPaper := &models.QuizPaper{
 | 
						quizPaper := &models.QuizPaper{
 | 
				
			||||||
		GUID:      uuid.NewString(),
 | 
							GUID:      uuid.NewString(),
 | 
				
			||||||
		CenterID:  request.CenterID,
 | 
							CenterID:  request.CenterID,
 | 
				
			||||||
@@ -154,7 +162,7 @@ func (controller *quizPaperController) Create(c *gin.Context) {
 | 
				
			|||||||
		Title:     request.Title,
 | 
							Title:     request.Title,
 | 
				
			||||||
		Content:   request.Content,
 | 
							Content:   request.Content,
 | 
				
			||||||
		Category:  request.Category,
 | 
							Category:  request.Category,
 | 
				
			||||||
		Tag:       request.Tag,
 | 
							Tag:       tag,
 | 
				
			||||||
		Status:    request.Status,
 | 
							Status:    request.Status,
 | 
				
			||||||
		CreatedAt: time.Now(),
 | 
							CreatedAt: time.Now(),
 | 
				
			||||||
		UpdatedAt: time.Now(),
 | 
							UpdatedAt: time.Now(),
 | 
				
			||||||
@@ -204,13 +212,20 @@ func (controller *quizPaperController) Update(c *gin.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var tag datatypes.JSON
 | 
				
			||||||
 | 
						tag, err = json.Marshal(request.Tag)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	user_id := c.GetInt64("sub")
 | 
						user_id := c.GetInt64("sub")
 | 
				
			||||||
	quizPaper.ManagerID = user_id
 | 
						quizPaper.ManagerID = user_id
 | 
				
			||||||
	quizPaper.CenterID = request.CenterID
 | 
						quizPaper.CenterID = request.CenterID
 | 
				
			||||||
	quizPaper.Title = request.Title
 | 
						quizPaper.Title = request.Title
 | 
				
			||||||
	quizPaper.Content = request.Content
 | 
						quizPaper.Content = request.Content
 | 
				
			||||||
	quizPaper.Category = request.Category
 | 
						quizPaper.Category = request.Category
 | 
				
			||||||
	quizPaper.Tag = request.Tag
 | 
						quizPaper.Tag = tag
 | 
				
			||||||
	quizPaper.Status = request.Status
 | 
						quizPaper.Status = request.Status
 | 
				
			||||||
	quizPaper.UpdatedAt = time.Now()
 | 
						quizPaper.UpdatedAt = time.Now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,18 +109,6 @@ func (controller *userController) Find(c *gin.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sub := c.GetString("sub")
 | 
					 | 
				
			||||||
	user_id, err := strconv.ParseInt(sub, 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if user_id != id {
 | 
					 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": "Wrong user"})
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result, err := controller.service.Find(id)
 | 
						result, err := controller.service.Find(id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -159,6 +159,7 @@ func (controller *userQuizController) Create(c *gin.Context) {
 | 
				
			|||||||
		CenterID:        request.CenterID,
 | 
							CenterID:        request.CenterID,
 | 
				
			||||||
		UserQuizPaperID: request.UserQuizPaperID,
 | 
							UserQuizPaperID: request.UserQuizPaperID,
 | 
				
			||||||
		No:              request.No,
 | 
							No:              request.No,
 | 
				
			||||||
 | 
							QuizID:          request.QuizID,
 | 
				
			||||||
		QuestionType:    request.QuestionType,
 | 
							QuestionType:    request.QuestionType,
 | 
				
			||||||
		Question:        request.Question,
 | 
							Question:        request.Question,
 | 
				
			||||||
		Content:         content,
 | 
							Content:         content,
 | 
				
			||||||
@@ -223,8 +224,29 @@ func (controller *userQuizController) Update(c *gin.Context) {
 | 
				
			|||||||
	// Result          string         `json:"result" example:"success"`
 | 
						// Result          string         `json:"result" example:"success"`
 | 
				
			||||||
	// Score           float32        `json:"score" example:"10"`
 | 
						// Score           float32        `json:"score" example:"10"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var content datatypes.JSON
 | 
				
			||||||
 | 
						content, err = json.Marshal(request.Content)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var answer datatypes.JSON
 | 
				
			||||||
 | 
						answer, err = json.Marshal([]string{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userquiz.CenterID = request.CenterID
 | 
						userquiz.CenterID = request.CenterID
 | 
				
			||||||
	userquiz.UserQuizPaperID = request.UserQuizPaperID
 | 
						userquiz.UserQuizPaperID = request.UserQuizPaperID
 | 
				
			||||||
 | 
						userquiz.No = request.No
 | 
				
			||||||
 | 
						userquiz.QuestionType = request.QuestionType
 | 
				
			||||||
 | 
						userquiz.Question = request.Question
 | 
				
			||||||
 | 
						userquiz.Content = content
 | 
				
			||||||
 | 
						userquiz.Answer = answer
 | 
				
			||||||
 | 
						userquiz.Status = request.Status
 | 
				
			||||||
 | 
						userquiz.Score = request.Score
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result, err := controller.service.Update(userquiz)
 | 
						result, err := controller.service.Update(userquiz)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
package controllers
 | 
					package controllers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
@@ -160,14 +159,14 @@ func (controller *userQuizPaperController) Create(c *gin.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var users []int64
 | 
						// var users []int64
 | 
				
			||||||
	err = json.Unmarshal(request.Users, &users)
 | 
						// err = json.Unmarshal(request.Users, &users)
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
						// 	c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
		return
 | 
						// 	return
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	templates := controller.service.Generate(users, quizPaper)
 | 
						templates := controller.service.Generate(request.Users, quizPaper)
 | 
				
			||||||
	userQuizPapers, err := controller.service.Insert(templates)
 | 
						userQuizPapers, err := controller.service.Insert(templates)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
							c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,8 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	config "learnsteam/cslms-api/configs"
 | 
						config "learnsteam/cslms-api/configs"
 | 
				
			||||||
 | 
						"learnsteam/cslms-api/internal/database"
 | 
				
			||||||
 | 
						"learnsteam/cslms-api/internal/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-gonic/gin"
 | 
						"github.com/gin-gonic/gin"
 | 
				
			||||||
	"github.com/golang-jwt/jwt/v5"
 | 
						"github.com/golang-jwt/jwt/v5"
 | 
				
			||||||
@@ -35,10 +37,14 @@ func Auth(permission string) gin.HandlerFunc {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fmt.Println("token", extract(c.Request))
 | 
							valid := Valid(c.Request)
 | 
				
			||||||
		fmt.Println("sub", sub)
 | 
							if !valid {
 | 
				
			||||||
 | 
								c.JSON(http.StatusUnauthorized, gin.H{"error": "token is not valid"})
 | 
				
			||||||
 | 
								c.Abort()
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c.Set("token", extract(c.Request))
 | 
							c.Set("token", Extract(c.Request))
 | 
				
			||||||
		c.Set("sub", sub)
 | 
							c.Set("sub", sub)
 | 
				
			||||||
		c.Set("role", role)
 | 
							c.Set("role", role)
 | 
				
			||||||
		c.Next()
 | 
							c.Next()
 | 
				
			||||||
@@ -67,17 +73,21 @@ func Permission(permission *string) gin.HandlerFunc {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fmt.Println("token", extract(c.Request))
 | 
							valid := Valid(c.Request)
 | 
				
			||||||
		fmt.Println("sub", sub)
 | 
							if !valid {
 | 
				
			||||||
 | 
								c.JSON(http.StatusUnauthorized, gin.H{"error": "token is not valid"})
 | 
				
			||||||
 | 
								c.Abort()
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		c.Set("token", extract(c.Request))
 | 
							c.Set("token", Extract(c.Request))
 | 
				
			||||||
		c.Set("sub", sub)
 | 
							c.Set("sub", sub)
 | 
				
			||||||
		c.Set("role", role)
 | 
							c.Set("role", role)
 | 
				
			||||||
		c.Next()
 | 
							c.Next()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func extract(r *http.Request) string {
 | 
					func Extract(r *http.Request) string {
 | 
				
			||||||
	authorization := r.Header.Get("Authorization")
 | 
						authorization := r.Header.Get("Authorization")
 | 
				
			||||||
	strArr := strings.Split(authorization, " ")
 | 
						strArr := strings.Split(authorization, " ")
 | 
				
			||||||
	if len(strArr) == 2 {
 | 
						if len(strArr) == 2 {
 | 
				
			||||||
@@ -86,8 +96,8 @@ func extract(r *http.Request) string {
 | 
				
			|||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func verify(r *http.Request) (*jwt.Token, error) {
 | 
					func Verify(r *http.Request) (*jwt.Token, error) {
 | 
				
			||||||
	tokenString := extract(r)
 | 
						tokenString := Extract(r)
 | 
				
			||||||
	jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
 | 
						jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
 | 
				
			||||||
		if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
							if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
				
			||||||
			return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
 | 
								return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
 | 
				
			||||||
@@ -99,8 +109,9 @@ func verify(r *http.Request) (*jwt.Token, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UserID(r *http.Request) (int64, error) {
 | 
					func UserID(r *http.Request) (int64, error) {
 | 
				
			||||||
	jwtToken, err := verify(r)
 | 
						jwtToken, err := Verify(r)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
		return -1, err
 | 
							return -1, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,7 +131,7 @@ func UserID(r *http.Request) (int64, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Role(r *http.Request) (*string, error) {
 | 
					func Role(r *http.Request) (*string, error) {
 | 
				
			||||||
	jwtToken, err := verify(r)
 | 
						jwtToken, err := Verify(r)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -134,3 +145,12 @@ func Role(r *http.Request) (*string, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return &role, nil
 | 
						return &role, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Valid(r *http.Request) bool {
 | 
				
			||||||
 | 
						tokenString := Extract(r)
 | 
				
			||||||
 | 
						var token models.Token
 | 
				
			||||||
 | 
						fmt.Println(tokenString)
 | 
				
			||||||
 | 
						err := database.DB.Where("token = ? AND status = ?", tokenString, "on").First(&token).Error
 | 
				
			||||||
 | 
						fmt.Println(&token)
 | 
				
			||||||
 | 
						return err == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,21 +4,6 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CREATE TABLE `Centers` (
 | 
					 | 
				
			||||||
//   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 | 
					 | 
				
			||||||
//   `guid_id` varchar(36) DEFAULT '',
 | 
					 | 
				
			||||||
//   `center_title` varchar(50) DEFAULT '' COMMENT '강동런스팀로봇코딩학원',
 | 
					 | 
				
			||||||
//   `center_name` varchar(50) DEFAULT '' COMMENT 'learnsteam_kd',
 | 
					 | 
				
			||||||
//   `owner_id` bigint(20) DEFAULT 0,
 | 
					 | 
				
			||||||
//   `content_page` text DEFAULT '' COMMENT '학원상세페이지, html/마크다운/text',
 | 
					 | 
				
			||||||
//   `company_info` text DEFAULT '' COMMENT '사업자정보-json\r\n기타 정보 추가 가능\r\n\r\n{\r\n  "company_ceo": "대표자이름",\r\n  "company_code": "사업자번호",\r\n  "company_phone": "대표전화번호",\r\n  "company_email": "대표전자메일",\r\n  "company_homepage": "대표홈페이지 url",\r\n  "company_logo": "로고이미지 url",\r\n  "company_cover_image": "대표 이미지", \r\n}',
 | 
					 | 
				
			||||||
//   `memo` varchar(256) DEFAULT '',
 | 
					 | 
				
			||||||
//   `created_at` timestamp NULL DEFAULT current_timestamp(),
 | 
					 | 
				
			||||||
//   `updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 | 
					 | 
				
			||||||
//   `status` varchar(10) DEFAULT NULL,
 | 
					 | 
				
			||||||
//   PRIMARY KEY (`id`)
 | 
					 | 
				
			||||||
// ) ENGINE=InnoDB AUTO_INCREMENT=1000005 DEFAULT CHARSET=utf8mb4 COMMENT='Centers의 이미지/영상은 Links에서 관리됨. ';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Center struct {
 | 
					type Center struct {
 | 
				
			||||||
	ID        int64     `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
						ID        int64     `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
				
			||||||
	GUID      string    `json:"guid_id" db:"guid_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6" gorm:"column:guid_id;size:255;index;"`
 | 
						GUID      string    `json:"guid_id" db:"guid_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6" gorm:"column:guid_id;size:255;index;"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ type QuizResponse struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type QuizListResponse struct {
 | 
					type QuizListResponse struct {
 | 
				
			||||||
	Data      []Quiz `json:"data"`
 | 
						Data      []QuizResponse `json:"data"`
 | 
				
			||||||
	Total     int64          `json:"total" example:"5"`
 | 
						Total     int64          `json:"total" example:"5"`
 | 
				
			||||||
	Page      int            `json:"page" example:"1"`
 | 
						Page      int            `json:"page" example:"1"`
 | 
				
			||||||
	TotalPage int64          `json:"totalPage" example:"1"`
 | 
						TotalPage int64          `json:"totalPage" example:"1"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,24 +6,6 @@ import (
 | 
				
			|||||||
	"gorm.io/datatypes"
 | 
						"gorm.io/datatypes"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CREATE TABLE `QuizPapers` (
 | 
					 | 
				
			||||||
//   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 | 
					 | 
				
			||||||
//   `guid_id` char(36) NOT NULL DEFAULT '0',
 | 
					 | 
				
			||||||
//   `center_id` bigint(20) NOT NULL DEFAULT 0,
 | 
					 | 
				
			||||||
//   `manager_id` bigint(20) NOT NULL DEFAULT 0,
 | 
					 | 
				
			||||||
//   `title` varchar(256) NOT NULL DEFAULT '' COMMENT '퀴즈시트 제목',
 | 
					 | 
				
			||||||
//   `status` varchar(10) NOT NULL DEFAULT '0' COMMENT 'on/off',
 | 
					 | 
				
			||||||
//   `content` text NOT NULL DEFAULT '' COMMENT 'markdown 문서',
 | 
					 | 
				
			||||||
//   `tags` varchar(256) NOT NULL DEFAULT '' COMMENT '출력,hello world,for반복문...',
 | 
					 | 
				
			||||||
//   `category` varchar(256) NOT NULL DEFAULT '파이썬기본',
 | 
					 | 
				
			||||||
//   `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
 | 
					 | 
				
			||||||
//   `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 | 
					 | 
				
			||||||
//   PRIMARY KEY (`id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `guid_id` (`guid_id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `center_id` (`center_id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `manager_id` (`manager_id`) USING BTREE
 | 
					 | 
				
			||||||
// ) ENGINE=InnoDB AUTO_INCREMENT=10000001 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='퀴즈시험지 관리 테이블\r\n\r\n';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type QuizPaper struct {
 | 
					type QuizPaper struct {
 | 
				
			||||||
	ID        int64          `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
						ID        int64          `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
				
			||||||
	GUID      string         `json:"guid_id" db:"guid_id" example:"ef74c59a-c707-4162-a52b-455906c81ec1" gorm:"column:guid_id;size:255;index;"`
 | 
						GUID      string         `json:"guid_id" db:"guid_id" example:"ef74c59a-c707-4162-a52b-455906c81ec1" gorm:"column:guid_id;size:255;index;"`
 | 
				
			||||||
@@ -48,7 +30,7 @@ type QuizPaperRequest struct {
 | 
				
			|||||||
	Title    string   `json:"title" example:"퀴즈 시트 제목"`
 | 
						Title    string   `json:"title" example:"퀴즈 시트 제목"`
 | 
				
			||||||
	Content  string   `json:"content" example:"퀴즈 시트 설명"`
 | 
						Content  string   `json:"content" example:"퀴즈 시트 설명"`
 | 
				
			||||||
	Category string   `json:"category" example:"파이썬기본"`
 | 
						Category string   `json:"category" example:"파이썬기본"`
 | 
				
			||||||
	Tag      datatypes.JSON `json:"tag"`
 | 
						Tag      []string `json:"tag" example:"Python,AI,Robot,파이썬"`
 | 
				
			||||||
	Status   string   `json:"status" example:"on"`
 | 
						Status   string   `json:"status" example:"on"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,7 +41,7 @@ type QuizPaperResponse struct {
 | 
				
			|||||||
	Title     string   `json:"title" example:"퀴즈 시트 제목"`
 | 
						Title     string   `json:"title" example:"퀴즈 시트 제목"`
 | 
				
			||||||
	Content   string   `json:"content" example:"퀴즈 시트 설명"`
 | 
						Content   string   `json:"content" example:"퀴즈 시트 설명"`
 | 
				
			||||||
	Category  string   `json:"category" example:"파이썬기본"`
 | 
						Category  string   `json:"category" example:"파이썬기본"`
 | 
				
			||||||
	Tag       datatypes.JSON `json:"tag"`
 | 
						Tag       []string `json:"tag" example:"Python,AI,Robot,파이썬"`
 | 
				
			||||||
	Status    string   `json:"status" example:"on"`
 | 
						Status    string   `json:"status" example:"on"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,17 +2,6 @@ package models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "time"
 | 
					import "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CREATE TABLE `UserTokens` (
 | 
					 | 
				
			||||||
//   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 | 
					 | 
				
			||||||
//   `user_id` bigint(20) DEFAULT 0,
 | 
					 | 
				
			||||||
//   `token` varchar(256) DEFAULT '',
 | 
					 | 
				
			||||||
//   `refresh_token` varchar(256) DEFAULT '',
 | 
					 | 
				
			||||||
//   `status` varchar(3) DEFAULT 'on' COMMENT 'on/off',
 | 
					 | 
				
			||||||
//   `register_at` timestamp NULL DEFAULT current_timestamp(),
 | 
					 | 
				
			||||||
//   `ending_at` timestamp NULL DEFAULT NULL COMMENT '종료날짜',
 | 
					 | 
				
			||||||
//   PRIMARY KEY (`id`) USING BTREE
 | 
					 | 
				
			||||||
// ) ENGINE=InnoDB AUTO_INCREMENT=1000017 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Token struct {
 | 
					type Token struct {
 | 
				
			||||||
	ID           int64  `json:"-" db:"id" gorm:"primary_key"`
 | 
						ID           int64  `json:"-" db:"id" gorm:"primary_key"`
 | 
				
			||||||
	UserID       int64  `json:"user_id" db:"user_id" gorm:"index;"`
 | 
						UserID       int64  `json:"user_id" db:"user_id" gorm:"index;"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,27 +2,6 @@ package models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import "time"
 | 
					import "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CREATE TABLE `Users` (
 | 
					 | 
				
			||||||
//   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 | 
					 | 
				
			||||||
//   `guid_id` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `first_name` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `last_name` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `user_name` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `password` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `gender` char(1) DEFAULT 'M' COMMENT 'M(남)/F(여)',
 | 
					 | 
				
			||||||
//   `user_role` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `memo_cs` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `register_at` datetime(3) DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '업데이트될때마다 자동저장',
 | 
					 | 
				
			||||||
//   `phone_cs` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   `upload_image` longtext DEFAULT NULL,
 | 
					 | 
				
			||||||
//   PRIMARY KEY (`id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `guid_id` (`guid_id`(768)),
 | 
					 | 
				
			||||||
//   KEY `first_name` (`first_name`(768)),
 | 
					 | 
				
			||||||
//   KEY `last_name` (`last_name`(768)),
 | 
					 | 
				
			||||||
//   KEY `user_name` (`user_name`(768))
 | 
					 | 
				
			||||||
// ) ENGINE=InnoDB AUTO_INCREMENT=1000023 DEFAULT CHARSET=utf8mb4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type User struct {
 | 
					type User struct {
 | 
				
			||||||
	ID         int64     `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
						ID         int64     `json:"id" db:"id" example:"100001" gorm:"column:id;primary_key;"`
 | 
				
			||||||
	GUID       string    `json:"guid_id" db:"guid_id" example:"137c1683-2ad6-4201-b256-253828b61c49" gorm:"column:guid_id;size:255;"`
 | 
						GUID       string    `json:"guid_id" db:"guid_id" example:"137c1683-2ad6-4201-b256-253828b61c49" gorm:"column:guid_id;size:255;"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ type UserQuiz struct {
 | 
				
			|||||||
	CenterID        int64          `json:"center_id" db:"center_id" example:"100001" gorm:"column:center_id;index;"`
 | 
						CenterID        int64          `json:"center_id" db:"center_id" example:"100001" gorm:"column:center_id;index;"`
 | 
				
			||||||
	UserQuizPaperID int64          `json:"user_quiz_paper_id" db:"user_quiz_paper_id" example:"1000001" gorm:"column:user_quiz_paper_id;index;"`
 | 
						UserQuizPaperID int64          `json:"user_quiz_paper_id" db:"user_quiz_paper_id" example:"1000001" gorm:"column:user_quiz_paper_id;index;"`
 | 
				
			||||||
	UserID          int64          `json:"user_id" db:"user_id" example:"1000001" gorm:"column:user_id;index;"`
 | 
						UserID          int64          `json:"user_id" db:"user_id" example:"1000001" gorm:"column:user_id;index;"`
 | 
				
			||||||
 | 
						QuizID          int64          `json:"quiz_id" db:"quiz_id" example:"1000001" gorm:"column:quiz_id;index;"`
 | 
				
			||||||
	No              int            `json:"vol_no" db:"vol_no" example:"5" gorm:"column:vol_no;index;"`
 | 
						No              int            `json:"vol_no" db:"vol_no" example:"5" gorm:"column:vol_no;index;"`
 | 
				
			||||||
	QuestionType    string         `json:"question_type" db:"question_type" example:"choice" gorm:"column:question_type;size:10;index;"`
 | 
						QuestionType    string         `json:"question_type" db:"question_type" example:"choice" gorm:"column:question_type;size:10;index;"`
 | 
				
			||||||
	Question        string         `json:"question" db:"question" example:"퀴즈 질문입니다." gorm:"column:question;size:512;"`
 | 
						Question        string         `json:"question" db:"question" example:"퀴즈 질문입니다." gorm:"column:question;size:512;"`
 | 
				
			||||||
@@ -33,6 +34,7 @@ type UserQuizRequest struct {
 | 
				
			|||||||
	CenterID        int64       `json:"center_id" example:"1000001"`
 | 
						CenterID        int64       `json:"center_id" example:"1000001"`
 | 
				
			||||||
	UserQuizPaperID int64       `json:"quiz_paper_id" example:"1000001"`
 | 
						UserQuizPaperID int64       `json:"quiz_paper_id" example:"1000001"`
 | 
				
			||||||
	UserID          int64       `json:"user_id" example:"1000001"`
 | 
						UserID          int64       `json:"user_id" example:"1000001"`
 | 
				
			||||||
 | 
						QuizID          int64       `json:"quiz_id" example:"1000001"`
 | 
				
			||||||
	No              int         `json:"vol_no" example:"1"`
 | 
						No              int         `json:"vol_no" example:"1"`
 | 
				
			||||||
	QuestionType    string      `json:"question_type" example:"choice"`
 | 
						QuestionType    string      `json:"question_type" example:"choice"`
 | 
				
			||||||
	Question        string      `json:"question" example:"질문입니다."`
 | 
						Question        string      `json:"question" example:"질문입니다."`
 | 
				
			||||||
@@ -49,6 +51,7 @@ type UserQuizResponse struct {
 | 
				
			|||||||
	CenterD         string      `json:"center_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6"`
 | 
						CenterD         string      `json:"center_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6"`
 | 
				
			||||||
	UserQuizPaperID int64       `json:"user_quiz_paper_id" example:"1000001"`
 | 
						UserQuizPaperID int64       `json:"user_quiz_paper_id" example:"1000001"`
 | 
				
			||||||
	UserID          int64       `json:"user_id" example:"1000001"`
 | 
						UserID          int64       `json:"user_id" example:"1000001"`
 | 
				
			||||||
 | 
						QuizID          int64       `json:"quiz_id" example:"1000001"`
 | 
				
			||||||
	No              int         `json:"vol_no" example:"5"`
 | 
						No              int         `json:"vol_no" example:"5"`
 | 
				
			||||||
	QuestionType    string      `json:"question_type" example:"check"`
 | 
						QuestionType    string      `json:"question_type" example:"check"`
 | 
				
			||||||
	Question        string      `json:"question" example:"퀴즈 질문입니다."`
 | 
						Question        string      `json:"question" example:"퀴즈 질문입니다."`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,30 +2,8 @@ package models
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"gorm.io/datatypes"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CREATE TABLE `UserQuizPapers` (
 | 
					 | 
				
			||||||
//   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 | 
					 | 
				
			||||||
//   `guid_id` char(36) NOT NULL DEFAULT '0',
 | 
					 | 
				
			||||||
//   `center_id` bigint(20) NOT NULL DEFAULT 0,
 | 
					 | 
				
			||||||
//   `quiz_paper_id` bigint(20) NOT NULL DEFAULT 0,
 | 
					 | 
				
			||||||
//   `status` varchar(10) NOT NULL DEFAULT '0' COMMENT '매칭된 학생퀴즈시험지 상태: \r\nwaiting(대기)/processing(시험진행중)/abort(취소)/marking(채점중)/done(완료) ',
 | 
					 | 
				
			||||||
//   `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '매칭된 학생',
 | 
					 | 
				
			||||||
//   `user_score` float NOT NULL DEFAULT 5 COMMENT '10',
 | 
					 | 
				
			||||||
//   `total_score` float NOT NULL DEFAULT 100 COMMENT '100.0, 5.0',
 | 
					 | 
				
			||||||
//   `start_at` timestamp NULL DEFAULT NULL COMMENT '학생시험시작시각',
 | 
					 | 
				
			||||||
//   `done_at` timestamp NULL DEFAULT NULL COMMENT '학생시험종료시각',
 | 
					 | 
				
			||||||
//   `created_at` timestamp NOT NULL DEFAULT current_timestamp(),
 | 
					 | 
				
			||||||
//   `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 | 
					 | 
				
			||||||
//   PRIMARY KEY (`id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `guid_id` (`guid_id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `center_id` (`center_id`) USING BTREE,
 | 
					 | 
				
			||||||
//   KEY `user_id` (`user_id`),
 | 
					 | 
				
			||||||
//   KEY `manager_id` (`quiz_paper_id`) USING BTREE
 | 
					 | 
				
			||||||
// ) ENGINE=InnoDB AUTO_INCREMENT=10000001 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='학생퀴즈시험지 매칭\r\n';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type UserQuizPaper struct {
 | 
					type UserQuizPaper struct {
 | 
				
			||||||
	ID          int64      `json:"id" db:"id" example:"1000015" gorm:"column:id;primary_key;"`
 | 
						ID          int64      `json:"id" db:"id" example:"1000015" gorm:"column:id;primary_key;"`
 | 
				
			||||||
	GUID        string     `json:"guid_id" db:"guid_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4" gorm:"column:guid_id;size:255;uniqueIndex"`
 | 
						GUID        string     `json:"guid_id" db:"guid_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4" gorm:"column:guid_id;size:255;uniqueIndex"`
 | 
				
			||||||
@@ -48,7 +26,7 @@ func (UserQuizPaper) TableName() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type UserQuizPaperRequest struct {
 | 
					type UserQuizPaperRequest struct {
 | 
				
			||||||
	QuizPaperID int64   `json:"quiz_paper_id" example:"1000002"`
 | 
						QuizPaperID int64   `json:"quiz_paper_id" example:"1000002"`
 | 
				
			||||||
	Users       datatypes.JSON `json:"users"`
 | 
						Users       []int64 `json:"users" example:"1000001,1000002,1000003,1000004"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UserQuizPaperResponse struct {
 | 
					type UserQuizPaperResponse struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ type TokenRepository interface {
 | 
				
			|||||||
	Create(*models.Token) (*models.Token, error)
 | 
						Create(*models.Token) (*models.Token, error)
 | 
				
			||||||
	Update(*models.Token) (*models.Token, error)
 | 
						Update(*models.Token) (*models.Token, error)
 | 
				
			||||||
	Delete(string) error
 | 
						Delete(string) error
 | 
				
			||||||
 | 
						Invalid(int64, string) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *tokenRepository) Generate(user_id int64, expire_at int64, role string) (string, error) {
 | 
					func (s *tokenRepository) Generate(user_id int64, expire_at int64, role string) (string, error) {
 | 
				
			||||||
@@ -69,6 +70,11 @@ func (r *tokenRepository) Update(token *models.Token) (*models.Token, error) {
 | 
				
			|||||||
	return row, err
 | 
						return row, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *tokenRepository) Invalid(user_id int64, tokenString string) error {
 | 
				
			||||||
 | 
						err := r.DB.Model(&models.Token{}).Where("user_id = ? AND token = ?", user_id, tokenString).Update("status", "off").Error
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *tokenRepository) Delete(id string) error {
 | 
					func (r *tokenRepository) Delete(id string) error {
 | 
				
			||||||
	var token *models.Token
 | 
						var token *models.Token
 | 
				
			||||||
	if err := r.DB.Where("id=?", id).First(&token).Error; err != nil {
 | 
						if err := r.DB.Where("id=?", id).First(&token).Error; err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
package repositories
 | 
					package repositories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"learnsteam/cslms-api/internal/models"
 | 
						"learnsteam/cslms-api/internal/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"gorm.io/gorm/clause"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type userQuizRepository struct {
 | 
					type userQuizRepository struct {
 | 
				
			||||||
@@ -64,8 +64,7 @@ func (r *userQuizRepository) Create(row *models.UserQuiz) (*models.UserQuiz, err
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *userQuizRepository) Insert(items []models.UserQuiz) ([]models.UserQuiz, error) {
 | 
					func (r *userQuizRepository) Insert(items []models.UserQuiz) ([]models.UserQuiz, error) {
 | 
				
			||||||
	fmt.Println(items)
 | 
						err := r.DB.Clauses(clause.OnConflict{DoNothing: true}).Create(&items).Error
 | 
				
			||||||
	err := r.DB.Create(&items).Error
 | 
					 | 
				
			||||||
	return items, err
 | 
						return items, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"learnsteam/cslms-api/internal/models"
 | 
						"learnsteam/cslms-api/internal/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"gorm.io/gorm/clause"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type userQuizPaperRepository struct {
 | 
					type userQuizPaperRepository struct {
 | 
				
			||||||
@@ -63,7 +64,7 @@ func (r *userQuizPaperRepository) Create(userQuizPaper *models.UserQuizPaper) (*
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *userQuizPaperRepository) Insert(items []models.UserQuizPaper) ([]models.UserQuizPaper, error) {
 | 
					func (r *userQuizPaperRepository) Insert(items []models.UserQuizPaper) ([]models.UserQuizPaper, error) {
 | 
				
			||||||
	err := r.DB.Create(&items).Error
 | 
						err := r.DB.Clauses(clause.OnConflict{DoNothing: true}).Create(&items).Error
 | 
				
			||||||
	return items, err
 | 
						return items, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package routers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"learnsteam/cslms-api/internal/controllers"
 | 
						"learnsteam/cslms-api/internal/controllers"
 | 
				
			||||||
 | 
						"learnsteam/cslms-api/internal/middleware"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/repositories"
 | 
						"learnsteam/cslms-api/internal/repositories"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/services"
 | 
						"learnsteam/cslms-api/internal/services"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,4 +51,5 @@ func (r *authRouter) SetAuthRouter() {
 | 
				
			|||||||
	group := r.router.Group("/auth")
 | 
						group := r.router.Group("/auth")
 | 
				
			||||||
	group.POST("login", r.controller.Login)
 | 
						group.POST("login", r.controller.Login)
 | 
				
			||||||
	group.POST("register", r.controller.Register)
 | 
						group.POST("register", r.controller.Register)
 | 
				
			||||||
 | 
						group.POST("logout", middleware.Auth("member"), r.controller.Logout)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package routers
 | 
					package routers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						configs "learnsteam/cslms-api/configs"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/database"
 | 
						"learnsteam/cslms-api/internal/database"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gin-contrib/cors"
 | 
						"github.com/gin-contrib/cors"
 | 
				
			||||||
@@ -10,10 +11,11 @@ import (
 | 
				
			|||||||
var Router *gin.Engine
 | 
					var Router *gin.Engine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Init() {
 | 
					func Init() {
 | 
				
			||||||
	gin.SetMode(gin.ReleaseMode)
 | 
						gin.SetMode(configs.MODE)
 | 
				
			||||||
	Router = gin.Default()
 | 
						Router = gin.Default()
 | 
				
			||||||
	config := cors.DefaultConfig()
 | 
						config := cors.DefaultConfig()
 | 
				
			||||||
	config.AllowOrigins = []string{"http://127.0.0.1:3000", "http://localhost:3000", "http://localhost:3030", "https://learnsteam-quiz.jongyeob.com"}
 | 
					
 | 
				
			||||||
 | 
						config.AllowOrigins = []string{"http://127.0.0.1:3000", "http://localhost:3000", "http://localhost:3030", "https://cslms-api.codingschool.co.kr"}
 | 
				
			||||||
	config.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "PATCH"}
 | 
						config.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "PATCH"}
 | 
				
			||||||
	config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type"}
 | 
						config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type"}
 | 
				
			||||||
	Router.Use(cors.New(config))
 | 
						Router.Use(cors.New(config))
 | 
				
			||||||
@@ -21,6 +23,7 @@ func Init() {
 | 
				
			|||||||
	maindb := database.GetDB()
 | 
						maindb := database.GetDB()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	InitAuthRouter(maindb, Router)
 | 
						InitAuthRouter(maindb, Router)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	InitCenterRouter(maindb, Router)
 | 
						InitCenterRouter(maindb, Router)
 | 
				
			||||||
	InitQuizPaperRouter(maindb, Router)
 | 
						InitQuizPaperRouter(maindb, Router)
 | 
				
			||||||
	InitQuizRouter(maindb, Router)
 | 
						InitQuizRouter(maindb, Router)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,9 @@ type TokenService interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Refresh(string) (*models.Token, error)
 | 
						Refresh(string) (*models.Token, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Generate(string, int64, string) (string, error)
 | 
						Generate(int64, int64, string) (string, error)
 | 
				
			||||||
	Verify(tokenString string) (*jwt.Token, error)
 | 
						Verify(string) (*jwt.Token, error)
 | 
				
			||||||
 | 
						Invalid(int64, string) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GetJwtToken(string) (*jwt.Token, error)
 | 
						GetJwtToken(string) (*jwt.Token, error)
 | 
				
			||||||
	ExtractTokenString(string) string
 | 
						ExtractTokenString(string) string
 | 
				
			||||||
@@ -90,7 +91,12 @@ func (s *tokenService) Verify(tokenString string) (*jwt.Token, error) {
 | 
				
			|||||||
	return jwtToken, err
 | 
						return jwtToken, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *tokenService) Generate(user_id string, expire_at int64, role string) (string, error) {
 | 
					func (s *tokenService) Invalid(user_id int64, tokenString string) error {
 | 
				
			||||||
 | 
						err := s.repository.Invalid(user_id, tokenString)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *tokenService) Generate(user_id int64, expire_at int64, role string) (string, error) {
 | 
				
			||||||
	claims := jwt.MapClaims{}
 | 
						claims := jwt.MapClaims{}
 | 
				
			||||||
	claims["authorized"] = true
 | 
						claims["authorized"] = true
 | 
				
			||||||
	claims["sub"] = user_id
 | 
						claims["sub"] = user_id
 | 
				
			||||||
@@ -153,14 +159,6 @@ func (s *tokenService) Refresh(refreshToken string) (*models.Token, error) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("refresh token is not valid")
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fmt.Println("refresh token is  valid")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Println("error", err.Error())
 | 
					 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -173,6 +171,7 @@ func (s *tokenService) Refresh(refreshToken string) (*models.Token, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errors.New("wrong user")
 | 
							return nil, errors.New("wrong user")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	role := claims["role"].(string)
 | 
						role := claims["role"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	token, err := s.repository.FindByRefreshToken(sub, refreshToken)
 | 
						token, err := s.repository.FindByRefreshToken(sub, refreshToken)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,7 @@ func (s *userQuizService) Generate(quiz_paper_id int64, userQuizPaper *models.Us
 | 
				
			|||||||
			UserQuizPaperID: userQuizPaper.ID,
 | 
								UserQuizPaperID: userQuizPaper.ID,
 | 
				
			||||||
			UserID:          userQuizPaper.UserID,
 | 
								UserID:          userQuizPaper.UserID,
 | 
				
			||||||
			No:              quiz.No,
 | 
								No:              quiz.No,
 | 
				
			||||||
 | 
								QuizID:          quiz.ID,
 | 
				
			||||||
			QuestionType:    quiz.QuestionType,
 | 
								QuestionType:    quiz.QuestionType,
 | 
				
			||||||
			Question:        quiz.Question,
 | 
								Question:        quiz.Question,
 | 
				
			||||||
			Content:         quiz.Content,
 | 
								Content:         quiz.Content,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,11 @@ package learsteam_quiz_test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"learnsteam/cslms-api/internal/controllers"
 | 
						"learnsteam/cslms-api/internal/controllers"
 | 
				
			||||||
 | 
						"learnsteam/cslms-api/internal/models"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/repositories"
 | 
						"learnsteam/cslms-api/internal/repositories"
 | 
				
			||||||
	"learnsteam/cslms-api/internal/services"
 | 
						"learnsteam/cslms-api/internal/services"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/suite"
 | 
						"github.com/stretchr/testify/suite"
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
@@ -36,7 +39,7 @@ type QuizTestSuite struct {
 | 
				
			|||||||
// 	suite.repository = repository
 | 
					// 	suite.repository = repository
 | 
				
			||||||
// 	suite.controller = controller
 | 
					// 	suite.controller = controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	suite.CreateSampleData()
 | 
					// 	// suite.CreateSampleData()
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *QuizTestSuite) CreateSampleData() {
 | 
					// func (suite *QuizTestSuite) CreateSampleData() {
 | 
				
			||||||
@@ -68,26 +71,26 @@ type QuizTestSuite struct {
 | 
				
			|||||||
// 	}
 | 
					// 	}
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *QuizTestSuite) TearDownSuite() {
 | 
					func (suite *QuizTestSuite) TearDownSuite() {
 | 
				
			||||||
// 	// DB 삭제
 | 
						// DB 삭제
 | 
				
			||||||
// 	suite.db.Migrator().DropTable(&models.Quiz{})
 | 
						suite.db.Migrator().DropTable(&models.Quiz{})
 | 
				
			||||||
// 	err := os.Remove("test.db")
 | 
						err := os.Remove("test.db")
 | 
				
			||||||
// 	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
// 		suite.Fail("Failed to remove the test database file")
 | 
							suite.Fail("Failed to remove the test database file")
 | 
				
			||||||
// 	}
 | 
						}
 | 
				
			||||||
// }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *QuizTestSuite) SetupTest() {
 | 
					func (suite *QuizTestSuite) SetupTest() {
 | 
				
			||||||
	// suite.CreateSampleData()
 | 
						// suite.CreateSampleData()
 | 
				
			||||||
// }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *QuizTestSuite) TearDownTest() {
 | 
					func (suite *QuizTestSuite) TearDownTest() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func TestQuizSuite(t *testing.T) {
 | 
					func TestQuizSuite(t *testing.T) {
 | 
				
			||||||
// 	suite.Run(t, new(QuizTestSuite))
 | 
						suite.Run(t, new(QuizTestSuite))
 | 
				
			||||||
// }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// // 목록 테스트
 | 
					// // 목록 테스트
 | 
				
			||||||
// func (suite *QuizTestSuite) TestListQuizSuccess() {
 | 
					// func (suite *QuizTestSuite) TestListQuizSuccess() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +1,49 @@
 | 
				
			|||||||
package learsteam_quiz_test
 | 
					package learsteam_quiz_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// type TokenTestSuite struct {
 | 
					import (
 | 
				
			||||||
// 	suite.Suite
 | 
						"fmt"
 | 
				
			||||||
// 	db         *gorm.DB
 | 
						config "learnsteam/cslms-api/configs"
 | 
				
			||||||
// 	repository repositories.TokenRepository
 | 
						"learnsteam/cslms-api/internal/controllers"
 | 
				
			||||||
// 	service    services.TokenService
 | 
						"learnsteam/cslms-api/internal/repositories"
 | 
				
			||||||
// 	controller controllers.TokenController
 | 
						"learnsteam/cslms-api/internal/services"
 | 
				
			||||||
// }
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *TokenTestSuite) SetupSuite() {
 | 
						"github.com/golang-jwt/jwt/v5"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/suite"
 | 
				
			||||||
 | 
						"github.com/tj/assert"
 | 
				
			||||||
 | 
						"gorm.io/driver/sqlite"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"gorm.io/gorm/schema"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TokenTestSuite struct {
 | 
				
			||||||
 | 
						suite.Suite
 | 
				
			||||||
 | 
						db         *gorm.DB
 | 
				
			||||||
 | 
						repository repositories.TokenRepository
 | 
				
			||||||
 | 
						service    services.TokenService
 | 
				
			||||||
 | 
						controller controllers.TokenController
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *TokenTestSuite) SetupSuite() {
 | 
				
			||||||
	// err := os.Remove("test.db")
 | 
						// err := os.Remove("test.db")
 | 
				
			||||||
	// if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
	// 	suite.Fail("Failed to remove the test database file")
 | 
						// 	suite.Fail("Failed to remove the test database file")
 | 
				
			||||||
	// }
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	database.Init()
 | 
						gorm_config := gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}}
 | 
				
			||||||
// 	gorm_config := gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}}
 | 
						db, _ := gorm.Open(sqlite.Open("test.db"), &gorm_config)
 | 
				
			||||||
// 	db, _ := gorm.Open(sqlite.Open("test.db"), &gorm_config)
 | 
						repository := repositories.NewTokenRepository(db)
 | 
				
			||||||
// 	repository := repositories.NewTokenRepository(db)
 | 
						service := services.NewTokenService(repository)
 | 
				
			||||||
// 	service := services.NewTokenService(repository)
 | 
						controller := controllers.NewTokenController(service)
 | 
				
			||||||
// 	controller := controllers.NewTokenController(service)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	suite.db = db
 | 
						suite.db = db
 | 
				
			||||||
// 	suite.service = service
 | 
						suite.service = service
 | 
				
			||||||
// 	suite.repository = repository
 | 
						suite.repository = repository
 | 
				
			||||||
// 	suite.controller = controller
 | 
						suite.controller = controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// suite.CreateSampleData()
 | 
						// suite.CreateSampleData()
 | 
				
			||||||
// }
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *TokenTestSuite) CreateSampleData() {
 | 
					// func (suite *TokenTestSuite) CreateSampleData() {
 | 
				
			||||||
// 	suite.db.AutoMigrate(&models.Token{})
 | 
					// 	suite.db.AutoMigrate(&models.Token{})
 | 
				
			||||||
@@ -51,34 +67,36 @@ package learsteam_quiz_test
 | 
				
			|||||||
// 	}
 | 
					// 	}
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *TokenTestSuite) TearDownSuite() {
 | 
					func (suite *TokenTestSuite) TearDownSuite() {
 | 
				
			||||||
// 	// suite.db.Migrator().DropTable(&models.Token{})
 | 
						// suite.db.Migrator().DropTable(&models.Token{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 	// err := os.Remove("test.db")
 | 
						// err := os.Remove("test.db")
 | 
				
			||||||
// 	// if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
// 	// 	suite.Fail("Failed to remove the test database file")
 | 
						// 	suite.Fail("Failed to remove the test database file")
 | 
				
			||||||
// 	// }
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
// func (suite *TokenTestSuite) SetupTest() {
 | 
					 | 
				
			||||||
// 	// suite.userRepository.DeleteByName("testUserName0001")
 | 
					 | 
				
			||||||
	// }
 | 
						// }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func (suite *TokenTestSuite) TearDownTest() {
 | 
					func (suite *TokenTestSuite) SetupTest() {
 | 
				
			||||||
 | 
						// suite.userRepository.DeleteByName("testUserName0001")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// }
 | 
					func (suite *TokenTestSuite) TearDownTest() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// func TestTokenSuite(t *testing.T) {
 | 
					}
 | 
				
			||||||
// 	suite.Run(t, new(TokenTestSuite))
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// // 토큰 생성 테스트
 | 
					func TestTokenSuite(t *testing.T) {
 | 
				
			||||||
// func (suite *TokenTestSuite) TestGenerateTokenSuccess() {
 | 
						suite.Run(t, new(TokenTestSuite))
 | 
				
			||||||
// 	user_id := "testuser"
 | 
					}
 | 
				
			||||||
// 	expire_at := time.Now().Add(time.Hour * 24 * 365).Unix()
 | 
					
 | 
				
			||||||
// 	token, err := suite.service.Generate(user_id, expire_at)
 | 
					// 토큰 생성 테스트
 | 
				
			||||||
// 	assert.NoError(suite.T(), err)
 | 
					func (suite *TokenTestSuite) TestGenerateTokenSuccess() {
 | 
				
			||||||
// 	assert.NotNil(suite.T(), token)
 | 
						user_id := int64(100000001)
 | 
				
			||||||
// }
 | 
						role := "admin"
 | 
				
			||||||
 | 
						expire_at := time.Now().Add(time.Hour * 24 * 365).Unix()
 | 
				
			||||||
 | 
						token, err := suite.service.Generate(user_id, expire_at, role)
 | 
				
			||||||
 | 
						assert.NoError(suite.T(), err)
 | 
				
			||||||
 | 
						assert.NotNil(suite.T(), token)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// // 토큰 생성 테스트
 | 
					// // 토큰 생성 테스트
 | 
				
			||||||
// func (suite *TokenTestSuite) TestGenerateTokenString() {
 | 
					// func (suite *TokenTestSuite) TestGenerateTokenString() {
 | 
				
			||||||
@@ -243,3 +261,37 @@ package learsteam_quiz_test
 | 
				
			|||||||
// 		assert.True(suite.T(), true)
 | 
					// 		assert.True(suite.T(), true)
 | 
				
			||||||
// 	}
 | 
					// 	}
 | 
				
			||||||
// }
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *TokenTestSuite) TestVerifyValidToken() {
 | 
				
			||||||
 | 
						expire_at := time.Now().Add(time.Hour * 24 * 365 * 100).Unix()
 | 
				
			||||||
 | 
						validToken, err := suite.service.Generate(10001, expire_at, "admin")
 | 
				
			||||||
 | 
						assert.NoError(suite.T(), err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						jwtToken, err := jwt.Parse(validToken, func(jwtToken *jwt.Token) (interface{}, error) {
 | 
				
			||||||
 | 
							if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return []byte(config.SECRET_KEY), nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.NoError(suite.T(), err)
 | 
				
			||||||
 | 
						assert.True(suite.T(), jwtToken.Valid)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *TokenTestSuite) TestVerifyExpiredToken() {
 | 
				
			||||||
 | 
						expire_at := time.Now().Add(-time.Hour * 24 * 365 * 100).Unix()
 | 
				
			||||||
 | 
						expiredToken, err := suite.service.Generate(10001, expire_at, "admin")
 | 
				
			||||||
 | 
						assert.NoError(suite.T(), err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Equal(suite.T(), "1", expiredToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						jwtToken, err := jwt.Parse(expiredToken, func(jwtToken *jwt.Token) (interface{}, error) {
 | 
				
			||||||
 | 
							if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return []byte(config.SECRET_KEY), nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert.Error(suite.T(), err)
 | 
				
			||||||
 | 
						assert.False(suite.T(), jwtToken.Valid)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user