nameserver config and domain cleanup

This commit is contained in:
George Shaw 2017-12-11 14:50:38 -06:00
parent 4b2fed1f76
commit 03cabc0bc2
20 changed files with 445 additions and 28 deletions

View file

@ -4,9 +4,45 @@ jQuery('._js_domain-management').on('click', function(e){
e.preventDefault();
ListDomains(BUNDLE_NAME);
ListServerNameservers();
domainManagementModal.modal('show');
});
function ListServerNameservers() {
var display = jQuery('._js_server-nameservers');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'api/settings/get_nameservers', true);
xhr.send();
xhr.onloadend = function() {
display.html('');
if(xhr.status == 200) {
if(xhr.response != undefined && xhr.response.length != 0) {
jsonResponse = JSON.parse(xhr.response)
jQuery.each(jsonResponse, function(k, v) {
display.append('<div class="row mt-2"><div class="col-12 d-flex align-items-center"><p class="mb-0">'+v+'</p></div></div>');
});
}
else {
display.html('<p class="mt-2">An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
}
}
else if(xhr.status == 204) {
display.html('<p class="mt-2">There are no nameservers stored in the server.</p>');
}
else {
if(xhr.response != undefined && xhr.response.length != 0) {
alert('Error: ' + xhr.response);
}
else {
alert('An error has occurred, refresh and try again. If problem persists please contact your administrator.');
}
}
}
}
function ListDomains(bundle_name) {
var list = jQuery('._js_registered-domains');

View file

@ -208,9 +208,16 @@
</div>
</form>
<h4 class="mt-3 mb-0">Registered Domains</h4>
<small>Please allow up to 15 minutes for the server to track your domain.</small>
<div class="container-full _js_registered-domains">
</div>
<h4 class="mt-3 mb-0">Server Nameservers</h4>
<small>Point your domains to one of these nameservers.</small>
<div class="container-full _js_server-nameservers">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>

View file

@ -164,13 +164,36 @@ func Create(res http.ResponseWriter, req *http.Request, logger *log.Logger, bund
return false
}
msg := string("Your new gPanel Bundle has been successfully registered.\r\n\n" +
"Account Port: " + strconv.Itoa(createBundleRequestData.AccPort) + "\r\n" +
"Public Port: " + strconv.Itoa(createBundleRequestData.PubPort) + "\r\n\n" +
"Default account username: root\r\n" +
"Default account password: " + tempPass + "\r\n\n" +
"Any questions, comments, or concerns can be directed toward your server administrator " + adminSettings.Name +
" at " + adminSettings.Email)
nameservers, err := ds.ListNameservers()
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
var msg string
if len(nameservers) > 0 {
var nameserversString string
for _, v := range nameservers {
nameserversString += "- " + v + "\r\n"
}
msg = string("Your new gPanel Bundle has been successfully registered.\r\n\n" +
"Account Port: " + strconv.Itoa(createBundleRequestData.AccPort) + "\r\n" +
"Public Port: " + strconv.Itoa(createBundleRequestData.PubPort) + "\r\n\n" +
"Default account username: root\r\n" +
"Default account password: " + tempPass + "\r\n\n" +
"Any questions, comments, or concerns can be directed toward your server administrator " + adminSettings.Name +
" at " + adminSettings.Email + "\r\n\n" + "This server impliments the following nameservers:\r\n" + nameserversString)
} else {
msg = string("Your new gPanel Bundle has been successfully registered.\r\n\n" +
"Account Port: " + strconv.Itoa(createBundleRequestData.AccPort) + "\r\n" +
"Public Port: " + strconv.Itoa(createBundleRequestData.PubPort) + "\r\n\n" +
"Default account username: root\r\n" +
"Default account password: " + tempPass + "\r\n\n" +
"Any questions, comments, or concerns can be directed toward your server administrator " + adminSettings.Name +
" at " + adminSettings.Email)
}
err = mail.SendSimple(createBundleRequestData.Email, "New gPanel Bundle - "+createBundleRequestData.Name, msg)
if err != nil {

View file

@ -8,6 +8,7 @@ import (
"strconv"
"github.com/Ennovar/gPanel/pkg/gpaccount"
"github.com/Ennovar/gPanel/pkg/database"
)
func Delete(res http.ResponseWriter, req *http.Request, logger *log.Logger, bundles map[string]*gpaccount.Controller, dir string) bool {
@ -34,6 +35,21 @@ func Delete(res http.ResponseWriter, req *http.Request, logger *log.Logger, bund
return false
}
ds, err := database.Open("server/" + database.DB_DOMAINS)
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
defer ds.Close()
err = ds.RemoveInstances(rqData.Name)
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
_ = bundles[rqData.Name].Public.Stop(false)
_ = bundles[rqData.Name].Stop(false)

View file

@ -0,0 +1,44 @@
package settings
import (
"net/http"
"log"
"strconv"
"encoding/json"
"github.com/Ennovar/gPanel/pkg/database"
)
func AddNameserver(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "POST" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return false
}
var nameserverRequestData database.Struct_Nameserver
err := json.NewDecoder(req.Body).Decode(&nameserverRequestData)
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusBadRequest)
return false
}
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
defer ds.Close()
err = ds.Put(database.BUCKET_NAMESERVERS, []byte(nameserverRequestData.Nameserver), nameserverRequestData)
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
}

