mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-29 12:07:56 +01:00
Merge pull request #13791 from reasonerjt/oidc-redirect-extra-parm
Add extra parms when forming redirect URI for OIDC
This commit is contained in:
commit
bc0b6b43ed
@ -144,6 +144,7 @@ var (
|
|||||||
{Name: common.OIDCUserClaim, Scope: UserScope, Group: OIDCGroup, ItemType: &StringType{}},
|
{Name: common.OIDCUserClaim, Scope: UserScope, Group: OIDCGroup, ItemType: &StringType{}},
|
||||||
{Name: common.OIDCVerifyCert, Scope: UserScope, Group: OIDCGroup, DefaultValue: "true", ItemType: &BoolType{}},
|
{Name: common.OIDCVerifyCert, Scope: UserScope, Group: OIDCGroup, DefaultValue: "true", ItemType: &BoolType{}},
|
||||||
{Name: common.OIDCAutoOnboard, Scope: UserScope, Group: OIDCGroup, DefaultValue: "false", ItemType: &BoolType{}},
|
{Name: common.OIDCAutoOnboard, Scope: UserScope, Group: OIDCGroup, DefaultValue: "false", ItemType: &BoolType{}},
|
||||||
|
{Name: common.OIDCExtraRedirectParms, Scope: UserScope, Group: OIDCGroup, DefaultValue: "{}", ItemType: &StringToStringMapType{}},
|
||||||
|
|
||||||
{Name: common.WithChartMuseum, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_CHARTMUSEUM", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
|
{Name: common.WithChartMuseum, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_CHARTMUSEUM", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
|
||||||
{Name: common.WithTrivy, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_TRIVY", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
|
{Name: common.WithTrivy, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_TRIVY", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
|
||||||
|
@ -189,6 +189,22 @@ func (t *MapType) get(str string) (interface{}, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringToStringMapType ...
|
||||||
|
type StringToStringMapType struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StringToStringMapType) validate(str string) error {
|
||||||
|
result := map[string]string{}
|
||||||
|
err := json.Unmarshal([]byte(str), &result)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *StringToStringMapType) get(str string) (interface{}, error) {
|
||||||
|
result := map[string]string{}
|
||||||
|
err := json.Unmarshal([]byte(str), &result)
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// QuotaType ...
|
// QuotaType ...
|
||||||
type QuotaType struct {
|
type QuotaType struct {
|
||||||
Int64Type
|
Int64Type
|
||||||
|
@ -98,6 +98,18 @@ func TestMapType_get(t *testing.T) {
|
|||||||
assert.Equal(t, map[string]interface{}{"sample": "abc", "another": "welcome"}, result)
|
assert.Equal(t, map[string]interface{}{"sample": "abc", "another": "welcome"}, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStringToStringMapType_validate(t *testing.T) {
|
||||||
|
test := &StringToStringMapType{}
|
||||||
|
assert.Nil(t, test.validate(`{"sample":"abc", "another":"welcome"}`))
|
||||||
|
assert.NotNil(t, test.validate(`{"sample":"abc", "another":123}`))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringToStringMapType_get(t *testing.T) {
|
||||||
|
test := &StringToStringMapType{}
|
||||||
|
result, _ := test.get(`{"sample":"abc", "another":"welcome"}`)
|
||||||
|
assert.Equal(t, map[string]string{"sample": "abc", "another": "welcome"}, result)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_parseInt64(t *testing.T) {
|
func Test_parseInt64(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
str string
|
str string
|
||||||
|
@ -108,6 +108,7 @@ const (
|
|||||||
OIDCAdminGroup = "oidc_admin_group"
|
OIDCAdminGroup = "oidc_admin_group"
|
||||||
OIDCGroupsClaim = "oidc_groups_claim"
|
OIDCGroupsClaim = "oidc_groups_claim"
|
||||||
OIDCAutoOnboard = "oidc_auto_onboard"
|
OIDCAutoOnboard = "oidc_auto_onboard"
|
||||||
|
OIDCExtraRedirectParms = "oidc_extra_redirect_parms"
|
||||||
OIDCScope = "oidc_scope"
|
OIDCScope = "oidc_scope"
|
||||||
OIDCUserClaim = "oidc_user_claim"
|
OIDCUserClaim = "oidc_user_claim"
|
||||||
|
|
||||||
|
@ -90,6 +90,7 @@ type OIDCSetting struct {
|
|||||||
RedirectURL string `json:"redirect_url"`
|
RedirectURL string `json:"redirect_url"`
|
||||||
Scope []string `json:"scope"`
|
Scope []string `json:"scope"`
|
||||||
UserClaim string `json:"user_claim"`
|
UserClaim string `json:"user_claim"`
|
||||||
|
ExtraRedirectParms map[string]string `json:"extra_redirect_parms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuotaSetting wraps the settings for Quota
|
// QuotaSetting wraps the settings for Quota
|
||||||
|
@ -161,10 +161,16 @@ func AuthCodeURL(state string) (string, error) {
|
|||||||
log.Errorf("Failed to get OAuth configuration, error: %v", err)
|
log.Errorf("Failed to get OAuth configuration, error: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) { // make sure the refresh token will be returned
|
var options []oauth2.AuthCodeOption
|
||||||
return conf.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent")), nil
|
setting := provider.setting.Load().(models.OIDCSetting)
|
||||||
|
for k, v := range setting.ExtraRedirectParms {
|
||||||
|
options = append(options, oauth2.SetAuthURLParam(k, v))
|
||||||
}
|
}
|
||||||
return conf.AuthCodeURL(state), nil
|
if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) { // make sure the refresh token will be returned
|
||||||
|
options = append(options, oauth2.AccessTypeOffline)
|
||||||
|
options = append(options, oauth2.SetAuthURLParam("prompt", "consent"))
|
||||||
|
}
|
||||||
|
return conf.AuthCodeURL(state, options...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExchangeToken get the token from token provider via the code
|
// ExchangeToken get the token from token provider via the code
|
||||||
|
@ -90,12 +90,24 @@ func TestHelperGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAuthCodeURL(t *testing.T) {
|
func TestAuthCodeURL(t *testing.T) {
|
||||||
|
conf := map[string]interface{}{
|
||||||
|
common.OIDCName: "test",
|
||||||
|
common.OIDCEndpoint: "https://accounts.google.com",
|
||||||
|
common.OIDCVerifyCert: "true",
|
||||||
|
common.OIDCScope: "openid, profile, offline_access",
|
||||||
|
common.OIDCCLientID: "client",
|
||||||
|
common.OIDCClientSecret: "secret",
|
||||||
|
common.ExtEndpoint: "https://harbor.test",
|
||||||
|
common.OIDCExtraRedirectParms: `{"test_key":"test_value"}`,
|
||||||
|
}
|
||||||
|
config.GetCfgManager().UpdateConfig(conf)
|
||||||
res, err := AuthCodeURL("random")
|
res, err := AuthCodeURL("random")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
u, err := url.ParseRequestURI(res)
|
u, err := url.ParseRequestURI(res)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
q, err := url.ParseQuery(u.RawQuery)
|
q, err := url.ParseQuery(u.RawQuery)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "test_value", q.Get("test_key"))
|
||||||
assert.Equal(t, "offline", q.Get("access_type"))
|
assert.Equal(t, "offline", q.Get("access_type"))
|
||||||
assert.False(t, strings.Contains(q.Get("scope"), "offline_access"))
|
assert.False(t, strings.Contains(q.Get("scope"), "offline_access"))
|
||||||
}
|
}
|
||||||
|
@ -419,6 +419,7 @@ func OIDCSetting() (*models.OIDCSetting, error) {
|
|||||||
RedirectURL: extEndpoint + common.OIDCCallbackPath,
|
RedirectURL: extEndpoint + common.OIDCCallbackPath,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
UserClaim: cfgMgr.Get(common.OIDCUserClaim).GetString(),
|
UserClaim: cfgMgr.Get(common.OIDCUserClaim).GetString(),
|
||||||
|
ExtraRedirectParms: cfgMgr.Get(common.OIDCExtraRedirectParms).GetStringToStringMap(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user