Skip to content

Commit 63c4d76

Browse files
author
Vic Shóstak
committed
Add .env for Docker; Fix JWT protected routes
1 parent 5e76291 commit 63c4d76

16 files changed

+364
-119
lines changed

.env.docker

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Server settings:
2+
SERVER_URL="0.0.0.0:5000"
3+
4+
# JWT settings:
5+
JWT_SECRET_KEY="secret"
6+
JWT_REFRESH_KEY="refresh"
7+
8+
# Database settings:
9+
DB_SERVER_URL="host=dev-postgres port=5432 user=postgres password=password dbname=postgres sslmode=disable"
10+
DB_MAX_CONNECTIONS=100
11+
DB_MAX_IDLE_CONNECTIONS=10
12+
DB_MAX_LIFETIME_CONNECTIONS=2

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ tmp/
77

88
# Test
99
*.out
10-
*.test
1110

1211
# Environment variables
1312
.env

Makefile

+12-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ security:
1414
test: security
1515
go test -cover ./...
1616

17+
test.db:
18+
go test -v -timeout 30s -coverprofile=cover.out -cover ./...
19+
go tool cover -func=cover.out
20+
1721
build: clean test
1822
CGO_ENABLED=0 go build -ldflags="-w -s" -o $(BUILD_DIR)/$(APP_NAME) main.go
1923

@@ -38,9 +42,6 @@ docker.network:
3842
docker network inspect dev-network >/dev/null 2>&1 || \
3943
docker network create -d bridge dev-network
4044

41-
docker.stop:
42-
docker stop dev-fiber dev-postgres
43-
4445
docker.fiber: docker.build
4546
docker run --rm -d \
4647
--name dev-fiber \
@@ -59,5 +60,13 @@ docker.postgres:
5960
-p 5432:5432 \
6061
postgres
6162

63+
docker.stop: docker.stop.fiber docker.stop.postgres
64+
65+
docker.stop.fiber:
66+
docker stop dev-fiber
67+
68+
docker.stop.postgres:
69+
docker stop dev-postgres
70+
6271
swag.init:
6372
swag init

app/controllers/book_controller.go

+76-60
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package controllers
33
import (
44
"time"
55

6-
"github.com/dgrijalva/jwt-go"
76
"github.com/gofiber/fiber/v2"
87
"github.com/google/uuid"
98
"github.com/koddr/tutorial-go-fiber-rest-api/app/models"
@@ -112,15 +111,21 @@ func CreateBook(c *fiber.Ctx) error {
112111
// Get now time.
113112
now := time.Now().Unix()
114113

115-
// Get data from JWT.
116-
token := c.Locals("jwt").(*jwt.Token)
117-
claims := token.Claims.(jwt.MapClaims)
114+
// Get claims from JWT.
115+
claims, err := utils.ExtractTokenMetadata(c)
116+
if err != nil {
117+
// Return status 500 and JWT parse error.
118+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
119+
"error": true,
120+
"msg": err.Error(),
121+
})
122+
}
118123

119124
// Set expiration time from JWT data of current book.
120-
expires := claims["expires"].(int64)
125+
expires := claims.Expires
121126

122-
// Set credential `book:create` from JWT data of current book.
123-
credential := claims["book:create"].(bool)
127+
// Set credential `book:delete` from JWT data of current book.
128+
credential := claims.Credentials["book:create"]
124129

