Passed
Push — main ( 7c64d9...5da60f )
by Yume
01:20
created

controllers.CreateMcq   B

Complexity

Conditions 6

Size

Total Lines 44
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 30
nop 1
dl 0
loc 44
rs 8.2266
c 0
b 0
f 0
1
package controllers
2
3
import (
4
	"fmt"
5
	"github.com/gofiber/fiber/v2"
6
	"github.com/memnix/memnixrest/app/models"
7
	"github.com/memnix/memnixrest/app/queries"
8
	"github.com/memnix/memnixrest/pkg/database"
9
	"github.com/memnix/memnixrest/pkg/utils"
10
	"net/http"
11
	"strconv"
12
)
13
14
// GetMcqsByDeck method
15
// @Description Get mcqs linked to the deck
16
// @Summary gets a list of mcqs
17
// @Tags Mcq
18
// @Produce json
19
// @Success 200 {array} models.Mcq
20
// @Router /v1/mcqs/{deckID} [get]
21
func GetMcqsByDeck(c *fiber.Ctx) error {
22
	db := database.DBConn // DB Conn
23
24
	auth := CheckAuth(c, models.PermUser) // Check auth
25
	if !auth.Success {
26
		return queries.AuthError(c, &auth)
27
	}
28
29
	// Params
30
	deckID := c.Params("deckID")
31
32
	var mcqs []models.Mcq
33
34
	if err := db.Joins("Deck").Where("mcqs.deck_id = ?", deckID).Find(&mcqs).Error; err != nil {
35
		deckidInt, _ := strconv.ParseUint(deckID, 10, 32)
36
		log := models.CreateLog(fmt.Sprintf("Error from %s on GetMcqsByDeck: %s", auth.User.Email, err.Error()), models.LogQueryGetError).SetType(models.LogTypeError).AttachIDs(auth.User.ID, uint(deckidInt), 0)
37
		_ = log.SendLog()
38
		return queries.RequestError(c, http.StatusInternalServerError, err.Error())
39
	}
40
41
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
42
		Success: true,
43
		Message: "Success get mcqs by deck.",
44
		Data:    mcqs,
45
		Count:   len(mcqs),
46
	})
47
}
48
49
// CreateMcq method
50
// @Description Create a new mcq
51
// @Summary creates a mcq
52
// @Tags Mcq
53
// @Produce json
54
// @Accept json
55
// @Param mcq body models.Mcq true "Mcq to create"
56
// @Success 200
57
// @Router /v1/mcqs/new [post]
58
func CreateMcq(c *fiber.Ctx) error {
59
	db := database.DBConn // DB Conn
60
61
	auth := CheckAuth(c, models.PermUser) // Check auth
62
	if !auth.Success {
63
		return queries.AuthError(c, &auth)
64
	}
65
66
	mcq := new(models.Mcq)
67
68
	if err := c.BodyParser(&mcq); err != nil {
69
		log := models.CreateLog(fmt.Sprintf("Error from %s on CreateMcq: %s", auth.User.Email, err.Error()), models.LogBodyParserError).SetType(models.LogTypeError).AttachIDs(auth.User.ID, 0, 0)
70
		_ = log.SendLog()
71
		return queries.RequestError(c, http.StatusBadRequest, err.Error())
72
	}
73
74
	if res := queries.CheckAccess(auth.User.ID, mcq.DeckID, models.AccessEditor); !res.Success {
75
		log := models.CreateLog(fmt.Sprintf("Forbidden from %s on deck %d - CreateMcq: %s", auth.User.Email, mcq.DeckID, res.Message), models.LogPermissionForbidden).SetType(models.LogTypeWarning).AttachIDs(auth.User.ID, mcq.DeckID, 0)
76
		_ = log.SendLog()
77
		return queries.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
78
	}
79
80
	if res := queries.CheckCardLimit(auth.User.Permissions, mcq.DeckID); !res {
81
		log := models.CreateLog(fmt.Sprintf("Forbidden from %s on deck %d - CreateMcq: This deck has reached his limit", auth.User.Email, mcq.DeckID), models.LogDeckCardLimit).SetType(models.LogTypeWarning).AttachIDs(auth.User.ID, mcq.DeckID, 0)
82
		_ = log.SendLog()
83
		return queries.RequestError(c, http.StatusForbidden, "This deck has reached his limit ! You can't add more mcq to it.")
84
	}
85
86
	if mcq.NotValidate() {
87
		log := models.CreateLog(fmt.Sprintf("Error from %s on CreateMcq: BadRequest", auth.User.Email), models.LogBadRequest).SetType(models.LogTypeError).AttachIDs(auth.User.ID, 0, 0)
88
		_ = log.SendLog()
89
		return queries.RequestError(c, http.StatusBadRequest, "You must provide at least 3 and at most 150 answers for Standalone MCQ")
90
	}
91
92
	db.Create(mcq)
93
94
	log := models.CreateLog(fmt.Sprintf("Created MCQ: %d - %s", mcq.ID, mcq.Name), models.LogCardCreated).SetType(models.LogTypeInfo).AttachIDs(auth.User.ID, mcq.DeckID, 0)
95
	_ = log.SendLog()
96
97
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
98
		Success: true,
99
		Message: "Success register a mcq",
100
		Data:    *mcq,
101
		Count:   1,
102
	})
