diff --git a/pkg/api/user/delete.go b/pkg/api/user/delete.go new file mode 100644 index 0000000..33a3bbb --- /dev/null +++ b/pkg/api/user/delete.go @@ -0,0 +1,60 @@ +package user + +import ( + "encoding/json" + "log" + "net/http" + "strconv" + + "github.com/Ennovar/gPanel/pkg/database" +) + +func Delete(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir string) bool { + if req.Method != "UPDATE" { + logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed)) + http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed) + return false + } + + var deleteUserRequestData struct { + User string `json:"user"` + } + + err := json.NewDecoder(req.Body).Decode(&deleteUserRequestData) + if err != nil { + logger.Println(req.URL.Path + "::" + err.Error()) + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + + ds, err := database.Open(dir + database.DB_MAIN) + if err != nil || ds == nil { + logger.Println(req.URL.Path + "::" + err.Error()) + http.Error(res, err.Error(), http.StatusInternalServerError) + return false + } + defer ds.Close() + + count, err := ds.Count(database.BUCKET_USERS) + if err != nil { + logger.Println(req.URL.Path + "::" + err.Error()) + http.Error(res, err.Error(), http.StatusInternalServerError) + return false + } + + if count <= 1 { + logger.Println(req.URL.Path + ":: if only one user exists it cannot be deleted") + http.Error(res, "If only one user exists it cannot be deleted", http.StatusBadRequest) + return false + } + + err = ds.Delete(database.BUCKET_USERS, []byte(deleteUserRequestData.User)) + if err != nil { + logger.Println(req.URL.Path + "::" + err.Error()) + http.Error(res, err.Error(), http.StatusInternalServerError) + return false + } + + res.WriteHeader(http.StatusNoContent) + return true +} diff --git a/pkg/database/database.go b/pkg/database/database.go index e37e271..d6fba85 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -122,3 +122,20 @@ func (ds *Datastore) Delete(bucket string, key []byte) error { return tx.Bucket([]byte(bucket)).Delete(key) }) } + +func (ds *Datastore) Count(bucket string) (int, error) { + count := 0 + + ds.handle.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte(bucket)) + c := b.Cursor() + + for k, _ := c.First(); k != nil; k, _ = c.Next() { + count++ + } + + return nil + }) + + return count, nil +} diff --git a/pkg/gpserver/apihandler.go b/pkg/gpserver/apihandler.go index f927457..8fbb074 100644 --- a/pkg/gpserver/apihandler.go +++ b/pkg/gpserver/apihandler.go @@ -74,6 +74,8 @@ func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request) (b return true, user.Logout(res, req, con.APILogger, con.Directory) case "/user/list": return true, user.List(res, req, con.APILogger, con.Directory) + case "/user/delete": + return true, user.Delete(res, req, con.APILogger, con.Directory) case "/bundle/create": return true, bundle.Create(res, req, con.APILogger, con.Bundles) case "/bundle/list": diff --git a/server/document_root/assets/js/panelHandlers/users/delete.js b/server/document_root/assets/js/panelHandlers/users/delete.js new file mode 100644 index 0000000..a764aac --- /dev/null +++ b/server/document_root/assets/js/panelHandlers/users/delete.js @@ -0,0 +1,32 @@ +jQuery(document).on('click', '._js_user-management-delete', function(e){ + e.preventDefault(); + + if(!jQuery(this).attr('data') || jQuery(this).attr('data') == "") { + alert("An error has occurred, please refresh and try again. If problem persists please contact your administrator."); + } + + var ensure = confirm('Are you sure you want to delete the user "' + jQuery(this).attr('data') + '"?'); + if(ensure) { + var requestData = {}; + requestData["user"] = jQuery(this).attr('data'); + + var xhr = new XMLHttpRequest(); + xhr.open('UPDATE', 'api/user/delete', true); + xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); + xhr.send(JSON.stringify(requestData)); + + xhr.onloadend = function() { + if(xhr.status == 204) { + listCurrentUsers(); + } + else { + if(xhr.response != undefined && xhr.response.length != 0) { + alert('Error: ' + xhr.response); + } + else { + alert("An error has occurred, please refresh and try again. If problem persists please contact your administrator."); + } + } + } + } +}); diff --git a/server/document_root/assets/js/panelHandlers/users/open.js b/server/document_root/assets/js/panelHandlers/users/open.js index 44d5f40..df75bc4 100644 --- a/server/document_root/assets/js/panelHandlers/users/open.js +++ b/server/document_root/assets/js/panelHandlers/users/open.js @@ -23,7 +23,7 @@ function listCurrentUsers() { if(xhr.response != undefined && xhr.response.length != 0) { jsonResponse = JSON.parse(xhr.response) jQuery.each(jsonResponse, function(k, v) { - display.append('
'+v+'
'+v+'