Skip to content

Commit

Permalink
feature(mappers): Added data mappers.
Browse files Browse the repository at this point in the history
solve some TODOs.
Added data_mapper.go. This file implements the functions "GetUserID", "GetDeleteRequest", and "GetEnrolledRequest".
  • Loading branch information
GuidoM197 committed Feb 4, 2025
1 parent 02b633d commit de5c212
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 39 deletions.
54 changes: 25 additions & 29 deletions controllers/course/courseController.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"gorm.io/gorm"
"net/http"
"rpl-service/constants"
"rpl-service/models"
"rpl-service/mappers"
"rpl-service/services/users"
)

Expand Down Expand Up @@ -39,14 +39,23 @@ func Exists(w http.ResponseWriter, r *http.Request, db *gorm.DB) {

func Create(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
// Should Create a new course
var body models.Course
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
body, getCourseRequestErr := mappers.GetCourseRequest(r)
if getCourseRequestErr != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}

userID := uuid.New() // TODO: get the actual userID
userIDString, getIDError := mappers.GetUserID(r)
if getIDError != nil {
http.Error(w, "Failed to get user ID", http.StatusInternalServerError)
return
}
userID, parseErr := uuid.Parse(userIDString)
if parseErr != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}

currentCourse, creatingCourseErr := users.CreateCourse(db, userID, body.Name, body.Description)
if creatingCourseErr != nil {
http.Error(w, "Failed to Create course", http.StatusInternalServerError)
Expand All @@ -70,38 +79,30 @@ func Create(w http.ResponseWriter, r *http.Request, db *gorm.DB) {

// EnrollToCourse TODO: Test this function after implementing auth0.
func EnrollToCourse(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
var enrollmentRequest struct {
UserID uuid.UUID `json:"UserID"`
CourseID uuid.UUID `json:"CourseID"`
}

if json.NewDecoder(r.Body).Decode(&enrollmentRequest) != nil {
enrollmentRequest, enrollmentRequestErr := mappers.GetEnrolledRequest(r)
if enrollmentRequestErr != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}

err := users.EnrollToCourse(db, enrollmentRequest.UserID, enrollmentRequest.CourseID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
enrollErr := users.EnrollToCourse(db, enrollmentRequest.UserID, enrollmentRequest.CourseID)
if enrollErr != nil {
http.Error(w, enrollErr.Error(), http.StatusInternalServerError)
return
}

w.WriteHeader(http.StatusCreated)
_, err = w.Write([]byte("User enrolled in course successfully"))
if err != nil {
_, writeErr := w.Write([]byte("User enrolled in course successfully"))
if writeErr != nil {
http.Error(w, "Failed to write response", http.StatusInternalServerError)
return
}
}

// StudentExists TODO: Test this function after implementing auth0.
func StudentExists(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
var enrollmentRequest struct {
UserID uuid.UUID `json:"UserID"`
CourseID uuid.UUID `json:"CourseID"`
}

if json.NewDecoder(r.Body).Decode(&enrollmentRequest) != nil {
enrollmentRequest, enrollmentRequestErr := mappers.GetEnrolledRequest(r)
if enrollmentRequestErr != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
Expand All @@ -121,13 +122,8 @@ func StudentExists(w http.ResponseWriter, r *http.Request, db *gorm.DB) {

// DeleteStudent TODO: Test this function after implementing auth0.
func DeleteStudent(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
var deleteRequest struct {
UserID uuid.UUID `json:"UserID"`
CourseID uuid.UUID `json:"CourseID"`
StudentID uuid.UUID `json:"StudentID"`
}

if json.NewDecoder(r.Body).Decode(&deleteRequest) != nil {
deleteRequest, deleteRequestErr := mappers.GetDeleteRequest(r)
if deleteRequestErr != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
Expand Down
101 changes: 101 additions & 0 deletions mappers/data_mapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package mappers

import (
"encoding/json"
"errors"
"fmt"
"github.com/auth0/go-jwt-middleware/v2/jwks"
"github.com/auth0/go-jwt-middleware/v2/validator"
"github.com/google/uuid"
"net/http"
"net/url"
"os"
"rpl-service/constants"
"rpl-service/models"
"strings"
"time"
)

func GetCourseRequest(r *http.Request) (models.Course, error) {
var body models.Course
if decodeErr := json.NewDecoder(r.Body).Decode(&body); decodeErr != nil {
return models.Course{}, errors.New("invalid request body")
}
return body, nil
}

func GetEnrolledRequest(r *http.Request) (EnrollmentRequest, error) {
var result EnrollmentRequest
if json.NewDecoder(r.Body).Decode(&result) != nil {
return result, errors.New("invalid request body")
}
return result, nil
}

func GetDeleteRequest(r *http.Request) (DeleteRequest, error) {
var result DeleteRequest
if json.NewDecoder(r.Body).Decode(&result) != nil {
return result, errors.New("invalid request body")
}
return result, nil
}

// GetUserID TODO: Check this when possible.
func GetUserID(r *http.Request) (string, error) {
// Auth0 configuration
issuerURL := os.Getenv("AUTH0_DOMAIN")
audience := []string{os.Getenv("AUTH0_AUDIENCE")}

// Parse the issuer URL
issuer, err := url.Parse(issuerURL)
if err != nil {
return constants.EmptyString, fmt.Errorf("failed to parse issuer URL: %w", err)
}

// Set up token validator
provider := jwks.NewCachingProvider(issuer, 5*time.Minute)

Check failure on line 56 in mappers/data_mapper.go

View workflow job for this annotation

GitHub Actions / lint-and-test

Magic number: 5, in <argument> detected (mnd)

Check failure on line 56 in mappers/data_mapper.go

View workflow job for this annotation

GitHub Actions / lint-and-test

Magic number: 5, in <argument> detected (mnd)
jwtValidator, err := validator.New(
provider.KeyFunc,
validator.RS256,
issuerURL,
audience,
)

if err != nil {
return constants.EmptyString, fmt.Errorf("failed to setup validator: %w", err)
}

// Validate token
token, err := jwtValidator.ValidateToken(r.Context(), r.Header.Get("Authorization"))
if err != nil {
return constants.EmptyString, fmt.Errorf("invalid token: %w", err)
}

// Extract claims
claims, ok := token.(*validator.ValidatedClaims)
if !ok {
return constants.EmptyString, errors.New("invalid token claims")
}

// Get user ID from subject
sub := claims.RegisteredClaims.Subject
parts := strings.Split(sub, "|")
if len(parts) != 2 {

Check failure on line 83 in mappers/data_mapper.go

View workflow job for this annotation

GitHub Actions / lint-and-test

Magic number: 2, in <condition> detected (mnd)

Check failure on line 83 in mappers/data_mapper.go

View workflow job for this annotation

GitHub Actions / lint-and-test

Magic number: 2, in <condition> detected (mnd)
return constants.EmptyString, errors.New("invalid subject format")
}

return parts[1], nil
}

// AUX

type EnrollmentRequest struct {
UserID uuid.UUID `json:"UserID"`
CourseID uuid.UUID `json:"CourseID"`
}

type DeleteRequest struct {
UserID uuid.UUID `json:"UserID"`
CourseID uuid.UUID `json:"CourseID"`
StudentID uuid.UUID `json:"StudentID"`
}
10 changes: 0 additions & 10 deletions services/users/userService.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ import (
)

func EnrollToCourse(db *gorm.DB, userID, courseID uuid.UUID) error {
// TODO: change the following line
// if !userExists(db, userID) {
// return errors.New("user does not exist")
//}

if IsUserInCourse(db, userID, courseID) {
return errors.New("user is already in course")
}
Expand Down Expand Up @@ -118,11 +113,6 @@ func CourseExists(db *gorm.DB, courseID uuid.UUID) bool {
return db.Model(models.Course{}).Where("ID = ?", courseID).Error == nil
}

// func userExists(db *gorm.DB, id uint) bool {
// // TODO: use Auth0
// return true
//}

func isOwner(db *gorm.DB, userID, courseID uuid.UUID) bool {
currentUser := models.IsEnrolled{}
db.Model(models.IsEnrolled{}).Where("UserID = ? AND CourseID = ?", userID, courseID).First(&currentUser)
Expand Down

0 comments on commit de5c212

Please sign in to comment.