package cmd import ( "crypto/sha256" "database/sql" "encoding/hex" "fmt" "log" "net/http" "github.com/gin-gonic/gin" _ "github.com/lib/pq" "github.com/spf13/viper" ) var ( ListenPort = "8080" db *sql.DB DB_Host string DB_Port string DB_User string DB_Pass string DB_Name string ) func getDBInfo() error { dbhost := viper.GetString("Server.DB_Host") if dbhost == "" { e := fmt.Errorf("No database IP address present in config file!\n") return e } else { DB_Host = dbhost } dbport := viper.GetString("Server.DB_Port") if dbport == "" { e := fmt.Errorf("No database port present in config file!\n") return e } else { DB_Port = dbport } dbuser := viper.GetString("Server.DB_User") if dbuser == "" { e := fmt.Errorf("No database username present in config file!\n") return e } else { DB_User = dbuser } dbpass := viper.GetString("Server.DB_Pass") if dbpass == "" { e := fmt.Errorf("No database password present in config file!\n") return e } else { DB_Pass = dbpass } dbname := viper.GetString("Server.DB_Name") if dbname == "" { e := fmt.Errorf("No database name present in config file!\n") return e } else { DB_Name = dbname } return nil } func openDB() error { psqlconn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", DB_Host, DB_Port, DB_User, DB_Pass, DB_Name) dba, err := sql.Open("postgres", psqlconn) if err != nil { return err } db = dba return nil } func setPort() { p := viper.GetString("Server.Port") if p != "" { ListenPort = p } } func server() { log.SetPrefix("[DRAHOOT] ") setPort() if err := getDBInfo(); err != nil { log.Fatalf("INVALID DB INFO: %v\nPlease refer to the example configuration file in the repo at https://git.bulgariu.xyz/raul/drahoot/src/branch/main/sample-config (default config path = ~/.config/drahoot/drahoot.toml)", err) } if err := openDB(); err != nil { log.Fatalf("Database machine broke: %v\n", err) } gin.SetMode(gin.ReleaseMode) r := gin.Default() r.GET("/", helloWorld) // TODO: Have fun creating new endpoints r.GET("/api/user", getUsers) r.GET("/api/user/:userid", getUser) r.POST("/api/user", createUser) r.Run(":" + ListenPort) } func hashPW(plain string) string { hashedPW := sha256.New() hashedPW.Write([]byte(plain)) sha256hash := hex.EncodeToString(hashedPW.Sum(nil)) return sha256hash } func createUser(c *gin.Context) { newuser := user{} if err := c.BindJSON(&newuser); err != nil { e := fmt.Sprintf("Something went wrong creating the user: %v\n", err) log.Print(e) c.String(http.StatusInternalServerError, e) return } secret := hashPW(newuser.Password) var dynStmt string if newuser.IsTeacher == true { dynStmt = `INSERT INTO profesores(nombre, apellido1, apellido2, email, password) values($1, $2, $3, $4, $5)` } else { dynStmt = `INSERT INTO alumnos(nombre, apellido1, apellido2, email, password) values($1, $2, $3, $4, $5)` } _, err := db.Exec(dynStmt, newuser.Name, newuser.Surname1, newuser.Surname2, newuser.Email, secret) if err != nil { e := fmt.Sprintf("Something went wrong trying to create the user: %v\n", err) log.Print(e) c.String(http.StatusInternalServerError, e) return } c.String(http.StatusOK, "Success!") } func getUser(c *gin.Context) { id := c.Param("userid") user := user{} dynStmt := `SELECT id_alumno,nombre,apellido1,apellido2,email FROM alumnos WHERE id_alumno = $1` err := db.QueryRow(dynStmt, id).Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email) if err != nil { if err == sql.ErrNoRows { c.String(http.StatusNotFound, "User not found") return } e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v\n", err) log.Print(e) c.String(http.StatusInternalServerError, e) return } c.IndentedJSON(http.StatusOK, user) } func getUsers(c *gin.Context) { users := []user{} rows, err := db.Query("SELECT id_alumno,nombre,apellido1,apellido2,email FROM alumnos") if err != nil { e := fmt.Sprintf("SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v\n", err) log.Print(e) c.String(http.StatusInternalServerError, e) return } defer rows.Close() for rows.Next() { user := user{} err = rows.Scan(&user.Id, &user.Name, &user.Surname1, &user.Surname2, &user.Email) if err != nil { e := fmt.Sprintf("SOMETHING BAD HAPPENED SCANNING THE ROWS: %v\n", err) log.Print(e) c.String(http.StatusInternalServerError, e) return } users = append(users, user) } c.IndentedJSON(http.StatusOK, users) } func helloWorld(c *gin.Context) { ua := c.Request.UserAgent() message := fmt.Sprintf("Hello %v!\n", ua) c.String(http.StatusOK, message) }