Passed
Push — main ( bec8e4...0fa79f )
by Yume
01:36
created

controllers.UpdateCard   A

Complexity

Conditions 5

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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