Passed
Push — main ( 619ee7...6c7dd4 )
by Yume
01:38
created

controllers.GetAllSubUsers   A

Complexity

Conditions 4

Size

Total Lines 32
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
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
10
	"github.com/gofiber/fiber/v2"
11
)
12
13
// GET
14
15
// GetAllDecks method to get all decks
16
// @Description Get every deck. Shouldn't really be used, consider using /v1/decks/public instead !
17
// @Summary get all decks
18
// @Tags Deck
19
// @Produce json
20
// @Success 200 {object} models.Deck
21
// @Router /v1/decks [get]
22
func GetAllDecks(c *fiber.Ctx) error {
23
	db := database.DBConn // DB Conn
24
25
	auth := CheckAuth(c, models.PermAdmin) // Check auth
26
	if !auth.Success {
27
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
28
			Success: false,
29
			Message: auth.Message,
30
			Data:    nil,
31
			Count:   0,
32
		})
33
	}
34
35
	var decks []models.Deck
36
37
	if res := db.Find(&decks); res.Error != nil {
38
39
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
40
			Success: false,
41
			Message: "Failed to get all decks",
42
			Data:    nil,
43
			Count:   0,
44
		})
45
	}
46
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
47
		Success: true,
48
		Message: "Get all decks",
49
		Data:    decks,
50
		Count:   len(decks),
51
	})
52
53
}
54
55
// GetDeckByID method to get a deck
56
// @Description Get a deck by tech ID
57
// @Summary get a deck
58
// @Tags Deck
59
// @Produce json
60
// @Param id path int true "Deck ID"
61
// @Success 200 {model} models.Deck
62
// @Router /v1/decks/{id} [get]
63
func GetDeckByID(c *fiber.Ctx) error {
64
	db := database.DBConn // DB Conn
65
66
	// Params
67
	id := c.Params("id")
68
69
	auth := CheckAuth(c, models.PermAdmin) // Check auth
70
	if !auth.Success {
71
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
72
			Success: false,
73
			Message: auth.Message,
74
			Data:    nil,
75
			Count:   0,
76
		})
77
	}
78
79
	deck := new(models.Deck)
80
81
	if err := db.First(&deck, id).Error; err != nil {
82
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
83
			Success: false,
84
			Message: err.Error(),
85
			Data:    nil,
86
			Count:   0,
87
		})
88
	}
89
90
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
91
		Success: true,
92
		Message: "Success get deck by ID.",
93
		Data:    *deck,
94
		Count:   1,
95
	})
96
}
97
98
// GetAllSubDecks method to get a deck
99
// @Description Get decks a user is sub to
100
// @Summary get a list of deck
101
// @Tags Deck
102
// @Produce json
103
// @Success 200 {array} models.Deck
104
// @Router /v1/decks/sub [get]
105
func GetAllSubDecks(c *fiber.Ctx) error {
106
	db := database.DBConn // DB Conn
107
108
	auth := CheckAuth(c, models.PermUser) // Check auth
109
	if !auth.Success {
110
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
111
			Success: false,
112
			Message: auth.Message,
113
			Data:    nil,
114
			Count:   0,
115
		})
116
	}
117
118
	var decks []models.Deck
119
120
	if err := db.Joins("JOIN accesses ON accesses.deck_id = decks.id AND accesses.user_id = ? AND accesses.permission >= ?", auth.User.ID, models.AccessStudent).Find(&decks).Error; err != nil {
121
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
122
			Success: false,
123
			Message: "Failed to get all sub decks",
124
			Data:    nil,
125
			Count:   0,
126
		})
127
	}
128
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
129
		Success: true,
130
		Message: "Get all sub decks",
131
		Data:    decks,
132
		Count:   len(decks),
133
	})
