Skip to content

Commit 7252698

Browse files
authored
Merge branch 'master' into master
2 parents ccf8c59 + 8841f81 commit 7252698

8 files changed

Lines changed: 93 additions & 61 deletions

File tree

internal/controllers/auth.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ import (
77

88
"github.com/CodeChefVIT/cookoff-backend/internal/db"
99
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/auth"
10-
helpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/auth"
1110
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/database"
1211
httphelpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/http"
1312
logger "github.com/CodeChefVIT/cookoff-backend/internal/helpers/logging"
1413
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/validator"
1514
"github.com/google/uuid"
15+
"github.com/jackc/pgx/v5"
1616
"github.com/jackc/pgx/v5/pgtype"
1717
"golang.org/x/crypto/bcrypt"
1818
)
1919

2020
type LoginRequest struct {
21-
Email string `json:"email" validate:"required"`
21+
Email string `json:"email" validate:"required,email"`
2222
Password string `json:"password" validate:"required"`
2323
}
2424

2525
type SignupRequest struct {
26-
Email string `json:"email" validate:"required"`
27-
Name string `json:"name" validate:"required"`
28-
RegNo string `json:"reg_no" validate:"required"`
26+
Email string `json:"email" validate:"required"`
27+
Name string `json:"name" validate:"required"`
28+
RegNo string `json:"reg_no" validate:"required"`
2929
Key string `json:"fuck_you" validate:"required"`
3030
}
3131

@@ -93,32 +93,32 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
9393

9494
user, err := database.Queries.GetUserByEmail(r.Context(), req.Email)
9595
if err != nil {
96-
logger.Errof("User not found or invalid credentials for email: %s, err: %v", req.Email, err)
97-
httphelpers.WriteError(w, http.StatusUnauthorized, "invalid credentials")
96+
if errors.Is(err, pgx.ErrNoRows) {
97+
httphelpers.WriteError(w, http.StatusNotFound, "user not found")
98+
return
99+
}
100+
logger.Infof("received error from database %v", err.Error())
101+
httphelpers.WriteError(w, http.StatusInternalServerError, "some error occurred")
98102
return
99103
}
100104

101105
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
102106
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
103-
httphelpers.WriteJSON(w, http.StatusBadRequest, map[string]string{
104-
"message": "invalid password",
105-
})
107+
httphelpers.WriteError(w, http.StatusConflict, "invalid password")
106108
return
107109
}
108110
httphelpers.WriteError(w, http.StatusInternalServerError, err.Error())
109111
}
110112

111-
accessToken, err := helpers.GenerateJWT(&user, false)
113+
accessToken, err := auth.GenerateJWT(&user, false)
112114
if err != nil {
113-
logger.Errof("Failed to generate access token for user: %s, err: %v", user.Email, err)
114-
httphelpers.WriteError(w, http.StatusUnauthorized, "failed to generate token")
115+
httphelpers.WriteError(w, http.StatusInternalServerError, "failed to generate token")
115116
return
116117
}
117118

118-
refreshToken, err := helpers.GenerateJWT(&user, true)
119+
refreshToken, err := auth.GenerateJWT(&user, true)
119120
if err != nil {
120-
logger.Errof("Failed to generate refresh token for user: %s, err: %v", user.Email, err)
121-
httphelpers.WriteError(w, http.StatusUnauthorized, "failed to generate token")
121+
httphelpers.WriteError(w, http.StatusInternalServerError, "failed to generate token")
122122
return
123123
}
124124

@@ -150,6 +150,6 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
150150

151151
httphelpers.WriteJSON(w, http.StatusOK, map[string]any{
152152
"message": "Login successful",
153-
"user": data,
153+
"data": data,
154154
})
155155
}

internal/controllers/me.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import (
44
"fmt"
55
"net/http"
66

7-
"github.com/CodeChefVIT/cookoff-backend/internal/db"
87
helpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/auth"
98
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/database"
109
httphelpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/http"
1110
logger "github.com/CodeChefVIT/cookoff-backend/internal/helpers/logging"
1211
"github.com/google/uuid"
1312
)
1413

14+
type DashboardSubmission struct {
15+
Title string `json:"title"`
16+
Description string `json:"description"`
17+
Score int `json:"score"`
18+
}
19+
1520
func MeHandler(w http.ResponseWriter, r *http.Request) {
1621
id, err := helpers.GetUserID(w, r)
1722
if err != nil {
@@ -33,11 +38,15 @@ func MeHandler(w http.ResponseWriter, r *http.Request) {
3338
return
3439
}
3540

36-
var submissionsByRound = make(map[string][]db.GetSubmissionsWithRoundByUserIdRow)
41+
var submissionsByRound = make(map[string][]DashboardSubmission)
3742

3843
for _, submission := range submissions {
3944
round := fmt.Sprint(submission.Round)
40-
submissionsByRound[round] = append(submissionsByRound[round], db.GetSubmissionsWithRoundByUserIdRow(submission))
45+
submissionsByRound[round] = append(submissionsByRound[round], DashboardSubmission{
46+
Title: *submission.Title,
47+
Description: *submission.Description,
48+
Score: 0,
49+
})
4150
}
4251

4352
data := map[string]any{

internal/controllers/questions.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ type QuestionRequest struct {
3737
OutputFormat *string `json:"output_format"`
3838
}
3939

40+
type QuestionByRoundResp struct {
41+
Question db.Question `json:"question"`
42+
Testcases []db.GetTestCasesByQuestionRow `json:"testcases"`
43+
}
44+
4045
func GetAllQuestion(w http.ResponseWriter, r *http.Request) {
4146
ctx := r.Context()
4247
fetchedQuestions, err := database.Queries.GetQuestions(ctx)
@@ -79,7 +84,22 @@ func GetQuestionsByRound(w http.ResponseWriter, r *http.Request) {
7984
httphelpers.WriteError(w, http.StatusBadRequest, err.Error())
8085
return
8186
}
82-
httphelpers.WriteJSON(w, 200, questions)
87+
88+
response := []QuestionByRoundResp{}
89+
for _, question := range questions {
90+
testcase, err := database.Queries.GetTestCasesByQuestion(ctx, question.ID)
91+
if err != nil {
92+
httphelpers.WriteError(w, http.StatusBadRequest, err.Error())
93+
return
94+
}
95+
resp := QuestionByRoundResp{
96+
Question: question,
97+
Testcases: testcase,
98+
}
99+
response = append(response, resp)
100+
}
101+
102+
httphelpers.WriteJSON(w, 200, response)
83103
}
84104

85105
func CreateQuestion(w http.ResponseWriter, r *http.Request) {

internal/controllers/refresh_token.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package controllers
22

33
import (
4+
"errors"
45
"net/http"
56

67
helpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/auth"
@@ -9,6 +10,7 @@ import (
910
logger "github.com/CodeChefVIT/cookoff-backend/internal/helpers/logging"
1011
"github.com/go-chi/jwtauth/v5"
1112
"github.com/google/uuid"
13+
"github.com/jackc/pgx/v5"
1214
)
1315

1416
func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
@@ -42,15 +44,17 @@ func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
4244

4345
user, err := database.Queries.GetUserById(r.Context(), userIdUUID)
4446
if err != nil {
47+
if errors.Is(err, pgx.ErrNoRows) {
48+
httphelpers.WriteError(w, http.StatusUnauthorized, "user not found")
49+
return
50+
}
4551
logger.Errof("User not found: %s, err: %v", user.Name, err)
46-
httphelpers.WriteError(w, http.StatusUnauthorized, "user not found")
4752
return
4853
}
4954

5055
accessToken, err := helpers.GenerateJWT(&user, false)
5156
if err != nil {
52-
logger.Errof("Failed to generate new access token for user: %s, err: %v", user.Name, err)
53-
httphelpers.WriteError(w, http.StatusUnauthorized, "failed to generate token")
57+
httphelpers.WriteError(w, http.StatusInternalServerError, "failed to generate token")
5458
return
5559
}
5660

@@ -66,8 +70,7 @@ func RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
6670

6771
refreshToken, err := helpers.GenerateJWT(&user, true)
6872
if err != nil {
69-
logger.Errof("Failed to generate new refresh token for user: %s, err: %v", user.Name, err)
70-
httphelpers.WriteError(w, http.StatusUnauthorized, "failed to generate token")
73+
httphelpers.WriteError(w, http.StatusInternalServerError, "failed to generate token")
7174
return
7275
}
7376

internal/controllers/testcase.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import (
1616
)
1717

1818
type createTestCaseRequest struct {
19-
ExpectedOutput string `json:"expected_output" validate:"required"`
20-
Memory string `json:"memory" validate:"required"`
21-
Input string `json:"input" validate:"required"`
22-
Hidden *bool `json:"hidden" validate:"required"`
23-
QuestionID string `json:"question_id" validate:"required"`
24-
Runtime float64 `json:"runtime" validate:"required"`
19+
ExpectedOutput string `json:"expected_output" validate:"required,omitempty"`
20+
Memory string `json:"memory" validate:"required,omitempty"`
21+
Input string `json:"input" validate:"required,omitempty"`
22+
Hidden *bool `json:"hidden" validate:"required,omitempty"`
23+
QuestionID string `json:"question_id" validate:"required,omitempty"`
24+
Runtime float64 `json:"runtime,string" validate:"required,omitempty"`
2525
}
2626

2727
func CreateTestCaseHandler(w http.ResponseWriter, r *http.Request) {
@@ -40,7 +40,7 @@ func CreateTestCaseHandler(w http.ResponseWriter, r *http.Request) {
4040
return
4141
}
4242

43-
var newTestCase = db.CreateTestCaseParams{
43+
newTestCase := db.CreateTestCaseParams{
4444
ExpectedOutput: testCase.ExpectedOutput,
4545
Memory: testCase.Memory,
4646
Input: testCase.Input,
@@ -114,7 +114,7 @@ func UpdateTestCaseHandler(w http.ResponseWriter, r *http.Request) {
114114
return
115115
}
116116

117-
var updateData = db.UpdateTestCaseParams{
117+
updateData := db.UpdateTestCaseParams{
118118
ExpectedOutput: originalTestCase.ExpectedOutput,
119119
Memory: originalTestCase.Memory,
120120
Input: originalTestCase.Input,
@@ -153,7 +153,11 @@ func UpdateTestCaseHandler(w http.ResponseWriter, r *http.Request) {
153153
return
154154
}
155155

156-
httphelpers.WriteJSON(w, http.StatusOK, map[string]string{"message": "Test case updated successfully"})
156+
httphelpers.WriteJSON(
157+
w,
158+
http.StatusOK,
159+
map[string]string{"message": "Test case updated successfully"},
160+
)
157161
}
158162

159163
func DeleteTestCaseHandler(w http.ResponseWriter, r *http.Request) {
@@ -194,5 +198,4 @@ func GetTestCaseByQuestionID(w http.ResponseWriter, r *http.Request) {
194198
"message": "fetched testcases",
195199
"data": testCases,
196200
})
197-
198201
}
Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
package auth
22

33
import (
4-
"fmt"
54
"net/http"
65

76
httphelpers "github.com/CodeChefVIT/cookoff-backend/internal/helpers/http"
87
"github.com/go-chi/jwtauth/v5"
98
)
109

11-
func RoleFromToken (w http.ResponseWriter,r *http.Request, user string) bool {
10+
func RoleFromToken(w http.ResponseWriter, r *http.Request, requiredRole string) bool {
1211
_, claims, err := jwtauth.FromContext(r.Context())
1312
if err != nil {
1413
httphelpers.WriteError(w, http.StatusUnauthorized, err.Error())
1514
return false
1615
}
17-
role, ok := claims["role"].(string)
18-
if !ok {
19-
http.Error(w, "Role not found in token", http.StatusUnauthorized)
20-
return ok
21-
}
22-
if role != user {
23-
msg := fmt.Sprintf("Access Denied: %s not allowed", role)
24-
httphelpers.WriteError(w, http.StatusForbidden, msg)
25-
return false
26-
}
27-
return true
28-
}
16+
role := claims["role"].(string)
17+
18+
return role != requiredRole
19+
}
20+

internal/server/routes.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func (s *Server) RegisterRoutes(taskClient *asynq.Client) http.Handler {
2626

2727
r.Post("/login/user", controllers.LoginHandler)
2828
r.Post("/token/refresh", controllers.RefreshTokenHandler)
29+
2930
r.Group(func(protected chi.Router) {
3031
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Post("/upgrade", controllers.UpgradeUserToRound)
3132
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Post("/roast", controllers.BanUser)
@@ -37,14 +38,18 @@ func (s *Server) RegisterRoutes(taskClient *asynq.Client) http.Handler {
3738

3839
protected.Get("/me", controllers.MeHandler)
3940
protected.Get("/protected", controllers.ProtectedHandler)
40-
protected.With(middlewares.BanCheckMiddleware).Post("/submit", controllers.SubmitCode)
41-
protected.With(middlewares.BanCheckMiddleware).Post("/runcode", controllers.RunCode)
42-
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Post("/question/create", controllers.CreateQuestion)
43-
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Get("/questions", controllers.GetAllQuestion)
44-
protected.With(middlewares.BanCheckMiddleware).Get("/question/round", controllers.GetQuestionsByRound)
45-
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Get("/question/{question_id}", controllers.GetQuestionById)
46-
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Delete("/question/{question_id}", controllers.DeleteQuestion)
47-
protected.With(middlewares.RoleAuthorizationMiddleware("admin")).Patch("/question", controllers.UpdateQuestion)
41+
42+
protected.With(middlewares.BanCheckMiddleware).Post("/submit", controllers.SubmitCode)
43+
protected.With(middlewares.BanCheckMiddleware).Post("/runcode", controllers.RunCode)
44+
protected.With(middlewares.BanCheckMiddleware).Get("/question/round", controllers.GetQuestionsByRound)
45+
46+
adminRoutes := protected.With(middlewares.RoleAuthorizationMiddleware("admin"))
47+
48+
adminRoutes.Post("/question/create", controllers.CreateQuestion)
49+
adminRoutes.Get("/questions", controllers.GetAllQuestion)
50+
adminRoutes.Get("/question/{question_id}", controllers.GetQuestionById)
51+
adminRoutes.Delete("/question/{question_id}", controllers.DeleteQuestion)
52+
adminRoutes.Patch("/question", controllers.UpdateQuestion)
4853
})
4954

5055
r.Group(func(protected chi.Router) {

internal/worker/submissionWorker.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/CodeChefVIT/cookoff-backend/internal/controllers"
1111
"github.com/CodeChefVIT/cookoff-backend/internal/db"
1212
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/database"
13+
logger "github.com/CodeChefVIT/cookoff-backend/internal/helpers/logging"
1314
"github.com/CodeChefVIT/cookoff-backend/internal/helpers/submission"
1415
"github.com/google/uuid"
1516
"github.com/hibiken/asynq"
@@ -20,9 +21,8 @@ const TypeProcessSubmission = "submission:process"
2021

2122
func ProcessSubmissionTask(ctx context.Context, t *asynq.Task) error {
2223
var data controllers.Data
23-
log.Print("Processing task: ", t.Type)
24-
log.Println("Payload: ", string(t.Payload()))
25-
log.Println(data)
24+
logger.Infof("Processing task: %v", t.Type)
25+
logger.Infof("Payload: %v", string(t.Payload()))
2626

2727
if err := json.Unmarshal(t.Payload(), &data); err != nil {
2828
log.Printf("Error unmarshalling task payload: %v\n", err)

0 commit comments

Comments
 (0)