Automatically create admin user on first start

Also changed order that extractToken looks for tokens. Used to
be cookies then headers then query. Now in reverse, to make it
easier to override, ie for replacing cookies during login.
This commit is contained in:
Anders Pitman 2020-10-13 09:48:03 -06:00
parent 8d6e4c2fe8
commit 5cd911f310
5 changed files with 108 additions and 80 deletions

16
auth.go
View File

@ -1,8 +1,6 @@
package main
import (
"crypto/rand"
"math/big"
"sync"
)
@ -33,17 +31,3 @@ func (a *Auth) Authorized(token string) bool {
return false
}
const chars string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func genRandomKey() (string, error) {
id := ""
for i := 0; i < 32; i++ {
randIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
if err != nil {
return "", err
}
id += string(chars[randIndex.Int64()])
}
return id, nil
}

View File

@ -48,6 +48,17 @@ func Listen() {
log.Fatal(err)
}
users := db.GetUsers()
if len(users) == 0 {
db.AddUser("admin", true)
token, err := db.AddToken("admin")
if err != nil {
log.Fatal("Failed to initialize admin user")
}
log.Println("Admin token: " + token)
}
certmagic.DefaultACME.DisableHTTPChallenge = true
//certmagic.DefaultACME.DisableTLSALPNChallenge = true
//certmagic.DefaultACME.CA = certmagic.LetsEncryptStagingCA
@ -103,8 +114,6 @@ func Listen() {
func (p *BoringProxy) proxyRequest(w http.ResponseWriter, r *http.Request) {
log.Println("proxy conn")
port, err := p.tunMan.GetPort(r.Host)
if err != nil {
log.Print(err)

View File

@ -16,7 +16,7 @@ type Database struct {
}
type TokenData struct {
Id string `json:"id"`
Owner string `json:"owner"`
}
type User struct {
@ -71,6 +71,27 @@ func NewDatabase() (*Database, error) {
return db, nil
}
func (d *Database) AddToken(owner string) (string, error) {
d.mutex.Lock()
defer d.mutex.Unlock()
_, exists := d.Users[owner]
if !exists {
return "", errors.New("Owner doesn't exist")
}
token, err := genRandomCode(32)
if err != nil {
return "", errors.New("Could not generat token")
}
d.Tokens[token] = TokenData{owner}
d.persist()
return token, nil
}
func (d *Database) GetTokenData(token string) (TokenData, bool) {
d.mutex.Lock()
defer d.mutex.Unlock()

View File

@ -1,9 +1,11 @@
package main
import (
"crypto/rand"
"encoding/json"
"errors"
"io/ioutil"
"math/big"
"net/http"
"strings"
)
@ -21,26 +23,8 @@ func saveJson(data interface{}, filePath string) error {
return nil
}
// Looks for auth token in cookie, then header, then query string
// Looks for auth token in query string, then headers, then cookies
func extractToken(tokenName string, r *http.Request) (string, error) {
tokenCookie, err := r.Cookie(tokenName)
if err == nil {
return tokenCookie.Value, nil
}
tokenHeader := r.Header.Get(tokenName)
if tokenHeader != "" {
return tokenHeader, nil
}
authHeader := r.Header.Get("Authorization")
if authHeader != "" {
tokenHeader := strings.Split(authHeader, " ")[1]
return tokenHeader, nil
}
query := r.URL.Query()
@ -49,5 +33,35 @@ func extractToken(tokenName string, r *http.Request) (string, error) {
return queryToken, nil
}
tokenHeader := r.Header.Get(tokenName)
if tokenHeader != "" {
return tokenHeader, nil
}
authHeader := r.Header.Get("Authorization")
if authHeader != "" {
tokenHeader := strings.Split(authHeader, " ")[1]
return tokenHeader, nil
}
tokenCookie, err := r.Cookie(tokenName)
if err == nil {
return tokenCookie.Value, nil
}
return "", errors.New("No token found")
}
const chars string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func genRandomCode(length int) (string, error) {
id := ""
for i := 0; i < length; i++ {
randIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
if err != nil {
return "", err
}
id += string(chars[randIndex.Int64()])
}
return id, nil
}