From 75b65b5e86e2500a22cd3c33eb86846288b5e319 Mon Sep 17 00:00:00 2001 From: George Shaw Date: Tue, 14 Nov 2017 17:38:35 -0600 Subject: [PATCH 1/7] starting to create server->account->public structure --- .../default_bundle/account}/README.md | 0 .../account}/assets/css/style.css | 0 .../account}/assets/js/formHandlers/login.js | 0 .../account}/assets/js/formHandlers/logout.js | 0 .../assets/js/formHandlers/register.js | 0 .../account}/assets/js/formHandlers/search.js | 0 .../assets/js/panelHandlers/logs/delete.js | 0 .../assets/js/panelHandlers/logs/view.js | 0 .../panelHandlers/publicServer/maintenance.js | 0 .../js/panelHandlers/publicServer/restart.js | 0 .../js/panelHandlers/publicServer/shutdown.js | 0 .../js/panelHandlers/publicServer/start.js | 0 .../js/panelHandlers/publicServer/status.js | 0 .../js/panelHandlers/security/ipFiltering.js | 0 .../default_bundle/account}/gPanel.html | 0 .../default_bundle/account}/index.html | 0 .../default_bundle}/public/test.html | 0 main.go | 13 +-- .../webhost.go => account/account.go} | 80 ++++++++++++-- pkg/account/authentication.go | 88 +++++++++++++++ pkg/api/user/auth.go | 2 +- pkg/api/user/get_secret.go | 4 +- pkg/api/user/logout.go | 2 +- pkg/database/database.go | 4 +- pkg/networking/session_store.go | 3 +- pkg/public/public.go | 12 +- pkg/{webhost => server}/authentication.go | 9 +- pkg/server/server.go | 62 +++++++++++ server/document_root/assets/css/style.css | 31 ++++++ .../assets/js/formHandlers/login.js | 31 ++++++ .../assets/js/formHandlers/logout.js | 20 ++++ .../assets/js/formHandlers/register.js | 27 +++++ .../assets/js/formHandlers/search.js | 4 + server/document_root/gPanel.html | 69 ++++++++++++ server/document_root/index.html | 104 ++++++++++++++++++ 35 files changed, 527 insertions(+), 38 deletions(-) rename {document_roots/webhost => bundles/default_bundle/account}/README.md (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/css/style.css (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/formHandlers/login.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/formHandlers/logout.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/formHandlers/register.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/formHandlers/search.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/logs/delete.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/logs/view.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/publicServer/maintenance.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/publicServer/restart.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/publicServer/shutdown.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/publicServer/start.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/publicServer/status.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/assets/js/panelHandlers/security/ipFiltering.js (100%) rename {document_roots/webhost => bundles/default_bundle/account}/gPanel.html (100%) rename {document_roots/webhost => bundles/default_bundle/account}/index.html (100%) rename {document_roots => bundles/default_bundle}/public/test.html (100%) rename pkg/{webhost/webhost.go => account/account.go} (52%) create mode 100644 pkg/account/authentication.go rename pkg/{webhost => server}/authentication.go (86%) create mode 100644 pkg/server/server.go create mode 100644 server/document_root/assets/css/style.css create mode 100644 server/document_root/assets/js/formHandlers/login.js create mode 100644 server/document_root/assets/js/formHandlers/logout.js create mode 100644 server/document_root/assets/js/formHandlers/register.js create mode 100644 server/document_root/assets/js/formHandlers/search.js create mode 100644 server/document_root/gPanel.html create mode 100644 server/document_root/index.html diff --git a/document_roots/webhost/README.md b/bundles/default_bundle/account/README.md similarity index 100% rename from document_roots/webhost/README.md rename to bundles/default_bundle/account/README.md diff --git a/document_roots/webhost/assets/css/style.css b/bundles/default_bundle/account/assets/css/style.css similarity index 100% rename from document_roots/webhost/assets/css/style.css rename to bundles/default_bundle/account/assets/css/style.css diff --git a/document_roots/webhost/assets/js/formHandlers/login.js b/bundles/default_bundle/account/assets/js/formHandlers/login.js similarity index 100% rename from document_roots/webhost/assets/js/formHandlers/login.js rename to bundles/default_bundle/account/assets/js/formHandlers/login.js diff --git a/document_roots/webhost/assets/js/formHandlers/logout.js b/bundles/default_bundle/account/assets/js/formHandlers/logout.js similarity index 100% rename from document_roots/webhost/assets/js/formHandlers/logout.js rename to bundles/default_bundle/account/assets/js/formHandlers/logout.js diff --git a/document_roots/webhost/assets/js/formHandlers/register.js b/bundles/default_bundle/account/assets/js/formHandlers/register.js similarity index 100% rename from document_roots/webhost/assets/js/formHandlers/register.js rename to bundles/default_bundle/account/assets/js/formHandlers/register.js diff --git a/document_roots/webhost/assets/js/formHandlers/search.js b/bundles/default_bundle/account/assets/js/formHandlers/search.js similarity index 100% rename from document_roots/webhost/assets/js/formHandlers/search.js rename to bundles/default_bundle/account/assets/js/formHandlers/search.js diff --git a/document_roots/webhost/assets/js/panelHandlers/logs/delete.js b/bundles/default_bundle/account/assets/js/panelHandlers/logs/delete.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/logs/delete.js rename to bundles/default_bundle/account/assets/js/panelHandlers/logs/delete.js diff --git a/document_roots/webhost/assets/js/panelHandlers/logs/view.js b/bundles/default_bundle/account/assets/js/panelHandlers/logs/view.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/logs/view.js rename to bundles/default_bundle/account/assets/js/panelHandlers/logs/view.js diff --git a/document_roots/webhost/assets/js/panelHandlers/publicServer/maintenance.js b/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/maintenance.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/publicServer/maintenance.js rename to bundles/default_bundle/account/assets/js/panelHandlers/publicServer/maintenance.js diff --git a/document_roots/webhost/assets/js/panelHandlers/publicServer/restart.js b/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/restart.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/publicServer/restart.js rename to bundles/default_bundle/account/assets/js/panelHandlers/publicServer/restart.js diff --git a/document_roots/webhost/assets/js/panelHandlers/publicServer/shutdown.js b/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/shutdown.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/publicServer/shutdown.js rename to bundles/default_bundle/account/assets/js/panelHandlers/publicServer/shutdown.js diff --git a/document_roots/webhost/assets/js/panelHandlers/publicServer/start.js b/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/start.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/publicServer/start.js rename to bundles/default_bundle/account/assets/js/panelHandlers/publicServer/start.js diff --git a/document_roots/webhost/assets/js/panelHandlers/publicServer/status.js b/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/status.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/publicServer/status.js rename to bundles/default_bundle/account/assets/js/panelHandlers/publicServer/status.js diff --git a/document_roots/webhost/assets/js/panelHandlers/security/ipFiltering.js b/bundles/default_bundle/account/assets/js/panelHandlers/security/ipFiltering.js similarity index 100% rename from document_roots/webhost/assets/js/panelHandlers/security/ipFiltering.js rename to bundles/default_bundle/account/assets/js/panelHandlers/security/ipFiltering.js diff --git a/document_roots/webhost/gPanel.html b/bundles/default_bundle/account/gPanel.html similarity index 100% rename from document_roots/webhost/gPanel.html rename to bundles/default_bundle/account/gPanel.html diff --git a/document_roots/webhost/index.html b/bundles/default_bundle/account/index.html similarity index 100% rename from document_roots/webhost/index.html rename to bundles/default_bundle/account/index.html diff --git a/document_roots/public/test.html b/bundles/default_bundle/public/test.html similarity index 100% rename from document_roots/public/test.html rename to bundles/default_bundle/public/test.html diff --git a/main.go b/main.go index f262ee4..b5b55cb 100644 --- a/main.go +++ b/main.go @@ -4,20 +4,15 @@ import ( "log" "net/http" - "github.com/Ennovar/gPanel/pkg/webhost" + "github.com/Ennovar/gPanel/pkg/server" "github.com/gorilla/context" ) func main() { - webhost := webhost.New() + gpServer := server.New() log.Printf("To Exit: CTRL+C") - go func() { - log.Print("Listening (public) on localhost:3000, serving out of the document_roots/public/ directory...") - _ = webhost.Public.Start() - }() - - log.Print("Listening (private) on localhost:2082, serving out of the document_roots/webhost/ directory...") - http.ListenAndServe("localhost:2082", context.ClearHandler(&webhost)) + log.Print("Listening (server) on localhost:2083, serving out of the server/document_root/ directory...") + http.ListenAndServe("localhost:2083", context.ClearHandler(gpServer)) } diff --git a/pkg/webhost/webhost.go b/pkg/account/account.go similarity index 52% rename from pkg/webhost/webhost.go rename to pkg/account/account.go index dfdbc30..6a7a16b 100644 --- a/pkg/webhost/webhost.go +++ b/pkg/account/account.go @@ -1,11 +1,15 @@ -// Package webhost handles the logic of the webhosting panel -package webhost +// Package account handles the logic of the gPanel account server +package account import ( + "context" + "errors" + "fmt" "io" "net/http" "os" "strconv" + "time" "github.com/Ennovar/gPanel/pkg/api" "github.com/Ennovar/gPanel/pkg/file" @@ -14,20 +18,72 @@ import ( ) type Controller struct { - Directory string - Public *public.Controller - ServerLogger *file.Handler + Directory string + DocumentRoot string + Port int + Public *public.Controller + GracefulShutdownTimeout time.Duration + Status int + ServerLogger *file.Handler } -// New returns a new PrivateHost type. -func New() Controller { +var controller Controller +var server http.Server + +// New returns a new Controller reference. +func New(root string) *Controller { serverErrorLogger, _ := file.Open(file.LOG_SERVER_ERRORS, true, true) - return Controller{ - Directory: "document_roots/webhost/", - Public: public.New(), - ServerLogger: serverErrorLogger, + controller = Controller{ + Directory: root, + DocumentRoot: "account/", + Port: 2082, + Public: public.New(root + "public/"), + GracefulShutdownTimeout: 5 * time.Second, + Status: 0, + ServerLogger: serverErrorLogger, } + + server = http.Server{ + Addr: "localhost:" + strconv.Itoa(controller.Port), + Handler: &controller, + ReadTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + MaxHeaderBytes: 0, + } + + return &controller +} + +func (con *Controller) Start() error { + if con.Status == 1 { + return errors.New("Account server is already on.") + } + + con.Status = 1 + go server.ListenAndServe() + return nil +} + +func (con *Controller) Stop(graceful bool) error { + if graceful { + context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) + defer cancel() + + err := server.Shutdown(context) + if err == nil { + return nil + } + + fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) + } + + if err := server.Close(); err != nil { + return err + } + + con.Status = 0 + return nil } // ServeHTTP function routes all requests for the private webhost server. It is used in the main @@ -41,7 +97,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { } if reqAuth(path) { - if !checkAuth(res, req) { + if !con.checkAuth(res, req) { con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusUnauthorized) + "::" + http.StatusText(http.StatusUnauthorized)) http.Error(res, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return diff --git a/pkg/account/authentication.go b/pkg/account/authentication.go new file mode 100644 index 0000000..6631470 --- /dev/null +++ b/pkg/account/authentication.go @@ -0,0 +1,88 @@ +// Package account handles the logic of the gPanel account server +package account + +import ( + "net/http" + "strings" + + "github.com/Ennovar/gPanel/pkg/api/user" + "github.com/Ennovar/gPanel/pkg/networking" + jwt "github.com/dgrijalva/jwt-go" +) + +// reqAuth function checks to see if the given path requires authentication. +func reqAuth(path string) bool { + path = strings.ToLower(path) + + dismissibleTypes := []string{".css", ".js"} + for _, t := range dismissibleTypes { + if strings.HasSuffix(path, t) { + return false + } + } + + dismissibleFiles := []string{ + "index.html", + "api/user/auth", + "api/user/register", + "api/user/logout", + } + for _, f := range dismissibleFiles { + if strings.HasSuffix(path, f) { + return false + } + } + + return true +} + +// checkAuth function returns a boolean based on whether or not the current +// caller is authenticated based off of encrypted sessions using JWT values. +func (con *Controller) checkAuth(res http.ResponseWriter, req *http.Request) bool { + store := networking.GetStore(networking.ACCOUNT_USER_AUTH) + + session_value, err := store.Read(res, req, "user") + if err != nil || session_value == nil { + return false + } + + username, ok := session_value.(string) + if !ok { + return false + } + + stored_secret, err := user.GetSecret(username, con.Directory) + if stored_secret == "" { + return false + } + + session_value, err = store.Read(res, req, "token") + if err != nil || session_value == nil { + return false + } + + tokenString, ok := session_value.(string) + if !ok { + return false + } + + keyfunc := func(t *jwt.Token) (interface{}, error) { + return []byte(stored_secret), nil + } + + p := jwt.Parser{ + ValidMethods: []string{"HS256", "HS384", "HS512"}, + } + t, err := p.ParseWithClaims(tokenString, &jwt.StandardClaims{}, keyfunc) + + if err != nil { + return false + } + + claims := t.Claims.(*jwt.StandardClaims) + if claims.Subject != username { + return false + } + + return true +} diff --git a/pkg/api/user/auth.go b/pkg/api/user/auth.go index cced68b..a83e3ed 100644 --- a/pkg/api/user/auth.go +++ b/pkg/api/user/auth.go @@ -80,7 +80,7 @@ func Auth(res http.ResponseWriter, req *http.Request) bool { return false } - store := networking.GetStore(networking.COOKIES_USER_AUTH) + store := networking.GetStore(networking.ACCOUNT_USER_AUTH) err = store.Set(res, req, "token", token, (60 * 60 * 24)) err2 := store.Set(res, req, "user", userRequestData.User, (60 * 60 * 24)) if err != nil || err2 != nil { diff --git a/pkg/api/user/get_secret.go b/pkg/api/user/get_secret.go index 6c8a0e9..f0d1e06 100644 --- a/pkg/api/user/get_secret.go +++ b/pkg/api/user/get_secret.go @@ -6,8 +6,8 @@ import "github.com/Ennovar/gPanel/pkg/database" // GetSecret is not accessible from the any client side request. It is // only used on the server side to help verify users are who they say they // are. -func GetSecret(user string) (string, error) { - ds, err := database.Open(database.DBLOC_MAIN) +func GetSecret(user string, directory string) (string, error) { + ds, err := database.Open(directory + database.DBLOC_MAIN) if err != nil { return "", err } diff --git a/pkg/api/user/logout.go b/pkg/api/user/logout.go index a6ec8f2..cfecb5c 100644 --- a/pkg/api/user/logout.go +++ b/pkg/api/user/logout.go @@ -16,7 +16,7 @@ func Logout(res http.ResponseWriter, req *http.Request) bool { return false } - store := networking.GetStore(networking.COOKIES_USER_AUTH) + store := networking.GetStore(networking.ACCOUNT_USER_AUTH) err := store.Delete(res, req) if err != nil { diff --git a/pkg/database/database.go b/pkg/database/database.go index 0a81b15..dfcf525 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -30,8 +30,8 @@ type Datastore struct { // Open function will open the database and return a Datastore struct // that has a handle within it for various datastore functions. -func Open(filename string) (*Datastore, error) { - db, err := bolt.Open(filename, 0666, &bolt.Options{Timeout: 15 * time.Second}) +func Open(filepath string) (*Datastore, error) { + db, err := bolt.Open(filepath, 0666, &bolt.Options{Timeout: 15 * time.Second}) if err != nil { return nil, err diff --git a/pkg/networking/session_store.go b/pkg/networking/session_store.go index 1e831d1..44d6647 100644 --- a/pkg/networking/session_store.go +++ b/pkg/networking/session_store.go @@ -11,7 +11,8 @@ import ( var key = []byte("GbP=K4#f$khYuZpStK68GyHxGg$4@5K-") const ( - COOKIES_USER_AUTH = "gpanel-webhost-user-auth" + ACCOUNT_USER_AUTH = "gpanel-account-user-auth" + SERVER_USER_AUTH = "gpanel-server-user-auth" ) type store struct { diff --git a/pkg/public/public.go b/pkg/public/public.go index 06450cd..304ebdf 100644 --- a/pkg/public/public.go +++ b/pkg/public/public.go @@ -16,7 +16,8 @@ import ( ) type Controller struct { - Directory string + DocumentRoot string + Port int GracefulShutdownTimeout time.Duration Status int ClientLogger *file.Handler @@ -28,13 +29,14 @@ var controller Controller var server http.Server // New function returns a new PublicWeb type. -func New() *Controller { +func New(root string) *Controller { clientLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) serverLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) loadLogHandler, _ := file.Open(file.LOG_LOADTIME, true, true) controller = Controller{ - Directory: "document_roots/public/", + DocumentRoot: root, + Port: 3000, GracefulShutdownTimeout: 5 * time.Second, Status: 0, ClientLogger: clientLogHandler, @@ -141,9 +143,9 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { path := req.URL.Path[1:] if len(path) == 0 { - path = (con.Directory + "index.html") + path = (con.DocumentRoot + "index.html") } else { - path = (con.Directory + path) + path = (con.DocumentRoot + path) } f, err := os.Open(path) diff --git a/pkg/webhost/authentication.go b/pkg/server/authentication.go similarity index 86% rename from pkg/webhost/authentication.go rename to pkg/server/authentication.go index f126339..8c31f9f 100644 --- a/pkg/webhost/authentication.go +++ b/pkg/server/authentication.go @@ -1,5 +1,4 @@ -// Package webhost handles the logic of the webhosting panel -package webhost +package server import ( "net/http" @@ -38,8 +37,8 @@ func reqAuth(path string) bool { // checkAuth function returns a boolean based on whether or not the current // caller is authenticated based off of encrypted sessions using JWT values. -func checkAuth(res http.ResponseWriter, req *http.Request) bool { - store := networking.GetStore(networking.COOKIES_USER_AUTH) +func (con *Controller) checkAuth(res http.ResponseWriter, req *http.Request) bool { + store := networking.GetStore(networking.SERVER_USER_AUTH) session_value, err := store.Read(res, req, "user") if err != nil || session_value == nil { @@ -51,7 +50,7 @@ func checkAuth(res http.ResponseWriter, req *http.Request) bool { return false } - stored_secret, err := user.GetSecret(username) + stored_secret, err := user.GetSecret(username, con.Directory) if stored_secret == "" { return false } diff --git a/pkg/server/server.go b/pkg/server/server.go new file mode 100644 index 0000000..f7f4260 --- /dev/null +++ b/pkg/server/server.go @@ -0,0 +1,62 @@ +package server + +import ( + "io" + "net/http" + "os" + + "github.com/Ennovar/gPanel/pkg/account" + "github.com/Ennovar/gPanel/pkg/routing" +) + +type Controller struct { + Directory string + DocumentRoot string + Bundles []account.Controller +} + +func New() *Controller { + return &Controller{ + Directory: "server/", + DocumentRoot: "document_root/", + Bundles: []account.Controller{}, + } +} + +func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { + path := req.URL.Path[1:] + if len(path) == 0 { + path = (con.Directory + con.DocumentRoot + "index.html") + } else { + path = (con.Directory + con.DocumentRoot + path) + } + + if reqAuth(path) { + if !con.checkAuth(res, req) { + http.Error(res, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + } + + f, err := os.Open(path) + + if err != nil { + routing.HttpThrowStatus(http.StatusNotFound, res) + return + } + + contentType, err := routing.GetContentType(path) + + if err != nil { + routing.HttpThrowStatus(http.StatusUnsupportedMediaType, res) + return + } + + res.Header().Add("Content-Type", contentType) + _, err = io.Copy(res, f) + + if err != nil { + routing.HttpThrowStatus(http.StatusInternalServerError, res) + return + } +} diff --git a/server/document_root/assets/css/style.css b/server/document_root/assets/css/style.css new file mode 100644 index 0000000..52547f1 --- /dev/null +++ b/server/document_root/assets/css/style.css @@ -0,0 +1,31 @@ +/* Sticky Footer Start */ +html { + position:relative; + min-height:100%; +} + +body { + margin-bottom:60px; +} + +.sticky-footer { + position:absolute; + bottom:0; + width:100%; + height:60px; + line-height:60px; + background-color:#E0EBF5; +} +/* Sticky Footer End */ + +/* Navbar Start */ +.navbar { + background-color:#E0EBF5 !important; +} +/* Navbar End */ + +/* General Start */ +.btn { + cursor:pointer; +} +/* General End */ diff --git a/server/document_root/assets/js/formHandlers/login.js b/server/document_root/assets/js/formHandlers/login.js new file mode 100644 index 0000000..3d12a41 --- /dev/null +++ b/server/document_root/assets/js/formHandlers/login.js @@ -0,0 +1,31 @@ +jQuery('#loginForm').on('submit', function(e){ + e.preventDefault(); + + var formData = {}; + for(var y = 0, yy = this.length; y < yy; y++) { + var input = this[y]; + if(input.name) { + formData[input.name] = input.value; + } + } + + 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(formData)); + + xhr.onloadend = function() { + if(xhr.status == 200 || xhr.status == 204) { + jQuery('.index-alert').html('Login Success: Redirecting in 2 seconds...'); + jQuery('.index-alert').removeClass('alert-danger').addClass('alert-success').removeClass('d-none'); + + setTimeout(function(){ + window.location.href = "/gPanel.html"; + }, 2000); + } + else { + jQuery('.index-alert').html("Login Error: " + xhr.response); + jQuery('.index-alert').removeClass('alert-success').addClass('alert-danger').removeClass('d-none'); + } + } +}); diff --git a/server/document_root/assets/js/formHandlers/logout.js b/server/document_root/assets/js/formHandlers/logout.js new file mode 100644 index 0000000..cf2e99a --- /dev/null +++ b/server/document_root/assets/js/formHandlers/logout.js @@ -0,0 +1,20 @@ +jQuery('#logoutForm').on('submit', function(e){ + e.preventDefault(); + + var check = confirm('Are you sure you want to logut?'); + + if(check) { + var xhr = new XMLHttpRequest(); + xhr.open(jQuery(this).attr('method'), jQuery(this).attr('action'), true); + xhr.send(); + + xhr.onloadend = function() { + if(xhr.status == 200 || xhr.status == 204) { + window.location.href = '/'; + } + else { + alert('An error has occurred. Please contact your server\'s administrator.'); + } + } + } +}); diff --git a/server/document_root/assets/js/formHandlers/register.js b/server/document_root/assets/js/formHandlers/register.js new file mode 100644 index 0000000..074a719 --- /dev/null +++ b/server/document_root/assets/js/formHandlers/register.js @@ -0,0 +1,27 @@ +jQuery('#registerForm').on('submit', function(e){ + e.preventDefault(); + + var formData = {}; + for(var y = 0, yy = this.length; y < yy; y++) { + var input = this[y]; + if(input.name) { + formData[input.name] = input.value; + } + } + + 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(formData)); + + xhr.onloadend = function() { + if(xhr.status == 200 || xhr.status == 204) { + jQuery('.index-alert').html('Register Success: You may now login.'); + jQuery('.index-alert').removeClass('alert-danger').addClass('alert-success').removeClass('d-none'); + } + else { + jQuery('.index-alert').html("Register Error: " + xhr.response); + jQuery('.index-alert').removeClass('alert-success').addClass('alert-danger').removeClass('d-none'); + } + } +}); diff --git a/server/document_root/assets/js/formHandlers/search.js b/server/document_root/assets/js/formHandlers/search.js new file mode 100644 index 0000000..e659a8a --- /dev/null +++ b/server/document_root/assets/js/formHandlers/search.js @@ -0,0 +1,4 @@ +jQuery('#searchForm').on('submit', function(e){ + e.preventDefault(); + alert('Search functionality coming soon.'); +}); diff --git a/server/document_root/gPanel.html b/server/document_root/gPanel.html new file mode 100644 index 0000000..4df6c16 --- /dev/null +++ b/server/document_root/gPanel.html @@ -0,0 +1,69 @@ + + + + gPanel Server + + + + + + + + + + + +
+
+
+
+
+

Test

+
Test
+ +
+ +
+
+
+
+ + + + + + + + + + + + + diff --git a/server/document_root/index.html b/server/document_root/index.html new file mode 100644 index 0000000..4f9f450 --- /dev/null +++ b/server/document_root/index.html @@ -0,0 +1,104 @@ + + + + gPanel Server + + + + + + + + + + + +
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ Register is Temporary, for development purposes only. +
+ +
+
+ + + + + + + + + + + + + + From 92c180e57da98be4c23506c8d7b72553ee941f60 Mon Sep 17 00:00:00 2001 From: George Shaw Date: Wed, 15 Nov 2017 12:10:21 -0600 Subject: [PATCH 2/7] started to fix APIs since adding gpserver --- main.go | 6 +-- pkg/api/api_handler.go | 50 ------------------ pkg/api/user/auth.go | 13 +++-- pkg/api/user/get_secret.go | 2 +- pkg/api/user/logout.go | 11 +++- pkg/api/user/register.go | 4 +- pkg/database/database.go | 2 +- pkg/gpaccount/apihandler.go | 48 +++++++++++++++++ pkg/{account => gpaccount}/authentication.go | 4 +- .../account.go => gpaccount/gpaccount.go} | 45 ++-------------- pkg/gpaccount/toggle.go | 39 ++++++++++++++ pkg/gpserver/apihandler.go | 48 +++++++++++++++++ pkg/{server => gpserver}/authentication.go | 3 +- .../server.go => gpserver/gpserver.go} | 16 ++++-- pkg/networking/session_store.go | 12 ++--- server/users.db | Bin 0 -> 32768 bytes 16 files changed, 188 insertions(+), 115 deletions(-) delete mode 100644 pkg/api/api_handler.go create mode 100644 pkg/gpaccount/apihandler.go rename pkg/{account => gpaccount}/authentication.go (95%) rename pkg/{account/account.go => gpaccount/gpaccount.go} (75%) create mode 100644 pkg/gpaccount/toggle.go create mode 100644 pkg/gpserver/apihandler.go rename pkg/{server => gpserver}/authentication.go (95%) rename pkg/{server/server.go => gpserver/gpserver.go} (77%) create mode 100644 server/users.db diff --git a/main.go b/main.go index b5b55cb..fe750b7 100644 --- a/main.go +++ b/main.go @@ -4,15 +4,15 @@ import ( "log" "net/http" - "github.com/Ennovar/gPanel/pkg/server" + "github.com/Ennovar/gPanel/pkg/gpserver" "github.com/gorilla/context" ) func main() { - gpServer := server.New() + mains := gpserver.New() log.Printf("To Exit: CTRL+C") log.Print("Listening (server) on localhost:2083, serving out of the server/document_root/ directory...") - http.ListenAndServe("localhost:2083", context.ClearHandler(gpServer)) + http.ListenAndServe("localhost:2083", context.ClearHandler(mains)) } diff --git a/pkg/api/api_handler.go b/pkg/api/api_handler.go deleted file mode 100644 index 87f814f..0000000 --- a/pkg/api/api_handler.go +++ /dev/null @@ -1,50 +0,0 @@ -// Package api handles all API calls -package api - -import ( - "net/http" - "strings" - - "github.com/Ennovar/gPanel/pkg/api/log" - "github.com/Ennovar/gPanel/pkg/api/server" - "github.com/Ennovar/gPanel/pkg/api/user" - "github.com/Ennovar/gPanel/pkg/public" -) - -// HandleAPI function takes a path and determines if it is an API call, if it is it will -// call the specified API. It returns two booleans, the first being if it is an API call and -// the second is the response of the API call's function. -// -// The path of an API is formatted as such: document_roots/webhost/api/some/thing. The path is split -// by the sequence of characters "api", returning the first half of the URL which is discarded, and the -// second half which will look like /some/thing. The second half is processed to see whether or not it is -// a valid API, and then handled accordingly from there. -func HandleAPI(res http.ResponseWriter, req *http.Request, path string, publicServer *public.Controller) (bool, bool) { - splitUrl := strings.SplitN(path, "api", 2) - suspectApi := strings.ToLower(splitUrl[len(splitUrl)-1]) - - switch suspectApi { - case "/user/auth": - return true, user.Auth(res, req) - case "/user/register": - return true, user.Register(res, req) - case "/user/logout": - return true, user.Logout(res, req) - case "/server/status": - return true, server.Status(res, req, publicServer) - case "/server/start": - return true, server.Start(res, req, publicServer) - case "/server/shutdown": - return true, server.Shutdown(res, req, publicServer) - case "/server/restart": - return true, server.Restart(res, req, publicServer) - case "/server/maintenance": - return true, server.Maintenance(res, req, publicServer) - case "/log/read": - return true, log.Read(res, req) - case "/log/delete": - return true, log.Delete(res, req) - default: - return false, false - } -} diff --git a/pkg/api/user/auth.go b/pkg/api/user/auth.go index a83e3ed..69a0afb 100644 --- a/pkg/api/user/auth.go +++ b/pkg/api/user/auth.go @@ -4,6 +4,7 @@ package user import ( "encoding/json" "net/http" + "strings" "time" "github.com/Ennovar/gPanel/pkg/database" @@ -15,7 +16,7 @@ import ( // Auth function is accessed by an API call from the webhost root // by accessing /user_auth and sending it a post request with userRequestData // struct in JSON format. -func Auth(res http.ResponseWriter, req *http.Request) bool { +func Auth(res http.ResponseWriter, req *http.Request, dir string) bool { if req.Method != "POST" { http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed) return false @@ -32,7 +33,7 @@ func Auth(res http.ResponseWriter, req *http.Request) bool { return false } - ds, err := database.Open(database.DBLOC_MAIN) + ds, err := database.Open(dir + database.DB_USERS) if err != nil || ds == nil { http.Error(res, err.Error(), http.StatusInternalServerError) return false @@ -80,7 +81,13 @@ func Auth(res http.ResponseWriter, req *http.Request) bool { return false } - store := networking.GetStore(networking.ACCOUNT_USER_AUTH) + var store networking.Store + if strings.Contains(dir, "bundles/") { + store = networking.GetStore(networking.ACCOUNT_USER_AUTH) + } else { + store = networking.GetStore(networking.SERVER_USER_AUTH) + } + err = store.Set(res, req, "token", token, (60 * 60 * 24)) err2 := store.Set(res, req, "user", userRequestData.User, (60 * 60 * 24)) if err != nil || err2 != nil { diff --git a/pkg/api/user/get_secret.go b/pkg/api/user/get_secret.go index f0d1e06..8cc7470 100644 --- a/pkg/api/user/get_secret.go +++ b/pkg/api/user/get_secret.go @@ -7,7 +7,7 @@ import "github.com/Ennovar/gPanel/pkg/database" // only used on the server side to help verify users are who they say they // are. func GetSecret(user string, directory string) (string, error) { - ds, err := database.Open(directory + database.DBLOC_MAIN) + ds, err := database.Open(directory + database.DB_USERS) if err != nil { return "", err } diff --git a/pkg/api/user/logout.go b/pkg/api/user/logout.go index cfecb5c..19f94b4 100644 --- a/pkg/api/user/logout.go +++ b/pkg/api/user/logout.go @@ -3,6 +3,7 @@ package user import ( "net/http" + "strings" "github.com/Ennovar/gPanel/pkg/networking" ) @@ -10,13 +11,19 @@ import ( // Logout function is accessed by an API call from the webhost root // by accessing /user_logout and sending it an empty POST request. This function will // delete the user-auth cookie session store -func Logout(res http.ResponseWriter, req *http.Request) bool { +func Logout(res http.ResponseWriter, req *http.Request, dir string) bool { if req.Method != "POST" { http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed) return false } - store := networking.GetStore(networking.ACCOUNT_USER_AUTH) + var store networking.Store + if strings.Contains(dir, "bundles/") { + store = networking.GetStore(networking.ACCOUNT_USER_AUTH) + } else { + store = networking.GetStore(networking.SERVER_USER_AUTH) + } + err := store.Delete(res, req) if err != nil { diff --git a/pkg/api/user/register.go b/pkg/api/user/register.go index cd6fb8d..c8b303f 100644 --- a/pkg/api/user/register.go +++ b/pkg/api/user/register.go @@ -12,7 +12,7 @@ import ( // Register function is accessed by an API call from the webhost root // by accessing /user_register and sending it a post request with userRequestData // struct in JSON format. -func Register(res http.ResponseWriter, req *http.Request) bool { +func Register(res http.ResponseWriter, req *http.Request, dir string) bool { if req.Method != "POST" { http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed) return false @@ -32,7 +32,7 @@ func Register(res http.ResponseWriter, req *http.Request) bool { return false } - ds, err := database.Open(database.DBLOC_MAIN) + ds, err := database.Open(dir + database.DB_USERS) if err != nil || ds == nil { http.Error(res, err.Error(), http.StatusInternalServerError) return false diff --git a/pkg/database/database.go b/pkg/database/database.go index dfcf525..9ab111f 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -11,7 +11,7 @@ import ( // Database constants const ( - DBLOC_MAIN = "datastore.db" + DB_USERS = "users.db" ) // Bucket constants diff --git a/pkg/gpaccount/apihandler.go b/pkg/gpaccount/apihandler.go new file mode 100644 index 0000000..bc0c346 --- /dev/null +++ b/pkg/gpaccount/apihandler.go @@ -0,0 +1,48 @@ +// Package gpaccount handles the logic of the gPanel account server +package gpaccount + +import ( + "net/http" + "strings" + + "github.com/Ennovar/gPanel/pkg/api/log" + "github.com/Ennovar/gPanel/pkg/api/server" + "github.com/Ennovar/gPanel/pkg/api/user" +) + +func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request) (bool, bool) { + path := req.URL.Path[1:] + if len(path) == 0 { + path = (con.Directory + "index.html") + } else { + path = (con.Directory + path) + } + + splitUrl := strings.SplitN(path, "api", 2) + suspectApi := strings.ToLower(splitUrl[len(splitUrl)-1]) + + switch suspectApi { + case "/user/auth": + return true, user.Auth(res, req, con.Directory) + case "/user/register": + return true, user.Register(res, req, con.Directory) + case "/user/logout": + return true, user.Logout(res, req, con.Directory) + case "/server/status": + return true, server.Status(res, req, con.Public) + case "/server/start": + return true, server.Start(res, req, con.Public) + case "/server/shutdown": + return true, server.Shutdown(res, req, con.Public) + case "/server/restart": + return true, server.Restart(res, req, con.Public) + case "/server/maintenance": + return true, server.Maintenance(res, req, con.Public) + case "/log/read": + return true, log.Read(res, req) + case "/log/delete": + return true, log.Delete(res, req) + default: + return false, false + } +} diff --git a/pkg/account/authentication.go b/pkg/gpaccount/authentication.go similarity index 95% rename from pkg/account/authentication.go rename to pkg/gpaccount/authentication.go index 6631470..f78e930 100644 --- a/pkg/account/authentication.go +++ b/pkg/gpaccount/authentication.go @@ -1,5 +1,5 @@ -// Package account handles the logic of the gPanel account server -package account +// Package gpaccount handles the logic of the gPanel account server +package gpaccount import ( "net/http" diff --git a/pkg/account/account.go b/pkg/gpaccount/gpaccount.go similarity index 75% rename from pkg/account/account.go rename to pkg/gpaccount/gpaccount.go index 6a7a16b..8ea1bd7 100644 --- a/pkg/account/account.go +++ b/pkg/gpaccount/gpaccount.go @@ -1,17 +1,13 @@ -// Package account handles the logic of the gPanel account server -package account +// Package gpaccount handles the logic of the gPanel account server +package gpaccount import ( - "context" - "errors" - "fmt" "io" "net/http" "os" "strconv" "time" - "github.com/Ennovar/gPanel/pkg/api" "github.com/Ennovar/gPanel/pkg/file" "github.com/Ennovar/gPanel/pkg/public" "github.com/Ennovar/gPanel/pkg/routing" @@ -28,7 +24,7 @@ type Controller struct { } var controller Controller -var server http.Server +var httpserver http.Server // New returns a new Controller reference. func New(root string) *Controller { @@ -44,7 +40,7 @@ func New(root string) *Controller { ServerLogger: serverErrorLogger, } - server = http.Server{ + httpserver = http.Server{ Addr: "localhost:" + strconv.Itoa(controller.Port), Handler: &controller, ReadTimeout: 30 * time.Second, @@ -55,37 +51,6 @@ func New(root string) *Controller { return &controller } -func (con *Controller) Start() error { - if con.Status == 1 { - return errors.New("Account server is already on.") - } - - con.Status = 1 - go server.ListenAndServe() - return nil -} - -func (con *Controller) Stop(graceful bool) error { - if graceful { - context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) - defer cancel() - - err := server.Shutdown(context) - if err == nil { - return nil - } - - fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) - } - - if err := server.Close(); err != nil { - return err - } - - con.Status = 0 - return nil -} - // ServeHTTP function routes all requests for the private webhost server. It is used in the main // function inside of the http.ListenAndServe() function for the private webhost host. func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { @@ -104,7 +69,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { } } - isApi, _ := api.HandleAPI(res, req, path, con.Public) + isApi, _ := con.apiHandler(res, req) if isApi { // API methods handle HTTP logic from here diff --git a/pkg/gpaccount/toggle.go b/pkg/gpaccount/toggle.go new file mode 100644 index 0000000..b96b274 --- /dev/null +++ b/pkg/gpaccount/toggle.go @@ -0,0 +1,39 @@ +// Package gpaccount handles the logic of the gPanel account server +package gpaccount + +import ( + "context" + "errors" + "fmt" +) + +func (con *Controller) Start() error { + if con.Status == 1 { + return errors.New("Account server is already on.") + } + + con.Status = 1 + go httpserver.ListenAndServe() + return nil +} + +func (con *Controller) Stop(graceful bool) error { + if graceful { + context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) + defer cancel() + + err := httpserver.Shutdown(context) + if err == nil { + return nil + } + + fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) + } + + if err := httpserver.Close(); err != nil { + return err + } + + con.Status = 0 + return nil +} diff --git a/pkg/gpserver/apihandler.go b/pkg/gpserver/apihandler.go new file mode 100644 index 0000000..1a10bef --- /dev/null +++ b/pkg/gpserver/apihandler.go @@ -0,0 +1,48 @@ +// Package gpserver handles the logic of the gPanel server +package gpserver + +import ( + "net/http" + "strings" + + "github.com/Ennovar/gPanel/pkg/api/log" + "github.com/Ennovar/gPanel/pkg/api/server" + "github.com/Ennovar/gPanel/pkg/api/user" +) + +func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request, curBundle int) (bool, bool) { + path := req.URL.Path[1:] + if len(path) == 0 { + path = (con.Directory + "index.html") + } else { + path = (con.Directory + path) + } + + splitUrl := strings.SplitN(path, "api", 2) + suspectApi := strings.ToLower(splitUrl[len(splitUrl)-1]) + + switch suspectApi { + case "/user/auth": + return true, user.Auth(res, req, con.Directory) + case "/user/register": + return true, user.Register(res, req, con.Directory) + case "/user/logout": + return true, user.Logout(res, req, con.Directory) + case "/server/status": + return true, server.Status(res, req, con.Bundles[curBundle].Public) + case "/server/start": + return true, server.Start(res, req, con.Bundles[curBundle].Public) + case "/server/shutdown": + return true, server.Shutdown(res, req, con.Bundles[curBundle].Public) + case "/server/restart": + return true, server.Restart(res, req, con.Bundles[curBundle].Public) + case "/server/maintenance": + return true, server.Maintenance(res, req, con.Bundles[curBundle].Public) + case "/log/read": + return true, log.Read(res, req) + case "/log/delete": + return true, log.Delete(res, req) + default: + return false, false + } +} diff --git a/pkg/server/authentication.go b/pkg/gpserver/authentication.go similarity index 95% rename from pkg/server/authentication.go rename to pkg/gpserver/authentication.go index 8c31f9f..46e457d 100644 --- a/pkg/server/authentication.go +++ b/pkg/gpserver/authentication.go @@ -1,4 +1,5 @@ -package server +// Package gpserver handles the logic of the gPanel server +package gpserver import ( "net/http" diff --git a/pkg/server/server.go b/pkg/gpserver/gpserver.go similarity index 77% rename from pkg/server/server.go rename to pkg/gpserver/gpserver.go index f7f4260..37ad4eb 100644 --- a/pkg/server/server.go +++ b/pkg/gpserver/gpserver.go @@ -1,25 +1,26 @@ -package server +// Package gpserver handles the logic of the gPanel server +package gpserver import ( "io" "net/http" "os" - "github.com/Ennovar/gPanel/pkg/account" + "github.com/Ennovar/gPanel/pkg/gpaccount" "github.com/Ennovar/gPanel/pkg/routing" ) type Controller struct { Directory string DocumentRoot string - Bundles []account.Controller + Bundles []gpaccount.Controller } func New() *Controller { return &Controller{ Directory: "server/", DocumentRoot: "document_root/", - Bundles: []account.Controller{}, + Bundles: []gpaccount.Controller{}, } } @@ -38,6 +39,13 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { } } + isApi, _ := con.apiHandler(res, req, 0) + + if isApi { + // API methods handle HTTP logic from here + return + } + f, err := os.Open(path) if err != nil { diff --git a/pkg/networking/session_store.go b/pkg/networking/session_store.go index 44d6647..e023085 100644 --- a/pkg/networking/session_store.go +++ b/pkg/networking/session_store.go @@ -15,14 +15,14 @@ const ( SERVER_USER_AUTH = "gpanel-server-user-auth" ) -type store struct { +type Store struct { handle *sessions.CookieStore cookieName string } // GetStore function takes a name and either creates/grabs a store with that name. -func GetStore(name string) store { - sessionStore := store{ +func GetStore(name string) Store { + sessionStore := Store{ handle: sessions.NewCookieStore(key), cookieName: name, } @@ -31,7 +31,7 @@ func GetStore(name string) store { } // Set function is attached to the store struct and will set a session value inside of the current store. -func (s *store) Set(res http.ResponseWriter, req *http.Request, key string, value interface{}, expire int) error { +func (s *Store) Set(res http.ResponseWriter, req *http.Request, key string, value interface{}, expire int) error { session, err := s.handle.Get(req, s.cookieName) if err != nil { @@ -49,7 +49,7 @@ func (s *store) Set(res http.ResponseWriter, req *http.Request, key string, valu } // Read function is attached to the store struct and will read a given session value inside of the current store. -func (s *store) Read(res http.ResponseWriter, req *http.Request, key string) (interface{}, error) { +func (s *Store) Read(res http.ResponseWriter, req *http.Request, key string) (interface{}, error) { session, err := s.handle.Get(req, s.cookieName) if err != nil { @@ -61,7 +61,7 @@ func (s *store) Read(res http.ResponseWriter, req *http.Request, key string) (in } // Delete function is attached to the store struct and will delete a given session value inside of the current store. -func (s *store) Delete(res http.ResponseWriter, req *http.Request) error { +func (s *Store) Delete(res http.ResponseWriter, req *http.Request) error { session, err := s.handle.Get(req, s.cookieName) if err != nil { diff --git a/server/users.db b/server/users.db new file mode 100644 index 0000000000000000000000000000000000000000..bd899a402940b4e1d23ef2a1db3d12782a572eb1 GIT binary patch literal 32768 zcmeI(%TCl#7y#e_!34vC9s6b$A{xeW2^bdyaf=WU5;p`$hj2^B=^(eb@F{!|p2l~; zM=-Wb|DB6jGUPi+`?sg3?diAs&pB;0`em$+_rE9aN2}whe#Nu8KElJb^5l745%JZ^ z&lmaK-fXlJ2@oJafB*pk1PBlyK!5;&$0IOOcV*E0f4puVd4HV$nV5bv_kR8FFKH7-{2oNAZfB*pk1PBlyK!CvT3dH*U z(MEqIK(()y{#W_`uX4L6vTjkv|CYF^x>(&*4IUhpTQ|>pw@GKeD3W(cGu>~#Z8blB z-CexiNjsNISNYlY^}?s~(~ZmQ`{(1 Date: Wed, 15 Nov 2017 13:17:15 -0600 Subject: [PATCH 3/7] fixing gitignore --- .gitignore | 17 ++++++++++------- .../default_bundle/logs}/README.md | 0 server/users.db | Bin 32768 -> 0 bytes 3 files changed, 10 insertions(+), 7 deletions(-) rename {logs => bundles/default_bundle/logs}/README.md (100%) delete mode 100644 server/users.db diff --git a/.gitignore b/.gitignore index c5dab9c..83f9dd1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ -# Ignore executables generated +# IGNORE GENERATED BINARIES main gpanel -# Ignore database files -datastore.db -datastore.db.lock +# IGNORE ALL BUNDLES EXCEPT FOR DEFAULT_BUNDLE +bundles/* +!bundles/default_bundle -# Ignore log files -logs/* -!logs/README.md +# IGNORE ALL FILES IN /LOG EXCEPT README +**/logs/* +!**/logs/README.md + +# IGNORE .DB FILES +**.db diff --git a/logs/README.md b/bundles/default_bundle/logs/README.md similarity index 100% rename from logs/README.md rename to bundles/default_bundle/logs/README.md diff --git a/server/users.db b/server/users.db deleted file mode 100644 index bd899a402940b4e1d23ef2a1db3d12782a572eb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI(%TCl#7y#e_!34vC9s6b$A{xeW2^bdyaf=WU5;p`$hj2^B=^(eb@F{!|p2l~; zM=-Wb|DB6jGUPi+`?sg3?diAs&pB;0`em$+_rE9aN2}whe#Nu8KElJb^5l745%JZ^ z&lmaK-fXlJ2@oJafB*pk1PBlyK!5;&$0IOOcV*E0f4puVd4HV$nV5bv_kR8FFKH7-{2oNAZfB*pk1PBlyK!CvT3dH*U z(MEqIK(()y{#W_`uX4L6vTjkv|CYF^x>(&*4IUhpTQ|>pw@GKeD3W(cGu>~#Z8blB z-CexiNjsNISNYlY^}?s~(~ZmQ`{(1 Date: Wed, 15 Nov 2017 15:06:25 -0600 Subject: [PATCH 4/7] started development on creating new bundles --- .../js/panelHandlers/{logs => log}/delete.js | 0 .../js/panelHandlers/{logs => log}/view.js | 0 bundles/default_bundle/logs/README.md | 1 + main.go | 4 +- pkg/api/bundle/create.go | 70 +++++++++++++++++ pkg/gpaccount/gpaccount.go | 8 +- pkg/gpserver/apihandler.go | 19 +---- pkg/gpserver/gpserver.go | 4 +- pkg/public/public.go | 78 +------------------ pkg/public/restart.go | 41 ++++++++++ pkg/public/toggle.go | 41 ++++++++++ .../assets/js/panelHandlers/bundles/create.js | 48 ++++++++++++ server/document_root/gPanel.html | 51 ++++++++++-- server/logs/README.md | 9 +++ 14 files changed, 269 insertions(+), 105 deletions(-) rename bundles/default_bundle/account/assets/js/panelHandlers/{logs => log}/delete.js (100%) rename bundles/default_bundle/account/assets/js/panelHandlers/{logs => log}/view.js (100%) create mode 100644 pkg/api/bundle/create.go create mode 100644 pkg/public/restart.go create mode 100644 pkg/public/toggle.go create mode 100644 server/document_root/assets/js/panelHandlers/bundles/create.js create mode 100644 server/logs/README.md diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/logs/delete.js b/bundles/default_bundle/account/assets/js/panelHandlers/log/delete.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/logs/delete.js rename to bundles/default_bundle/account/assets/js/panelHandlers/log/delete.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/logs/view.js b/bundles/default_bundle/account/assets/js/panelHandlers/log/view.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/logs/view.js rename to bundles/default_bundle/account/assets/js/panelHandlers/log/view.js diff --git a/bundles/default_bundle/logs/README.md b/bundles/default_bundle/logs/README.md index bc23fc2..9ee4345 100644 --- a/bundles/default_bundle/logs/README.md +++ b/bundles/default_bundle/logs/README.md @@ -4,5 +4,6 @@ The actual log files are ignored by the .gitignore file. They are generated auto Current log files: - client_errors.log +- account_errors.log - server_errors.log - loadtime.log diff --git a/main.go b/main.go index fe750b7..00a1ba8 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,6 @@ func main() { log.Printf("To Exit: CTRL+C") - log.Print("Listening (server) on localhost:2083, serving out of the server/document_root/ directory...") - http.ListenAndServe("localhost:2083", context.ClearHandler(mains)) + log.Print("Listening (server) on localhost:2082, serving out of the server/document_root/ directory...") + http.ListenAndServe("localhost:2082", context.ClearHandler(mains)) } diff --git a/pkg/api/bundle/create.go b/pkg/api/bundle/create.go new file mode 100644 index 0000000..636a387 --- /dev/null +++ b/pkg/api/bundle/create.go @@ -0,0 +1,70 @@ +package bundle + +import ( + "encoding/json" + "errors" + "net" + "net/http" + "strconv" + + "github.com/Ennovar/gPanel/pkg/gpaccount" +) + +func Create(res http.ResponseWriter, req *http.Request, bundles map[string]*gpaccount.Controller) bool { + if req.Method != "POST" { + http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + return false + } + + var createBundleRequestData struct { + Name string `json:"name"` + AccPort int `json:"account_port"` + PubPort int `json:"public_port"` + } + + err := json.NewDecoder(req.Body).Decode(&createBundleRequestData) + if err != nil { + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + + check, err := net.Listen("tcp", ":"+strconv.Itoa(createBundleRequestData.AccPort)) + if err != nil { + http.Error(res, "A service is already listening on port "+strconv.Itoa(createBundleRequestData.AccPort), http.StatusInternalServerError) + return false + } + check.Close() + + check, err = net.Listen("tcp", ":"+strconv.Itoa(createBundleRequestData.PubPort)) + if err != nil { + http.Error(res, "A service is already listening on port "+strconv.Itoa(createBundleRequestData.PubPort), http.StatusInternalServerError) + return false + } + check.Close() + + err = nil + for k, v := range bundles { + if k == createBundleRequestData.Name { + err = errors.New("Bundle \"" + k + "\" already exists") + break + } + + if v.Port == createBundleRequestData.AccPort || + v.Port == createBundleRequestData.PubPort || + v.Public.Port == createBundleRequestData.AccPort || + v.Public.Port == createBundleRequestData.PubPort { + err = errors.New("An existing bundle is using the port \"" + strconv.Itoa(v.Port) + "\" already") + break + } + } + + if err != nil { + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + + res.WriteHeader(http.StatusOK) + res.Write([]byte(createBundleRequestData.Name)) + + return true +} diff --git a/pkg/gpaccount/gpaccount.go b/pkg/gpaccount/gpaccount.go index 8ea1bd7..982bf79 100644 --- a/pkg/gpaccount/gpaccount.go +++ b/pkg/gpaccount/gpaccount.go @@ -27,14 +27,14 @@ var controller Controller var httpserver http.Server // New returns a new Controller reference. -func New(root string) *Controller { +func New(dir string, accPort int, pubPort int) *Controller { serverErrorLogger, _ := file.Open(file.LOG_SERVER_ERRORS, true, true) controller = Controller{ - Directory: root, + Directory: dir, DocumentRoot: "account/", - Port: 2082, - Public: public.New(root + "public/"), + Port: accPort, + Public: public.New(dir+"public/", pubPort), GracefulShutdownTimeout: 5 * time.Second, Status: 0, ServerLogger: serverErrorLogger, diff --git a/pkg/gpserver/apihandler.go b/pkg/gpserver/apihandler.go index 1a10bef..dfdfefa 100644 --- a/pkg/gpserver/apihandler.go +++ b/pkg/gpserver/apihandler.go @@ -5,8 +5,7 @@ import ( "net/http" "strings" - "github.com/Ennovar/gPanel/pkg/api/log" - "github.com/Ennovar/gPanel/pkg/api/server" + "github.com/Ennovar/gPanel/pkg/api/bundle" "github.com/Ennovar/gPanel/pkg/api/user" ) @@ -28,20 +27,8 @@ func (con *Controller) apiHandler(res http.ResponseWriter, req *http.Request, cu return true, user.Register(res, req, con.Directory) case "/user/logout": return true, user.Logout(res, req, con.Directory) - case "/server/status": - return true, server.Status(res, req, con.Bundles[curBundle].Public) - case "/server/start": - return true, server.Start(res, req, con.Bundles[curBundle].Public) - case "/server/shutdown": - return true, server.Shutdown(res, req, con.Bundles[curBundle].Public) - case "/server/restart": - return true, server.Restart(res, req, con.Bundles[curBundle].Public) - case "/server/maintenance": - return true, server.Maintenance(res, req, con.Bundles[curBundle].Public) - case "/log/read": - return true, log.Read(res, req) - case "/log/delete": - return true, log.Delete(res, req) + case "/bundle/create": + return true, bundle.Create(res, req, con.Bundles) default: return false, false } diff --git a/pkg/gpserver/gpserver.go b/pkg/gpserver/gpserver.go index 37ad4eb..18c4289 100644 --- a/pkg/gpserver/gpserver.go +++ b/pkg/gpserver/gpserver.go @@ -13,14 +13,14 @@ import ( type Controller struct { Directory string DocumentRoot string - Bundles []gpaccount.Controller + Bundles map[string]*gpaccount.Controller } func New() *Controller { return &Controller{ Directory: "server/", DocumentRoot: "document_root/", - Bundles: []gpaccount.Controller{}, + Bundles: make(map[string]*gpaccount.Controller), } } diff --git a/pkg/public/public.go b/pkg/public/public.go index 304ebdf..f5f6d5a 100644 --- a/pkg/public/public.go +++ b/pkg/public/public.go @@ -2,8 +2,6 @@ package public import ( - "context" - "errors" "fmt" "io" "net/http" @@ -21,7 +19,6 @@ type Controller struct { GracefulShutdownTimeout time.Duration Status int ClientLogger *file.Handler - ServerLogger *file.Handler LoadTimeLogger *file.Handler } @@ -29,18 +26,16 @@ var controller Controller var server http.Server // New function returns a new PublicWeb type. -func New(root string) *Controller { +func New(root string, port int) *Controller { clientLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) - serverLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) loadLogHandler, _ := file.Open(file.LOG_LOADTIME, true, true) controller = Controller{ DocumentRoot: root, - Port: 3000, + Port: port, GracefulShutdownTimeout: 5 * time.Second, Status: 0, ClientLogger: clientLogHandler, - ServerLogger: serverLogHandler, LoadTimeLogger: loadLogHandler, } @@ -55,73 +50,6 @@ func New(root string) *Controller { return &controller } -// Start function starts listening on the public server -func (con *Controller) Start() error { - if con.Status == 1 { - return errors.New("Public server is already on.") - } - - con.Status = 1 - go server.ListenAndServe() - return nil -} - -// Stop function stops the server gracefully or forceful, depending on the boolean input -func (con *Controller) Stop(graceful bool) error { - if graceful { - context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) - defer cancel() - - err := server.Shutdown(context) - if err == nil { - return nil - } - - fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) - } - - if err := server.Close(); err != nil { - return err - } - - con.Status = 0 - return nil -} - -// Restart function combines both the start and stop function, using different -// status codes, as it is restarting. -func (con *Controller) Restart(graceful bool) error { - con.Status = 3 - - if graceful { - context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) - defer cancel() - - err := server.Shutdown(context) - if err != nil { - fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) - - err = server.Close() - if err != nil { - return err - } - } - } - - err := server.Close() - if err != nil { - return err - } - - con.Status = 1 - go server.ListenAndServe() - return nil -} - -func (con *Controller) Maintenance() { - con.Status = 2 -} - // ServeHTTP function routes all requests for the public web server. It is used in the main // function inside of the http.ListenAndServe() function for the public host. func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { @@ -168,7 +96,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { _, err = io.Copy(res, f) if err != nil { - con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusInternalServerError) + "::" + err.Error()) + fmt.Printf("Server error serving files to client: %v\n", err) routing.HttpThrowStatus(http.StatusInternalServerError, res) return } diff --git a/pkg/public/restart.go b/pkg/public/restart.go new file mode 100644 index 0000000..8fbc5f1 --- /dev/null +++ b/pkg/public/restart.go @@ -0,0 +1,41 @@ +// Package public handles the logic of the public facing website +package public + +import ( + "context" + "fmt" +) + +// Restart function combines both the start and stop function, using different +// status codes, as it is restarting. +func (con *Controller) Restart(graceful bool) error { + con.Status = 3 + + if graceful { + context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) + defer cancel() + + err := server.Shutdown(context) + if err != nil { + fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) + + err = server.Close() + if err != nil { + return err + } + } + } + + err := server.Close() + if err != nil { + return err + } + + con.Status = 1 + go server.ListenAndServe() + return nil +} + +func (con *Controller) Maintenance() { + con.Status = 2 +} diff --git a/pkg/public/toggle.go b/pkg/public/toggle.go new file mode 100644 index 0000000..be01957 --- /dev/null +++ b/pkg/public/toggle.go @@ -0,0 +1,41 @@ +// Package public handles the logic of the public facing website +package public + +import ( + "context" + "errors" + "fmt" +) + +// Start function starts listening on the public server +func (con *Controller) Start() error { + if con.Status == 1 { + return errors.New("Public server is already on.") + } + + con.Status = 1 + go server.ListenAndServe() + return nil +} + +// Stop function stops the server gracefully or forceful, depending on the boolean input +func (con *Controller) Stop(graceful bool) error { + if graceful { + context, cancel := context.WithTimeout(context.Background(), con.GracefulShutdownTimeout) + defer cancel() + + err := server.Shutdown(context) + if err == nil { + return nil + } + + fmt.Printf("Graceful shutdown failed attempting forced: %v\n", err) + } + + if err := server.Close(); err != nil { + return err + } + + con.Status = 0 + return nil +} diff --git a/server/document_root/assets/js/panelHandlers/bundles/create.js b/server/document_root/assets/js/panelHandlers/bundles/create.js new file mode 100644 index 0000000..c51864c --- /dev/null +++ b/server/document_root/assets/js/panelHandlers/bundles/create.js @@ -0,0 +1,48 @@ +newBundleModal = jQuery('.new-bundle-modal'); + +jQuery('._js_bundles-create').on('click', function(e){ + e.preventDefault(); + + newBundleModal.modal('show'); +}); + +jQuery('._js_create-bundle-form').on('submit', function(e){ + e.preventDefault(); + + var formData = {}; + for(var y = 0, yy = this.length; y < yy; y++) { + var input = this[y]; + if(input.name) { + if(input.type == "number") { + formData[input.name] = parseInt(input.value); + } + else { + formData[input.name] = input.value; + } + } + } + + 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(formData)); + + xhr.onloadend = function() { + if(xhr.status == 200) { + if(xhr.response != undefined && xhr.response.length != 0) { + alert("Bundle \"" + xhr.response + "\" successfully created."); + } + else { + alert("Bundle successfully created."); + } + } + else { + if(xhr.response != undefined && xhr.response.length != 0) { + alert("Error: " + xhr.response); + } + else { + alert("An error has occurred. Please try again. If problem persists contact server administrator."); + } + } + } +}); diff --git a/server/document_root/gPanel.html b/server/document_root/gPanel.html index 4df6c16..d9ec059 100644 --- a/server/document_root/gPanel.html +++ b/server/document_root/gPanel.html @@ -27,17 +27,54 @@ + + +
-

