sync
This commit is contained in:
@@ -4,5 +4,6 @@ go 1.24.2
|
||||
|
||||
require (
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/neo4j/neo4j-go-driver/v5 v5.28.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/neo4j/neo4j-go-driver/v5 v5.28.0 h1:chDT68PHNa8JZRmjSkGzAbk1weLWo4rMtDvccvpobg0=
|
||||
github.com/neo4j/neo4j-go-driver/v5 v5.28.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=
|
||||
|
||||
+13
-5
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
)
|
||||
|
||||
@@ -34,7 +35,7 @@ func serve() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
driver_ctx := context.Background()
|
||||
driver, err := neo4j.NewDriverWithContext("bolt://localhost:7687", neo4j.BasicAuth("neo4j", "jzLbsy2C23WHzQ-", ""))
|
||||
driver, err := neo4j.NewDriverWithContext(os.Getenv("NEO4J_BOLT"), neo4j.BasicAuth("neo4j", os.Getenv("NEO4J_PASSWORD"), ""))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -43,18 +44,19 @@ func serve() {
|
||||
|
||||
err = driver.VerifyConnectivity(driver_ctx)
|
||||
if err != nil {
|
||||
log.Println("Error connecting to neo4j.")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("neo4j connection established.")
|
||||
|
||||
rsrc_endpoints := []string{
|
||||
"/auth",
|
||||
"/users",
|
||||
"/users",
|
||||
"/users/{user_id}",
|
||||
"/users/{user_id}",
|
||||
"/users/{user_id}",
|
||||
"/users/{user_id}",
|
||||
"/users/{user_id}/posts",
|
||||
"/users/{user_id}/spaces",
|
||||
"/spaces",
|
||||
@@ -74,9 +76,9 @@ func serve() {
|
||||
|
||||
methods := []string{
|
||||
http.MethodPost,
|
||||
http.MethodGet,
|
||||
http.MethodGet,
|
||||
http.MethodPost,
|
||||
http.MethodGet,
|
||||
http.MethodGet,
|
||||
http.MethodPatch,
|
||||
http.MethodDelete,
|
||||
http.MethodGet,
|
||||
@@ -97,10 +99,10 @@ func serve() {
|
||||
}
|
||||
|
||||
functions := []func(http.ResponseWriter, *http.Request){
|
||||
auth_user(driver, driver_ctx),
|
||||
create_new_user(driver, driver_ctx),
|
||||
retrieve_all_users(driver, driver_ctx),
|
||||
retrieve_user(driver, driver_ctx),
|
||||
auth_user(driver, driver_ctx),
|
||||
update_user(driver, driver_ctx),
|
||||
delete_user(driver, driver_ctx),
|
||||
retrieve_users_posts(driver, driver_ctx),
|
||||
@@ -168,5 +170,11 @@ func serve() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := godotenv.Load("../.env")
|
||||
if err != nil {
|
||||
log.Println("Error loading .env.")
|
||||
return
|
||||
}
|
||||
|
||||
serve()
|
||||
}
|
||||
|
||||
+121
-21
@@ -3,24 +3,112 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
// "fmt"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
//"io"
|
||||
// "log"
|
||||
"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) {
|
||||
return
|
||||
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:2025")
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,38 +120,47 @@ func retrieve_all_users(driver neo4j.DriverWithContext, driver_ctx context.Conte
|
||||
|
||||
func retrieve_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
user_id, _ := strconv.Atoi(mux.Vars(r)["user_id"])
|
||||
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": user_id,
|
||||
"user_id": id,
|
||||
}, neo4j.EagerResultTransformer,
|
||||
neo4j.ExecuteQueryWithDatabase("neo4j"))
|
||||
|
||||
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),
|
||||
}
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
send_response(w, json)
|
||||
}
|
||||
}
|
||||
|
||||
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", "http://localhost:2025")
|
||||
|
||||
username := r.FormValue("username")
|
||||
password_hash := r.FormValue("password_hash")
|
||||
|
||||
@@ -96,7 +193,10 @@ func auth_user(driver neo4j.DriverWithContext, driver_ctx context.Context) http.
|
||||
return
|
||||
}
|
||||
|
||||
send_response(w, json)
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user