103
}
104
105
// PUT
106
107
// UpdateMcqById method
108
// @Description Edit a mcq
109
// @Summary edits a mcq
110
// @Tags Mcq
111
// @Produce json
112
// @Success 200
113
// @Accept json
114
// @Param mcq body models.Mcq true "mcq to edit"
115
// @Router /v1/mcqs/{mcqID}/edit [put]
116
func UpdateMcqById(c *fiber.Ctx) error {
117
	db := database.DBConn // DB Conn
118
119
	// Params
120
	id := c.Params("id")
121
122
	auth := CheckAuth(c, models.PermUser) // Check auth
123
	if !auth.Success {
124
		return queries.AuthError(c, &auth)
125
	}
126
127
	mcq := new(models.Mcq)
128
129
	if err := db.First(&mcq, id).Error; err != nil {
130
		log := models.CreateLog(fmt.Sprintf("Error on UpdateMcqById: %s from %s", err.Error(), auth.User.Email), models.LogQueryGetError).SetType(models.LogTypeError).AttachIDs(auth.User.ID, 0, 0)
131
		_ = log.SendLog()
132
		return queries.RequestError(c, http.StatusInternalServerError, err.Error())
133
	}
134
135
	if res := queries.CheckAccess(auth.User.ID, mcq.DeckID, models.AccessEditor); !res.Success {
136
		log := models.CreateLog(fmt.Sprintf("Forbidden from %s on deck %d - UpdateCardByID: %s", auth.User.Email, mcq.DeckID, res.Message), models.LogPermissionForbidden).SetType(models.LogTypeWarning).AttachIDs(auth.User.ID, mcq.DeckID, 0)
137
		_ = log.SendLog()
138
		return queries.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
139
	}
140
141
	if err := UpdateMcq(c, mcq); !err.Success {
142
		log := models.CreateLog(fmt.Sprintf("Error on UpdateCardByID: %s from %s", err.Message, auth.User.Email), models.LogBadRequest).SetType(models.LogTypeError).AttachIDs(auth.User.ID, 0, 0)
143
		_ = log.SendLog()
144
		return queries.RequestError(c, http.StatusBadRequest, err.Message)
145
	}
146
147
	log := models.CreateLog(fmt.Sprintf("Edited: %d - %s", mcq.ID, mcq.Name), models.LogCardEdited).SetType(models.LogTypeInfo).AttachIDs(auth.User.ID, mcq.DeckID, 0)
148
	_ = log.SendLog()
149
150
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
151
		Success: true,
152
		Message: "Success update mcq by ID",
153
		Data:    *mcq,
154
		Count:   1,
155
	})
156
}
157
158
// UpdateMcq function
159
func UpdateMcq(c *fiber.Ctx, mcq *models.Mcq) *models.ResponseHTTP {
160
	db := database.DBConn
161
162
	deckId := mcq.DeckID
163
164
	res := new(models.ResponseHTTP)
165
166
	if err := c.BodyParser(&mcq); err != nil {
167
		res.GenerateError(err.Error())
168
		return res
169
	}
170
171
	if deckId != mcq.DeckID {
172
		res.GenerateError(utils.ErrorBreak)
173
		return res
174
	}
175
176
	if mcq.Type == models.McqStandalone && (len(mcq.Answers) < utils.MinMcqAnswersLen || len(mcq.Answers) > utils.MaxMcqAnswersLen) || len(mcq.Name) > utils.MaxMcqName || mcq.Name == "" {
177
		res.GenerateError(utils.ErrorRequestFailed)
178
		return res
179
	}
180
181
	if mcq.Type == models.McqLinked {
182
		mcq.UpdateLinkedAnswers()
183
	}
184
185
	db.Save(mcq)
186
187
	res.GenerateSuccess("Success update mcq", nil, 0)
188
	return res
189
}
190
191
// DeleteMcqById method
192
// @Description Delete a mcq
193
// @Summary deletes a mcq
194
// @Tags Mcq
195
// @Produce json
196
// @Success 200
197
// @Router /v1/mcqs/{mcqID} [delete]
198
func DeleteMcqById(c *fiber.Ctx) error {
199
	db := database.DBConn // DB Conn
200
	id := c.Params("id")
201
202
	auth := CheckAuth(c, models.PermUser) // Check auth
203
	if !auth.Success {
204
		return queries.AuthError(c, &auth)
205
	}
206
207
	mcq := new(models.Mcq)
208
209
	if err := db.First(&mcq, id).Error; err != nil {
210
		return queries.RequestError(c, http.StatusServiceUnavailable, err.Error())
211
	}
212
213
	if res := queries.CheckAccess(auth.User.ID, mcq.DeckID, models.AccessOwner); !res.Success {
214
		log := models.CreateLog(fmt.Sprintf("Forbidden from %s on deck %d and mcq %d - DeleteMcqById: %s", auth.User.Email, mcq.DeckID, mcq.ID, res.Message), models.LogPermissionForbidden).SetType(models.LogTypeWarning).AttachIDs(auth.User.ID, mcq.DeckID, 0)
215
		_ = log.SendLog()
216
		return queries.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
217
	}
218
219
	db.Delete(mcq)
220
221
	log := models.CreateLog(fmt.Sprintf("Deleted: %d - %s", mcq.ID, mcq.Name), models.LogCardDeleted).SetType(models.LogTypeInfo).AttachIDs(auth.User.ID, mcq.DeckID, 0)
222
	_ = log.SendLog()
223
224
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
225
		Success: true,
226
		Message: "Success delete mcq by ID",
227
		Data:    *mcq,
228
		Count:   1,
229
	})
230
231
}
232