diff --git a/jwk/handler.go b/jwk/handler.go index 9e6721cbed9..a4463645e06 100644 --- a/jwk/handler.go +++ b/jwk/handler.go @@ -199,7 +199,13 @@ func (h *Handler) GetKey(w http.ResponseWriter, r *http.Request, ps httprouter.P var setName = ps.ByName("set") var keyName = ps.ByName("key") - if _, err := h.W.TokenAllowed(ctx, h.W.TokenFromRequest(r), &ladon.Request{ + if err := h.W.IsAllowed(ctx, &ladon.Request{ + Subject: "", + Resource: "rn:hydra:keys:" + setName + ":" + keyName, + Action: "get", + }); err == nil { + // Allow unauthorized requests to access this resource if it is enabled by policies + } else if _, err := h.W.TokenAllowed(ctx, h.W.TokenFromRequest(r), &ladon.Request{ Resource: "rn:hydra:keys:" + setName + ":" + keyName, Action: "get", }, "hydra.keys.get"); err != nil { diff --git a/jwk/manager_test.go b/jwk/manager_test.go index 131d937217f..0ecb3297e9c 100644 --- a/jwk/manager_test.go +++ b/jwk/manager_test.go @@ -23,6 +23,7 @@ import ( "github.com/ory-am/fosite/rand" "github.com/square/go-jose" "golang.org/x/net/context" + "net/http" ) var managers = map[string]Manager{} @@ -30,6 +31,7 @@ var managers = map[string]Manager{} var testGenerator = &RS256Generator{} var ts *httptest.Server +var httpManager *HTTPManager func init() { localWarden, httpClient := internal.NewFirewall( @@ -43,23 +45,30 @@ func init() { }, &ladon.DefaultPolicy{ ID: "1", Subjects: []string{"alice"}, - Resources: []string{"rn:hydra:keys:<.*>"}, + Resources: []string{"rn:hydra:keys:<.*>"}, Actions: []string{"create", "get", "delete", "update"}, Effect: ladon.AllowAccess, + }, &ladon.DefaultPolicy{ + ID: "2", + Subjects: []string{"alice", ""}, + Resources: []string{"rn:hydra:keys:anonymous<.*>"}, + Actions: []string{"get"}, + Effect: ladon.AllowAccess, }, ) - r := httprouter.New() + router := httprouter.New() h := Handler{ Manager: &MemoryManager{}, W: localWarden, H: &herodot.JSON{}, } - h.SetRoutes(r) - ts := httptest.NewServer(r) + h.SetRoutes(router) + ts := httptest.NewServer(router) u, _ := url.Parse(ts.URL + "/keys") managers["memory"] = &MemoryManager{} - managers["http"] = &HTTPManager{Client: httpClient, Endpoint: u} + httpManager = &HTTPManager{Client: httpClient, Endpoint: u} + managers["http"] = httpManager } var rethinkManager = new(RethinkManager) @@ -155,6 +164,27 @@ func TestColdStart(t *testing.T) { rethinkManager.Unlock() } +func TestHTTPManagerPublicKeyGet(t *testing.T) { + anonymous := &HTTPManager{Endpoint: httpManager.Endpoint, Client: http.DefaultClient} + ks, _ := testGenerator.Generate("") + priv := ks.Key("private") + + name := "http" + m := httpManager + + _, err := m.GetKey("anonymous", "baz") + pkg.AssertError(t, true, err, name) + + err = m.AddKey("anonymous", First(priv)) + pkg.AssertError(t, false, err, name) + + time.Sleep(time.Millisecond * 100) + + got, err := anonymous.GetKey("anonymous", "private") + pkg.RequireError(t, false, err, name) + assert.Equal(t, priv, got.Keys, "%s", name) +} + func TestManagerKey(t *testing.T) { ks, _ := testGenerator.Generate("") priv := ks.Key("private") diff --git a/pkg/test_helpers.go b/pkg/test_helpers.go index 90df2717579..98f320701a5 100644 --- a/pkg/test_helpers.go +++ b/pkg/test_helpers.go @@ -26,7 +26,7 @@ func RequireError(t *testing.T, expectError bool, err error, args ...interface{} t.Logf("Unexpected error: %s\n", err.Error()) t.Logf("Arguments: %v\n", args) if e, ok := errors.Cause(err).(stackTracer); ok { - t.Logf("Stack:\n%s\n", e.StackTrace()) + t.Logf("Stack:\n%+v\n", e.StackTrace()) } t.Logf("\n\n") } @@ -39,7 +39,7 @@ func AssertError(t *testing.T, expectError bool, err error, args ...interface{}) t.Logf("Unexpected error: %s\n", err.Error()) t.Logf("Arguments: %s\n", args) if e, ok := errors.Cause(err).(stackTracer); ok { - t.Logf("Stack:\n%s\n", e.StackTrace()) + t.Logf("Stack:\n%+v\n", e.StackTrace()) } t.Logf("\n\n") }