2024-12-06 10:38:37 +01:00
package cmd
import (
2024-12-10 11:36:25 +01:00
"crypto/sha256"
2024-12-06 13:55:01 +01:00
"database/sql"
2024-12-10 11:36:25 +01:00
"encoding/hex"
2024-12-06 10:38:37 +01:00
"fmt"
2024-12-06 13:55:01 +01:00
"log"
2024-12-06 10:38:37 +01:00
"net/http"
"github.com/gin-gonic/gin"
2024-12-06 13:55:01 +01:00
_ "github.com/lib/pq"
2024-12-06 10:38:37 +01:00
"github.com/spf13/viper"
)
var (
ListenPort = "8080"
2024-12-06 13:55:01 +01:00
2024-12-09 10:42:31 +01:00
db * sql . DB
2024-12-06 13:55:01 +01:00
DB_Host string
DB_Port string
DB_User string
DB_Pass string
DB_Name string
2024-12-06 10:38:37 +01:00
)
2024-12-06 13:55:01 +01:00
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
}
2024-12-09 10:42:31 +01:00
func openDB ( ) error {
2024-12-06 13:55:01 +01:00
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 )
2024-12-09 10:42:31 +01:00
dba , err := sql . Open ( "postgres" , psqlconn )
2024-12-06 13:55:01 +01:00
if err != nil {
2024-12-09 10:42:31 +01:00
return err
2024-12-06 13:55:01 +01:00
}
2024-12-09 10:42:31 +01:00
db = dba
return nil
2024-12-06 13:55:01 +01:00
}
2024-12-06 10:38:37 +01:00
2024-12-06 13:55:01 +01:00
func setPort ( ) {
2024-12-06 10:38:37 +01:00
p := viper . GetString ( "Server.Port" )
if p != "" {
ListenPort = p
}
2024-12-06 13:55:01 +01:00
}
2024-12-06 10:38:37 +01:00
2024-12-06 13:55:01 +01:00
func server ( ) {
log . SetPrefix ( "[DRAHOOT] " )
setPort ( )
if err := getDBInfo ( ) ; err != nil {
2024-12-09 10:42:31 +01:00
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 )
2024-12-06 13:55:01 +01:00
}
gin . SetMode ( gin . ReleaseMode )
2024-12-06 10:38:37 +01:00
r := gin . Default ( )
r . GET ( "/" , helloWorld )
2024-12-09 10:42:31 +01:00
// TODO: Have fun creating new endpoints
2024-12-10 11:36:25 +01:00
r . GET ( "/api/user" , getUsers )
2024-12-09 17:21:03 +01:00
r . GET ( "/api/user/:userid" , getUser )
2024-12-10 11:36:25 +01:00
r . POST ( "/api/user" , createUser )
2024-12-06 10:38:37 +01:00
r . Run ( ":" + ListenPort )
}
2024-12-10 11:36:25 +01:00
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
2024-12-10 13:52:59 +01:00
if newuser . AccountType != "estudiante" && newuser . AccountType != "profesor" {
if newuser . AccountType == "admin" {
c . String ( http . StatusTeapot , "https://xkcd.com/327/\n" )
return
}
c . String ( http . StatusNotFound , "Invalid account type\n" )
return
2024-12-10 11:36:25 +01:00
}
2024-12-10 13:52:59 +01:00
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 , secret , newuser . AccountType )
2024-12-10 11:36:25 +01:00
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
}
2024-12-10 13:52:59 +01:00
c . String ( http . StatusOK , "Success!\n" )
2024-12-10 11:36:25 +01:00
}
2024-12-11 12:36:02 +01:00
func setResponse ( content any , success bool ) response {
msg := response { Contents : content , Success : success }
return msg
}
2024-12-09 17:21:03 +01:00
func getUser ( c * gin . Context ) {
id := c . Param ( "userid" )
user := user { }
2024-12-11 12:36:02 +01:00
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 )
2024-12-09 17:21:03 +01:00
if err != nil {
2024-12-09 17:58:26 +01:00
if err == sql . ErrNoRows {
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusNotFound , setResponse ( "User not found" , false ) )
2024-12-09 17:58:26 +01:00
return
}
2024-12-09 17:21:03 +01:00
e := fmt . Sprintf ( "SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v\n" , err )
log . Print ( e )
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusInternalServerError , setResponse ( e , false ) )
2024-12-09 17:21:03 +01:00
return
}
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusOK , setResponse ( user , true ) )
2024-12-09 17:21:03 +01:00
}
2024-12-09 10:42:31 +01:00
func getUsers ( c * gin . Context ) {
users := [ ] user { }
2024-12-11 12:36:02 +01:00
rows , err := db . Query ( "SELECT id_usuario,nombre,apellido1,apellido2,email,rol FROM usuarios" )
2024-12-06 13:55:01 +01:00
if err != nil {
2024-12-09 10:42:31 +01:00
e := fmt . Sprintf ( "SOMETHING BAD HAPPENED QUERYING THE DATABASE: %v\n" , err )
log . Print ( e )
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusInternalServerError , setResponse ( e , false ) )
2024-12-06 13:55:01 +01:00
return
}
2024-12-09 10:42:31 +01:00
defer rows . Close ( )
for rows . Next ( ) {
user := user { }
2024-12-11 12:36:02 +01:00
err = rows . Scan ( & user . Id , & user . Name , & user . Surname1 , & user . Surname2 , & user . Email , & user . AccountType )
2024-12-09 10:42:31 +01:00
if err != nil {
e := fmt . Sprintf ( "SOMETHING BAD HAPPENED SCANNING THE ROWS: %v\n" , err )
log . Print ( e )
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusInternalServerError , setResponse ( e , false ) )
2024-12-09 10:42:31 +01:00
return
}
users = append ( users , user )
2024-12-06 13:55:01 +01:00
}
2024-12-11 12:36:02 +01:00
c . IndentedJSON ( http . StatusOK , setResponse ( users , true ) )
2024-12-06 13:55:01 +01:00
}
2024-12-06 10:38:37 +01:00
func helloWorld ( c * gin . Context ) {
ua := c . Request . UserAgent ( )
message := fmt . Sprintf ( "Hello %v!\n" , ua )
c . String ( http . StatusOK , message )
}