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