Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

188 make all users follow sac super club #255

Merged
merged 15 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/src/controllers/category.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func NewCategoryController(categoryService services.CategoryServiceInterface) *C
// @Failure 400 {string} errors.Error
// @Failure 401 {string} errors.Error
// @Failure 404 {string} errors.Error
// @Failure 409 {string} errors.Error
// @Failure 500 {string} errors.Error
// @Router /categories/ [post]
func (cat *CategoryController) CreateCategory(c *fiber.Ctx) error {
Expand Down
1 change: 1 addition & 0 deletions backend/src/controllers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func NewUserController(userService services.UserServiceInterface) *UserControlle
// @Failure 400 {object} errors.Error
// @Failure 401 {object} errors.Error
// @Failure 404 {object} errors.Error
// @Failure 409 {object} errors.Error
// @Failure 500 {object} errors.Error
// @Router /users/ [post]
func (u *UserController) CreateUser(c *fiber.Ctx) error {
Expand Down
3 changes: 2 additions & 1 deletion backend/src/controllers/user_follower.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import (
"github.com/GenerateNU/sac/backend/src/services"
"github.com/GenerateNU/sac/backend/src/utilities"
"github.com/gofiber/fiber/v2"
)

Expand Down Expand Up @@ -33,7 +34,7 @@ func (uf *UserFollowerController) CreateFollowing(c *fiber.Ctx) error {
if err != nil {
return err.FiberError(c)
}
return c.SendStatus(fiber.StatusCreated)
return utilities.FiberMessage(c, fiber.StatusCreated, "Successfully followed club")
}

// DeleteFollowing godoc
Expand Down
3 changes: 2 additions & 1 deletion backend/src/controllers/user_member.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import (
"github.com/GenerateNU/sac/backend/src/services"
"github.com/GenerateNU/sac/backend/src/utilities"
"github.com/gofiber/fiber/v2"
)

Expand Down Expand Up @@ -34,7 +35,7 @@ func (um *UserMemberController) CreateMembership(c *fiber.Ctx) error {
return err.FiberError(c)
}

return c.SendStatus(fiber.StatusCreated)
return utilities.FiberMessage(c, fiber.StatusCreated, "Successfully joined club")
}

// DeleteMembership godoc
Expand Down
28 changes: 21 additions & 7 deletions backend/src/database/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ func MigrateDB(settings config.Settings, db *gorm.DB) error {
return err
}

// Check if the database already has a super user
var superUser models.User
if err := db.Where("role = ?", models.Super).First(&superUser).Error; err != nil {
if err := createSuperUser(settings, db); err != nil {
Expand All @@ -112,26 +111,30 @@ func createSuperUser(settings config.Settings, db *gorm.DB) error {
var user models.User

if err := db.Where("nuid = ?", superUser.NUID).First(&user).Error; err != nil {
tx := db.Begin()
tx := db.Begin().Session(&gorm.Session{SkipHooks: true})

if err := tx.Error; err != nil {
return err
}

if err := tx.Create(&superUser).Error; err != nil {
superClub := SuperClub()
if err := tx.Create(&superClub).Error; err != nil {
tx.Rollback()
return err
}

SuperUserUUID = superUser.ID

superClub := SuperClub()
if err := tx.Model(&superClub).Update("num_members", gorm.Expr("num_members + 1")).Error; err != nil {
tx.Rollback()
return err
}

if err := tx.Create(&superClub).Error; err != nil {
if err := tx.Create(&superUser).Error; err != nil {
tx.Rollback()
return err
}

SuperUserUUID = superUser.ID

membership := models.Membership{
ClubID: superClub.ID,
UserID: superUser.ID,
Expand All @@ -143,7 +146,18 @@ func createSuperUser(settings config.Settings, db *gorm.DB) error {
return err
}

follower := models.Follower{
ClubID: superClub.ID,
UserID: superUser.ID,
}

if err := tx.Create(&follower).Error; err != nil {
tx.Rollback()
return err
}

return tx.Commit().Error
}

return nil
}
8 changes: 8 additions & 0 deletions backend/src/errors/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,12 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get club events",
}
FailedToJoinClub = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to join club",
}
AlreadyMemberOfClub = Error{
StatusCode: fiber.StatusBadRequest,
Message: "already member of club",
}
)
4 changes: 4 additions & 0 deletions backend/src/errors/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,8 @@ var (
StatusCode: fiber.StatusNotFound,
Message: "user not following club",
}
FailedToFollowClub = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to follow club",
}
)
12 changes: 1 addition & 11 deletions backend/src/models/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Club struct {

SoftDeletedAt gorm.DeletedAt `gorm:"type:timestamptz;default:NULL" json:"-" validate:"-"`

Name string `gorm:"type:varchar(255)" json:"name" validate:"required,max=255"`
Name string `gorm:"type:varchar(255);unique" json:"name" validate:"required,max=255"`
Preview string `gorm:"type:varchar(255)" json:"preview" validate:"required,max=255"`
Description string `gorm:"type:varchar(255)" json:"description" validate:"required,http_url,mongo_url,max=255"` // MongoDB URL
NumMembers int `gorm:"type:int" json:"num_members" validate:"required,min=1"`
Expand Down Expand Up @@ -114,16 +114,6 @@ func (cqp *ClubQueryParams) IntoWhere() string {
return "WHERE " + strings.Join(conditions, " AND ")
}

func (c *Club) AfterCreate(tx *gorm.DB) (err error) {
tx.Model(&c).Update("num_members", c.NumMembers+1)
return
}

func (c *Club) AfterDelete(tx *gorm.DB) (err error) {
tx.Model(&c).Update("num_members", c.NumMembers-1)
return
}

func (c *Club) SearchId() string {
return c.ID.String()
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/models/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type Series struct {

// TODO: add not null to required fields on all gorm models
type EventSeries struct {
EventID uuid.UUID `gorm:"not null; type:uuid; primary_key;" json:"event_id" validate:"uuid4"`
EventID uuid.UUID `gorm:"not null; type:uuid; primaryKey;" json:"event_id" validate:"uuid4"`
Event Event `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
SeriesID uuid.UUID `gorm:"not null; type:uuid;" json:"series_id" validate:"uuid4"`
Series Series `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Expand Down
17 changes: 17 additions & 0 deletions backend/src/models/follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package models

import (
"github.com/google/uuid"
)

func (Follower) TableName() string {
return "user_club_followers"
}

type Follower struct {
UserID uuid.UUID `gorm:"type:uuid;not null;primaryKey" json:"user_id" validate:"required,uuid4"`
ClubID uuid.UUID `gorm:"type:uuid;not null;primaryKey" json:"club_id" validate:"required,uuid4"`

Club *Club `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
}
14 changes: 5 additions & 9 deletions backend/src/models/membership.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package models

import "github.com/google/uuid"
import (
"github.com/google/uuid"
)

type MembershipType string

Expand All @@ -9,19 +11,13 @@ const (
MembershipTypeAdmin MembershipType = "admin"
)

type Tabler interface {
TableName() string
}

func (Membership) TableName() string {
return "user_club_members"
}

type Membership struct {
Model

UserID uuid.UUID `gorm:"type:uuid;not null" json:"user_id" validate:"required,uuid4"`
ClubID uuid.UUID `gorm:"type:uuid;not null" json:"club_id" validate:"required,uuid4"`
UserID uuid.UUID `gorm:"type:uuid;not null;primaryKey" json:"user_id" validate:"required,uuid4"`
ClubID uuid.UUID `gorm:"type:uuid;not null;primaryKey" json:"club_id" validate:"required,uuid4"`

Club *Club `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
User *User `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Expand Down
6 changes: 5 additions & 1 deletion backend/src/models/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import (
"github.com/google/uuid"
)

type Tabler interface {
TableName() string
}

type Model struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id" example:"123e4567-e89b-12d3-a456-426614174000"`
ID uuid.UUID `gorm:"type:uuid;primaryKey;default:uuid_generate_v4()" json:"id" example:"123e4567-e89b-12d3-a456-426614174000"`
CreatedAt time.Time `gorm:"type:timestamp;default:CURRENT_TIMESTAMP" json:"created_at" example:"2023-09-20T16:34:50Z"`
UpdatedAt time.Time `gorm:"type:timestamp;default:CURRENT_TIMESTAMP" json:"updated_at" example:"2023-09-20T16:34:50Z"`
}
35 changes: 35 additions & 0 deletions backend/src/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package models

import (
"github.com/google/uuid"
"gorm.io/gorm"
)

type UserRole string
Expand Down Expand Up @@ -89,3 +90,37 @@ type UpdatePasswordRequestBody struct {
type CreateUserTagsBody struct {
Tags []uuid.UUID `json:"tags" validate:"required"`
}

func (u *User) AfterCreate(tx *gorm.DB) (err error) {
sac := &Club{}
if err := tx.Where("name = ?", "SAC").First(sac).Error; err != nil {
return err
}

if err := tx.Model(u).Association("Member").Append(sac); err != nil {
return err
}

if err := tx.Model(u).Association("Follower").Append(sac); err != nil {
return err
}

if err := tx.Model(&Club{}).Where("id = ?", sac.ID).Update("num_members", gorm.Expr("num_members + 1")).Error; err != nil {
return err
}

return nil
}

func (u *User) AfterDelete(tx *gorm.DB) (err error) {
sac := &Club{}
if err := tx.Where("name = ?", "SAC").First(sac).Error; err != nil {
return err
}

if err := tx.Model(&Club{}).Where("id = ?", sac.ID).Update("num_members", gorm.Expr("num_members - 1")).Error; err != nil {
return err
}

return nil
}
2 changes: 1 addition & 1 deletion backend/src/services/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (a *AuthService) UpdatePassword(id string, passwordBody models.UpdatePasswo
return err
}

correct, passwordErr := auth.ComparePasswordAndHash(passwordBody.OldPassword, passwordHash)
correct, passwordErr := auth.ComparePasswordAndHash(passwordBody.OldPassword, *passwordHash)
if passwordErr != nil || !correct {
return &errors.FailedToValidateUser
}
Expand Down
15 changes: 14 additions & 1 deletion backend/src/transactions/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,25 @@ func CreateClub(db *gorm.DB, userId uuid.UUID, club models.Club) (*models.Club,

tx := db.Begin()

club.NumMembers = 1

if err := tx.Create(&club).Error; err != nil {
tx.Rollback()
return nil, &errors.FailedToCreateClub
}

if err := tx.Model(&club).Association("Admin").Append(user); err != nil {
membership := models.Membership{
ClubID: club.ID,
UserID: user.ID,
MembershipType: models.MembershipTypeAdmin,
}

if err := tx.Create(&membership).Error; err != nil {
tx.Rollback()
return nil, &errors.FailedToCreateClub
}

if err := tx.Model(&user).Association("Follower").Append(&club); err != nil {
tx.Rollback()
return nil, &errors.FailedToCreateClub
}
Expand Down
11 changes: 5 additions & 6 deletions backend/src/transactions/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ func GetUser(db *gorm.DB, id uuid.UUID, preloads ...OptionalQuery) (*models.User
return &user, nil
}

func GetUserPasswordHash(db *gorm.DB, id uuid.UUID) (string, *errors.Error) {
func GetUserPasswordHash(db *gorm.DB, id uuid.UUID) (*string, *errors.Error) {
var user models.User
if err := db.Select("password_hash").First(&user, id).Error; err != nil {
if stdliberrors.Is(err, gorm.ErrRecordNotFound) {
return "", &errors.UserNotFound
return nil, &errors.UserNotFound
} else {
return "", &errors.FailedToGetUser
return nil, &errors.FailedToGetUser
}
}

return user.PasswordHash, nil
return &user.PasswordHash, nil
}

func UpdateUser(db *gorm.DB, id uuid.UUID, user models.User) (*models.User, *errors.Error) {
Expand Down Expand Up @@ -107,8 +107,7 @@ func UpdatePassword(db *gorm.DB, id uuid.UUID, passwordHash string) *errors.Erro
}

func DeleteUser(db *gorm.DB, id uuid.UUID) *errors.Error {
result := db.Delete(&models.User{}, id)
if result.RowsAffected == 0 {
if result := db.Delete(&models.User{}, id); result.RowsAffected == 0 {
if result.Error == nil {
return &errors.UserNotFound
} else {
Expand Down
20 changes: 4 additions & 16 deletions backend/src/transactions/user_follower.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package transactions

import (
"slices"

"github.com/GenerateNU/sac/backend/src/errors"
"github.com/GenerateNU/sac/backend/src/models"
"github.com/google/uuid"
Expand All @@ -21,35 +19,25 @@ func CreateFollowing(db *gorm.DB, userId uuid.UUID, clubId uuid.UUID) *errors.Er
}

if err := db.Model(&user).Association("Follower").Append(club); err != nil {
return &errors.FailedToUpdateUser
return &errors.FailedToFollowClub
}

return nil
}

func DeleteFollowing(db *gorm.DB, userId uuid.UUID, clubId uuid.UUID) *errors.Error {
user, err := GetUser(db, userId, PreloadFollwer())
user, err := GetUser(db, userId)
if err != nil {
return err
}

club, err := GetClub(db, clubId, PreloadFollwer())
club, err := GetClub(db, clubId)
if err != nil {
return err
}

userFollowingClubIDs := make([]uuid.UUID, len(user.Follower))

for i, club := range user.Follower {
userFollowingClubIDs[i] = club.ID
}

if !slices.Contains(userFollowingClubIDs, club.ID) {
return &errors.UserNotFollowingClub
}

if err := db.Model(&user).Association("Follower").Delete(club); err != nil {
return &errors.FailedToUpdateUser
return &errors.UserNotFollowingClub
}

return nil
Expand Down
Loading
Loading