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:
George Shaw 2017-10-26 14:50:25 -05:00
parent 48e6e5224b
commit d451bda6b5
6 changed files with 238 additions and 68 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
main
gpanel
datastore.db

View file

@ -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>

View file

@ -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
}

View file

@ -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
View 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
}

View file

@ -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)
})
}