Compare commits
3 Commits
48c50a5b7e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 125ce9c955 | |||
| 131f19deed | |||
| 2ac552e840 |
@@ -1,94 +1,9 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import "context"
|
||||||
"context"
|
|
||||||
"database/sql"
|
|
||||||
_ "embed"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
type DB interface {
|
||||||
"golang.org/x/crypto/bcrypt"
|
Setup() error
|
||||||
)
|
CheckLogin(ctx context.Context, username, password string) (bool, error)
|
||||||
|
AddUser(ctx context.Context, username, password string) error
|
||||||
//go:embed setup.sql
|
|
||||||
var setupSql string
|
|
||||||
|
|
||||||
const DB_NAME = "s3Browser"
|
|
||||||
|
|
||||||
type DB struct {
|
|
||||||
dbConn *sql.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDB(dataSourceName string) (*DB, error) {
|
|
||||||
db, err := sql.Open("mysql", dataSourceName)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
db.SetConnMaxLifetime(time.Minute * 3)
|
|
||||||
db.SetMaxOpenConns(10)
|
|
||||||
db.SetMaxIdleConns(10)
|
|
||||||
|
|
||||||
return &DB{
|
|
||||||
dbConn: db,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DB) Setup() error {
|
|
||||||
tx, err := d.dbConn.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = tx.Exec(setupSql)
|
|
||||||
if err != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DB) CheckLogin(ctx context.Context, username, password string) (bool, error) {
|
|
||||||
rows, err := d.dbConn.QueryContext(ctx, "SELECT password FROM user WHERE username = ?", username)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !rows.Next() {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var passwordHash []byte
|
|
||||||
err = rows.Scan(&passwordHash)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if bcrypt.CompareHashAndPassword(passwordHash, []byte(password)) != nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DB) AddUser(ctx context.Context, username, password string) error {
|
|
||||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = d.dbConn.ExecContext(ctx, "INSERT INTO user (username,password) VALUES (?,?)", username, hash)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
94
internal/db/mysql.go
Normal file
94
internal/db/mysql.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
_ "embed"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed setup.sql
|
||||||
|
var setupSql string
|
||||||
|
|
||||||
|
const DB_NAME = "s3Browser"
|
||||||
|
|
||||||
|
type mysqlDB struct {
|
||||||
|
dbConn *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDB(dataSourceName string) (DB, error) {
|
||||||
|
db, err := sql.Open("mysql", dataSourceName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
db.SetConnMaxLifetime(time.Minute * 3)
|
||||||
|
db.SetMaxOpenConns(10)
|
||||||
|
db.SetMaxIdleConns(10)
|
||||||
|
|
||||||
|
return &mysqlDB{
|
||||||
|
dbConn: db,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *mysqlDB) Setup() error {
|
||||||
|
tx, err := d.dbConn.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.Exec(setupSql)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *mysqlDB) CheckLogin(ctx context.Context, username, password string) (bool, error) {
|
||||||
|
rows, err := d.dbConn.QueryContext(ctx, "SELECT password FROM user WHERE username = ?", username)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rows.Next() {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var passwordHash []byte
|
||||||
|
err = rows.Scan(&passwordHash)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if bcrypt.CompareHashAndPassword(passwordHash, []byte(password)) != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *mysqlDB) AddUser(ctx context.Context, username, password string) error {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = d.dbConn.ExecContext(ctx, "INSERT INTO user (username,password) VALUES (?,?)", username, hash)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
75
internal/gql/gql_test.go
Normal file
75
internal/gql/gql_test.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package gql_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.kapelle.org/niklas/s3browser/internal/gql"
|
||||||
|
"git.kapelle.org/niklas/s3browser/internal/loader"
|
||||||
|
"git.kapelle.org/niklas/s3browser/internal/s3"
|
||||||
|
"github.com/graph-gophers/dataloader"
|
||||||
|
"github.com/graphql-go/graphql"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setup(t *testing.T) (*assert.Assertions, context.Context, graphql.Schema) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
schema, _ := gql.GraphqlSchema()
|
||||||
|
|
||||||
|
s3, err := s3.NewMockS3([]string{"bucket1"})
|
||||||
|
assert.NoError(err)
|
||||||
|
ctx = context.WithValue(ctx, "s3Client", s3)
|
||||||
|
|
||||||
|
loader := loader.NewLoader(loader.CacheConfig{
|
||||||
|
ListObjectsLoaderCache: &dataloader.NoCache{},
|
||||||
|
ListObjectsRecursiveLoaderCache: &dataloader.NoCache{},
|
||||||
|
StatObjectLoaderCache: &dataloader.NoCache{},
|
||||||
|
ListBucketsLoaderCache: &dataloader.NoCache{},
|
||||||
|
})
|
||||||
|
assert.NotNil(loader)
|
||||||
|
ctx = context.WithValue(ctx, "loader", loader)
|
||||||
|
|
||||||
|
return assert, ctx, schema
|
||||||
|
}
|
||||||
|
|
||||||
|
func do(ctx context.Context, schema graphql.Schema, query string) *graphql.Result {
|
||||||
|
params := graphql.Params{
|
||||||
|
Schema: schema,
|
||||||
|
RequestString: query,
|
||||||
|
Context: ctx,
|
||||||
|
}
|
||||||
|
r := graphql.Do(params)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateSchema(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
assert.NotPanics(func() {
|
||||||
|
gql.GraphqlTypes()
|
||||||
|
})
|
||||||
|
|
||||||
|
var schema graphql.Schema
|
||||||
|
var err error
|
||||||
|
|
||||||
|
assert.NotPanics(func() {
|
||||||
|
schema, err = gql.GraphqlSchema()
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(schema)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAuth(t *testing.T) {
|
||||||
|
assert, ctx, schema := setup(t)
|
||||||
|
|
||||||
|
r := do(ctx, schema, `
|
||||||
|
{
|
||||||
|
authorized
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
t.Logf("Data: %v", r.Data)
|
||||||
|
assert.Len(r.Errors, 0)
|
||||||
|
}
|
||||||
@@ -222,7 +222,7 @@ func deleteDirectory(ctx context.Context, id types.ID) error {
|
|||||||
//login Checks for valid username password combination. Returns singed jwt string
|
//login Checks for valid username password combination. Returns singed jwt string
|
||||||
func login(ctx context.Context, username, password string) (types.LoginResult, error) {
|
func login(ctx context.Context, username, password string) (types.LoginResult, error) {
|
||||||
|
|
||||||
dbStore := ctx.Value("dbStore").(*db.DB)
|
dbStore := ctx.Value("dbStore").(db.DB)
|
||||||
|
|
||||||
succes, err := dbStore.CheckLogin(ctx, username, password)
|
succes, err := dbStore.CheckLogin(ctx, username, password)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user