Skip to content
Snippets Groups Projects
Commit 3363892f authored by guoguo.yu's avatar guoguo.yu :speech_balloon:
Browse files

update

parent 2c478b62
No related branches found
No related tags found
No related merge requests found
...@@ -15,6 +15,8 @@ import ( ...@@ -15,6 +15,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/go-gomail/gomail" "github.com/go-gomail/gomail"
"io"
"mime/multipart"
) )
var usersCollection *mongo.Collection var usersCollection *mongo.Collection
...@@ -23,7 +25,10 @@ var URI string ...@@ -23,7 +25,10 @@ var URI string
var messages []models.Post var messages []models.Post
var err error var err error
var user models.User var user models.User
var userUpdated models.User
var username_global string var username_global string
var globalAvatarURL string = "https://mstd.dansmonorage.blue/system/site_uploads/files/000/000/002/original/mascot.png"
var admins []models.User
// Session represents a user session. // Session represents a user session.
type Session struct { type Session struct {
...@@ -70,6 +75,130 @@ func sendPasswordResetEmail(email, token string) error { ...@@ -70,6 +75,130 @@ func sendPasswordResetEmail(email, token string) error {
return d.DialAndSend(m) return d.DialAndSend(m)
} }
func getAllUsers() ([]models.User, 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 all users from the database
var users []models.User
cursor, err := usersCollection.Find(context.Background(), bson.M{})
if err != nil {
return nil, err
}
defer cursor.Close(context.Background())
for cursor.Next(context.Background()) {
var user models.User
err := cursor.Decode(&user)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
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
}
}
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")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Filter the users to only include admins
for _, user := range users {
if user.Role == "admin" {
admins = append(admins, user)
}
}
// Pass the filtered list of admins to the template
err = tmpl.Execute(w, admins)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
// Define a function to handle the POST request // Define a function to handle the POST request
func handleMessage(w http.ResponseWriter, r *http.Request) { func handleMessage(w http.ResponseWriter, r *http.Request) {
...@@ -126,6 +255,76 @@ func handleMessage(w http.ResponseWriter, r *http.Request) { ...@@ -126,6 +255,76 @@ func handleMessage(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/profile", http.StatusTemporaryRedirect) http.Redirect(w, r, "/profile", http.StatusTemporaryRedirect)
} }
func updateUserAvatar(username, avatarURL string) (models.User, error) {
// Connect to the MongoDB database
clientOptions := options.Client().ApplyURI(URI)
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
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) {
return models.User{}, err
}
user.Avatar = avatarURL
data.Avatar = avatarURL
globalAvatarURL = avatarURL
data.GlobalAvatarURL = avatarURL
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() { func main() {
// Initialize the sessions map // Initialize the sessions map
sessions = make(map[string]Session) sessions = make(map[string]Session)
...@@ -150,9 +349,65 @@ func main() { ...@@ -150,9 +349,65 @@ func main() {
http.HandleFunc("/profile", successSignin) http.HandleFunc("/profile", successSignin)
http.HandleFunc("/reset-password", handlePasswordReset) http.HandleFunc("/reset-password", handlePasswordReset)
http.HandleFunc("/post", handlePost) http.HandleFunc("/post", handlePost)
http.HandleFunc("/messages", messagesHandler)
http.HandleFunc("/edit", editHandler)
http.HandleFunc("/admin", adminHandler)
http.HandleFunc("/delete", deleteHandler)
log.Fatal(http.ListenAndServe(":5500", nil)) log.Fatal(http.ListenAndServe(":5500", nil))
} }
//deleteUser function
func deleteUser(username string) error {
// Connect to the MongoDB database
clientOptions := options.Client().ApplyURI(URI)
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
return err
}
defer client.Disconnect(context.Background())
// Delete the user from the database
_, err = usersCollection.DeleteOne(context.Background(), bson.M{"username": username})
if err != nil {
return err
}
return nil
}
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)
}
//getCurrentUser function //getCurrentUser function
func getCurrentUser(r *http.Request) models.User { func getCurrentUser(r *http.Request) models.User {
return user return user
...@@ -268,6 +523,7 @@ func signUpHandler(w http.ResponseWriter, r *http.Request) { ...@@ -268,6 +523,7 @@ func signUpHandler(w http.ResponseWriter, r *http.Request) {
Age: age, Age: age,
Bio: bio, Bio: bio,
Role: admin, Role: admin,
Avatar: "https://mstd.dansmonorage.blue/system/site_uploads/files/000/000/002/original/mascot.png",
} }
var search models.User var search models.User
if usersCollection.FindOne(context.TODO(), bson.M{"username": username}).Decode(&search); search.Username == username { if usersCollection.FindOne(context.TODO(), bson.M{"username": username}).Decode(&search); search.Username == username {
...@@ -299,11 +555,24 @@ func successSignin(w http.ResponseWriter, r *http.Request) { ...@@ -299,11 +555,24 @@ func successSignin(w http.ResponseWriter, r *http.Request) {
return return
} }
cookie := http.Cookie{
Name: "username",
Value: username_global,
Expires: time.Now().Add(24 * time.Hour),
}
http.SetCookie(w, &cookie)
username := cookie.Value
fmt.Println("printing username from cookie value")
fmt.Println(username)
err = tmpl.Execute(w, data) err = tmpl.Execute(w, data)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
// Get the username from the database // Get the username from the database
//var user models.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": r.FormValue("username")}).Decode(&user)
...@@ -315,7 +584,6 @@ func successSignin(w http.ResponseWriter, r *http.Request) { ...@@ -315,7 +584,6 @@ func successSignin(w http.ResponseWriter, r *http.Request) {
if messageContent != "" { if messageContent != "" {
// Create a new message object // Create a new message object
message := models.Post{ message := models.Post{
//From: user.Username,
Username: username_global, Username: username_global,
Title: r.FormValue("title"), Title: r.FormValue("title"),
CreatedAt: time.Now(), CreatedAt: time.Now(),
...@@ -345,29 +613,183 @@ func successSignin(w http.ResponseWriter, r *http.Request) { ...@@ -345,29 +613,183 @@ func successSignin(w http.ResponseWriter, r *http.Request) {
return return
} }
fmt.Println(messages) fmt.Println(messages)
// Render the profile page with the user's messages
tmpl, err := template.ParseFiles("./view/profile.html") }
// getUser retrieves a user document from the database.
func getUser(username string) (models.User, error) {
// Connect to the MongoDB database
clientOptions := options.Client().ApplyURI(URI)
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
return models.User{}, err
}
defer client.Disconnect(context.Background())
// Retrieve the user document from the database
var user models.User
err = usersCollection.FindOne(context.Background(), bson.M{"username": username}).Decode(&user)
if err != nil {
return models.User{}, err
}
return user, nil
}
//updateUser updates a user document in the database.
func updateUser(user models.User) error {
// Connect to the MongoDB database
clientOptions := options.Client().ApplyURI(URI)
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
return 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
}
// saveAvatarFile saves an avatar file to disk.
func saveAvatarFile(username, filename string, file multipart.File) error {
// Create the uploads directory if it does not already exist
err := os.MkdirAll("./uploads", os.ModePerm)
if err != nil {
return err
}
// Create a new file in the uploads directory
f, err := os.OpenFile("./uploads/"+username+"_"+filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
defer f.Close()
// Copy the uploaded file to the new file
_, err = io.Copy(f, file)
if err != nil {
return err
}
return nil
}
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
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 { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
err = tmpl.Execute(w, struct { err = tmpl.Execute(w, struct {
User models.User User models.User
Messages []models.Post
FullName string
Email string
}{ }{
User: user, User: user,
Messages: messages,
FullName: user.FullName,
Email: user.Email,
}) })
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return 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
}
} }
func getUserMessages(username string) ([]models.Post, error) { func getUserMessages(username string) ([]models.Post, error) {
......
...@@ -10,4 +10,12 @@ type PageTemplate struct { ...@@ -10,4 +10,12 @@ type PageTemplate struct {
UserID int UserID int
Role string Role string
Messages []Post Messages []Post
Avatar string
User User
GlobalAvatarURL string
}
type AdminTemplate struct {
Users []User
} }
\ No newline at end of file
...@@ -19,4 +19,5 @@ type User struct { ...@@ -19,4 +19,5 @@ type User struct {
Bio string Bio string
Role string Role string
Posts []Post Posts []Post
Avatar string `bson:"avatarURL"`
} }
...@@ -103,11 +103,21 @@ ...@@ -103,11 +103,21 @@
<h2>Posts</h2> <h2>Posts</h2>
<ul> <ul>
{{range .Messages}} {{range .Messages}}
<li>{{.Content}} ({{.Timestamp}})</li> <li>{{.Content}}</li>
{{end}} {{end}}
</ul> </ul>
<a href="/messages">Messages</a>
<h2>Avatar</h2>
{{if .User.Avatar}}
<img src="/uploads/{{.User.Avatar}}" alt="avatar" class="profile-photo">
{{else}}
<img src="https://mstd.dansmonorage.blue/system/site_uploads/files/000/000/002/original/mascot.png" alt="avatar"
class="profile-photo">
{{end}}
<a href="/edit?username={{.User.Username}}">EditProfile</a>
<a href="/admin">Admin</a>
<p>User ID: {{.UserID}}</p>
</body> </body>
</html> </html>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment