mirror of
https://github.com/donl/gPanel.git
synced 2026-05-25 22:06:55 -06:00
boltdb is working as well as authentication and registration for users. you can take it in index.html of the webhost
This commit is contained in:
parent
48e6e5224b
commit
d451bda6b5
6 changed files with 238 additions and 68 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
main
|
||||
gpanel
|
||||
datastore.db
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<link rel="icon" type="image/x-icon" href="https://play.golang.org/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<form id="authForm" method="POST" action="authentication">
|
||||
<form class="api_form" method="POST" action="authentication">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -28,30 +28,55 @@
|
|||
</table>
|
||||
</form>
|
||||
|
||||
<form class="api_form" method="POST" action="registration">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">gPanel Registration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Username:</td>
|
||||
<td><input type="text" placeholder="username..." name="user"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><input type="password" placeholder="password..." name="pass"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" value="Register"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
var form = document.getElementById('authForm');
|
||||
var form = document.getElementsByClassName('api_form');
|
||||
|
||||
form.onsubmit = function(e) {
|
||||
e.preventDefault();
|
||||
for(var i = 0; i < form.length; i++) {
|
||||
form[i].onsubmit = function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var formData = {};
|
||||
for(var i = 0, ii = form.length; i < ii; i++) {
|
||||
var input = form[i];
|
||||
if(input.name) {
|
||||
formData[input.name] = input.value;
|
||||
var formData = {};
|
||||
for(var y = 0, yy = this.length; y < yy; y++) {
|
||||
var input = this[y];
|
||||
if(input.name) {
|
||||
formData[input.name] = input.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
formData['redirect'] = 'ePanel.html';
|
||||
console.log(formData); //debugging
|
||||
console.log(form.action);
|
||||
console.log(formData); //debugging
|
||||
console.log(this.action);
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(form.method, form.action, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
|
||||
xhr.send(JSON.stringify(formData));
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open(this.method, this.action, true);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
|
||||
xhr.send(JSON.stringify(formData));
|
||||
|
||||
xhr.onloadend = function() {
|
||||
console.log(xhr.status);
|
||||
xhr.onloadend = function() {
|
||||
console.log(xhr.response)
|
||||
console.log(xhr.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ func HandleAPI(path string, res http.ResponseWriter, req *http.Request) (bool, b
|
|||
|
||||
switch suspectApi {
|
||||
case "authentication":
|
||||
return true, Authentication(res, req)
|
||||
return true, UserAuthentication(res, req)
|
||||
case "registration":
|
||||
return true, UserRegistration(res, req)
|
||||
default:
|
||||
return false, false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
// Package api handles all API calls
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// auth struct is the structure of the JSON data to be retrieved from
|
||||
// the authentication API request
|
||||
var auth struct {
|
||||
User string `json:"user"`
|
||||
Pass string `json:"pass"`
|
||||
}
|
||||
|
||||
// Authentication function is accessed by an API call from the webhost root
|
||||
// by accessing /authentication and sending it a post request with
|
||||
func Authentication(res http.ResponseWriter, req *http.Request) bool {
|
||||
if req.Method != "POST" {
|
||||
http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed)
|
||||
return false
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&auth)
|
||||
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
} else {
|
||||
|
||||
if auth.User == "root" && auth.Pass == "root" {
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
} else {
|
||||
http.Error(res, "Authentication failed", http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
96
pkg/api/user.go
Normal file
96
pkg/api/user.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
// Package api handles all API calls
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/database"
|
||||
)
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// UserAuthentication function is accessed by an API call from the webhost root
|
||||
// by accessing /authentication and sending it a post request with
|
||||
func UserAuthentication(res http.ResponseWriter, req *http.Request) bool {
|
||||
if req.Method != "POST" {
|
||||
http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed)
|
||||
return false
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&userRequestData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
ds, err := database.Open(database.DBLOC_MAIN)
|
||||
if err != nil || ds == nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
defer ds.Close()
|
||||
|
||||
err = ds.Get(database.BUCKET_USERS, []byte(userRequestData.User), &userDatabaseData)
|
||||
|
||||
if err == database.ErrKeyNotExist {
|
||||
http.Error(res, "User does not exist in database", http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
if userRequestData.Pass != userDatabaseData.Pass {
|
||||
http.Error(res, "Invalid password", http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// UserAuthentication function is accessed by an API call from the webhost root
|
||||
// by accessing /authentication and sending it a post request with
|
||||
func UserRegistration(res http.ResponseWriter, req *http.Request) bool {
|
||||
if req.Method != "POST" {
|
||||
http.Error(res, req.Method+" HTTP method is unsupported for this API.", http.StatusMethodNotAllowed)
|
||||
return false
|
||||
}
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&userRequestData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
} else if len(userRequestData.User) == 0 || len(userRequestData.Pass) == 0 {
|
||||
http.Error(res, "Username or password field cannot be blank", http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
ds, err := database.Open(database.DBLOC_MAIN)
|
||||
if err != nil || ds == nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
defer ds.Close()
|
||||
|
||||
userDatabaseData.Pass = userRequestData.Pass
|
||||
err = ds.Put(database.BUCKET_USERS, []byte(userRequestData.User), userDatabaseData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
|
||||
}
|
||||
|
|
@ -2,16 +2,103 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"log"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
)
|
||||
|
||||
func init() {
|
||||
db, err := bolt.Open("test.db", 0600, &bolt.Options{Timeout: 5 * time.Second})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
// Database constants
|
||||
const (
|
||||
DBLOC_MAIN string = "datastore.db"
|
||||
)
|
||||
|
||||
// Bucket constants
|
||||
const (
|
||||
BUCKET_USERS string = "users"
|
||||
)
|
||||
|
||||
// Error codes
|
||||
var (
|
||||
ErrKeyNotExist error = errors.New("key does not exist")
|
||||
)
|
||||
|
||||
type Datastore struct {
|
||||
handle *bolt.DB
|
||||
}
|
||||
|
||||
// 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})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds := &Datastore{
|
||||
handle: db,
|
||||
}
|
||||
|
||||
// Ensure that all top-level buckets exist
|
||||
err = ds.handle.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists([]byte(BUCKET_USERS))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
// Close is a function attached to the Datastore struct that will close the current bolt instance
|
||||
func (ds *Datastore) Close() error {
|
||||
return ds.handle.Close()
|
||||
}
|
||||
|
||||
// Get is a function attached to the Datastore struct that will get data from the current bolt instance
|
||||
func (ds *Datastore) Get(bucket string, key []byte, result interface{}) error {
|
||||
return ds.handle.View(func(tx *bolt.Tx) error {
|
||||
dsValue := tx.Bucket([]byte(bucket)).Get(key)
|
||||
|
||||
if dsValue == nil {
|
||||
return ErrKeyNotExist
|
||||
}
|
||||
|
||||
return json.Unmarshal(dsValue, result)
|
||||
})
|
||||
}
|
||||
|
||||
// Put is a function attached to the Datastore struct that will put data into the current bolt instance
|
||||
func (ds *Datastore) Put(bucket string, key []byte, value interface{}) error {
|
||||
var err error
|
||||
dsValue, ok := value.([]byte)
|
||||
|
||||
if !ok {
|
||||
dsValue, err = json.Marshal(value)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ds.handle.Update(func(tx *bolt.Tx) error {
|
||||
return tx.Bucket([]byte(bucket)).Put(key, dsValue)
|
||||
})
|
||||
}
|
||||
|
||||
// Delete is a function attached to the Datastore struct that will delete data from the current bolt instance
|
||||
func (ds *Datastore) Delete(bucket string, key []byte) error {
|
||||
return ds.handle.Update(func(tx *bolt.Tx) error {
|
||||
return tx.Bucket([]byte(bucket)).Delete(key)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue