mirror of
https://github.com/donl/gPanel.git
synced 2026-05-29 14:22:24 -06:00
commit
ff6b8b37e5
21 changed files with 121 additions and 62 deletions
|
|
@ -1,17 +1,3 @@
|
|||
# gPanel Frontend Development
|
||||
|
||||
The client side, front end of gPanel. Developed using Angular, SASS, and Bootstrap. Managed with NPM package manager.
|
||||
|
||||
__Note__: In the early stages of development the frontend will be static HTML/CSS/JS. Once enough progress is made it will then be translated into Angular and SASS code.
|
||||
|
||||
## Contribution Set-up & Deployment
|
||||
|
||||
Layout and Components
|
||||
```shell
|
||||
gPanel/document_roots/webhost/gPanel.html
|
||||
```
|
||||
|
||||
Styles
|
||||
```shell
|
||||
gPanel/document_roots/webhost/styles.css
|
||||
```
|
||||
In the early stages of gPanel the only technologies we will be using on the front end are HTML/CSS/JS, utilizing the jQuery, bootstrap, and font-awesome libraries respectively. The reason for doing this is to keep front end development as simple as possible in order to push development of the overall software faster.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ jQuery('._js_diagnostics-clear-log').on('click', function(e){
|
|||
var title;
|
||||
switch(logName) {
|
||||
case "client_errors":
|
||||
title = "Client Error Log (4xx)";
|
||||
title = "Client Error Log";
|
||||
break;
|
||||
case "server_errors":
|
||||
title = "Server Error Log (5xx)";
|
||||
title = "Server Error Log";
|
||||
break;
|
||||
case "load_time":
|
||||
title = "Load Time Log";
|
||||
|
|
@ -27,7 +27,7 @@ jQuery('._js_diagnostics-clear-log').on('click', function(e){
|
|||
requestData["name"] = logName+".log";
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('UPDATE', 'api/logs/delete', true);
|
||||
xhr.open('UPDATE', 'api/log/delete', true);
|
||||
xhr.send(JSON.stringify(requestData));
|
||||
|
||||
xhr.onloadend = function() {
|
||||
|
|
@ -8,10 +8,10 @@ jQuery('._js_diagnostics-view-log').on('click', function(e){
|
|||
var title;
|
||||
switch(logName) {
|
||||
case "client_errors":
|
||||
title = "Client Error Log (4xx)";
|
||||
title = "Client Error Log";
|
||||
break;
|
||||
case "server_errors":
|
||||
title = "Server Error Log (5xx)";
|
||||
title = "Server Error Log";
|
||||
break;
|
||||
case "load_time":
|
||||
title = "Load Time Log";
|
||||
|
|
@ -27,7 +27,7 @@ jQuery('._js_diagnostics-view-log').on('click', function(e){
|
|||
requestData["name"] = logName+".log";
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', 'api/logs/read', true);
|
||||
xhr.open('POST', 'api/log/read', true);
|
||||
xhr.send(JSON.stringify(requestData));
|
||||
|
||||
xhr.onloadend = function() {
|
||||
|
|
@ -72,8 +72,8 @@
|
|||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Diagnostics</h4>
|
||||
<h6 class="card-subtitle mb-4 text-muted">View various server data pools that may help pinpoint issues</h6>
|
||||
<h4 class="card-title">Logs</h4>
|
||||
<h6 class="card-subtitle mb-4 text-muted">View various client and server data logs that may help pinpoint issues</h6>
|
||||
<button type="button" class="btn btn-outline-primary _js_diagnostics-view-log" data="client_errors">Client Error Log</button>
|
||||
<button type="button" class="btn btn-outline-primary _js_diagnostics-view-log" data="server_errors">Server Error Log</button>
|
||||
<button type="button" class="btn btn-outline-primary _js_diagnostics-view-log" data="load_time">Load Time Log</button>
|
||||
|
|
@ -110,8 +110,8 @@
|
|||
<script type="text/javascript" src="assets/js/panelHandlers/publicServer/shutdown.js"></script>
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/publicServer/restart.js"></script>
|
||||
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/diagnostics/viewLog.js"></script>
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/diagnostics/deleteLog.js"></script>
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/logs/view.js"></script>
|
||||
<script type="text/javascript" src="assets/js/panelHandlers/logs/delete.js"></script>
|
||||
<!-- KEEP AT BOTTOM OF BODY TAGS -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/api/logs"
|
||||
"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"
|
||||
|
|
@ -40,10 +40,10 @@ func HandleAPI(res http.ResponseWriter, req *http.Request, path string, publicSe
|
|||
return true, server.Restart(res, req, publicServer)
|
||||
case "/server/maintenance":
|
||||
return true, server.Maintenance(res, req, publicServer)
|
||||
case "/logs/read":
|
||||
return true, logs.Read(res, req)
|
||||
case "/logs/delete":
|
||||
return true, logs.Delete(res, req)
|
||||
case "/log/read":
|
||||
return true, log.Read(res, req)
|
||||
case "/log/delete":
|
||||
return true, log.Delete(res, req)
|
||||
default:
|
||||
return false, false
|
||||
}
|
||||
|
|
|
|||
27
pkg/api/log/README.md
Normal file
27
pkg/api/log/README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Log API Documentation
|
||||
|
||||
```go
|
||||
/*
|
||||
Relative API Path:
|
||||
api/log/read
|
||||
Request:
|
||||
{
|
||||
"name": string
|
||||
}
|
||||
Response(200, 404, 405):
|
||||
[log contents]
|
||||
*/
|
||||
func Read(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
||||
/*
|
||||
Relative API Path:
|
||||
api/log/delete
|
||||
Request:
|
||||
{
|
||||
"name": string
|
||||
}
|
||||
Response(204, 404, 405):
|
||||
N/A
|
||||
*/
|
||||
func Delete(res http.ResponseWriter, req *http.Request) bool {}
|
||||
```
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Package logs is a child of package api to handle api calls concerning log files
|
||||
package logs
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/file"
|
||||
)
|
||||
|
||||
// Delete function is accessed from api/logs/delete and will attempt to
|
||||
// delete a given log based off of request data.
|
||||
func Delete(res http.ResponseWriter, req *http.Request) bool {
|
||||
if req.Method != "UPDATE" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// Package logs is a child of package api to handle api calls concerning log files
|
||||
package logs
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/file"
|
||||
)
|
||||
|
||||
// Read function is accessed from api/logs/read and will attempt to read
|
||||
// a given log based off of the request data.
|
||||
func Read(res http.ResponseWriter, req *http.Request) bool {
|
||||
if req.Method != "POST" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
@ -6,8 +6,11 @@ Relative API Path:
|
|||
api/server/status
|
||||
Request:
|
||||
N/A
|
||||
Response():
|
||||
N/A
|
||||
Response(200, 405):
|
||||
"0" - OFF,
|
||||
"1" - ON,
|
||||
"2" - "MAINTENANCE",
|
||||
"3" - "RESTARTING"
|
||||
*/
|
||||
func Status(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
||||
|
|
@ -16,27 +19,31 @@ Relative API Path:
|
|||
api/server/start
|
||||
Request:
|
||||
N/A
|
||||
Response():
|
||||
Response(204, 405, 409):
|
||||
N/A
|
||||
*/
|
||||
func Start(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
||||
/*
|
||||
Relative API Path:
|
||||
api/server/Shutdown
|
||||
api/server/shutdown
|
||||
Request:
|
||||
N/A
|
||||
Response():
|
||||
{
|
||||
"graceful": boolean
|
||||
}
|
||||
Response(204, 404, 405):
|
||||
N/A
|
||||
*/
|
||||
func Shutdown(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
||||
/*
|
||||
Relative API Path:
|
||||
api/server/Restart
|
||||
api/server/restart
|
||||
Request:
|
||||
N/A
|
||||
Response():
|
||||
{
|
||||
"graceful": boolean
|
||||
}
|
||||
Response(204, 404, 405):
|
||||
N/A
|
||||
*/
|
||||
func Restart(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
|
@ -46,7 +53,7 @@ Relative API Path:
|
|||
api/server/maintenance
|
||||
Request:
|
||||
N/A
|
||||
Response():
|
||||
Response(204, 405):
|
||||
N/A
|
||||
*/
|
||||
func Maintenance(res http.ResponseWriter, req *http.Request) bool {}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/public"
|
||||
)
|
||||
|
||||
// Maintenance function is called from /api/server/maintenance and will place the public server into
|
||||
// maintenance mode.
|
||||
func Maintenance(res http.ResponseWriter, req *http.Request, publicServer *public.Controller) bool {
|
||||
if req.Method != "UPDATE" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/public"
|
||||
)
|
||||
|
||||
// Restart function is called from /api/server/restart and will attempt to shutdown, either gracefully
|
||||
// or not gracefully (contingent on request data), and then turn back on the public server.
|
||||
func Restart(res http.ResponseWriter, req *http.Request, publicServer *public.Controller) bool {
|
||||
if req.Method != "UPDATE" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/public"
|
||||
)
|
||||
|
||||
// Shutdown function is called from /api/server/shutdown and will attempt to shutdown, either gracefully
|
||||
// or not gracefully (contingent on request data).
|
||||
func Shutdown(res http.ResponseWriter, req *http.Request, publicServer *public.Controller) bool {
|
||||
if req.Method != "UPDATE" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/public"
|
||||
)
|
||||
|
||||
// Start function is called from /api/server/start and turn the public server on.
|
||||
func Start(res http.ResponseWriter, req *http.Request, publicServer *public.Controller) bool {
|
||||
if req.Method != "UPDATE" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import (
|
|||
"github.com/Ennovar/gPanel/pkg/public"
|
||||
)
|
||||
|
||||
// Status function is called from api/server/status and will return the current status of
|
||||
// the public server.
|
||||
func Status(res http.ResponseWriter, req *http.Request, publicServer *public.Controller) bool {
|
||||
if req.Method != "GET" {
|
||||
http.Error(res, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Relative API Path:
|
|||
api/user/auth
|
||||
Request:
|
||||
{
|
||||
"user": "test",
|
||||
"pass": "test",
|
||||
"user": string,
|
||||
"pass": string,
|
||||
}
|
||||
Response(204, 400, 401, 405, 500):
|
||||
N/A
|
||||
|
|
@ -19,8 +19,8 @@ Relative API Path:
|
|||
api/user/register
|
||||
Request:
|
||||
{
|
||||
"user": "test",
|
||||
"pass": "test",
|
||||
"user": string,
|
||||
"pass": string,
|
||||
}
|
||||
Response (204, 400, 405, 500):
|
||||
N/A
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ func Auth(res http.ResponseWriter, req *http.Request) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
var userRequestData struct {
|
||||
User string `json:"user"`
|
||||
Pass string `json:"pass"`
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&userRequestData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
|
|
@ -34,6 +39,11 @@ func Auth(res http.ResponseWriter, req *http.Request) bool {
|
|||
}
|
||||
defer ds.Close()
|
||||
|
||||
var userDatabaseData struct {
|
||||
Pass string `json:"pass"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
err = ds.Get(database.BUCKET_USERS, []byte(userRequestData.User), &userDatabaseData)
|
||||
|
||||
if err == database.ErrKeyNotExist {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ func GetSecret(user string) (string, error) {
|
|||
}
|
||||
defer ds.Close()
|
||||
|
||||
var userDatabaseData struct {
|
||||
Pass string `json:"pass"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
err = ds.Get(database.BUCKET_USERS, []byte(user), &userDatabaseData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ func Register(res http.ResponseWriter, req *http.Request) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
var userRequestData struct {
|
||||
User string `json:"user"`
|
||||
Pass string `json:"pass"`
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&userRequestData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
|
|
@ -34,6 +39,11 @@ func Register(res http.ResponseWriter, req *http.Request) bool {
|
|||
}
|
||||
defer ds.Close()
|
||||
|
||||
var userDatabaseData struct {
|
||||
Pass string `json:"pass"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
err = ds.Get(database.BUCKET_USERS, []byte(userRequestData.User), &userDatabaseData)
|
||||
if err != database.ErrKeyNotExist {
|
||||
http.Error(res, "Username already exists in the database", http.StatusBadRequest)
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
// Package user is a child of package api to handle api calls concerning users
|
||||
package user
|
||||
|
||||
// userRequestData struct is the structure of the JSON data to be
|
||||
// retrieved from the authentication API request
|
||||
var userRequestData struct {
|
||||
User string `json:"user"`
|
||||
Pass string `json:"pass"`
|
||||
}
|
||||
|
||||
// userDatabaseData struct is the structure of the JSON data to be retrieved from
|
||||
// the bolt database inside of the user bucket, using the username as the key.
|
||||
var userDatabaseData struct {
|
||||
Pass string `json:"pass"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
|
@ -21,6 +21,10 @@ type Handler struct {
|
|||
append bool
|
||||
}
|
||||
|
||||
// Open function attempts to open a file and returns the handler for said file.
|
||||
// This function takes a parameter append which if set to false will truncate the
|
||||
// file upon writing to it. The log parameter denotes whether or not to look inside
|
||||
// of the log folder when attempting to open a given file.
|
||||
func Open(file string, append bool, log bool) (*Handler, error) {
|
||||
var err error
|
||||
var absPath string
|
||||
|
|
@ -57,6 +61,10 @@ func Open(file string, append bool, log bool) (*Handler, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// checkexistence function is ran everytime the handler has a function called from it.
|
||||
// This function ensures that the file still exists whenever trying to perform various
|
||||
// operations on it. The boolean parameter, createIfNotExist, if set to true, will create
|
||||
// the file again if it has been deleted.
|
||||
func (h *Handler) checkExistence(createIfNotExist bool) (bool, error) {
|
||||
if _, err := os.Stat(h.path); os.IsNotExist(err) {
|
||||
if createIfNotExist {
|
||||
|
|
@ -78,6 +86,7 @@ func (h *Handler) checkExistence(createIfNotExist bool) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// Read function is attached to the file handler type and will read the current file.
|
||||
func (h *Handler) Read() ([]byte, error) {
|
||||
_, err := h.checkExistence(true)
|
||||
if err != nil {
|
||||
|
|
@ -92,6 +101,7 @@ func (h *Handler) Read() ([]byte, error) {
|
|||
return data, err
|
||||
}
|
||||
|
||||
// Write function is attached to the file handler type and will write to the current file.
|
||||
func (h *Handler) Write(data string) (int, error) {
|
||||
_, err := h.checkExistence(true)
|
||||
if err != nil {
|
||||
|
|
@ -106,6 +116,9 @@ func (h *Handler) Write(data string) (int, error) {
|
|||
return written, err
|
||||
}
|
||||
|
||||
// Close function is attached to the current file and will attempt to close the current file.
|
||||
// The boolean parameter delete, if set to true, will also attempt to delete the file
|
||||
// upon closing it.
|
||||
func (h *Handler) Close(delete bool) (error, error) {
|
||||
exist, _ := h.checkExistence(false)
|
||||
if !exist {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ type store struct {
|
|||
cookieName string
|
||||
}
|
||||
|
||||
// GetStore function takes a name and either creates/grabs a store with that name.
|
||||
func GetStore(name string) store {
|
||||
sessionStore := store{
|
||||
handle: sessions.NewCookieStore(key),
|
||||
|
|
@ -28,6 +29,7 @@ func GetStore(name string) store {
|
|||
return sessionStore
|
||||
}
|
||||
|
||||
// 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 {
|
||||
session, err := s.handle.Get(req, s.cookieName)
|
||||
|
||||
|
|
@ -45,6 +47,7 @@ func (s *store) Set(res http.ResponseWriter, req *http.Request, key string, valu
|
|||
return nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
session, err := s.handle.Get(req, s.cookieName)
|
||||
|
||||
|
|
@ -56,6 +59,7 @@ func (s *store) Read(res http.ResponseWriter, req *http.Request, key string) (in
|
|||
return value, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
session, err := s.handle.Get(req, s.cookieName)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue