diff --git a/main.go b/main.go index 6dfb670716793987079f1887e8fe6d5da1387818..9f048abb3e60e670321042b78bf95f79fa069ee8 100644 --- a/main.go +++ b/main.go @@ -18,15 +18,19 @@ import ( ) var usersCollection *mongo.Collection -var messageCollection *mongo.Collection +var postsCollection *mongo.Collection var URI string var messages []models.Post var err error +var user models.User +var username_global string // Session represents a user session. type Session struct { ID string CreationTime time.Time + UserID int + Username string } // sessions is a map to store active sessions. @@ -137,7 +141,7 @@ func main() { } fmt.Println("Connected successfully") usersCollection = client.Database("authentication").Collection("users") - messageCollection = client.Database("mydb").Collection("messages") + postsCollection = client.Database("mydb").Collection("messages") fs := http.FileServer(http.Dir("./view")) http.Handle("/", fs) http.HandleFunc("/signin", signInHandler) @@ -145,9 +149,89 @@ func main() { http.HandleFunc("/failed-signin", failedSignin) http.HandleFunc("/profile", successSignin) http.HandleFunc("/reset-password", handlePasswordReset) + http.HandleFunc("/post", handlePost) log.Fatal(http.ListenAndServe(":5500", nil)) } +//getCurrentUser function +func getCurrentUser(r *http.Request) models.User { + return user +} + +//a saveUser function that updates the user and its posts in the database +func saveUser(user models.User) 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()) + + // Update the user in the database + _, err = usersCollection.UpdateOne(context.Background(), bson.M{"username": user.Username}, bson.M{"$set": user}) + if err != nil { + return err + } + + return nil +} + +func handlePost(w http.ResponseWriter, r *http.Request) { + // Get the current user + user := getCurrentUser(r) + + // Parse the form data + err := r.ParseForm() + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + // Get the post title and content from the form data + title := r.Form.Get("title") + content := r.Form.Get("content") + + // Create a new post with the title, content, author, and current date/time + post := models.Post{ + Title: title, + Content: content, + Username: user.Username, + CreatedAt: time.Now(), + } + // Add the post to the database + // 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(), post) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + + + // Append the new post to the user's Posts slice + user.Posts = append(user.Posts, post) + + // Save the updated user to the database + err = saveUser(user) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the profile page + http.Redirect(w, r, "/profile", http.StatusSeeOther) +} + func handlePasswordReset(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") token := r.FormValue("token") @@ -221,16 +305,19 @@ func successSignin(w http.ResponseWriter, r *http.Request) { return } // Get the username from the database - var user models.User - err = usersCollection.FindOne(context.Background(), bson.M{"username": r.FormValue("username")}).Decode(&user) - + //var user models.User + //err = usersCollection.FindOne(context.Background(), bson.M{"username": r.FormValue("username")}).Decode(&user) + err = usersCollection.FindOne(context.Background(), bson.M{"username": username_global}).Decode(&user) + fmt.Println("printing user related") + fmt.Println(username_global) // 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", + Username: username_global, + Title: r.FormValue("title"), CreatedAt: time.Now(), Content: messageContent, } @@ -244,7 +331,7 @@ func successSignin(w http.ResponseWriter, r *http.Request) { defer client.Disconnect(context.Background()) // Insert the message into the database - _, err = messageCollection.InsertOne(context.TODO(), message) + _, err = postsCollection.InsertOne(context.TODO(), message) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -257,56 +344,44 @@ func successSignin(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } + fmt.Println(messages) - // 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] - if !ok { - // Create a new session - session = Session{ - ID: time.Now().String(), - CreationTime: time.Now(), - } - 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() { - // 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 { + return nil, err + } + defer client.Disconnect(context.Background()) + + // Retrieve the user's messages from the database + var messages []models.Post + cursor, err := postsCollection.Find(context.Background(), bson.M{"username": username}) + if err != nil { + return nil, err + } + defer cursor.Close(context.Background()) + for cursor.Next(context.Background()) { + var message models.Post + err := cursor.Decode(&message) + if err != nil { + return nil, err + } + messages = append(messages, message) + } + + fmt.Println("printing messages from user" + username) + fmt.Println(messages) + + + return messages, nil +} + +func getUserMessages_backup(username string) ([]models.Post, error) { // Connect to the MongoDB database //clientOptions := options.Client().ApplyURI(URI) //client, err := mongo.Connect(context.Background(), clientOptions) @@ -315,15 +390,17 @@ func getUserMessages(username string) ([]models.Post, error) { //} //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}) + // Query the messages table for messages with the given username + rows, err := postsCollection.Find(context.Background(), bson.M{"username": username}) + fmt.Println("printing rows") + fmt.Println(rows) if err != nil { return nil, err } defer rows.Close(context.Background()) // Iterate over the rows and create Message objects - messages := []models.Post{} + messages = []models.Post{} for rows.Next(context.Background()) { var message models.Post err := rows.Decode(&message) @@ -336,8 +413,68 @@ func getUserMessages(username string) ([]models.Post, error) { 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": user.Username}).Decode(&user) + username := user.Username + fmt.Println("printing user related") + fmt.Println(user.Username) + fmt.Println(username) + // Retrieve the user's messages from the database + messages, err := getUserMessages(user.Username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Handle form submission for Post Writing + messageContent := r.FormValue("message") + // get the string of username + username_local := user.Username + if messageContent != "" { + // Create a new message object + message := models.Post{ + Username: username_local, + CreatedAt: time.Now(), + Content: messageContent, + Title: r.FormValue("title"), + } + + // Insert the message into the database + _, err = postsCollection.InsertOne(context.Background(), message) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Append the new message to the messages slice + messages = append(messages, message) + } + + // 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 + } +} +func profileHandler_backup(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) @@ -348,9 +485,10 @@ func profileHandler(w http.ResponseWriter, r *http.Request) { // Create a new message object message := models.Post{ //From: user.Username, - Username: "admin", + Username: user.Username, CreatedAt: time.Now(), Content: messageContent, + Title: r.FormValue("title"), } // Connect to the MongoDB database @@ -362,7 +500,7 @@ func profileHandler(w http.ResponseWriter, r *http.Request) { defer client.Disconnect(context.Background()) // Insert the message into the database - _, err = messageCollection.InsertOne(context.TODO(), message) + _, err = postsCollection.InsertOne(context.TODO(), message) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -398,6 +536,7 @@ func profileHandler(w http.ResponseWriter, r *http.Request) { func signInHandler(w http.ResponseWriter, r *http.Request) { username := r.FormValue("username") + username_global = username password := r.FormValue("password") var user models.User var messages []models.Post @@ -406,7 +545,7 @@ func signInHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/failed-signin", http.StatusTemporaryRedirect) return } - err = messageCollection.FindOne(context.Background(), bson.M{"username": username}).Decode(&messages) + err = postsCollection.FindOne(context.Background(), bson.M{"username": username}).Decode(&messages) data = models.PageTemplate{ Username: user.Username, Fullname: user.FullName, diff --git a/models/post.go b/models/post.go new file mode 100644 index 0000000000000000000000000000000000000000..5834e473418f6941e163160e3153de081c785baa --- /dev/null +++ b/models/post.go @@ -0,0 +1,15 @@ +package models + +import ( + "go.mongodb.org/mongo-driver/bson/primitive" + "time" +) + +type Post struct { + ID primitive.ObjectID `bson:"_id,omitempty"` + Username string `bson:"username"` + Title string `bson:"title"` + CreatedAt time.Time `bson:"timestamp"` + Content string `bson:"content"` //it will be rendered as HTML +} + diff --git a/models/user.go b/models/user.go index 031cfc4c3ff5951e3846b8ca3ec1a6bbd90bd0f9..918ec26a7f2cfa246dca7b39b2c309bf29ea59f6 100644 --- a/models/user.go +++ b/models/user.go @@ -18,4 +18,5 @@ type User struct { Age int Bio string Role string + Posts []Post } diff --git a/view/profile.html b/view/profile.html index 533b86181c67d7313058ad3e6004a7331d66114f..7b0fa657aabb78bf4b476ab5fe1e26dc38e0b719 100644 --- a/view/profile.html +++ b/view/profile.html @@ -89,16 +89,18 @@ <p id="admin"></p> </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> + <form action="/post" method="post"> + <label for="title">Title:</label> + <input type="text" id="title" name="title" required> + <label for="content">Content:</label> + <textarea id="content" name="content" required></textarea> + <input type="submit" value="Post"> + </form> - <button type="submit">Submit</button> + </div> - </form> + <h2>Posts</h2> <ul> {{range .Messages}} <li>{{.Content}} ({{.Timestamp}})</li>