Test

-
Test
- -
-
@@ -64,6 +101,8 @@ + + diff --git a/server/logs/README.md b/server/logs/README.md new file mode 100644 index 0000000..9ee4345 --- /dev/null +++ b/server/logs/README.md @@ -0,0 +1,9 @@ +# gPanel Logs + +The actual log files are ignored by the .gitignore file. They are generated automatically upon being needed within the software itself. + +Current log files: +- client_errors.log +- account_errors.log +- server_errors.log +- loadtime.log From e97c5c634c9abe841cf338726cdfc33fb62f008a Mon Sep 17 00:00:00 2001 From: George Shaw Date: Wed, 15 Nov 2017 16:00:05 -0600 Subject: [PATCH 5/7] creating bundles is done --- .gitignore | 3 + pkg/api/bundle/create.go | 32 +++++++++++ pkg/api/user/auth.go | 2 +- pkg/api/user/get_secret.go | 2 +- pkg/api/user/register.go | 2 +- pkg/database/database.go | 8 ++- pkg/file/dircopy.go | 112 +++++++++++++++++++++++++++++++++++++ pkg/gpaccount/gpaccount.go | 19 ++++--- pkg/gpaccount/toggle.go | 1 + pkg/public/public.go | 26 ++++----- pkg/public/toggle.go | 1 + 11 files changed, 183 insertions(+), 25 deletions(-) create mode 100644 pkg/file/dircopy.go diff --git a/.gitignore b/.gitignore index 83f9dd1..55d4dcd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ bundles/* # IGNORE .DB FILES **.db + +# IGNORE OSX FINDER FILES +**.DS_Store diff --git a/pkg/api/bundle/create.go b/pkg/api/bundle/create.go index 636a387..e289056 100644 --- a/pkg/api/bundle/create.go +++ b/pkg/api/bundle/create.go @@ -7,6 +7,8 @@ import ( "net/http" "strconv" + "github.com/Ennovar/gPanel/pkg/database" + "github.com/Ennovar/gPanel/pkg/file" "github.com/Ennovar/gPanel/pkg/gpaccount" ) @@ -63,6 +65,36 @@ func Create(res http.ResponseWriter, req *http.Request, bundles map[string]*gpac return false } + newBundle := "bundles/bundle_" + createBundleRequestData.Name + err = file.CopyDir("bundles/default_bundle", newBundle) + if err != nil { + http.Error(res, err.Error(), http.StatusInternalServerError) + return false + } + + ds, err := database.Open(newBundle + "/" + database.DB_MAIN) + if err != nil { + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + defer ds.Close() + + err = ds.Put(database.BUCKET_PORTS, []byte("account"), createBundleRequestData.AccPort) + if err != nil { + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + + err = ds.Put(database.BUCKET_PORTS, []byte("public"), createBundleRequestData.PubPort) + if err != nil { + http.Error(res, err.Error(), http.StatusBadRequest) + return false + } + + bundles[createBundleRequestData.Name] = gpaccount.New(newBundle+"/", createBundleRequestData.AccPort, createBundleRequestData.PubPort) + _ = bundles[createBundleRequestData.Name].Start() + _ = bundles[createBundleRequestData.Name].Public.Start() + res.WriteHeader(http.StatusOK) res.Write([]byte(createBundleRequestData.Name)) diff --git a/pkg/api/user/auth.go b/pkg/api/user/auth.go index 69a0afb..e636abe 100644 --- a/pkg/api/user/auth.go +++ b/pkg/api/user/auth.go @@ -33,7 +33,7 @@ func Auth(res http.ResponseWriter, req *http.Request, dir string) bool { return false } - ds, err := database.Open(dir + database.DB_USERS) + ds, err := database.Open(dir + database.DB_MAIN) if err != nil || ds == nil { http.Error(res, err.Error(), http.StatusInternalServerError) return false diff --git a/pkg/api/user/get_secret.go b/pkg/api/user/get_secret.go index 8cc7470..7a4b003 100644 --- a/pkg/api/user/get_secret.go +++ b/pkg/api/user/get_secret.go @@ -7,7 +7,7 @@ import "github.com/Ennovar/gPanel/pkg/database" // only used on the server side to help verify users are who they say they // are. func GetSecret(user string, directory string) (string, error) { - ds, err := database.Open(directory + database.DB_USERS) + ds, err := database.Open(directory + database.DB_MAIN) if err != nil { return "", err } diff --git a/pkg/api/user/register.go b/pkg/api/user/register.go index c8b303f..0fec4b6 100644 --- a/pkg/api/user/register.go +++ b/pkg/api/user/register.go @@ -32,7 +32,7 @@ func Register(res http.ResponseWriter, req *http.Request, dir string) bool { return false } - ds, err := database.Open(dir + database.DB_USERS) + ds, err := database.Open(dir + database.DB_MAIN) if err != nil || ds == nil { http.Error(res, err.Error(), http.StatusInternalServerError) return false diff --git a/pkg/database/database.go b/pkg/database/database.go index 9ab111f..1258827 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -11,12 +11,13 @@ import ( // Database constants const ( - DB_USERS = "users.db" + DB_MAIN = "datastore.db" ) // Bucket constants const ( BUCKET_USERS = "users" + BUCKET_PORTS = "ports" ) // Error codes @@ -45,6 +46,11 @@ func Open(filepath string) (*Datastore, error) { err = ds.handle.Update(func(tx *bolt.Tx) error { _, err := tx.CreateBucketIfNotExists([]byte(BUCKET_USERS)) + if err != nil { + return err + } + _, err = tx.CreateBucketIfNotExists([]byte(BUCKET_PORTS)) + if err != nil { return err } diff --git a/pkg/file/dircopy.go b/pkg/file/dircopy.go new file mode 100644 index 0000000..415fa96 --- /dev/null +++ b/pkg/file/dircopy.go @@ -0,0 +1,112 @@ +// Package file handles various file operations +package file + +import ( + "errors" + "io" + "io/ioutil" + "os" + "path/filepath" +) + +// CopyFile copies the contents of the file named src to the file named +// by dst. The file will be created if it does not already exist. If the +// destination file exists, all it's contents will be replaced by the contents +// of the source file. The file mode will be copied from the source and +// the copied data is synced/flushed to stable storage. +func CopyFile(src, dst string) error { + in, err := os.Open(src) + if err != nil { + return err + } + defer in.Close() + + out, err := os.Create(dst) + if err != nil { + return err + } + defer func() { + if e := out.Close(); e != nil { + err = e + } + }() + + _, err = io.Copy(out, in) + if err != nil { + return err + } + + err = out.Sync() + if err != nil { + return err + } + + si, err := os.Stat(src) + if err != nil { + return err + } + err = os.Chmod(dst, si.Mode()) + if err != nil { + return err + } + + return nil +} + +// CopyDir recursively copies a directory tree, attempting to preserve permissions. +// Source directory must exist, destination directory must *not* exist. +// Symlinks are ignored and skipped. +func CopyDir(src string, dst string) error { + src = filepath.Clean(src) + dst = filepath.Clean(dst) + + si, err := os.Stat(src) + if err != nil { + return err + } + if !si.IsDir() { + return errors.New("source is not a directory") + } + + _, err = os.Stat(dst) + if err != nil && !os.IsNotExist(err) { + return err + } + if err == nil { + return errors.New("destination already exists") + } + + err = os.MkdirAll(dst, si.Mode()) + if err != nil { + return err + } + + entries, err := ioutil.ReadDir(src) + if err != nil { + return err + } + + for _, entry := range entries { + srcPath := filepath.Join(src, entry.Name()) + dstPath := filepath.Join(dst, entry.Name()) + + if entry.IsDir() { + err = CopyDir(srcPath, dstPath) + if err != nil { + return err + } + } else { + // Skip symlinks. + if entry.Mode()&os.ModeSymlink != 0 { + continue + } + + err = CopyFile(srcPath, dstPath) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/pkg/gpaccount/gpaccount.go b/pkg/gpaccount/gpaccount.go index 982bf79..7525b06 100644 --- a/pkg/gpaccount/gpaccount.go +++ b/pkg/gpaccount/gpaccount.go @@ -2,13 +2,13 @@ package gpaccount import ( + "fmt" "io" "net/http" "os" "strconv" "time" - "github.com/Ennovar/gPanel/pkg/file" "github.com/Ennovar/gPanel/pkg/public" "github.com/Ennovar/gPanel/pkg/routing" ) @@ -20,7 +20,7 @@ type Controller struct { Public *public.Controller GracefulShutdownTimeout time.Duration Status int - ServerLogger *file.Handler + // ServerLogger *file.Handler } var controller Controller @@ -28,7 +28,7 @@ var httpserver http.Server // New returns a new Controller reference. func New(dir string, accPort int, pubPort int) *Controller { - serverErrorLogger, _ := file.Open(file.LOG_SERVER_ERRORS, true, true) + // serverErrorLogger, _ := file.Open(file.LOG_SERVER_ERRORS, true, true) controller = Controller{ Directory: dir, @@ -37,7 +37,7 @@ func New(dir string, accPort int, pubPort int) *Controller { Public: public.New(dir+"public/", pubPort), GracefulShutdownTimeout: 5 * time.Second, Status: 0, - ServerLogger: serverErrorLogger, + // ServerLogger: serverErrorLogger, } httpserver = http.Server{ @@ -61,9 +61,11 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { path = (con.Directory + path) } + fmt.Println("acc: " + path) + if reqAuth(path) { if !con.checkAuth(res, req) { - con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusUnauthorized) + "::" + http.StatusText(http.StatusUnauthorized)) + // con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusUnauthorized) + "::" + http.StatusText(http.StatusUnauthorized)) http.Error(res, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } @@ -79,7 +81,8 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { f, err := os.Open(path) if err != nil { - con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusNotFound) + "::" + err.Error()) + // con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusNotFound) + "::" + err.Error()) + fmt.Println(err.Error()) routing.HttpThrowStatus(http.StatusNotFound, res) return } @@ -87,7 +90,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { contentType, err := routing.GetContentType(path) if err != nil { - con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusUnsupportedMediaType) + "::" + err.Error()) + // con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusUnsupportedMediaType) + "::" + err.Error()) routing.HttpThrowStatus(http.StatusUnsupportedMediaType, res) return } @@ -96,7 +99,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { _, err = io.Copy(res, f) if err != nil { - con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusInternalServerError) + "::" + err.Error()) + // con.ServerLogger.Write(path + "::" + strconv.Itoa(http.StatusInternalServerError) + "::" + err.Error()) routing.HttpThrowStatus(http.StatusInternalServerError, res) return } diff --git a/pkg/gpaccount/toggle.go b/pkg/gpaccount/toggle.go index b96b274..9cdecba 100644 --- a/pkg/gpaccount/toggle.go +++ b/pkg/gpaccount/toggle.go @@ -14,6 +14,7 @@ func (con *Controller) Start() error { con.Status = 1 go httpserver.ListenAndServe() + fmt.Printf("gPanel account server now serving out of %s%s on port %d\n", con.Directory, con.DocumentRoot, con.Port) return nil } diff --git a/pkg/public/public.go b/pkg/public/public.go index f5f6d5a..c3601b6 100644 --- a/pkg/public/public.go +++ b/pkg/public/public.go @@ -6,10 +6,8 @@ import ( "io" "net/http" "os" - "strconv" "time" - "github.com/Ennovar/gPanel/pkg/file" "github.com/Ennovar/gPanel/pkg/routing" ) @@ -18,8 +16,8 @@ type Controller struct { Port int GracefulShutdownTimeout time.Duration Status int - ClientLogger *file.Handler - LoadTimeLogger *file.Handler + // ClientLogger *file.Handler + // LoadTimeLogger *file.Handler } var controller Controller @@ -27,16 +25,16 @@ var server http.Server // New function returns a new PublicWeb type. func New(root string, port int) *Controller { - clientLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) - loadLogHandler, _ := file.Open(file.LOG_LOADTIME, true, true) + // clientLogHandler, _ := file.Open(file.LOG_CLIENT_ERRORS, true, true) + // loadLogHandler, _ := file.Open(file.LOG_LOADTIME, true, true) controller = Controller{ DocumentRoot: root, Port: port, GracefulShutdownTimeout: 5 * time.Second, Status: 0, - ClientLogger: clientLogHandler, - LoadTimeLogger: loadLogHandler, + // ClientLogger: clientLogHandler, + // LoadTimeLogger: loadLogHandler, } server = http.Server{ @@ -53,7 +51,7 @@ func New(root string, port int) *Controller { // ServeHTTP function routes all requests for the public web server. It is used in the main // function inside of the http.ListenAndServe() function for the public host. func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { - startTime := time.Now() + // startTime := time.Now() switch con.Status { case 0: // This will actually never show because this function won't run if the server is off @@ -76,10 +74,12 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { path = (con.DocumentRoot + path) } + fmt.Println("pub: " + path) + f, err := os.Open(path) if err != nil { - con.ClientLogger.Write(path + "::" + strconv.Itoa(http.StatusNotFound) + "::" + err.Error()) + // con.ClientLogger.Write(path + "::" + strconv.Itoa(http.StatusNotFound) + "::" + err.Error()) routing.HttpThrowStatus(http.StatusNotFound, res) return } @@ -87,7 +87,7 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { contentType, err := routing.GetContentType(path) if err != nil { - con.ClientLogger.Write(path + "::" + strconv.Itoa(http.StatusUnsupportedMediaType) + "::" + err.Error()) + // con.ClientLogger.Write(path + "::" + strconv.Itoa(http.StatusUnsupportedMediaType) + "::" + err.Error()) routing.HttpThrowStatus(http.StatusUnsupportedMediaType, res) return } @@ -101,6 +101,6 @@ func (con *Controller) ServeHTTP(res http.ResponseWriter, req *http.Request) { return } - elapsedTime := time.Since(startTime) - con.LoadTimeLogger.Write(path + " rendered in " + strconv.FormatFloat(elapsedTime.Seconds(), 'f', 6, 64) + " seconds") + // elapsedTime := time.Since(startTime) + // con.LoadTimeLogger.Write(path + " rendered in " + strconv.FormatFloat(elapsedTime.Seconds(), 'f', 6, 64) + " seconds") } diff --git a/pkg/public/toggle.go b/pkg/public/toggle.go index be01957..a6ead45 100644 --- a/pkg/public/toggle.go +++ b/pkg/public/toggle.go @@ -15,6 +15,7 @@ func (con *Controller) Start() error { con.Status = 1 go server.ListenAndServe() + fmt.Printf("Public server now serving out of %s on port %d\n", con.DocumentRoot, con.Port) return nil } From 0407be5573835a641586fc64f0f92718e6966d3d Mon Sep 17 00:00:00 2001 From: George Shaw Date: Thu, 16 Nov 2017 16:21:01 -0600 Subject: [PATCH 6/7] creating bundles now works --- {bundles/default_bundle/account => account}/README.md | 0 .../default_bundle/account => account}/assets/css/style.css | 0 .../account => account}/assets/js/formHandlers/login.js | 0 .../account => account}/assets/js/formHandlers/logout.js | 0 .../account => account}/assets/js/formHandlers/register.js | 0 .../account => account}/assets/js/formHandlers/search.js | 0 .../assets/js/panelHandlers/log/delete.js | 0 .../account => account}/assets/js/panelHandlers/log/view.js | 0 .../assets/js/panelHandlers/publicServer/maintenance.js | 0 .../assets/js/panelHandlers/publicServer/restart.js | 0 .../assets/js/panelHandlers/publicServer/shutdown.js | 0 .../assets/js/panelHandlers/publicServer/start.js | 0 .../assets/js/panelHandlers/publicServer/status.js | 0 .../assets/js/panelHandlers/security/ipFiltering.js | 0 {bundles/default_bundle/account => account}/gPanel.html | 0 {bundles/default_bundle/account => account}/index.html | 4 ++-- pkg/gpaccount/gpaccount.go | 6 ++---- pkg/public/public.go | 5 ++--- 18 files changed, 6 insertions(+), 9 deletions(-) rename {bundles/default_bundle/account => account}/README.md (100%) rename {bundles/default_bundle/account => account}/assets/css/style.css (100%) rename {bundles/default_bundle/account => account}/assets/js/formHandlers/login.js (100%) rename {bundles/default_bundle/account => account}/assets/js/formHandlers/logout.js (100%) rename {bundles/default_bundle/account => account}/assets/js/formHandlers/register.js (100%) rename {bundles/default_bundle/account => account}/assets/js/formHandlers/search.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/log/delete.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/log/view.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/publicServer/maintenance.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/publicServer/restart.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/publicServer/shutdown.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/publicServer/start.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/publicServer/status.js (100%) rename {bundles/default_bundle/account => account}/assets/js/panelHandlers/security/ipFiltering.js (100%) rename {bundles/default_bundle/account => account}/gPanel.html (100%) rename {bundles/default_bundle/account => account}/index.html (98%) diff --git a/bundles/default_bundle/account/README.md b/account/README.md similarity index 100% rename from bundles/default_bundle/account/README.md rename to account/README.md diff --git a/bundles/default_bundle/account/assets/css/style.css b/account/assets/css/style.css similarity index 100% rename from bundles/default_bundle/account/assets/css/style.css rename to account/assets/css/style.css diff --git a/bundles/default_bundle/account/assets/js/formHandlers/login.js b/account/assets/js/formHandlers/login.js similarity index 100% rename from bundles/default_bundle/account/assets/js/formHandlers/login.js rename to account/assets/js/formHandlers/login.js diff --git a/bundles/default_bundle/account/assets/js/formHandlers/logout.js b/account/assets/js/formHandlers/logout.js similarity index 100% rename from bundles/default_bundle/account/assets/js/formHandlers/logout.js rename to account/assets/js/formHandlers/logout.js diff --git a/bundles/default_bundle/account/assets/js/formHandlers/register.js b/account/assets/js/formHandlers/register.js similarity index 100% rename from bundles/default_bundle/account/assets/js/formHandlers/register.js rename to account/assets/js/formHandlers/register.js diff --git a/bundles/default_bundle/account/assets/js/formHandlers/search.js b/account/assets/js/formHandlers/search.js similarity index 100% rename from bundles/default_bundle/account/assets/js/formHandlers/search.js rename to account/assets/js/formHandlers/search.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/log/delete.js b/account/assets/js/panelHandlers/log/delete.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/log/delete.js rename to account/assets/js/panelHandlers/log/delete.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/log/view.js b/account/assets/js/panelHandlers/log/view.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/log/view.js rename to account/assets/js/panelHandlers/log/view.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/maintenance.js b/account/assets/js/panelHandlers/publicServer/maintenance.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/publicServer/maintenance.js rename to account/assets/js/panelHandlers/publicServer/maintenance.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/restart.js b/account/assets/js/panelHandlers/publicServer/restart.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/publicServer/restart.js rename to account/assets/js/panelHandlers/publicServer/restart.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/shutdown.js b/account/assets/js/panelHandlers/publicServer/shutdown.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/publicServer/shutdown.js rename to account/assets/js/panelHandlers/publicServer/shutdown.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/start.js b/account/assets/js/panelHandlers/publicServer/start.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/publicServer/start.js rename to account/assets/js/panelHandlers/publicServer/start.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/publicServer/status.js b/account/assets/js/panelHandlers/publicServer/status.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/publicServer/status.js rename to account/assets/js/panelHandlers/publicServer/status.js diff --git a/bundles/default_bundle/account/assets/js/panelHandlers/security/ipFiltering.js b/account/assets/js/panelHandlers/security/ipFiltering.js similarity index 100% rename from bundles/default_bundle/account/assets/js/panelHandlers/security/ipFiltering.js rename to account/assets/js/panelHandlers/security/ipFiltering.js diff --git a/bundles/default_bundle/account/gPanel.html b/account/gPanel.html similarity index 100% rename from bundles/default_bundle/account/gPanel.html rename to account/gPanel.html diff --git a/bundles/default_bundle/account/index.html b/account/index.html similarity index 98% rename from bundles/default_bundle/account/index.html rename to account/index.html index 283302e..9178b8e 100644 --- a/bundles/default_bundle/account/index.html +++ b/account/index.html @@ -1,7 +1,7 @@ - gPanel + gPanel Account @@ -12,7 +12,7 @@
+ + +
@@ -73,7 +93,7 @@
Create new bundles and update current bundles.
- +
@@ -103,6 +123,7 @@ +