mirror of
https://github.com/aunefyren/wrapperr
synced 2024-11-10 13:44:12 +00:00
1a7c66c4b4
Basic Auth on front end Switched to GIN for http routing Reworked middleware
175 lines
4.7 KiB
Go
175 lines
4.7 KiB
Go
package utilities
|
|
|
|
import (
|
|
"aunefyren/wrapperr/models"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"math/big"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/kardianos/osext"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func decodeBase64BigInt(s string) *big.Int {
|
|
buffer, err := base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(s)
|
|
if err != nil {
|
|
log.Fatalf("failed to decode base64: %v", err)
|
|
}
|
|
|
|
return big.NewInt(0).SetBytes(buffer)
|
|
}
|
|
|
|
func checkScopes(requiredScopes []string, providedScopes string) bool {
|
|
|
|
for _, value := range requiredScopes {
|
|
if !strings.Contains(providedScopes, value) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func HashAndSalt(pwd_string string) (string, error) {
|
|
|
|
pwd := []byte(pwd_string)
|
|
|
|
// Use GenerateFromPassword to hash & salt pwd.
|
|
// MinCost is just an integer constant provided by the bcrypt
|
|
// package along with DefaultCost & MaxCost.
|
|
// The cost can be any value you want provided it isn't lower
|
|
// than the MinCost (4)
|
|
hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
// GenerateFromPassword returns a byte slice so we need to
|
|
// convert the bytes to a string and return it
|
|
return string(hash), nil
|
|
}
|
|
|
|
func ComparePasswords(hashedPwd string, pwd string) bool {
|
|
// Since we'll be getting the hashed password from the DB it
|
|
// will be a string so we'll need to convert it to a byte slice
|
|
plainPwd := []byte(pwd)
|
|
|
|
byteHash := []byte(hashedPwd)
|
|
err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func RestartSelf() error {
|
|
self, err := osext.Executable()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := os.Args
|
|
env := os.Environ()
|
|
// Windows does not support exec syscall.
|
|
if runtime.GOOS == "windows" {
|
|
cmd := exec.Command(self, args[1:]...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdin = os.Stdin
|
|
cmd.Env = env
|
|
err := cmd.Run()
|
|
if err == nil {
|
|
os.Exit(0)
|
|
}
|
|
return err
|
|
}
|
|
return syscall.Exec(self, args, env)
|
|
}
|
|
|
|
func GetOriginIPString(context *gin.Context) (stringReply string) {
|
|
ip := context.ClientIP()
|
|
stringReply = " - Origin: " + string(ip) + " "
|
|
return
|
|
}
|
|
|
|
func BuildURL(port int, domain_ip string, https bool, url_base string) (string, error) {
|
|
|
|
var url string = ""
|
|
|
|
if https {
|
|
url = url + "https://"
|
|
} else {
|
|
url = url + "http://"
|
|
}
|
|
|
|
domain_ip = strings.TrimPrefix(domain_ip, "http://")
|
|
domain_ip = strings.TrimPrefix(domain_ip, "https://")
|
|
|
|
url = url + domain_ip
|
|
|
|
if !(https && port == 443) && !(!https && port == 80) {
|
|
url = url + ":" + strconv.Itoa(port)
|
|
}
|
|
|
|
if url_base != "" {
|
|
|
|
url_base = strings.TrimPrefix(url_base, "/")
|
|
url_base = strings.TrimSuffix(url_base, "/")
|
|
|
|
url = url + "/" + url_base + "/"
|
|
|
|
} else {
|
|
|
|
url = strings.TrimPrefix(url, "/")
|
|
url = url + "/"
|
|
|
|
}
|
|
|
|
return url, nil
|
|
}
|
|
|
|
func PrintASCII() {
|
|
fmt.Println(``)
|
|
fmt.Println(` ___ __ ________ ________ ________ ________ _______ ________ ________ `)
|
|
fmt.Println(`|\ \ |\ \ |\ __ \ |\ __ \ |\ __ \ |\ __ \ |\ ___ \ |\ __ \ |\ __ \ `)
|
|
fmt.Println(`\ \ \ \ \ \\ \ \|\ \\ \ \|\ \\ \ \|\ \\ \ \|\ \\ \ __/| \ \ \|\ \\ \ \|\ \ `)
|
|
fmt.Println(` \ \ \ __\ \ \\ \ _ _\\ \ __ \\ \ ____\\ \ ____\\ \ \_|/__\ \ _ _\\ \ _ _\ `)
|
|
fmt.Println(` \ \ \|\__\_\ \\ \ \\ \|\ \ \ \ \\ \ \___| \ \ \___| \ \ \_|\ \\ \ \\ \|\ \ \\ \| `)
|
|
fmt.Println(` \ \____________\\ \__\\ _\ \ \__\ \__\\ \__\ \ \__\ \ \_______\\ \__\\ _\ \ \__\\ _\ `)
|
|
fmt.Println(` \|____________| \|__|\|__| \|__|\|__| \|__| \|__| \|_______| \|__|\|__| \|__|\|__|`)
|
|
fmt.Println(` ____________ ____________ ____________ ____________ ____________ ____________ ____________ `)
|
|
fmt.Println(`|\____________\|\____________\|\____________\|\____________\|\____________\|\____________\|\____________\`)
|
|
fmt.Println(`\|____________|\|____________|\|____________|\|____________|\|____________|\|____________|\|____________|`)
|
|
fmt.Println(``)
|
|
}
|
|
|
|
func ValidateBasicAuth(context *gin.Context, adminConfig models.AdminConfig) (err error) {
|
|
err = nil
|
|
|
|
username, password, okay := context.Request.BasicAuth()
|
|
if !okay {
|
|
context.Writer.Header().Add("WWW-Authenticate", `Basic realm="Give username and password"`)
|
|
context.JSON(http.StatusUnauthorized, gin.H{"error": "No basic auth present."})
|
|
context.Abort()
|
|
return
|
|
}
|
|
|
|
// Hash new password
|
|
passwordValidity := ComparePasswords(adminConfig.AdminPassword, password)
|
|
|
|
// Validate admin username and password
|
|
if !passwordValidity || adminConfig.AdminUsername != username {
|
|
return errors.New("Invalid username or password.")
|
|
}
|
|
|
|
return
|
|
}
|