Passed
Pull Request — main (#42)
by Yume
01:11
created

controllers.UpdateMcqByID   B

Complexity

Conditions 5

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

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