diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index 46ad272..33c25fe 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -50,6 +50,9 @@ func (a *Api) StartApi() { authentication := r.PathPrefix("/api/auth").Subrouter() authentication.HandleFunc("/login", a.generateToken).Methods("PUT") authentication.HandleFunc("/register", a.registerUser).Methods("POST") + authentication.HandleFunc("/delete/{user}", a.deleteUser).Methods("DELETE") + authentication.HandleFunc("/password/{user}", a.changePassword).Methods("PUT") + authentication.HandleFunc("/password", a.changePassword).Methods("PUT") authentication.HandleFunc("/admin/register", a.registerAdminUser).Methods("POST") authentication.HandleFunc("/admin/exists", a.adminUserExists).Methods("GET") iot := r.PathPrefix("/api/device").Subrouter() diff --git a/backend/services/controller/internal/api/user.go b/backend/services/controller/internal/api/user.go index 59891e3..6800d40 100644 --- a/backend/services/controller/internal/api/user.go +++ b/backend/services/controller/internal/api/user.go @@ -5,8 +5,10 @@ import ( "log" "net/http" + "github.com/gorilla/mux" "github.com/leandrofars/oktopus/internal/api/auth" "github.com/leandrofars/oktopus/internal/db" + "github.com/leandrofars/oktopus/internal/utils" ) func (a *Api) retrieveUsers(w http.ResponseWriter, r *http.Request) { @@ -68,6 +70,81 @@ func (a *Api) registerUser(w http.ResponseWriter, r *http.Request) { } } +func (a *Api) deleteUser(w http.ResponseWriter, r *http.Request) { + tokenString := r.Header.Get("Authorization") + if tokenString == "" { + w.WriteHeader(http.StatusUnauthorized) + return + } + email, err := auth.ValidateToken(tokenString) + if err != nil { + w.WriteHeader(http.StatusUnauthorized) + return + } + + //Check if user which is requesting deletion has the necessary privileges + rUser, err := a.db.FindUser(email) + if rUser.Level != AdminUser { + w.WriteHeader(http.StatusForbidden) + return + } + + userEmail := mux.Vars(r)["user"] + if userEmail == email { + w.WriteHeader(http.StatusBadRequest) + return + } + + if err := a.db.DeleteUser(userEmail); err != nil { + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(err) + return + } +} + +func (a *Api) changePassword(w http.ResponseWriter, r *http.Request) { + tokenString := r.Header.Get("Authorization") + if tokenString == "" { + w.WriteHeader(http.StatusUnauthorized) + return + } + email, err := auth.ValidateToken(tokenString) + if err != nil { + w.WriteHeader(http.StatusUnauthorized) + return + } + + userToChangePasswd := mux.Vars(r)["user"] + if userToChangePasswd != "" && userToChangePasswd != email { + rUser, _ := a.db.FindUser(email) + if rUser.Level != AdminUser { + w.WriteHeader(http.StatusForbidden) + return + } + email = userToChangePasswd + } + + var user db.User + err = json.NewDecoder(r.Body).Decode(&user) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + utils.MarshallEncoder(err, w) + return + } + user.Email = email + + if err := user.HashPassword(user.Password); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + if err := a.db.UpdatePassword(user); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + +} + func (a *Api) registerAdminUser(w http.ResponseWriter, r *http.Request) { var user db.User diff --git a/backend/services/controller/internal/db/user.go b/backend/services/controller/internal/db/user.go index 3f251d1..af0950f 100644 --- a/backend/services/controller/internal/db/user.go +++ b/backend/services/controller/internal/db/user.go @@ -27,6 +27,11 @@ func (d *Database) RegisterUser(user User) error { return err } +func (d *Database) UpdatePassword(user User) error { + _, err := d.users.UpdateOne(d.ctx, bson.D{{"email", user.Email}}, bson.D{{"$set", bson.D{{"password", user.Password}}}}) + return err +} + func (d *Database) FindAllUsers() ([]map[string]interface{}, error) { var result []map[string]interface{} cursor, err := d.users.Find(d.ctx, bson.D{{}}) @@ -45,6 +50,11 @@ func (d *Database) FindUser(email string) (User, error) { return result, err } +func (d *Database) DeleteUser(email string) error { + _, err := d.users.DeleteOne(d.ctx, bson.D{{"email", email}}) + return err +} + func (user *User) HashPassword(password string) error { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) if err != nil {