Passed
Push — main ( e647c7...bec8e4 )
by Yume
01:04
created

controllers.GetCardsFromDeck   A

Complexity

Conditions 3

Size

Total Lines 32
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 22
nop 1
dl 0
loc 32
rs 9.352
c 0
b 0
f 0
1
package controllers
2
3
import (
4
	"memnixrest/app/database"
5
	"memnixrest/app/models"
6
	"memnixrest/pkg/queries"
7
	"net/http"
8
	"strconv"
9
	"strings"
10
11
	"github.com/gofiber/fiber/v2"
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 c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
27
			Success: false,
28
			Message: auth.Message,
29
			Data:    nil,
30
			Count:   0,
31
		})
32
	}
33
34
	if res = queries.FetchNextTodayCard(c, &auth.User); !res.Success {
35
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
36
			Success: false,
37
			Message: res.Message,
38
			Data:    nil,
39
			Count:   0,
40
		})
41
	}
42
43
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
44
		Success: true,
45
		Message: "Get todays card",
46
		Data:    res.Data,
47
		Count:   1,
48
	})
49
}
50
51
// GetNextCard method
52
// @Description Get next card
53
// @Summary gets a card
54
// @Tags Card
55
// @Produce json
56
// @Success 200 {object} models.Card
57
// @Router /v1/cards/next [get]
58
func GetNextCard(c *fiber.Ctx) error {
59
	//db := database.DBConn // DB Conn
60
61
	res := *new(models.ResponseHTTP)
62
	auth := CheckAuth(c, models.PermUser) // Check auth
63
	if !auth.Success {
64
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
65
			Success: false,
66
			Message: auth.Message,
67
			Data:    nil,
68
			Count:   0,
69
		})
70
	}
71
72
	if res = queries.FetchNextCard(c, &auth.User); !res.Success {
73
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
74
			Success: false,
75
			Message: res.Message,
76
			Data:    nil,
77
			Count:   0,
78
		})
79
	}
80
81
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
82
		Success: true,
83
		Message: "Get next card",
84
		Data:    res.Data,
85
		Count:   1,
86
	})
87
}
88
89
// GetNextCardByDeck method
90
// @Description Get next card by deckID
91
// @Summary get a card
92
// @Tags Card
93
// @Produce json
94
// @Success 200 {object} models.Card
95
// @Router /v1/cards/{deckID}/next [get]
96
func GetNextCardByDeck(c *fiber.Ctx) error {
97
	//db := database.DBConn // DB Conn
98
99
	deckID := c.Params("deckID")
100
101
	res := *new(models.ResponseHTTP)
102
	auth := CheckAuth(c, models.PermUser) // Check auth
103
	if !auth.Success {
104
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
105
			Success: false,
106
			Message: auth.Message,
107
			Data:    nil,
108
			Count:   0,
109
		})
110
	}
111
112
	if res = queries.FetchNextCardByDeck(c, &auth.User, deckID); !res.Success {
113
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
114
			Success: false,
115
			Message: res.Message,
116
			Data:    nil,
117
			Count:   0,
118
		})
119
	}
120
121
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
122
		Success: true,
123
		Message: "Get next card by deck",
124
		Data:    res.Data,
125
		Count:   1,
126
	})
127
}
128
129
// GetAllCards method
130
// @Description Get every card. Shouldn't really be used
131
// @Summary gets all cards
132
// @Tags Card
133
// @Produce json
134
// @Success 200 {array} models.Card
135
// @Router /v1/cards/ [get]
136
func GetAllCards(c *fiber.Ctx) error {
137
	db := database.DBConn // DB Conn
138
139
	auth := CheckAuth(c, models.PermAdmin) // Check auth
140
	if !auth.Success {
141
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
142
			Success: false,
143
			Message: auth.Message,
144
			Data:    nil,
145
			Count:   0,
146
		})
147
	}
148
149
	var cards []models.Card
150
151
	if res := db.Joins("Deck").Find(&cards); res.Error != nil {
152
153
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
154
			Success: false,
155
			Message: "Failed to get all cards",
156
			Data:    nil,
157
			Count:   0,
158
		})
159
	}
160
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
161
		Success: true,
162
		Message: "Get All cards",
163
		Data:    cards,
164
		Count:   len(cards),
165
	})
