Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dex
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
dex
Commits
e077803e
Commit
e077803e
authored
Sep 02, 2015
by
Yifan Gu
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #105 from yifan-gu/tests
refresh: bcrypt raw bytes rather than base64 encoded string.
parents
ff71593c
44c6cb44
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
149 additions
and
65 deletions
+149
-65
0005_refresh_token_create.sql
db/migrations/0005_refresh_token_create.sql
+1
-1
assets.go
db/migrations/assets.go
+3
-3
refresh.go
db/refresh.go
+17
-11
db_test.go
functional/db_test.go
+77
-2
repo.go
refresh/refreshtest/repo.go
+2
-2
repo.go
refresh/repo.go
+16
-15
server_test.go
server/server_test.go
+33
-31
No files found.
db/migrations/0005_refresh_token_create.sql
View file @
e077803e
-- +migrate Up
-- +migrate Up
CREATE
TABLE
refresh_token
(
CREATE
TABLE
refresh_token
(
id
bigint
NOT
NULL
,
id
bigint
NOT
NULL
,
payload_hash
text
,
payload_hash
bytea
,
user_id
text
,
user_id
text
,
client_id
text
client_id
text
);
);
...
...
db/migrations/assets.go
View file @
e077803e
...
@@ -155,7 +155,7 @@ func dbMigrations0004_session_nonceSql() (*asset, error) {
...
@@ -155,7 +155,7 @@ func dbMigrations0004_session_nonceSql() (*asset, error) {
return
a
,
nil
return
a
,
nil
}
}
var
_dbMigrations0005_refresh_token_createSql
=
[]
byte
(
"
\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x90\x51\x4f\xc2\x30\x10\xc7\xdf\xf7\x29\xee\x0d\x88\x62\xc2\x2b\x3e\x95\xed\x0c\x8b\x5d\xa7\x5d\x2b\xf2\xb4\x
54\x56\x59\xc3\x1c\x73\xad\x46\xbe\xbd\x65\x13\x08\xc4\x68\xdf\xfa\xbb\xfb\xdf\x2f\x77\xe3\x31\x5c\xbd\x99\x75\xab\x9c\x06\xd9\x04\x21\x47\x22\x10\x04\x99\x51\x84\x56\xbf\xb6\xda\x96\xb9\xdb\x6e\x74\x0d\xc3\x00\xfc\x33\x05\xbc\x98\xb5\xa9\x1d\xb0\x54\x00\x93\x94\x5e\x77\xbc\x51\xbb\x6a\xab\x8a\xbc\x54\xb6\x04\xa7\xbf\x5c\x8f\x3f\xac\x6e\x73\x9f\x39\x91\x55\x65\x74\xed\x0e\x2c\x18\xdd\x06\x07\x69\x86\x8f\x12\x59\x78\xe1\xf5\x9d\xb9\xd5\xef\x5d\x36\x13\x84\x0b\x58\xc4\x62\x0e\x93\x0e\xc4\xcc\x67\x13\x64\x02\x66\xcb\x1f\xc4\x52\x48\x62\xf6\x44\xa8\xc4\xe3\x9f\x3c\x9f\xfe\x21\x09\xe7\x08\x13\xaf\x25\x54\x20\xff\xdb\x0a\xe9\x82\x61\xb4\x1f\x7e\x56\xbd\x31\xc5\x31\xdf\x9f\x2a\x65\xf4\xa2\x07\xfa\x72\x98\x52\x99\xb0\xfd\xd9\x32\x14\x10\xe1\x1d\x91\x54\x40\xed\x57\xff\x54\xd5\x70\xf0\x9b\x74\x30\x9d\xb6\x7a\xbd\xaa\x94\xb5\xa3\x7f\x35\xdd\x4e\x24\x8a\xbc\x88\x65\x82\x93\xd8\xdf\xe2\x7c\x68\xb3\xd1\x3b\x78\xe0\x71\x42\xf8\x12\xee\x71\x09\x43\x53\xf8\xb9\xdf\x01\x00\x00\xff\xff\xff\xeb\x3d\xc4\xf9
\x01\x00\x00
"
)
var
_dbMigrations0005_refresh_token_createSql
=
[]
byte
(
"
\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x90\x51\x4f\xc2\x30\x10\xc7\xdf\xf7\x29\xee\x0d\x88\x62\xc2\x2b\x3e\x95\xed\x0c\x8b\x5d\xa7\x5d\x2b\xf2\xb4\x
14\x56\xa1\x61\x8e\xb9\x56\xe3\xbe\xbd\x65\x13\x0c\xc4\x68\xdf\xfa\xbb\xfb\xdf\x2f\x77\xe3\x31\x5c\xbd\x9a\x4d\xa3\x9c\x06\x59\x07\x21\x47\x22\x10\x04\x99\x51\x84\x46\xbf\x34\xda\x6e\x73\xb7\xdf\xe9\x0a\x86\x01\xf8\x67\x0a\x58\x99\x8d\xa9\x1c\xb0\x54\x00\x93\x94\x5e\x77\xbc\x56\x6d\xb9\x57\x45\xbe\x55\x76\x0b\xab\xd6\x69\xd5\xf3\x77\xab\x9b\xdc\x87\x9c\xfe\x74\x3d\x59\x97\x46\x57\xee\xc8\x82\xd1\x6d\x70\xb4\x66\xf8\x28\x91\x85\x17\x62\xdf\x99\x5b\xfd\xd6\x65\x33\x41\xb8\x80\x45\x2c\xe6\x30\xe9\x40\xcc\x7c\x36\x41\x26\x60\xb6\xfc\x46\x2c\x85\x24\x66\x4f\x84\x4a\x3c\xfd\xc9\xf3\xcf\x3f\x24\xe1\x1c\x61\xe2\xb5\x84\x0a\xe4\x7f\x5b\x21\x5d\x30\x8c\x0e\xc3\xcf\xaa\x37\xa6\x38\xe5\xfb\x5b\xa5\x8c\x5e\xf4\x40\x5f\x0e\x53\x2a\x13\x76\xb8\x5b\x86\x02\x22\xbc\x23\x92\x0a\xa8\xfc\xea\x1f\xaa\x1c\x0e\x7e\x93\x0e\xa6\xd3\x46\x6f\xd6\xa5\xb2\x76\xf4\xaf\xa6\xdb\x89\x44\x91\x17\xb1\x4c\x70\x12\xfb\x5b\x9c\x0f\xad\x77\xba\x85\x07\x1e\x27\x84\x2f\xe1\x1e\x97\x30\x34\x85\x9f\xfb\x15\x00\x00\xff\xff\xc4\xcc\xa8\xfd\xfa
\x01\x00\x00
"
)
func
dbMigrations0005_refresh_token_createSqlBytes
()
([]
byte
,
error
)
{
func
dbMigrations0005_refresh_token_createSqlBytes
()
([]
byte
,
error
)
{
return
bindataRead
(
return
bindataRead
(
...
@@ -170,7 +170,7 @@ func dbMigrations0005_refresh_token_createSql() (*asset, error) {
...
@@ -170,7 +170,7 @@ func dbMigrations0005_refresh_token_createSql() (*asset, error) {
return
nil
,
err
return
nil
,
err
}
}
info
:=
bindataFileInfo
{
name
:
"db/migrations/0005_refresh_token_create.sql"
,
size
:
50
5
,
mode
:
os
.
FileMode
(
436
),
modTime
:
time
.
Unix
(
1
,
0
)}
info
:=
bindataFileInfo
{
name
:
"db/migrations/0005_refresh_token_create.sql"
,
size
:
50
6
,
mode
:
os
.
FileMode
(
436
),
modTime
:
time
.
Unix
(
1
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
return
a
,
nil
}
}
...
@@ -215,7 +215,7 @@ func dbMigrations0007_session_scopeSql() (*asset, error) {
...
@@ -215,7 +215,7 @@ func dbMigrations0007_session_scopeSql() (*asset, error) {
return
a
,
nil
return
a
,
nil
}
}
var
_dbMigrationsAssetsGo
=
[]
byte
(
"
\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x99\xdf\x6f\xdb\x46\x12\xc7\x9f\xad\xbf\x82\x35\xd0\x42\x3
e\xf8\x64\xfe\x14\x45\x03\x7d\x69\x93\x03\xf2\xd0\x14\xb8\xe6\x9e\xce\x07\x61\x49\x2e\x5d\xa2\xb2\xe4\x88\x72\xcf\x49\x90\xff\xfd\xe6\xb3\x33\xb2\x9d\x58\xb2\x13\xe7\x82\xa0\x0f\x8c\xc5\xe5\xec\xec\xfc\x9e\xd9\x6f\x4e\x4e\xa2\x9f\x57\xad\x8f\xce\xfd\xd2\xaf\xdd\xc6\xb7\x51\xfd\x26\x3a\x5f\xfd\xbd\xee\x97\xad\xdb\xb8\xc9\x48\x08\x86\xd5\xd5\xba\xf1\xc3\x29\xbf\xdb\xfa\xe4\xa2\x3f\x17\xca\x7e\xb5\x1c\x4e\xe2\x38\x4e\xe6\xfd\xb2\xdf\xf4\x6e\x31\xbf\x59\x9f\x0c\xaf\x17\x3b\x69\xd3\x79\xeb\xaf\xe7\xae\xbd\xe8\xf7\xd3\x64\xf3\xab\xc1\xaf\xe7\xcd\xda\x23\xcd\xdc\x6d\xf6\x52\xe6\xf3\xc1\x0f\x83\xbc\xcd\x97\xab\x65\xe3\xf7\xd2\x15\xf3\xb5\xef\xd6\x7e\xf8\x7d\xbe\x59\xfd\xe1\x97\xc6\x7a\x2f\xf9\x54\x05\xf0\x17\xae\x5f\xcc\xaf\x96\xfd\xeb\xab\xfd\xb4\xe5\x8d\x08\x43\xb3\xba\xdc\x43\xe7\x86\xc1\x6f\x86\xc9\xf9\x8a\x4f\xcf\x7e\x8d\x5e\xfe\xfa\x2a\x7a\xfe\xec\xc5\xab\xef\x46\xa3\x4b\xd7\xfc\xe1\xce\x7d\x74\x4b\x3d\x1a\xf5\x17\x97\xab\xf5\x26\x1a\x8f\x0e\x0e\xeb\x37\x1b\x3f\x1c\xca\x8f\x66\x75\x71\x29\x1a\x0c\x27\xe7\x6f\xfb\x4b\x16\xba\x8b\x0d\x7f\xfa\x15\xff\x0e\x9b\x75\xbf\x3c\x0f\x84\xab\xf0\xef\xa6\xbf\xf0\xfa\xf9\xa4\x5f\x5d\x6d\xfa\x05\x2f\x97\x6e\xf3\xfb\x49\xd7\x2f\x3c\x3f\x0e\x47\x47\xa3\x51\x77\xb5\x6c\x22\x73\xf4\x3f\xbd\x6b\xc7\xfc\x88\xfe\xfd\x1f\x8e\x3d\x8e\x96\xee\xc2\x47\xca\xfa\x28\x1a\x6f\x57\xfd\x7a\xbd\x5a\x1f\x45\xef\x46\x07\xe7\x6f\xc3\x5b\x74\xfa\x63\x84\x54\x93\x97\xfe\xbf\x30\xf1\xeb\x71\x10\x9b\xf7\x9f\xae\xba\x4e\xde\x61\x7b\x74\x34\x3a\xe8\xbb\xb0\xe1\xbb\x1f\xa3\x65\xbf\x80\xc5\xc1\xda\x6f\xae\xd6\x4b\x5e\x8f\x23\x51\x69\xf2\x1c\xee\xdd\xf8\x10\x46\xd1\xf7\xaf\x4f\xa3\xef\xff\x3c\x54\x49\xc2\x59\xc2\xe3\xfd\x68\x74\xf0\xa7\x5b\x47\xf5\x55\x17\xe9\x39\x7a\xc8\xe8\x60\xae\xe2\xfc\x18\xf5\xab\xc9\xcf\xab\xcb\x37\xe3\x1f\x84\xe6\x58\x64\x93\x5d\xcd\xe2\xf9\x56\xd2\xc9\xcf\x8b\xd5\xe0\xc7\xa2\xfe\xff\x49\x1e\xd8\x28\xff\x3d\x8c\x84\x50\xe5\xb6\x45\x11\x6b\xf2\x13\xa2\x8f\x8f\x8e\xa1\x18\xc9\xb7\xcd\x9b\x4b\x1f\x85\x40\xc1\xe4\x57\xcd\x06\x2e\x41\x3f\xf3\x87\x1c\xb3\xec\x56\x51\xb4\x1a\x26\xff\x10\x1f\xbe\x90\x97\x9b\x7d\xe6\xc2\xed\xfa\x1d\x0e\x77\x7c\x38\x3a\x18\xfa\xb7\x3e\xea\x97\x9b\x69\x3e\x3a\xb8\x20\xe7\x8d\xd7\x2f\xf2\x3b\xac\xbc\x92\xb0\x89\x88\x9d\x09\xbf\x60\x1f\x22\x64\xdc\xf5\x1f\x1f\x71\x14\xbd\x14\xce\xe3\x23\xe3\xcd\x51\xa6\x5c\xd7\x4f\x38\x54\x36\xef\xdf\xfb\x9b\x08\x22\x7b\x83\x28\x1f\x6e\x45\xc4\x07\xb7\x22\xab\x6c\xbd\x23\xf9\x87\x0c\xd0\xeb\x31\x06\x28\x27\x3c\x6e\x14\xbd\xc7\xc1\xb4\xdf\xcf\xe4\xc5\xf0\xac\x5f\x0b\x8b\x7a\xb5\x5a\xdc\xdd\xed\x16\xc3\x23\x9a\xbf\x19\x54\x71\xbf\xee\x5c\xe3\xdf\xbd\xbf\xb3\xdb\x22\x81\xe0\x9e\xb7\xf5\x2f\x37\x15\x61\x77\x8d\xfd\xed\xf5\x42\x42\x5d\x63\x63\x7c\x78\x76\x9d\x74\x67\xd7\xb3\xfa\xec\x3a\x9e\xc9\x13\xdb\x53\x9d\x5d\x4f\xbd\xac\xdb\x5a\x27\x34\x55\x23\x4f\x76\x76\xdd\x40\xef\xce\xae\x5b\xd9\x93\xc9\xb7\x44\x9e\x66\x7a\x76\xed\x65\xbd\x94\x7d\xb1\x7c\xab\x12\xf9\x2e\xb4\x33\x59\x9f\xca\x53\xc9\x37\x27\x74\xae\x94\xf7\x56\xe8\xe4\xfb\x54\x1e\x27\x4f\x9d\x0b\xad\x7c\x2b\x0b\x7d\xcf\x84\x26\x63\x5d\xde\x53\xf8\x8a\x1c\x05\x32\xc8\xbe\x5c\x78\x26\xc2\x7f\x2a\xfc\xda\x52\xff\x16\xfc\x96\x73\x73\xa1\x4b\x84\x57\x23\xeb\x8d\x57\x99\xd8\x3f\x13\x5e\x33\x59\x2f\x44\x97\x56\xde\x3b\xd1\xc3\x23\x53\xad\xfb\x91\x2f\xf1\x6a\x87\x46\xce\x8c\x4b\x3d\x07\x79\xd0\x3d\x67\x8f\xe9\x03\x7d\xe6\xd5\x1e\xa9\xf0\xab\x38\x47\xe4\xc9\x53\xf9\x2d\x67\xe4\x9d\xea\x5a\xc3\x0f\xd9\x65\xbd\xab\xd4\xbe\x9d\xd0\x77\xb2\x56\xb7\x26\x27\xfa\x0a\xad\x97\xf3\x2a\x79\x3a\xa1\xcd\x65\x6d\xda\xa8\x1d\x3c\xb6\x90\xef\xb9\xf0\xcf\x90\x51\xde\x1b\x91\xa1\x90\xdf\x59\xa3\x74\x8d\xf0\xe9\x62\xd5\xbf\x92\xfd\xad\x53\xfb\xa3\x3b\x76\x44\x06\x74\x76\x85\xca\xee\x32\xb5\x2b\x7b\xb0\x4b\xdc\x98\x6d\xcc\x2e\xc8\x54\x6e\xfd\xd5\xa9\x1c\x31\xba\xa7\x7a\x76\x23\xb2\x37\x95\xae\x97\x46\x9f\xc7\x6a\xb3\x26\x35\x79\xe4\xbb\x6f\x35\x5e\xb0\x5d\x1d\xab\x8e\x71\xad\x71\xe3\x52\xf5\x1d\x3e\x47\x37\xd6\xe3\xa9\xc6\x46\x93\x68\x9c\x20\x17\x3a\x25\xf2\xb7\xc6\xe7\x99\xfa\x27\xc4\x06\x7b\xe5\xdc\x02\xbb\x39\xe5\x53\x0b\xcf\x54\xce\xae\x90\x9f\xb8\xad\x2c\x3e\x6b\x3d\x83\x38\xc6\xff\xb1\x7c\xf7\xb9\xfa\xaa\x26\x06\x0b\xd5\xbf\xcb\xf4\x3d\x4f\x54\x16\xe8\x90\x21\xc6\xe7\x7c\x2b\x95\x7f\xb0\xbf\xf9\x33\x11\x9a\x5a\xfe\xa6\xb1\xc6\x46\xdd\x29\x3d\xb2\x95\x42\xef\xe5\x3c\x1f\xab\xfd\xb1\x67\xd3\xe8\x1a\x39\x92\xb5\xea\x13\x72\x89\x78\x40\x26\xce\xc6\x86\xb3\xc6\xe4\x91\xf5\x59\xaa\x79\x88\xbf\x90\x1f\x7a\xf8\x63\x5b\x64\x08\xb6\xef\x34\x5f\x3a\xa1\x2b\x33\xe5\x93\x57\x6a\x93\xd8\xec\x85\x1f\x90\xa9\x90\xef\x69\xaa\xb6\x43\x2e\xe8\x39\x23\x17\x7e\x49\xad\x7c\x89\x3b\x62\x95\x1c\x49\xa9\x03\xb1\x7e\xc7\x8e\xae\xd2\x9c\x42\xef\xa2\xd1\xdc\xc1\xe7\xc9\x4c\xe3\x02\x9f\x95\x7c\x73\xaa\xef\xb4\x52\xf9\x1c\xf1\x28\x6b\xc5\xd6\xf7\x99\xf2\x22\x66\x1b\xe1\x9f\x96\x6a\x73\xe2\x93\xda\x43\x3e\x3a\xe2\x92\x5a\xd1\x6a\x7e\x40\x83\x2d\xf0\x0f\x71\x51\x78\x95\x21\x6f\x35\xce\xa9\x11\x69\xa1\xf2\x12\x97\x41\xff\x4a\xcf\xc5\x06\xc4\x25\x79\x43\xbd\x21\x9e\xa0\x0f\xe7\x4c\xd5\x27\xc8\x12\xea\xa0\xac\xf9\x46\x63\xa7\x8c\x95\x3f\xf5\x0c\x9d\xdb\x56\x65\xe2\x37\x36\xcf\x4b\xb5\x9b\xe7\x5c\xe1\x3b\x95\xb3\x3a\xa7\x35\xa8\x20\xd6\xa0\x4b\x35\xc6\xf0\x1d\x3e\x87\x07\x6b\x29\x7c\x2b\xcd\x07\xea\x21\xfe\x26\x6f\x67\x56\x4f\xe1\x8f\x0f\x1c\x74\x53\xd5\xbb\x6e\xd4\x0e\xd8\x98\x78\xe5\x0c\x7c\x48\x5d\x46\x5f\xe2\xa4\xc3\xbe\x8d\xd6\x49\x6a\x98\xcf\x34\xfe\x4b\x6a\x56\xa7\x3a\x15\xc4\x3f\xbe\x92\xf5\x7a\xa6\xfe\xa5\x2e\x84\x5e\x50\x6a\x2d\xaf\x9d\xfa\x9c\xb8\x22\x8e\xb6\xbd\x81\xda\xc7\xe3\xbc\xd6\x39\x72\x88\x5a\x4e\x3d\x8a\x8b\x2d\xdd\xe1\x76\x4a\xfc\xa4\x86\x64\x43\xcd\xae\x61\x71\x3b\xfa\xdc\x19\x36\x65\x4a\xfa\xb4\x3e\x77\x2c\x94\x87\x9f\x7a\xef\x38\x14\xea\xa3\x9b\xd1\xe5\x93\xf8\x23\xf1\xdf\xc2\xec\x75\x57\xe2\x30\x7c\xdd\x4c\xb8\x9f\xa3\xff\x63\x83\xe5\xcd\x3c\x18\x26\x3a\x61\xfe\xd1\x98\xf0\x8e\x01\xea\x34\xfa\x0c\x95\x23\xe6\xa6\xd3\x28\xc9\x66\xb3\xe3\x88\x11\xe8\xf4\xee\x84\x34\xce\xb3\xe9\x51\x58\x67\xb0\x39\xd5\xc1\xe7\x5f\xcb\xfe\x7a\x9c\x1c\x47\xf1\x91\x4c\xb0\x0e\x29\x7e\x08\x26\x78\x17\xf4\x3e\x8d\x4c\x7d\x44\x3c\x8d\xc2\x9f\xf7\x37\x5e\x74\xc7\x0f\x0d\x2b\x77\x2e\x79\x4f\x1d\x52\x68\x54\xa1\x39\x14\xda\x18\xc2\x20\xd0\x6a\x80\xa7\xd6\x4c\xd3\x46\x0b\x24\x34\xf0\x23\x11\x29\xd4\x25\x09\x94\x2b\x5f\x12\x32\x6e\xb5\x60\x41\xc3\x7b\x99\x6b\x93\x2e\x2d\xf1\xf2\x99\xf1\xaf\x94\x3f\xe7\xa4\xb5\x36\x1f\x92\x9d\x35\x9a\x27\x85\x85\x44\xa7\x38\xd1\xa0\x68\xd0\x33\xd9\x97\xda\x13\x1a\xb6\xd7\x44\x63\xb8\x08\x43\x91\xd7\x46\x16\x5b\x12\x52\x88\x29\x98\x34\x1d\x86\x11\xce\x60\x8d\x24\x86\x37\x05\x2c\xb7\xe6\x8f\x6e\x9d\x3d\x99\xed\x9b\x19\x0d\x45\x9f\xa2\x59\x34\xb7\xcd\x1d\x19\x82\x3c\x89\x26\xf5\xf6\xcc\xe9\x4c\x8b\x08\x32\x33\xb0\xd0\x28\x0a\x1b\xc2\x28\x9e\x61\x70\xc3\x7e\x4e\x8b\x35\xfa\x51\xb0\xa0\xa5\x99\xd3\x04\x28\x4e\x9c\x11\xa7\xf7\x0b\x08\x32\xd5\xd6\x78\x43\xa1\xf7\x77\x7c\xbb\xb7\x80\x7c\x18\x24\x5f\x5c\x38\x3e\x64\xb7\xbb\x60\x7c\x04\x3e\x3c\x58\x28\x3e\xe4\xf7\x84\x02\xb1\x53\xbf\xaf\x56\x18\xee\xa9\xb6\x2d\x08\xe9\xf4\xdb\xd7\x83\x7b\x80\xce\x5f\xa5\x2a\xc0\x2b\xb5\x51\x99\xf7\x90\xad\x9d\xae\x71\x4d\x49\x8d\x07\xad\x98\xfd\x61\x6f\xa2\xef\x5c\x11\x68\xe1\x9c\xd7\x15\xfa\x14\x96\x71\x41\x4e\x6f\x99\x5e\x68\xe6\xe5\x36\xee\x72\xf5\xe0\x5c\xf8\xc0\x3b\x54\x27\x67\x95\xc9\xc6\xcf\xd4\xc6\x06\x6f\x57\x13\x32\x1d\x7d\x82\x1c\x76\x1d\x60\x7c\x6c\xe5\x49\x52\x1d\x83\xa8\x00\x64\xbe\x73\x56\x3d\xa6\x3a\xa6\x33\xb6\x55\x36\xbe\x27\xf1\xfd\xec\x4e\xad\x3a\x7a\xbb\xca\x70\xfd\x78\x3c\xbb\x77\xb9\xfc\x8b\x73\x7c\x17\xd3\xdd\x99\xbe\x13\x42\x7c\x30\xdf\x77\xf1\x7e\x42\xd6\x3f\xa0\xf7\x57\xcb\xfd\x3d\xca\x6e\x2b\x40\x92\x7c\xfb\x0a\xf0\x11\x50\xfb\x57\xc8\x7f\xe2\x7e\x9b\xe3\xe4\x6a\x38\xcb\x72\x90\x3c\xfe\xdc\x9c\x27\x87\x9b\xda\x26\x8a\x5a\x79\x73\x0e\x32\x84\xb3\x2a\xbd\x22\xf0\x7b\x9b\xdb\xa1\xdb\xe6\xf7\x73\x92\x2b\x20\x30\x02\xd7\x25\xec\xc6\x75\xe8\xf1\x9c\xbc\xef\x84\x2f\xce\xc8\xfb\x2c\x77\xe7\xe3\x0e\xa0\xfe\xc1\x6c\xbc\xcf\xf7\x09\xb9\xb8\x57\xdf\xaf\x96\x89\x3b\xd5\xb4\x3c\x9c\xc6\xdf\x3e\x0d\x77\xff\x3f\xc8\x53\xb3\x91\xcb\x70\x15\x6b\xf4\xd3\xb5\x00\x3d\x6e\x80\x44\x2e\xaf\x9d\x66\x03\xf3\x2d\xe0\x1f\x19\xc7\xfe\x69\xaa\xb4\x74\x31\xe6\x64\xe6\x52\x80\xa6\xd8\xc0\x10\x66\xc8\x30\x77\xda\x1c\x4e\x56\x32\xa3\x16\x06\x70\x01\xdc\x00\xe0\x00\x1e\x30\x97\x92\x35\x01\xa0\xf2\x7a\xf9\xe6\x22\x0b\x30\x80\xfc\x80\x1a\xcc\xbf\x41\x16\xa7\x17\xfe\xae\xd6\xf7\xd4\x32\x89\x8b\x35\x97\x74\x66\xe9\xda\x2e\xf3\x01\xc4\x34\x20\x85\x0b\x3b\x80\x08\x99\x98\x1a\x58\x00\xf8\x12\xba\x65\xae\xf4\x45\x72\x0b\xc0\x01\x20\xd5\x53\x05\xf1\xb8\xf0\xd7\x06\x62\x61\x3f\x2a\x06\x76\x40\xfe\x60\x47\x00\x8a\x4c\xa7\x00\x40\x81\x6a\xa6\x17\xf8\x70\x47\x68\x15\x74\x2b\xac\x02\x00\x0e\x00\x78\x01\x98\x20\x77\x6d\x53\x02\x3a\x01\x58\x38\x03\xe6\xc2\x7a\xae\x32\xc4\x36\xc3\x23\x13\xfa\xcd\x3a\x05\x23\x5d\x63\xf2\x64\x0a\x6a\x71\xbf\xa8\xac\xf2\x61\x3f\xe4\x0c\x3e\xf1\x5a\x51\x01\x86\x00\x3c\x02\xa8\x56\x2a\x20\x04\x28\x0c\x3f\x26\x8c\xc2\x40\x88\x00\x3a\x71\x3f\x6a\x4d\xef\x42\x41\x08\x7c\x19\xc0\xcf\x4c\xed\xc4\xb4\x51\x6c\xfd\x93\xea\x39\xe8\xc7\x5f\xd6\x02\xe8\x54\x2a\x3d\x80\x0c\x95\x30\x80\x54\xb5\x01\xbc\xf9\xed\x74\xc4\x7e\x2a\x6f\x8e\xae\xc6\xd3\x6f\xf5\x6a\xf4\x6f\x67\xf7\x22\xe2\x38\x80\x98\x33\xe5\x0d\x38\xca\x7d\x07\x7b\xa5\xdb\x2e\x53\xeb\x44\xe5\x2b\x03\xee\x0c\xdc\xe6\x5c\xee\x36\x85\x81\xbf\xc4\x0c\x00\x15\x7f\x5b\x03\x8c\x99\xe4\xb0\x1f\x9d\xc6\x19\x70\x47\xdc\xd1\x7d\xf0\x6d\x61\x77\xc8\xda\x80\x70\xe2\x0a\x10\x89\xbb\x16\xf1\x84\xfd\x12\x03\xaa\x90\x09\x60\x10\x3f\x00\xf4\x21\x1b\x6b\x01\x98\x8c\x15\x24\x02\xfc\xc6\x57\xe4\x5d\xb0\x39\x20\x98\x53\xf9\x98\xf4\x02\x40\x6a\x80\x1c\xc0\x51\x66\xc0\x55\xe8\x6c\xf9\x6d\xbc\x84\xbc\x2c\x54\x5f\xfc\xd0\x5a\xce\x30\x5d\x02\x10\x93\x43\xdc\xf1\x98\x28\x03\xa0\x66\xa0\x28\xdd\x0f\xd0\x1c\xa0\x31\x4c\x9a\xde\xba\x6b\x65\xf7\xcb\x4c\xbf\x85\x58\xe8\xec\x0e\xf9\x51\x37\xe3\x09\x00\x5b\x7b\x0b\x3c\xdf\xd2\xed\xeb\x66\x7b\x6b\xd9\x17\x37\xb5\xbd\x9c\x77\xf7\xb6\xfd\xff\xb9\xfc\x60\x8b\xdb\x7b\xca\x13\x3a\xdd\x63\xb6\x78\xb0\xe1\xfd\x2f\x00\x00\xff\xff\xfb\x08\x01\x0a
\x00\x20\x00\x00
"
)
var
_dbMigrationsAssetsGo
=
[]
byte
(
"
\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd4\x99\xdf\x6f\xdb\x46\x12\xc7\x9f\xad\xbf\x82\x35\xd0\x42\x3
a\xf8\x64\x92\xe2\x2f\x19\xe8\x4b\xdb\x1c\x90\x87\xa6\xc0\x35\xf7\x74\x3e\x08\x4b\x72\xe9\x12\x95\x25\x47\x94\x7b\x4e\x82\xfc\xef\x37\x9f\x9d\x91\xeb\xc4\x92\x9d\x38\x17\x04\x7d\x60\x2c\x2e\x67\x67\xe7\xf7\xcc\x7e\x73\x7a\x1a\xfd\xb8\x6e\x7d\x74\xe1\x57\x7e\xe3\xb6\xbe\x8d\xea\xd7\xd1\xc5\xfa\xef\x75\xbf\x6a\xdd\xd6\x4d\x47\x42\x30\xac\xaf\x37\x8d\x1f\xce\xf8\xdd\xd6\xa7\x97\xfd\x85\x50\xf6\xeb\xd5\x70\x1a\xc7\x71\xb2\xe8\x57\xfd\xb6\x77\xcb\xc5\xed\xfa\x74\x78\xb5\xdc\x4b\x9b\x2e\x5a\x7f\xb3\x70\xed\x65\x7f\x98\x66\xb6\xb8\x1e\xfc\x66\xd1\x6c\x3c\xd2\x2c\xdc\xf6\x20\x65\xb6\x18\xfc\x30\xc8\xdb\x62\xb5\x5e\x35\xfe\x20\x5d\xbe\xd8\xf8\x6e\xe3\x87\xdf\x16\xdb\xf5\xef\x7e\x65\xac\x0f\x92\x17\x2a\x80\xbf\x74\xfd\x72\x71\xbd\xea\x5f\x5d\x1f\xa6\x2d\x6f\x45\x18\x9a\xf5\xd5\x01\x3a\x37\x0c\x7e\x3b\x4c\x2f\xd6\x7c\xfa\xe9\x97\xe8\xc5\x2f\x2f\xa3\x67\x3f\x3d\x7f\xf9\xcd\x68\x74\xe5\x9a\xdf\xdd\x85\x8f\xfe\xa4\x1e\x8d\xfa\xcb\xab\xf5\x66\x1b\x8d\x47\x47\xc7\xf5\xeb\xad\x1f\x8e\xe5\x47\xb3\xbe\xbc\x12\x0d\x86\xd3\x8b\x37\xfd\x15\x0b\xdd\xe5\x96\x3f\xfd\x9a\x7f\x87\xed\xa6\x5f\x5d\x04\xc2\x75\xf8\x77\xdb\x5f\x7a\xfd\x7c\xda\xaf\xaf\xb7\xfd\x92\x97\x2b\xb7\xfd\xed\xb4\xeb\x97\x9e\x1f\xc7\xa3\xc9\x68\xd4\x5d\xaf\x9a\xc8\x1c\xfd\x4f\xef\xda\x31\x3f\xa2\x7f\xff\x87\x63\x4f\xa2\x95\xbb\xf4\x91\xb2\x9e\x44\xe3\xdd\xaa\xdf\x6c\xd6\x9b\x49\xf4\x76\x74\x74\xf1\x26\xbc\x45\x67\xdf\x47\x48\x35\x7d\xe1\xff\x0b\x13\xbf\x19\x07\xb1\x79\xff\xe1\xba\xeb\xe4\x1d\xb6\x93\xc9\xe8\xa8\xef\xc2\x86\x6f\xbe\x8f\x56\xfd\x12\x16\x47\x1b\xbf\xbd\xde\xac\x78\x3d\x89\x44\xa5\xe9\x33\xb8\x77\xe3\x63\x18\x45\xdf\xbe\x3a\x8b\xbe\xfd\xe3\x58\x25\x09\x67\x09\x8f\x77\xa3\xd1\xd1\x1f\x6e\x13\xd5\xd7\x5d\xa4\xe7\xe8\x21\xa3\xa3\x85\x8a\xf3\x7d\xd4\xaf\xa7\x3f\xae\xaf\x5e\x8f\xbf\x13\x9a\x13\x91\x4d\x76\x35\xcb\x67\x3b\x49\xa7\x3f\x2e\xd7\x83\x1f\x8b\xfa\xff\x27\x79\x60\xa3\xfc\x0f\x30\x12\x42\x95\xdb\x16\x45\xac\xe9\x0f\x88\x3e\x9e\x9c\x40\x31\x92\x6f\xdb\xd7\x57\x3e\x0a\x81\x82\xc9\xaf\x9b\x2d\x5c\x82\x7e\xe6\x0f\x39\x66\xd5\xad\xa3\x68\x3d\x4c\xff\x21\x3e\x7c\x2e\x2f\xb7\xfb\xcc\x85\xbb\xf5\x3b\x1c\xee\xf8\x70\x74\x34\xf4\x6f\x7c\xd4\xaf\xb6\x45\x36\x3a\xba\x24\xe7\x8d\xd7\xcf\xf2\x3b\xac\xbc\x94\xb0\x89\x88\x9d\x29\xbf\x60\x1f\x22\x64\xdc\xf5\x1f\x1e\x31\x89\x5e\x08\xe7\xf1\xc4\x78\x73\x94\x29\xd7\xf5\x53\x0e\x95\xcd\x87\xf7\xfe\x2a\x82\xc8\xde\x20\xca\xfb\x5b\x11\xf1\xc1\xad\xc8\x2a\x5b\xef\x48\xfe\x3e\x03\xf4\x7a\x8c\x01\xca\x09\x8f\x5b\x45\xef\x71\x30\xed\x0f\x33\x79\x3e\xfc\xd4\x6f\x84\x45\xbd\x5e\x2f\xef\xee\x76\xcb\xe1\x11\xcd\x5f\x0f\xaa\xb8\xdf\x74\xae\xf1\x6f\xdf\xdd\xd9\x6d\x91\x40\x70\x2f\xda\xfa\xe7\xdb\x8a\xb0\xbf\xc6\xfe\xfa\x6a\x29\xa1\xae\xb1\x31\x3e\x3e\xbf\x49\xba\xf3\x9b\xaa\x3e\xbf\x89\x2b\x79\x62\x7b\xe6\xe7\x37\x85\x97\x75\x5b\xeb\x84\x66\xde\xc8\x33\x3b\xbf\x69\xa0\x77\xe7\x37\xad\xec\x99\xc9\xb7\x44\x9e\xa6\x38\xbf\xf1\xb2\x5e\xca\xbe\x58\xbe\xcd\x13\xf9\x2e\xb4\x95\xac\x17\xf2\xcc\xe5\x9b\x13\x3a\x57\xca\x7b\x2b\x74\xf2\xbd\x90\xc7\xc9\x53\x67\x42\x2b\xdf\xca\x5c\xdf\x67\x42\x33\x63\x5d\xde\x53\xf8\x8a\x1c\x39\x32\xc8\xbe\x4c\x78\x26\xc2\xbf\x10\x7e\x6d\xa9\x7f\x73\x7e\xcb\xb9\x99\xd0\x25\xc2\xab\x91\xf5\xc6\xab\x4c\xec\xaf\x84\x57\x25\xeb\xb9\xe8\xd2\xca\x7b\x27\x7a\x78\x64\xaa\x75\x3f\xf2\x25\x5e\xed\xd0\xc8\x99\x71\xa9\xe7\x20\x0f\xba\x67\xec\x31\x7d\xa0\x9f\x79\xb5\x47\x2a\xfc\xe6\x9c\x23\xf2\x64\xa9\xfc\x96\x33\xb2\x4e\x75\xad\xe1\x87\xec\xb2\xde\xcd\xd5\xbe\x9d\xd0\x77\xb2\x56\xb7\x26\x27\xfa\x0a\xad\x97\xf3\xe6\xf2\x74\x42\x9b\xc9\x5a\xd1\xa8\x1d\x3c\xb6\x90\xef\x99\xf0\x9f\x21\xa3\xbc\x37\x22\x43\x2e\xbf\x67\x8d\xd2\x35\xc2\xa7\x8b\x55\xff\xb9\xec\x6f\x9d\xda\x1f\xdd\xb1\x23\x32\xa0\xb3\xcb\x55\x76\x37\x53\xbb\xb2\x07\xbb\xc4\x8d\xd9\xc6\xec\x82\x4c\xe5\xce\x5f\x9d\xca\x11\xa3\x7b\xaa\x67\x37\x22\x7b\x33\xd7\xf5\xd2\xe8\xb3\x58\x6d\xd6\xa4\x26\x8f\x7c\xf7\xad\xc6\x0b\xb6\xab\x63\xd5\x31\xae\x35\x6e\x5c\xaa\xbe\xc3\xe7\xe8\xc6\x7a\x5c\x68\x6c\x34\x89\xc6\x09\x72\xa1\x53\x22\x7f\x6b\x7c\x3e\x53\xff\x84\xd8\x60\xaf\x9c\x9b\x63\x37\xa7\x7c\x6a\xe1\x99\xca\xd9\x73\xe4\x27\x6e\xe7\x16\x9f\xb5\x9e\x41\x1c\xe3\xff\x58\xbe\xfb\x4c\x7d\x55\x13\x83\xb9\xea\xdf\xcd\xf4\x3d\x4b\x54\x16\xe8\x90\x21\xc6\xe7\x7c\x2b\x95\x7f\xb0\xbf\xf9\x33\x11\x9a\x5a\xfe\xa6\xb1\xc6\x46\xdd\x29\x3d\xb2\x95\x42\xef\xe5\x3c\x1f\xab\xfd\xb1\x67\xd3\xe8\x1a\x39\x32\x6b\xd5\x27\xe4\x12\xf1\x80\x4c\x9c\x8d\x0d\xab\xc6\xe4\x91\xf5\x2a\xd5\x3c\xc4\x5f\xc8\x0f\x3d\xfc\xb1\x2d\x32\x04\xdb\x77\x9a\x2f\x9d\xd0\x95\x33\xe5\x93\xcd\xd5\x26\xb1\xd9\x0b\x3f\x20\x53\x2e\xdf\xd3\x54\x6d\x87\x5c\xd0\x73\x46\x26\xfc\x92\x5a\xf9\x12\x77\xc4\x2a\x39\x92\x52\x07\x62\xfd\x8e\x1d\xdd\x5c\x73\x0a\xbd\xf3\x46\x73\x07\x9f\x27\x95\xc6\x05\x3e\x2b\xf9\xe6\x54\xdf\x62\xae\xf2\x39\xe2\x51\xd6\xf2\x9d\xef\x67\xca\x8b\x98\x6d\x84\x7f\x5a\xaa\xcd\x89\x4f\x6a\x0f\xf9\xe8\x88\x4b\x6a\x45\xab\xf9\x01\x0d\xb6\xc0\x3f\xc4\x45\xee\x55\x86\xac\xd5\x38\xa7\x46\xa4\xb9\xca\x4b\x5c\x06\xfd\xe7\x7a\x2e\x36\x20\x2e\xc9\x1b\xea\x0d\xf1\x04\x7d\x38\xa7\x50\x9f\x20\x4b\xa8\x83\xb2\xe6\x1b\x8d\x9d\x32\x56\xfe\xd4\x33\x74\x6e\x5b\x95\x89\xdf\xd8\x3c\x2b\xd5\x6e\x9e\x73\x85\x6f\x21\x67\x75\x4e\x6b\x50\x4e\xac\x41\x97\x6a\x8c\xe1\x3b\x7c\x0e\x0f\xd6\x52\xf8\xce\x35\x1f\xa8\x87\xf8\x9b\xbc\xad\xac\x9e\xc2\x1f\x1f\x38\xe8\x0a\xd5\xbb\x6e\xd4\x0e\xd8\x98\x78\xe5\x0c\x7c\x48\x5d\x46\x5f\xe2\xa4\xc3\xbe\x8d\xd6\x49\x6a\x98\x9f\x69\xfc\x97\xd4\xac\x4e\x75\xca\x89\x7f\x7c\x25\xeb\x75\xa5\xfe\xa5\x2e\x84\x5e\x50\x6a\x2d\xaf\x9d\xfa\x9c\xb8\x22\x8e\x76\xbd\x81\xda\xc7\xe3\xbc\xd6\x39\x72\x88\x5a\x4e\x3d\x8a\xf3\x1d\xdd\xf1\x6e\x4a\xfc\xa8\x86\x64\x43\xcd\xbe\x61\x71\x37\xfa\xdc\x19\x36\x65\x4a\xfa\xb8\x3e\x77\x22\x94\xc7\x1f\x7b\xef\x38\x16\xea\xc9\xed\xe8\xf2\x51\xfc\x91\xf8\x6f\x61\xf6\xba\x2b\x71\x18\xbe\x6e\x27\xdc\x4f\xd1\xff\xb1\xc1\xf2\x76\x1e\x0c\x13\x9d\x30\xff\x60\x4c\x78\xcb\x00\x75\x16\x7d\x82\xca\x11\x73\xd3\x59\x94\xcc\xaa\xea\x24\x62\x04\x3a\xbb\x3b\x21\x8d\xb3\x59\x31\x09\xeb\x0c\x36\x67\x3a\xf8\xfc\x6b\xd5\xdf\x8c\x93\x93\x28\x9e\xc8\x04\xeb\x90\xe2\xbb\x60\x82\xb7\x41\xef\xb3\xc8\xd4\x47\xc4\xb3\x28\xfc\x79\x77\xeb\x45\x77\xf2\xd0\xb0\x72\xe7\x92\xf7\xd4\x21\x85\x46\x15\x9a\x43\xae\x8d\x21\x0c\x02\xad\x06\x78\x6a\xcd\x34\x6d\xb4\x40\x42\x03\x3f\x12\x91\x42\x5d\x92\x40\x99\xf2\x25\x21\xe3\x56\x0b\x16\x34\xbc\x97\x99\x36\xe9\xd2\x12\x2f\xab\x8c\xff\x5c\xf9\x73\x4e\x5a\x6b\xf3\x21\xd9\x59\xa3\x79\x52\x58\x48\x74\x8a\x13\x0d\x8a\x06\x5d\xc9\xbe\xd4\x9e\xd0\xb0\xbd\x26\x1a\xc3\x45\x18\x8a\xbc\x36\xb2\xd8\x92\x90\x42\x4c\xc1\xa4\xe9\x30\x8c\x70\x06\x6b\x24\x31\xbc\x29\x60\x99\x35\x7f\x74\xeb\xec\x99\xd9\xbe\xca\x68\x28\xfa\x14\xcd\xbc\xf9\xb3\xb9\x23\x43\x90\x27\xd1\xa4\xde\x9d\x59\x54\x5a\x44\x90\x99\x81\x85\x46\x91\xdb\x10\x46\xf1\x0c\x83\x1b\xf6\x73\x5a\xac\xd1\x8f\x82\x05\x2d\xcd\x9c\x26\x40\x71\xe2\x8c\x38\xbd\x5f\x40\x90\xa9\xb6\xc6\x1b\x0a\xbd\xbf\xe3\xdb\x83\x05\xe4\xfd\x20\xf9\xec\xc2\xf1\x3e\xbb\xfd\x05\xe3\x03\xf0\xe1\xc1\x42\xf1\x3e\xbf\x27\x14\x88\xbd\xfa\x7d\xb1\xc2\x70\x4f\xb5\x5d\x41\x48\x8b\xaf\x5f\x0f\xee\x01\x3a\x7f\x95\xaa\x00\xaf\xd4\x46\x65\xde\x43\xb6\x76\xba\xc6\x35\x25\x35\x1e\xb4\x62\xf6\x87\xbd\x89\xbe\x73\x45\xa0\x85\x73\x5e\x97\xeb\x93\x5b\xc6\x05\x39\xbd\x65\x7a\xae\x99\x97\xd9\xb8\xcb\xd5\x83\x73\xe1\x03\xef\x50\x9d\x9c\x55\x26\x1b\x3f\x53\x1b\x1b\xbc\x5d\x4d\xc8\x74\xf4\x09\x72\xd8\x75\x80\xf1\xb1\x95\x27\x49\x75\x0c\xa2\x02\x90\xf9\xce\x59\xf5\x28\x74\x4c\x67\x6c\x9b\xdb\xf8\x9e\xc4\xf7\xb3\x3b\xb5\xea\xe8\xed\x2a\xc3\xf5\xe3\xf1\xec\xde\xe7\xf2\xcf\xce\xf1\x7d\x4c\xf7\x67\xfa\x5e\x08\xf1\xc1\x7c\xdf\xc7\xfb\x09\x59\xff\x80\xde\x5f\x2c\xf7\x0f\x28\xbb\xab\x00\x49\xf2\xf5\x2b\xc0\x07\x40\xed\x5f\x21\xff\x89\xfb\x5d\x8e\x93\xab\xe1\x2c\xcb\x41\xf2\xf8\x53\x73\x9e\x1c\x6e\x6a\x9b\x28\x6a\xe5\xcd\x39\xc8\x10\xce\x9a\xeb\x15\x81\xdf\xbb\xdc\x0e\xdd\x36\xbb\x9f\x93\x5c\x01\x81\x11\xb8\x2e\x61\x37\xae\x43\x8f\xe7\xe4\x7d\x27\x7c\x76\x46\xde\x67\xb9\x3f\x1f\xf7\x00\xf5\x0f\x66\xe3\x7d\xbe\x4f\xc8\xc5\x83\xfa\x7e\xb1\x4c\xdc\xab\xa6\xe5\x61\x11\x7f\xfd\x34\xdc\xff\xff\x20\x4f\xcd\x46\x2e\xc3\xf3\x58\xa3\x9f\xae\x05\xe8\x71\x0b\x24\x72\x79\xed\x34\x1b\x98\x6f\x01\xff\xc8\x38\xf6\x17\xa9\xd2\xd2\xc5\x98\x93\x99\x4b\x01\x9a\x62\x03\x43\x98\x21\xc3\xdc\x69\x73\x38\x59\x19\x2e\xfb\x06\x70\x39\x03\x1d\x99\x75\x99\x9b\x59\xe3\x72\xcc\xac\xcd\xe5\x9b\x8b\x2c\xc0\x40\x6c\xc0\x1a\xf3\x6f\x90\xc5\xe9\x85\xbf\xab\xf5\x3d\xb5\x4c\x62\x2f\x97\x74\x66\x69\xf6\xd3\x0d\x01\x0b\x00\x31\x00\x52\xb8\xb0\x03\x16\x71\x79\x4e\x0d\x2c\x00\x7c\x09\xdd\x32\xd3\xb9\x3d\x37\x70\x32\x00\x65\x00\x39\x99\x82\x78\x85\x81\x39\xb5\xd9\xc3\x1b\xb0\x0a\xa0\x1a\x1b\x40\x53\x94\xba\x06\x30\x04\xaf\xaa\xb5\x3b\x42\xa3\xa0\x5b\x6e\x15\x00\x70\x00\xc0\x0b\xc0\x04\xb9\x01\x11\xd0\x1d\x20\x36\xd8\xa1\x54\xe0\xb1\xb6\xca\x02\x00\x48\x57\x77\xb5\x76\x7c\x40\x1c\xaa\x27\xa0\x14\xfb\x59\x07\x3c\x05\x64\x00\x2c\x40\xd7\x00\x3e\x65\x0a\x6c\xa1\xf3\xdc\x40\x27\x78\xe3\xc3\xa6\xd2\x29\x82\xc9\xa2\xb0\x89\x03\xdf\x00\x20\xa1\x4b\x00\x53\xb1\x05\x3e\x28\xd5\xd7\xe8\x1d\x6c\x54\x2b\xf8\x1b\x64\x91\xef\x33\x03\xb9\x00\x2e\x00\x4b\x90\x3d\x35\x50\x97\x38\xc2\x56\x00\x63\x54\x5d\x40\x4a\xc0\x53\xe8\x01\xae\x00\x87\x6a\x03\x3b\x91\x8f\x7d\x9c\x99\x9a\x2c\x99\xc5\x67\x00\x5d\x1b\x3d\x97\x29\xae\x33\xe0\x1b\x40\x16\x5a\x26\x1a\xec\x4c\x3c\x31\x49\xd5\x06\x24\xe2\x0f\xc0\x3c\xc0\x16\xe4\x4e\xed\x6e\x83\x5c\x00\x7b\x80\x4b\x8d\xf1\x72\x06\x4c\x05\x70\xac\x52\x10\x89\x18\x63\x1f\x40\x51\x65\x20\x17\xdd\x07\x7d\x00\xba\xd9\x1f\x40\x3c\xa7\xb1\x8a\xaf\xb0\x03\x7b\x2a\xab\xfc\xc4\x58\x00\x8a\x66\x7a\xf7\x44\x26\x57\x19\xf0\xed\x34\x4f\x39\x3b\x31\x79\xb8\x77\x11\x23\xb1\x81\x61\x80\x73\xd8\x26\x80\xec\x06\x1e\x03\x2e\x71\x16\xb2\x38\x03\xf4\x5a\xbb\xeb\x66\x99\xfa\x0e\xbf\x05\x10\xb5\x51\xff\x32\x41\xee\xf4\x09\xf9\xd0\x69\xa7\x0a\x31\xe8\xd4\xee\xe4\x06\x20\x1c\xa0\x16\xf6\x23\xb7\x82\x6d\xbd\xc6\x10\x76\x23\x27\xa0\x05\x44\xed\x0c\x78\xfd\xb0\xb3\x91\xaf\xf8\x3b\xe8\xd9\x6a\xce\x86\x7b\xe7\x83\x9d\xed\x60\x5d\xfb\xec\x06\x77\x90\xf3\xfe\x3e\x77\xf8\x3f\x9a\x1f\x6c\x77\x07\x4f\x79\x42\xd7\x7b\xcc\x16\xf7\x9a\xdf\xff\x02\x00\x00\xff\xff\x3c\x2b\x49\x80
\x00\x20\x00\x00
"
)
func
dbMigrationsAssetsGoBytes
()
([]
byte
,
error
)
{
func
dbMigrationsAssetsGoBytes
()
([]
byte
,
error
)
{
return
bindataRead
(
return
bindataRead
(
...
...
db/refresh.go
View file @
e077803e
package
db
package
db
import
(
import
(
"encoding/base64"
"errors"
"errors"
"fmt"
"fmt"
"strconv"
"strconv"
...
@@ -31,7 +32,7 @@ type refreshTokenRepo struct {
...
@@ -31,7 +32,7 @@ type refreshTokenRepo struct {
type
refreshTokenModel
struct
{
type
refreshTokenModel
struct
{
ID
int64
`db:"id"`
ID
int64
`db:"id"`
PayloadHash
string
`db:"payload_hash"`
PayloadHash
[]
byte
`db:"payload_hash"`
// TODO(yifan): Use some sort of foreign key to manage database level
// TODO(yifan): Use some sort of foreign key to manage database level
// data integrity.
// data integrity.
UserID
string
`db:"user_id"`
UserID
string
`db:"user_id"`
...
@@ -39,25 +40,29 @@ type refreshTokenModel struct {
...
@@ -39,25 +40,29 @@ type refreshTokenModel struct {
}
}
// buildToken combines the token ID and token payload to create a new token.
// buildToken combines the token ID and token payload to create a new token.
func
buildToken
(
tokenID
int64
,
tokenPayload
string
)
string
{
func
buildToken
(
tokenID
int64
,
tokenPayload
[]
byte
)
string
{
return
fmt
.
Sprintf
(
"%d%s%s"
,
tokenID
,
refresh
.
TokenDelimer
,
tokenPayload
)
return
fmt
.
Sprintf
(
"%d%s%s"
,
tokenID
,
refresh
.
TokenDelimer
,
base64
.
URLEncoding
.
EncodeToString
(
tokenPayload
)
)
}
}
// parseToken parses a token and returns the token ID and token payload.
// parseToken parses a token and returns the token ID and token payload.
func
parseToken
(
token
string
)
(
int64
,
string
,
error
)
{
func
parseToken
(
token
string
)
(
int64
,
[]
byte
,
error
)
{
parts
:=
strings
.
SplitN
(
token
,
refresh
.
TokenDelimer
,
2
)
parts
:=
strings
.
SplitN
(
token
,
refresh
.
TokenDelimer
,
2
)
if
len
(
parts
)
!=
2
{
if
len
(
parts
)
!=
2
{
return
-
1
,
""
,
refresh
.
ErrorInvalidToken
return
-
1
,
nil
,
refresh
.
ErrorInvalidToken
}
}
id
,
err
:=
strconv
.
ParseInt
(
parts
[
0
],
0
,
64
)
id
,
err
:=
strconv
.
ParseInt
(
parts
[
0
],
0
,
64
)
if
err
!=
nil
{
if
err
!=
nil
{
return
-
1
,
""
,
refresh
.
ErrorInvalidToken
return
-
1
,
nil
,
refresh
.
ErrorInvalidToken
}
}
return
id
,
parts
[
1
],
nil
tokenPayload
,
err
:=
base64
.
URLEncoding
.
DecodeString
(
parts
[
1
])
if
err
!=
nil
{
return
-
1
,
nil
,
refresh
.
ErrorInvalidToken
}
return
id
,
tokenPayload
,
nil
}
}
func
checkTokenPayload
(
payloadHash
,
payload
string
)
error
{
func
checkTokenPayload
(
payloadHash
,
payload
[]
byte
)
error
{
if
err
:=
bcrypt
.
CompareHashAndPassword
(
[]
byte
(
payloadHash
),
[]
byte
(
payload
)
);
err
!=
nil
{
if
err
:=
bcrypt
.
CompareHashAndPassword
(
payloadHash
,
payload
);
err
!=
nil
{
switch
err
{
switch
err
{
case
bcrypt
.
ErrMismatchedHashAndPassword
:
case
bcrypt
.
ErrMismatchedHashAndPassword
:
return
refresh
.
ErrorInvalidToken
return
refresh
.
ErrorInvalidToken
...
@@ -89,13 +94,13 @@ func (r *refreshTokenRepo) Create(userID, clientID string) (string, error) {
...
@@ -89,13 +94,13 @@ func (r *refreshTokenRepo) Create(userID, clientID string) (string, error) {
return
""
,
err
return
""
,
err
}
}
payloadHash
,
err
:=
bcrypt
.
GenerateFromPassword
(
[]
byte
(
tokenPayload
)
,
bcrypt
.
DefaultCost
)
payloadHash
,
err
:=
bcrypt
.
GenerateFromPassword
(
tokenPayload
,
bcrypt
.
DefaultCost
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
record
:=
&
refreshTokenModel
{
record
:=
&
refreshTokenModel
{
PayloadHash
:
string
(
payloadHash
)
,
PayloadHash
:
payloadHash
,
UserID
:
userID
,
UserID
:
userID
,
ClientID
:
clientID
,
ClientID
:
clientID
,
}
}
...
@@ -109,6 +114,7 @@ func (r *refreshTokenRepo) Create(userID, clientID string) (string, error) {
...
@@ -109,6 +114,7 @@ func (r *refreshTokenRepo) Create(userID, clientID string) (string, error) {
func
(
r
*
refreshTokenRepo
)
Verify
(
clientID
,
token
string
)
(
string
,
error
)
{
func
(
r
*
refreshTokenRepo
)
Verify
(
clientID
,
token
string
)
(
string
,
error
)
{
tokenID
,
tokenPayload
,
err
:=
parseToken
(
token
)
tokenID
,
tokenPayload
,
err
:=
parseToken
(
token
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
...
functional/db_test.go
View file @
e077803e
package
functional
package
functional
import
(
import
(
"encoding/base64"
"fmt"
"fmt"
"net/url"
"net/url"
"os"
"os"
...
@@ -342,6 +343,12 @@ func TestDBClientIdentityAll(t *testing.T) {
...
@@ -342,6 +343,12 @@ func TestDBClientIdentityAll(t *testing.T) {
}
}
}
}
// buildRefreshToken combines the token ID and token payload to create a new token.
// used in the tests to created a refresh token.
func
buildRefreshToken
(
tokenID
int64
,
tokenPayload
[]
byte
)
string
{
return
fmt
.
Sprintf
(
"%d%s%s"
,
tokenID
,
refresh
.
TokenDelimer
,
base64
.
URLEncoding
.
EncodeToString
(
tokenPayload
))
}
func
TestDBRefreshRepoCreate
(
t
*
testing
.
T
)
{
func
TestDBRefreshRepoCreate
(
t
*
testing
.
T
)
{
r
:=
db
.
NewRefreshTokenRepo
(
connect
(
t
))
r
:=
db
.
NewRefreshTokenRepo
(
connect
(
t
))
...
@@ -383,6 +390,13 @@ func TestDBRefreshRepoVerify(t *testing.T) {
...
@@ -383,6 +390,13 @@ func TestDBRefreshRepoVerify(t *testing.T) {
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
}
badTokenPayload
,
err
:=
refresh
.
DefaultRefreshTokenGenerator
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
tokenWithBadID
:=
"404"
+
token
[
1
:
]
tokenWithBadPayload
:=
buildRefreshToken
(
1
,
badTokenPayload
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
token
string
token
string
creds
oidc
.
ClientCredentials
creds
oidc
.
ClientCredentials
...
@@ -390,7 +404,39 @@ func TestDBRefreshRepoVerify(t *testing.T) {
...
@@ -390,7 +404,39 @@ func TestDBRefreshRepoVerify(t *testing.T) {
expected
string
expected
string
}{
}{
{
{
"invalid-token-foo"
,
"invalid-token-format"
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
""
,
},
{
"b/invalid-base64-encoded-format"
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
""
,
},
{
"1/invalid-base64-encoded-format"
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
""
,
},
{
token
+
"corrupted-token-payload"
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
""
,
},
{
// The token's ID content is invalid.
tokenWithBadID
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
""
,
},
{
// The token's payload content is invalid.
tokenWithBadPayload
,
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
oidc
.
ClientCredentials
{
ID
:
"client-foo"
,
Secret
:
"secret-foo"
},
refresh
.
ErrorInvalidToken
,
refresh
.
ErrorInvalidToken
,
""
,
""
,
...
@@ -428,13 +474,42 @@ func TestDBRefreshRepoRevoke(t *testing.T) {
...
@@ -428,13 +474,42 @@ func TestDBRefreshRepoRevoke(t *testing.T) {
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
}
badTokenPayload
,
err
:=
refresh
.
DefaultRefreshTokenGenerator
()
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
tokenWithBadID
:=
"404"
+
token
[
1
:
]
tokenWithBadPayload
:=
buildRefreshToken
(
1
,
badTokenPayload
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
token
string
token
string
userID
string
userID
string
err
error
err
error
}{
}{
{
{
"invalid-token-foo"
,
"invalid-token-format"
,
"user-foo"
,
refresh
.
ErrorInvalidToken
,
},
{
"1/invalid-base64-encoded-format"
,
"user-foo"
,
refresh
.
ErrorInvalidToken
,
},
{
token
+
"corrupted-token-payload"
,
"user-foo"
,
refresh
.
ErrorInvalidToken
,
},
{
// The token's ID is invalid.
tokenWithBadID
,
"user-foo"
,
refresh
.
ErrorInvalidToken
,
},
{
// The token's payload is invalid.
tokenWithBadPayload
,
"user-foo"
,
"user-foo"
,
refresh
.
ErrorInvalidToken
,
refresh
.
ErrorInvalidToken
,
},
},
...
...
refresh/refreshtest/repo.go
View file @
e077803e
...
@@ -10,9 +10,9 @@ import (
...
@@ -10,9 +10,9 @@ import (
// The tokens are in the form { refresh-1, refresh-2 ... refresh-n}.
// The tokens are in the form { refresh-1, refresh-2 ... refresh-n}.
func
NewTestRefreshTokenRepo
()
(
refresh
.
RefreshTokenRepo
,
error
)
{
func
NewTestRefreshTokenRepo
()
(
refresh
.
RefreshTokenRepo
,
error
)
{
var
tokenIdx
int
var
tokenIdx
int
tokenGenerator
:=
func
()
(
string
,
error
)
{
tokenGenerator
:=
func
()
(
[]
byte
,
error
)
{
tokenIdx
++
tokenIdx
++
return
fmt
.
Sprintf
(
"refresh-%d"
,
tokenIdx
),
nil
return
[]
byte
(
fmt
.
Sprintf
(
"refresh-%d"
,
tokenIdx
)
),
nil
}
}
return
refresh
.
NewRefreshTokenRepoWithTokenGenerator
(
tokenGenerator
),
nil
return
refresh
.
NewRefreshTokenRepoWithTokenGenerator
(
tokenGenerator
),
nil
}
}
refresh/repo.go
View file @
e077803e
package
refresh
package
refresh
import
(
import
(
"bytes"
"crypto/rand"
"crypto/rand"
"encoding/base64"
"errors"
"errors"
"fmt"
"fmt"
"strconv"
"strconv"
...
@@ -17,25 +17,26 @@ const (
...
@@ -17,25 +17,26 @@ const (
var
(
var
(
ErrorInvalidUserID
=
errors
.
New
(
"invalid user ID"
)
ErrorInvalidUserID
=
errors
.
New
(
"invalid user ID"
)
ErrorInvalidClientID
=
errors
.
New
(
"invalid client ID"
)
ErrorInvalidClientID
=
errors
.
New
(
"invalid client ID"
)
ErrorInvalidToken
=
errors
.
New
(
"invalid token"
)
ErrorInvalidToken
=
errors
.
New
(
"invalid token"
)
)
)
type
RefreshTokenGenerator
func
()
(
string
,
error
)
type
RefreshTokenGenerator
func
()
(
[]
byte
,
error
)
func
(
g
RefreshTokenGenerator
)
Generate
()
(
string
,
error
)
{
func
(
g
RefreshTokenGenerator
)
Generate
()
(
[]
byte
,
error
)
{
return
g
()
return
g
()
}
}
func
DefaultRefreshTokenGenerator
()
(
string
,
error
)
{
func
DefaultRefreshTokenGenerator
()
(
[]
byte
,
error
)
{
// TODO(yifan) Remove this duplicated token generate function.
// TODO(yifan) Remove this duplicated token generate function.
b
:=
make
([]
byte
,
DefaultRefreshTokenPayloadLength
)
b
:=
make
([]
byte
,
DefaultRefreshTokenPayloadLength
)
n
,
err
:=
rand
.
Read
(
b
)
n
,
err
:=
rand
.
Read
(
b
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
nil
,
err
}
else
if
n
!=
DefaultRefreshTokenPayloadLength
{
}
else
if
n
!=
DefaultRefreshTokenPayloadLength
{
return
""
,
errors
.
New
(
"unable to read enough random bytes"
)
return
nil
,
errors
.
New
(
"unable to read enough random bytes"
)
}
}
return
b
ase64
.
URLEncoding
.
EncodeToString
(
b
)
,
nil
return
b
,
nil
}
}
type
RefreshTokenRepo
interface
{
type
RefreshTokenRepo
interface
{
...
@@ -52,7 +53,7 @@ type RefreshTokenRepo interface {
...
@@ -52,7 +53,7 @@ type RefreshTokenRepo interface {
}
}
type
refreshToken
struct
{
type
refreshToken
struct
{
payload
string
payload
[]
byte
userID
string
userID
string
clientID
string
clientID
string
}
}
...
@@ -63,21 +64,21 @@ type memRefreshTokenRepo struct {
...
@@ -63,21 +64,21 @@ type memRefreshTokenRepo struct {
}
}
// buildToken combines the token ID and token payload to create a new token.
// buildToken combines the token ID and token payload to create a new token.
func
buildToken
(
tokenID
int
,
tokenPayload
string
)
string
{
func
buildToken
(
tokenID
int
,
tokenPayload
[]
byte
)
string
{
return
fmt
.
Sprintf
(
"%d%s%s"
,
tokenID
,
TokenDelimer
,
tokenPayload
)
return
fmt
.
Sprintf
(
"%d%s%s"
,
tokenID
,
TokenDelimer
,
tokenPayload
)
}
}
// parseToken parses a token and returns the token ID and token payload.
// parseToken parses a token and returns the token ID and token payload.
func
parseToken
(
token
string
)
(
int
,
string
,
error
)
{
func
parseToken
(
token
string
)
(
int
,
[]
byte
,
error
)
{
parts
:=
strings
.
SplitN
(
token
,
TokenDelimer
,
2
)
parts
:=
strings
.
SplitN
(
token
,
TokenDelimer
,
2
)
if
len
(
parts
)
!=
2
{
if
len
(
parts
)
!=
2
{
return
-
1
,
""
,
ErrorInvalidToken
return
-
1
,
nil
,
ErrorInvalidToken
}
}
id
,
err
:=
strconv
.
Atoi
(
parts
[
0
])
id
,
err
:=
strconv
.
Atoi
(
parts
[
0
])
if
err
!=
nil
{
if
err
!=
nil
{
return
-
1
,
""
,
ErrorInvalidToken
return
-
1
,
nil
,
ErrorInvalidToken
}
}
return
id
,
parts
[
1
]
,
nil
return
id
,
[]
byte
(
parts
[
1
])
,
nil
}
}
// NewRefreshTokenRepo returns an in-memory RefreshTokenRepo useful for development.
// NewRefreshTokenRepo returns an in-memory RefreshTokenRepo useful for development.
...
@@ -131,7 +132,7 @@ func (r *memRefreshTokenRepo) Verify(clientID, token string) (string, error) {
...
@@ -131,7 +132,7 @@ func (r *memRefreshTokenRepo) Verify(clientID, token string) (string, error) {
return
""
,
ErrorInvalidToken
return
""
,
ErrorInvalidToken
}
}
if
record
.
payload
!=
tokenPayload
{
if
!
bytes
.
Equal
(
record
.
payload
,
tokenPayload
)
{
return
""
,
ErrorInvalidToken
return
""
,
ErrorInvalidToken
}
}
...
@@ -153,7 +154,7 @@ func (r *memRefreshTokenRepo) Revoke(userID, token string) error {
...
@@ -153,7 +154,7 @@ func (r *memRefreshTokenRepo) Revoke(userID, token string) error {
return
ErrorInvalidToken
return
ErrorInvalidToken
}
}
if
record
.
payload
!=
tokenPayload
{
if
!
bytes
.
Equal
(
record
.
payload
,
tokenPayload
)
{
return
ErrorInvalidToken
return
ErrorInvalidToken
}
}
...
...
server/server_test.go
View file @
e077803e
...
@@ -397,7 +397,7 @@ func TestServerTokenFail(t *testing.T) {
...
@@ -397,7 +397,7 @@ func TestServerTokenFail(t *testing.T) {
signer
jose
.
Signer
signer
jose
.
Signer
argCC
oidc
.
ClientCredentials
argCC
oidc
.
ClientCredentials
argKey
string
argKey
string
err
string
err
error
scope
[]
string
scope
[]
string
refreshToken
string
refreshToken
string
}{
}{
...
@@ -423,7 +423,7 @@ func TestServerTokenFail(t *testing.T) {
...
@@ -423,7 +423,7 @@ func TestServerTokenFail(t *testing.T) {
signer
:
signerFixture
,
signer
:
signerFixture
,
argCC
:
ccFixture
,
argCC
:
ccFixture
,
argKey
:
"foo"
,
argKey
:
"foo"
,
err
:
oauth2
.
ErrorInvalidGrant
,
err
:
oauth2
.
NewError
(
oauth2
.
ErrorInvalidGrant
)
,
scope
:
[]
string
{
"openid"
,
"offline_access"
},
scope
:
[]
string
{
"openid"
,
"offline_access"
},
},
},
...
@@ -432,7 +432,7 @@ func TestServerTokenFail(t *testing.T) {
...
@@ -432,7 +432,7 @@ func TestServerTokenFail(t *testing.T) {
signer
:
signerFixture
,
signer
:
signerFixture
,
argCC
:
oidc
.
ClientCredentials
{
ID
:
"YYY"
},
argCC
:
oidc
.
ClientCredentials
{
ID
:
"YYY"
},
argKey
:
keyFixture
,
argKey
:
keyFixture
,
err
:
oauth2
.
ErrorInvalidClient
,
err
:
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
scope
:
[]
string
{
"openid"
,
"offline_access"
},
scope
:
[]
string
{
"openid"
,
"offline_access"
},
},
},
...
@@ -441,7 +441,7 @@ func TestServerTokenFail(t *testing.T) {
...
@@ -441,7 +441,7 @@ func TestServerTokenFail(t *testing.T) {
signer
:
&
StaticSigner
{
sig
:
nil
,
err
:
errors
.
New
(
"fail"
)},
signer
:
&
StaticSigner
{
sig
:
nil
,
err
:
errors
.
New
(
"fail"
)},
argCC
:
ccFixture
,
argCC
:
ccFixture
,
argKey
:
keyFixture
,
argKey
:
keyFixture
,
err
:
oauth2
.
ErrorServerError
,
err
:
oauth2
.
NewError
(
oauth2
.
ErrorServerError
)
,
scope
:
[]
string
{
"openid"
,
"offline_access"
},
scope
:
[]
string
{
"openid"
,
"offline_access"
},
},
},
}
}
...
@@ -502,18 +502,14 @@ func TestServerTokenFail(t *testing.T) {
...
@@ -502,18 +502,14 @@ func TestServerTokenFail(t *testing.T) {
t
.
Fatalf
(
"case %d: expect refresh token %q, got %q"
,
i
,
tt
.
refreshToken
,
token
)
t
.
Fatalf
(
"case %d: expect refresh token %q, got %q"
,
i
,
tt
.
refreshToken
,
token
)
panic
(
""
)
panic
(
""
)
}
}
if
tt
.
err
==
""
{
if
!
reflect
.
DeepEqual
(
err
,
tt
.
err
)
{
if
err
!=
nil
{
t
.
Errorf
(
"case %d: expect %v, got %v"
,
i
,
tt
.
err
,
err
)
t
.
Errorf
(
"case %d: got non-nil error: %v"
,
i
,
err
)
}
else
if
jwt
==
nil
{
t
.
Errorf
(
"case %d: got nil JWT"
,
i
)
}
}
}
else
{
if
err
==
nil
&&
jwt
==
nil
{
if
err
.
Error
()
!=
tt
.
err
{
t
.
Errorf
(
"case %d: got nil JWT"
,
i
)
t
.
Errorf
(
"case %d: want err %q, got %q"
,
i
,
tt
.
err
,
err
.
Error
())
}
else
if
jwt
!=
nil
{
t
.
Errorf
(
"case %d: got non-nil JWT"
,
i
)
}
}
if
err
!=
nil
&&
jwt
!=
nil
{
t
.
Errorf
(
"case %d: got non-nil JWT %v"
,
i
,
jwt
)
}
}
}
}
}
}
...
@@ -537,7 +533,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -537,7 +533,7 @@ func TestServerRefreshToken(t *testing.T) {
clientID
string
// The client that associates with the token.
clientID
string
// The client that associates with the token.
creds
oidc
.
ClientCredentials
creds
oidc
.
ClientCredentials
signer
jose
.
Signer
signer
jose
.
Signer
err
string
err
error
}{
}{
// Everything is good.
// Everything is good.
{
{
...
@@ -545,7 +541,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -545,7 +541,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
credXXX
,
credXXX
,
signerFixture
,
signerFixture
,
""
,
nil
,
},
},
// Invalid refresh token(malformatted).
// Invalid refresh token(malformatted).
{
{
...
@@ -553,15 +549,23 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -553,15 +549,23 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
credXXX
,
credXXX
,
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidRequest
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidRequest
)
,
},
},
// Invalid refresh token.
// Invalid refresh token
(invalid payload content)
.
{
{
"0/refresh-
1
"
,
"0/refresh-
2
"
,
"XXX"
,
"XXX"
,
credXXX
,
credXXX
,
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidRequest
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidRequest
),
},
// Invalid refresh token(invalid ID content).
{
"1/refresh-2"
,
"XXX"
,
credXXX
,
signerFixture
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidRequest
),
},
},
// Invalid client(client is not associated with the token).
// Invalid client(client is not associated with the token).
{
{
...
@@ -569,7 +573,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -569,7 +573,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
credYYY
,
credYYY
,
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidClient
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
},
},
// Invalid client(no client ID).
// Invalid client(no client ID).
{
{
...
@@ -577,7 +581,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -577,7 +581,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
oidc
.
ClientCredentials
{
ID
:
""
,
Secret
:
"aaa"
},
oidc
.
ClientCredentials
{
ID
:
""
,
Secret
:
"aaa"
},
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidClient
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
},
},
// Invalid client(no such client).
// Invalid client(no such client).
{
{
...
@@ -585,7 +589,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -585,7 +589,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
oidc
.
ClientCredentials
{
ID
:
"AAA"
,
Secret
:
"aaa"
},
oidc
.
ClientCredentials
{
ID
:
"AAA"
,
Secret
:
"aaa"
},
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidClient
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
},
},
// Invalid client(no secrets).
// Invalid client(no secrets).
{
{
...
@@ -593,7 +597,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -593,7 +597,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
oidc
.
ClientCredentials
{
ID
:
"XXX"
},
oidc
.
ClientCredentials
{
ID
:
"XXX"
},
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidClient
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
},
},
// Invalid client(invalid secret).
// Invalid client(invalid secret).
{
{
...
@@ -601,7 +605,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -601,7 +605,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
oidc
.
ClientCredentials
{
ID
:
"XXX"
,
Secret
:
"bad-secret"
},
oidc
.
ClientCredentials
{
ID
:
"XXX"
,
Secret
:
"bad-secret"
},
signerFixture
,
signerFixture
,
oauth2
.
ErrorInvalidClient
,
oauth2
.
NewError
(
oauth2
.
ErrorInvalidClient
)
,
},
},
// Signing operation fails.
// Signing operation fails.
{
{
...
@@ -609,7 +613,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -609,7 +613,7 @@ func TestServerRefreshToken(t *testing.T) {
"XXX"
,
"XXX"
,
credXXX
,
credXXX
,
&
StaticSigner
{
sig
:
nil
,
err
:
errors
.
New
(
"fail"
)},
&
StaticSigner
{
sig
:
nil
,
err
:
errors
.
New
(
"fail"
)},
oauth2
.
ErrorServerError
,
oauth2
.
NewError
(
oauth2
.
ErrorServerError
)
,
},
},
}
}
...
@@ -646,11 +650,9 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -646,11 +650,9 @@ func TestServerRefreshToken(t *testing.T) {
}
}
jwt
,
err
:=
srv
.
RefreshToken
(
tt
.
creds
,
tt
.
token
)
jwt
,
err
:=
srv
.
RefreshToken
(
tt
.
creds
,
tt
.
token
)
if
err
!=
nil
{
if
!
reflect
.
DeepEqual
(
err
,
tt
.
err
)
{
if
err
.
Error
()
!=
tt
.
err
{
t
.
Errorf
(
"Case %d: expect: %v, got: %v"
,
i
,
tt
.
err
,
err
)
t
.
Errorf
(
"Case %d: expect: %v, got: %v"
,
i
,
tt
.
err
,
err
)
}
}
}
if
jwt
!=
nil
{
if
jwt
!=
nil
{
if
string
(
jwt
.
Signature
)
!=
"beer"
{
if
string
(
jwt
.
Signature
)
!=
"beer"
{
...
@@ -715,7 +717,7 @@ func TestServerRefreshToken(t *testing.T) {
...
@@ -715,7 +717,7 @@ func TestServerRefreshToken(t *testing.T) {
srv
.
UserRepo
=
userRepo
srv
.
UserRepo
=
userRepo
_
,
err
=
srv
.
RefreshToken
(
credXXX
,
"0/refresh-1"
)
_
,
err
=
srv
.
RefreshToken
(
credXXX
,
"0/refresh-1"
)
if
err
==
nil
||
err
.
Error
()
!=
oauth2
.
ErrorServerError
{
if
!
reflect
.
DeepEqual
(
err
,
oauth2
.
NewError
(
oauth2
.
ErrorServerError
))
{
t
.
Errorf
(
"Expect: %v, got: %v"
,
oauth2
.
ErrorServerError
,
err
)
t
.
Errorf
(
"Expect: %v, got: %v"
,
oauth2
.
NewError
(
oauth2
.
ErrorServerError
)
,
err
)
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment