mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-28 03:27:41 +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.OIDCVerifyCert, Scope: UserScope, Group: OIDCGroup, DefaultValue: "true", 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.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
|
||||
}
|
||||
|
||||
// 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 ...
|
||||
type QuotaType struct {
|
||||
Int64Type
|
||||
|
@ -98,6 +98,18 @@ func TestMapType_get(t *testing.T) {
|
||||
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) {
|
||||
type args struct {
|
||||
str string
|
||||
|
@ -108,6 +108,7 @@ const (
|
||||
OIDCAdminGroup = "oidc_admin_group"
|
||||
OIDCGroupsClaim = "oidc_groups_claim"
|
||||
OIDCAutoOnboard = "oidc_auto_onboard"
|
||||
OIDCExtraRedirectParms = "oidc_extra_redirect_parms"
|
||||
OIDCScope = "oidc_scope"
|
||||
OIDCUserClaim = "oidc_user_claim"
|
||||
|
||||
|
@ -79,17 +79,18 @@ type HTTPAuthProxy struct {
|
||||
|
||||
// OIDCSetting wraps the settings for OIDC auth endpoint
|
||||
type OIDCSetting struct {
|
||||
Name string `json:"name"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
VerifyCert bool `json:"verify_cert"`
|
||||
AutoOnboard bool `json:"auto_onboard"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
GroupsClaim string `json:"groups_claim"`
|
||||
AdminGroup string `json:"admin_group"`
|
||||
RedirectURL string `json:"redirect_url"`
|
||||
Scope []string `json:"scope"`
|
||||
UserClaim string `json:"user_claim"`
|
||||
Name string `json:"name"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
VerifyCert bool `json:"verify_cert"`
|
||||
AutoOnboard bool `json:"auto_onboard"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
GroupsClaim string `json:"groups_claim"`
|
||||
AdminGroup string `json:"admin_group"`
|
||||
RedirectURL string `json:"redirect_url"`
|
||||
Scope []string `json:"scope"`
|
||||
UserClaim string `json:"user_claim"`
|
||||
ExtraRedirectParms map[string]string `json:"extra_redirect_parms"`
|
||||
}
|
||||
|
||||
// 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)
|
||||
return "", err
|
||||
}
|
||||
if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) { // make sure the refresh token will be returned
|
||||
return conf.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", "consent")), nil
|
||||
var options []oauth2.AuthCodeOption
|
||||
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
|
||||
|
@ -90,12 +90,24 @@ func TestHelperGet(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")
|
||||
assert.Nil(t, err)
|
||||
u, err := url.ParseRequestURI(res)
|
||||
assert.Nil(t, err)
|
||||
q, err := url.ParseQuery(u.RawQuery)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "test_value", q.Get("test_key"))
|
||||
assert.Equal(t, "offline", q.Get("access_type"))
|
||||
assert.False(t, strings.Contains(q.Get("scope"), "offline_access"))
|
||||
}
|
||||
|
@ -408,17 +408,18 @@ func OIDCSetting() (*models.OIDCSetting, error) {
|
||||
extEndpoint := strings.TrimSuffix(cfgMgr.Get(common.ExtEndpoint).GetString(), "/")
|
||||
scope := splitAndTrim(scopeStr, ",")
|
||||
return &models.OIDCSetting{
|
||||
Name: cfgMgr.Get(common.OIDCName).GetString(),
|
||||
Endpoint: cfgMgr.Get(common.OIDCEndpoint).GetString(),
|
||||
VerifyCert: cfgMgr.Get(common.OIDCVerifyCert).GetBool(),
|
||||
AutoOnboard: cfgMgr.Get(common.OIDCAutoOnboard).GetBool(),
|
||||
ClientID: cfgMgr.Get(common.OIDCCLientID).GetString(),
|
||||
ClientSecret: cfgMgr.Get(common.OIDCClientSecret).GetString(),
|
||||
GroupsClaim: cfgMgr.Get(common.OIDCGroupsClaim).GetString(),
|
||||
AdminGroup: cfgMgr.Get(common.OIDCAdminGroup).GetString(),
|
||||
RedirectURL: extEndpoint + common.OIDCCallbackPath,
|
||||
Scope: scope,
|
||||
UserClaim: cfgMgr.Get(common.OIDCUserClaim).GetString(),
|
||||
Name: cfgMgr.Get(common.OIDCName).GetString(),
|
||||
Endpoint: cfgMgr.Get(common.OIDCEndpoint).GetString(),
|
||||
VerifyCert: cfgMgr.Get(common.OIDCVerifyCert).GetBool(),
|
||||
AutoOnboard: cfgMgr.Get(common.OIDCAutoOnboard).GetBool(),
|
||||
ClientID: cfgMgr.Get(common.OIDCCLientID).GetString(),
|
||||
ClientSecret: cfgMgr.Get(common.OIDCClientSecret).GetString(),
|
||||
GroupsClaim: cfgMgr.Get(common.OIDCGroupsClaim).GetString(),
|
||||
AdminGroup: cfgMgr.Get(common.OIDCAdminGroup).GetString(),
|
||||
RedirectURL: extEndpoint + common.OIDCCallbackPath,
|
||||
Scope: scope,
|
||||
UserClaim: cfgMgr.Get(common.OIDCUserClaim).GetString(),
|
||||
ExtraRedirectParms: cfgMgr.Get(common.OIDCExtraRedirectParms).GetStringToStringMap(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user