yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/saml_provider.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package qcloud 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 "time" 21 "unicode" 22 23 "yunion.io/x/pkg/errors" 24 25 api "yunion.io/x/cloudmux/pkg/apis/cloudid" 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 "yunion.io/x/cloudmux/pkg/multicloud" 28 "yunion.io/x/onecloud/pkg/util/samlutils" 29 ) 30 31 type SAMLProvider struct { 32 multicloud.SResourceBase 33 QcloudTags 34 client *SQcloudClient 35 36 Name string 37 Description string 38 CreateTime time.Time 39 ModifyTime time.Time 40 SAMLMetadata string 41 } 42 43 func (self *SAMLProvider) GetId() string { 44 return self.Name 45 } 46 47 func (self *SAMLProvider) GetGlobalId() string { 48 return self.Name 49 } 50 51 func (self *SAMLProvider) GetName() string { 52 return self.Name 53 } 54 55 func (self *SAMLProvider) GetStatus() string { 56 return api.SAML_PROVIDER_STATUS_AVAILABLE 57 } 58 59 func (self *SAMLProvider) Delete() error { 60 return self.client.DeleteSAMLProvider(self.Name) 61 } 62 63 func (self *SAMLProvider) GetAuthUrl() string { 64 return fmt.Sprintf("https://cloud.tencent.com/login/forwardIdp/%s/%s", self.client.ownerName, self.Name) 65 } 66 67 func (self *SAMLProvider) GetMetadataDocument() (*samlutils.EntityDescriptor, error) { 68 provider, err := self.client.GetSAMLProvider(self.Name) 69 if err != nil { 70 return nil, errors.Wrapf(err, "GetSAMLProvider(%s)", self.Name) 71 } 72 metadata, err := base64.StdEncoding.DecodeString(provider.SAMLMetadata) 73 if err != nil { 74 return nil, errors.Wrapf(err, "decode metadata") 75 } 76 ret, err := samlutils.ParseMetadata(metadata) 77 if err != nil { 78 return nil, errors.Wrapf(err, "ParseMetadata") 79 } 80 return &ret, nil 81 } 82 83 func (self *SAMLProvider) UpdateMetadata(metadata samlutils.EntityDescriptor) error { 84 return self.client.UpdateSAMLProvider(self.Name, metadata.String(), "") 85 } 86 87 func (self *SQcloudClient) ListSAMLProviders() ([]SAMLProvider, error) { 88 resp, err := self.camRequest("ListSAMLProviders", nil) 89 if err != nil { 90 return nil, errors.Wrapf(err, "ListSAMLProviders") 91 } 92 result := []SAMLProvider{} 93 err = resp.Unmarshal(&result, "SAMLProviderSet") 94 if err != nil { 95 return nil, errors.Wrapf(err, "Unmarshal") 96 } 97 return result, nil 98 } 99 100 func (self *SQcloudClient) CreateSAMLProvider(name, metadata, desc string) (*SAMLProvider, error) { 101 if len(desc) == 0 { 102 desc = "For CloudId Service" 103 } 104 //支持3-128个数字、大小写字母、和+=,.@_- 105 name = func() string { 106 ret := "" 107 for _, c := range name { 108 if unicode.IsLetter(c) || unicode.IsNumber(c) || 109 c == '+' || c == '=' || c == ',' || c == '.' || c == '@' || c == '_' || c == '-' { 110 ret += string(c) 111 } else { 112 ret += "-" 113 } 114 } 115 return ret 116 }() 117 if len(name) > 128 { 118 name = name[:128] 119 } 120 params := map[string]string{ 121 "Name": name, 122 "Description": desc, 123 "SAMLMetadataDocument": base64.StdEncoding.EncodeToString([]byte(metadata)), 124 } 125 _, err := self.camRequest("CreateSAMLProvider", params) 126 if err != nil { 127 return nil, errors.Wrapf(err, "CreateSAMLProvider") 128 } 129 return self.GetSAMLProvider(name) 130 } 131 132 func (self *SQcloudClient) GetSAMLProvider(name string) (*SAMLProvider, error) { 133 params := map[string]string{ 134 "Name": name, 135 } 136 resp, err := self.camRequest("GetSAMLProvider", params) 137 if err != nil { 138 return nil, errors.Wrapf(err, "GetSAMLProvider") 139 } 140 result := &SAMLProvider{client: self} 141 err = resp.Unmarshal(result) 142 if err != nil { 143 return nil, errors.Wrapf(err, "resp.Unmarshal") 144 } 145 return result, nil 146 } 147 148 func (self *SQcloudClient) DeleteSAMLProvider(name string) error { 149 params := map[string]string{ 150 "Name": name, 151 } 152 _, err := self.camRequest("DeleteSAMLProvider", params) 153 return err 154 } 155 156 func (self *SQcloudClient) UpdateSAMLProvider(name, metadata, desc string) error { 157 params := map[string]string{ 158 "Name": name, 159 } 160 if len(desc) > 0 { 161 params["Description"] = desc 162 } 163 if len(metadata) > 0 { 164 params["SAMLMetadataDocument"] = base64.StdEncoding.EncodeToString([]byte(metadata)) 165 } 166 _, err := self.camRequest("UpdateSAMLProvider", params) 167 if err != nil { 168 return errors.Wrap(err, "UpdateSAMLProvider") 169 } 170 return nil 171 } 172 173 func (self *SQcloudClient) GetICloudSAMLProviders() ([]cloudprovider.ICloudSAMLProvider, error) { 174 providers, err := self.ListSAMLProviders() 175 if err != nil { 176 return nil, errors.Wrapf(err, "ListSAMLProviders") 177 } 178 ret := []cloudprovider.ICloudSAMLProvider{} 179 for i := range providers { 180 providers[i].client = self 181 ret = append(ret, &providers[i]) 182 } 183 return ret, nil 184 }