mirror of
https://github.com/donl/gPanel.git
synced 2026-05-25 22:06:55 -06:00
added jwt authentication
This commit is contained in:
parent
c55a3127c1
commit
3461ffaec2
12 changed files with 316 additions and 247 deletions
|
|
@ -1,99 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Private Test</title>
|
||||
<link rel="icon" type="image/x-icon" href="https://play.golang.org/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<form class="api_form" method="POST" action="user_auth">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">gPanel Login</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="Login"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<form class="api_form" method="POST" action="user_register">
|
||||
<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>
|
||||
|
||||
<form class="api_form" method="POST" action="user_logout">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">gPanel Logout</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2"><input type="submit" value="Logout"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
var form = document.getElementsByClassName('api_form');
|
||||
|
||||
for(var i = 0; i < form.length; i++) {
|
||||
form[i].onsubmit = 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;
|
||||
}
|
||||
}
|
||||
console.log(formData); //debugging
|
||||
console.log(this.action);
|
||||
|
||||
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.response)
|
||||
console.log(xhr.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -39,6 +39,9 @@
|
|||
<button type="button" class="btn btn-outline-primary">Forced Shutdown</button>
|
||||
<button type="button" class="btn btn-outline-primary">Restart</button>
|
||||
</div>
|
||||
<div class="card-footer text-muted text-center">
|
||||
Server Status: <span class="text-success">ON</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ package api
|
|||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/api/user"
|
||||
)
|
||||
|
||||
// HandleAPI function takes a path and determines if it is an API call, if it is it will
|
||||
|
|
@ -15,11 +17,11 @@ func HandleAPI(path string, res http.ResponseWriter, req *http.Request) (bool, b
|
|||
|
||||
switch suspectApi {
|
||||
case "user_auth":
|
||||
return true, UserAuthentication(res, req)
|
||||
return true, user.UserAuthentication(res, req)
|
||||
case "user_register":
|
||||
return true, UserRegistration(res, req)
|
||||
return true, user.UserRegistration(res, req)
|
||||
case "user_logout":
|
||||
return true, UserLogout(res, req)
|
||||
return true, user.UserLogout(res, req)
|
||||
default:
|
||||
return false, false
|
||||
}
|
||||
|
|
|
|||
139
pkg/api/user.go
139
pkg/api/user.go
|
|
@ -1,139 +0,0 @@
|
|||
// Package api handles all API calls
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/database"
|
||||
"github.com/Ennovar/gPanel/pkg/encryption"
|
||||
"github.com/Ennovar/gPanel/pkg/networking"
|
||||
)
|
||||
|
||||
// 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 /user_auth and sending it a post request with userRequestData
|
||||
// struct in JSON format.
|
||||
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.", http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
err = encryption.CheckPassword([]byte(userDatabaseData.Pass), []byte(userRequestData.Pass))
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
store := networking.GetStore(networking.COOKIES_USER_AUTH)
|
||||
err = store.Set(res, req, "auth", true, (60 * 60 * 24))
|
||||
|
||||
if err != nil {
|
||||
http.Error(res, http.StatusText(500), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
}
|
||||
|
||||
// UserRegistration 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 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()
|
||||
|
||||
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)
|
||||
return false
|
||||
}
|
||||
|
||||
userDatabaseData.Pass, err = encryption.HashPassword(userRequestData.Pass)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// UserRegistration 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 UserLogout(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
|
||||
}
|
||||
|
||||
store := networking.GetStore(networking.COOKIES_USER_AUTH)
|
||||
err := store.Delete(res, req)
|
||||
|
||||
if err != nil {
|
||||
http.Error(res, http.StatusText(500), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
}
|
||||
16
pkg/api/user/user.go
Normal file
16
pkg/api/user/user.go
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// 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"`
|
||||
}
|
||||
87
pkg/api/user/user_auth.go
Normal file
87
pkg/api/user/user_auth.go
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Package user is a child of package api to handle api calls concerning users
|
||||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/database"
|
||||
"github.com/Ennovar/gPanel/pkg/encryption"
|
||||
"github.com/Ennovar/gPanel/pkg/networking"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
// UserAuthentication 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 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.StatusInternalServerError)
|
||||
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.", http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
err = encryption.CheckPassword([]byte(userDatabaseData.Pass), []byte(userRequestData.Pass))
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusUnauthorized)
|
||||
return false
|
||||
}
|
||||
|
||||
secret, err := encryption.RandomString()
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
userDatabaseData.Secret = secret
|
||||
|
||||
err = ds.Put(database.BUCKET_USERS, []byte(userRequestData.User), userDatabaseData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
claims := jwt.StandardClaims{
|
||||
Subject: userRequestData.User,
|
||||
NotBefore: now.Unix(),
|
||||
IssuedAt: now.Unix(),
|
||||
ExpiresAt: now.Add(24 * time.Hour).Unix(),
|
||||
}
|
||||
|
||||
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret))
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
store := networking.GetStore(networking.COOKIES_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 {
|
||||
http.Error(res, http.StatusText(500), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
}
|
||||
29
pkg/api/user/user_logout.go
Normal file
29
pkg/api/user/user_logout.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// Package user is a child of package api to handle api calls concerning users
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/networking"
|
||||
)
|
||||
|
||||
// UserLogout 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 UserLogout(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
|
||||
}
|
||||
|
||||
store := networking.GetStore(networking.COOKIES_USER_AUTH)
|
||||
err := store.Delete(res, req)
|
||||
|
||||
if err != nil {
|
||||
http.Error(res, http.StatusText(500), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
}
|
||||
59
pkg/api/user/user_register.go
Normal file
59
pkg/api/user/user_register.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Package user is a child of package api to handle api calls concerning users
|
||||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/database"
|
||||
"github.com/Ennovar/gPanel/pkg/encryption"
|
||||
)
|
||||
|
||||
// UserRegistration 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 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.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
defer ds.Close()
|
||||
|
||||
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)
|
||||
return false
|
||||
}
|
||||
|
||||
userDatabaseData.Pass, err = encryption.HashPassword(userRequestData.Pass)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
userDatabaseData.Secret = ""
|
||||
|
||||
err = ds.Put(database.BUCKET_USERS, []byte(userRequestData.User), userDatabaseData)
|
||||
if err != nil {
|
||||
http.Error(res, err.Error(), http.StatusInternalServerError)
|
||||
return false
|
||||
}
|
||||
|
||||
res.WriteHeader(http.StatusNoContent)
|
||||
return true
|
||||
}
|
||||
21
pkg/api/user/user_token.go
Normal file
21
pkg/api/user/user_token.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Package user is a child of package api to handle api calls concerning users
|
||||
package user
|
||||
|
||||
import "github.com/Ennovar/gPanel/pkg/database"
|
||||
|
||||
// UserSecret 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 UserSecret(user string) (string, error) {
|
||||
ds, err := database.Open(database.DBLOC_MAIN)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = ds.Get(database.BUCKET_USERS, []byte(user), &userDatabaseData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return userDatabaseData.Secret, nil
|
||||
}
|
||||
19
pkg/encryption/random_string.go
Normal file
19
pkg/encryption/random_string.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Encryption package has functions inside of it that utilize various encypting and hashing techniques
|
||||
package encryption
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func RandomString() (string, error) {
|
||||
n := 5
|
||||
b := make([]byte, n)
|
||||
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
s := fmt.Sprintf("%X", b)
|
||||
return s, nil
|
||||
}
|
||||
|
|
@ -11,19 +11,26 @@ import (
|
|||
)
|
||||
|
||||
type PublicWeb struct {
|
||||
Directory string
|
||||
Directory string
|
||||
MaintenanceMode int
|
||||
}
|
||||
|
||||
// NewPublicWeb returns a new PublicWeb type.
|
||||
func NewPublicWeb() PublicWeb {
|
||||
return PublicWeb{
|
||||
Directory: "document_roots/public/",
|
||||
Directory: "document_roots/public/",
|
||||
MaintenanceMode: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (pub *PublicWeb) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if pub.MaintenanceMode == 1 {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
w.Write([]byte("We are currently in maintenance mode, please check back later."))
|
||||
}
|
||||
|
||||
path := req.URL.Path[1:]
|
||||
if len(path) == 0 {
|
||||
path = (pub.Directory + "index.html")
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/Ennovar/gPanel/pkg/api"
|
||||
"github.com/Ennovar/gPanel/pkg/api/user"
|
||||
"github.com/Ennovar/gPanel/pkg/logging"
|
||||
"github.com/Ennovar/gPanel/pkg/networking"
|
||||
"github.com/Ennovar/gPanel/pkg/routing"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type PrivateHost struct {
|
||||
|
|
@ -36,11 +38,10 @@ func reqAuth(path string) bool {
|
|||
}
|
||||
|
||||
dismissibleFiles := []string{
|
||||
"api_testing.html",
|
||||
"index.html",
|
||||
"user_auth",
|
||||
"user_register",
|
||||
"user_logut",
|
||||
"user_logout",
|
||||
}
|
||||
for _, f := range dismissibleFiles {
|
||||
if strings.HasSuffix(path, f) {
|
||||
|
|
@ -64,18 +65,81 @@ func (priv *PrivateHost) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
if reqAuth(path) {
|
||||
store := networking.GetStore(networking.COOKIES_USER_AUTH)
|
||||
|
||||
session_value, err := store.Read(w, req, "auth")
|
||||
session_value, err := store.Read(w, req, "user")
|
||||
if err != nil {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "1")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if session_value == nil {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "2")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
if auth, ok := session_value.(bool); !ok || !auth {
|
||||
username, ok := session_value.(string)
|
||||
if !ok {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "3")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
stored_secret, err := user.UserSecret(username)
|
||||
if stored_secret == "" {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "4")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
session_value, err = store.Read(w, req, "token")
|
||||
if err != nil {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "5")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if session_value == nil {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "6")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
tokenString, ok := session_value.(string)
|
||||
if !ok {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "7")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// if len(tokenString) < 7 {
|
||||
// logging.Console("DEBUG::", logging.NORMAL_LOG, "8")
|
||||
// http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
// return
|
||||
// }
|
||||
// tokenString = tokenString[7:]
|
||||
|
||||
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 {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, username)
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, tokenString)
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, stored_secret)
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
claims := t.Claims.(*jwt.StandardClaims)
|
||||
if claims.Subject != username {
|
||||
logging.Console("DEBUG::", logging.NORMAL_LOG, "10")
|
||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue