| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // Copyright 2019 Yunion
- //
- // 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 oauth2
- import (
- "context"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- api "yunion.io/x/onecloud/pkg/apis/identity"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/keystone/driver"
- "yunion.io/x/onecloud/pkg/keystone/models"
- "yunion.io/x/onecloud/pkg/mcclient"
- )
- // OAuth2.0
- type SOAuth2Driver struct {
- driver.SBaseIdentityDriver
- oauth2Config *api.SOAuth2IdpConfigOptions
- isDebug bool
- }
- func NewOAuth2Driver(idpId, idpName, template, targetDomainId string, conf api.TConfigs) (driver.IIdentityBackend, error) {
- base, err := driver.NewBaseIdentityDriver(idpId, idpName, template, targetDomainId, conf)
- if err != nil {
- return nil, errors.Wrap(err, "NewBaseIdentityDriver")
- }
- drv := SOAuth2Driver{SBaseIdentityDriver: base}
- drv.SetVirtualObject(&drv)
- err = drv.prepareConfig()
- if err != nil {
- return nil, errors.Wrap(err, "prepareConfig")
- }
- return &drv, nil
- }
- func (self *SOAuth2Driver) prepareConfig() error {
- if self.oauth2Config == nil {
- confJson := jsonutils.Marshal(self.Config[api.IdentityDriverOAuth2])
- conf := api.SOAuth2IdpConfigOptions{}
- err := confJson.Unmarshal(&conf)
- if err != nil {
- return errors.Wrap(err, "json.Unmarshal")
- }
- log.Debugf("%s %s %#v", self.Config, confJson, self.oauth2Config)
- self.oauth2Config = &conf
- }
- return nil
- }
- func (self *SOAuth2Driver) GetSsoRedirectUri(ctx context.Context, callbackUrl, state string) (string, error) {
- factory := findDriverFactory(self.Template)
- if factory == nil {
- return "", errors.Wrapf(httperrors.ErrNotSupported, "template %s not supported", self.Template)
- }
- driver := factory.NewDriver(self.oauth2Config.AppId, self.oauth2Config.Secret)
- ctx = context.WithValue(ctx, "config", self.SBaseIdentityDriver.Config)
- return driver.GetSsoRedirectUri(ctx, callbackUrl, state)
- }
- func (self *SOAuth2Driver) Authenticate(ctx context.Context, ident mcclient.SAuthenticationIdentity) (*api.SUserExtended, error) {
- factory := findDriverFactory(self.Template)
- if factory == nil {
- return nil, errors.Wrapf(httperrors.ErrNotSupported, "template %s not supported", self.Template)
- }
- options := self.oauth2Config.SIdpAttributeOptions
- options.Update(factory.IdpAttributeOptions())
- driver := factory.NewDriver(self.oauth2Config.AppId, self.oauth2Config.Secret)
- ctx = context.WithValue(ctx, "config", self.SBaseIdentityDriver.Config)
- attrs, err := driver.Authenticate(ctx, ident.OAuth2.Code)
- if err != nil {
- return nil, errors.Wrapf(err, "driver %s Authenticate", self.Template)
- }
- var domainId, domainName, usrId, usrName string
- if v, ok := attrs[options.DomainIdAttribute]; ok && len(v) > 0 {
- domainId = v[0]
- }
- if v, ok := attrs[options.DomainNameAttribute]; ok && len(v) > 0 {
- domainName = v[0]
- }
- if v, ok := attrs[options.UserIdAttribute]; ok && len(v) > 0 {
- usrId = v[0]
- }
- if v, ok := attrs[options.UserNameAttribute]; ok && len(v) > 0 {
- usrName = v[0]
- }
- idp, err := models.IdentityProviderManager.FetchIdentityProviderById(self.IdpId)
- if err != nil {
- return nil, errors.Wrap(err, "self.GetIdentityProvider")
- }
- domain, usr, err := idp.SyncOrCreateDomainAndUser(ctx, domainId, domainName, usrId, usrName)
- if err != nil {
- return nil, errors.Wrap(err, "idp.SyncOrCreateDomainAndUser")
- }
- extUser, err := models.UserManager.FetchUserExtended(usr.Id, "", "", "")
- if err != nil {
- return nil, errors.Wrap(err, "models.UserManager.FetchUserExtended")
- }
- idp.TryUserJoinProject(options, ctx, usr, domain.Id, attrs)
- extUser.AuditIds = []string{ident.OAuth2.Code}
- return extUser, nil
- }
- func (self *SOAuth2Driver) Sync(ctx context.Context) error {
- factory := findDriverFactory(self.Template)
- if factory == nil {
- return nil
- }
- if driver, isOk := factory.NewDriver(self.oauth2Config.AppId, self.oauth2Config.Secret).(IOAuth2Synchronizer); isOk {
- ctx = context.WithValue(ctx, "config", self.SBaseIdentityDriver.Config)
- return driver.Sync(ctx, self.IdpId)
- }
- return nil
- }
- func (self *SOAuth2Driver) Probe(ctx context.Context) error {
- return nil
- }
|