Passed
Pull Request — main (#20)
by Yume
01:36
created

controllers.GetNextCard   A

Complexity

Conditions 3

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 12
nop 1
dl 0
loc 17
rs 9.8
c 0
b 0
f 0
1
package controllers
2
3
import (
4
	"github.com/gofiber/fiber/v2"
5
	"memnixrest/app/models"
6
	queries2 "memnixrest/app/queries"
7
	"memnixrest/pkg/database"
8
	"memnixrest/pkg/utils"
9
	"net/http"
10
	"strconv"
11
	"strings"
12
)
13
14
// GetTodayCard method
15
// @Description Get next today card
16
// @Summary gets a card
17
// @Tags Card
18
// @Produce json
19
// @Success 200 {object} models.Card
20
// @Router /v1/cards/today [get]
21
func GetTodayCard(c *fiber.Ctx) error {
22
	res := new(models.ResponseHTTP)
23
24
	auth := CheckAuth(c, models.PermUser) // Check auth
25
	if !auth.Success {
26
		return queries2.AuthError(c, auth)
27
	}
28
29
	if res = queries2.FetchNextTodayCard(auth.User.ID); !res.Success {
30
		return queries2.RequestError(c, http.StatusInternalServerError, res.Message)
31
	}
32
33
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
34
		Success: true,
35
		Message: "Get today's card",
36
		Data:    res.Data,
37
		Count:   1,
38
	})
39
}
40
41
// GetTrainingCardsByDeck method
42
// @Description Get training cards
43
// @Summary gets a list of cards
44
// @Tags Card
45
// @Produce json
46
// @Success 200 {array} models.Card
47
// @Router /v1/cards/{deckID}/training [get]
48
func GetTrainingCardsByDeck(c *fiber.Ctx) error {
49
	res := new(models.ResponseHTTP)
50
51
	auth := CheckAuth(c, models.PermUser) // Check auth
52
	if !auth.Success {
53
		return queries2.AuthError(c, auth)
54
	}
55
56
	deckID := c.Params("deckID")
57
	deckIdInt, _ := strconv.ParseInt(deckID, 10, 32)
58
59
	access := queries2.CheckAccess(auth.User.ID, uint(deckIdInt), models.AccessStudent)
60
	if !access.Success {
61
		return queries2.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
62
	}
63
64
	if res = queries2.FetchTrainingCards(auth.User.ID, uint(deckIdInt)); !res.Success {
65
		return queries2.RequestError(c, http.StatusInternalServerError, res.Message)
66
	}
67
68
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
69
		Success: true,
70
		Message: "Get today's card",
71
		Data:    res.Data,
72
		Count:   res.Count,
73
	})
74
}
75
76
// GetNextCard method
77
// @Description Get next card
78
// @Summary gets a card
79
// @Tags Card
80
// @Produce json
81
// @Success 200 {object} models.Card
82
// @Router /v1/cards/next [get]
83
func GetNextCard(c *fiber.Ctx) error {
84
85
	res := new(models.ResponseHTTP)
86
	auth := CheckAuth(c, models.PermUser) // Check auth
87
	if !auth.Success {
88
		return queries2.AuthError(c, auth)
89
	}
90
91
	if res = queries2.FetchNextCard(auth.User.ID, 0); !res.Success {
92
		return queries2.RequestError(c, http.StatusInternalServerError, res.Message)
93
	}
94
95
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
96
		Success: true,
97
		Message: "Get next card",
98
		Data:    res.Data,
99
		Count:   1,
100
	})
101
}
102
103
// GetNextCardByDeck method
104
// @Description Get next card by deckID
105
// @Summary get a card
106
// @Tags Card
107
// @Produce json
108
// @Success 200 {object} models.Card
109
// @Router /v1/cards/{deckID}/next [get]
110
func GetNextCardByDeck(c *fiber.Ctx) error {
111
112
	deckID := c.Params("deckID")
113
	deckIDInt, _ := strconv.Atoi(deckID)
114
	res := new(models.ResponseHTTP)
115
	auth := CheckAuth(c, models.PermUser) // Check auth
116
	if !auth.Success {
117
		return queries2.AuthError(c, auth)
118
	}
119
120
	if res = queries2.FetchNextCard(auth.User.ID, uint(deckIDInt)); !res.Success {
121
		return queries2.RequestError(c, http.StatusInternalServerError, res.Message)
122
123
	}
124
125
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
126
		Success: true,
127
		Message: "Get next card by deck",
128
		Data:    res.Data,
129
		Count:   1,
130
	})
131
}
132
133
// GetAllCards method
134
// @Description Get every card. Shouldn't really be used
135
// @Summary gets all cards
136
// @Tags Card
137
// @Produce json
138
// @Success 200 {array} models.Card
139
// @Router /v1/cards/ [get]
140
func GetAllCards(c *fiber.Ctx) error {
141
	db := database.DBConn // DB Conn
142
143
	auth := CheckAuth(c, models.PermAdmin) // Check auth
144
	if !auth.Success {
145
		return queries2.AuthError(c, auth)
146
	}
147
148
	var cards []models.Card
149
150
	if res := db.Joins("Deck").Find(&cards); res.Error != nil {
151
		return queries2.RequestError(c, http.StatusInternalServerError, utils.ErrorRequestFailed)
152
	}
153
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
154
		Success: true,
155
		Message: "Get All cards",
156
		Data:    cards,
157
		Count:   len(cards),
158
	})
159
160
}
161
162
// GetCardByID method to get a card by id
163
// @Description Get a card by tech id
164
// @Summary gets a card
165
// @Tags Card
166
// @Produce json
167
// @Param id path int true "Card ID"
168
// @Success 200 {object} models.Card
169
// @Router /v1/cards/id/{id} [get]
170
func GetCardByID(c *fiber.Ctx) error {
171
	db := database.DBConn // DB Conn
172
173
	auth := CheckAuth(c, models.PermAdmin) // Check auth
174
	if !auth.Success {
175
		return queries2.AuthError(c, auth)
176
	}
177
	// Params
178
	id := c.Params("id")
179
180
	card := new(models.Card)
181
182
	if err := db.Joins("Deck").First(&card, id).Error; err != nil {
183
		return queries2.RequestError(c, http.StatusInternalServerError, err.Error())
184
185
	}
186
187
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
188
		Success: true,
189
		Message: "Success get card by ID.",
190
		Data:    *card,
191
		Count:   1,
192
	})
193
}
194
195
// GetCardsFromDeck method to get cards from deck
196
// @Description Get every card from a deck
197
// @Summary gets a list of card
198
// @Tags Card
199
// @Produce json
200
// @Param deckID path int true "Deck ID"
201
// @Success 200 {array} models.Card
202
// @Router /v1/cards/deck/{deckID} [get]
203
func GetCardsFromDeck(c *fiber.Ctx) error {
204
	db := database.DBConn // DB Conn
205
206
	// Params
207
	id := c.Params("deckID")
208
209
	auth := CheckAuth(c, models.PermAdmin) // Check auth
210
	if !auth.Success {
211
		return queries2.AuthError(c, auth)
212
	}
213
214
	var cards []models.Card
215
216
	if err := db.Joins("Deck").Where("cards.deck_id = ?", id).Find(&cards).Error; err != nil {
217
		return queries2.RequestError(c, http.StatusInternalServerError, err.Error())
218
	}
219
220
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
221
		Success: true,
222
		Message: "Success get cards from deck.",
223
		Data:    cards,
224
		Count:   len(cards),
225
	})
226
}
227
228
// POST
229
230
// CreateNewCard method
231
// @Description Create a new card
232
// @Summary creates a card
233
// @Tags Card
234
// @Produce json
235
// @Accept json
236
// @Param card body models.Card true "Card to create"
237
// @Success 200
238
// @Router /v1/cards/new [post]
239
func CreateNewCard(c *fiber.Ctx) error {
240
	db := database.DBConn // DB Conn
241
	result := new(models.ResponseHTTP)
242
	card := new(models.Card)
243
244
	auth := CheckAuth(c, models.PermUser) // Check auth
245
	if !auth.Success {
246
		return queries2.AuthError(c, auth)
247
	}
248
249
	if err := c.BodyParser(&card); err != nil {
250
		return queries2.RequestError(c, http.StatusBadRequest, err.Error())
251
	}
252
253
	if res := queries2.CheckAccess(auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
254
		return queries2.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
255
	}
256
257
	if len(card.Question) <= 5 || len(card.Answer) <= 5 {
258
		return queries2.RequestError(c, http.StatusBadRequest, utils.ErrorQALen)
259
	}
260
261
	db.Create(card)
262
263
	log := queries2.CreateLog(models.LogCardCreated, auth.User.Username+" created "+card.Question)
264
	_ = queries2.CreateUserLog(auth.User.ID, log)
265
	_ = queries2.CreateDeckLog(card.DeckID, log)
266
	_ = queries2.CreateCardLog(card.ID, log)
267
268
	var users []models.User
269
270
	if result = queries2.GetSubUsers(card.DeckID); !result.Success {
271
		return queries2.RequestError(c, http.StatusInternalServerError, utils.ErrorRequestFailed)
272
	}
273
274
	switch result.Data.(type) {
275
	default:
276
		return queries2.RequestError(c, http.StatusInternalServerError, utils.ErrorRequestFailed)
277
	case []models.User:
278
		users = result.Data.([]models.User)
279
	}
280
281
	for _, s := range users {
282
		_ = queries2.GenerateMemDate(s.ID, card.ID, card.DeckID)
283
	}
284
285
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
286
		Success: true,
287
		Message: "Success register a card",
288
		Data:    *card,
289
		Count:   1,
290
	})
