From 9ce98f4acd34a49a23685d79556672264c7afca3 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Tue, 26 Mar 2019 00:15:57 +0800 Subject: [PATCH] Add controller to handle oidc login The controller will redirect user to the OIDC login page based on configuration. Additionally this commit add some basic code to wrap `oauth2` package and `provider` in `go-oidc`, and fixed an issue in UT to make InMemoryDriver for config management thread-safe. Signed-off-by: Daniel Jiang --- src/Gopkg.lock | 36 +- src/Gopkg.toml | 4 + src/common/config/manager.go | 12 +- src/common/config/metadata/type.go | 6 +- src/common/utils/oidc/helper.go | 131 ++ src/common/utils/oidc/helper_test.go | 99 + src/core/controllers/oidc.go | 44 + src/core/router.go | 1 + .../github.com/coreos/go-oidc/.gitignore | 2 + .../github.com/coreos/go-oidc/.travis.yml | 16 + .../github.com/coreos/go-oidc/CONTRIBUTING.md | 71 + src/vendor/github.com/coreos/go-oidc/DCO | 36 + src/vendor/github.com/coreos/go-oidc/LICENSE | 202 ++ .../github.com/coreos/go-oidc/MAINTAINERS | 2 + src/vendor/github.com/coreos/go-oidc/NOTICE | 5 + .../github.com/coreos/go-oidc/README.md | 72 + .../coreos/go-oidc/code-of-conduct.md | 61 + src/vendor/github.com/coreos/go-oidc/jose.go | 20 + src/vendor/github.com/coreos/go-oidc/jwks.go | 228 +++ src/vendor/github.com/coreos/go-oidc/oidc.go | 374 ++++ src/vendor/github.com/coreos/go-oidc/test | 16 + .../github.com/coreos/go-oidc/verify.go | 243 +++ .../pquerna/cachecontrol/.travis.yml | 10 + .../github.com/pquerna/cachecontrol/LICENSE | 202 ++ .../github.com/pquerna/cachecontrol/README.md | 107 + .../github.com/pquerna/cachecontrol/api.go | 48 + .../cachecontrol/cacheobject/directive.go | 546 +++++ .../pquerna/cachecontrol/cacheobject/lex.go | 93 + .../cachecontrol/cacheobject/object.go | 387 ++++ .../cachecontrol/cacheobject/reasons.go | 95 + .../cachecontrol/cacheobject/warning.go | 107 + .../github.com/pquerna/cachecontrol/doc.go | 25 + .../golang.org/x/crypto/ed25519/ed25519.go | 181 ++ .../ed25519/internal/edwards25519/const.go | 1422 +++++++++++++ .../internal/edwards25519/edwards25519.go | 1771 +++++++++++++++++ .../square/go-jose.v2/.gitcookies.sh.enc | 1 + .../gopkg.in/square/go-jose.v2/.gitignore | 7 + .../gopkg.in/square/go-jose.v2/.travis.yml | 46 + .../gopkg.in/square/go-jose.v2/BUG-BOUNTY.md | 10 + .../square/go-jose.v2/CONTRIBUTING.md | 14 + src/vendor/gopkg.in/square/go-jose.v2/LICENSE | 202 ++ .../gopkg.in/square/go-jose.v2/README.md | 118 ++ .../gopkg.in/square/go-jose.v2/asymmetric.go | 592 ++++++ .../square/go-jose.v2/cipher/cbc_hmac.go | 196 ++ .../square/go-jose.v2/cipher/concat_kdf.go | 75 + .../square/go-jose.v2/cipher/ecdh_es.go | 62 + .../square/go-jose.v2/cipher/key_wrap.go | 109 + .../gopkg.in/square/go-jose.v2/crypter.go | 535 +++++ src/vendor/gopkg.in/square/go-jose.v2/doc.go | 27 + .../gopkg.in/square/go-jose.v2/encoding.go | 179 ++ .../gopkg.in/square/go-jose.v2/json/LICENSE | 27 + .../gopkg.in/square/go-jose.v2/json/README.md | 13 + .../gopkg.in/square/go-jose.v2/json/decode.go | 1183 +++++++++++ .../gopkg.in/square/go-jose.v2/json/encode.go | 1197 +++++++++++ .../gopkg.in/square/go-jose.v2/json/indent.go | 141 ++ .../square/go-jose.v2/json/scanner.go | 623 ++++++ .../gopkg.in/square/go-jose.v2/json/stream.go | 480 +++++ .../gopkg.in/square/go-jose.v2/json/tags.go | 44 + src/vendor/gopkg.in/square/go-jose.v2/jwe.go | 294 +++ src/vendor/gopkg.in/square/go-jose.v2/jwk.go | 608 ++++++ src/vendor/gopkg.in/square/go-jose.v2/jws.go | 321 +++ .../gopkg.in/square/go-jose.v2/opaque.go | 83 + .../gopkg.in/square/go-jose.v2/shared.go | 499 +++++ .../gopkg.in/square/go-jose.v2/signing.go | 389 ++++ .../gopkg.in/square/go-jose.v2/symmetric.go | 482 +++++ 65 files changed, 15227 insertions(+), 5 deletions(-) create mode 100644 src/common/utils/oidc/helper.go create mode 100644 src/common/utils/oidc/helper_test.go create mode 100644 src/core/controllers/oidc.go create mode 100644 src/vendor/github.com/coreos/go-oidc/.gitignore create mode 100644 src/vendor/github.com/coreos/go-oidc/.travis.yml create mode 100644 src/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md create mode 100644 src/vendor/github.com/coreos/go-oidc/DCO create mode 100644 src/vendor/github.com/coreos/go-oidc/LICENSE create mode 100644 src/vendor/github.com/coreos/go-oidc/MAINTAINERS create mode 100644 src/vendor/github.com/coreos/go-oidc/NOTICE create mode 100644 src/vendor/github.com/coreos/go-oidc/README.md create mode 100644 src/vendor/github.com/coreos/go-oidc/code-of-conduct.md create mode 100644 src/vendor/github.com/coreos/go-oidc/jose.go create mode 100644 src/vendor/github.com/coreos/go-oidc/jwks.go create mode 100644 src/vendor/github.com/coreos/go-oidc/oidc.go create mode 100755 src/vendor/github.com/coreos/go-oidc/test create mode 100644 src/vendor/github.com/coreos/go-oidc/verify.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/.travis.yml create mode 100644 src/vendor/github.com/pquerna/cachecontrol/LICENSE create mode 100644 src/vendor/github.com/pquerna/cachecontrol/README.md create mode 100644 src/vendor/github.com/pquerna/cachecontrol/api.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/cacheobject/directive.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/cacheobject/lex.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/cacheobject/object.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/cacheobject/reasons.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/cacheobject/warning.go create mode 100644 src/vendor/github.com/pquerna/cachecontrol/doc.go create mode 100644 src/vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 src/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 src/vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/.gitcookies.sh.enc create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/.gitignore create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/.travis.yml create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/BUG-BOUNTY.md create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/CONTRIBUTING.md create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/LICENSE create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/README.md create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/asymmetric.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/cipher/concat_kdf.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/cipher/ecdh_es.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/cipher/key_wrap.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/crypter.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/doc.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/encoding.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/LICENSE create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/README.md create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/decode.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/encode.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/indent.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/scanner.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/stream.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/json/tags.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/jwe.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/jwk.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/jws.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/opaque.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/shared.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/signing.go create mode 100644 src/vendor/gopkg.in/square/go-jose.v2/symmetric.go diff --git a/src/Gopkg.lock b/src/Gopkg.lock index 8a4d497cb..42da4319e 100644 --- a/src/Gopkg.lock +++ b/src/Gopkg.lock @@ -100,6 +100,14 @@ revision = "542e16cac74562eefac970a7d0d1467640d1f1cb" version = "v1.7.0" +[[projects]] + digest = "1:f6e5e1bc64c2908167e6aa9a1fe0c084d515132a1c63ad5b6c84036aa06dc0c1" + name = "github.com/coreos/go-oidc" + packages = ["."] + pruneopts = "UT" + revision = "1180514eaf4d9f38d0d19eef639a1d695e066e72" + version = "v2.0.0" + [[projects]] digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" name = "github.com/davecgh/go-spew" @@ -404,6 +412,17 @@ revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" +[[projects]] + branch = "master" + digest = "1:bd9efe4e0b0f768302a1e2f0c22458149278de533e521206e5ddc71848c269a0" + name = "github.com/pquerna/cachecontrol" + packages = [ + ".", + "cacheobject", + ] + pruneopts = "UT" + revision = "1555304b9b35fdd2b425bccf1a5613677705e7d0" + [[projects]] digest = "1:3f68283c56d93b885f33c679708079e834815138649e9f59ffbc572c2993e0f8" name = "github.com/robfig/cron" @@ -433,10 +452,12 @@ version = "v1.2.0" [[projects]] - digest = "1:9c94d918a2ac65f60d6b7895b2e9612e4554b40ee2446f2f807cadb3e57da7e2" + digest = "1:ab3259b9f5008a18ff8c1cc34623eccce354f3a9faf5b409983cd6717d64b40b" name = "golang.org/x/crypto" packages = [ "cast5", + "ed25519", + "ed25519/internal/edwards25519", "openpgp", "openpgp/armor", "openpgp/clearsign", @@ -529,6 +550,18 @@ revision = "8168ee085ee43257585e50c6441aadf54ecb2c9f" version = "v2.5.0" +[[projects]] + digest = "1:c0c30f47f9c16f227ba82f0bdfd14fa968453c30b7677a07903b3b4f34b98d49" + name = "gopkg.in/square/go-jose.v2" + packages = [ + ".", + "cipher", + "json", + ] + pruneopts = "UT" + revision = "628223f44a71f715d2881ea69afc795a1e9c01be" + version = "v2.3.0" + [[projects]] digest = "1:2a81c6e126d36ad027328cffaa4888fc3be40f09dc48028d1f93705b718130b9" name = "gopkg.in/yaml.v2" @@ -685,6 +718,7 @@ "github.com/casbin/casbin/model", "github.com/casbin/casbin/persist", "github.com/casbin/casbin/util", + "github.com/coreos/go-oidc", "github.com/dghubble/sling", "github.com/dgrijalva/jwt-go", "github.com/docker/distribution", diff --git a/src/Gopkg.toml b/src/Gopkg.toml index c1e85d0df..145dc2681 100644 --- a/src/Gopkg.toml +++ b/src/Gopkg.toml @@ -112,6 +112,10 @@ ignored = ["github.com/goharbor/harbor/tests*"] name = "github.com/robfig/cron" version = "=1.0" +[[constraint]] + name = "github.com/coreos/go-oidc" + version = "=2.0.0" + [[constraint]] name = "gopkg.in/yaml.v2" version = "=2.1.1" diff --git a/src/common/config/manager.go b/src/common/config/manager.go index fb70b1b3d..0df6eaa47 100644 --- a/src/common/config/manager.go +++ b/src/common/config/manager.go @@ -17,6 +17,7 @@ package config import ( "fmt" "os" + "sync" "github.com/goharbor/harbor/src/common" "github.com/goharbor/harbor/src/common/config/metadata" @@ -52,6 +53,7 @@ func NewRESTCfgManager(configURL, secret string) *CfgManager { // InMemoryDriver driver for unit testing type InMemoryDriver struct { + sync.Mutex cfgMap map[string]interface{} } @@ -59,11 +61,19 @@ type InMemoryDriver struct { // it should be invoked before get any user scope config // for system scope config, because it is immutable, no need to call this method func (d *InMemoryDriver) Load() (map[string]interface{}, error) { - return d.cfgMap, nil + d.Lock() + defer d.Unlock() + res := make(map[string]interface{}) + for k, v := range d.cfgMap { + res[k] = v + } + return res, nil } // Save only save user config setting to driver, for example: database, REST func (d *InMemoryDriver) Save(cfg map[string]interface{}) error { + d.Lock() + defer d.Unlock() for k, v := range cfg { d.cfgMap[k] = v } diff --git a/src/common/config/metadata/type.go b/src/common/config/metadata/type.go index b9fb36d3e..6ed790c97 100644 --- a/src/common/config/metadata/type.go +++ b/src/common/config/metadata/type.go @@ -61,11 +61,11 @@ type AuthModeType struct { } func (t *AuthModeType) validate(str string) error { - if str == common.LDAPAuth || str == common.DBAuth || str == common.UAAAuth || str == common.HTTPAuth { + if str == common.LDAPAuth || str == common.DBAuth || str == common.UAAAuth || str == common.HTTPAuth || str == common.OIDCAuth { return nil } - return fmt.Errorf("invalid %s, shoud be one of %s, %s, %s, %s", - common.AUTHMode, common.DBAuth, common.LDAPAuth, common.UAAAuth, common.HTTPAuth) + return fmt.Errorf("invalid %s, shoud be one of %s, %s, %s, %s, %s", + common.AUTHMode, common.DBAuth, common.LDAPAuth, common.UAAAuth, common.HTTPAuth, common.OIDCAuth) } // ProjectCreationRestrictionType ... diff --git a/src/common/utils/oidc/helper.go b/src/common/utils/oidc/helper.go new file mode 100644 index 000000000..f7928571d --- /dev/null +++ b/src/common/utils/oidc/helper.go @@ -0,0 +1,131 @@ +// Copyright 2018 Project Harbor 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 oidc + +import ( + "context" + "fmt" + gooidc "github.com/coreos/go-oidc" + "github.com/goharbor/harbor/src/common/models" + "github.com/goharbor/harbor/src/common/utils/log" + "github.com/goharbor/harbor/src/core/config" + "golang.org/x/oauth2" + "strings" + "sync" + "sync/atomic" + "time" +) + +const googleEndpoint = "https://accounts.google.com" + +type providerHelper struct { + sync.Mutex + ep atomic.Value + instance atomic.Value + setting atomic.Value +} + +func (p *providerHelper) get() (*gooidc.Provider, error) { + if p.instance.Load() != nil { + if p.ep.Load().(string) != p.setting.Load().(models.OIDCSetting).Endpoint { + if err := p.create(); err != nil { + return nil, err + } + } + } else { + p.Lock() + defer p.Unlock() + if p.instance.Load() == nil { + if err := p.loadConf(); err != nil { + return nil, err + } + if err := p.create(); err != nil { + return nil, err + } + go func() { + for { + if err := p.loadConf(); err != nil { + log.Warningf(err.Error()) + } + time.Sleep(3 * time.Second) + } + }() + } + } + + return p.instance.Load().(*gooidc.Provider), nil + +} + +func (p *providerHelper) loadConf() error { + var c *models.OIDCSetting + c, err := config.OIDCSetting() + if err != nil { + return fmt.Errorf("failed to load OIDC setting: %v", err) + } + p.setting.Store(*c) + return nil +} + +func (p *providerHelper) create() error { + bc := context.Background() + s := p.setting.Load().(models.OIDCSetting) + provider, err := gooidc.NewProvider(bc, s.Endpoint) + if err != nil { + return err + } + p.ep.Store(s.Endpoint) + p.instance.Store(provider) + return nil +} + +var provider = &providerHelper{} + +func getOauthConf() (*oauth2.Config, error) { + p, err := provider.get() + if err != nil { + return nil, err + } + setting := provider.setting.Load().(models.OIDCSetting) + scopes := []string{} + for _, sc := range setting.Scope { + if strings.HasPrefix(p.Endpoint().AuthURL, googleEndpoint) && sc == gooidc.ScopeOfflineAccess { + log.Warningf("Dropped unsupported scope: %s ", sc) + continue + } + scopes = append(scopes, sc) + } + return &oauth2.Config{ + ClientID: setting.ClientID, + ClientSecret: setting.ClientSecret, + Scopes: scopes, + RedirectURL: setting.RedirectURL, + Endpoint: p.Endpoint(), + }, nil +} + +// AuthCodeURL returns the URL for OIDC provider's consent page. The state should be verified when user is redirected +// back to Harbor. +func AuthCodeURL(state string) (string, error) { + conf, err := getOauthConf() + if err != nil { + log.Errorf("Failed to get OAuth configuration, error: %v", err) + return "", err + } + if strings.HasPrefix(conf.Endpoint.AuthURL, googleEndpoint) { + return conf.AuthCodeURL(state, oauth2.AccessTypeOffline), nil + } + return conf.AuthCodeURL(state), nil +} diff --git a/src/common/utils/oidc/helper_test.go b/src/common/utils/oidc/helper_test.go new file mode 100644 index 000000000..57c6b65c0 --- /dev/null +++ b/src/common/utils/oidc/helper_test.go @@ -0,0 +1,99 @@ +// Copyright 2018 Project Harbor 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 oidc + +import ( + "github.com/goharbor/harbor/src/common" + "github.com/goharbor/harbor/src/common/models" + "github.com/goharbor/harbor/src/core/config" + "github.com/stretchr/testify/assert" + "net/url" + "os" + "strings" + "testing" + "time" +) + +func TestMain(m *testing.M) { + conf := map[string]interface{}{ + common.OIDCName: "test", + common.OIDCEndpoint: "https://accounts.google.com", + common.OIDCSkipCertVerify: "false", + common.OIDCScope: "openid, profile, offline_access", + common.OIDCCLientID: "client", + common.OIDCClientSecret: "secret", + common.ExtEndpoint: "https://harbor.test", + } + + config.InitWithSettings(conf) + + result := m.Run() + if result != 0 { + os.Exit(result) + } +} + +func TestHelperLoadConf(t *testing.T) { + testP := &providerHelper{} + assert.Nil(t, testP.setting.Load()) + err := testP.loadConf() + assert.Nil(t, err) + assert.Equal(t, "test", testP.setting.Load().(models.OIDCSetting).Name) + assert.Nil(t, testP.ep.Load()) +} + +func TestHelperCreate(t *testing.T) { + testP := &providerHelper{} + err := testP.loadConf() + assert.Nil(t, err) + assert.Nil(t, testP.instance.Load()) + err = testP.create() + assert.Nil(t, err) + assert.EqualValues(t, "https://accounts.google.com", testP.ep.Load().(string)) + assert.NotNil(t, testP.instance.Load()) +} + +func TestHelperGet(t *testing.T) { + testP := &providerHelper{} + p, err := testP.get() + assert.Nil(t, err) + assert.Equal(t, "https://oauth2.googleapis.com/token", p.Endpoint().TokenURL) + + update := map[string]interface{}{ + common.OIDCName: "test", + common.OIDCEndpoint: "https://accounts.google.com", + common.OIDCSkipCertVerify: "false", + common.OIDCScope: "openid, profile, offline_access", + common.OIDCCLientID: "client", + common.OIDCClientSecret: "new-secret", + common.ExtEndpoint: "https://harbor.test", + } + config.GetCfgManager().UpdateConfig(update) + + t.Log("Sleep for 5 seconds") + time.Sleep(5 * time.Second) + assert.Equal(t, "new-secret", testP.setting.Load().(models.OIDCSetting).ClientSecret) +} + +func TestAuthCodeURL(t *testing.T) { + 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, "offline", q.Get("access_type")) + assert.False(t, strings.Contains(q.Get("scope"), "offline_access")) +} diff --git a/src/core/controllers/oidc.go b/src/core/controllers/oidc.go new file mode 100644 index 000000000..a8dfc91d3 --- /dev/null +++ b/src/core/controllers/oidc.go @@ -0,0 +1,44 @@ +// Copyright 2018 Project Harbor 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 controllers + +import ( + "fmt" + "github.com/goharbor/harbor/src/common" + "github.com/goharbor/harbor/src/common/utils" + "github.com/goharbor/harbor/src/common/utils/oidc" + "github.com/goharbor/harbor/src/core/api" + "github.com/goharbor/harbor/src/core/config" + "net/http" +) + +// OIDCController handles requests for OIDC login, callback and user onboard +type OIDCController struct { + api.BaseController +} + +// RedirectLogin redirect user's browser to OIDC provider's login page +func (oc *OIDCController) RedirectLogin() { + if mode, _ := config.AuthMode(); mode != common.OIDCAuth { + oc.RenderError(http.StatusPreconditionFailed, fmt.Sprintf("Auth Mode: %s is not OIDC based.", mode)) + return + } + url, err := oidc.AuthCodeURL(utils.GenerateRandomString()) + if err != nil { + oc.RenderFormatedError(http.StatusInternalServerError, err) + } + // Force to use the func 'Redirect' of beego.Controller + oc.Controller.Redirect(url, http.StatusFound) +} diff --git a/src/core/router.go b/src/core/router.go index b18a187c4..4ccae2e0f 100644 --- a/src/core/router.go +++ b/src/core/router.go @@ -37,6 +37,7 @@ func initRouters() { beego.Router("/c/reset", &controllers.CommonController{}, "post:ResetPassword") beego.Router("/c/userExists", &controllers.CommonController{}, "post:UserExists") beego.Router("/c/sendEmail", &controllers.CommonController{}, "get:SendResetEmail") + beego.Router("/c/oidc_login", &controllers.OIDCController{}, "get:RedirectLogin") // API: beego.Router("/api/projects/:pid([0-9]+)/members/?:pmid([0-9]+)", &api.ProjectMemberAPI{}) diff --git a/src/vendor/github.com/coreos/go-oidc/.gitignore b/src/vendor/github.com/coreos/go-oidc/.gitignore new file mode 100644 index 000000000..c96f2f47b --- /dev/null +++ b/src/vendor/github.com/coreos/go-oidc/.gitignore @@ -0,0 +1,2 @@ +/bin +/gopath diff --git a/src/vendor/github.com/coreos/go-oidc/.travis.yml b/src/vendor/github.com/coreos/go-oidc/.travis.yml new file mode 100644 index 000000000..f2f3c9c81 --- /dev/null +++ b/src/vendor/github.com/coreos/go-oidc/.travis.yml @@ -0,0 +1,16 @@ +language: go + +go: + - 1.7.5 + - 1.8 + +install: + - go get -v -t github.com/coreos/go-oidc/... + - go get golang.org/x/tools/cmd/cover + - go get github.com/golang/lint/golint + +script: + - ./test + +notifications: + email: false diff --git a/src/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md b/src/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md new file mode 100644 index 000000000..6662073a8 --- /dev/null +++ b/src/vendor/github.com/coreos/go-oidc/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# How to Contribute + +CoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via +GitHub pull requests. This document outlines some of the conventions on +development workflow, commit message formatting, contact points and other +resources to make it easier to get your contribution accepted. + +# Certificate of Origin + +By contributing to this project you agree to the Developer Certificate of +Origin (DCO). This document was created by the Linux Kernel community and is a +simple statement that you, as a contributor, have the legal right to make the +contribution. See the [DCO](DCO) file for details. + +# Email and Chat + +The project currently uses the general CoreOS email list and IRC channel: +- Email: [coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev) +- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org + +Please avoid emailing maintainers found in the MAINTAINERS file directly. They +are very busy and read the mailing lists. + +## Getting Started + +- Fork the repository on GitHub +- Read the [README](README.md) for build and test instructions +- Play with the project, submit bugs, submit patches! + +## Contribution Flow + +This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work (usually master). +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- Make sure the tests pass, and add any new tests as appropriate. +- Submit a pull request to the original repository. + +Thanks for your contributions! + +### Format of the Commit Message + +We follow a rough convention for commit messages that is designed to answer two +questions: what changed and why. The subject line should feature the what and +the body of the commit should describe the why. + +``` +scripts: add the test-cluster command + +this uses tmux to setup a test cluster that you can easily kill and +start for debugging. + +Fixes #38 +``` + +The format can be described more formally as follows: + +``` +: + + + +