...

Source file src/github.com/ory/fosite/introspection_request_handler_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  	"context"
    26  	"fmt"
    27  	"net/http"
    28  	"net/url"
    29  	"testing"
    30  
    31  	"github.com/golang/mock/gomock"
    32  	"github.com/pkg/errors"
    33  	"github.com/stretchr/testify/assert"
    34  	"github.com/stretchr/testify/require"
    35  
    36  	"github.com/ory/fosite"
    37  	. "github.com/ory/fosite"
    38  	"github.com/ory/fosite/compose"
    39  	"github.com/ory/fosite/internal"
    40  	"github.com/ory/fosite/storage"
    41  )
    42  
    43  func TestIntrospectionResponseTokenUse(t *testing.T) {
    44  	ctrl := gomock.NewController(t)
    45  	validator := internal.NewMockTokenIntrospector(ctrl)
    46  	defer ctrl.Finish()
    47  
    48  	ctx := gomock.AssignableToTypeOf(context.WithValue(context.TODO(), ContextKey("test"), nil))
    49  
    50  	f := compose.ComposeAllEnabled(new(compose.Config), storage.NewExampleStore(), []byte{}, nil).(*Fosite)
    51  	httpreq := &http.Request{
    52  		Method: "POST",
    53  		Header: http.Header{
    54  			"Authorization": []string{"bearer some-token"},
    55  		},
    56  		PostForm: url.Values{
    57  			"token": []string{"introspect-token"},
    58  		},
    59  	}
    60  	for k, c := range []struct {
    61  		description string
    62  		setup       func()
    63  		expectedTU  TokenUse
    64  		expectedATT string
    65  	}{
    66  		{
    67  			description: "introspecting access token",
    68  			setup: func() {
    69  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
    70  				validator.EXPECT().IntrospectToken(ctx, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
    71  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(AccessToken, nil)
    72  			},
    73  			expectedATT: BearerAccessToken,
    74  			expectedTU:  AccessToken,
    75  		},
    76  		{
    77  			description: "introspecting refresh token",
    78  			setup: func() {
    79  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
    80  				validator.EXPECT().IntrospectToken(ctx, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
    81  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(RefreshToken, nil)
    82  			},
    83  			expectedATT: "",
    84  			expectedTU:  RefreshToken,
    85  		},
    86  	} {
    87  		t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
    88  			c.setup()
    89  			res, err := f.NewIntrospectionRequest(context.TODO(), httpreq, &DefaultSession{})
    90  			require.NoError(t, err)
    91  			assert.Equal(t, c.expectedATT, res.GetAccessTokenType())
    92  			assert.Equal(t, c.expectedTU, res.GetTokenUse())
    93  		})
    94  	}
    95  }
    96  func TestIntrospectionResponse(t *testing.T) {
    97  	r := &fosite.IntrospectionResponse{
    98  		AccessRequester: fosite.NewAccessRequest(nil),
    99  		Active:          true,
   100  	}
   101  
   102  	assert.Equal(t, r.AccessRequester, r.GetAccessRequester())
   103  	assert.Equal(t, r.Active, r.IsActive())
   104  }
   105  
   106  func TestNewIntrospectionRequest(t *testing.T) {
   107  	ctrl := gomock.NewController(t)
   108  	validator := internal.NewMockTokenIntrospector(ctrl)
   109  	defer ctrl.Finish()
   110  
   111  	ctx := gomock.AssignableToTypeOf(context.WithValue(context.TODO(), ContextKey("test"), nil))
   112  
   113  	f := compose.ComposeAllEnabled(new(compose.Config), storage.NewExampleStore(), []byte{}, nil).(*Fosite)
   114  	httpreq := &http.Request{
   115  		Method: "POST",
   116  		Header: http.Header{},
   117  		Form:   url.Values{},
   118  	}
   119  	newErr := errors.New("asdf")
   120  
   121  	for k, c := range []struct {
   122  		description string
   123  		setup       func()
   124  		expectErr   error
   125  		isActive    bool
   126  	}{
   127  		{
   128  			description: "should fail",
   129  			setup: func() {
   130  			},
   131  			expectErr: ErrInvalidRequest,
   132  		},
   133  		{
   134  			description: "should fail",
   135  			setup: func() {
   136  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
   137  				httpreq = &http.Request{
   138  					Method: "POST",
   139  					Header: http.Header{
   140  						"Authorization": []string{"bearer some-token"},
   141  					},
   142  					PostForm: url.Values{
   143  						"token": []string{"introspect-token"},
   144  					},
   145  				}
   146  				validator.EXPECT().IntrospectToken(ctx, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   147  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), newErr)
   148  			},
   149  			isActive:  false,
   150  			expectErr: ErrInactiveToken,
   151  		},
   152  		{
   153  			description: "should pass",
   154  			setup: func() {
   155  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
   156  				httpreq = &http.Request{
   157  					Method: "POST",
   158  					Header: http.Header{
   159  						"Authorization": []string{"bearer some-token"},
   160  					},
   161  					PostForm: url.Values{
   162  						"token": []string{"introspect-token"},
   163  					},
   164  				}
   165  				validator.EXPECT().IntrospectToken(ctx, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   166  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   167  			},
   168  			isActive: true,
   169  		},
   170  		{
   171  			description: "should pass with basic auth if username and password encoded",
   172  			setup: func() {
   173  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
   174  				httpreq = &http.Request{
   175  					Method: "POST",
   176  					Header: http.Header{
   177  						//Basic Authorization with username=encoded:client and password=encoded&password
   178  						"Authorization": []string{"Basic ZW5jb2RlZCUzQWNsaWVudDplbmNvZGVkJTI2cGFzc3dvcmQ="},
   179  					},
   180  					PostForm: url.Values{
   181  						"token": []string{"introspect-token"},
   182  					},
   183  				}
   184  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   185  			},
   186  			isActive: true,
   187  		},
   188  		{
   189  			description: "should pass with basic auth if username and password not encoded",
   190  			setup: func() {
   191  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
   192  				httpreq = &http.Request{
   193  					Method: "POST",
   194  					Header: http.Header{
   195  						//Basic Authorization with username=my-client and password=foobar
   196  						"Authorization": []string{"Basic bXktY2xpZW50OmZvb2Jhcg=="},
   197  					},
   198  					PostForm: url.Values{
   199  						"token": []string{"introspect-token"},
   200  					},
   201  				}
   202  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   203  			},
   204  			isActive: true,
   205  		},
   206  		{
   207  			description: "should pass with basic auth if username and password not encoded",
   208  			setup: func() {
   209  				f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
   210  				httpreq = &http.Request{
   211  					Method: "POST",
   212  					Header: http.Header{
   213  						//Basic Authorization with username=my-client and password=foobaz
   214  						"Authorization": []string{"Basic bXktY2xpZW50OmZvb2Jheg=="},
   215  					},
   216  					PostForm: url.Values{
   217  						"token": []string{"introspect-token"},
   218  					},
   219  				}
   220  				validator.EXPECT().IntrospectToken(ctx, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(TokenUse(""), nil)
   221  			},
   222  			isActive: true,
   223  		},
   224  	} {
   225  		t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
   226  			c.setup()
   227  			res, err := f.NewIntrospectionRequest(context.TODO(), httpreq, &DefaultSession{})
   228  
   229  			if c.expectErr != nil {
   230  				assert.EqualError(t, err, c.expectErr.Error())
   231  			} else {
   232  				require.NoError(t, err)
   233  				assert.Equal(t, c.isActive, res.IsActive())
   234  			}
   235  		})
   236  	}
   237  }
   238  

View as plain text