diff --git a/.env b/.env index 6a1ca89e91d03b60218f83ce831a863a25da2331..1b01720b4c1ea67572f28dd7d623e377a0fb0d66 100644 --- a/.env +++ b/.env @@ -2,4 +2,4 @@ MONGO_URI=mongodb+srv://secapp-tp:hepiaschooltp@cluster0.pkjspwr.mongodb.net/ #MONGO_URI=mongodb+srv://yug:HUDDwcbVSuDzmDXG@cluster0.ttzwnxf.mongodb.net/ SENDGRID_API_KEY=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 SMTP_FROM_ADDRESS=notifications@mstd.dansmonorage.blue -PORT=5500 +PORT=5500 \ No newline at end of file diff --git a/README.md b/README.md index f10a5f0dd86191cac8d64fa51393114f2408c16c..ba7f30941ce9ac09a9ed142e6aa4fdadddcd292d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +User can report a message +• Admin can see top reported messages and can hide or delete +them +• Fat client that just show the number of all total messages + + # Basic Auth system Simple website of 3 screens (sign up, sign in and profile) diff --git a/main.go b/main.go index a22e9303ae5f1679c9be84b7cb1a3e52f0d09702..72f0146ea5ad3d5cb6df2a901647b51b33c297eb 100644 --- a/main.go +++ b/main.go @@ -1,25 +1,25 @@ package main import ( - "tp-secApp/models" "context" + "encoding/json" "fmt" - "html/template" - "log" - "net/http" - "os" + "github.com/go-gomail/gomail" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" - "go.mongodb.org/mongo-driver/bson/primitive" - "strconv" - "time" - "github.com/go-gomail/gomail" + "html/template" "io" + "log" "mime/multipart" - "encoding/json" + "net/http" + "os" + "strconv" "strings" + "time" + "tp-secApp/models" ) var usersCollection *mongo.Collection @@ -47,18 +47,18 @@ type Session struct { var sessions map[string]Session func cleanupSessions(w http.ResponseWriter, r *http.Request) { - expirationDuration := 10 * time.Second + expirationDuration := 10 * time.Second - for sessionID, session := range sessions { - if time.Since(session.CreationTime) > expirationDuration { - // Session has expired, remove it - delete(sessions, sessionID) + for sessionID, session := range sessions { + if time.Since(session.CreationTime) > expirationDuration { + // Session has expired, remove it + delete(sessions, sessionID) // call the timeoutHandler timeoutfor(w, r) - fmt.Printf("Session with ID %s has expired.\n", sessionID) - } - } + fmt.Printf("Session with ID %s has expired.\n", sessionID) + } + } } func timeoutfor(w http.ResponseWriter, r *http.Request) { @@ -67,17 +67,17 @@ func timeoutfor(w http.ResponseWriter, r *http.Request) { } func sendPasswordResetEmail(email, token string) error { - m := gomail.NewMessage() + m := gomail.NewMessage() //sendgrid_email := os.Getenv("SMTP_FROM_ADDRESS") - m.SetHeader("From", "notifications@mstd.dansmonorage.blue") - m.SetHeader("To", email) - m.SetHeader("Subject", "Password Reset") - m.SetBody("text/html", fmt.Sprintf(":((", token)) + m.SetHeader("From", "notifications@mstd.dansmonorage.blue") + m.SetHeader("To", email) + m.SetHeader("Subject", "Password Reset") + m.SetBody("text/html", fmt.Sprintf(":((", token)) - sendgrid := os.Getenv("SENDGRID_API_KEY") + sendgrid := os.Getenv("SENDGRID_API_KEY") d := gomail.NewDialer("smtp.sendgrid.net", 587, "apikey", sendgrid) // Send the email - return d.DialAndSend(m) + return d.DialAndSend(m) } func getAllUsers() ([]models.User, error) { @@ -109,157 +109,55 @@ func getAllUsers() ([]models.User, error) { } func adminHandler(w http.ResponseWriter, r *http.Request) { - // Check if the user is an admin - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if user.Role != "admin" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // Retrieve all users from the database - users, err := getAllUsers() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Filter the users to only include admins - var admins []models.User - for _, user := range users { - if user.Role != "admin" { - admins = append(admins, user) - } - } - - // Render the admin page with the list of admins - tmpl, err := template.ParseFiles("./view/admin.html") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = tmpl.Execute(w, models.AdminTemplate{ - Users: admins, - }) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } -func adminHandler_old(w http.ResponseWriter, r *http.Request) { - // Check if the user is an admin - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - fmt.Println("printing user role") - fmt.Println(user.Role) - if user.Role != "admin" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // Retrieve all users from the database - users, err := getAllUsers() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Render the admin page with the list of users - tmpl, err := template.ParseFiles("./view/admin.html") + // Retrieve all users from the database + users, err := getAllUsers() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Filter the users to only include admins + var admins []models.User for _, user := range users { - if user.Role == "admin" { + if user.Role != "admin" { admins = append(admins, user) } } - // Pass the filtered list of admins to the template - err = tmpl.Execute(w, admins) + // Render the admin page with the list of admins + tmpl, err := template.ParseFiles("./view/admin.html") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } -} - -// 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) + err = tmpl.Execute(w, models.AdminTemplate{ + Users: admins, + }) 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) } +// Define a function to handle the POST request + func updateUserAvatar(username, avatarURL string) (models.User, error) { // Connect to the MongoDB database clientOptions := options.Client().ApplyURI(URI) @@ -268,15 +166,15 @@ func updateUserAvatar(username, avatarURL string) (models.User, error) { return models.User{}, err } defer client.Disconnect(context.Background()) - + // Update the user's avatar URL in the database _, err = usersCollection.UpdateOne(context.Background(), bson.M{"username": username}, bson.M{"$set": bson.M{"avatar": avatarURL}}) if err != nil { return models.User{}, err } - - user, err:= getUser(username) - if(err != nil) { + + user, err := getUser(username) + if err != nil { return models.User{}, err } user.Avatar = avatarURL @@ -287,60 +185,17 @@ func updateUserAvatar(username, avatarURL string) (models.User, error) { return user, nil } -func uploadAvatarHandler(w http.ResponseWriter, r *http.Request) { - // Get the user's username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - username := cookie.Value - - // Retrieve the uploaded image data - file, _, err := r.FormFile("avatar") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer file.Close() - - // Save the uploaded image to disk - filename := fmt.Sprintf("%s.jpg", username) - err = os.MkdirAll("./uploads", os.ModePerm) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - f, err := os.OpenFile("./uploads/"+filename, os.O_WRONLY|os.O_CREATE, 0666) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer f.Close() - io.Copy(f, file) - - // Update the user's avatar URL in the database - userUpdated, err = updateUserAvatar(username, "/uploads/"+filename) - 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) + sessions = make(map[string]Session) // Load the .env file godotenv.Load() 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 - // of control and begins panicking. - // When the function F calls panic, execution of F stops, + panic(err) //panic is a built-in function that stops the ordinary flow + // of control and begins panicking. + // When the function F calls panic, execution of F stops, // any deferred functions in F are executed normally, and then F returns to its caller. } fmt.Println("Connected successfully") @@ -368,9 +223,203 @@ func main() { http.HandleFunc("/api/message/", IDmessagesAPIHandler) http.HandleFunc("/api/message", postPublicMessageHandler) http.HandleFunc("/generate-api-token", generateAPITokenHandler) + http.HandleFunc("/report", reportHandler) + http.HandleFunc("/admin-handle-report", adminHandleReportHandler) + http.HandleFunc("/hide-message", hideMessageHandler) + http.HandleFunc("/delete-message", deleteMessageHandler) log.Fatal(http.ListenAndServe(":5500", nil)) } +func deleteMessageHandler(w http.ResponseWriter, r *http.Request) { + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // Get message ID from request + messageId := r.PostFormValue("messageID") + + objID, err := primitive.ObjectIDFromHex(messageId) + if err != nil { + http.Error(w, "Invalid message ID", http.StatusBadRequest) + return + } + + // Delete message from database + _, err = privateMessagesCollection.DeleteOne(context.Background(), bson.M{"_id": objID}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect back to the admin handle report page + http.Redirect(w, r, "/admin-handle-report", http.StatusSeeOther) +} + +func hideMessageHandler(w http.ResponseWriter, r *http.Request) { + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // Connect to the MongoDB database + clientOptions := options.Client().ApplyURI(URI) + client, err := mongo.Connect(context.Background(), clientOptions) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer client.Disconnect(context.Background()) + + // Get message ID from request + messageId := r.PostFormValue("messageID") + + objID, err := primitive.ObjectIDFromHex(messageId) + if err != nil { + http.Error(w, "Invalid message ID", http.StatusBadRequest) + return + } + // Update message to set Hidden field to true + _, err = privateMessagesCollection.UpdateOne(context.Background(), bson.M{"_id": objID}, bson.M{"$set": bson.M{"hidden": true}}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect back to the admin handle report page + http.Redirect(w, r, "/admin-handle-report", http.StatusSeeOther) +} + +func adminHandleReportHandler(w http.ResponseWriter, r *http.Request) { + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + // Connect to the MongoDB database + clientOptions := options.Client().ApplyURI(URI) + client, err := mongo.Connect(context.Background(), clientOptions) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer client.Disconnect(context.Background()) + // Retrieve all messages that are reported from the database + var messages []models.PrivateMessage + cursor, err := privateMessagesCollection.Find(context.Background(), bson.M{"reports": bson.M{"$gt": 0}}) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer cursor.Close(context.Background()) + // Iterate through the messages + for cursor.Next(context.Background()) { + var message models.PrivateMessage + err := cursor.Decode(&message) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + messages = append(messages, message) + } + fmt.Println("printing reported messages") + fmt.Println(messages) + // Render the admin-handle-report.html page + data := struct { + Messages []models.PrivateMessage + }{ + Messages: messages, + } + tmpl := template.Must(template.ParseFiles("view/admin-handle-report.html")) + tmpl.Execute(w, data) +} + +func reportHandler(w http.ResponseWriter, r *http.Request) { + // Get the message ID from the request + messageID := r.FormValue("messageID") + fmt.Println("printing messageID") + fmt.Println(messageID) + objID, err := primitive.ObjectIDFromHex(messageID) + if err != nil { + http.Error(w, "Invalid message ID", http.StatusBadRequest) + return + } + // Connect to the MongoDB database + clientOptions := options.Client().ApplyURI(URI) + client, err := mongo.Connect(context.Background(), clientOptions) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer client.Disconnect(context.Background()) + // Retrieve the message from the database + var message models.PrivateMessage + err = privateMessagesCollection.FindOne(context.Background(), bson.M{"_id": objID}).Decode(&message) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + // Print the message to the console + fmt.Println("message") + fmt.Println(message) + + // Increment the Reports field of the message + message.Reports++ + + // Update the message in the database + _, err = privateMessagesCollection.UpdateOne( + context.Background(), + bson.M{"_id": objID}, + bson.M{ + "$set": bson.M{ + "reports": message.Reports, + // include other fields that you want to update + }, + }, + ) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the previous page + http.Redirect(w, r, r.Referer(), http.StatusSeeOther) +} func postPublicMessageHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { @@ -396,7 +445,7 @@ func postPublicMessageHandler(w http.ResponseWriter, r *http.Request) { return } defer client.Disconnect(context.Background()) - + tokensCollection = client.Database("Token").Collection("tokens") err = tokensCollection.FindOne(context.Background(), bson.M{"token": token}).Decode(&result) if err != nil { @@ -407,14 +456,6 @@ func postPublicMessageHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("printing result") fmt.Println(result) - // Get the message data from the REST request body - - /*var message models.Post - err = json.NewDecoder(r.Body).Decode(&message) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - }*/ message := r.FormValue("message") // Create a document that contains the message doc := bson.M{"message": message} @@ -500,18 +541,6 @@ func IDmessagesAPIHandler(w http.ResponseWriter, r *http.Request) { } -func getMessage(client *mongo.Client, messageID string) (bson.M, error) { - messagesCollection := client.Database("yourDatabase").Collection("messages") - - var message bson.M - err := messagesCollection.FindOne(context.Background(), bson.M{"_id": messageID}).Decode(&message) - if err != nil { - return nil, err - } - - return message, nil -} - func messagesAPIHandler(w http.ResponseWriter, r *http.Request) { // Handle the API request here if r.Method != http.MethodGet { @@ -519,7 +548,6 @@ func messagesAPIHandler(w http.ResponseWriter, r *http.Request) { return } - // Check the XAPITOKEN header token := r.Header.Get("XAPITOKEN") @@ -527,7 +555,7 @@ func messagesAPIHandler(w http.ResponseWriter, r *http.Request) { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } - + // Verify the API token var result struct { Username string `bson:"username"` @@ -573,7 +601,7 @@ func messagesAPIHandler(w http.ResponseWriter, r *http.Request) { } // send the messages back to the user RESTfully err = json.NewEncoder(w).Encode(messages) - + } func getAllPrivateMessagesAdmin() ([]models.PrivateMessage, error) { @@ -601,38 +629,36 @@ func getAllPrivateMessagesAdmin() ([]models.PrivateMessage, error) { } messages = append(messages, message) } - fmt.Println("printing messages from getAllPrivateMessagesAdmin") - fmt.Println(messages) return messages, nil } func generateAPIToken(username string) string { - // Get the current time - now := time.Now() + // Get the current time + now := time.Now() - // Combine the username and the current time to create the token - token := fmt.Sprintf("%s_%d", username, now.Unix()) + // Combine the username and the current time to create the token + token := fmt.Sprintf("%s_%d", username, now.Unix()) - return token + return token } func generateAPITokenHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) - return - } - - // Get the username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value + if r.Method != http.MethodGet { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return + } + + // Get the username from the cookie + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value var isAdmin string = "false" - // Generate a new API token - token := generateAPIToken(username) + // Generate a new API token + token := generateAPIToken(username) // Connect to the MongoDB database clientOptions := options.Client().ApplyURI(URI) client, err := mongo.Connect(context.Background(), clientOptions) @@ -655,7 +681,7 @@ func generateAPITokenHandler(w http.ResponseWriter, r *http.Request) { } // Save the API token to the MongoDB database - tokensCollection := client.Database("Token").Collection("tokens") + tokensCollection := client.Database("Token").Collection("tokens") // Delete the user's old API token from the database if it exists _, err = tokensCollection.DeleteOne(context.Background(), bson.M{"username": username}) if err != nil { @@ -664,90 +690,55 @@ func generateAPITokenHandler(w http.ResponseWriter, r *http.Request) { } // Insert the token into the database - _, err = tokensCollection.InsertOne(context.TODO(), map[string]string{ - "username": username, - "token": token, - "is_admin": isAdmin, - }) + _, err = tokensCollection.InsertOne(context.TODO(), map[string]string{ + "username": username, + "token": token, + "is_admin": isAdmin, + }) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Display the API token to the user - w.Write([]byte("Your new API token is: " + token)) -} - -func privateMessagesAPIHandler(w http.ResponseWriter, r *http.Request) { - // Handle the API request here + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + // Display the API token to the user + w.Write([]byte("Your new API token is: " + token)) } func privateMessagesHandler(w http.ResponseWriter, r *http.Request) { - // Get the username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - - // Get the private messages from the database - messages, err := getAllPrivateMessages(username) - fmt.Println("printing messages") - fmt.Println(messages) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - // Convert the Content field to template.HTML - for i := range messages { - messages[i].Content = template.HTML(messages[i].Content) - } - // Create a data structure to hold the messages - data := struct { - PrivateMessages []models.PrivateMessage - }{ - PrivateMessages: messages, - } - - // Render the DM.html page - tmpl := template.Must(template.ParseFiles("view/DM.html")) - tmpl.Execute(w, data) -} - -func getAllPrivateMessages(username string) ([]models.PrivateMessage, error) { - // Connect to the MongoDB database - clientOptions := options.Client().ApplyURI(URI) - client, err := mongo.Connect(context.Background(), clientOptions) + // Get the username from the cookie + cookie, err := r.Cookie("username") if err != nil { - return nil, err + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return } - defer client.Disconnect(context.Background()) + username := cookie.Value - // Retrieve all private messages from the database - var messages []models.PrivateMessage - cursor, err := privateMessagesCollection.Find(context.Background(), bson.M{"$or": []bson.M{ - bson.M{"sender": username}, - bson.M{"receiver": username}, - }}) + // Get the private messages from the database + messages, err := getAllPrivateMessages(username) + fmt.Println("printing messages") + fmt.Println(messages) if err != nil { - return nil, err + http.Error(w, err.Error(), http.StatusInternalServerError) + return } - defer cursor.Close(context.Background()) - for cursor.Next(context.Background()) { - var message models.PrivateMessage - err := cursor.Decode(&message) - if err != nil { - return nil, err - } - messages = append(messages, message) + // Convert the Content field to template.HTML + for i := range messages { + messages[i].Content = template.HTML(messages[i].Content) + } + // Create a data structure to hold the messages + data := struct { + PrivateMessages []models.PrivateMessage + }{ + PrivateMessages: messages, } - return messages, nil + // Render the DM.html page + tmpl := template.Must(template.ParseFiles("view/DM.html")) + tmpl.Execute(w, data) } -func getPrivateMessages(username string) ([]models.PrivateMessage, error) { + +func getAllPrivateMessages(username string) ([]models.PrivateMessage, error) { // Connect to the MongoDB database clientOptions := options.Client().ApplyURI(URI) client, err := mongo.Connect(context.Background(), clientOptions) @@ -783,7 +774,7 @@ func sendPrivateMessage(sender, receiver, content string) error { message := models.PrivateMessage{ Sender: sender, Receiver: receiver, - Content: template.HTML(content), + Content: template.HTML(content), Timestamp: time.Now(), } @@ -805,28 +796,28 @@ func sendPrivateMessage(sender, receiver, content string) error { } func sendPrivateMessageHandler(w http.ResponseWriter, r *http.Request) { - // Get the username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - sender := cookie.Value - - // Get the receiver and content from the form data - receiver := r.FormValue("receiver") - content := r.FormValue("content") - - // Send the private message - err = sendPrivateMessage(sender, receiver, content) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Redirect the user back to the private messages page - http.Redirect(w, r, "/private-messages", http.StatusSeeOther) -} + // Get the username from the cookie + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + sender := cookie.Value + + // Get the receiver and content from the form data + receiver := r.FormValue("receiver") + content := r.FormValue("content") + + // Send the private message + err = sendPrivateMessage(sender, receiver, content) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the private messages page + http.Redirect(w, r, "/private-messages", http.StatusSeeOther) +} func adminChangePasswordHandler(w http.ResponseWriter, r *http.Request) { // Check if the user is an admin @@ -851,7 +842,7 @@ func adminChangePasswordHandler(w http.ResponseWriter, r *http.Request) { password := r.FormValue("password") // Update the user's password in the database - _,err = updateEmailAndPassword(usernameToChange, "", password) + _, err = updateEmailAndPassword(usernameToChange, "", password) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -861,8 +852,7 @@ func adminChangePasswordHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/admin", http.StatusSeeOther) } - -//deleteUser function +// deleteUser function func deleteUser(username string) error { // Connect to the MongoDB database clientOptions := options.Client().ApplyURI(URI) @@ -882,43 +872,43 @@ func deleteUser(username string) error { } func deleteHandler(w http.ResponseWriter, r *http.Request) { - // Check if the user is an admin - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if user.Role != "admin" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // Get the username to delete from the form data - usernameToDelete := r.FormValue("username") - - // Delete the user from the database - err = deleteUser(usernameToDelete) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Redirect the user back to the admin page - http.Redirect(w, r, "/admin", http.StatusSeeOther) + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // Get the username to delete from the form data + usernameToDelete := r.FormValue("username") + + // Delete the user from the database + err = deleteUser(usernameToDelete) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the admin page + http.Redirect(w, r, "/admin", http.StatusSeeOther) } -//getCurrentUser function +// getCurrentUser function func getCurrentUser(r *http.Request) models.User { return user } -//a saveUser function that updates the user and its posts in the database +// 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) @@ -938,27 +928,27 @@ func saveUser(user models.User) error { } 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(), - } + // 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) @@ -976,20 +966,18 @@ func handlePost(w http.ResponseWriter, r *http.Request) { return } - - - // Append the new post to the user's Posts slice - user.Posts = append(user.Posts, post) + // 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 - } + // 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) + // Redirect the user back to the profile page + http.Redirect(w, r, "/profile", http.StatusSeeOther) } func handlePasswordReset(w http.ResponseWriter, r *http.Request) { @@ -1025,8 +1013,8 @@ func signUpHandler(w http.ResponseWriter, r *http.Request) { Email: email, Password: password, Username: username, - Age: age, - Bio: bio, + Age: age, + Bio: bio, Role: admin, Avatar: "https://mstd.dansmonorage.blue/system/site_uploads/files/000/000/002/original/mascot.png", } @@ -1061,8 +1049,8 @@ func successSignin(w http.ResponseWriter, r *http.Request) { } cookie := http.Cookie{ - Name: "username", - Value: username_global, + Name: "username", + Value: username_global, Expires: time.Now().Add(24 * time.Hour), } http.SetCookie(w, &cookie) @@ -1077,20 +1065,17 @@ 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) 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{ - Username: username_global, - Title: r.FormValue("title"), + Username: username_global, + Title: r.FormValue("title"), CreatedAt: time.Now(), Content: messageContent, } @@ -1141,7 +1126,7 @@ func getUser(username string) (models.User, error) { return user, nil } -//updateUser updates a user document in the database. +// updateUser updates a user document in the database. func updateUser(user models.User) error { // Connect to the MongoDB database clientOptions := options.Client().ApplyURI(URI) @@ -1193,79 +1178,77 @@ func updateEmailAndPassword(username, email, password string) (models.User, erro return models.User{}, err } defer client.Disconnect(context.Background()) - + // Update the user's avatar URL in the database _, err = usersCollection.UpdateOne(context.Background(), bson.M{"username": username}, bson.M{"$set": bson.M{"email": email, "password": password}}) if err != nil { return models.User{}, err } - - user, err:= getUser(username) - if(err != nil) { + + user, err := getUser(username) + if err != nil { return models.User{}, err } user.Email = email user.Password = password - return user, nil } func editbyAdminHandler(w http.ResponseWriter, r *http.Request) { - // Check if the user is an admin - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if user.Role != "admin" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // Get the username, email, and password from the form data - usernameToUpdate := r.FormValue("username") - email := r.FormValue("email") - password := r.FormValue("password") - - // Update the email and password of the user in the database - _,err = updateEmailAndPassword(usernameToUpdate, email, password) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Redirect the user back to the admin page - http.Redirect(w, r, "/admin", http.StatusSeeOther) + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // Get the username, email, and password from the form data + usernameToUpdate := r.FormValue("username") + email := r.FormValue("email") + password := r.FormValue("password") + + // Update the email and password of the user in the database + _, err = updateEmailAndPassword(usernameToUpdate, email, password) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the admin page + http.Redirect(w, r, "/admin", http.StatusSeeOther) } func editbyAdminHandler_old(w http.ResponseWriter, r *http.Request) { - // Check if the user is an admin - cookie, err := r.Cookie("username") - if err != nil { - http.Redirect(w, r, "/signin", http.StatusSeeOther) - return - } - username := cookie.Value - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if user.Role != "admin" { - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - // Get the username to delete from the form data - usernameToEdit := r.FormValue("username") - + // Check if the user is an admin + cookie, err := r.Cookie("username") + if err != nil { + http.Redirect(w, r, "/signin", http.StatusSeeOther) + return + } + username := cookie.Value + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if user.Role != "admin" { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + + // Get the username to delete from the form data + usernameToEdit := r.FormValue("username") // Edit the user from the database userEdit, err := getUser(usernameToEdit) @@ -1303,7 +1286,7 @@ func editbyAdminHandler_old(w http.ResponseWriter, r *http.Request) { file, handler, err := r.FormFile("avatar") if err == nil { defer file.Close() - + // Save the file to disk err = saveAvatarFile(userEdit.Username, handler.Filename, file) if err != nil { @@ -1323,176 +1306,173 @@ func editbyAdminHandler_old(w http.ResponseWriter, r *http.Request) { } // Render the edit page with the user's information - tmpl, err := template.ParseFiles("./view/edit.html") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = tmpl.Execute(w, struct { - User models.User - }{ - User: user, - }) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Redirect the user back to the admin page - http.Redirect(w, r, "/admin", http.StatusSeeOther) + tmpl, err := template.ParseFiles("./view/edit.html") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + err = tmpl.Execute(w, struct { + User models.User + }{ + User: user, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Redirect the user back to the admin page + http.Redirect(w, r, "/admin", http.StatusSeeOther) } func editHandler(w http.ResponseWriter, r *http.Request) { - // Get the user's username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - username := cookie.Value + // Get the user's username from the cookie + cookie, err := r.Cookie("username") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + username := cookie.Value fmt.Println("printing username from cookie value in editHandler") fmt.Println(username) - // Retrieve the user's information from the database - user, err := getUser(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Handle form submission - if r.Method == "POST" { - // Parse the form data - err := r.ParseMultipartForm(32 << 20) // 32 MB - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Update the user's information in the database - user.FullName = r.FormValue("fullname") - user.Email = r.FormValue("email") - err = updateUser(user) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Upload the new avatar file (if provided) - file, handler, err := r.FormFile("avatar") - if err == nil { - defer file.Close() - - // Save the file to disk - err = saveAvatarFile(user.Username, handler.Filename, file) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Update the user's avatar URL in the database - user.Avatar = fmt.Sprintf("/avatars/%s/%s", user.Username, handler.Filename) - err = updateUser(user) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } - - // Redirect the user to the profile page - http.Redirect(w, r, "/profile", http.StatusSeeOther) - return - } - - // Render the edit page with the user's information - tmpl, err := template.ParseFiles("./view/edit.html") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = tmpl.Execute(w, struct { - User models.User - }{ - User: user, - }) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } + // Retrieve the user's information from the database + user, err := getUser(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Handle form submission + if r.Method == "POST" { + // Parse the form data + err := r.ParseMultipartForm(32 << 20) // 32 MB + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Update the user's information in the database + user.FullName = r.FormValue("fullname") + user.Email = r.FormValue("email") + err = updateUser(user) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Upload the new avatar file (if provided) + file, handler, err := r.FormFile("avatar") + if err == nil { + defer file.Close() + + // Save the file to disk + err = saveAvatarFile(user.Username, handler.Filename, file) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Update the user's avatar URL in the database + user.Avatar = fmt.Sprintf("/avatars/%s/%s", user.Username, handler.Filename) + err = updateUser(user) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } + + // Redirect the user to the profile page + http.Redirect(w, r, "/profile", http.StatusSeeOther) + return + } + + // Render the edit page with the user's information + tmpl, err := template.ParseFiles("./view/edit.html") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + err = tmpl.Execute(w, struct { + User models.User + }{ + User: user, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } } func messagesHandler(w http.ResponseWriter, r *http.Request) { - // Get the user's username from the cookie - cookie, err := r.Cookie("username") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - username := cookie.Value - - // Retrieve the user's messages from the database - messages, err := getUserMessages(username) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Render the messages page with the user's messages - tmpl, err := template.ParseFiles("./view/messages.html") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - err = tmpl.Execute(w, struct { - Messages []models.Post - }{ - Messages: messages, - }) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } + // Get the user's username from the cookie + cookie, err := r.Cookie("username") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + username := cookie.Value + + // Retrieve the user's messages from the database + messages, err := getUserMessages(username) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Render the messages page with the user's messages + tmpl, err := template.ParseFiles("./view/messages.html") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + err = tmpl.Execute(w, struct { + Messages []models.Post + }{ + Messages: messages, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } } 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) - } - - - - - return messages, nil + // 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) + } + + 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) - //if err != nil { - // log.Fatal(err) - //} - //defer client.Disconnect(context.Background()) + // 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 username rows, err := postsCollection.Find(context.Background(), bson.M{"username": username}) @@ -1502,7 +1482,7 @@ func getUserMessages_backup(username string) ([]models.Post, error) { return nil, err } defer rows.Close(context.Background()) - + // Iterate over the rows and create Message objects messages = []models.Post{} for rows.Next(context.Background()) { @@ -1514,69 +1494,68 @@ func getUserMessages_backup(username string) ([]models.Post, error) { 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": user.Username}).Decode(&user) + // 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") + // 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 - } + 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 @@ -1589,10 +1568,10 @@ func profileHandler_backup(w http.ResponseWriter, r *http.Request) { // Create a new message object message := models.Post{ //From: user.Username, - Username: user.Username, + Username: user.Username, CreatedAt: time.Now(), Content: messageContent, - Title: r.FormValue("title"), + Title: r.FormValue("title"), } // Connect to the MongoDB database @@ -1654,9 +1633,9 @@ func signInHandler(w http.ResponseWriter, r *http.Request) { Username: user.Username, Fullname: user.FullName, Email: user.Email, - Age: user.Age, - Bio: user.Bio, - Role: user.Role, + Age: user.Age, + Bio: user.Bio, + Role: user.Role, Messages: messages, } // Create a new session @@ -1667,6 +1646,5 @@ func signInHandler(w http.ResponseWriter, r *http.Request) { } sessions[session.ID] = session - http.Redirect(w, r, "/profile", http.StatusTemporaryRedirect) } diff --git a/models/private_message.go b/models/private_message.go index d57b132fede627ccb81b7076bd0fe6f30c5af439..2d0f7408c3ece37e189f75df2802e265d89ba5ed 100644 --- a/models/private_message.go +++ b/models/private_message.go @@ -11,4 +11,6 @@ type PrivateMessage struct { Receiver string `bson:"receiver"` Content template.HTML `bson:"content"` Timestamp time.Time `bson:"timestamp"` + Reports int `bson:"reports"` + Hidden bool `bson:"hidden"` } \ No newline at end of file diff --git a/ouput/go_build_auth_login_school_tp b/ouput/go_build_auth_login_school_tp new file mode 100755 index 0000000000000000000000000000000000000000..bb7da685033ea87ea7ed9a89c8c8332814db1805 --- /dev/null +++ b/ouput/go_build_auth_login_school_tp @@ -0,0 +1 @@ +ELF \ No newline at end of file diff --git a/ouput/go_build_auth_login_school_tp_ b/ouput/go_build_auth_login_school_tp_ new file mode 100755 index 0000000000000000000000000000000000000000..bb7da685033ea87ea7ed9a89c8c8332814db1805 --- /dev/null +++ b/ouput/go_build_auth_login_school_tp_ @@ -0,0 +1 @@ +ELF \ No newline at end of file diff --git a/output b/output index af9ba38241307c9d14cc480e33b32b58495ef669..c87eef1b3f7b8b1852d9434d76afe9ddd649d216 100755 Binary files a/output and b/output differ diff --git a/view/DM.html b/view/DM.html index 2263ddcf4e199e7c8ff1bf072c6cadb7eec4aecd..05a6fc80ad3149b2f294e51d5a6ac9596038acd3 100644 --- a/view/DM.html +++ b/view/DM.html @@ -18,9 +18,16 @@ <ul> {{range .PrivateMessages}} <li> + {{if not .Hidden}} + <p> Message ID : {{.ID}}</p> <p>From: {{.Sender}} To: {{.Receiver}}</p> <p>Message: {{.Content}}</p> <p>Time: {{.Timestamp}}</p> + <form method="POST" action="/report"> + <input type="hidden" name="messageID" value="{{.ID}}"> + <button type="submit">Report</button> + </form> + {{end}} </li> {{end}} </ul> diff --git a/view/admin-handle-report.html b/view/admin-handle-report.html new file mode 100644 index 0000000000000000000000000000000000000000..f630c7fed5ac497ec45b77509b908a7679e9fdf3 --- /dev/null +++ b/view/admin-handle-report.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> + +<head> + <title>Admin - Handle Reports</title> +</head> + +<body> + <h1>Reported Messages</h1> + <ul> + {{range .Messages}} + <li> + <p>Message ID: {{.ID}}</p> + <p>From: {{.Sender}} To: {{.Receiver}}</p> + <p>Message: {{.Content}}</p> + <p>Time: {{.Timestamp}}</p> + <p>Reports: {{.Reports}}</p> + <form method="POST" action="/hide-message"> + <input type="hidden" name="messageID" value="{{.ID}}"> + <button type="submit">Hide</button> + </form> + <form method="POST" action="/delete-message"> + <input type="hidden" name="messageID" value="{{.ID}}"> + <button type="submit">Delete</button> + </form> + </li> + {{end}} + </ul> +</body> + +</html> \ No newline at end of file diff --git a/view/profile.html b/view/profile.html index 104ab2ed1a0e82a17df7006ac5114c50d7de3d6c..c57d7ef7d75272ccd456e2a127640cb02056877e 100644 --- a/view/profile.html +++ b/view/profile.html @@ -88,6 +88,7 @@ <p id="bio">{{.Bio}}</p> <p id="admin"></p> </div> + <p><a href="/private-messages">Private Messages</a></p> <p><a href="index.html">Logout</a></p> <form action="/post" method="post">