125130
// Create a new book struct.
126131
book := &models.Book{}
@@ -136,7 +141,7 @@ func CreateBook(c *fiber.Ctx) error {
136141

137142
// Only book with `book:create` credential can create a new book.
138143
if credential && now < expires {
139-
// Create a new validator for book model.
144+
// Create a new validator for a book model.
140145
validate := validators.BookValidator()
141146

142147
// Validate book fields.
@@ -202,15 +207,21 @@ func UpdateBook(c *fiber.Ctx) error {
202207
// Get now time.
203208
now := time.Now().Unix()
204209

205-
// Get data from JWT.
206-
token := c.Locals("jwt").(*jwt.Token)
207-
claims := token.Claims.(jwt.MapClaims)
210+
// Get claims from JWT.
211+
claims, err := utils.ExtractTokenMetadata(c)
212+
if err != nil {
213+
// Return status 500 and JWT parse error.
214+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
215+
"error": true,
216+
"msg": err.Error(),
217+
})
218+
}
208219

209220
// Set expiration time from JWT data of current book.
210-
expires := claims["expires"].(int64)
221+
expires := claims.Expires
211222

212-
// Set credential `book:update` from JWT data of current book.
213-
credential := claims["book:update"].(bool)
223+
// Set credential `book:delete` from JWT data of current book.
224+
credential := claims.Credentials["book:update"]
214225

215226
// Create a new book struct.
216227
book := &models.Book{}
@@ -224,28 +235,9 @@ func UpdateBook(c *fiber.Ctx) error {
224235
})
225236
}
226237

227-
// Create database connection.
228-
db, err := database.OpenDBConnection()
229-
if err != nil {
230-
// Return status 500 and database connection error.
231-
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
232-
"error": true,
233-
"msg": err.Error(),
234-
})
235-
}
236-
237-
// Checking, if book with given ID is exists.
238-
if _, err := db.GetBook(book.ID); err != nil {
239-
// Return status 404 and book not found error.
240-
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
241-
"error": true,
242-
"msg": "book not found",
243-
})
244-
}
245-
246238
// Only book with `book:update` credential can update book profile.
247239
if credential && now < expires {
248-
// Create a new validator for book model.
240+
// Create a new validator for a book model.
249241
validate := validators.BookValidator()
250242

251243
// Validate book fields.
@@ -257,6 +249,25 @@ func UpdateBook(c *fiber.Ctx) error {
257249
})
258250
}
259251

252+
// Create database connection.
253+
db, err := database.OpenDBConnection()
254+
if err != nil {
255+
// Return status 500 and database connection error.
256+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
257+
"error": true,
258+
"msg": err.Error(),
259+
})
260+
}
261+
262+
// Checking, if book with given ID is exists.
263+
if _, err := db.GetBook(book.ID); err != nil {
264+
// Return status 404 and book not found error.
265+
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
266+
"error": true,
267+
"msg": "book not found",
268+
})
269+
}
270+
260271
// Set book data to update:
261272
book.UpdatedAt = time.Now()
262273

@@ -297,15 +308,21 @@ func DeleteBook(c *fiber.Ctx) error {
297308
// Get now time.
298309
now := time.Now().Unix()
299310

300-
// Get data from JWT.
301-
token := c.Locals("jwt").(*jwt.Token)
302-
claims := token.Claims.(jwt.MapClaims)
311+
// Get claims from JWT.
312+
claims, err := utils.ExtractTokenMetadata(c)
313+
if err != nil {
314+
// Return status 500 and JWT parse error.
315+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
316+
"error": true,
317+
"msg": err.Error(),
318+
})
319+
}
303320

304321
// Set expiration time from JWT data of current book.
305-
expires := claims["expires"].(int64)
322+
expires := claims.Expires
306323

307324
// Set credential `book:delete` from JWT data of current book.
308-
credential := claims["book:delete"].(bool)
325+
credential := claims.Credentials["book:delete"]
309326

310327
// Create new Book struct
311328
book := &models.Book{}
@@ -319,27 +336,27 @@ func DeleteBook(c *fiber.Ctx) error {
319336
})
320337
}
321338

