can create users with passwords

master
Jordan Orelli 5 years ago
parent 5674955902
commit 01b6315b99

@ -0,0 +1,5 @@
package db
type DB struct {
Users
}

@ -0,0 +1,55 @@
package db
import (
"database/sql"
"fmt"
"os"
_ "github.com/mattn/go-sqlite3"
"golang.org/x/crypto/bcrypt"
)
type SQLite struct {
db *sql.DB
}
func OpenSQLite(path string) (*SQLite, error) {
db, err := sql.Open("sqlite3", path)
if err != nil {
return nil, fmt.Errorf("unable to open sqlite3 database at %s: %v", path, err)
}
if _, err := db.Exec(`
create table if not exists users (
id integer primary key autoincrement,
name text unique not null,
phash text not null,
psalt text not null
);`); err != nil {
fmt.Fprintf(os.Stderr, "failed to create users table: %v\n", err)
}
return &SQLite{db: db}, nil
}
func (db *SQLite) CreateUser(name, pass, salt string) error {
combined := []byte(pass + salt)
hashBytes, err := bcrypt.GenerateFromPassword(combined, 13)
if err != nil {
return fmt.Errorf("unable to generate password hash: %v", err)
}
hash := string(hashBytes)
if _, err := db.db.Exec(`
insert into users (name, phash, psalt)
values (?, ?, ?);
`, name, hash, salt); err != nil {
return fmt.Errorf("unable to insert user: %v", err)
}
return nil
}
func (db *SQLite) CheckPassword(name, pass string) error {
return nil
}
func (db *SQLite) Close() error { return db.db.Close() }

@ -0,0 +1,6 @@
package db
type Users interface {
CreateUser(name, pass string) error
CheckPassword(name, pass string) error
}

@ -6,6 +6,8 @@ require (
github.com/gorilla/mux v1.7.3
github.com/gorilla/websocket v1.4.1
github.com/jordanorelli/blammo v0.0.0-20200201231725-9fd70eb7c1f2
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/prometheus/common v0.4.0
github.com/spf13/cobra v0.0.6
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad // indirect
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad
)

@ -1,7 +1,9 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -57,6 +59,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
@ -70,6 +74,7 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@ -77,6 +82,7 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@ -100,6 +106,7 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@ -118,6 +125,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -128,6 +136,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

@ -1,48 +1,110 @@
package main
import (
"crypto/rand"
"fmt"
"net"
"net/http"
"os"
"github.com/jordanorelli/blammo"
"github.com/jordanorelli/kloam/db"
"github.com/spf13/cobra"
)
func cryptostring(n int) string {
b := make([]byte, n)
rand.Read(b)
letters := `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%*-=+`
r := make([]byte, 0, n)
for _, n := range b {
r = append(r, letters[int(n)%len(letters)])
}
return string(r)
}
func runServer(cmd *cobra.Command, args []string) {
stdout := blammo.NewLineWriter(os.Stdout)
stderr := blammo.NewLineWriter(os.Stderr)
log := blammo.NewLog("kloam", blammo.DebugWriter(stdout), blammo.InfoWriter(stdout), blammo.ErrorWriter(stderr))
conn, err := db.OpenSQLite(cmd.Flag("db").Value.String())
if err != nil {
log.Error("unable to open sqlite database: %v", err)
os.Exit(1)
}
defer conn.Close()
s := server{
Log: log,
db: conn,
join: make(chan player),
leave: make(chan *player),
inbox: make(chan message),
souls: make(map[string]soul),
}
s.init()
go s.run()
lis, err := net.Listen("tcp", cmd.Flag("listen").Value.String())
if err != nil {
log.Error("listen error: %v", err)
return
}
log.Info("listening on %v", lis.Addr())
http.Serve(lis, s.handler())
}
func runUserCreate(cmd *cobra.Command, args []string) {
conn, err := db.OpenSQLite(cmd.Flag("db").Value.String())
if err != nil {
fmt.Fprintf(os.Stderr, "unable to open sqlite database: %v\n", err)
}
defer conn.Close()
user := args[0]
var pass string
if len(args) > 1 {
pass = args[1]
} else {
pass = cryptostring(12)
}
salt := cryptostring(12)
if err := conn.CreateUser(user, pass, salt); err != nil {
fmt.Fprintf(os.Stderr, "failed to create user: %v\n", err)
return
}
fmt.Printf("created:\n\tuser:\t%s\n\tpass:\t%s\n", user, pass)
}
func main() {
cmd := &cobra.Command{
Use: "kloam",
}
cmd.PersistentFlags().String("db", "./kloam.sqlite3", "path to a sqlite3 file to use as a database")
server := &cobra.Command{
Use: "server",
Short: "the kloam multiplayer server",
Run: func(cmd *cobra.Command, args []string) {
stdout := blammo.NewLineWriter(os.Stdout)
stderr := blammo.NewLineWriter(os.Stderr)
log := blammo.NewLog("kloam", blammo.DebugWriter(stdout), blammo.InfoWriter(stdout), blammo.ErrorWriter(stderr))
s := server{
Log: log,
join: make(chan player),
leave: make(chan *player),
inbox: make(chan message),
souls: make(map[string]soul),
}
s.init()
go s.run()
lis, err := net.Listen("tcp", cmd.Flag("listen").Value.String())
if err != nil {
log.Error("listen error: %v", err)
return
}
log.Info("listening on %v", lis.Addr())
http.Serve(lis, s.handler())
},
Run: runServer,
}
server.Flags().StringP("listen", "l", "0.0.0.0:9001", "ip:port to listen on")
cmd.AddCommand(server)
cmd.Execute()
user := &cobra.Command{
Use: "user",
Short: "user management stuff",
}
cmd.AddCommand(user)
userCreate := &cobra.Command{
Use: "create",
Short: "create a user",
Args: cobra.RangeArgs(1, 2),
Run: runUserCreate,
}
user.AddCommand(userCreate)
cmd.Execute()
}

@ -69,7 +69,11 @@ type login struct {
}
func (l *login) exec(s *server, from *player) {
from.username = l.Username
if err := s.db.CheckPassword(l.Username, l.Password); err != nil {
from.username = l.Username
} else {
}
}
type death struct {

@ -9,6 +9,7 @@ import (
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/jordanorelli/blammo"
"github.com/jordanorelli/kloam/db"
)
type server struct {
@ -19,6 +20,7 @@ type server struct {
leave chan *player
inbox chan message
souls map[string]soul
db *db.SQLite
}
func (s *server) init() {

Loading…
Cancel
Save