From b1d3bbaf56e55af3bc8db79ae6233e9d6c383ab6 Mon Sep 17 00:00:00 2001 From: Caleb Doxsey Date: Wed, 29 Apr 2020 10:55:46 -0600 Subject: [PATCH] authorize: add support for .pomerium and unauthenticated routes (#639) * authorize: add support for .pomerium and unauthenticated routes integration-tests: add test for forward auth dashboard urls * proxy: fix ctx error test to return a 200 when authorize allows it --- authorize/evaluator/opa/policy/authz.rego | 35 ++++++---- .../evaluator/opa/policy/authz_test.rego | 45 +++++++++++++ authorize/evaluator/opa/policy/statik.go | 2 +- authorize/grpc.go | 15 ++++- go.sum | 6 +- integration/authorization_test.go | 5 +- integration/dashboard_test.go | 17 +++++ integration/manifests/lib/pomerium.libsonnet | 66 +++++++++++-------- proxy/forward_auth.go | 29 ++++---- proxy/middleware.go | 5 +- proxy/middleware_test.go | 2 +- 11 files changed, 158 insertions(+), 69 deletions(-) diff --git a/authorize/evaluator/opa/policy/authz.rego b/authorize/evaluator/opa/policy/authz.rego index 707bfe2ef..ad03a6fc2 100644 --- a/authorize/evaluator/opa/policy/authz.rego +++ b/authorize/evaluator/opa/policy/authz.rego @@ -5,10 +5,15 @@ import data.shared_key default allow = false +# allow public +allow { + route := first_allowed_route(input.url) + route_policies[route].AllowPublicUnauthenticatedAccess == true +} + # allow by email allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) token.payload.email = route_policies[route].allowed_users[_] token.valid count(deny)==0 @@ -16,8 +21,7 @@ allow { # allow group allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) some group token.payload.groups[group] == route_policies[route].allowed_groups[_] token.valid @@ -26,8 +30,7 @@ allow { # allow by impersonate email allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) token.payload.impersonate_email = route_policies[route].allowed_users[_] token.valid count(deny)==0 @@ -35,8 +38,7 @@ allow { # allow by impersonate group allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) some group token.payload.impersonate_groups[group] == route_policies[route].allowed_groups[_] token.valid @@ -45,8 +47,7 @@ allow { # allow by domain allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) some domain email_in_domain(token.payload.email, route_policies[route].allowed_domains[domain]) token.valid @@ -55,14 +56,24 @@ allow { # allow by impersonate domain allow { - some route - allowed_route(input.url, route_policies[route]) + route := first_allowed_route(input.url) some domain email_in_domain(token.payload.impersonate_email, route_policies[route].allowed_domains[domain]) token.valid count(deny)==0 } +# allow pomerium urls +allow { + contains(input.url, "/.pomerium/") + not contains(input.url,"/.pomerium/admin") +} + +# returns the first matching route +first_allowed_route(input_url) = route { + route := [route | some route ; allowed_route(input.url, route_policies[route])][0] +} + allowed_route(input_url, policy){ input_url_obj := parse_url(input_url) allowed_route_source(input_url_obj, policy) diff --git a/authorize/evaluator/opa/policy/authz_test.rego b/authorize/evaluator/opa/policy/authz_test.rego index 285cbc131..949ee0e2c 100644 --- a/authorize/evaluator/opa/policy/authz_test.rego +++ b/authorize/evaluator/opa/policy/authz_test.rego @@ -65,6 +65,51 @@ test_email_denied { } } +test_public_allowed { + allow with data.route_policies as [{ + "source": "example.com", + "AllowPublicUnauthenticatedAccess": true + }] with input as { + "url": "http://example.com", + "host": "example.com" + } +} +test_public_denied { + not allow with data.route_policies as [ + { + "source": "example.com", + "prefix": "/by-user", + "allowed_users": ["bob@example.com"] + }, + { + "source": "example.com", + "AllowPublicUnauthenticatedAccess": true + } + ] with input as { + "url": "http://example.com/by-user", + "host": "example.com" + } +} + +test_pomerium_allowed { + allow with data.route_policies as [{ + "source": "example.com", + "allowed_users": ["bob@example.com"] + }] with input as { + "url": "http://example.com/.pomerium/", + "host": "example.com" + } +} +test_pomerium_denied { + not allow with data.route_policies as [{ + "source": "example.com", + "allowed_users": ["bob@example.com"] + }] with input as { + "url": "http://example.com/.pomerium/admin", + "host": "example.com" + } +} + test_parse_url { url := parse_url("http://example.com/some/path?qs") url.scheme == "http" diff --git a/authorize/evaluator/opa/policy/statik.go b/authorize/evaluator/opa/policy/statik.go index ad90c3361..ca8d43a94 100644 --- a/authorize/evaluator/opa/policy/statik.go +++ b/authorize/evaluator/opa/policy/statik.go @@ -10,7 +10,7 @@ import ( const Rego = "rego" // static asset namespace func init() { - data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x12\x03\x95P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00authz.regoUT\x05\x00\x01D=\x9e^\xc4X\xdbn\xdc6\x10}\x16\xbfb\xc2\xc0\x80\xd4\xa8r\x12\xa0\x05*Tp_\xfa\x05}\x14\x14\x85\x96fwiK\xa4@R\xf6n\x16\xfb\xef\x05Ii/Zy\xe38\xae\xfbbY\xc3\x99\xc33gF\xbcl\xc7\xaa{\xb6D\xe8d\x8b\x8a\xf7m\xc2z\xb3\xfaF\x08o;\xa9\x0c\xd4\xcc\xb0D\xc9\xde`\xd9\xc9\x86W\x1c\xf5\xc9\x90^1\x85uy\x8f\x1bBj\\\xb0\xbe1\xc0\x9aF>B\x06\x0b\xd6h$\xe4\xfd`\xb8\xdd\x00\xb6\x8c7\xc4\xbfnI\xa0e\x8b\xe0\xc0I\xe0\x8cX\x97\xee5\xe4\xa2\xebM\xd2\xab&\x86\xd3\xc9s\xf7ZD$0\xf2\x1eE\xd2\xb1M#Y\x9d8d\xc8\xe6\xbd\x93\x11\xbc\xd7\xa8t^\x16c\xf4\x03kxM\x82J\xf6\xc2\x845\x8aM\x94e\x1fI`\x14\xab0\xd4\x9d\xe2\xc2,BzJ\x1fB\x07\x9a]=\xf8\xf7\xec\xea!\xa21\xf8\xa9b\x98\xa1UD\x11\xd9\x1dtX*\xd9w\xaf$\x82\x0b\xf6\x80\x13A\x9cQ\xe7\xeeQ@\xf6=e\x06\xf7\x17K\xe3\xe2\x8f\xa4q\xef\x13i<\x97S1n7\xc0\xdb\x0e\x95\x96\x82\x19\xfc\x0f\x1b\xe4h\x96\xf2M\x9a\xe5,\xad\x1fj\x9c3\xba\x97u{\x9b\x9e:&\xf5\xc6\xfdu\x96\xec\xcbz\xad\x96-\xe3\xe25\x85\x1a\x10\x03W\xa4\x92\x8b\xd2\x1b\xc2\x99u\xe0 \xa4\xbdF>R\xe7\xfeyh\xe1\x1f\x94\xca\x87\xcft\xdb0\xf2\xfd\x05+\x86\x91\xc2\xa5\x9e\xfb\xbf\xb4<\xfb4\xdeH\xd7\xf3\xdc_\xa8\xf1L\x02'z\xcf\x88W:\xf1\\\x82\x9bhK\x82\xbd\xb1\x94\xb7w\x90f\xd01\xa5\xd1\x1a\x0e\xfe\xd1\xa4\x0c\xa5\x96\xbd\xaa\x8e\x00m\xec\x1et\xea\xdc)\\\xf0\xf5s\x9d\x99Y=\xd3U\xe1\x12\x9f\x84\x9d&\x7f\x99\xb2m:y{\x87\x95I\x96hBo\x8d\x81\xfa \x1a\x03\xa5\x91]\x99(%\xbbW\xc7}\xe7p\x03o\x9b\xaf\x84\x0fL\xbcK4)Z\xb2\x92\xdaXv\xa7\x08\xce|\xae\xc3\xc5j<\xc5\xd7\x07]\xd4\xe1\xe7qG\x1d\x0cSF?\xf2i\x1f$\xb65F\xc4\xc4G\xce\xd4\xf9B\x03=\xc9\x82\x99\xd5\xe5\xdc~\ns\xc8k$\xce\xcc\xcaNs\x9e\xdby.\x97:\xfc\xa9\x89]\xcc\xc5l~\x16u\xc8Ga\xd92S\xad\xc6\xe6t.\xf1L^\xaeH\x87^\xd6FE\x90\xc1\x16\xa8\xaeV\xd8\"M\xc1\xff\x13\x03\xb5-KS\xb0\x8fQ\xc3\x14\x9cb;\xcb,/\xe3\xbd\xaf\xf7Q\xec\xd1\x0e\x17\xf6\x08f\xe7O\x16\\\xd4%k\x9aR\x1b\xc5\xc5\xb2\xd4\xfd\xadcY\x8a\x90\x04\xc1\xd7\xf0&\x0dW\xc6t\xb9.n\xa2\xf4\xfa:\xba \xf3/\xd7\xc5\x87(\xcc\xbf\xdc\xbc/~\x89\xbe\xc6$\x08\xb4Q1|\x8a\xf2\x8f\x05 |\xbd@H\xd5\xb2\x86\x7f\xf3\x9f\x97k\x88an\x97\xde\xcc\xf0\x90'\xbd\xa6nK3j_\x8e\xa7\x9d\xad\xd7\xe0\xfcnp&\xd3-\xecd\x9dw\x05[\xdb\xc5Bw\x0d7\xe3 \xfd\x8bF\xe3v\xb4v}\xf0\x99\x04\xeb\xfc\x93;^\x0d{\xe3\xeep\xcd\xc2u\xc7\x15\xd6\x87\x8b\xd6h\xd8\x92@\xc8\xc7Rc%E\xad\xd3\xcc\xf0\x16\x13k\x11:\x8c\xae?\xe1\x1f$\xc8W\xc8jT1\x0c{R\x0cea\xf9p\x99\xdc=\x9a\xa4\xc6J\xd6\xfb}[\xa3\x8a\xac\xa4\xc3 a\xdd\xc1\x9fp4\x81\xe7$69u\xdb\x1cp\xbd\xa7\x16\xe2\xba\x8bh\xb1%\xc1`\xd9\xfb\xee\xb7W\x1f\xb3b\x1anY\x0d\xac\xaf9\x8a\n!d}\x1d\xa5p\xa5AH\x03\\\xc0\xd5\x87\x07\x1a\xe7\x9e\x91\xeb\xa2\x91\x0f\xeb\xeb\"\xb2S\xbc '\x8b\x8d\x0d\xb6(\x8c\xadU\xc3\xb5 \x8fp\xe3\xc3t'\x07!\x1bm\xd3du{|\x00\x9a\"\xb9\x0b\xb2\xf3\xd1\xb3\xc7\xac\xef\x1dD*)\x8c=\xb8\x1c\x9d\x9fh2\xde\xd3\xaf\x1d0u\xbc\xc8{\xb0Q \xa4\xf8\xd5\x99\x1dC\x0d\x0b%[`U\x85\x9a\x8b\xa5g\xeb\x8fJz(\xd8\x98\x88\xd5\xc1\xe3\x15\xdbyU\x9e\x91\xcb\xb3\xe9\xfa\x92g\xb0\xa5\x03\x84[.\x86\x9aQ'\x06M\xc1=\xfd\x02\xe2\xfe\x8daR\xdf\xf3\xe2\x96\x0f\xa8\xf8bc\xd7\x8cC\x99c\x0b\x11\x04Tc\xa5\xd0\xaeS\x87\x9f,b7\xc0z;\xddQg\x91 \xd8\x91\xc0Q\xb5\x00iv\x9a\xaf\xb5\xf9\xef{:\xe2o\xaf\xfe\xaa3\x1d\xf3V\xa2\xf9R`]\xde=\x9a4\x1b\xb8\xa3p\xdc\xedH\xb8\xa5\xacY\xd2\x14\xe8\xdf\xff|\xfe\xedw\xba\x9bh\x1d\x0f?\xba\xf0\xa5\xb0\xcb\xe4=n\"B\xc8\xb4V\xf6O\xec*h\x17\x1a\x00\xfb\x9e\x97v\xb5\xb56\xb2#\xff\x06\x00\x00\xff\xffPK\x07\x08\xab\xe0F\x9a\x82\x04\x00\x00\xf4\x11\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x12\x03\x95P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00 \x00authz_test.regoUT\x05\x00\x01D=\x9e^\xd4UkO\xe38\x14\xfd\x9c\xfc\x8a(\x9f`\xd5i\xbb\xa1\x8f\x19$\xb4\xc3#0}\x0d\x85\x14\xd2\x82P\xe4&&q\xf3pj;\xa4\xcd\xa8\xff}e\x97\xb6\x19\x08\xbb\x01\xad\x84\xf6Se\xdf{\xcf=\xf7\x9e\xe3&\x06\xb6\x0f\\\xa8\xc48\x84\x04%a\x15$\xcc\xcbdy\x962\xcb\x83\xc0\x81D9\x1f\xf4\x9bCd\xc0\xf6\xf8,\\\x9e\xde\xcdbW\x8f\x1f\xf5\xe6\xd5W-\xeb\xc0\xf1@\xa3}\x92\xb5~\x98\xda\xf1\xb7Nz\xe1\xb7C\xd3\xa8\xdb\xcd\xf6\xb5\xa5u/\x96\xe7\x97\x1a;=ndzg\xe2\x99O}\xbd\xa5]R\x8d\xdd\xb5&\x84\xa4\xce\xc9\xd7\xe8\xa09\x0b\x86\xb1{\xa3\xb7b\xac?un\xb4z0\xec\x03l\xe3l<\x19\xcc\x8f\xfd\xe4K\xaf\x1b\x05\xb8\x1b\x1cg=W\x1b\x03\xab\x8e\x0cd\xb8\xc6q\x12.\x1a\x8d\x93\x83\xa8}v5s\x0ffC\xef\xda\x15\x02x\x80@g\xb3\xff)\xa0\xb0\xd5HHPu\xa0\x8d\x1d\xb8\x97\xd3\xa7\xea\xef\xcb2\x83\x94Y0\x04(\xb0@\x10\xe0\x14:\\\xb3\x84\xae\x05G\xb8:KY\x15F\xbc\xd6\xe2\xb5{;GTx\xa6\xa4\x82\xc4Q\x0f\x95{\x15.@\x18\x07\xb0j\xe3P}\xa8\xf0\x88\x80\xe5j\xcf0\xfc\x9e\x0f\xcb\xd2\xaa\xa2\xe4\x98\xec\xcb\xb2$\xba+)b\x9e\xe2\x00\x06\xaa\x04'\x0cZ1\x0e\x90\x8d U\x00U\xeeE;\x8a\x13bC\x8e\x9aG\x14\xfd\x9e\x07\xb08{*8\xbdl\xfc K\xab\x87\\\x93\xbc[\x01\xcdS\xca'\xed6\xcasv'\x91\x82\xa28a< \xd8%D\x0c\xec1\x16\x1f\xd6j\xaf\x18z\x98\xb2B\xea\x9c\xb2z\xa8\xf0\x1fYZ\xc9\xab\x8d0\xeb\xbcO\x91D\x8a0SJ\xa8\"K\x12o\x9aW\xe6\x8d\xf1%5\x06\xcc\xe3 5\xf0|\xb1\x91\xcc\xc1!@\x11}\xcdZ\x96\xa4U\xe5C-\xa6/Z\xec\\\x11a\x1c\xc1\xef\xdb\xbf\xba|\x9f\xcf1\xc73\xd7\xf7\xdbC\xbc[\x07F\xe8\xd3\x9emI\x93\xbc\xff\xe9N\xf1\xf4\x7f\xfdtc@(\xb4\x12\x12\x08aH\xc0u\xd9\xde\xed\x15\x99\x80\xe2\x10\xd6\xb8}\xff\x9aSu_\x14U\xa9\xed\xc1\x10*GGkb\xea\xfa\x96s\x11w\xbf\xab\xc3C\xbc^\x84vp\xea\x96\xd3f\xcbk\x81\xd6rpz\xbf\xdd\x17qS+\xca\xaf7\xe4[\xed\xbf\xbf\xbe \xe1\xa30\xf4#8\xb5\xff\n\xe8\xdfqj\xe5\x80J0Z#m\xdf\xdb\x9bh\x98\xb8\xff,W\xb1\x1bb\x02\x1f\xd1\xa2\xbc\x1b\xd6\xf9\xe2\x9f\xb6\xe4\x88\xc0 Q$l)\\\xf9\x02DDK\x8eX\xc0a[\xfe\xc6t\xfcY\x94\x9fm\xf3\x0d)9YAQ\xa9!\nW\xb2\xfdD~d!\xaf\x8a\x8b\xd7A\xa0\x0b\xdf\xa1\xb5H\xe7\xb8\xd5?Jn\xa4`\xb0-\xc8s\xf0\x19\xab\xfcp[\x80\xfb\xc52{X\x0f\xf7w\x00\x00\x00\xff\xffPK\x07\x08\xf7ol\x88\x94\x03\x00\x00\xb8\x0c\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x12\x03\x95P\xab\xe0F\x9a\x82\x04\x00\x00\xf4\x11\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00authz.regoUT\x05\x00\x01D=\x9e^PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x12\x03\x95P\xf7ol\x88\x94\x03\x00\x00\xb8\x0c\x00\x00\x0f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc3\x04\x00\x00authz_test.regoUT\x05\x00\x01D=\x9e^PK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\x87\x00\x00\x00\x9d\x08\x00\x00\x00\x00" + data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\xcd\xb0\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00 \x00authz.regoUT\x05\x00\x01\xe2\xa8\xa8^\xbcX_o\xdb6\x10\x7f\x16?\xc5\x95E\x01i\xd5\xe4\xb6\xc0\x06\xcc\x9b\x91\xf5a\xef\x03\x86= \xaaJKg\x9b\x89D $U\xdb\xf5\xfc\xdd\x87#%\xdbQl7M\xd3\xbeD\xd6\xf1\xeew\xbf\xfb\xa3#\x99V\x14wb\x89\xd065j\xd9\xd5\x89\xe8\xec\xea3c\xb2n\x1bm\xa1\x14V$\xba\xe9,\xe6mS\xc9B\xa2\xb9\xb7dVBc\x99\xdf\xe1\x96\xb1\x12\x17\xa2\xab,\x88\xaaj\xd60\x83\x85\xa8\x0c2\xf6\xb2\x17\xb4\xdd\xbc\x92\x05\xf3/;\x168T\x98\xce`!\xb5\xb1\xb9\x93c\x99;q(U\xdb\xd9\xa4\xd3U\xd4+\x1e\xdc\xa7\xee5K\xde\x93\xfe\xdf\x0e\xf3_E\xa4QYY\x08\x8b\xe5\xfb\xa2@c`6\x03\xab;d\xfb#\x85\xf9\x16\xb0\x16\xb2z\x02 \xdb\xdc\xa1JZ\xb1\xad\x1aQ&\x0e\x05fp\x9e\xda\x80\xd2\x19\xd4&\xcd\xb3\xc1\xfa\x93\xa8d\xc9\x82\xa2\xe9\x94\x0dKT\xdbh6{s\xcao\xa9\x9b\xae}\x029\xd3\xd4\xd8\x1b\x8f\x88:\xa1I\xdd#\xa3\x94\\g\xdc\xab\x7f\x05\xe5\xf9\x16d\xdd\xa26\x8d\x12\x16\x9f)\xbd'\x88\xf9wJ\xf5\x88\xf7\xf3g\xfe4\x86\x1fQ\x85\xb2\xa9\x85TO\x0d\xa1\xb7\x0e\\\xb6s\xa9r/\x08\xcf\xb4}\xfc\x05\xf6\xde\xd2\xa4\xfe\x99E_\x13\xc4iI~D@\x0f\x1a\xed\xbb\x057\xccW\xe8te\x8eA\x15\x8d\xb2\x04x\x0c \x06>I\x06\xed \x8fX\xa0\x1a\x0bg\xf4N\xd5DYK\xc5#\xefP\xa3\xed\xb42`W\xe8s\x05\xb5\xb0\xc5J\xaa\xa5\x0f\x8e]L`N \x1c\xbe\xb5{9\xf7y\x80\xff\xc0%\xd7\xbf\xfc\x0e\x17jp!\x89Q\x96\xbe\xc9\x88\xe2\x05\xcf18\x83m\xb4c\xc1A\x987\xf3[\"\xd0\nm\x90\x04'LYp\x0f)7M\xa7\x8b\x13@\xb2=\x80\x8e\x95[\x8d\x0b\xb9y\xac\xb2\xb0\xabG\xaaj\\\xe2E\xd8q\xf0\xd7)S\x05\x9a\xf9-\x166Y\xa2\x0d\xbd4\x06\xee\x8dx\x0c\x9cG4M8g\xfbg\xc7}\xe1p\x03/;_ o\x98x\x95hT\xb4d\xd5\x18K\xec\xee#8\xf1\xc3<\\\xad\xc6%\xbe\xde\xe8j\x1e\xbe\x1dw\xc8\x83\x15\xda\x9a\xb5\x1c\xf7AB\xad1 &\xde\xf2L\x9d\xaf4\xd0E\x16\xc2\xae\xae\xc7\xf6M\x98}\\\x03qaW\xe4\xe6al\x0fc\xb9\xd6\xe1\x97\x1c;\x9b\xab\xd1|+j\x1f\x8f\xc6\xdcM\xbb\xa19\x9dJ|&.W\xa4c/\x1b\xabi\xf2\xed\x80\x9bb\x855\xf2)\xf8\x1f1pjY>\x05z\x0c9\x9c\x82\xcb\xd8\x9e\x98\xa5y|\xd0\xf5:Z\xaci9\xa3QJ\xfe\x93\x85T%\x0d\xdc\xdcX-\xd527\xdd\xdc\xb1\xccU\xc8\x82\xe0cx3\x0dW\xd6\xb6\xa9\xc9n\xa2\xe9d\x12\xdd\x84\xe9\x87I\xf6:\n\xd3\x0f7/\xb3\x9f\xa2\x8f1\x0b\x02cu\x0co#\x1a\xa2\x81\xaf\x17\xa8F\xd7\xa2\x92\x9f\xfd\xe7\xe5\x1a\xa2\xf7\xed\xc2;\xb3\xdc\xc7\xc9'\x9c\xa8\x1b\xab\x0f\xe5\xb8\xacLZ\xbd\xf2\x8b^\x99\x8d\xf7\xd5~\xf7\xf4o\xae`\x1b\x1a\x16\xa6\xad\xa4\x1d\x16\xf9\x9f\xb4\x9d\xf9=r\xe3\xfa\xe0\x1d\x0b6\xe9[w$\xea7\xec\xfd\xf1\x1e\x81\x9bVj,\x8f7\x89A\xb0\xa3=q\x9d\x1b,\x1aU\x9a\xe9\xcc\xca\x1a\x13\x92(\x13F\x93\xb7\xf8\x1b\x0b\xd2\x15\x8a\x12u\x0c\xfdN\x1fC\x9e\x11\x1f\xd9$\xb7k\x9b\x94X4\xe5a\xc72\xa8#Ji\x7f\xc8\xd9\xb4\xf0\x07\x9c8\xf0\x9c\xd46\xe5n\xaf\x07i\x0e\xd4B\xdc\xb4\x11\xcfv,\xe8%\x07]\xd3j\xa9\xec\"\xecmV\xc2\xc0\\\x94 \xbaR\xa2*\x10B\xd1\x95\xd1\x14^\x19\xa0\xed]*x\xf5\xfa\x13\x8fS\xcf\xc8u\xd1\xc0Gte\x16\x91\x8b'\xc4D\xd8Xa\x8d\xcaR\xad*ilx\x82\x1b\x1f\xddE\xa7\x87\x15\xb2\xa60\xdd\xb1\xe2xX\x19#\xb9\x1b\xa0\xd311\x9c9)~\xe1tt\xee\xf0\xc3\xcf\x9ei\xd8K +P\x8d\xfa\xd9\x89\x1dC\x03\x0b\xdd\xd4 \xe8\xbaG\x87\x1b\xbf\xe2\xa6\x89\xe9\x0b6\x04By\xf0x\xd9\xee|V\x1e\x11\xcb\xa3\xe9\xfa\x92\xcf`\xc7{\x087.\xfa\x9aq\x97\x0c>\x05\xf7\xf4\x03\xc4\xfd\x8caT\xdf\x87\xc5\xcd?\xa1\x96\x8b-\xcd\x8cc\x99c\x82\x08\x02n\xb0\xd0Hs\xeax'\x8f\xdd\x82\xe8\xc8\xddIg\xb1 \xd8\xb3\xc0Q%\x80\xe9\xec~\xbc$\xf3\xdf\xf7x\xc5\xdf\xee\xfc\xf5d\xbc\xe6\xa5\xcc\xc8\xa5\xc22\xbf]\xdb\xe9\xac\xe7\x8e\xcaq\xa7\x95p\xc7E\xb5\xe4S\xe0\x7f\xfd\xf3\xee\x97_\xf9~\x94\xeb\xb8\xff\xaf\x82\\*\x1a\x93w\xb8\x8d\x18c\xe3Z\xd1\x9f\xd8U\x90\x06\x0d\x00\xbd\xa79M[\x92\xb1=\xfb?\x00\x00\xff\xffPK\x07\x08\xe8\xb4\xfa\xee\x9d\x04\x00\x00\xd5\x10\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00E\xb3\x9cP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00 \x00authz_test.regoUT\x05\x00\x01\x82\xad\xa8^\xd4V[O\xe38\x18}N~E\x94'X\x95\xb6\x1bz\x99AB;\x05\n\xd3\xdbPHK[\x10\x8a\xdc\xc4$n\x938\xb5\x1dz\x19\xf5\xbf\xaf\xec\xf4\x12 \x1dR\x16 \xed\x13\x8a\xed\xef|\xe7\x9c\xefB\x03`\x8e\x81\x0d\x95\x00{\x90\xa0\xd0\xcb\x82\x909\x0bY\x1eM\x99\xe1@`A\xa2\x9c\x9c*\xbfeIe\xf3@=Q\xd4z\xaf\xa3fdI\x05\xae\xcd?\x7f\xeaZ\xb1\xa4\xcaK\x99\"\xdbG\xbem\x8c\xe1|\x1d1fs\xfe\x04\x9bLD\x8c\xf9\xc7\xf5\xf8\xd2\x9b\xb4\x1a\xdf\xbby\xcbk;\xad\xf3^\xfen0/]\x18\x04\xd4\x1b\xd3j\x9d\xb6\xac\xd9\xc4\xf2\xc3q\xc7Y\x8c\xf1\xf1\x85\xd1'\x149\xd3A5\x1f\xccHW\x0f\xbc|\xbdCz\xdaMP[\x14H\xe7\xefg\xab\xfa|?-\x95{\xed\xc2\x8cLFh:\xb7\xcam;hw.\x8a\xb3\xe7\x9b\xb3V\xb9Sk \xbd\x97\xefk\xb7\xf9\xe0ib\\\xd7\x18]\xb4on\xd9\xb0|\x87\x08\xd1\x87Wu\xd4\xfc\xa5\x1f\xfd\xaa\xb7Zdp\xd7\xe8\xf5Xwx\xa7w\xfa\xd5Q\xb3|g^NZ\xcdb\x1b\xe9\xb0\xdc\xbf\xf0\xe6\xe7\xf7\xa3\xc0\xae\x06O\xd5\xe2\xcd7mQ\x83\xfd\x96F\x9bdQ\xfa\xd9\xd3*\xdfk\xd3\xabq\xd9\xeb\xe9y\xb3X\xbe5\xb4\xfa\xd5\xfc\xf2Zc\xe7\x95\xc2\xa2Z\x1b8\xbd\xe7f\xb5\xa4]S\x8d\xdd\x97\x06\x84L\xad\xb3o\xfeqq\xe4\xb6\x03\xbb[-\x05\xb8\xfa\\\xebjy\xb7\xdd\x04\xd8\xc4\x8b\xfe\xa05\xa9\x8c\xc3\xa3F\xddwq\xdd\xad,\x1a\xb6\xd6\x07F\x1e\xe9H\xb7\xf5J\xe8\xcd\n\x85\xb3c\xbf|q3\xb2\x8fGm\xe7\xd6\x16\x05p\x00\x81\xd6\xda\xff!\xa0\xb0T\x08\x89\x9b\xb5\xa0\x89-x\x10\xabOv|(\xcb\x0cRf@\x0f \xd7\x00\xae\x8b\xa7\xd0\xe25\x0biTp\x84\xb3\xa3)\xcbB\x9f\xc7\x1a<\xf6`\xdb\x11\x19\xfeRRAh\xa9'\xca\x83\ng\xc0\x0b\\\x985\xb1\xa7>f\xf8\x8d\x80\xe5\xd5\x1ea\xf8#~-K\xcb\x8c\x12cr(\xcb\x92\xc8\xaeL\x11s\x14\x0b0\x90%8d\xd0\x08\xb0\x8bL\x04\xa9\x02\xa8\xf2 \xd2Q\x1c\x12\x13r\xd48\xa2\xc8\xb7\x12`p\xf6Tpz\x9d\xf8Q\x96\x96\x8f\xb1$\xf1n\x054N)\xfeh\xeb(\x7f\xb3\xfd\x12O\x90\x1f\x84\x8c_\x08v!\x11\x82\x1d\xc6\x82\x93\\\xee\x0dC\x07S\x96H\x9dSVO\x14\xfeG\x96\x96\xf2r]\x98\xe8\xdd\x97\x94D\xf21SRTE\x96$\x9e4^\x99\x1d\xf2%5\x00\xcc\xe1\x0fr`u\xb0.\x99\x85=\x80|\xfa\x96\xb5,I\xcb\xcc\x87R\x0c_\xa5\xd8v\x85\x8f\xb1\x0f\x7flV]<\xcf\xd74\xc7\x8a\xeb\xfe\xed!\xe6\xd6\x82>\xfa\xb2\xb1M\xd9$\xfb\x8f\xee\x10\x0f\xff\xd7\xa3\x1b\x84C\x17\x99\xf1\xa5\xfa 6U8D[ w}\xfe/\x1a\xfa\x0c\x99\x80A\xabb\x9a\x90r\xe7\x18 \xe1\xd6\xaa\xff,1\x92\x14W\xb4m\xb7\x94\xb5O\x98\xde\x84\xb1%\xf0 \xcd\xa2\xc1\x9d\x1f Ow\x8doBg$\xef\x88\xb7YR\xfb'-7\xbb \xa5\x85/h\xff\xc1\xca\x95\x97\xab\xe5\xf3\xc9\xfd\x91\xca\xac={#\x97]\x93\xcd\xbd\xa7\xed\xa5\xb4\xbd\x1b\xe5\x8b\xd5\x01\xcbC\xfe{\x12W\x1a\x01\xa1\xd0\x08\x89+\xb6.q\xf9\xd2\xdd\x9c\x1d$\xa5\xa1\xd8\x839\xfe\xbf\xe9\x9f U\x0fEP\x96\x9a\x0e\xf4\xa0rz\x1a\x11S\xa3S\x9e[\x9c\xbdL\xce\xafx\xbc\xb8\xda\xc2\xa9\x1bNkw\"c#\x1b7m\xb5>O\xe2\xa6f\x94\xdf;l_\x1e\xee\x1f\x9f\xf0\xe0\xa30\xf4#8\xb9\xcf\x02z\x1f'\x97\x0e(\x05\xa3\x08i3';\xd10\xb1\xff\\\xae\xe4n\x88\xb6k\xfan\x88m\xe3\x94\x12\xc5\xf0\x88\xb6\x14]\xf9\n$\x1a\xadt\x12\x138l\xc2w\xa8\xe3c\x91^\xdb\xfa\x07bJe A\xa9D$Z\xb2\xf9\xfd\xfb\x11C\xde\x04'\xdbA\xa0\x0d\xf7\xa8\xb5x\xceq\xb3\x7f\xa5t$A\xd8\x06du\xb9\xc2J/n\x03\xf00\x9b/\x1e#q\xff\x06\x00\x00\xff\xffPK\x07\x08\xa6?V\xfb\n\x04\x00\x00\x95\x10\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\xcd\xb0\x9cP\xe8\xb4\xfa\xee\x9d\x04\x00\x00\xd5\x10\x00\x00\n\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00authz.regoUT\x05\x00\x01\xe2\xa8\xa8^PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00E\xb3\x9cP\xa6?V\xfb\n\x04\x00\x00\x95\x10\x00\x00\x0f\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xde\x04\x00\x00authz_test.regoUT\x05\x00\x01\x82\xad\xa8^PK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\x87\x00\x00\x00. \x00\x00\x00\x00" fs.RegisterWithNamespace("rego", data) } \ No newline at end of file diff --git a/authorize/grpc.go b/authorize/grpc.go index d42aaaf5b..fa1a70e90 100644 --- a/authorize/grpc.go +++ b/authorize/grpc.go @@ -8,6 +8,7 @@ import ( "github.com/pomerium/pomerium/authorize/evaluator" "github.com/pomerium/pomerium/internal/grpc/authorize" + "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/telemetry/trace" ) @@ -25,7 +26,19 @@ func (a *Authorize) IsAuthorized(ctx context.Context, in *authorize.IsAuthorized RemoteAddr: in.GetRequestRemoteAddr(), URL: getFullURL(in.GetRequestUrl(), in.GetRequestHost()), } - return a.pe.IsAuthorized(ctx, req) + reply, err := a.pe.IsAuthorized(ctx, req) + log.Info(). + // request + Str("method", req.Method). + Str("url", req.URL). + // reply + Bool("allow", reply.Allow). + Strs("deny-reasons", reply.DenyReasons). + Str("user", reply.User). + Str("email", reply.Email). + Strs("groups", reply.Groups). + Msg("authorize.grpc.IsAuthorized") + return reply, err } type protoHeader map[string]*authorize.IsAuthorizedRequest_Headers diff --git a/go.sum b/go.sum index dd1ccadda..4d5d64147 100644 --- a/go.sum +++ b/go.sum @@ -108,12 +108,11 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= @@ -513,8 +512,6 @@ google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -549,6 +546,7 @@ google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLY google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/integration/authorization_test.go b/integration/authorization_test.go index b4f5c1f1f..35f311877 100644 --- a/integration/authorization_test.go +++ b/integration/authorization_test.go @@ -16,8 +16,6 @@ func TestAuthorization(t *testing.T) { defer clearTimeout() t.Run("public", func(t *testing.T) { - t.Skip() // pomerium doesn't currently handle unauthenticated public routes - client := testcluster.NewHTTPClient() req, err := http.NewRequestWithContext(ctx, "GET", "https://httpdetails.localhost.pomerium.io", nil) @@ -33,7 +31,6 @@ func TestAuthorization(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode, "unexpected status code, headers=%v", res.Header) }) - t.Run("domains", func(t *testing.T) { t.Run("allowed", func(t *testing.T) { client := testcluster.NewHTTPClient() @@ -78,7 +75,7 @@ func TestAuthorization(t *testing.T) { client := testcluster.NewHTTPClient() res, err := flows.Authenticate(ctx, client, mustParseURL("https://httpdetails.localhost.pomerium.io/by-group"), "joe@cats.test", []string{"user"}) if assert.NoError(t, err) { - assertDeniedAccess(t, res, "expected Forbidden for user") + assertDeniedAccess(t, res, "expected Forbidden for user, but got %d", res.StatusCode) } }) }) diff --git a/integration/dashboard_test.go b/integration/dashboard_test.go index 84a83d1bc..b973ecbf3 100644 --- a/integration/dashboard_test.go +++ b/integration/dashboard_test.go @@ -28,6 +28,23 @@ func TestDashboard(t *testing.T) { } defer res.Body.Close() + assert.Equal(t, http.StatusOK, res.StatusCode, "unexpected status code") + assert.Equal(t, "image/svg+xml", res.Header.Get("Content-Type")) + }) + t.Run("forward auth image asset", func(t *testing.T) { + client := testcluster.NewHTTPClient() + + req, err := http.NewRequestWithContext(ctx, "GET", "https://fa-httpdetails.localhost.pomerium.io/.pomerium/assets/img/pomerium.svg", nil) + if err != nil { + t.Fatal(err) + } + + res, err := client.Do(req) + if !assert.NoError(t, err, "unexpected http error") { + return + } + defer res.Body.Close() + assert.Equal(t, http.StatusOK, res.StatusCode, "unexpected status code") assert.Equal(t, "image/svg+xml", res.Header.Get("Content-Type")) }) diff --git a/integration/manifests/lib/pomerium.libsonnet b/integration/manifests/lib/pomerium.libsonnet index 19b173f22..3911c7e40 100644 --- a/integration/manifests/lib/pomerium.libsonnet +++ b/integration/manifests/lib/pomerium.libsonnet @@ -1,30 +1,33 @@ local tls = import './tls.libsonnet'; -local PomeriumPolicy = function() [ - { - from: 'http://httpdetails.localhost.pomerium.io', - prefix: '/by-domain', - to: 'http://httpdetails.default.svc.cluster.local', - allowed_domains: ['dogs.test'], - }, - { - from: 'http://httpdetails.localhost.pomerium.io', - prefix: '/by-user', - to: 'http://httpdetails.default.svc.cluster.local', - allowed_users: ['bob@dogs.test'], - }, - { - from: 'http://httpdetails.localhost.pomerium.io', - prefix: '/by-group', - to: 'http://httpdetails.default.svc.cluster.local', - allowed_groups: ['admin'], - }, - { - from: 'http://httpdetails.localhost.pomerium.io', - to: 'http://httpdetails.default.svc.cluster.local', - allow_public_unauthenticated_access: true, - }, -]; +local PomeriumPolicy = function() std.flattenArrays([ + [ + { + from: 'http://' + domain + '.localhost.pomerium.io', + prefix: '/by-domain', + to: 'http://' + domain + '.default.svc.cluster.local', + allowed_domains: ['dogs.test'], + }, + { + from: 'http://' + domain + '.localhost.pomerium.io', + prefix: '/by-user', + to: 'http://' + domain + '.default.svc.cluster.local', + allowed_users: ['bob@dogs.test'], + }, + { + from: 'http://' + domain + '.localhost.pomerium.io', + prefix: '/by-group', + to: 'http://' + domain + '.default.svc.cluster.local', + allowed_groups: ['admin'], + }, + { + from: 'http://' + domain + '.localhost.pomerium.io', + to: 'http://' + domain + '.default.svc.cluster.local', + allow_public_unauthenticated_access: true, + }, + ] + for domain in ['httpdetails', 'fa-httpdetails'] +]); local PomeriumPolicyHash = std.base64(std.md5(std.manifestJsonEx(PomeriumPolicy(), ''))); @@ -292,20 +295,27 @@ local PomeriumForwardAuthIngress = function() { tls: [ { hosts: [ - 'fa-httpecho.localhost.pomerium.io', + 'fa-httpdetails.localhost.pomerium.io', ], secretName: 'pomerium-tls', }, ], rules: [ { - host: 'fa-httpecho.localhost.pomerium.io', + host: 'fa-httpdetails.localhost.pomerium.io', http: { paths: [ + { + path: '/.pomerium/', + backend: { + serviceName: 'proxy', + servicePort: 'https', + }, + }, { path: '/', backend: { - serviceName: 'httpecho', + serviceName: 'httpdetails', servicePort: 'http', }, }, diff --git a/proxy/forward_auth.go b/proxy/forward_auth.go index 133948154..d7fe72226 100644 --- a/proxy/forward_auth.go +++ b/proxy/forward_auth.go @@ -117,21 +117,22 @@ func (p *Proxy) Verify(verifyOnly bool) http.Handler { } originalRequest := p.getOriginalRequest(r, uri) - if _, err := sessions.FromContext(r.Context()); err != nil { - if verifyOnly { - return httputil.NewError(http.StatusUnauthorized, err) - } - authN := *p.authenticateSigninURL - q := authN.Query() - q.Set(urlutil.QueryCallbackURI, uri.String()) - q.Set(urlutil.QueryRedirectURI, uri.String()) // final destination - q.Set(urlutil.QueryForwardAuth, urlutil.StripPort(r.Host)) // add fwd auth to trusted audience - authN.RawQuery = q.Encode() - httputil.Redirect(w, r, urlutil.NewSignedURL(p.SharedKey, &authN).String(), http.StatusFound) - return nil - } - if err := p.authorize(w, originalRequest); err != nil { + // no session, so redirect + if _, err := sessions.FromContext(r.Context()); err != nil { + if verifyOnly { + return httputil.NewError(http.StatusUnauthorized, err) + } + authN := *p.authenticateSigninURL + q := authN.Query() + q.Set(urlutil.QueryCallbackURI, uri.String()) + q.Set(urlutil.QueryRedirectURI, uri.String()) // final destination + q.Set(urlutil.QueryForwardAuth, urlutil.StripPort(r.Host)) // add fwd auth to trusted audience + authN.RawQuery = q.Encode() + httputil.Redirect(w, r, urlutil.NewSignedURL(p.SharedKey, &authN).String(), http.StatusFound) + return nil + } + return err } diff --git a/proxy/middleware.go b/proxy/middleware.go index 22f3076fb..555477b50 100644 --- a/proxy/middleware.go +++ b/proxy/middleware.go @@ -103,10 +103,7 @@ func (p *Proxy) AuthorizeSession(next http.Handler) http.Handler { func (p *Proxy) authorize(w http.ResponseWriter, r *http.Request) error { ctx, span := trace.StartSpan(r.Context(), "proxy.authorize") defer span.End() - jwt, err := sessions.FromContext(ctx) - if err != nil { - return httputil.NewError(http.StatusInternalServerError, err) - } + jwt, _ := sessions.FromContext(ctx) authz, err := p.AuthorizeClient.Authorize(ctx, jwt, r) if err != nil { return httputil.NewError(http.StatusInternalServerError, err) diff --git a/proxy/middleware_test.go b/proxy/middleware_test.go index 455d72395..174f04768 100644 --- a/proxy/middleware_test.go +++ b/proxy/middleware_test.go @@ -159,7 +159,7 @@ func TestProxy_AuthorizeSession(t *testing.T) { }{ {"user is authorized", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeResponse: &authorize.IsAuthorizedReply{Allow: true}}, nil, identity.MockProvider{}, http.StatusOK}, {"user is not authorized", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeResponse: &authorize.IsAuthorizedReply{Allow: false}}, nil, identity.MockProvider{}, http.StatusForbidden}, - {"ctx error", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeResponse: &authorize.IsAuthorizedReply{Allow: true}}, errors.New("hi"), identity.MockProvider{}, http.StatusInternalServerError}, + {"ctx error", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeResponse: &authorize.IsAuthorizedReply{Allow: true}}, errors.New("hi"), identity.MockProvider{}, http.StatusOK}, {"authz client error", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeError: errors.New("err")}, nil, identity.MockProvider{}, http.StatusInternalServerError}, {"expired, reauth failed", 200, &mstore.Store{Session: &sessions.State{Email: "user@test.example", Expiry: jwt.NewNumericDate(time.Now().Add(10 * time.Second))}}, client.MockAuthorize{AuthorizeResponse: &authorize.IsAuthorizedReply{SessionExpired: true}}, nil, identity.MockProvider{}, http.StatusForbidden}, //todo(bdd): it's a bit tricky to test the refresh flow