Skip to content

Commit 8627b61

Browse files
committed
Finish support-jsondb, drop windows sqlite support; fix path handling
1 parent ea77dbd commit 8627b61

File tree

15 files changed

+256
-3010
lines changed

15 files changed

+256
-3010
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ build: vendoring
1515
CGO_ENABLED=1 go build -o bin/showqr $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' github.com/dafanasiev/OTPCredentialProvider-backend/app/showqr
1616

1717
build-win64: vendoring
18-
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -o bin/checkserver.exe $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' github.com/dafanasiev/OTPCredentialProvider-backend/app/checkserver
19-
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -o bin/showqr.exe $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' github.com/dafanasiev/OTPCredentialProvider-backend/app/showqr
18+
GOOS=windows GOARCH=amd64 go build -o bin/checkserver.exe $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' github.com/dafanasiev/OTPCredentialProvider-backend/app/checkserver
19+
GOOS=windows GOARCH=amd64 go build -o bin/showqr.exe $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' github.com/dafanasiev/OTPCredentialProvider-backend/app/showqr
2020

2121
clean:
2222
rm -rf bin/

app/checkserver/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"log"
66
"net"
77
"os"
8-
"path"
8+
"path/filepath"
99

1010
"google.golang.org/grpc"
1111
"google.golang.org/grpc/reflection"
@@ -23,7 +23,7 @@ func main() {
2323
if err != nil {
2424
log.Fatal("cant get current working directory")
2525
}
26-
pathResolver := shared.NewPathResolver(selfDir, path.Join(selfDir, "..", "data"), path.Join(selfDir, "..", "etc"))
26+
pathResolver := shared.NewPathResolver(selfDir, filepath.Join(selfDir, "..", "data"), filepath.Join(selfDir, "..", "etc"))
2727
configFileName := pathResolver.PathToAbs("${dir.config}/root.config")
2828

2929
config, err := configuration.NewAppConfig(configFileName)

app/checkserver/server.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func (s *server) Check(ctx context.Context, req *api.CheckRequest) (*api.CheckRe
8888
return nil, err
8989
}
9090

91-
user, err := s.db.FindTOTPUserOptions(req.Login)
91+
user, err := s.db.Find(req.Login)
9292
if err != nil {
9393
log.Printf("ERROR: unable to fetch user %s from db; error:%s", req.Login, err.Error())
9494
return nil, errors.New(CheckError_UnknownUser)
@@ -123,16 +123,16 @@ func (s *server) Check(ctx context.Context, req *api.CheckRequest) (*api.CheckRe
123123
}
124124

125125
func onAuthenticateLocked(user *entitites.TOTPUserOptions, db store.UsersDb) {
126-
err := db.UpdateUser(user.UserId, user.LockUntil, user.FailCount+1)
126+
err := db.Update(user.Login, user.LockUntil, user.FailCount+1)
127127
if err != nil {
128-
log.Printf("WARNING: cant update user %s with id %d; error:%s", user.Login, user.UserId, err.Error())
128+
log.Printf("WARNING: cant update user %s with login %s; error:%s", user.Login, user.Login, err.Error())
129129
}
130130
}
131131

132132
func onAuthenticateSuccess(user *entitites.TOTPUserOptions, db store.UsersDb) {
133-
err := db.UpdateUser(user.UserId, time.Unix(0, 0), 0)
133+
err := db.Update(user.Login, time.Unix(0, 0), 0)
134134
if err != nil {
135-
log.Printf("WARNING: cant update user %s with id %d; error:%s", user.Login, user.UserId, err.Error())
135+
log.Printf("WARNING: cant update user %s with login %s; error:%s", user.Login, user.Login, err.Error())
136136
}
137137
}
138138

@@ -146,13 +146,13 @@ func onAuthenticateFailed(user *entitites.TOTPUserOptions, db store.UsersDb) {
146146
case entitites.LockStrategyType_None:
147147
break
148148
case entitites.LockStrategyType_Simple:
149-
err := db.UpdateUser(user.UserId, newLockUntil, user.FailCount+1)
149+
err := db.Update(user.Login, newLockUntil, user.FailCount+1)
150150
if err != nil {
151-
log.Printf("WARNING: cant update user %s with id %d; error:%s", user.Login, user.UserId, err.Error())
151+
log.Printf("WARNING: cant update user %s with login %s; error:%s", user.Login, user.Login, err.Error())
152152
}
153153
break
154154
default:
155-
log.Printf("WARNING: unknown LockStrategy value [%d] for user %s with userId %d", user.LockStrategy, user.Login, user.UserId)
155+
log.Printf("WARNING: unknown LockStrategy value [%d] for user %s", user.LockStrategy, user.Login)
156156
break
157157
}
158158
}

app/showqr/main.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66

77
"bytes"
88
"image/png"
9-
"path"
9+
"path/filepath"
1010

1111
"github.com/dafanasiev/OTPCredentialProvider-backend/shared"
1212
"github.com/dafanasiev/OTPCredentialProvider-backend/shared/configuration"
@@ -35,7 +35,8 @@ func main() {
3535
if err != nil {
3636
log.Fatal("Cant get current working directory")
3737
}
38-
pathResolver := shared.NewPathResolver(selfDir, path.Join(selfDir, "..", "data"), path.Join(selfDir, "..", "etc"))
38+
39+
pathResolver := shared.NewPathResolver(selfDir, filepath.Join(selfDir, "..", "data"), filepath.Join(selfDir, "..", "etc"))
3940

4041
configFileName := pathResolver.PathToAbs("${dir.config}/root.config")
4142
config, err := configuration.NewAppConfig(configFileName)
@@ -56,7 +57,7 @@ func main() {
5657

5758
defer db.Close()
5859

59-
user, err := db.FindTOTPUserOptions(opts.Login)
60+
user, err := db.Find(opts.Login)
6061
if err != nil {
6162
log.Fatalf("unable to find Login %s in db die to error:%s", opts.Login, err.Error())
6263
}

etc/root.config

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
[server]
22
host = "127.0.0.1"
33
port = 11345
4-
apikey = "secret_api_key"
4+
apikey = "ebf225b4-8aed-4384-8b8e-3c2c0f72b3ef"
55

66
[db]
7-
type = "sqlite"
8-
connectionString = "${dir.data}/users.db"
7+
#type = "sqlite"
8+
#connectionString = "${dir.data}/users.db"
9+
10+
11+
type = "json"
12+
connectionString = "${dir.data}"

go.mod

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ go 1.13
55
require (
66
github.com/balasanjay/totp v0.0.0-20170916044655-9daf9d6ff090
77
github.com/golang/protobuf v1.3.2
8+
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect
89
github.com/jessevdk/go-flags v1.4.0
910
github.com/kr/pretty v0.1.0 // indirect
10-
github.com/mattn/go-sqlite3 v2.0.1+incompatible
11+
github.com/mattn/go-sqlite3 v2.0.2+incompatible
12+
github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975
1113
github.com/pelletier/go-toml v1.6.0
1214
github.com/pkg/errors v0.8.1
1315
github.com/qpliu/qrencode-go v0.0.0-20170225035013-ad8353b4581f // indirect
14-
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663
15-
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab // indirect
16+
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
17+
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 // indirect
1618
golang.org/x/text v0.3.2 // indirect
17-
google.golang.org/genproto v0.0.0-20191206224255-0243a4be9c8f // indirect
18-
google.golang.org/grpc v1.25.1
19+
google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f // indirect
20+
google.golang.org/grpc v1.26.0
1921
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
2022
gopkg.in/yaml.v2 v2.2.7 // indirect
2123
)

go.sum

+16-13
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,29 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
77
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
88
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
99
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10-
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
10+
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
1111
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
1212
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
1313
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
1414
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
1515
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
1616
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
1717
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
18+
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
1819
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
20+
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8=
21+
github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw=
1922
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
2023
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
2124
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
2225
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
2326
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
2427
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
2528
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
26-
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
27-
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
29+
github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U=
30+
github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
31+
github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975 h1:zm/Rb2OsnLWCY88Njoqgo4X6yt/lx3oBNWhepX0AOMU=
32+
github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975/go.mod h1:4Mct/lWCFf1jzQTTAaWtOI7sXqmG+wBeiBfT4CxoaJk=
2833
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
2934
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
3035
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@@ -41,17 +46,16 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
4146
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
4247
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
4348
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
44-
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663 h1:Dd5RoEW+yQi+9DMybroBctIdyiwuNT7sJFMC27/6KxI=
45-
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
49+
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
50+
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
4651
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
4752
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4853
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4954
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5055
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
51-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
5256
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
53-
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab h1:FvshnhkKW+LO3HWHodML8kuVX8rnJTxKm9dFPuI68UM=
54-
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
57+
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=
58+
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5559
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
5660
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
5761
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -64,13 +68,12 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
6468
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
6569
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
6670
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
67-
google.golang.org/genproto v0.0.0-20191206224255-0243a4be9c8f h1:naitw5DILWPQvG0oG04mR9jF8fmKpRdW3E3zzKA4D0Y=
68-
google.golang.org/genproto v0.0.0-20191206224255-0243a4be9c8f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
71+
google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f h1:2wh8dWY8959cBGQvk1RD+/eQBgRYYDaZ+hT0/zsARoA=
72+
google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
6973
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
7074
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
71-
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
72-
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
73-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
75+
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
76+
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
7477
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
7578
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
7679
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

shared/store/entitites/TOTPUserOptions.go

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const (
1313
)
1414

1515
type TOTPUserOptions struct{
16-
UserId int
1716
Login string
1817

1918
Time func() time.Time

shared/store/json/usersdb.go

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package json
2+
3+
import (
4+
"crypto/sha1"
5+
"crypto/sha256"
6+
"crypto/sha512"
7+
"encoding/hex"
8+
"fmt"
9+
"github.com/dafanasiev/OTPCredentialProvider-backend/shared"
10+
"github.com/dafanasiev/OTPCredentialProvider-backend/shared/store/entitites"
11+
scribble "github.com/nanobox-io/golang-scribble"
12+
"hash"
13+
"time"
14+
)
15+
16+
type usersDbJson struct {
17+
dbDir string
18+
db *scribble.Driver
19+
}
20+
21+
type userRow struct {
22+
Login string
23+
Tries []int64
24+
TimeStep int
25+
Digits uint8
26+
SecretKey string
27+
Hash int
28+
29+
LockStrategy entitites.LockStrategyType
30+
LockUntil string
31+
LockTimeout int
32+
33+
FailCountBeforeLock int
34+
FailCount int
35+
}
36+
37+
func (u *usersDbJson) Open() (err error) {
38+
u.db, err = scribble.New(u.dbDir, nil)
39+
return
40+
}
41+
42+
func (u *usersDbJson) Close() error {
43+
u.db = nil
44+
return nil
45+
}
46+
47+
func (u *usersDbJson) Flush() error {
48+
return nil
49+
}
50+
51+
func (u *usersDbJson) Find(login string) (*entitites.TOTPUserOptions, error) {
52+
if u.db == nil {
53+
return nil, fmt.Errorf("db not opened")
54+
}
55+
56+
row, hash, secret, err := findStored(u, login)
57+
if err != nil {
58+
return nil, err
59+
}
60+
61+
var lockUntil time.Time
62+
if row.LockUntil == "" {
63+
lockUntil = time.Unix(0, 0)
64+
} else {
65+
lockUntil, err = time.Parse(time.RFC3339, row.LockUntil)
66+
if err != nil {
67+
return nil, err
68+
}
69+
}
70+
71+
return &entitites.TOTPUserOptions{
72+
Login: login,
73+
Digits: row.Digits,
74+
TimeStep: time.Duration(row.TimeStep) * time.Second,
75+
Time: time.Now,
76+
Hash: hash,
77+
Tries: row.Tries,
78+
Secret: secret,
79+
LockStrategy: row.LockStrategy,
80+
LockUntil: lockUntil,
81+
LockTimeout: time.Duration(row.LockTimeout) * time.Second,
82+
FailCount: row.FailCount,
83+
FailCountBeforeLock: row.FailCountBeforeLock,
84+
}, nil
85+
}
86+
87+
func (u *usersDbJson) Update(login string, lockUntil time.Time, failCount int) error {
88+
if u.db == nil {
89+
return fmt.Errorf("db not opened")
90+
}
91+
92+
row, _, _, err := findStored(u, login)
93+
if err != nil {
94+
return err
95+
}
96+
97+
if lockUntil.IsZero() {
98+
row.LockUntil = ""
99+
} else {
100+
row.LockUntil = lockUntil.Format(time.RFC3339)
101+
}
102+
row.FailCount = failCount
103+
104+
err = u.db.Write("user", login, row)
105+
return err
106+
}
107+
func NewUsersDb(dbDir string, resolver shared.PathResolver) (*usersDbJson, error) {
108+
return &usersDbJson{
109+
dbDir: resolver.PathToAbs(dbDir),
110+
}, nil
111+
}
112+
113+
func hashFactory(algo int) func() hash.Hash {
114+
switch algo {
115+
case 0:
116+
return sha1.New
117+
case 1:
118+
return sha256.New
119+
case 2:
120+
return sha512.New
121+
default:
122+
return nil
123+
}
124+
}
125+
126+
127+
func findStored(u *usersDbJson, login string) (userRow, func() hash.Hash, []byte, error) {
128+
var row userRow
129+
err := u.db.Read("user", login, &row)
130+
if err != nil {
131+
return userRow{}, nil, nil, err
132+
}
133+
134+
hash := hashFactory(row.Hash)
135+
if hash == nil {
136+
return userRow{}, nil, nil, fmt.Errorf("unable to parse hash for algo %d: unknown algo for login %s", row.Hash, login)
137+
}
138+
139+
secret, err := hex.DecodeString(row.SecretKey)
140+
if err != nil {
141+
return userRow{}, nil, nil, fmt.Errorf("unable to parse secretkey for login %s", login)
142+
}
143+
return row, hash, secret, nil
144+
}

0 commit comments

Comments
 (0)