View file

@ -8,14 +8,14 @@ import (
"encoding/json"
)
func GetAdmin(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir string) bool {
func GetAdmin(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "GET" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return false
}
ds, err := database.Open(dir + database.DB_SETTINGS)
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)

View file

@ -0,0 +1,48 @@
package settings
import (
"net/http"
"log"
"strconv"
"github.com/Ennovar/gPanel/pkg/database"
"encoding/json"
)
func GetNameservers(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "GET" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return false
}
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
defer ds.Close()
nameservers, err := ds.ListNameservers()
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
if len(nameservers) > 0 {
b, err := json.Marshal(nameservers)
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
res.WriteHeader(http.StatusOK)
res.Write(b)
return true
}
res.WriteHeader(http.StatusNoContent)
return true
}

View file

@ -8,14 +8,14 @@ import (
"github.com/Ennovar/gPanel/pkg/database"
)
func GetSMTP(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir string) bool {
func GetSMTP(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "GET" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return false
}
ds, err := database.Open(dir + database.DB_SETTINGS)
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)

View file

@ -0,0 +1,44 @@
package settings
import (
"net/http"
"log"
"strconv"
"github.com/Ennovar/gPanel/pkg/database"
"encoding/json"
)
func RemoveNameserver(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "DELETE" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return false
}
var nameserverRequestData database.Struct_Nameserver
err := json.NewDecoder(req.Body).Decode(&nameserverRequestData)
if err != nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusBadRequest)
return false
}
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)
return false
}
defer ds.Close()
err = ds.Delete(database.BUCKET_NAMESERVERS, []byte(nameserverRequestData.Nameserver))
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
}

View file

@ -8,7 +8,7 @@ import (
"encoding/json"
)
func SetAdmin(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir string) bool {
func SetAdmin(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "POST" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
@ -24,7 +24,7 @@ func SetAdmin(res http.ResponseWriter, req *http.Request, logger *log.Logger, di
return false
}
ds, err := database.Open(dir + database.DB_SETTINGS)
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)

View file

@ -9,7 +9,7 @@ import (
"github.com/Ennovar/gPanel/pkg/database"
)
func SetSMTP(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir string) bool {
func SetSMTP(res http.ResponseWriter, req *http.Request, logger *log.Logger) bool {
if req.Method != "POST" && req.Method != "UPDATE" {
logger.Println(req.URL.Path + "::" + req.Method + "::" + strconv.Itoa(http.StatusMethodNotAllowed) + "::" + http.StatusText(http.StatusMethodNotAllowed))
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
@ -39,7 +39,7 @@ func SetSMTP(res http.ResponseWriter, req *http.Request, logger *log.Logger, dir
return false
}
ds, err := database.Open(dir + database.DB_SETTINGS)
ds, err := database.Open("server/" + database.DB_SETTINGS)
if err != nil || ds == nil {
logger.Println(req.URL.Path + "::" + err.Error())
http.Error(res, err.Error(), http.StatusInternalServerError)

View file

@ -26,6 +26,7 @@ const (
// DB_SETTINGS BUCKETS
BUCKET_GENERAL = "general"
BUCKET_NAMESERVERS = "nameservers"
// DB_DOMAINS BUCKETS
BUCKET_DOMAINS = "domains"
@ -77,6 +78,11 @@ func Open(filepath string) (*Datastore, error) {
if err != nil {
return err
}
_, err = tx.CreateBucketIfNotExists([]byte(BUCKET_NAMESERVERS))
if err != nil {
return err
}
}
if strings.HasSuffix(filepath, DB_DOMAINS) {

View file

@ -10,6 +10,10 @@ type Struct_Domain struct {
PublicPort int `json:"port"`
}
type Struct_Nameserver struct {
Nameserver string `json:"nameserver"`
}
func (ds *Datastore) ListDomains(bundle string) (map[string]Struct_Domain, error) {
filtered := make(map[string]Struct_Domain)
var holder Struct_Domain
@ -29,5 +33,49 @@ func (ds *Datastore) ListDomains(bundle string) (map[string]Struct_Domain, error
return nil
})
return filtered, nil
}
func (ds *Datastore) RemoveInstances(bundle string) error {
var holder Struct_Domain
ds.handle.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(BUCKET_DOMAINS))
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
json.Unmarshal(v, &holder)
if holder.BundleName == bundle {
err := ds.Delete(BUCKET_DOMAINS, k)
if err != nil {
return err
}
}
}
return nil
})
return nil
}
func (ds *Datastore) ListNameservers() ([]string, error) {
filtered := make([]string, 0)
var holder Struct_Nameserver
ds.handle.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(BUCKET_NAMESERVERS))
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
json.Unmarshal(v, &holder)
filtered = append(filtered, holder.Nameserver)
}
return nil
})
return filtered, nil
}

View file

@ -65,6 +65,8 @@ func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request) (b
return true, domain.Link(res, req, con.APILogger, con.Public.Port)
case "/domain/unlink":
return true, domain.Unlink(res, req, con.APILogger)
case "/settings/get_nameservers":
return true, settings.GetNameservers(res, req, con.APILogger)
default:
return false, false
}

View file

@ -90,13 +90,19 @@ func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request) (b
case "/log/delete":
return true, logapi.Truncate(res, req, con.APILogger, con.Directory)
case "/settings/set_smtp":
return true, settings.SetSMTP(res, req, con.APILogger, con.Directory)
return true, settings.SetSMTP(res, req, con.APILogger)
case "/settings/get_smtp":
return true, settings.GetSMTP(res, req, con.APILogger, con.Directory)
return true, settings.GetSMTP(res, req, con.APILogger)
case "/settings/set_admin":
return true, settings.SetAdmin(res, req, con.APILogger, con.Directory)
return true, settings.SetAdmin(res, req, con.APILogger)
case "/settings/get_admin":
return true, settings.GetAdmin(res, req, con.APILogger, con.Directory)
return true, settings.GetAdmin(res, req, con.APILogger)
case "/settings/add_nameserver":
return true, settings.AddNameserver(res, req, con.APILogger)
case "/settings/get_nameservers":
return true, settings.GetNameservers(res, req, con.APILogger)
case "/settings/remove_nameserver":
return true, settings.RemoveNameserver(res, req, con.APILogger)
default:
return false, false
}

View file