134
}
135
136
// GetAllSubUsers method to get a list of users
137
// @Description Get all the sub users to a deck
138
// @Summary get a list of users
139
// @Tags Deck
140
// @Produce json
141
// @Success 200 {array} models.User
142
// @Router /v1/decks/{deckID}/users [get]
143
func GetAllSubUsers(c *fiber.Ctx) error {
144
145
	// Params
146
	deckID := c.Params("id")
147
148
	auth := CheckAuth(c, models.PermUser) // Check auth
149
	if !auth.Success {
150
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
151
			Success: false,
152
			Message: auth.Message,
153
			Data:    nil,
154
			Count:   0,
155
		})
156
	}
157
158
	var users []models.User
159
	id, _ := strconv.ParseUint(deckID, 10, 32)
160
161
	if users = queries.GetSubUsers(c, uint(id)); len(users) == 0 || users == nil {
162
		return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
163
			Success: false,
164
			Message: "Couldn't get sub users",
165
			Data:    nil,
166
			Count:   0,
167
		})
168
	}
169
170
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
171
		Success: true,
172
		Message: "Get all sub users",
173
		Data:    users,
174
		Count:   len(users),
175
	})
176
}
177
178
// GetAllAvailableDecks method to get a list of deck
179
// @Description Get all public deck that you are not sub to
180
// @Summary get a list of deck
181
// @Tags Deck
182
// @Produce json
183
// @Success 200 {array} models.Deck
184
// @Router /v1/decks/available [get]
185
func GetAllAvailableDecks(c *fiber.Ctx) error {
186
	db := database.DBConn // DB Conn
187
188
	// Params
189
190
	auth := CheckAuth(c, models.PermUser) // Check auth
191
	if !auth.Success {
192
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
193
			Success: false,
194
			Message: auth.Message,
195
			Data:    nil,
196
			Count:   0,
197
		})
198
	}
199
200
	var decks []models.Deck
201
202
	if err := db.Joins("left join accesses ON decks.id = accesses.deck_id AND accesses.user_id = ?", auth.User.ID).Where("decks.status = ? AND ((accesses.deck_id IS NULL) OR (accesses.permission < ?))", models.DeckPublic, models.AccessStudent).Find(&decks).Error; err != nil {
203
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
204
			Success: false,
205
			Message: "Failed to get all public decks: " + err.Error(),
206
			Data:    nil,
207
			Count:   0,
208
		})
209
	}
210
211
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
212
		Success: true,
213
		Message: "Get all available decks",
214
		Data:    decks,
215
		Count:   len(decks),
216
	})
217
}
218
219
// GetAllPublicDecks method to get a list of deck
220
// @Description Get all public deck
221
// @Summary get a list of deck
222
// @Tags Deck
223
// @Produce json
224
// @Success 200 {array} models.Deck
225
// @Router /v1/decks/public [get]
226
func GetAllPublicDecks(c *fiber.Ctx) error {
227
	db := database.DBConn // DB Conn
228
229
	auth := CheckAuth(c, models.PermUser) // Check auth
230
	if !auth.Success {
231
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
232
			Success: false,
233
			Message: auth.Message,
234
			Data:    nil,
235
			Count:   0,
236
		})
237
	}
238
239
	var decks []models.Deck
240
241
	if err := db.Where("decks.status = ?", models.DeckPublic).Find(&decks).Error; err != nil {
242
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
243
			Success: false,
244
			Message: "Failed to get all public decks",
245
			Data:    nil,
246
			Count:   0,
247
		})
248
	}
249
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
250
		Success: true,
251
		Message: "Get all public decks",
252
		Data:    decks,
253
		Count:   len(decks),
254
	})
255
}
256
257
// POST
258
259
// CreateNewDeck method
260
// @Description Create a new deck
261
// @Summary create a deck
262
// @Tags Deck
263
// @Produce json
264
// @Success 200
265
// @Accept json
266
// @Param deck body models.Deck true "Deck to create"
267
// @Router /v1/decks/new [post]
268
func CreateNewDeck(c *fiber.Ctx) error {
269
	db := database.DBConn // DB Conn
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
	deck := new(models.Deck)
282
283
	if err := c.BodyParser(&deck); err != nil {
284
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
285
			Success: false,
286
			Message: err.Error(),
287
			Data:    nil,
288
			Count:   0,
289
		})
290
	}
291
292
	if len(deck.DeckName) <= 5 {
293
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
294
			Success: false,
295
			Message: "Your deck's name should be at least 5 char long.",
296
			Data:    nil,
297
			Count:   0,
298
		})
299
	}
300
301
	deck.Status = models.DeckPrivate
302
303
	db.Create(deck)
304
305
	if err := queries.GenerateCreatorAccess(c, &auth.User, deck); !err.Success {
306
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
307
			Success: false,
308
			Message: err.Message,
309
			Data:    nil,
310
			Count:   0,
311
		})
312
	}
313
314
	log := queries.CreateLog(models.LogDeckCreated, auth.User.Username+" created "+deck.DeckName)
315
	_ = queries.CreateUserLog(auth.User.ID, *log)
316
	_ = queries.CreateDeckLog(deck.ID, *log)
317
318
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
319
		Success: true,
320
		Message: "Success register a deck",
321
		Data:    *deck,
322
		Count:   1,
323
	})
324
}
325
326
// UnSubToDeck method
327
// @Description Unsubscribe to a deck
328
// @Summary unsub deck
329
// @Tags Deck
330
// @Produce json
331
// @Success 200
332
// @Accept json
333
// @Router /v1/decks/{deckID}/unsubscribe [post]
334
func UnSubToDeck(c *fiber.Ctx) error {
335
	db := database.DBConn // DB Conn
336
337
	auth := CheckAuth(c, models.PermUser) // Check auth
338
	if !auth.Success {
339
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
340
			Success: false,
341
			Message: auth.Message,
342
			Data:    nil,
343
			Count:   0,
344
		})
345
	}
346
347
	// Params
348
	deckID := c.Params("id")
349
350
	access := new(models.Access)
351
	if err := db.Joins("User").Joins("Deck").Where("accesses.user_id = ? AND accesses.deck_id =?", auth.User.ID, deckID).Find(&access).Error; err != nil {
352
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
353
			Success: false,
354
			Message: "This user isn't sub to the deck",
355
			Data:    nil,
356
			Count:   0,
357
		})
358
	}
359
360
	access.Permission = 0
361
	db.Preload("User").Preload("Deck").Save(access)
362
363
	_ = queries.DeleteRating(c, &auth.User, &access.Deck)
364
365
	log := queries.CreateLog(models.LogUnsubscribe, auth.User.Username+" unsubscribed to "+access.Deck.DeckName)
366
	_ = queries.CreateUserLog(auth.User.ID, *log)
367
	_ = queries.CreateDeckLog(access.Deck.ID, *log)
368
369
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
370
		Success: true,
371
		Message: "Success unsub to the deck",
372
		Data:    nil,
373
		Count:   0,
374
	})
375
}
376
377
// SubToDeck method
378
// @Description Subscribe to a deck
379
// @Summary sub deck
380
// @Tags Deck
381
// @Produce json
382
// @Success 200
383
// @Accept json
384
// @Router /v1/decks/{deckID}/subscribe [post]
385
func SubToDeck(c *fiber.Ctx) error {
386
	db := database.DBConn // DB Conn
387
	deckID := c.Params("id")
388
	deck := new(models.Deck)
389
390
	// Check auth
391
	auth := CheckAuth(c, models.PermUser)
392
	if !auth.Success {
393
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
394
			Success: false,
395
			Message: auth.Message,
396
			Data:    nil,
397
			Count:   0,
398
		})
399
	}
400
401
	if err := db.First(&deck, deckID).Error; err != nil {
402
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
403
			Success: false,
404
			Message: err.Error(),
405
			Data:    nil,
406
			Count:   0,
407
		})
408
	}
409
410
	if err := queries.GenerateAccess(c, &auth.User, deck); !err.Success {
411
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
412
			Success: false,
413
			Message: err.Message,
414
			Data:    nil,
415
			Count:   0,
416
		})
417
	}
418
419
	if err := queries.PopulateMemDate(c, &auth.User, deck); !err.Success {
420
		return c.Status(http.StatusInternalServerError).JSON(models.ResponseHTTP{
421
			Success: false,
422
			Message: err.Message,
423
			Data:    nil,
424
			Count:   0,
425
		})
426
	}
427
428
	log := queries.CreateLog(models.LogSubscribe, auth.User.Username+" subscribed to "+deck.DeckName)
429
	_ = queries.CreateUserLog(auth.User.ID, *log)
430
	_ = queries.CreateDeckLog(deck.ID, *log)
431
432
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
433
		Success: true,
434
		Message: "Success subscribing to deck",
435
		Data:    nil,
436
		Count:   0,
437
	})
438
}
439
440
// PUT
441
442
// UpdateDeckByID method
443
// @Description Edit a deck
444
// @Summary edit a deck
445
// @Tags Deck
446
// @Produce json
447
// @Success 200
448
// @Accept json
449
// @Param deck body models.Deck true "Deck to edit"
450
// @Router /v1/decks/{deckID}/edit [put]
451
func UpdateDeckByID(c *fiber.Ctx) error {
452
	db := database.DBConn // DB Conn
453
454
	// Params
455
	id := c.Params("id")
456
457
	auth := CheckAuth(c, models.PermUser) // Check auth
458
	if !auth.Success {
459
		return c.Status(http.StatusUnauthorized).JSON(models.ResponseHTTP{
460
			Success: false,
461
			Message: auth.Message,
462
			Data:    nil,
463
			Count:   0,
464
		})
465
	}
466
467
	deck := new(models.Deck)
468
469
	if err := db.First(&deck, id).Error; err != nil {
470
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
471
			Success: false,
472
			Message: err.Error(),
473
			Data:    nil,
474
			Count:   0,
475
		})
476
	}
477
478
	if res := queries.CheckAccess(c, auth.User.ID, deck.ID, models.AccessOwner); !res.Success {
479
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
480
			Success: false,
481
			Message: "You don't have the permission to edit this deck!",
482
			Data:    nil,
483
			Count:   0,
484
		})
485
	}
486
487
	if err := UpdateDeck(c, deck); err != nil {
488
		return c.Status(http.StatusServiceUnavailable).JSON(models.ResponseHTTP{
489
			Success: false,
490
			Message: "Couldn't update the deck",
491
			Data:    nil,
492
			Count:   0,
493
		})
494
	}
495
496
	log := queries.CreateLog(models.LogDeckEdited, auth.User.Username+" edited "+deck.DeckName)
497
	_ = queries.CreateUserLog(auth.User.ID, *log)
498
	_ = queries.CreateDeckLog(deck.ID, *log)
499
500
	return c.Status(http.StatusOK).JSON(models.ResponseHTTP{
501
		Success: true,
502
		Message: "Success update deck by ID",
503
		Data:    *deck,
504
		Count:   1,
505
	})
506
}
507
508
// UpdateDeck
509
func UpdateDeck(c *fiber.Ctx, d *models.Deck) error {
510
	db := database.DBConn
511
512
	if err := c.BodyParser(&d); err != nil {
513
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
514
			Success: false,
515
			Message: err.Error(),
516
			Data:    nil,
517
			Count:   0,
518
		})
519
	}
520
521
	if len(d.DeckName) <= 5 {
522
		return c.Status(http.StatusBadRequest).JSON(models.ResponseHTTP{
523
			Success: false,
524
			Message: "Your deck's name should be at least 5 char long.",
525
			Data:    nil,
526
			Count:   0,
527
		})
528
	}
529
530
	db.Save(d)
531
532
	return nil
533
}
534