Backend/internal/api/services/friends/friend_add.go
2024-12-06 21:53:09 +01:00

121 lines
3.4 KiB
Go
Executable file

/*
ScheduleTogether Backend
Copyright (C) 2024, Zervó Zadachin
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License version 3
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License version 3 for more details.
This program incorporates external libraries for certain functionalities.
These libraries are covered by their respective licenses, and their usage
agreements are as outlined in their respective documentation or source
code.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package friends
import (
"slices"
"github.com/kataras/iris/v12"
db "git.zervo.org/scheduletogether/backend/internal/database"
"git.zervo.org/scheduletogether/backend/pkg/helpers/request"
"git.zervo.org/scheduletogether/backend/pkg/types"
)
func FriendAdd_Service(ctx iris.Context, req types.FriendsAddRequest) {
// Start a transaction
tx := db.Db.Begin()
// Get requesting user's ID from claims
claims := request.GetUserClaims(ctx)
id := claims.UserId
// Make sure target user exists
// Here target refers to the user *receiving* the request
var targetUser db.User
err := tx.Where("username = ?", req.Username).First(&targetUser).Error
if err != nil {
tx.Rollback()
ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{
Error: "User does not exist",
})
return
}
// Get user from database
// Here source user refers to the user *sending* the request
var sourceUser db.User
err = tx.Where("id = ?", id).First(&sourceUser).Error
if err != nil {
tx.Rollback()
ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(types.CommonErrorResponse{
Error: "Failed to retrieve user from the database",
})
logboi.Warn("Failed to retrieve user from the database: " + err.Error())
return
}
// Make sure users are not already friends
if slices.Contains(sourceUser.Friends, targetUser.Uuid) {
tx.Rollback()
ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{
Error: "You are already friends with this user",
})
}
// Make sure friend request has not already been sent
var friendRequest db.FriendRequest
err = tx.Where("target = ? AND source = ?", targetUser.Uuid, sourceUser.Uuid).First(&friendRequest).Error
if err == nil {
tx.Rollback()
ctx.StatusCode(iris.StatusBadRequest)
ctx.JSON(types.CommonErrorResponse{
Error: "Friend request already sent",
})
return
}
// Add friend request
err = tx.Create(&db.FriendRequest{
Source: sourceUser.Uuid,
Target: targetUser.Uuid,
}).Error
if err != nil {
tx.Rollback()
ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(types.CommonErrorResponse{
Error: "Something went wrong, please try again later",
})
return
}
// Commit the transaction if everything is successful
err = tx.Commit().Error
if err != nil {
tx.Rollback()
ctx.StatusCode(iris.StatusInternalServerError)
ctx.JSON(types.CommonErrorResponse{
Error: "Something went wrong, please try again later",
})
return
}
ctx.JSON(types.CommonMessageResponse{
Message: "Friend request sent",
})
}