@ -0,0 +1,31 @@
jQuery('._js_add-nameserver-form').on('submit', function(e){
e.preventDefault();
var nameserver = jQuery(this).find('#addNameserver');
if(nameserver && nameserver.val()) {
var requestData = {};
requestData["nameserver"] = nameserver.val();
var xhr = new XMLHttpRequest();
xhr.open(jQuery(this).attr('method'), jQuery(this).attr('action'), true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(JSON.stringify(requestData));
xhr.onloadend = function() {
if (xhr.status == 204) {
ListNameservers();
}
else {
if(xhr.response != undefined && xhr.response.length != 0) {
alert('Error: ' + xhr.response);
}
else {
alert('An error has occurred, refresh and try again. If problem persists please contact your administrator.');
}
}
}
}
else {
alert('The nameserver field has to be filled out.');
}
});

View file

@ -0,0 +1,43 @@
var nameserverModal = jQuery('.nameserver-config-modal');
jQuery('._js_nameserver-config').on('click', function(e){
e.preventDefault();
ListNameservers();
nameserverModal.modal('show');
});
function ListNameservers(){
var display = jQuery('._js_current-nameservers');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'api/settings/get_nameservers', true);
xhr.send();
xhr.onloadend = function() {
display.html('');
if(xhr.status == 200) {
if(xhr.response != undefined && xhr.response.length != 0) {
jsonResponse = JSON.parse(xhr.response)
jQuery.each(jsonResponse, function(k, v) {
display.append('<div class="row mt-2"><div class="col-6 d-flex align-items-center"><p class="mb-0">'+v+'</p></div><div class="col-6 d-flex justify-content-end"><div class="btn-group" role="group"><button class="btn btn-outline-danger _js_remove-nameserver" data="'+v+'">Delete</button></div></div></div>');
});
}
else {
display.html('<p class="mt-2">An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
}
}
else if(xhr.status == 204) {
display.html('<p class="mt-2">There are no nameservers stored in the server.</p>');
}
else {
if(xhr.response != undefined && xhr.response.length != 0) {
alert('Error: ' + xhr.response);
}
else {
alert('An error has occurred, refresh and try again. If problem persists please contact your administrator.');
}
}
}
}

View file

@ -0,0 +1,30 @@
jQuery(document).on('click', '._js_remove-nameserver', function(e){
e.preventDefault();
var nameserver = jQuery(this).attr('data');
var requestData = {};
requestData["nameserver"] = nameserver;
var ensure = confirm("Are you sure you want to delete this nameserver?");
if(ensure) {
var xhr = new XMLHttpRequest();
xhr.open('DELETE', 'api/settings/remove_nameserver', true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(JSON.stringify(requestData));
xhr.onloadend = function () {
if (xhr.status == 204) {
ListNameservers();
}
else {
if (xhr.response != undefined && xhr.response.length != 0) {
alert('Error: ' + xhr.response);
}
else {
alert('An error has occurred, refresh and try again. If problem persists please contact your administrator.');
}
}
}
}
});

View file

@ -27,23 +27,18 @@ function listCurrentUsers() {
});
}
else {
display.html('<p>An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
display.html('<p class="mt-2">An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
}
}
else if(xhr.status == 204) {
if(xhr.response != undefined && xhr.response.length != 0) {
display.html('<p>There are no users in the server. This is a problem, this shouldn\'t be like this.</p>');
}
else {
display.html('<p>An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
}
display.html('<p class="mt-2">There are no users in the server. This is a problem, this shouldn\'t be like this.</p>');
}
else {
if(xhr.response != undefined && xhr.response.length != 0) {
display.html('<p>Error: ' + xhr.response + '</p>');
display.html('<p class="mt-2">Error: ' + xhr.response + '</p>');
}
else {
display.html('<p>An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
display.html('<p class="mt-2">An error has occurred, please refresh. If problem persists please contact your administrator.</p>');
}
}
}

View file

@ -365,6 +365,40 @@
</div>
</div>
<!-- Nameserver Configuration Modal -->
<div class="modal fade nameserver-config-modal" tabindex="-1" role="dialog" aria-labelledby="nameserver-config-modal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Nameserver Configuration</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="_js_add-nameserver-form" action="api/settings/add_nameserver" method="POST">
<div class="form-group">
<label for="addNameserver">Nameserver</label>
<input type="text" class="form-control" id="addNameserver" placeholder="Nameserver" value="">
<small class="form-text text-muted">This will be displayed to clients in order for them to point their domains toward the server.</small>
</div>
<div class="btn-group" role="group">
<button type="submit" class="btn btn-primary">Add Nameserver</button>
</div>
</form>
<h4 class="mt-3 mb-0">Current Nameservers</h4>
<div class="container-full _js_current-nameservers">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-12">
@ -418,6 +452,7 @@
<div class="btn-group" role="group">
<button type="button" class="btn btn-outline-primary _js_smtp-credentials">SMTP Credentials</button>
<button type="button" class="btn btn-outline-primary _js_admin-settings">Administrator Settings</button>
<button type="button" class="btn btn-outline-primary _js_nameserver-config">Nameserver Configuration</button>
</div>
</div>
</div>
@ -472,6 +507,9 @@
<script type="text/javascript" src="assets/js/panelHandlers/settings/smtp.js"></script>
<script type="text/javascript" src="assets/js/panelHandlers/settings/admin.js"></script>
<script type="text/javascript" src="assets/js/panelHandlers/settings/nameserver_config.js"></script>
<script type="text/javascript" src="assets/js/panelHandlers/settings/add_nameserver.js"></script>
<script type="text/javascript" src="assets/js/panelHandlers/settings/remove_nameserver.js"></script>
<!-- KEEP AT BOTTOM OF BODY TAGS -->
</body>
</html>