Logout
This commit is contained in:
@ -1,7 +1,9 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"learnsteam/cslms-api/internal/models"
|
||||
"learnsteam/cslms-api/internal/services"
|
||||
@ -12,6 +14,7 @@ import (
|
||||
type AuthController interface {
|
||||
Register(*gin.Context)
|
||||
Login(*gin.Context)
|
||||
Logout(*gin.Context)
|
||||
}
|
||||
|
||||
type authController struct {
|
||||
@ -29,7 +32,7 @@ func NewAuthController(service services.AuthService, tokenService services.Token
|
||||
// Register
|
||||
//
|
||||
// @Summary 회원가입
|
||||
// @Description 회원가입
|
||||
// @Description 회원가입
|
||||
// @Tags 회원가입
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
@ -62,7 +65,7 @@ func (controller *authController) Register(c *gin.Context) {
|
||||
// Login 사용자 로그인
|
||||
//
|
||||
// @Summary 사용자 로그인 로그인
|
||||
// @Description 사용자가 로그인합니다.
|
||||
// @Description 사용자가 로그인합니다.
|
||||
// @Tags 로그인
|
||||
//
|
||||
// @Accept json
|
||||
@ -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) {
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
|
||||
return
|
||||
}
|
||||
token, err := func() (*string, error) {
|
||||
authorization := c.GetHeader("Authorization")
|
||||
strArr := strings.Split(authorization, " ")
|
||||
if len(strArr) == 2 {
|
||||
return &strArr[1], nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid authorization header")
|
||||
}
|
||||
}()
|
||||
|
||||
err := controller.tokenService.Delete(token)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
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("RefreshToken", "", -1, "/", "localhost", false, true)
|
||||
c.SetCookie("ExpiresAt", "", -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.JSON(http.StatusOK, gin.H{"message": "logout"})
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/datatypes"
|
||||
)
|
||||
|
||||
type QuizPaperController interface {
|
||||
@ -147,6 +149,12 @@ func (controller *quizPaperController) Create(c *gin.Context) {
|
||||
|
||||
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{
|
||||
GUID: uuid.NewString(),
|
||||
CenterID: request.CenterID,
|
||||
@ -154,7 +162,7 @@ func (controller *quizPaperController) Create(c *gin.Context) {
|
||||
Title: request.Title,
|
||||
Content: request.Content,
|
||||
Category: request.Category,
|
||||
Tag: request.Tag,
|
||||
Tag: tag,
|
||||
Status: request.Status,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
@ -204,13 +212,20 @@ func (controller *quizPaperController) Update(c *gin.Context) {
|
||||
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")
|
||||
quizPaper.ManagerID = user_id
|
||||
quizPaper.CenterID = request.CenterID
|
||||
quizPaper.Title = request.Title
|
||||
quizPaper.Content = request.Content
|
||||
quizPaper.Category = request.Category
|
||||
quizPaper.Tag = request.Tag
|
||||
quizPaper.Tag = tag
|
||||
quizPaper.Status = request.Status
|
||||
quizPaper.UpdatedAt = time.Now()
|
||||
|
||||
|
@ -109,18 +109,6 @@ func (controller *userController) Find(c *gin.Context) {
|
||||
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)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
|
@ -159,6 +159,7 @@ func (controller *userQuizController) Create(c *gin.Context) {
|
||||
CenterID: request.CenterID,
|
||||
UserQuizPaperID: request.UserQuizPaperID,
|
||||
No: request.No,
|
||||
QuizID: request.QuizID,
|
||||
QuestionType: request.QuestionType,
|
||||
Question: request.Question,
|
||||
Content: content,
|
||||
@ -223,8 +224,29 @@ func (controller *userQuizController) Update(c *gin.Context) {
|
||||
// Result string `json:"result" example:"success"`
|
||||
// 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.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)
|
||||
if err != nil {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -160,14 +159,14 @@ func (controller *userQuizPaperController) Create(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
var users []int64
|
||||
err = json.Unmarshal(request.Users, &users)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
// var users []int64
|
||||
// err = json.Unmarshal(request.Users, &users)
|
||||
// if err != nil {
|
||||
// c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
// return
|
||||
// }
|
||||
|
||||
templates := controller.service.Generate(users, quizPaper)
|
||||
templates := controller.service.Generate(request.Users, quizPaper)
|
||||
userQuizPapers, err := controller.service.Insert(templates)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"strings"
|
||||
|
||||
config "learnsteam/cslms-api/configs"
|
||||
"learnsteam/cslms-api/internal/database"
|
||||
"learnsteam/cslms-api/internal/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
@ -35,10 +37,14 @@ func Auth(permission string) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("token", extract(c.Request))
|
||||
fmt.Println("sub", sub)
|
||||
valid := Valid(c.Request)
|
||||
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("role", role)
|
||||
c.Next()
|
||||
@ -67,17 +73,21 @@ func Permission(permission *string) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("token", extract(c.Request))
|
||||
fmt.Println("sub", sub)
|
||||
valid := Valid(c.Request)
|
||||
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("role", role)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func extract(r *http.Request) string {
|
||||
func Extract(r *http.Request) string {
|
||||
authorization := r.Header.Get("Authorization")
|
||||
strArr := strings.Split(authorization, " ")
|
||||
if len(strArr) == 2 {
|
||||
@ -86,8 +96,8 @@ func extract(r *http.Request) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func verify(r *http.Request) (*jwt.Token, error) {
|
||||
tokenString := extract(r)
|
||||
func Verify(r *http.Request) (*jwt.Token, error) {
|
||||
tokenString := Extract(r)
|
||||
jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
|
||||
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
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) {
|
||||
jwtToken, err := verify(r)
|
||||
jwtToken, err := Verify(r)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1, err
|
||||
}
|
||||
|
||||
@ -120,7 +131,7 @@ func UserID(r *http.Request) (int64, error) {
|
||||
}
|
||||
|
||||
func Role(r *http.Request) (*string, error) {
|
||||
jwtToken, err := verify(r)
|
||||
jwtToken, err := Verify(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -134,3 +145,12 @@ func Role(r *http.Request) (*string, error) {
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
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;"`
|
||||
|
@ -59,11 +59,11 @@ type QuizResponse struct {
|
||||
}
|
||||
|
||||
type QuizListResponse struct {
|
||||
Data []Quiz `json:"data"`
|
||||
Total int64 `json:"total" example:"5"`
|
||||
Page int `json:"page" example:"1"`
|
||||
TotalPage int64 `json:"totalPage" example:"1"`
|
||||
PageSize int `json:"pageSize" example:"10"`
|
||||
Data []QuizResponse `json:"data"`
|
||||
Total int64 `json:"total" example:"5"`
|
||||
Page int `json:"page" example:"1"`
|
||||
TotalPage int64 `json:"totalPage" example:"1"`
|
||||
PageSize int `json:"pageSize" example:"10"`
|
||||
}
|
||||
|
||||
type QuizContent struct {
|
||||
|
@ -6,24 +6,6 @@ import (
|
||||
"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 {
|
||||
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;"`
|
||||
@ -44,23 +26,23 @@ func (QuizPaper) TableName() string {
|
||||
}
|
||||
|
||||
type QuizPaperRequest struct {
|
||||
CenterID int64 `json:"center_id" example:"100001"`
|
||||
Title string `json:"title" example:"퀴즈 시트 제목"`
|
||||
Content string `json:"content" example:"퀴즈 시트 설명"`
|
||||
Category string `json:"category" example:"파이썬기본"`
|
||||
Tag datatypes.JSON `json:"tag"`
|
||||
Status string `json:"status" example:"on"`
|
||||
CenterID int64 `json:"center_id" example:"100001"`
|
||||
Title string `json:"title" example:"퀴즈 시트 제목"`
|
||||
Content string `json:"content" example:"퀴즈 시트 설명"`
|
||||
Category string `json:"category" example:"파이썬기본"`
|
||||
Tag []string `json:"tag" example:"Python,AI,Robot,파이썬"`
|
||||
Status string `json:"status" example:"on"`
|
||||
}
|
||||
|
||||
type QuizPaperResponse struct {
|
||||
ID int64 `json:"id" example:"100001"`
|
||||
CenterID int64 `json:"center_id" example:"100001"`
|
||||
ManagerID int64 `json:"manager_id" example:"100001"`
|
||||
Title string `json:"title" example:"퀴즈 시트 제목"`
|
||||
Content string `json:"content" example:"퀴즈 시트 설명"`
|
||||
Category string `json:"category" example:"파이썬기본"`
|
||||
Tag datatypes.JSON `json:"tag"`
|
||||
Status string `json:"status" example:"on"`
|
||||
ID int64 `json:"id" example:"100001"`
|
||||
CenterID int64 `json:"center_id" example:"100001"`
|
||||
ManagerID int64 `json:"manager_id" example:"100001"`
|
||||
Title string `json:"title" example:"퀴즈 시트 제목"`
|
||||
Content string `json:"content" example:"퀴즈 시트 설명"`
|
||||
Category string `json:"category" example:"파이썬기본"`
|
||||
Tag []string `json:"tag" example:"Python,AI,Robot,파이썬"`
|
||||
Status string `json:"status" example:"on"`
|
||||
}
|
||||
|
||||
type QuizPaperListResponse struct {
|
||||
|
@ -2,17 +2,6 @@ package models
|
||||
|
||||
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 {
|
||||
ID int64 `json:"-" db:"id" gorm:"primary_key"`
|
||||
UserID int64 `json:"user_id" db:"user_id" gorm:"index;"`
|
||||
|
@ -2,27 +2,6 @@ package models
|
||||
|
||||
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 {
|
||||
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;"`
|
||||
|
@ -12,6 +12,7 @@ type UserQuiz struct {
|
||||
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;"`
|
||||
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;"`
|
||||
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;"`
|
||||
@ -33,6 +34,7 @@ type UserQuizRequest struct {
|
||||
CenterID int64 `json:"center_id" example:"1000001"`
|
||||
UserQuizPaperID int64 `json:"quiz_paper_id" example:"1000001"`
|
||||
UserID int64 `json:"user_id" example:"1000001"`
|
||||
QuizID int64 `json:"quiz_id" example:"1000001"`
|
||||
No int `json:"vol_no" example:"1"`
|
||||
QuestionType string `json:"question_type" example:"choice"`
|
||||
Question string `json:"question" example:"질문입니다."`
|
||||
@ -49,6 +51,7 @@ type UserQuizResponse struct {
|
||||
CenterD string `json:"center_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6"`
|
||||
UserQuizPaperID int64 `json:"user_quiz_paper_id" example:"1000001"`
|
||||
UserID int64 `json:"user_id" example:"1000001"`
|
||||
QuizID int64 `json:"quiz_id" example:"1000001"`
|
||||
No int `json:"vol_no" example:"5"`
|
||||
QuestionType string `json:"question_type" example:"check"`
|
||||
Question string `json:"question" example:"퀴즈 질문입니다."`
|
||||
|
@ -2,30 +2,8 @@ package models
|
||||
|
||||
import (
|
||||
"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 {
|
||||
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"`
|
||||
@ -47,8 +25,8 @@ func (UserQuizPaper) TableName() string {
|
||||
}
|
||||
|
||||
type UserQuizPaperRequest struct {
|
||||
QuizPaperID int64 `json:"quiz_paper_id" example:"1000002"`
|
||||
Users datatypes.JSON `json:"users"`
|
||||
QuizPaperID int64 `json:"quiz_paper_id" example:"1000002"`
|
||||
Users []int64 `json:"users" example:"1000001,1000002,1000003,1000004"`
|
||||
}
|
||||
|
||||
type UserQuizPaperResponse struct {
|
||||
|
@ -26,6 +26,7 @@ type TokenRepository interface {
|
||||
Create(*models.Token) (*models.Token, error)
|
||||
Update(*models.Token) (*models.Token, error)
|
||||
Delete(string) error
|
||||
Invalid(int64, 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
|
||||
}
|
||||
|
||||
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 {
|
||||
var token *models.Token
|
||||
if err := r.DB.Where("id=?", id).First(&token).Error; err != nil {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"learnsteam/cslms-api/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
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) {
|
||||
fmt.Println(items)
|
||||
err := r.DB.Create(&items).Error
|
||||
err := r.DB.Clauses(clause.OnConflict{DoNothing: true}).Create(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"learnsteam/cslms-api/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type userQuizPaperRepository struct {
|
||||
@ -63,7 +64,7 @@ func (r *userQuizPaperRepository) Create(userQuizPaper *models.UserQuizPaper) (*
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package routers
|
||||
|
||||
import (
|
||||
"learnsteam/cslms-api/internal/controllers"
|
||||
"learnsteam/cslms-api/internal/middleware"
|
||||
"learnsteam/cslms-api/internal/repositories"
|
||||
"learnsteam/cslms-api/internal/services"
|
||||
|
||||
@ -50,4 +51,5 @@ func (r *authRouter) SetAuthRouter() {
|
||||
group := r.router.Group("/auth")
|
||||
group.POST("login", r.controller.Login)
|
||||
group.POST("register", r.controller.Register)
|
||||
group.POST("logout", middleware.Auth("member"), r.controller.Logout)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
configs "learnsteam/cslms-api/configs"
|
||||
"learnsteam/cslms-api/internal/database"
|
||||
|
||||
"github.com/gin-contrib/cors"
|
||||
@ -10,10 +11,11 @@ import (
|
||||
var Router *gin.Engine
|
||||
|
||||
func Init() {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
gin.SetMode(configs.MODE)
|
||||
Router = gin.Default()
|
||||
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.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type"}
|
||||
Router.Use(cors.New(config))
|
||||
@ -21,6 +23,7 @@ func Init() {
|
||||
maindb := database.GetDB()
|
||||
|
||||
InitAuthRouter(maindb, Router)
|
||||
|
||||
InitCenterRouter(maindb, Router)
|
||||
InitQuizPaperRouter(maindb, Router)
|
||||
InitQuizRouter(maindb, Router)
|
||||
|
@ -25,8 +25,9 @@ type TokenService interface {
|
||||
|
||||
Refresh(string) (*models.Token, error)
|
||||
|
||||
Generate(string, int64, string) (string, error)
|
||||
Verify(tokenString string) (*jwt.Token, error)
|
||||
Generate(int64, int64, string) (string, error)
|
||||
Verify(string) (*jwt.Token, error)
|
||||
Invalid(int64, string) error
|
||||
|
||||
GetJwtToken(string) (*jwt.Token, error)
|
||||
ExtractTokenString(string) string
|
||||
@ -90,7 +91,12 @@ func (s *tokenService) Verify(tokenString string) (*jwt.Token, error) {
|
||||
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["authorized"] = true
|
||||
claims["sub"] = user_id
|
||||
@ -153,14 +159,6 @@ func (s *tokenService) Refresh(refreshToken string) (*models.Token, error) {
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -173,6 +171,7 @@ func (s *tokenService) Refresh(refreshToken string) (*models.Token, error) {
|
||||
if err != nil {
|
||||
return nil, errors.New("wrong user")
|
||||
}
|
||||
|
||||
role := claims["role"].(string)
|
||||
|
||||
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,
|
||||
UserID: userQuizPaper.UserID,
|
||||
No: quiz.No,
|
||||
QuizID: quiz.ID,
|
||||
QuestionType: quiz.QuestionType,
|
||||
Question: quiz.Question,
|
||||
Content: quiz.Content,
|
||||
|
Reference in New Issue
Block a user