Skip to content

Commit

Permalink
Merge pull request #31 from APandamonium1/modifying-user-details
Browse files Browse the repository at this point in the history
Modifying user details for admin & RBAC with google cloud authentication
  • Loading branch information
PeanutBrrutter authored Jul 7, 2024
2 parents 9ad1279 + 33a203f commit 3ff5d9f
Show file tree
Hide file tree
Showing 26 changed files with 1,934 additions and 228 deletions.
Binary file modified EduSync.exe
Binary file not shown.
252 changes: 252 additions & 0 deletions adminHandler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
package main

import (
"encoding/json"
"html/template"
"net/http"

"github.com/gorilla/mux"
)

func AdminHandler(router *mux.Router) {
router.HandleFunc("/admin", func(res http.ResponseWriter, req *http.Request) {
t, err := template.ParseFiles("templates/admin/index.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, nil)
}).Methods("GET")

router.HandleFunc("/admin/search_student", func(res http.ResponseWriter, req *http.Request) {
t, err := template.ParseFiles("templates/admin/search_student.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, nil)
}).Methods("GET")

router.HandleFunc("/admin/api/search_student", func(res http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get("name")
class := req.URL.Query().Get("class")
students, err := searchStudents(name, class)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(students)
}).Methods("GET")

router.HandleFunc("/admin/student/{googleID}/edit", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

student, err := readStudent(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}

t, err := template.ParseFiles("templates/admin/edit_student.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, student)
}).Methods("GET")

router.HandleFunc("/admin/student/{googleID}", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

switch req.Method {
case http.MethodGet:
student, err := readStudent(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(student)
case http.MethodPut:
var updates map[string]interface{}
if err := json.NewDecoder(req.Body).Decode(&updates); err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
if err := updateStudent(currentUser, googleID, updates); err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.WriteHeader(http.StatusNoContent)
}
}).Methods("GET", "PUT")

router.HandleFunc("/admin/search_parent", func(res http.ResponseWriter, req *http.Request) {
t, err := template.ParseFiles("templates/admin/search_parent.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, nil)
}).Methods("GET")

router.HandleFunc("/admin/api/search_parent", func(res http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get("name")
parents, err := searchParents(name)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(parents)
}).Methods("GET")

router.HandleFunc("/admin/parent/{googleID}/edit", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

parent, err := readParent(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}

t, err := template.ParseFiles("templates/admin/edit_parent.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, parent)
}).Methods("GET")

router.HandleFunc("/admin/parent/{googleID}", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

switch req.Method {
case http.MethodGet:
parent, err := readParent(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(parent)
case http.MethodPut:
var updates map[string]interface{}
if err := json.NewDecoder(req.Body).Decode(&updates); err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
if err := updateParent(currentUser, googleID, updates); err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.WriteHeader(http.StatusNoContent)
}
}).Methods("GET", "PUT")

router.HandleFunc("/admin/search_instructor", func(res http.ResponseWriter, req *http.Request) {
t, err := template.ParseFiles("templates/admin/search_instructor.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, nil)
}).Methods("GET")

router.HandleFunc("/admin/api/search_instructor", func(res http.ResponseWriter, req *http.Request) {
name := req.URL.Query().Get("name")
instructors, err := searchInstructors(name)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(instructors)
}).Methods("GET")

router.HandleFunc("/admin/instructor/{googleID}/edit", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

instructor, err := readInstructor(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}

t, err := template.ParseFiles("templates/admin/edit_instructor.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
t.Execute(res, instructor)
}).Methods("GET")

router.HandleFunc("/admin/instructor/{googleID}", func(res http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
googleID := vars["googleID"]

currentUser, err := GetCurrentUser(req)
if err != nil {
http.Error(res, "Unauthorized", http.StatusUnauthorized)
return
}

switch req.Method {
case http.MethodGet:
instructor, err := readInstructor(currentUser, googleID)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.Header().Set("Content-Type", "application/json")
json.NewEncoder(res).Encode(instructor)
case http.MethodPut:
var updates map[string]interface{}
if err := json.NewDecoder(req.Body).Decode(&updates); err != nil {
http.Error(res, err.Error(), http.StatusBadRequest)
return
}
if err := updateInstructor(currentUser, googleID, updates); err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
res.WriteHeader(http.StatusNoContent)
}
}).Methods("GET", "PUT")
}
14 changes: 14 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ html {
-webkit-text-size-adjust: 100%; /* 2 */
}

.content{
font-size: 16px;
margin-bottom: 100px;
}

.page-footer {
bottom: 0;
}

.button-container {
display: flex;
gap: 10px; /* Adjust the gap between buttons as needed */
}

/* Sections
========================================================================== */

Expand Down
84 changes: 55 additions & 29 deletions authHandler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"encoding/json"
"fmt"
"html/template"
"log"
Expand All @@ -24,10 +25,7 @@ func AuthHandler(router *mux.Router, config *Config) {
store.Options.Secure = isProd

gothic.Store = store

goth.UseProviders(
google.New(config.GoogleClientID, config.GoogleClientSecret, "https://localhost:8080/auth/google/callback", "email", "profile"),
)
goth.UseProviders(google.New(config.GoogleClientID, config.GoogleClientSecret, "https://localhost:8080/auth/google/callback", "email", "profile"))

router.HandleFunc("/auth/{provider}/callback", func(res http.ResponseWriter, req *http.Request) {
user, err := gothic.CompleteUserAuth(res, req)
Expand All @@ -36,35 +34,63 @@ func AuthHandler(router *mux.Router, config *Config) {
return
}

// Role assignment logic
var role string
switch user.Email {
case "[email protected]":
role = "Admin"
case "[email protected]":
role = "Instructor"
case "[email protected]":
role = "Parent"
default:
role = "Student"
}

// Create or update the user in Firebase with the assigned role
// student := NewStudent(user.UserID, user.Name, user.Email, "91234567", "TE", "Mr. Smith", "Jane Doe", role, 10, 10.0)
student := NewStudent(user.UserID, user.Name, user.Email, "91234567", "TE", "Jane Doe", role, 10, 10.0)
err = createStudent(student.User, student)
userObj, userRole, err := getUserRole(user.Email)
if err != nil {
log.Println("Error creating student:", err)
} else {
log.Println("Student created/updated successfully!")
fmt.Fprintln(res, err)
return
}
log.Println("User role:", userRole)

t, err := template.ParseFiles("templates/success.html")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
// Only store the user object into the session if userRole is not an empty string
if userRole != "" {
// Create a User object with the user role
currentUser := User{
GoogleID: user.UserID,
Name: user.Name,
Email: user.Email,
ContactNumber: userObj.ContactNumber, // Use contact number from the retrieved user object
Role: userObj.Role,
CreatedAt: userObj.CreatedAt,
UpdatedAt: userObj.UpdatedAt,
}

// Serialize the user object to JSON
userData, err := json.Marshal(currentUser)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}

// Get the session and store the user data
session, err := store.Get(req, "auth-session")
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}
session.Values["user"] = userData
err = session.Save(req, res)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
return
}

// Redirect based on user role
if userRole == "Admin" {
AdminHandler(router)
http.Redirect(res, req, "/admin", http.StatusFound)
} else if userRole == "Instructor" {
InstructorHandler(router)
http.Redirect(res, req, "/instructor", http.StatusFound)
} else if userRole == "Student" {
StudentHandler(router)
http.Redirect(res, req, "/student", http.StatusFound)
} else if userRole == "Parent" {
ParentHandler(router)
http.Redirect(res, req, "/parent", http.StatusFound)
}
} else {
http.Redirect(res, req, "/unregistered", http.StatusFound)
}
t.Execute(res, user)
}).Methods("GET")

router.HandleFunc("/auth/{provider}", func(res http.ResponseWriter, req *http.Request) {
Expand Down
Loading

0 comments on commit 3ff5d9f

Please sign in to comment.