291
}
292
293
// PostResponse method
294
// @Description Post a response and check it
295
// @Summary posts a response
296
// @Tags Card
297
// @Produce json
298
// @Success 200
299
// @Accept json
300
// @Router /v1/cards/response [post]
301
func PostResponse(c *fiber.Ctx) error {
302
	db := database.DBConn // DB Conn
303
304
	auth := CheckAuth(c, models.PermUser) // Check auth
305
	if !auth.Success {
306
		return queries2.AuthError(c, auth)
307
	}
308
309
	response := new(models.CardResponse)
310
	card := new(models.Card)
311
312
	if err := c.BodyParser(&response); err != nil {
313
		return queries2.RequestError(c, http.StatusBadRequest, err.Error())
314
315
	}
316
317
	if err := db.Joins("Deck").First(&card, response.CardID).Error; err != nil {
318
		return queries2.RequestError(c, http.StatusServiceUnavailable, err.Error())
319
	}
320
321
	res := queries2.CheckAccess(auth.User.ID, card.Deck.ID, models.AccessStudent)
322
	if !res.Success {
323
		return queries2.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
324
	}
325
326
	validation := new(models.CardResponseValidation)
327
328
	if strings.EqualFold(
329
		strings.ReplaceAll(response.Response, " ", ""), strings.ReplaceAll(card.Answer, " ", "")) {
330
		validation.Validate = true
331
		validation.Message = "Correct answer"
332
	} else {
333
		validation.Validate = false
334
		validation.Message = "Incorrect answer"
335
	}
336
337
	_ = queries2.PostMem(&auth.User, card, validation, response.Training)
338
339
	validation.Answer = card.Answer
340
341
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
342
		Success: true,
343
		Message: "Success post response",
344
		Data:    *validation,
345
		Count:   1,
346
	})
347
}
348
349
// PUT
350
351
// UpdateCardByID method
352
// @Description Edit a card
353
// @Summary edits a card
354
// @Tags Card
355
// @Produce json
356
// @Success 200
357
// @Accept json
358
// @Param card body models.Card true "card to edit"
359
// @Router /v1/cards/{cardID}/edit [put]
360
func UpdateCardByID(c *fiber.Ctx) error {
361
	db := database.DBConn // DB Conn
362
363
	// Params
364
	id := c.Params("id")
365
366
	auth := CheckAuth(c, models.PermUser) // Check auth
367
	if !auth.Success {
368
		return queries2.AuthError(c, auth)
369
	}
370
371
	card := new(models.Card)
372
373
	if err := db.First(&card, id).Error; err != nil {
374
		return queries2.RequestError(c, http.StatusInternalServerError, err.Error())
375
	}
376
377
	if res := queries2.CheckAccess(auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
378
		return queries2.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
379
	}
380
381
	if err := UpdateCard(c, card); !err.Success {
382
		return queries2.RequestError(c, http.StatusBadRequest, err.Message)
383
	}
384
385
	log := queries2.CreateLog(models.LogCardEdited, auth.User.Username+" edited "+card.Question)
386
	_ = queries2.CreateUserLog(auth.User.ID, log)
387
	_ = queries2.CreateCardLog(card.ID, log)
388
389
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
390
		Success: true,
391
		Message: "Success update card by ID",
392
		Data:    *card,
393
		Count:   1,
394
	})
395
}
396
397
// UpdateCard function
398
func UpdateCard(c *fiber.Ctx, card *models.Card) *models.ResponseHTTP {
399
	db := database.DBConn
400
401
	deckId := card.DeckID
402
403
	res := new(models.ResponseHTTP)
404
405
	if err := c.BodyParser(&card); err != nil {
406
		res.GenerateError(err.Error())
407
		return res
408
	}
409
410
	if deckId != card.DeckID {
411
		res.GenerateError(utils.ErrorBreak)
412
		return res
413
	}
414
415
	if len(card.Question) <= 5 || len(card.Answer) <= 5 {
416
		res.GenerateError(utils.ErrorQALen)
417
		return res
418
	}
419
420
	db.Save(card)
421
422
	res.GenerateSuccess("Success update card", nil, 0)
423
	return res
424
}
425
426
// DeleteCardById method
427
// @Description Delete a card
428
// @Summary deletes a card
429
// @Tags Card
430
// @Produce json
431
// @Success 200
432
// @Router /v1/cards/{cardID} [delete]
433
func DeleteCardById(c *fiber.Ctx) error {
434
	db := database.DBConn // DB Conn
435
	id := c.Params("id")
436
437
	auth := CheckAuth(c, models.PermUser) // Check auth
438
	if !auth.Success {
439
		return queries2.AuthError(c, auth)
440
	}
441
442
	card := new(models.Card)
443
444
	if err := db.First(&card, id).Error; err != nil {
445
		return queries2.RequestError(c, http.StatusServiceUnavailable, err.Error())
446
	}
447
448
	if res := queries2.CheckAccess(auth.User.ID, card.DeckID, models.AccessOwner); !res.Success {
449
		return queries2.RequestError(c, http.StatusForbidden, utils.ErrorForbidden)
450
	}
451
452
	db.Delete(card)
453
454
	log := queries2.CreateLog(models.LogCardDeleted, auth.User.Username+" deleted "+card.Question)
455
	_ = queries2.CreateUserLog(auth.User.ID, log)
456
	_ = queries2.CreateCardLog(card.ID, log)
457
458
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
459
		Success: true,
460
		Message: "Success delete card by ID",
461
		Data:    *card,
462
		Count:   1,
463
	})
464
465
}
466