diff --git a/cmd/serverFunc.go b/cmd/serverFunc.go index 79ab12d..1d24ce6 100644 --- a/cmd/serverFunc.go +++ b/cmd/serverFunc.go @@ -7,7 +7,6 @@ import ( "fmt" "log" "net/http" - "strconv" "github.com/gin-gonic/gin" _ "github.com/lib/pq" @@ -39,176 +38,28 @@ func server() { gin.SetMode(gin.ReleaseMode) r := gin.Default() r.GET("/api/ping", ping) - //r.GET("/", helloWorld) - // TODO: Have fun creating new endpoints + + // CRUD for users r.GET("/api/user", getUsers) r.GET("/api/user/:userid", getUser) r.POST("/api/user", createUser) r.DELETE("/api/user/:userid", deleteUser) r.PUT("/api/user/:userid", modifyUser) + // TODO: Finish the following: + // CRUD for quizzes + // CRUD for quiz questions + // CRUD for question answers + // CRUD for quiz attempts + r.Run(":" + ListenPort) } -func checkUserExists(id string) bool { - dynStmt := `SELECT id_usuario FROM usuarios WHERE id_usuario = $1` - err := db.QueryRow(dynStmt, id).Scan() - if err == sql.ErrNoRows { - return false - } else { - return true - } -} - -func modifyUser(c *gin.Context) { - id := c.Param("userid") - dynStmt := `UPDATE usuarios SET email=$1,nombre=$2,apellido1=$3,apellido2=$4,password=$5 WHERE id_usuario = $6` - - _, err := strconv.Atoi(id) - if err != nil { - e := fmt.Sprintf("Invalid identifier") - c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) - return - } - - if exists := checkUserExists(id); exists != true { - c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) - return - } - - user := user{} - if err := c.BindJSON(&user); err != nil { - e := fmt.Sprintf("Something went wrong updating the user: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - - _, err = db.Exec(dynStmt, user.Email, user.Name, user.Surname1, user.Surname2, hashPW(user.Password), id) - if err != nil { - e := fmt.Sprintf("Something went wrong trying to modify the user: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - - c.IndentedJSON(http.StatusOK, setResponse(user, true)) -} - -func deleteUser(c *gin.Context) { - id := c.Param("userid") - dynStmt := `DELETE FROM usuarios WHERE id_usuario = $1` - - _, err := strconv.Atoi(id) - if err != nil { - e := fmt.Sprintf("Invalid identifier") - c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) - return - } - - if exists := checkUserExists(id); exists != true { - c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) - return - } - - _, err = db.Exec(dynStmt, id) - if err != nil { - e := fmt.Sprintf("Something went wrong trying to delete the user: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - e := fmt.Sprintf("User successfully deleted") - c.IndentedJSON(http.StatusOK, setResponse(e, true)) -} - -func createUser(c *gin.Context) { - newuser := user{} - if err := c.BindJSON(&newuser); err != nil { - e := fmt.Sprintf("Something went wrong creating the user: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - - var dynStmt string - if newuser.AccountType != "estudiante" && newuser.AccountType != "profesor" { - if newuser.AccountType == "admin" { - e := fmt.Sprintf("Nice try (https://xkcd.com/327/)") - c.IndentedJSON(http.StatusTeapot, setResponse(e, false)) - return - } - e := fmt.Sprintf("Invalid account type\n") - c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) - return - } - dynStmt = `INSERT INTO usuarios(nombre, apellido1, apellido2, email, password, rol) values($1, $2, $3, $4, $5, $6)` - _, err := db.Exec(dynStmt, newuser.Name, newuser.Surname1, newuser.Surname2, newuser.Email, hashPW(newuser.Password), newuser.AccountType) - if err != nil { - e := fmt.Sprintf("Something went wrong trying to create the user: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - e := fmt.Sprintf("User %v has been created!", newuser.Name) - c.IndentedJSON(http.StatusOK, setResponse(e, true)) -} - func setResponse(content any, success bool) response { msg := response{Contents: content, Success: success} return msg } -func getUser(c *gin.Context) { - id := c.Param("userid") - - _, err := strconv.Atoi(id) - if err != nil { - e := fmt.Sprintf("Invalid identifier") - c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) - return - } - - user := user{} - dynStmt := `SELECT id_usuario,nombre,apellido1,apellido2,email,rol FROM usuarios WHERE id_usuario = $1` - err = db.QueryRow(dynStmt, id).Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email, &user.AccountType) - if err != nil { - if err == sql.ErrNoRows { - c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) - return - } - e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - c.IndentedJSON(http.StatusOK, setResponse(user, true)) -} - -func getUsers(c *gin.Context) { - users := []user{} - rows, err := db.Query("SELECT id_usuario,nombre,apellido1,apellido2,email,rol FROM usuarios") - if err != nil { - e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - defer rows.Close() - for rows.Next() { - user := user{} - err = rows.Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email, &user.AccountType) - if err != nil { - e := fmt.Sprintf("SOMETHING BAD HAPPENED SCANNING THE ROWS: %v", err) - log.Println(e) - c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) - return - } - users = append(users, user) - } - c.IndentedJSON(http.StatusOK, setResponse(users, true)) -} - func ping(c *gin.Context) { c.IndentedJSON(http.StatusOK, setResponse("Pong!", true)) } diff --git a/cmd/userapi.go b/cmd/userapi.go new file mode 100644 index 0000000..258d3e1 --- /dev/null +++ b/cmd/userapi.go @@ -0,0 +1,180 @@ +package cmd + +import ( + "database/sql" + "fmt" + "log" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" +) + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func checkUserExists(id string) bool { + dynStmt := `SELECT id_usuario FROM usuarios WHERE id_usuario = $1` + err := db.QueryRow(dynStmt, id).Scan() + if err == sql.ErrNoRows { + return false + } else { + return true + } +} + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func modifyUser(c *gin.Context) { + id := c.Param("userid") + dynStmt := `UPDATE usuarios SET email=$1,nombre=$2,apellido1=$3,apellido2=$4,password=$5 WHERE id_usuario = $6` + + _, err := strconv.Atoi(id) + if err != nil { + e := fmt.Sprintf("Invalid identifier") + c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) + return + } + + if exists := checkUserExists(id); exists != true { + c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) + return + } + + user := user{} + if err := c.BindJSON(&user); err != nil { + e := fmt.Sprintf("Something went wrong updating the user: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + + _, err = db.Exec(dynStmt, user.Email, user.Name, user.Surname1, user.Surname2, hashPW(user.Password), id) + if err != nil { + e := fmt.Sprintf("Something went wrong trying to modify the user: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + + c.IndentedJSON(http.StatusOK, setResponse("User successfully modified", true)) +} + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func deleteUser(c *gin.Context) { + id := c.Param("userid") + dynStmt := `DELETE FROM usuarios WHERE id_usuario = $1` + + _, err := strconv.Atoi(id) + if err != nil { + e := fmt.Sprintf("Invalid identifier") + c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) + return + } + + if exists := checkUserExists(id); exists != true { + c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) + return + } + + _, err = db.Exec(dynStmt, id) + if err != nil { + e := fmt.Sprintf("Something went wrong trying to delete the user: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + c.IndentedJSON(http.StatusOK, setResponse("User successfully deleted", true)) +} + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func createUser(c *gin.Context) { + newuser := user{} + if err := c.BindJSON(&newuser); err != nil { + e := fmt.Sprintf("Something went wrong creating the user: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + + var dynStmt string + if newuser.AccountType != "estudiante" && newuser.AccountType != "profesor" { + if newuser.AccountType == "admin" { + c.IndentedJSON(http.StatusTeapot, setResponse("Nice try (https://xkcd.com/327/)", false)) + return + } + c.IndentedJSON(http.StatusNotFound, setResponse("Invalid account type", false)) + return + } + dynStmt = `INSERT INTO usuarios(nombre, apellido1, apellido2, email, password, rol) values($1, $2, $3, $4, $5, $6)` + _, err := db.Exec(dynStmt, newuser.Name, newuser.Surname1, newuser.Surname2, newuser.Email, hashPW(newuser.Password), newuser.AccountType) + if err != nil { + e := fmt.Sprintf("Something went wrong trying to create the user: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + e := fmt.Sprintf("User %v has been created!", newuser.Name) + c.IndentedJSON(http.StatusOK, setResponse(e, true)) +} + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func getUser(c *gin.Context) { + id := c.Param("userid") + + _, err := strconv.Atoi(id) + if err != nil { + e := fmt.Sprintf("Invalid identifier") + c.IndentedJSON(http.StatusNotFound, setResponse(e, false)) + return + } + + user := user{} + dynStmt := `SELECT id_usuario,nombre,apellido1,apellido2,email,rol FROM usuarios WHERE id_usuario = $1` + err = db.QueryRow(dynStmt, id).Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email, &user.AccountType) + if err != nil { + if err == sql.ErrNoRows { + c.IndentedJSON(http.StatusNotFound, setResponse("User not found", false)) + return + } + e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + c.IndentedJSON(http.StatusOK, setResponse(user, true)) +} + +// ////////////////////////////////////////////////////////////////////////// +// Placeholder +// ////////////////////////////////////////////////////////////////////////// +func getUsers(c *gin.Context) { + users := []user{} + rows, err := db.Query("SELECT id_usuario,nombre,apellido1,apellido2,email,rol FROM usuarios") + if err != nil { + e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + defer rows.Close() + for rows.Next() { + user := user{} + err = rows.Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email, &user.AccountType) + if err != nil { + e := fmt.Sprintf("SOMETHING BAD HAPPENED SCANNING THE ROWS: %v", err) + log.Println(e) + c.IndentedJSON(http.StatusInternalServerError, setResponse(e, false)) + return + } + users = append(users, user) + } + c.IndentedJSON(http.StatusOK, setResponse(users, true)) +}