mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-21 09:58:10 +08:00
253 lines
9.0 KiB
Go
253 lines
9.0 KiB
Go
// 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 models
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/errors"
|
|
"yunion.io/x/sqlchemy"
|
|
|
|
api "yunion.io/x/onecloud/pkg/apis/cloudid"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
|
"yunion.io/x/onecloud/pkg/cloudid/options"
|
|
"yunion.io/x/onecloud/pkg/cloudprovider"
|
|
"yunion.io/x/onecloud/pkg/httperrors"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
"yunion.io/x/onecloud/pkg/util/samlutils"
|
|
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
|
)
|
|
|
|
type SSAMLProviderManager struct {
|
|
db.SStatusInfrasResourceBaseManager
|
|
db.SExternalizedResourceBaseManager
|
|
SCloudaccountResourceBaseManager
|
|
}
|
|
|
|
var SAMLProviderManager *SSAMLProviderManager
|
|
|
|
func init() {
|
|
SAMLProviderManager = &SSAMLProviderManager{
|
|
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
|
|
SSAMLProvider{},
|
|
"saml_provider_tbl",
|
|
"saml_provider",
|
|
"saml_providers",
|
|
),
|
|
}
|
|
SAMLProviderManager.SetVirtualObject(SAMLProviderManager)
|
|
}
|
|
|
|
type SSAMLProvider struct {
|
|
db.SStatusInfrasResourceBase
|
|
db.SExternalizedResourceBase
|
|
SCloudaccountResourceBase
|
|
|
|
EntityId string `get:"domain" create:"domain_optional" list:"domain"`
|
|
MetadataDocument string `get:"domain" create:"domain_optional"`
|
|
AuthUrl string `width:"512" charset:"ascii" get:"domain" list:"domain"`
|
|
}
|
|
|
|
func (manager *SSAMLProviderManager) GetIVirtualModelManager() db.IVirtualModelManager {
|
|
return manager.GetVirtualObject().(db.IVirtualModelManager)
|
|
}
|
|
|
|
func (manager *SSAMLProviderManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (manager *SSAMLProviderManager) FetchUniqValues(ctx context.Context, data jsonutils.JSONObject) jsonutils.JSONObject {
|
|
accountId, _ := data.GetString("cloudaccount_id")
|
|
return jsonutils.Marshal(map[string]string{"cloudaccount_id": accountId})
|
|
}
|
|
|
|
func (manager *SSAMLProviderManager) FilterByUniqValues(q *sqlchemy.SQuery, values jsonutils.JSONObject) *sqlchemy.SQuery {
|
|
accountId, _ := values.GetString("cloudaccount_id")
|
|
if len(accountId) > 0 {
|
|
q = q.Equals("cloudaccount_id", accountId)
|
|
}
|
|
return q
|
|
}
|
|
|
|
// 创建云账号的身份提供商
|
|
func (manager *SSAMLProviderManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.SAMLProviderCreateInput) (api.SAMLProviderCreateInput, error) {
|
|
if len(input.CloudaccountId) == 0 {
|
|
return input, httperrors.NewMissingParameterError("cloudaccount_id")
|
|
}
|
|
_, err := validators.ValidateModel(userCred, CloudaccountManager, &input.CloudaccountId)
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
input.EntityId = options.Options.ApiServer
|
|
if len(input.EntityId) == 0 {
|
|
return input, httperrors.NewResourceNotReadyError("not set api_server")
|
|
}
|
|
input.Name = strings.TrimPrefix(input.EntityId, "https://")
|
|
input.Name = strings.TrimPrefix(input.Name, "http://")
|
|
|
|
input.MetadataDocument = SamlIdpInstance().GetMetadata(input.CloudaccountId).String()
|
|
input.StatusInfrasResourceBaseCreateInput, err = manager.SStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StatusInfrasResourceBaseCreateInput)
|
|
if err != nil {
|
|
return input, err
|
|
}
|
|
return input, nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
|
self.StartSAMLProviderCreateTask(ctx, userCred, "")
|
|
}
|
|
|
|
// 公有云身份提供商列表
|
|
func (manager *SSAMLProviderManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.SAMLProviderListInput) (*sqlchemy.SQuery, error) {
|
|
var err error
|
|
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q, err = manager.SCloudaccountResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudaccountResourceListInput)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return q, nil
|
|
}
|
|
|
|
// 删除
|
|
func (self *SSAMLProvider) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
|
params := jsonutils.NewDict()
|
|
return self.StartSAMLProviderDeleteTask(ctx, userCred, params, "")
|
|
}
|
|
|
|
func (self *SSAMLProvider) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
|
return nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
|
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
|
|
}
|
|
|
|
func (self *SSAMLProvider) StartSAMLProviderDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "SAMLProviderDeleteTask", self, userCred, data, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(userCred, api.SAML_PROVIDER_STATUS_DELETING, "")
|
|
task.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) IsNeedUpldateMetadata() bool {
|
|
if len(self.ExternalId) == 0 || len(self.EntityId) == 0 || len(self.MetadataDocument) == 0 {
|
|
return false
|
|
}
|
|
metadata := SamlIdpInstance().GetMetadata(self.Id)
|
|
if self.EntityId != metadata.EntityId {
|
|
return false
|
|
}
|
|
|
|
keyword := fmt.Sprintf("login/%s", self.CloudaccountId)
|
|
if strings.Contains(self.MetadataDocument, keyword) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (self *SSAMLProvider) StartSAMLProviderUpdateMetadataTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "SAMLProviderUpdateMetadataTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(userCred, api.SAML_PROVIDER_STATUS_UPDATE_METADATA, "")
|
|
task.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) StartSAMLProviderCreateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "SAMLProviderCreateTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(userCred, api.SAML_PROVIDER_STATUS_CREATING, "")
|
|
task.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) StartSAMLProviderSyncTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
|
|
task, err := taskman.TaskManager.NewTask(ctx, "SAMLProviderSyncTask", self, userCred, nil, parentTaskId, "", nil)
|
|
if err != nil {
|
|
return errors.Wrap(err, "NewTask")
|
|
}
|
|
self.SetStatus(userCred, api.SAML_PROVIDER_STATUS_SYNC, "")
|
|
task.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SSAMLProvider) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
|
|
return self.RealDelete(ctx, userCred)
|
|
}
|
|
|
|
func (self *SSAMLProvider) SyncWithCloudSAMLProvider(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudSAMLProvider) error {
|
|
_, err := db.Update(self, func() error {
|
|
self.ExternalId = ext.GetGlobalId()
|
|
self.AuthUrl = ext.GetAuthUrl()
|
|
self.Status = ext.GetStatus()
|
|
metadata, err := ext.GetMetadataDocument()
|
|
if err != nil {
|
|
log.Errorf("failed to get metadata for %s error: %v", self.Name, err)
|
|
}
|
|
if metadata != nil {
|
|
self.EntityId = metadata.EntityId
|
|
self.MetadataDocument = metadata.String()
|
|
if self.IsNeedUpldateMetadata() {
|
|
self.Status = api.SAML_PROVIDER_STATUS_NOT_MATCH
|
|
}
|
|
}
|
|
if self.EntityId != options.Options.ApiServer {
|
|
self.Status = api.SAML_PROVIDER_STATUS_NOT_MATCH
|
|
}
|
|
return nil
|
|
})
|
|
return err
|
|
}
|
|
|
|
func (self *SSAMLProvider) GetMetadataDocument() (samlutils.EntityDescriptor, error) {
|
|
return samlutils.ParseMetadata([]byte(self.MetadataDocument))
|
|
}
|
|
|
|
func (manager *SSAMLProviderManager) FetchCustomizeColumns(
|
|
ctx context.Context,
|
|
userCred mcclient.TokenCredential,
|
|
query jsonutils.JSONObject,
|
|
objs []interface{},
|
|
fields stringutils2.SSortedStrings,
|
|
isList bool,
|
|
) []api.SAMLProviderDetails {
|
|
rows := make([]api.SAMLProviderDetails, len(objs))
|
|
infRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
|
acRows := manager.SCloudaccountResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
|
for i := range rows {
|
|
rows[i] = api.SAMLProviderDetails{
|
|
StatusInfrasResourceBaseDetails: infRows[i],
|
|
CloudaccountResourceDetails: acRows[i],
|
|
}
|
|
}
|
|
return rows
|
|
}
|