322-
// Create database connection.
323-
db, err := database.OpenDBConnection()
324-
if err != nil {
325-
// Return status 500 and database connection error.
326-
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
327-
"error": true,
328-
"msg": err.Error(),
329-
})
330-
}
331-
332-
// Checking, if book with given ID is exists.
333-
if _, err := db.GetBook(book.ID); err != nil {
334-
// Return status 404 and book not found error.
335-
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
336-
"error": true,
337-
"msg": "book not found",
338-
})
339-
}
340-
341339
// Only book with `book:delete` credential can delete book profile.
342340
if credential && now < expires {
341+
// Create database connection.
342+
db, err := database.OpenDBConnection()
343+
if err != nil {
344+
// Return status 500 and database connection error.
345+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
346+
"error": true,
347+
"msg": err.Error(),
348+
})
349+
}
350+
351+
// Checking, if book with given ID is exists.
352+
if _, err := db.GetBook(book.ID); err != nil {
353+
// Return status 404 and book not found error.
354+
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
355+
"error": true,
356+
"msg": "book not found",
357+
})
358+
}
359+
343360
// Delete book by given ID.
344361
if err := db.DeleteBook(book.ID); err != nil {
345362
// Return status 500 and delete book process error.
@@ -350,11 +367,10 @@ func DeleteBook(c *fiber.Ctx) error {
350367
}
351368
} else {
352369
// Return status 403 and permission denied error.
353-
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
370+
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
354371
"error": true,
355372
"msg": "permission denied, check credentials or expiration time of your token",
356373
})
357-
358374
}
359375

360376
return c.JSON(fiber.Map{

go.sum

+13-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSUL
1212
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
1313
github.com/arsmn/fiber-swagger/v2 v2.3.0 h1:FC6RvYCBQlV0rbAEuCgxHilWLLNGmN8ClFRlY5l8RSs=
1414
github.com/arsmn/fiber-swagger/v2 v2.3.0/go.mod h1:bScnIE8qvQF5/wvsewuwXPkLN23eGQZqqNIyBA6Xd2E=
15+
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
1516
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
1617
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
1718
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -39,13 +40,15 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
3940
github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
4041
github.com/go-openapi/swag v0.19.12 h1:Bc0bnY2c3AoF7Gc+IMIAQQsD8fLHjHpc19wXvYuayQI=
4142
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
43+
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
4244
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
4345
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
4446
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
4547
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
4648
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
4749
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
4850
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
51+
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
4952
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
5053
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
5154
github.com/gofiber/fiber/v2 v2.1.0/go.mod h1:aG+lMkwy3LyVit4CnmYUbUdgjpc3UYOltvlJZ78rgQ0=
@@ -54,6 +57,7 @@ github.com/gofiber/fiber/v2 v2.6.0 h1:OywSUL6QPY/+/b89Ulnb8reovwm5QGjZQfk74v0R7U
5457
github.com/gofiber/fiber/v2 v2.6.0/go.mod h1:f8BRRIMjMdRyt2qmJ/0Sea3j3rwwfufPrh9WNBRiVZ0=
5558
github.com/gofiber/jwt/v2 v2.1.0 h1:eTahBQ8vO73fcXjpQjv/xiKZqMjvDtw5QmsvdgWQg6w=
5659
github.com/gofiber/jwt/v2 v2.1.0/go.mod h1:sf3l8cbwW93qL0kM9jcX9QTc8VIJgXCO1RWquBJUqTg=
60+
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
5761
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
5862
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
5963
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
@@ -73,6 +77,7 @@ github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw=
7377
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
7478
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
7579
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
80+
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
7681
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
7782
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
7883
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
@@ -122,16 +127,19 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
122127
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
123128
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
124129
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
130+
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
125131
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
126132
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
127133
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
128134
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
135+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
129136
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
130137
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
131138
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
132139
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
133140
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
134141
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
142+
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
135143
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
136144
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
137145
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -145,8 +153,10 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
145153
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
146154
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
147155
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
156+
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
148157
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
149158
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
159+
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
150160
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
151161
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
152162
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -157,13 +167,13 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC
157167
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
158168
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
159169
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
170+
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
160171
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
161172
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
162173
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
163174
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
164175
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
165176
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
166-
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
167177
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
168178
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
169179
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -206,6 +216,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
206216
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
207217
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
208218
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
219+
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
209220
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
210221
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
211222
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -265,6 +276,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
265276
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
266277
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
267278
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
279+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
268280
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
269281
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
270282
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=

0 commit comments

Comments
 (0)