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
ebe51e73
Commit
ebe51e73
authored
Nov 03, 2016
by
Eric Chiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/dex: accept raw bcrypt'd hash as well as base64'd version of hash
parent
aa7f304b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
156 additions
and
22 deletions
+156
-22
config.go
cmd/dex/config.go
+45
-2
config_test.go
cmd/dex/config_test.go
+105
-18
serve.go
cmd/dex/serve.go
+5
-1
config-dev.yaml
examples/config-dev.yaml
+1
-1
No files found.
cmd/dex/config.go
View file @
ebe51e73
package
main
import
(
"encoding/base64"
"encoding/json"
"fmt"
"golang.org/x/crypto/bcrypt"
"github.com/coreos/dex/connector"
"github.com/coreos/dex/connector/github"
"github.com/coreos/dex/connector/ldap"
...
...
@@ -38,7 +41,47 @@ type Config struct {
// StaticPasswords cause the server use this list of passwords rather than
// querying the storage. Cannot be specified without enabling a passwords
// database.
StaticPasswords
[]
storage
.
Password
`json:"staticPasswords"`
StaticPasswords
[]
password
`json:"staticPasswords"`
}
type
password
storage
.
Password
func
(
p
*
password
)
UnmarshalJSON
(
b
[]
byte
)
error
{
var
data
struct
{
Email
string
`json:"email"`
Username
string
`json:"username"`
UserID
string
`json:"userID"`
Hash
string
`json:"hash"`
}
if
err
:=
json
.
Unmarshal
(
b
,
&
data
);
err
!=
nil
{
return
err
}
*
p
=
password
(
storage
.
Password
{
Email
:
data
.
Email
,
Username
:
data
.
Username
,
UserID
:
data
.
UserID
,
})
if
len
(
data
.
Hash
)
==
0
{
return
fmt
.
Errorf
(
"no password hash provided"
)
}
// If this value is a valid bcrypt, use it.
_
,
bcryptErr
:=
bcrypt
.
Cost
([]
byte
(
data
.
Hash
))
if
bcryptErr
==
nil
{
p
.
Hash
=
[]
byte
(
data
.
Hash
)
return
nil
}
// For backwards compatibility try to base64 decode this value.
hashBytes
,
err
:=
base64
.
StdEncoding
.
DecodeString
(
data
.
Hash
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"malformed bcrypt hash: %v"
,
bcryptErr
)
}
if
_
,
err
:=
bcrypt
.
Cost
(
hashBytes
);
err
!=
nil
{
return
fmt
.
Errorf
(
"malformed bcrypt hash: %v"
,
err
)
}
p
.
Hash
=
hashBytes
return
nil
}
// OAuth2 describes enabled OAuth2 extensions.
...
...
@@ -161,7 +204,7 @@ func (c *Connector) UnmarshalJSON(b []byte) error {
}
*
c
=
Connector
{
Type
:
conn
.
Type
,
Name
:
conn
.
Typ
e
,
Name
:
conn
.
Nam
e
,
ID
:
conn
.
ID
,
Config
:
connConfig
,
}
...
...
cmd/dex/config_test.go
View file @
ebe51e73
...
...
@@ -3,37 +3,124 @@ package main
import
(
"testing"
"github.com/coreos/dex/connector/mock"
"github.com/coreos/dex/connector/oidc"
"github.com/coreos/dex/storage"
"github.com/coreos/dex/storage/sql"
"github.com/ghodss/yaml"
"github.com/kylelemons/godebug/pretty"
yaml
"gopkg.in/yaml.v2"
)
func
TestUnmarshalClients
(
t
*
testing
.
T
)
{
data
:=
`staticClients:
var
_
=
yaml
.
YAMLToJSON
func
TestUnmarshalConfig
(
t
*
testing
.
T
)
{
rawConfig
:=
[]
byte
(
`
issuer: http://127.0.0.1:5556/dex
storage:
type: sqlite3
config:
file: examples/dex.db
web:
http: 127.0.0.1:5556
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
`
var
c
Config
if
err
:=
yaml
.
Unmarshal
([]
byte
(
data
),
&
c
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
wantClients
:=
[]
storage
.
Client
{
{
ID
:
"example-app"
,
Name
:
"Example App"
,
Secret
:
"ZXhhbXBsZS1hcHAtc2VjcmV0"
,
RedirectURIs
:
[]
string
{
"http://127.0.0.1:5555/callback"
,
connectors:
- type: mockCallback
id: mock
name: Example
- type: oidc
id: google
name: Google
config:
issuer: https://accounts.google.com
# Config values starting with a "$" will read from the environment.
clientID: $GOOGLE_CLIENT_ID
clientSecret: $GOOGLE_CLIENT_SECRET
redirectURI: http://127.0.0.1:5556/dex/callback/google
enablePasswordDB: true
staticPasswords:
- email: "admin@example.com"
# bcrypt hash of the string "password"
hash: "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
- email: "foo@example.com"
# base64'd value of the same bcrypt hash above. We want to be able to parse both of these
hash: "JDJhJDEwJDMzRU1UMGNWWVZsUHk2V0FNQ0xzY2VMWWpXaHVIcGJ6NXl1Wnh1L0dBRmowM0o5THl0anV5"
username: "foo"
userID: "41331323-6f44-45e6-b3b9-2c4b60c02be5"
`
)
want
:=
Config
{
Issuer
:
"http://127.0.0.1:5556/dex"
,
Storage
:
Storage
{
Type
:
"sqlite3"
,
Config
:
&
sql
.
SQLite3
{
File
:
"examples/dex.db"
,
},
},
Web
:
Web
{
HTTP
:
"127.0.0.1:5556"
,
},
StaticClients
:
[]
storage
.
Client
{
{
ID
:
"example-app"
,
Secret
:
"ZXhhbXBsZS1hcHAtc2VjcmV0"
,
Name
:
"Example App"
,
RedirectURIs
:
[]
string
{
"http://127.0.0.1:5555/callback"
,
},
},
},
Connectors
:
[]
Connector
{
{
Type
:
"mockCallback"
,
ID
:
"mock"
,
Name
:
"Example"
,
Config
:
&
mock
.
CallbackConfig
{},
},
{
Type
:
"oidc"
,
ID
:
"google"
,
Name
:
"Google"
,
Config
:
&
oidc
.
Config
{
Issuer
:
"https://accounts.google.com"
,
ClientID
:
"$GOOGLE_CLIENT_ID"
,
ClientSecret
:
"$GOOGLE_CLIENT_SECRET"
,
RedirectURI
:
"http://127.0.0.1:5556/dex/callback/google"
,
},
},
},
EnablePasswordDB
:
true
,
StaticPasswords
:
[]
password
{
{
Email
:
"admin@example.com"
,
Hash
:
[]
byte
(
"$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
),
Username
:
"admin"
,
UserID
:
"08a8684b-db88-4b73-90a9-3cd1661f5466"
,
},
{
Email
:
"foo@example.com"
,
Hash
:
[]
byte
(
"$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
),
Username
:
"foo"
,
UserID
:
"41331323-6f44-45e6-b3b9-2c4b60c02be5"
,
},
},
}
if
diff
:=
pretty
.
Compare
(
wantClients
,
c
.
StaticClients
);
diff
!=
""
{
t
.
Errorf
(
"did not get expected clients: %s"
,
diff
)
var
c
Config
if
err
:=
yaml
.
Unmarshal
(
rawConfig
,
&
c
);
err
!=
nil
{
t
.
Fatalf
(
"failed to decode config: %v"
,
err
)
}
if
diff
:=
pretty
.
Compare
(
c
,
want
);
diff
!=
""
{
t
.
Errorf
(
"got!=want: %s"
,
diff
)
}
}
cmd/dex/serve.go
View file @
ebe51e73
...
...
@@ -136,7 +136,11 @@ func serve(cmd *cobra.Command, args []string) error {
s
=
storage
.
WithStaticClients
(
s
,
c
.
StaticClients
)
}
if
len
(
c
.
StaticPasswords
)
>
0
{
s
=
storage
.
WithStaticPasswords
(
s
,
c
.
StaticPasswords
)
passwords
:=
make
([]
storage
.
Password
,
len
(
c
.
StaticPasswords
))
for
i
,
p
:=
range
c
.
StaticPasswords
{
passwords
[
i
]
=
storage
.
Password
(
p
)
}
s
=
storage
.
WithStaticPasswords
(
s
,
passwords
)
}
serverConfig
:=
server
.
Config
{
...
...
examples/config-dev.yaml
View file @
ebe51e73
...
...
@@ -58,7 +58,7 @@ enablePasswordDB: true
staticPasswords
:
-
email
:
"
admin@example.com"
# bcrypt hash of the string "password"
hash
:
"
JDJhJDE0JDh4TnlVZ3pzSmVuQm4ySlRPT2QvbmVGcUlnQzF4TEFVRFA3VlpTVzhDNWlkLnFPcmNlYUJX
"
hash
:
"
$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy
"
username
:
"
admin"
userID
:
"
08a8684b-db88-4b73-90a9-3cd1661f5466"
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