From 6ecc8ae2bee0554713c4e2fea5279e8b9013fa73 Mon Sep 17 00:00:00 2001
From: "guoguo.yu" <guoguo.yu@etu.hesge.ch>
Date: Thu, 19 Oct 2023 11:07:04 +0200
Subject: [PATCH] :/

---
 go.mod               |   2 +
 go.sum               |  10 ++
 main.go              | 230 +++++++++++++++++++++++++++++++++++++++++--
 models/page_templ.go |  17 ++--
 view/profile.html    |  19 +++-
 5 files changed, 262 insertions(+), 16 deletions(-)

diff --git a/go.mod b/go.mod
index 1557296..ce51a3c 100644
--- a/go.mod
+++ b/go.mod
@@ -14,12 +14,14 @@ require (
 	github.com/gorilla/securecookie v1.1.1 // indirect
 	github.com/klauspost/compress v1.13.6 // indirect
 	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
+	github.com/sirupsen/logrus v1.9.3 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
 	github.com/xdg-go/stringprep v1.0.4 // indirect
 	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 	golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
 	golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
 	golang.org/x/text v0.7.0 // indirect
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 )
diff --git a/go.sum b/go.sum
index ce9989c..56cad35 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,4 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df h1:Bao6dhmbTA1KFVxmJ6nBoMuOJit2yjEgLJpIMYpop0E=
@@ -16,6 +17,11 @@ github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQ
 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
@@ -44,6 +50,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -62,3 +70,5 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
index 3b7437d..6dfb670 100644
--- a/main.go
+++ b/main.go
@@ -18,6 +18,10 @@ import (
 )
 
 var usersCollection *mongo.Collection
+var messageCollection *mongo.Collection
+var URI string
+var messages []models.Post
+var err error
 
 // Session represents a user session.
 type Session struct {
@@ -62,12 +66,68 @@ func sendPasswordResetEmail(email, token string) error {
     return d.DialAndSend(m)
 }
 
+
+// Define a function to handle the POST request
+func handleMessage(w http.ResponseWriter, r *http.Request) {
+    // Parse the form data
+    err := r.ParseForm()
+    if err != nil {
+        http.Error(w, err.Error(), http.StatusBadRequest)
+        return
+    }
+
+    // Get the message data from the form
+    username := r.Form.Get("username")
+    content := r.Form.Get("content")
+	hasAttachment := r.Form.Get("hasAttachment")
+
+
+    // Create a new message object
+    message := models.Post{
+        Username:      username,
+        CreatedAt: time.Now(),
+        Content:   content,
+    }
+	if hasAttachment == "true" {
+		//attachment := models.Attachment{
+		//	PostID: message.ID,
+		//	Description: r.Form.Get("description"),
+		//}
+		//_, err = usersCollection.InsertOne(context.Background(), attachment)
+		//if err != nil {
+		//	http.Error(w, err.Error(), http.StatusInternalServerError)
+		//	return
+		//}
+
+
+	}
+
+    // Connect to the MongoDB database
+    clientOptions := options.Client().ApplyURI(URI)
+    client, err := mongo.Connect(context.Background(), clientOptions)
+    if err != nil {
+        log.Fatal(err)
+    }
+    defer client.Disconnect(context.Background())
+
+    // Insert the message into the database
+    collection := client.Database("mydb").Collection("messages")
+	_, err = collection.InsertOne(context.Background(), message)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Redirect the user back to their profile page
+	http.Redirect(w, r, "/profile", http.StatusTemporaryRedirect)
+}
+
 func main() {
 	// Initialize the sessions map
     sessions = make(map[string]Session)
 	// Load the .env file
 	godotenv.Load()
-	URI := os.Getenv("MONGO_URI")
+	URI = os.Getenv("MONGO_URI")
 	client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI))
 	if err != nil {
 		panic(err) //panic is a built-in function that stops the ordinary flow 
@@ -77,6 +137,7 @@ func main() {
 	}
 	fmt.Println("Connected successfully")
 	usersCollection = client.Database("authentication").Collection("users")
+	messageCollection = client.Database("mydb").Collection("messages")
 	fs := http.FileServer(http.Dir("./view"))
 	http.Handle("/", fs)
 	http.HandleFunc("/signin", signInHandler)
@@ -159,6 +220,66 @@ func successSignin(w http.ResponseWriter, r *http.Request) {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
+	// Get the username from the database
+	var user models.User
+	err = usersCollection.FindOne(context.Background(), bson.M{"username": r.FormValue("username")}).Decode(&user)
+
+	// Handle form submission for Post Writing
+	messageContent := r.FormValue("message")
+	if messageContent != "" {
+		// Create a new message object
+		message := models.Post{
+			//From:      user.Username,
+			Username:	  "admin",
+			CreatedAt: time.Now(),
+			Content:   messageContent,
+		}
+
+		// Connect to the MongoDB database
+		clientOptions := options.Client().ApplyURI(URI)
+		client, err := mongo.Connect(context.Background(), clientOptions)
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer client.Disconnect(context.Background())
+
+		// Insert the message into the database
+		_, err = messageCollection.InsertOne(context.TODO(), message)
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+	}
+
+	// Retrieve the user's messages from the database
+	messages, err = getUserMessages(user.Username)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Render the profile page with the user's messages
+	tmpl, err = template.ParseFiles("./view/profile.html")
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	err = tmpl.Execute(w, struct {
+		User     models.User
+		Messages []models.Post
+		FullName string
+		Email    string
+	}{
+		User:     user,
+		Messages: messages,
+		FullName: user.FullName,
+		Email:    user.Email,
+	})
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
 	// Load the session
 	sessionID := r.Header.Get("Session-ID")
 	session, ok := sessions[sessionID]
@@ -170,18 +291,108 @@ func successSignin(w http.ResponseWriter, r *http.Request) {
 		}
 		sessions[session.ID] = session
 	}
-
+	
 	// Create a timer for inactivity logout
-	timeoutDuration := 2 * time.Second // Adjust the timeout duration as needed
-	inactivityTimer := time.NewTimer(timeoutDuration)
-
-	go func() {
+	//timeoutDuration := 2 * time.Second // Adjust the timeout duration as needed
+	//inactivityTimer := time.NewTimer(timeoutDuration)
+	
+	/*go func() {
 		// Wait for the inactivity timer to expire
 		<-inactivityTimer.C
-
+		
 		// Log the user out due to inactivity
 		http.Redirect(w, r,  "/signin", http.StatusTemporaryRedirect)
-	}()
+	}()*/
+		
+}
+
+func getUserMessages(username string) ([]models.Post, error) {
+    // Connect to the MongoDB database
+    //clientOptions := options.Client().ApplyURI(URI)
+    //client, err := mongo.Connect(context.Background(), clientOptions)
+    //if err != nil {
+    //    log.Fatal(err)
+    //}
+    //defer client.Disconnect(context.Background())
+
+	// Query the messages table for messages with the given user ID
+	rows, err := messageCollection.Find(context.Background(), bson.M{"username": username})
+	if err != nil {
+		return nil, err
+	}
+	defer rows.Close(context.Background())
+	
+	// Iterate over the rows and create Message objects
+	messages := []models.Post{}
+	for rows.Next(context.Background()) {
+		var message models.Post
+		err := rows.Decode(&message)
+		if err != nil {
+			return nil, err
+		}
+		messages = append(messages, message)
+	}
+
+
+	return messages, nil
+}
+
+func profileHandler(w http.ResponseWriter, r *http.Request) {
+	// Get the username from the database
+	var user models.User
+	err := usersCollection.FindOne(context.Background(), bson.M{"username": r.FormValue("username")}).Decode(&user)
+
+	// Handle form submission for Post Writing
+	messageContent := r.FormValue("message")
+	if messageContent != "" {
+		// Create a new message object
+		message := models.Post{
+			//From:      user.Username,
+			Username:	  "admin",
+			CreatedAt: time.Now(),
+			Content:   messageContent,
+		}
+
+		// Connect to the MongoDB database
+		clientOptions := options.Client().ApplyURI(URI)
+		client, err := mongo.Connect(context.Background(), clientOptions)
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer client.Disconnect(context.Background())
+
+		// Insert the message into the database
+		_, err = messageCollection.InsertOne(context.TODO(), message)
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+	}
+
+	// Retrieve the user's messages from the database
+	messages, err = getUserMessages(user.Username)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	// Render the profile page with the user's messages
+	tmpl, err := template.ParseFiles("./view/profile.html")
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	err = tmpl.Execute(w, struct {
+		User     models.User
+		Messages []models.Post
+	}{
+		User:     user,
+		Messages: messages,
+	})
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
 
 }
 
@@ -189,11 +400,13 @@ func signInHandler(w http.ResponseWriter, r *http.Request) {
 	username := r.FormValue("username")
 	password := r.FormValue("password")
 	var user models.User
+	var messages []models.Post
 	err := usersCollection.FindOne(context.TODO(), bson.M{"username": username}).Decode(&user)
 	if err != nil || user.Username != username || user.Password != password {
 		http.Redirect(w, r, "/failed-signin", http.StatusTemporaryRedirect)
 		return
 	}
+	err = messageCollection.FindOne(context.Background(), bson.M{"username": username}).Decode(&messages)
 	data = models.PageTemplate{
 		Username: user.Username,
 		Fullname: user.FullName,
@@ -201,6 +414,7 @@ func signInHandler(w http.ResponseWriter, r *http.Request) {
 		Age: user.Age,
 		Bio: user.Bio,
 		Role: user.Role,
+		Messages: messages,
 	}
 	// Create a new session
 	r.Header.Add("Session-ID", time.Now().String())
diff --git a/models/page_templ.go b/models/page_templ.go
index 3adedff..b0cac6a 100644
--- a/models/page_templ.go
+++ b/models/page_templ.go
@@ -1,10 +1,13 @@
 package models
 
 type PageTemplate struct {
-	Username string
-	Email    string
-	Fullname string
-	Age		 int
-	Bio		 string
-	Role	 string
-}
+    Fullname string
+    Email    string
+    Username string
+    Age      int
+    Bio      string
+    Admin    bool
+    UserID   int
+	Role    string
+    Messages []Post
+}
\ No newline at end of file
diff --git a/view/profile.html b/view/profile.html
index 6c4a145..533b861 100644
--- a/view/profile.html
+++ b/view/profile.html
@@ -90,6 +90,23 @@
         </div>
         <p><a href="index.html">Logout</a></p>
     </div>
+
+    <h2>Write Message</h2>
+    <form method="post" action="/profile">
+        <label for="message">Message:</label>
+        <input type="text" id="message" name="message" required>
+
+        <button type="submit">Submit</button>
+
+    </form>
+    <ul>
+        {{range .Messages}}
+        <li>{{.Content}} ({{.Timestamp}})</li>
+        {{end}}
+    </ul>
+
+    <p>User ID: {{.UserID}}</p>
 </body>
 
-</html>
\ No newline at end of file
+</html>
+</body>
\ No newline at end of file
-- 
GitLab