yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/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 aliyun 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 "strings" 21 "time" 22 23 "yunion.io/x/jsonutils" 24 "yunion.io/x/pkg/errors" 25 26 "yunion.io/x/cloudmux/pkg/apis/cloudid" 27 api "yunion.io/x/cloudmux/pkg/apis/cloudid" 28 "yunion.io/x/cloudmux/pkg/cloudprovider" 29 "yunion.io/x/onecloud/pkg/compute/options" 30 "yunion.io/x/cloudmux/pkg/multicloud" 31 "yunion.io/x/onecloud/pkg/util/httputils" 32 "yunion.io/x/onecloud/pkg/util/samlutils" 33 ) 34 35 type SAMLProvider struct { 36 multicloud.SResourceBase 37 AliyunTags 38 client *SAliyunClient 39 40 Arn string 41 CreateDate time.Time 42 Description string 43 SAMLProviderName string 44 UpdateDate time.Time 45 46 // base64 47 EncodedSAMLMetadataDocument string 48 } 49 50 func (self *SAMLProvider) GetName() string { 51 return self.SAMLProviderName 52 } 53 54 func (self *SAMLProvider) GetGlobalId() string { 55 return self.Arn 56 } 57 58 func (self *SAMLProvider) GetId() string { 59 return self.Arn 60 } 61 62 func (self *SAMLProvider) GetAuthUrl() string { 63 input := samlutils.SIdpInitiatedLoginInput{ 64 EntityID: cloudprovider.SAML_ENTITY_ID_ALIYUN_ROLE, 65 IdpId: self.client.cpcfg.AccountId, 66 } 67 return httputils.JoinPath(options.Options.ApiServer, cloudid.SAML_IDP_PREFIX, fmt.Sprintf("sso?%s", jsonutils.Marshal(input).QueryString())) 68 } 69 70 func (self *SAMLProvider) Delete() error { 71 return self.client.DeleteSAMLProvider(self.SAMLProviderName) 72 } 73 74 func (self *SAMLProvider) GetStatus() string { 75 return api.SAML_PROVIDER_STATUS_AVAILABLE 76 } 77 78 func (self *SAliyunClient) ListSAMLProviders(marker string, maxItems int) ([]SAMLProvider, string, error) { 79 if maxItems < 1 || maxItems > 100 { 80 maxItems = 100 81 } 82 params := map[string]string{ 83 "MaxItems": fmt.Sprintf("%d", maxItems), 84 } 85 if len(marker) > 0 { 86 params["Marker"] = marker 87 } 88 resp, err := self.imsRequest("ListSAMLProviders", params) 89 if err != nil { 90 return nil, "", errors.Wrapf(err, "ListSAMLProviders") 91 } 92 result := []SAMLProvider{} 93 err = resp.Unmarshal(&result, "SAMLProviders", "SAMLProvider") 94 if err != nil { 95 return nil, "", errors.Wrapf(err, "resp.Unmarshal") 96 } 97 marker, _ = resp.GetString("Marker") 98 return result, marker, nil 99 } 100 101 func (self *SAliyunClient) DeleteSAMLProvider(name string) error { 102 params := map[string]string{ 103 "SAMLProviderName": name, 104 } 105 _, err := self.imsRequest("DeleteSAMLProvider", params) 106 if err != nil { 107 return errors.Wrapf(err, "DeleteSAMLProvider") 108 } 109 return nil 110 } 111 112 func (self *SAMLProvider) GetMetadataDocument() (*samlutils.EntityDescriptor, error) { 113 sp, err := self.client.GetSAMLProvider(self.SAMLProviderName) 114 if err != nil { 115 return nil, errors.Wrapf(err, "GetSAMLProvider(%s)", self.SAMLProviderName) 116 } 117 metadata, err := base64.StdEncoding.DecodeString(sp.EncodedSAMLMetadataDocument) 118 if err != nil { 119 return nil, errors.Wrapf(err, "DecodeString") 120 } 121 ret, err := samlutils.ParseMetadata(metadata) 122 if err != nil { 123 return nil, errors.Wrapf(err, "ParseMetadata") 124 } 125 return &ret, nil 126 } 127 128 func (self *SAMLProvider) UpdateMetadata(metadata samlutils.EntityDescriptor) error { 129 return self.client.UpdateSAMLProvider(self.SAMLProviderName, metadata.String()) 130 } 131 132 func (self *SAliyunClient) GetSAMLProvider(name string) (*SAMLProvider, error) { 133 params := map[string]string{ 134 "SAMLProviderName": name, 135 } 136 resp, err := self.imsRequest("GetSAMLProvider", params) 137 if err != nil { 138 return nil, errors.Wrapf(err, "GetSAMLProvider") 139 } 140 sp := &SAMLProvider{client: self} 141 err = resp.Unmarshal(sp, "SAMLProvider") 142 if err != nil { 143 return nil, errors.Wrapf(err, "resp.Unmarshal") 144 } 145 return sp, nil 146 } 147 148 func (self *SAliyunClient) UpdateSAMLProvider(name string, metadata string) error { 149 params := map[string]string{ 150 "SAMLProviderName": name, 151 "NewEncodedSAMLMetadataDocument": base64.StdEncoding.EncodeToString([]byte(metadata)), 152 } 153 _, err := self.imsRequest("UpdateSAMLProvider", params) 154 if err != nil { 155 return errors.Wrapf(err, "GetSAMLProvider") 156 } 157 return nil 158 } 159 160 func (self *SAliyunClient) CreateSAMLProvider(name, metadata, desc string) (*SAMLProvider, error) { 161 name = strings.ReplaceAll(name, ":", "_") 162 params := map[string]string{ 163 "EncodedSAMLMetadataDocument": base64.StdEncoding.EncodeToString([]byte(metadata)), 164 "SAMLProviderName": name, 165 } 166 if len(desc) > 0 { 167 params["Description"] = desc 168 } 169 resp, err := self.imsRequest("CreateSAMLProvider", params) 170 if err != nil { 171 return nil, errors.Wrapf(err, "CreateSAMLProvider") 172 } 173 sp := &SAMLProvider{client: self} 174 err = resp.Unmarshal(sp, "SAMLProvider") 175 if err != nil { 176 return nil, errors.Wrapf(err, "resp.Unmarshal") 177 } 178 return sp, nil 179 } 180 181 func (self *SAliyunClient) GetICloudSAMLProviders() ([]cloudprovider.ICloudSAMLProvider, error) { 182 marker := "" 183 sps := []SAMLProvider{} 184 for { 185 part, _marker, err := self.ListSAMLProviders(marker, 100) 186 if err != nil { 187 return nil, errors.Wrapf(err, "ListSAMLProviders") 188 } 189 sps = append(sps, part...) 190 if len(_marker) == 0 { 191 break 192 } 193 marker = _marker 194 } 195 ret := []cloudprovider.ICloudSAMLProvider{} 196 for i := range sps { 197 sps[i].client = self 198 ret = append(ret, &sps[i]) 199 } 200 return ret, nil 201 }