...

Source file src/github.com/ory/fosite/authorize_error_test.go

Documentation: github.com/ory/fosite

     1  /*
     2   * Copyright © 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   * @author		Aeneas Rekkas <aeneas+oss@aeneas.io>
    17   * @copyright 	2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
    18   * @license 	Apache-2.0
    19   *
    20   */
    21  
    22  package fosite_test
    23  
    24  import (
    25  	"fmt"
    26  	"net/http"
    27  	"net/url"
    28  	"testing"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/stretchr/testify/assert"
    32  
    33  	. "github.com/ory/fosite"
    34  	. "github.com/ory/fosite/internal"
    35  )
    36  
    37  // Test for
    38  // * https://tools.ietf.org/html/rfc6749#section-4.1.2.1
    39  //   If the request fails due to a missing, invalid, or mismatching
    40  //   redirection URI, or if the client identifier is missing or invalid,
    41  //   the authorization server SHOULD inform the resource owner of the
    42  //   error and MUST NOT automatically redirect the user-agent to the
    43  //   invalid redirection URI.
    44  // * https://tools.ietf.org/html/rfc6749#section-3.1.2
    45  //   The redirection endpoint URI MUST be an absolute URI as defined by
    46  //   [RFC3986] Section 4.3.  The endpoint URI MAY include an
    47  //   "application/x-www-form-urlencoded" formatted (per Appendix B) query
    48  //   component ([RFC3986] Section 3.4), which MUST be retained when adding
    49  //   additional query parameters.  The endpoint URI MUST NOT include a
    50  //   fragment component.
    51  func TestWriteAuthorizeError(t *testing.T) {
    52  	var urls = []string{
    53  		"https://foobar.com/",
    54  		"https://foobar.com/?foo=bar",
    55  	}
    56  	var purls = []*url.URL{}
    57  	for _, u := range urls {
    58  		purl, _ := url.Parse(u)
    59  		purls = append(purls, purl)
    60  	}
    61  
    62  	header := http.Header{}
    63  	for k, c := range []struct {
    64  		err                  *RFC6749Error
    65  		debug                bool
    66  		doNotUseLegacyFormat bool
    67  		mock                 func(*MockResponseWriter, *MockAuthorizeRequester)
    68  		checkHeader          func(*testing.T, int)
    69  	}{
    70  		// 0
    71  		{
    72  			err: ErrInvalidGrant,
    73  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
    74  				req.EXPECT().IsRedirectURIValid().Return(false)
    75  				req.EXPECT().GetResponseMode().Return(ResponseModeDefault)
    76  				rw.EXPECT().Header().Times(3).Return(header)
    77  				rw.EXPECT().WriteHeader(http.StatusBadRequest)
    78  				rw.EXPECT().Write(gomock.Any())
    79  			},
    80  			checkHeader: func(t *testing.T, k int) {
    81  				assert.Equal(t, "application/json;charset=UTF-8", header.Get("Content-Type"))
    82  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
    83  				assert.Equal(t, "no-cache", header.Get("Pragma"))
    84  			},
    85  		},
    86  		// 1
    87  		{
    88  			debug: true,
    89  			err:   ErrInvalidRequest.WithDebug("with-debug"),
    90  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
    91  				req.EXPECT().IsRedirectURIValid().Return(true)
    92  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
    93  				req.EXPECT().GetState().Return("foostate")
    94  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
    95  				req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
    96  				rw.EXPECT().Header().Times(3).Return(header)
    97  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
    98  			},
    99  			checkHeader: func(t *testing.T, k int) {
   100  				a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   101  				b, _ := url.Parse(header.Get("Location"))
   102  				assert.Equal(t, a, b)
   103  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   104  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   105  			},
   106  		},
   107  		// 2
   108  		{
   109  			debug:                true,
   110  			doNotUseLegacyFormat: true,
   111  			err:                  ErrInvalidRequest.WithDebug("with-debug"),
   112  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   113  				req.EXPECT().IsRedirectURIValid().Return(true)
   114  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   115  				req.EXPECT().GetState().Return("foostate")
   116  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
   117  				req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
   118  				rw.EXPECT().Header().Times(3).Return(header)
   119  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   120  			},
   121  			checkHeader: func(t *testing.T, k int) {
   122  				a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.+with-debug&state=foostate")
   123  				b, _ := url.Parse(header.Get("Location"))
   124  				assert.Equal(t, a, b)
   125  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   126  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   127  			},
   128  		},
   129  		// 3
   130  		{
   131  			doNotUseLegacyFormat: true,
   132  			err:                  ErrInvalidRequest.WithDebug("with-debug"),
   133  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   134  				req.EXPECT().IsRedirectURIValid().Return(true)
   135  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   136  				req.EXPECT().GetState().Return("foostate")
   137  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
   138  				req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
   139  				rw.EXPECT().Header().Times(3).Return(header)
   140  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   141  			},
   142  			checkHeader: func(t *testing.T, k int) {
   143  				a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   144  				b, _ := url.Parse(header.Get("Location"))
   145  				assert.Equal(t, a, b)
   146  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   147  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   148  			},
   149  		},
   150  		// 4
   151  		{
   152  			err: ErrInvalidRequest.WithDebug("with-debug"),
   153  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   154  				req.EXPECT().IsRedirectURIValid().Return(true)
   155  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   156  				req.EXPECT().GetState().Return("foostate")
   157  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
   158  				req.EXPECT().GetResponseMode().Return(ResponseModeDefault).AnyTimes()
   159  				rw.EXPECT().Header().Times(3).Return(header)
   160  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   161  			},
   162  			checkHeader: func(t *testing.T, k int) {
   163  				a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   164  				b, _ := url.Parse(header.Get("Location"))
   165  				assert.Equal(t, a, b)
   166  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   167  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   168  			},
   169  		},
   170  		// 5
   171  		{
   172  			err: ErrInvalidRequest,
   173  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   174  				req.EXPECT().IsRedirectURIValid().Return(true)
   175  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   176  				req.EXPECT().GetState().Return("foostate")
   177  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
   178  				req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
   179  				rw.EXPECT().Header().Times(3).Return(header)
   180  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   181  			},
   182  			checkHeader: func(t *testing.T, k int) {
   183  				a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&foo=bar&state=foostate")
   184  				b, _ := url.Parse(header.Get("Location"))
   185  				assert.Equal(t, a, b)
   186  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   187  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   188  			},
   189  		},
   190  		// 6
   191  		{
   192  			err: ErrUnsupportedGrantType,
   193  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   194  				req.EXPECT().IsRedirectURIValid().Return(true)
   195  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   196  				req.EXPECT().GetState().Return("foostate")
   197  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"foobar"}))
   198  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   199  				rw.EXPECT().Header().Times(3).Return(header)
   200  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   201  			},
   202  			checkHeader: func(t *testing.T, k int) {
   203  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=unsupported_grant_type&error_description=The+authorization+grant+type+is+not+supported+by+the+authorization+server.&state=foostate")
   204  				b, _ := url.Parse(header.Get("Location"))
   205  				assert.Equal(t, a, b)
   206  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   207  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   208  			},
   209  		},
   210  		// 7
   211  		{
   212  			err: ErrInvalidRequest,
   213  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   214  				req.EXPECT().IsRedirectURIValid().Return(true)
   215  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   216  				req.EXPECT().GetState().Return("foostate")
   217  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
   218  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   219  				rw.EXPECT().Header().Times(3).Return(header)
   220  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   221  			},
   222  			checkHeader: func(t *testing.T, k int) {
   223  				a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   224  				b, _ := url.Parse(header.Get("Location"))
   225  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   226  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   227  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   228  			},
   229  		},
   230  		// 8
   231  		{
   232  			err: ErrInvalidRequest,
   233  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   234  				req.EXPECT().IsRedirectURIValid().Return(true)
   235  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   236  				req.EXPECT().GetState().Return("foostate")
   237  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
   238  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   239  				rw.EXPECT().Header().Times(3).Return(header)
   240  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   241  			},
   242  			checkHeader: func(t *testing.T, k int) {
   243  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   244  				b, _ := url.Parse(header.Get("Location"))
   245  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   246  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   247  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   248  			},
   249  		},
   250  		// 9
   251  		{
   252  			err: ErrInvalidRequest.WithDebug("with-debug"),
   253  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   254  				req.EXPECT().IsRedirectURIValid().Return(true)
   255  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   256  				req.EXPECT().GetState().Return("foostate")
   257  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   258  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   259  				rw.EXPECT().Header().Times(3).Return(header)
   260  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   261  			},
   262  			checkHeader: func(t *testing.T, k int) {
   263  				a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   264  				b, _ := url.Parse(header.Get("Location"))
   265  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   266  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   267  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   268  			},
   269  		},
   270  		// 10
   271  		{
   272  			err:   ErrInvalidRequest.WithDebug("with-debug"),
   273  			debug: true,
   274  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   275  				req.EXPECT().IsRedirectURIValid().Return(true)
   276  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   277  				req.EXPECT().GetState().Return("foostate")
   278  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   279  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   280  				rw.EXPECT().Header().Times(3).Return(header)
   281  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   282  			},
   283  			checkHeader: func(t *testing.T, k int) {
   284  				a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   285  				b, _ := url.Parse(header.Get("Location"))
   286  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   287  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   288  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   289  			},
   290  		},
   291  		// 11
   292  		{
   293  			err:                  ErrInvalidRequest.WithDebug("with-debug"),
   294  			debug:                true,
   295  			doNotUseLegacyFormat: true,
   296  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   297  				req.EXPECT().IsRedirectURIValid().Return(true)
   298  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   299  				req.EXPECT().GetState().Return("foostate")
   300  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   301  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   302  				rw.EXPECT().Header().Times(3).Return(header)
   303  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   304  			},
   305  			checkHeader: func(t *testing.T, k int) {
   306  				a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.+with-debug&state=foostate")
   307  				b, _ := url.Parse(header.Get("Location"))
   308  				assert.NotContains(t, header.Get("Location"), "error_hint")
   309  				assert.NotContains(t, header.Get("Location"), "error_debug")
   310  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   311  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   312  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   313  			},
   314  		},
   315  		// 12
   316  		{
   317  			err:                  ErrInvalidRequest.WithDebug("with-debug"),
   318  			doNotUseLegacyFormat: true,
   319  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   320  				req.EXPECT().IsRedirectURIValid().Return(true)
   321  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[0]))
   322  				req.EXPECT().GetState().Return("foostate")
   323  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   324  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   325  				rw.EXPECT().Header().Times(3).Return(header)
   326  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   327  			},
   328  			checkHeader: func(t *testing.T, k int) {
   329  				a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   330  				b, _ := url.Parse(header.Get("Location"))
   331  				assert.NotContains(t, header.Get("Location"), "error_hint")
   332  				assert.NotContains(t, header.Get("Location"), "error_debug")
   333  				assert.NotContains(t, header.Get("Location"), "with-debug")
   334  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   335  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   336  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   337  			},
   338  		},
   339  		// 13
   340  		{
   341  			err: ErrInvalidRequest.WithDebug("with-debug"),
   342  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   343  				req.EXPECT().IsRedirectURIValid().Return(true)
   344  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   345  				req.EXPECT().GetState().Return("foostate")
   346  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   347  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   348  				rw.EXPECT().Header().Times(3).Return(header)
   349  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   350  			},
   351  			checkHeader: func(t *testing.T, k int) {
   352  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   353  				b, _ := url.Parse(header.Get("Location"))
   354  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   355  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   356  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   357  			},
   358  		},
   359  		// 14
   360  		{
   361  			debug: true,
   362  			err:   ErrInvalidRequest.WithDebug("with-debug"),
   363  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   364  				req.EXPECT().IsRedirectURIValid().Return(true)
   365  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   366  				req.EXPECT().GetState().Return("foostate")
   367  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
   368  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   369  				rw.EXPECT().Header().Times(3).Return(header)
   370  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   371  			},
   372  			checkHeader: func(t *testing.T, k int) {
   373  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   374  				b, _ := url.Parse(header.Get("Location"))
   375  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   376  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   377  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   378  			},
   379  		},
   380  		// 15
   381  		{
   382  			debug: true,
   383  			err:   ErrInvalidRequest.WithDebug("with-debug"),
   384  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   385  				req.EXPECT().IsRedirectURIValid().Return(true)
   386  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   387  				req.EXPECT().GetState().Return("foostate")
   388  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"id_token"}))
   389  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   390  				rw.EXPECT().Header().Times(3).Return(header)
   391  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   392  			},
   393  			checkHeader: func(t *testing.T, k int) {
   394  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   395  				b, _ := url.Parse(header.Get("Location"))
   396  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   397  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   398  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   399  			},
   400  		},
   401  		// 16
   402  		{
   403  			debug: true,
   404  			err:   ErrInvalidRequest.WithDebug("with-debug"),
   405  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   406  				req.EXPECT().IsRedirectURIValid().Return(true)
   407  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   408  				req.EXPECT().GetState().Return("foostate")
   409  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
   410  				req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
   411  				rw.EXPECT().Header().Times(3).Return(header)
   412  				rw.EXPECT().WriteHeader(http.StatusSeeOther)
   413  			},
   414  			checkHeader: func(t *testing.T, k int) {
   415  				a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
   416  				b, _ := url.Parse(header.Get("Location"))
   417  				assert.Equal(t, a, b, "\n\t%s\n\t%s", header.Get("Location"), a.String())
   418  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   419  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   420  			},
   421  		},
   422  		// 17
   423  		{
   424  			debug: true,
   425  			err:   ErrInvalidRequest.WithDebug("with-debug"),
   426  			mock: func(rw *MockResponseWriter, req *MockAuthorizeRequester) {
   427  				req.EXPECT().IsRedirectURIValid().Return(true)
   428  				req.EXPECT().GetRedirectURI().Return(copyUrl(purls[1]))
   429  				req.EXPECT().GetState().Return("foostate")
   430  				req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
   431  				req.EXPECT().GetResponseMode().Return(ResponseModeFormPost).Times(2)
   432  				rw.EXPECT().Header().Times(3).Return(header)
   433  				rw.EXPECT().Write(gomock.Any()).AnyTimes()
   434  			},
   435  			checkHeader: func(t *testing.T, k int) {
   436  				assert.Equal(t, "no-store", header.Get("Cache-Control"))
   437  				assert.Equal(t, "no-cache", header.Get("Pragma"))
   438  				assert.Equal(t, "text/html;charset=UTF-8", header.Get("Content-Type"))
   439  			},
   440  		},
   441  	} {
   442  		t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
   443  			oauth2 := &Fosite{
   444  				SendDebugMessagesToClients: c.debug,
   445  				UseLegacyErrorFormat:       !c.doNotUseLegacyFormat,
   446  			}
   447  
   448  			ctrl := gomock.NewController(t)
   449  			defer ctrl.Finish()
   450  			rw := NewMockResponseWriter(ctrl)
   451  			req := NewMockAuthorizeRequester(ctrl)
   452  
   453  			c.mock(rw, req)
   454  			oauth2.WriteAuthorizeError(rw, req, c.err)
   455  			c.checkHeader(t, k)
   456  			header = http.Header{}
   457  		})
   458  	}
   459  }
   460  
   461  func copyUrl(u *url.URL) *url.URL {
   462  	u2, _ := url.Parse(u.String())
   463  	return u2
   464  }
   465  

View as plain text