@@ -21,6 +21,7 @@ package oauth
|
||||
import (
|
||||
"errors"
|
||||
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -152,12 +153,33 @@ type Client struct {
|
||||
AccessTokenInactivityTimeout *time.Duration `json:"accessTokenInactivityTimeout,omitempty" yaml:"accessTokenInactivityTimeout,omitempty"`
|
||||
}
|
||||
|
||||
var (
|
||||
// Allow any redirect URI if the redirectURI is defined in request
|
||||
AllowAllRedirectURI = "*"
|
||||
DefaultTokenMaxAge = time.Second * 86400
|
||||
DefaultAccessTokenInactivityTimeout = time.Duration(0)
|
||||
DefaultClients = []Client{{
|
||||
Name: "default",
|
||||
RespondWithChallenges: true,
|
||||
RedirectURIs: []string{AllowAllRedirectURI},
|
||||
GrantMethod: GrantHandlerAuto,
|
||||
ScopeRestrictions: []string{"full"},
|
||||
AccessTokenMaxAge: &DefaultTokenMaxAge,
|
||||
AccessTokenInactivityTimeout: &DefaultAccessTokenInactivityTimeout,
|
||||
}}
|
||||
)
|
||||
|
||||
func (o *Options) OAuthClient(name string) (Client, error) {
|
||||
for _, found := range o.Clients {
|
||||
if found.Name == name {
|
||||
return found, nil
|
||||
}
|
||||
}
|
||||
for _, defaultClient := range DefaultClients {
|
||||
if defaultClient.Name == name {
|
||||
return defaultClient, nil
|
||||
}
|
||||
}
|
||||
return Client{}, ErrorClientNotFound
|
||||
}
|
||||
func (o *Options) IdentityProviderOptions(name string) (IdentityProviderOptions, error) {
|
||||
@@ -169,16 +191,37 @@ func (o *Options) IdentityProviderOptions(name string) (IdentityProviderOptions,
|
||||
return IdentityProviderOptions{}, ErrorClientNotFound
|
||||
}
|
||||
|
||||
func (c Client) anyRedirectAbleURI() []string {
|
||||
uris := make([]string, 0)
|
||||
for _, uri := range c.RedirectURIs {
|
||||
_, err := url.Parse(uri)
|
||||
if err == nil {
|
||||
uris = append(uris, uri)
|
||||
}
|
||||
}
|
||||
return uris
|
||||
}
|
||||
|
||||
func (c Client) ResolveRedirectURL(expectURL string) (string, error) {
|
||||
// RedirectURIs is empty
|
||||
if len(c.RedirectURIs) == 0 {
|
||||
return "", ErrorRedirectURLNotAllowed
|
||||
}
|
||||
allowAllRedirectURI := sliceutil.HasString(c.RedirectURIs, AllowAllRedirectURI)
|
||||
redirectAbleURIs := c.anyRedirectAbleURI()
|
||||
|
||||
if expectURL == "" {
|
||||
return c.RedirectURIs[0], nil
|
||||
// Need to specify at least one RedirectURI
|
||||
if len(redirectAbleURIs) > 0 {
|
||||
return redirectAbleURIs[0], nil
|
||||
} else {
|
||||
return "", ErrorRedirectURLNotAllowed
|
||||
}
|
||||
}
|
||||
if sliceutil.HasString(c.RedirectURIs, expectURL) {
|
||||
if allowAllRedirectURI || sliceutil.HasString(redirectAbleURIs, expectURL) {
|
||||
return expectURL, nil
|
||||
}
|
||||
|
||||
return "", ErrorRedirectURLNotAllowed
|
||||
}
|
||||
|
||||
|
||||
104
pkg/apiserver/authentication/oauth/oauth_options_test.go
Normal file
104
pkg/apiserver/authentication/oauth/oauth_options_test.go
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2020 The KubeSphere Authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* /
|
||||
*/
|
||||
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDefaultAuthOptions(t *testing.T) {
|
||||
oneDay := time.Second * 86400
|
||||
zero := time.Duration(0)
|
||||
expect := Client{
|
||||
Name: "default",
|
||||
RespondWithChallenges: true,
|
||||
RedirectURIs: []string{AllowAllRedirectURI},
|
||||
GrantMethod: GrantHandlerAuto,
|
||||
ScopeRestrictions: []string{"full"},
|
||||
AccessTokenMaxAge: &oneDay,
|
||||
AccessTokenInactivityTimeout: &zero,
|
||||
}
|
||||
|
||||
options := NewOptions()
|
||||
client, err := options.OAuthClient("default")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff(expect, client); len(diff) != 0 {
|
||||
t.Errorf("%T differ (-got, +expected), %s", expect, diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientResolveRedirectURL(t *testing.T) {
|
||||
|
||||
options := NewOptions()
|
||||
defaultClient, err := options.OAuthClient("default")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tests := []struct {
|
||||
Name string
|
||||
client Client
|
||||
expectError error
|
||||
expectURL string
|
||||
}{
|
||||
{
|
||||
Name: "default client test",
|
||||
client: defaultClient,
|
||||
expectError: nil,
|
||||
expectURL: "https://localhost:8080/auth/cb",
|
||||
},
|
||||
{
|
||||
Name: "custom client test",
|
||||
client: Client{
|
||||
Name: "default",
|
||||
RespondWithChallenges: true,
|
||||
RedirectURIs: []string{"https://foo.bar.com/oauth/cb"},
|
||||
GrantMethod: GrantHandlerAuto,
|
||||
ScopeRestrictions: []string{"full"},
|
||||
},
|
||||
expectError: ErrorRedirectURLNotAllowed,
|
||||
expectURL: "https://foo.bar.com/oauth/err",
|
||||
},
|
||||
{
|
||||
Name: "custom client test",
|
||||
client: Client{
|
||||
Name: "default",
|
||||
RespondWithChallenges: true,
|
||||
RedirectURIs: []string{AllowAllRedirectURI, "https://foo.bar.com/oauth/cb"},
|
||||
GrantMethod: GrantHandlerAuto,
|
||||
ScopeRestrictions: []string{"full"},
|
||||
},
|
||||
expectError: nil,
|
||||
expectURL: "https://foo.bar.com/oauth/err2",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
redirectURL, err := test.client.ResolveRedirectURL(test.expectURL)
|
||||
if err != test.expectError {
|
||||
t.Errorf("expected error: %s, got: %s", test.expectError, err)
|
||||
}
|
||||
if test.expectError == nil && test.expectURL != redirectURL {
|
||||
t.Errorf("expected redirect url: %s, got: %s", test.expectURL, redirectURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user