Update godeps
This commit is contained in:
parent
1298cffca2
commit
06938a9f2b
7 changed files with 238 additions and 103 deletions
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
|
@ -17,7 +17,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/mux",
|
||||
"Rev": "8a875a034c69b940914d83ea03d3f1299b4d094b"
|
||||
"Rev": "94903de8c98a68d8b4483c529b26a5d146e386a2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/schema",
|
||||
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/thermokarst/jwt",
|
||||
"Rev": "774185ba9ebde2a02689173b736b760a13a6b777"
|
||||
"Rev": "66ca404d841ed908aa6cc9361107b0c363c94cd8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/bcrypt",
|
||||
|
|
36
Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go
generated
vendored
36
Godeps/_workspace/src/github.com/gorilla/mux/mux_test.go
generated
vendored
|
@ -135,6 +135,42 @@ func TestHost(t *testing.T) {
|
|||
path: "",
|
||||
shouldMatch: false,
|
||||
},
|
||||
{
|
||||
title: "Path route with single pattern with pipe, match",
|
||||
route: new(Route).Path("/{category:a|b/c}"),
|
||||
request: newRequest("GET", "http://localhost/a"),
|
||||
vars: map[string]string{"category": "a"},
|
||||
host: "",
|
||||
path: "/a",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route with single pattern with pipe, match",
|
||||
route: new(Route).Path("/{category:a|b/c}"),
|
||||
request: newRequest("GET", "http://localhost/b/c"),
|
||||
vars: map[string]string{"category": "b/c"},
|
||||
host: "",
|
||||
path: "/b/c",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route with multiple patterns with pipe, match",
|
||||
route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"),
|
||||
request: newRequest("GET", "http://localhost/a/product_name/1"),
|
||||
vars: map[string]string{"category": "a", "product": "product_name", "id": "1"},
|
||||
host: "",
|
||||
path: "/a/product_name/1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
{
|
||||
title: "Path route with multiple patterns with pipe, match",
|
||||
route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"),
|
||||
request: newRequest("GET", "http://localhost/b/c/product_name/1"),
|
||||
vars: map[string]string{"category": "b/c", "product": "product_name", "id": "1"},
|
||||
host: "",
|
||||
path: "/b/c/product_name/1",
|
||||
shouldMatch: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
testRoute(t, test)
|
||||
|
|
73
Godeps/_workspace/src/github.com/thermokarst/jwt/README.md
generated
vendored
73
Godeps/_workspace/src/github.com/thermokarst/jwt/README.md
generated
vendored
|
@ -9,6 +9,7 @@ your application:
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -21,60 +22,90 @@ func protectMe(w http.ResponseWriter, r *http.Request) {
|
|||
fmt.Fprintf(w, "secured")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var authFunc = func(email string, password string) error {
|
||||
// Hard-code a user --- this could easily be a database call, etc.
|
||||
func dontProtectMe(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "not secured")
|
||||
}
|
||||
|
||||
func auth(email string, password string) error {
|
||||
// Hard-code a user
|
||||
if email != "test" || password != "test" {
|
||||
return errors.New("invalid credentials")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var claimsFunc = func(userId string) (map[string]interface{}, error) {
|
||||
func setClaims(id string) (map[string]interface{}, error) {
|
||||
currentTime := time.Now()
|
||||
return map[string]interface{}{
|
||||
"iat": currentTime.Unix(),
|
||||
"exp": currentTime.Add(time.Minute * 60 * 24).Unix(),
|
||||
"sub": userId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var verifyClaimsFunc = func(claims []byte) error {
|
||||
func verifyClaims(claims []byte, r *http.Request) error {
|
||||
currentTime := time.Now()
|
||||
var c struct {
|
||||
Exp int64
|
||||
Iat int64
|
||||
Sub string
|
||||
}
|
||||
err := json.Unmarshal(claims, &c)
|
||||
if err != nil {
|
||||
return err
|
||||
Exp int64
|
||||
}
|
||||
_ = json.Unmarshal(claims, &c)
|
||||
if currentTime.After(time.Unix(c.Exp, 0)) {
|
||||
return errors.New("this token has expired!")
|
||||
}
|
||||
if c.Sub != "test" {
|
||||
return errors.New("who are you??!")
|
||||
return errors.New("this token has expired")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := &jwt.Config{
|
||||
Secret: "password",
|
||||
Auth: authFunc,
|
||||
Claims: claimsFunc,
|
||||
Auth: auth,
|
||||
Claims: setClaims,
|
||||
}
|
||||
|
||||
j, err := jwt.New(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
protect := http.HandlerFunc(protectMe)
|
||||
dontProtect := http.HandlerFunc(dontProtectMe)
|
||||
|
||||
http.Handle("/authenticate", j.GenerateToken())
|
||||
http.Handle("/secure", j.Secure(protect, verifyClaimsFunc))
|
||||
http.Handle("/secure", j.Secure(protect, verifyClaims))
|
||||
http.Handle("/insecure", dontProtect)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
$ http GET :8080/secure
|
||||
|
||||
HTTP/1.1 401 Unauthorized
|
||||
Content-Length: 23
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Date: Fri, 08 May 2015 06:43:35 GMT
|
||||
|
||||
please provide a token
|
||||
|
||||
$ http POST :8080/authenticate email=test password=test
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 130
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Date: Fri, 08 May 2015 06:31:42 GMT
|
||||
|
||||
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MzExNTI0ODAsImlhdCI6MTQzMTA2NjA4MH0=.UbJmLqOF4bTH/8+o6CrZfoi1Fu7zTDfCV0kwMQyzmos=
|
||||
|
||||
$ http GET :8080/secure Authorization:"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MzExNTI0ODAsImlhdCI6MTQzMTA2NjA4MH0=.UbJmLqOF4bTH/8+o6CrZfoi1Fu7zTDfCV0kwMQyzmos="
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 7
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
Date: Fri, 08 May 2015 06:38:30 GMT
|
||||
|
||||
secured
|
||||
```
|
||||
|
||||
# Installation
|
||||
|
||||
$ go get github.com/thermokarst/jwt
|
||||
|
@ -98,6 +129,10 @@ config := &jwt.Config{
|
|||
j, err := jwt.New(config)
|
||||
```
|
||||
|
||||
You can also customize the field names by specifying `IdentityField` and
|
||||
`VerifyField` in the `Config` struct, if you want the credentials to be
|
||||
something other than `"email"` and `"password"`.
|
||||
|
||||
Once the middleware is instantiated, create a route for users to generate a JWT
|
||||
at.
|
||||
|
||||
|
|
28
Godeps/_workspace/src/github.com/thermokarst/jwt/examples/net-http.go
generated
vendored
28
Godeps/_workspace/src/github.com/thermokarst/jwt/examples/net-http.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -17,8 +18,7 @@ func dontProtectMe(w http.ResponseWriter, r *http.Request) {
|
|||
fmt.Fprintf(w, "not secured")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var authFunc = func(email string, password string) error {
|
||||
func auth(email string, password string) error {
|
||||
// Hard-code a user
|
||||
if email != "test" || password != "test" {
|
||||
return errors.New("invalid credentials")
|
||||
|
@ -26,7 +26,7 @@ func main() {
|
|||
return nil
|
||||
}
|
||||
|
||||
var claimsFunc = func(string) (map[string]interface{}, error) {
|
||||
func setClaims(id string) (map[string]interface{}, error) {
|
||||
currentTime := time.Now()
|
||||
return map[string]interface{}{
|
||||
"iat": currentTime.Unix(),
|
||||
|
@ -34,24 +34,36 @@ func main() {
|
|||
}, nil
|
||||
}
|
||||
|
||||
var verifyClaimsFunc = func([]byte) error {
|
||||
// We don't really care about the claims, just approve as-is
|
||||
func verifyClaims(claims []byte, r *http.Request) error {
|
||||
currentTime := time.Now()
|
||||
var c struct {
|
||||
Iat int64
|
||||
Exp int64
|
||||
}
|
||||
_ = json.Unmarshal(claims, &c)
|
||||
if currentTime.After(time.Unix(c.Exp, 0)) {
|
||||
return errors.New("this token has expired")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := &jwt.Config{
|
||||
Secret: "password",
|
||||
Auth: authFunc,
|
||||
Claims: claimsFunc,
|
||||
Auth: auth,
|
||||
Claims: setClaims,
|
||||
}
|
||||
|
||||
j, err := jwt.New(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
protect := http.HandlerFunc(protectMe)
|
||||
dontProtect := http.HandlerFunc(dontProtectMe)
|
||||
|
||||
http.Handle("/authenticate", j.GenerateToken())
|
||||
http.Handle("/secure", j.Secure(protect, verifyClaimsFunc))
|
||||
http.Handle("/secure", j.Secure(protect, verifyClaims))
|
||||
http.Handle("/insecure", dontProtect)
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
|
59
Godeps/_workspace/src/github.com/thermokarst/jwt/jwt.go
generated
vendored
59
Godeps/_workspace/src/github.com/thermokarst/jwt/jwt.go
generated
vendored
|
@ -31,15 +31,9 @@ var (
|
|||
ErrMalformedToken = errors.New("please provide a valid token")
|
||||
ErrInvalidSignature = errors.New("signature could not be verified")
|
||||
ErrParsingCredentials = errors.New("error parsing credentials")
|
||||
ErrInvalidMethod = errors.New("invalid request method")
|
||||
)
|
||||
|
||||
// Config is a container for setting up the JWT middleware.
|
||||
type Config struct {
|
||||
Secret string
|
||||
Auth AuthFunc
|
||||
Claims ClaimsFunc
|
||||
}
|
||||
|
||||
// AuthFunc is a type for delegating user authentication to the client-code.
|
||||
type AuthFunc func(string, string) error
|
||||
|
||||
|
@ -47,8 +41,17 @@ type AuthFunc func(string, string) error
|
|||
type ClaimsFunc func(string) (map[string]interface{}, error)
|
||||
|
||||
// VerifyClaimsFunc is a type for processing and validating JWT claims on one
|
||||
// or more route's in the client-code.
|
||||
type VerifyClaimsFunc func([]byte) error
|
||||
// or more routes in the client-code.
|
||||
type VerifyClaimsFunc func([]byte, *http.Request) error
|
||||
|
||||
// Config is a container for setting up the JWT middleware.
|
||||
type Config struct {
|
||||
Secret string
|
||||
Auth AuthFunc
|
||||
Claims ClaimsFunc
|
||||
IdentityField string
|
||||
VerifyField string
|
||||
}
|
||||
|
||||
// Middleware is where we store all the specifics related to the client's
|
||||
// JWT needs.
|
||||
|
@ -56,6 +59,8 @@ type Middleware struct {
|
|||
secret string
|
||||
auth AuthFunc
|
||||
claims ClaimsFunc
|
||||
identityField string
|
||||
verifyField string
|
||||
}
|
||||
|
||||
// New creates a new Middleware from a user-specified configuration.
|
||||
|
@ -72,10 +77,18 @@ func New(c *Config) (*Middleware, error) {
|
|||
if c.Claims == nil {
|
||||
return nil, ErrMissingClaimsFunc
|
||||
}
|
||||
if c.IdentityField == "" {
|
||||
c.IdentityField = "email"
|
||||
}
|
||||
if c.VerifyField == "" {
|
||||
c.VerifyField = "password"
|
||||
}
|
||||
m := &Middleware{
|
||||
secret: c.Secret,
|
||||
auth: c.Auth,
|
||||
claims: c.Claims,
|
||||
identityField: c.IdentityField,
|
||||
verifyField: c.VerifyField,
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
@ -142,7 +155,7 @@ func (m *Middleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
|
|||
message: "decoding claims",
|
||||
}
|
||||
}
|
||||
err = v(claimSet)
|
||||
err = v(claimSet, r)
|
||||
if err != nil {
|
||||
return &jwtError{
|
||||
status: http.StatusUnauthorized,
|
||||
|
@ -163,6 +176,13 @@ func (m *Middleware) Secure(h http.Handler, v VerifyClaimsFunc) http.Handler {
|
|||
// the requester.
|
||||
func (m *Middleware) GenerateToken() http.Handler {
|
||||
generateHandler := func(w http.ResponseWriter, r *http.Request) *jwtError {
|
||||
if r.Method != "POST" {
|
||||
return &jwtError{
|
||||
status: http.StatusBadRequest,
|
||||
err: ErrInvalidMethod,
|
||||
message: "receiving request",
|
||||
}
|
||||
}
|
||||
var b map[string]string
|
||||
err := json.NewDecoder(r.Body).Decode(&b)
|
||||
if err != nil {
|
||||
|
@ -172,7 +192,22 @@ func (m *Middleware) GenerateToken() http.Handler {
|
|||
message: "parsing authorization",
|
||||
}
|
||||
}
|
||||
err = m.auth(b["email"], b["password"])
|
||||
// Check if required fields are in the body
|
||||
if _, ok := b[m.identityField]; !ok {
|
||||
return &jwtError{
|
||||
status: http.StatusBadRequest,
|
||||
err: ErrParsingCredentials,
|
||||
message: "parsing credentials, missing identity field",
|
||||
}
|
||||
}
|
||||
if _, ok := b[m.verifyField]; !ok {
|
||||
return &jwtError{
|
||||
status: http.StatusBadRequest,
|
||||
err: ErrParsingCredentials,
|
||||
message: "parsing credentials, missing verify field",
|
||||
}
|
||||
}
|
||||
err = m.auth(b[m.identityField], b[m.verifyField])
|
||||
if err != nil {
|
||||
return &jwtError{
|
||||
status: http.StatusInternalServerError,
|
||||
|
@ -192,7 +227,7 @@ func (m *Middleware) GenerateToken() http.Handler {
|
|||
}
|
||||
|
||||
// Generate claims for user
|
||||
claims, err := m.claims(b["email"])
|
||||
claims, err := m.claims(b[m.identityField])
|
||||
if err != nil {
|
||||
return &jwtError{
|
||||
status: http.StatusInternalServerError,
|
||||
|
|
19
Godeps/_workspace/src/github.com/thermokarst/jwt/jwt_test.go
generated
vendored
19
Godeps/_workspace/src/github.com/thermokarst/jwt/jwt_test.go
generated
vendored
|
@ -32,7 +32,7 @@ var claimsFunc = func(id string) (map[string]interface{}, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
var verifyClaimsFunc = func(claims []byte) error {
|
||||
var verifyClaimsFunc = func(claims []byte, r *http.Request) error {
|
||||
currentTime := time.Now()
|
||||
var c struct {
|
||||
Exp int64
|
||||
|
@ -100,6 +100,12 @@ func TestNewJWTMiddleware(t *testing.T) {
|
|||
if _, ok := claimsVal["iat"]; !ok {
|
||||
t.Errorf("wanted a claims set, got %v", claimsVal)
|
||||
}
|
||||
if middleware.identityField != "email" {
|
||||
t.Errorf("wanted email, got %v", middleware.identityField)
|
||||
}
|
||||
if middleware.verifyField != "password" {
|
||||
t.Errorf("wanted password, got %v", middleware.verifyField)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewJWTMiddlewareNoConfig(t *testing.T) {
|
||||
|
@ -215,3 +221,14 @@ func TestSecureHandlerGoodToken(t *testing.T) {
|
|||
t.Errorf("wanted %s, got %s", "test", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTokenHandlerNotPOST(t *testing.T) {
|
||||
middleware := newMiddlewareOrFatal(t)
|
||||
resp := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest("PUT", "http://example.com", nil)
|
||||
middleware.GenerateToken().ServeHTTP(resp, req)
|
||||
body := strings.TrimSpace(resp.Body.String())
|
||||
if body != ErrInvalidMethod.Error() {
|
||||
t.Errorf("wanted %q, got %q", ErrInvalidMethod.Error(), body)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue