package main import ( "context" "encoding/json" "fmt" "io" "os" "strconv" //"io" "log" "net/http" // "os" // "os/signal" // "reflect" "math/rand" "strings" // "sync" // "time" "github.com/gorilla/mux" "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) func id_exists(id int, driver neo4j.DriverWithContext, driver_ctx context.Context) bool { result, _ := neo4j.ExecuteQuery(driver_ctx, driver, "MATCH (u:User) WHERE id(u) = $id RETURN count(u)", map[string]any{ "id": id, }, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j")) if len(result.Records) > 0 { return true } else { return false } } func create_new_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") err := r.ParseMultipartForm(10 << 20) // Limit to 10MB if err != nil { log.Println("Unable to parse form.") } username := r.FormValue("username") email := r.FormValue("email") password_hash := r.FormValue("password_hash") id := rand.Intn(999999999999) + 1 for id_exists(id, driver, driver_ctx) { id = rand.Intn(999999999999) + 1 } profile_picture_file, header, err := r.FormFile("profile_picture") if err != nil { log.Println("Error retrieving file from form.") } defer profile_picture_file.Close() filename_parts := strings.Split(header.Filename, ".") ext := filename_parts[len(filename_parts)-1] dst, err := os.Create(os.Getenv("PROFILE_IMAGES_FQ_PATH") + strconv.Itoa(id) + ext) if err != nil { log.Println("Error saving profile picture.") } defer dst.Close() _, err = io.Copy(dst, profile_picture_file) if err != nil { log.Println("Error writing file to filesystem.") } result, _ := neo4j.ExecuteQuery(driver_ctx, driver, "CREATE (u:User {id: $id, username: $username, email: $email, password_hash: $password_hash, profile_picture: $profile_picture, created_at: datetime()})-[:USER_TYPE]->(:Role {name: 'User'}) RETURN elementId(u) AS id", map[string]any{ "id": id, "username": username, "email": email, "password_hash": password_hash, "profile_picture": strconv.Itoa(id) + ext, }, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j")) if len(result.Records) > 0 { ret := struct { Auth bool `json:"auth"` Id string `json:"id"` }{ Auth: true, Id: strconv.Itoa(id), } json, err := json.Marshal(ret) if err != nil { return } w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, string(json)) log.Println("User ID:", id, "Action: Signup") } else { return } } } func retrieve_all_users(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { return } } func retrieve_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { id, _ := strconv.Atoi(mux.Vars(r)["user_id"]) result, _ := neo4j.ExecuteQuery(driver_ctx, driver, "MATCH (u:User) WHERE id(u) = $user_id RETURN u.username AS username, u.email AS email, u.profile_picture AS profile_picture", map[string]any{ "user_id": id, }, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j")) if len(result.Records) > 0 { record := result.Records[0] vals := record.AsMap() user := struct { Username string `json:"username"` Email string `json:"email"` ProfilePicture string `json:"profile_picture"` }{ Username: vals["username"].(string), Email: vals["email"].(string), ProfilePicture: vals["profile_picture"].(string), } json, err := json.Marshal(user) if err != nil { return } w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, string(json)) log.Println("User ID:", id, "Action: Retrieval") } else { return } } } func auth_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") username := r.FormValue("username") password_hash := r.FormValue("password_hash") result, _ := neo4j.ExecuteQuery(driver_ctx, driver, "MATCH (u:User) WHERE u.username = $username RETURN u.password_hash AS password_hash, elementId(u) AS id", map[string]any{ "username": username, }, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j")) if len(result.Records) > 0 { record := result.Records[0] vals := record.AsMap() if vals["password_hash"] != password_hash { return } id := strings.Split(vals["id"].(string), ":")[2] ret := struct { Auth bool `json:"auth"` Id string `json:"id"` }{ Auth: true, Id: id, } json, err := json.Marshal(ret) if err != nil { return } w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, string(json)) log.Println("User ID:", id, "Action: Login") } else { return } } } func update_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { return } } func delete_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { return } } func retrieve_users_posts(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { return } } func retrieve_users_spaces(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { return } }