Skip to content

Commit

Permalink
change: refactor and lint code (#2)
Browse files Browse the repository at this point in the history
* change (build): remove vendor

+ remove vendor directory
+ use go mod instead
+ reduce code base in repository

* chore (lint): fix lint warnings

* change (keyvalue): refactor keyvalue package

+ create unittest
+ change some error handling in keyvalue package

* change (git): update .gitignore
  • Loading branch information
khangnkn authored Oct 19, 2020
1 parent 8fc87e2 commit d6d984d
Show file tree
Hide file tree
Showing 579 changed files with 211 additions and 450,398 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/zalopay-oss/tokeny
go 1.14

require (
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/atotto/clipboard v0.1.2
github.com/golang/mock v1.4.4
github.com/manifoldco/promptui v0.7.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
Expand Down
7 changes: 4 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package main

import (
"fmt"
"log"
"os"
"os/user"

"github.com/urfave/cli/v2"
"github.com/zalopay-oss/tokeny/pkg/keyvalue"
"github.com/zalopay-oss/tokeny/pkg/password"
"github.com/zalopay-oss/tokeny/pkg/session"
"github.com/zalopay-oss/tokeny/pkg/tokeny"
"github.com/zalopay-oss/tokeny/pkg/tokenycli"
"log"
"os"
"os/user"
)

func main() {
Expand Down
7 changes: 6 additions & 1 deletion pkg/crypto/utils.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
// nolint: gosec
package crypto

import (
"crypto/hmac"
"crypto/sha1"
"log"
)

func ComputeHMACSHA1(key []byte, data []byte) []byte {
h := hmac.New(sha1.New, key)
h.Write(data)
_, err := h.Write(data)
if err != nil {
log.Fatalln(err)
}
return h.Sum(nil)
}
18 changes: 14 additions & 4 deletions pkg/hotp/hotp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ package hotp
import (
"encoding/binary"
"fmt"
"math"

"github.com/zalopay-oss/tokeny/pkg/crypto"
"github.com/zalopay-oss/tokeny/pkg/utils"
"math"
)

func Generate(key []byte, counter []byte, otpLength int) string {
hash := crypto.ComputeHMACSHA1(key, counter)
offset := hash[19] & 0xf
truncatedHash := hash[offset : offset+4]
truncatedHash[0] = truncatedHash[0] & 0x7f
truncatedHash := truncate(hash)
hNum := binary.BigEndian.Uint32(truncatedHash)
otp := hNum % (uint32)(math.Pow10(otpLength))
result := utils.Padding0(fmt.Sprint(otp), otpLength)
return result
}

func truncate(hash []byte) []byte {
var (
last4BitFilter byte = 0xf
firstBitFilter byte = 0x7f
)
offset := hash[19] & last4BitFilter
truncatedHash := hash[offset : offset+4]
truncatedHash[0] &= firstBitFilter
return truncatedHash
}
68 changes: 43 additions & 25 deletions pkg/keyvalue/sqlStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package keyvalue

import (
"database/sql"
"log"

_ "github.com/mattn/go-sqlite3"
"github.com/pkg/errors"
"log"
)

const (
Expand Down Expand Up @@ -36,13 +37,6 @@ func (s *sqlStore) ensureTable() error {
return err
}

func (s *sqlStore) logErr(err error) {
if err == nil {
return
}
log.Printf("%q", err)
}

func (s *sqlStore) Set(key string, value string) error {
exist, err := s.exist(key)
if err != nil {
Expand Down Expand Up @@ -76,12 +70,19 @@ func (s *sqlStore) Get(key string) (string, error) {
return "", err
}

defer func() {
err := stmt.Close()
if err != nil {
log.Fatalln(err)
}
}()

var value string
err = stmt.QueryRow(key).Scan(&value)
if errors.Is(err, sql.ErrNoRows) {
return "", ErrNoRecord
}
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return "", ErrNoRecord
}
return "", err
}

Expand All @@ -94,46 +95,63 @@ func (s *sqlStore) Delete(key string) error {
return err
}

var value string
err = stmt.QueryRow(key).Scan(&value)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ErrNoRecord
defer func() {
err := stmt.Close()
if err != nil {
log.Fatalln(err)
}
}()

err = stmt.QueryRow(key).Err()
if errors.Is(err, sql.ErrNoRows) {
return ErrNoRecord
}
if err != nil {
return err
}

_, err = s.db.Exec(_deleteSQL, key)
if err != nil {
if _, err := s.db.Exec(_deleteSQL, key); err != nil {
return err
}
return nil
}

func (s *sqlStore) GetAllWithPrefixed(keyPrefix string) ([]KeyValue, error) {
stmt, err := s.db.Prepare(_allPrefixedSQL)
defer func() {
err := stmt.Close()
if err != nil {
log.Fatalln(err)
}
}()
if err != nil {
return nil, err
}

result := make([]KeyValue, 0)

r, err := stmt.Query(keyPrefix + "%")
rows, err := stmt.Query(keyPrefix + "%")
if err != nil {
return nil, err
}
defer r.Close()

for r.Next() {
defer func() {
if rows.Err() != nil {
log.Fatalln(rows.Err())
}
err := rows.Close()
if err != nil {
log.Fatalln(err)
}
}()

for rows.Next() {
var k, v string
err = r.Scan(&k, &v)
err = rows.Scan(&k, &v)
if err != nil {
return nil, err
}
result = append(result, KeyValue{Key: k, Value: v})
}
if err := r.Err(); err != nil {
return nil, err
}
return result, nil
}
117 changes: 117 additions & 0 deletions pkg/keyvalue/sqlStore_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package keyvalue

import (
"database/sql"
"testing"

"github.com/DATA-DOG/go-sqlmock"
_ "github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/suite"
)

type sqlStoreTestSuite struct {
suite.Suite
sqlDB *sql.DB
mock sqlmock.Sqlmock
}

func (s *sqlStoreTestSuite) SetupTest() {
conn, mock, err := sqlmock.New(
sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual),
)
if err != nil {
s.Fail("error creating db connection", err)
}
s.sqlDB = conn
s.mock = mock
}

func (s *sqlStoreTestSuite) TearDownTest() {
s.mock.ExpectClose()
err := s.sqlDB.Close()
if err != nil {
s.Fail("error closing db connection", err)
}
if err := s.mock.ExpectationsWereMet(); err != nil {
s.Fail("all expectation were not met", err)
}
}

func (s *sqlStoreTestSuite) TestGetSuccessfully() {
key := "foo"
expected := "bar"
s.mock.ExpectPrepare(_selectSQL).
ExpectQuery().
WithArgs(key).
WillReturnRows(sqlmock.NewRows([]string{"v"}).AddRow(expected))

// Do test
store := &sqlStore{s.sqlDB}
result, err := store.Get(key)
s.NoError(err)
s.Equal(expected, result, "expect result = %s", expected)
if err := s.mock.ExpectationsWereMet(); err != nil {
s.Fail("all expectation were not met", err)
}

}
func (s *sqlStoreTestSuite) TestGetEmptyKey() {
key := "foo"
s.mock.ExpectPrepare(_selectSQL).
ExpectQuery().
WithArgs(key).
WillReturnError(sql.ErrNoRows)

// Do test
store := &sqlStore{s.sqlDB}
result, err := store.Get(key)
s.EqualError(err, ErrNoRecord.Error())
s.Empty(result)
if err := s.mock.ExpectationsWereMet(); err != nil {
s.Fail("all expectation were not met", err)
}

}

func (s *sqlStoreTestSuite) TestDeleteSuccessfully() {
key := "foo"
s.mock.ExpectPrepare(_selectSQL).
ExpectQuery().
WithArgs(key).
WillReturnRows(
sqlmock.NewRows([]string{"k", "v"}).
AddRow(key, "bar"),
)
s.mock.ExpectExec(_deleteSQL).
WithArgs(key).
WillReturnResult(sqlmock.NewResult(1, 1))

// Do test
store := &sqlStore{s.sqlDB}
err := store.Delete(key)
s.NoError(err)
if err := s.mock.ExpectationsWereMet(); err != nil {
s.Fail("all expectation were not met", err)
}

}
func (s *sqlStoreTestSuite) TestDeleteEmptyKey() {
key := "foo"
s.mock.ExpectPrepare(_selectSQL).
ExpectQuery().
WithArgs(key).
WillReturnError(sql.ErrNoRows)

// Do test
store := &sqlStore{s.sqlDB}
err := store.Delete(key)
s.EqualError(err, ErrNoRecord.Error())
if err := s.mock.ExpectationsWereMet(); err != nil {
s.Fail("all expectation were not met", err)
}

}

func TestSqlStore(t *testing.T) {
suite.Run(t, new(sqlStoreTestSuite))
}
4 changes: 2 additions & 2 deletions pkg/password/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import "github.com/pkg/errors"

var (
ErrPasswordsMismatch = errors.New("passwords do not match")
ErrNotRegistered = errors.New("have not registered yet")
ErrWrongPassword = errors.New("wrong password")
ErrNotRegistered = errors.New("have not registered yet")
ErrWrongPassword = errors.New("wrong password")
)
4 changes: 2 additions & 2 deletions pkg/password/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package password

import (
"encoding/hex"
"github.com/zalopay-oss/tokeny/pkg/keyvalue"

"github.com/pkg/errors"
"github.com/zalopay-oss/tokeny/pkg/keyvalue"
"golang.org/x/crypto/bcrypt"
)

Expand Down Expand Up @@ -75,4 +76,3 @@ func (m *manager) Login(pwd string) error {

return nil
}

3 changes: 2 additions & 1 deletion pkg/session/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package session
import (
"errors"
"fmt"
"github.com/zalopay-oss/tokeny/pkg/keyvalue"
"strconv"
"time"

"github.com/zalopay-oss/tokeny/pkg/keyvalue"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion pkg/tokeny/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package tokeny
import "github.com/pkg/errors"

var (
ErrNoEntryFound = errors.New("no entry found")
ErrNoEntryFound = errors.New("no entry found")
ErrEntryExistedBefore = errors.New("entry existed before")
)
7 changes: 4 additions & 3 deletions pkg/tokeny/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package tokeny

import (
"errors"
"github.com/zalopay-oss/tokeny/pkg/keyvalue"
"github.com/zalopay-oss/tokeny/pkg/totp"
"strings"
"unicode"

"github.com/zalopay-oss/tokeny/pkg/keyvalue"
"github.com/zalopay-oss/tokeny/pkg/totp"
)

const (
Expand Down Expand Up @@ -85,7 +86,7 @@ func (r *repository) List() ([]string, error) {
if err != nil {
return nil, err
}
result := make([]string, len(kvs), len(kvs))
result := make([]string, len(kvs))
for i, kv := range kvs {
result[i] = strings.TrimPrefix(kv.Key, entryKeyPrefix)
}
Expand Down
Loading

0 comments on commit d6d984d

Please sign in to comment.