mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
Merge pull request #5836 from swordqiu/hotfix/qj-cas-project-name-regexp-issue
fix: cas auto create project fetch failure
This commit is contained in:
@@ -27,6 +27,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/keystone/driver"
|
||||
"yunion.io/x/onecloud/pkg/keystone/models"
|
||||
@@ -148,22 +149,27 @@ func (self *SCASDriver) Authenticate(ctx context.Context, ident mcclient.SAuthen
|
||||
return nil, errors.Wrap(err, "models.UserManager.FetchUserExtended")
|
||||
}
|
||||
|
||||
self.userTryJoinProject(ctx, usr, domain, resp)
|
||||
self.userTryJoinProject(ctx, usr, domain.Id, resp)
|
||||
|
||||
return extUser, nil
|
||||
}
|
||||
|
||||
func (self *SCASDriver) userTryJoinProject(ctx context.Context, usr *models.SUser, domain *models.SDomain, resp []byte) {
|
||||
func (self *SCASDriver) userTryJoinProject(ctx context.Context, usr *models.SUser, domainId string, resp []byte) {
|
||||
var err error
|
||||
var targetProject *models.SProject
|
||||
log.Debugf("userTryJoinProject resp %s proj %s", string(resp), self.casConfig.CasProjectAttribute)
|
||||
if !consts.GetNonDefaultDomainProjects() {
|
||||
domainId = api.DEFAULT_DOMAIN_ID
|
||||
}
|
||||
if len(self.casConfig.CasProjectAttribute) > 0 {
|
||||
projName := fetchAttribute(resp, self.casConfig.CasProjectAttribute)
|
||||
if len(projName) > 0 {
|
||||
targetProject, err = models.ProjectManager.FetchProject("", projName, domain.Id, domain.Name)
|
||||
casProjName := fetchAttribute(resp, self.casConfig.CasProjectAttribute)
|
||||
if len(casProjName) > 0 {
|
||||
projName := models.NormalizeProjectName(casProjName)
|
||||
targetProject, err = models.ProjectManager.FetchProject("", projName, domainId, "")
|
||||
if err != nil {
|
||||
log.Errorf("fetch project %s fail %s", projName, err)
|
||||
if errors.Cause(err) == sql.ErrNoRows && self.casConfig.AutoCreateCasProject.IsTrue() {
|
||||
targetProject, err = models.ProjectManager.NewProject(ctx, projName, "cas project", domain)
|
||||
targetProject, err = models.ProjectManager.NewProject(ctx, projName, "cas project", domainId)
|
||||
if err != nil {
|
||||
log.Errorf("auto create project %s fail %s", projName, err)
|
||||
}
|
||||
@@ -183,7 +189,7 @@ func (self *SCASDriver) userTryJoinProject(ctx context.Context, usr *models.SUse
|
||||
if len(self.casConfig.CasRoleAttribute) > 0 {
|
||||
roleName := fetchAttribute(resp, self.casConfig.CasRoleAttribute)
|
||||
if len(roleName) > 0 {
|
||||
targetRole, err = models.RoleManager.FetchRole("", roleName, domain.Id, domain.Name)
|
||||
targetRole, err = models.RoleManager.FetchRole("", roleName, domainId, "")
|
||||
if err != nil {
|
||||
log.Errorf("fetch role %s fail %s", roleName, err)
|
||||
}
|
||||
@@ -205,7 +211,7 @@ func (self *SCASDriver) userTryJoinProject(ctx context.Context, usr *models.SUse
|
||||
}
|
||||
|
||||
func fetchAttribute(heystack []byte, name string) string {
|
||||
pattern := regexp.MustCompile(fmt.Sprintf(`<%s>(\w+)</%s>`, name, name))
|
||||
pattern := regexp.MustCompile(fmt.Sprintf(`<%s>([^<]*)</%s>`, name, name))
|
||||
result := pattern.FindAllStringSubmatch(string(heystack), -1)
|
||||
if len(result) > 0 && len(result[0]) > 1 {
|
||||
return strings.TrimSpace(result[0][1])
|
||||
|
||||
@@ -48,15 +48,32 @@ func TestXmlUnmarshal(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFetchAttribute(t *testing.T) {
|
||||
xmlstr := `<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
||||
cases := []struct {
|
||||
Xml string
|
||||
Key string
|
||||
Want string
|
||||
}{
|
||||
{
|
||||
Xml: `<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
||||
<cas:authenticationSuccess>
|
||||
<cas:user>casuser</cas:user>
|
||||
<cas:proj>casproj</cas:proj>
|
||||
</cas:authenticationSuccess>
|
||||
</cas:serviceResponse>`
|
||||
got := fetchAttribute([]byte(xmlstr), "cas:proj")
|
||||
want := "casproj"
|
||||
if got != want {
|
||||
t.Errorf("want %s got %s", want, got)
|
||||
</cas:serviceResponse>`,
|
||||
Key: "cas:proj",
|
||||
Want: "casproj",
|
||||
},
|
||||
{
|
||||
Xml: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"><cas:authenticationSuccess><cas:user>lcftest0416</cas:user><cas:proj>周凌测试无线公司1112342</cas:proj></cas:authenticationSuccess></cas:serviceResponse>`,
|
||||
Key: "cas:proj",
|
||||
Want: "周凌测试无线公司1112342",
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := fetchAttribute([]byte(c.Xml), c.Key)
|
||||
if got != c.Want {
|
||||
t.Errorf("want %s got %s", c.Want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,7 +776,7 @@ func (self *SIdentityProvider) SyncOrCreateDomain(ctx context.Context, extId str
|
||||
_, err := ProjectManager.NewProject(ctx,
|
||||
fmt.Sprintf("%s_default_project", extName),
|
||||
fmt.Sprintf("Default project for domain %s", extName),
|
||||
domain,
|
||||
domain.Id,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("ProjectManager.NewProject fail %s", err)
|
||||
|
||||
@@ -627,16 +627,16 @@ func (project *SProject) GetUsages() []db.IUsage {
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SProjectManager) NewProject(ctx context.Context, name string, desc string, domain *SDomain) (*SProject, error) {
|
||||
lockman.LockClass(ctx, manager, domain.Id)
|
||||
defer lockman.ReleaseClass(ctx, manager, domain.Id)
|
||||
func (manager *SProjectManager) NewProject(ctx context.Context, name string, desc string, domainId string) (*SProject, error) {
|
||||
lockman.LockClass(ctx, manager, domainId)
|
||||
defer lockman.ReleaseClass(ctx, manager, domainId)
|
||||
|
||||
project := &SProject{}
|
||||
project.SetModelManager(ProjectManager, project)
|
||||
projectName := NormalizeProjectName(name)
|
||||
ownerId := &db.SOwnerId{}
|
||||
if manager.NamespaceScope() == rbacutils.ScopeDomain {
|
||||
ownerId.DomainId = domain.Id
|
||||
ownerId.DomainId = domainId
|
||||
}
|
||||
newName, err := db.GenerateName(ProjectManager, ownerId, projectName)
|
||||
if err != nil {
|
||||
@@ -645,10 +645,10 @@ func (manager *SProjectManager) NewProject(ctx context.Context, name string, des
|
||||
newName = projectName
|
||||
}
|
||||
project.Name = newName
|
||||
project.DomainId = domain.Id
|
||||
project.DomainId = domainId
|
||||
project.Description = desc
|
||||
project.IsDomain = tristate.False
|
||||
project.ParentId = domain.Id
|
||||
project.ParentId = domainId
|
||||
err = ProjectManager.TableSpec().Insert(project)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Insert")
|
||||
|
||||
Reference in New Issue
Block a user