166
167
}
168
169
// GetCardByID method to get a card by id
170
// @Description Get a card by tech id
171
// @Summary gets a card
172
// @Tags Card
173
// @Produce json
174
// @Param id path int true "Card ID"
175
// @Success 200 {object} models.Card
176
// @Router /v1/cards/id/{id} [get]
177
func GetCardByID(c *fiber.Ctx) error {
178
	db := database.DBConn // DB Conn
179
180
	auth := CheckAuth(c, models.PermAdmin) // Check auth
181
	if !auth.Success {
182
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
183
			Success: false,
184
			Message: auth.Message,
185
			Data:    nil,
186
			Count:   0,
187
		})
188
	}
189
190
	// Params
191
	id := c.Params("id")
192
193
	card := new(models.Card)
194
195
	if err := db.Joins("Deck").First(&card, id).Error; err != nil {
196
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
197
			Success: false,
198
			Message: err.Error(),
199
			Data:    nil,
200
			Count:   0,
201
		})
202
	}
203
204
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
205
		Success: true,
206
		Message: "Success get card by ID.",
207
		Data:    *card,
208
		Count:   1,
209
	})
210
}
211
212
// GetCardsFromDeck method to get cards from deck
213
// @Description Get every card from a deck
214
// @Summary gets a list of card
215
// @Tags Card
216
// @Produce json
217
// @Param deckID path int true "Deck ID"
218
// @Success 200 {array} models.Card
219
// @Router /v1/cards/deck/{deckID} [get]
220
func GetCardsFromDeck(c *fiber.Ctx) error {
221
	db := database.DBConn // DB Conn
222
223
	// Params
224
	id := c.Params("deckID")
225
226
	auth := CheckAuth(c, models.PermAdmin) // Check auth
227
	if !auth.Success {
228
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
229
			Success: false,
230
			Message: auth.Message,
231
			Data:    nil,
232
			Count:   0,
233
		})
234
	}
235
236
	var cards []models.Card
237
238
	if err := db.Joins("Deck").Where("cards.deck_id = ?", id).Find(&cards).Error; err != nil {
239
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
240
			Success: false,
241
			Message: err.Error(),
242
			Data:    nil,
243
			Count:   0,
244
		})
245
	}
246
247
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
248
		Success: true,
249
		Message: "Success get cards from deck.",
250
		Data:    cards,
251
		Count:   len(cards),
252
	})
253
}
254
255
// POST
256
257
// CreateNewCard method
258
// @Description Create a new card
259
// @Summary creates a card
260
// @Tags Card
261
// @Produce json
262
// @Accept json
263
// @Param card body models.Card true "Card to create"
264
// @Success 200
265
// @Router /v1/cards/new [post]
266
func CreateNewCard(c *fiber.Ctx) error {
267
	db := database.DBConn // DB Conn
268
269
	card := new(models.Card)
270
271
	auth := CheckAuth(c, models.PermUser) // Check auth
272
	if !auth.Success {
273
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
274
			Success: false,
275
			Message: auth.Message,
276
			Data:    nil,
277
			Count:   0,
278
		})
279
	}
280
281
	if err := c.BodyParser(&card); err != nil {
282
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
283
			Success: false,
284
			Message: err.Error(),
285
			Data:    nil,
286
			Count:   0,
287
		})
288
	}
289
290
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
291
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
292
			Success: false,
293
			Message: "You don't have the permission to add a card to this deck !",
294
			Data:    nil,
295
			Count:   0,
296
		})
297
	}
298
299
	if len(card.Question) <= 5 || len(card.Answer) <= 5 {
300
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
301
			Success: false,
302
			Message: "You must provide a question and an answer (at least 5char).",
303
			Data:    nil,
304
			Count:   0,
305
		})
306
	}
307
308
	db.Create(card)
309
310
	log := queries.CreateLog(models.LogCardCreated, auth.User.Username+" created "+card.Question)
311
	_ = queries.CreateUserLog(auth.User.ID, *log)
312
	_ = queries.CreateDeckLog(card.DeckID, *log)
313
	_ = queries.CreateCardLog(card.ID, *log)
314
315
	var users []models.User
316
317
	if users = queries.GetSubUsers(c, card.DeckID); len(users) > 0 {
318
		for _, s := range users {
319
			_ = queries.GenerateMemDate(c, &s, card)
320
321
		}
322
	}
323
324
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
325
		Success: true,
326
		Message: "Success register a card",
327
		Data:    *card,
328
		Count:   1,
329
	})
330
}
331
332
// CreateNewCardBulk method
333
// @Description Create cards
334
// @Summary create cards
335
// @Tags Card
336
// @Produce json
337
// @Accept json
338
// @Param card body models.Card true "Cards to create"
339
// @Success 200
340
// @Router /v1/cards/deck/{deckID}/bulk [post]
341
func CreateNewCardBulk(c *fiber.Ctx) error {
342
	db := database.DBConn // DB Conn
343
344
	deckID, _ := strconv.ParseUint(c.Params("deckID"), 10, 32)
345
346
	auth := CheckAuth(c, models.PermUser) // Check auth
347
	if !auth.Success {
348
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
349
			Success: false,
350
			Message: auth.Message,
351
			Data:    nil,
352
			Count:   0,
353
		})
354
	}
355
356
	type Data struct {
357
		Cards []models.Card `json:"cards"`
358
	}
359
360
	data := new(Data)
361
362
	if err := c.BodyParser(&data); err != nil {
363
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
364
			Success: false,
365
			Message: err.Error(),
366
			Data:    nil,
367
			Count:   0,
368
		})
369
	}
370
371
	if res := queries.CheckAccess(c, auth.User.ID, uint(deckID), models.AccessEditor); !res.Success {
372
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
373
			Success: false,
374
			Message: "You don't have the permission to add a card to this deck !",
375
			Data:    nil,
376
			Count:   0,
377
		})
378
	}
379
380
	for _, card := range data.Cards {
381
		if len(card.Question) < 1 || len(card.Answer) < 1 {
382
			_ = models.ResponseHTTP{
383
				Success: false,
384
				Message: "You must provide a question and an answer.",
385
				Data:    nil,
386
				Count:   0,
387
			}
388
		} else {
389
			ca := &card
390
			ca.DeckID = uint(deckID)
391
			db.Create(ca)
392
393
			log := queries.CreateLog(models.LogCardCreated, auth.User.Username+" created "+ca.Question)
394
			_ = queries.CreateUserLog(auth.User.ID, *log)
395
			_ = queries.CreateDeckLog(uint(deckID), *log)
396
			_ = queries.CreateCardLog(ca.ID, *log)
397
398
			_ = models.ResponseHTTP{
399
				Success: true,
400
				Message: "Success creating card",
401
				Data:    nil,
402
				Count:   0,
403
			}
404
405
			var users []models.User
406
407
			if users = queries.GetSubUsers(c, uint(deckID)); len(users) > 0 {
408
409
				for _, s := range users {
410
					_ = queries.GenerateMemDate(c, &s, &card)
411
				}
412
			}
413
		}
414
415
	}
416
417
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
418
		Success: true,
419
		Message: "Success bulk creation",
420
		Data:    data.Cards,
421
		Count:   len(data.Cards),
422
	})
423
}
424
425
// PostResponse method
426
// @Description Post a response and check it
427
// @Summary posts a response
428
// @Tags Card
429
// @Produce json
430
// @Success 200
431
// @Accept json
432
// @Router /v1/cards/response [post]
433
func PostResponse(c *fiber.Ctx) error {
434
	db := database.DBConn // DB Conn
435
436
	auth := CheckAuth(c, models.PermUser) // Check auth
437
	if !auth.Success {
438
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
439
			Success: false,
440
			Message: auth.Message,
441
			Data:    nil,
442
			Count:   0,
443
		})
444
	}
445
446
	response := new(models.CardResponse)
447
	card := new(models.Card)
448
449
	if err := c.BodyParser(&response); err != nil {
450
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
451
			Success: false,
452
			Message: err.Error(),
453
			Data:    nil,
454
			Count:   0,
455
		})
456
	}
457
458
	if err := db.Joins("Deck").First(&card, response.CardID).Error; err != nil {
459
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
460
			Success: false,
461
			Message: err.Error(),
462
			Data:    nil,
463
			Count:   0,
464
		})
465
	}
466
467
	res := queries.CheckAccess(c, auth.User.ID, card.Deck.ID, models.AccessStudent)
468
469
	if !res.Success {
470
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
471
			Success: false,
472
			Message: "You don't have the permission to answer this deck!",
473
			Data:    nil,
474
			Count:   0,
475
		})
476
	}
477
478
	validation := new(models.CardResponseValidation)
479
480
	if strings.EqualFold(
481
		strings.Replace(response.Response, " ", "", -1), strings.Replace(card.Answer, " ", "", -1)) {
482
		validation.Validate = true
483
		validation.Message = "Correct answer"
484
	} else {
485
		validation.Validate = false
486
		validation.Message = "Incorrect answer"
487
	}
488
489
	_ = queries.PostMem(c, auth.User, *card, *validation)
490
491
	validation.Answer = card.Answer
492
493
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
494
		Success: true,
495
		Message: "Success post response",
496
		Data:    *validation,
497
		Count:   1,
498
	})
499
}
500
501
// PUT
502
503
// UpdateCardByID method
504
// @Description Edit a card
505
// @Summary edits a card
506
// @Tags Card
507
// @Produce json
508
// @Success 200
509
// @Accept json
510
// @Param card body models.Card true "card to edit"
511
// @Router /v1/cards/{cardID}/edit [put]
512
func UpdateCardByID(c *fiber.Ctx) error {
513
	db := database.DBConn // DB Conn
514
515
	// Params
516
	id := c.Params("id")
517
518
	auth := CheckAuth(c, models.PermUser) // Check auth
519
	if !auth.Success {
520
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
521
			Success: false,
522
			Message: auth.Message,
523
			Data:    nil,
524
			Count:   0,
525
		})
526
	}
527
528
	card := new(models.Card)
529
530
	if err := db.First(&card, id).Error; err != nil {
531
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
532
			Success: false,
533
			Message: err.Error(),
534
			Data:    nil,
535
			Count:   0,
536
		})
537
	}
538
539
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessEditor); !res.Success {
540
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
541
			Success: false,
542
			Message: "You don't have the permission to edit this card!",
543
			Data:    nil,
544
			Count:   0,
545
		})
546
	}
547
548
	if err := UpdateCard(c, card); err != nil {
549
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
550
			Success: false,
551
			Message: "Couldn't update the card",
552
			Data:    nil,
553
			Count:   0,
554
		})
555
	}
556
557
	log := queries.CreateLog(models.LogCardEdited, auth.User.Username+" edited "+card.Question)
558
	_ = queries.CreateUserLog(auth.User.ID, *log)
559
	_ = queries.CreateCardLog(card.ID, *log)
560
561
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
562
		Success: true,
563
		Message: "Success update card by ID",
564
		Data:    *card,
565
		Count:   1,
566
	})
567
}
568
569
// UpdateCard function
570
func UpdateCard(c *fiber.Ctx, card *models.Card) error {
571
	db := database.DBConn
572
573
	deckId := card.DeckID
574
575
	if err := c.BodyParser(&card); err != nil {
576
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
577
			Success: false,
578
			Message: err.Error(),
579
			Data:    nil,
580
			Count:   0,
581
		})
582
	}
583
584
	if deckId != card.DeckID {
585
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
586
			Success: false,
587
			Message: "You shouldn't change the deck of your card ! Don't try to break Memnix.",
588
			Data:    nil,
589
			Count:   0,
590
		})
591
	}
592
593
	if len(card.Question) <= 5 || len(card.Answer) <= 5 {
594
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
595
			Success: false,
596
			Message: "You must provide a question and an answer (at least 5char).",
597
			Data:    nil,
598
			Count:   0,
599
		})
600
	}
601
602
	db.Save(card)
603
604
	return nil
605
}
606
607
// DeleteCardById method
608
// @Description Delete a card
609
// @Summary deletes a card
610
// @Tags Card
611
// @Produce json
612
// @Success 200
613
// @Router /v1/cards/{cardID} [delete]
614
func DeleteCardById(c *fiber.Ctx) error {
615
	db := database.DBConn // DB Conn
616
	id := c.Params("id")
617
618
	auth := CheckAuth(c, models.PermUser) // Check auth
619
	if !auth.Success {
620
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
621
			Success: false,
622
			Message: auth.Message,
623
			Data:    nil,
624
			Count:   0,
625
		})
626
	}
627
628
	card := new(models.Card)
629
630
	if err := db.First(&card, id).Error; err != nil {
631
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
632
			Success: false,
633
			Message: err.Error(),
634
			Data:    nil,
635
			Count:   0,
636
		})
637
	}
638
639
	if res := queries.CheckAccess(c, auth.User.ID, card.DeckID, models.AccessOwner); !res.Success {
640
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
641
			Success: false,
642
			Message: "You don't have the permission to delete this card!",
643
			Data:    nil,
644
			Count:   0,
645
		})
646
	}
647
648
	db.Delete(card)
649
650
	log := queries.CreateLog(models.LogCardDeleted, auth.User.Username+" deleted "+card.Question)
651
	_ = queries.CreateUserLog(auth.User.ID, *log)
652
	_ = queries.CreateCardLog(card.ID, *log)
653
654
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
655
		Success: true,
656
		Message: "Success delete card by ID",
657
		Data:    *card,
658
		Count:   1,
659
	})
660
661
}
662