@@ -16,6 +16,7 @@ package aliyun
1616
1717import (
1818 "fmt"
19+ "strings"
1920 "time"
2021
2122 "yunion.io/x/log"
@@ -41,28 +42,34 @@ type SUser struct {
4142 client * SAliyunClient
4243 multicloud.SBaseClouduser
4344
44- Comments string
45- CreateDate time.Time
46- DisplayName string
47- Email string
48- MobilePhone string
49- UserId string
50- UserName string
45+ Comments string
46+ CreateDate time.Time
47+ DisplayName string
48+ Email string
49+ MobilePhone string
50+ ProvisionType string
51+ Status string
52+ UserId string
53+ UserPrincipalName string
5154}
5255
5356func (user * SUser ) GetGlobalId () string {
5457 if len (user .UserId ) > 0 {
5558 return user .UserId
5659 }
57- u , err := user .client .GetUser (user .UserName )
60+ u , err := user .client .GetUser (user .UserPrincipalName )
5861 if err != nil {
5962 return ""
6063 }
6164 return u .UserId
6265}
6366
6467func (user * SUser ) GetName () string {
65- return user .UserName
68+ info := strings .Split (user .UserPrincipalName , "@" )
69+ if len (info ) == 2 {
70+ return info [0 ]
71+ }
72+ return user .UserPrincipalName
6673}
6774
6875func (user * SUser ) GetEmailAddr () string {
@@ -74,31 +81,31 @@ func (user *SUser) GetInviteUrl() string {
7481}
7582
7683func (user * SUser ) Delete () error {
77- groups , err := user .client .ListGroupsForUser (user .UserName )
84+ groups , err := user .client .ListGroupsForUser (user .GetName () )
7885 if err != nil {
7986 return errors .Wrap (err , "ListGroupsForUser" )
8087 }
8188 for i := range groups {
82- err = user .client .RemoveUserFromGroup (groups [i ].GroupName , user .UserName )
89+ err = user .client .RemoveUserFromGroup (groups [i ].GroupName , user .GetName () )
8390 if err != nil {
84- return errors .Wrapf (err , "RemoveUserFromGroup %s > %s" , groups [i ].GroupName , user .UserName )
91+ return errors .Wrapf (err , "RemoveUserFromGroup %s > %s" , groups [i ].GroupName , user .GetName () )
8592 }
8693 }
87- policies , err := user .client .ListPoliciesForUser (user .UserName )
94+ policies , err := user .client .ListPoliciesForUser (user .GetName () )
8895 if err != nil {
8996 return errors .Wrap (err , "ListPoliciesForUser" )
9097 }
9198 for i := range policies {
92- err = user .client .DetachPolicyFromUser (policies [i ].PolicyName , policies [i ].PolicyType , user .UserName )
99+ err = user .client .DetachPolicyFromUser (policies [i ].PolicyName , policies [i ].PolicyType , user .GetName () )
93100 if err != nil {
94- return errors .Wrapf (err , "DetachPolicyFromUser %s %s %s" , policies [i ].PolicyName , policies [i ].PolicyType , user .UserName )
101+ return errors .Wrapf (err , "DetachPolicyFromUser %s %s %s" , policies [i ].PolicyName , policies [i ].PolicyType , user .GetName () )
95102 }
96103 }
97- return user .client .DeleteClouduser (user .UserName )
104+ return user .client .DeleteClouduser (user .GetName () )
98105}
99106
100107func (user * SUser ) GetICloudgroups () ([]cloudprovider.ICloudgroup , error ) {
101- groups , err := user .client .ListGroupsForUser (user .UserName )
108+ groups , err := user .client .ListGroupsForUser (user .GetName () )
102109 if err != nil {
103110 return nil , errors .Wrapf (err , "ListGroupsForUser" )
104111 }
@@ -111,11 +118,11 @@ func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
111118}
112119
113120func (user * SUser ) UpdatePassword (password string ) error {
114- return user .client .UpdateLoginProfile (user .UserName , password )
121+ return user .client .UpdateLoginProfile (user .UserPrincipalName , password , nil , nil , "" )
115122}
116123
117124func (user * SUser ) GetICloudpolicies () ([]cloudprovider.ICloudpolicy , error ) {
118- policies , err := user .client .ListPoliciesForUser (user .UserName )
125+ policies , err := user .client .ListPoliciesForUser (user .GetName () )
119126 if err != nil {
120127 return nil , errors .Wrap (err , "ListPoliciesForUser" )
121128 }
@@ -128,32 +135,49 @@ func (user *SUser) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
128135}
129136
130137func (user * SUser ) IsConsoleLogin () bool {
131- _ , err := user .client .GetLoginProfile (user .UserName )
132- if errors .Cause (err ) == cloudprovider .ErrNotFound {
138+ profile , err := user .client .GetLoginProfile (user .UserPrincipalName )
139+ if err != nil {
140+ if errors .Cause (err ) == cloudprovider .ErrNotFound {
141+ return false
142+ }
133143 return false
134144 }
135- return true
145+ return profile . Status == "Active"
136146}
137147
138148func (user * SUser ) SetDisable () error {
139- return user .client .DeleteLoginProfile (user .UserName )
149+ profile , err := user .client .GetLoginProfile (user .UserPrincipalName )
150+ if err != nil {
151+ if errors .Cause (err ) == cloudprovider .ErrNotFound {
152+ return nil
153+ }
154+ return errors .Wrapf (err , "GetLoginProfile" )
155+ }
156+ return user .client .UpdateLoginProfile (user .UserPrincipalName , "" , & profile .PasswordResetRequired , & profile .MFABindRequired , "Inactive" )
140157}
141158
142- func (user * SUser ) SetEnable (password string ) error {
143- _ , err := user .client .CreateLoginProfile (user .UserName , password )
144- return err
159+ func (user * SUser ) SetEnable (opts * cloudprovider.SClouduserEnableOptions ) error {
160+ _ , err := user .client .GetLoginProfile (user .UserPrincipalName )
161+ if err != nil {
162+ if errors .Cause (err ) == cloudprovider .ErrNotFound {
163+ _ , err := user .client .CreateLoginProfile (user .UserPrincipalName , opts .Password , opts .PasswordResetRequired , opts .EnableMfa )
164+ return err
165+ }
166+ return errors .Wrapf (err , "GetLoginProfile" )
167+ }
168+ return user .client .UpdateLoginProfile (user .UserPrincipalName , opts .Password , & opts .PasswordResetRequired , & opts .EnableMfa , "Active" )
145169}
146170
147171func (user * SUser ) ResetPassword (password string ) error {
148- return user .client .ResetClouduserPassword (user .UserName , password )
172+ return user .client .ResetClouduserPassword (user .UserPrincipalName , password )
149173}
150174
151175func (user * SUser ) AttachPolicy (policyName string , policyType api.TPolicyType ) error {
152- return user .client .AttachPolicyToUser (policyName , utils .Capitalize (string (policyType )), user .UserName )
176+ return user .client .AttachPolicyToUser (policyName , utils .Capitalize (string (policyType )), user .GetName () )
153177}
154178
155179func (user * SUser ) DetachPolicy (policyName string , policyType api.TPolicyType ) error {
156- return user .client .DetachPolicyFromUser (policyName , utils .Capitalize (string (policyType )), user .UserName )
180+ return user .client .DetachPolicyFromUser (policyName , utils .Capitalize (string (policyType )), user .GetName () )
157181}
158182
159183func (self * SAliyunClient ) DeleteClouduser (name string ) error {
@@ -164,10 +188,22 @@ func (self *SAliyunClient) DeleteClouduser(name string) error {
164188 return err
165189}
166190
191+ func (self * SAliyunClient ) GetDefaultDomain () (string , error ) {
192+ resp , err := self .imsRequest ("GetDefaultDomain" , nil )
193+ if err != nil {
194+ return "" , errors .Wrapf (err , "GetDefaultDomain" )
195+ }
196+ return resp .GetString ("DefaultDomainName" )
197+ }
198+
167199func (self * SAliyunClient ) CreateUser (name , phone , email , comments string ) (* SUser , error ) {
200+ domain , err := self .GetDefaultDomain ()
201+ if err != nil {
202+ return nil , err
203+ }
168204 params := map [string ]string {
169- "UserName " : name ,
170- "DisplayName" : name ,
205+ "UserPrincipalName " : fmt . Sprintf ( "%s@%s" , name , domain ) ,
206+ "DisplayName" : name ,
171207 }
172208 if len (phone ) > 0 {
173209 params ["MobilePhone" ] = phone
@@ -178,7 +214,7 @@ func (self *SAliyunClient) CreateUser(name, phone, email, comments string) (*SUs
178214 if len (comments ) > 0 {
179215 params ["Comments" ] = comments
180216 }
181- resp , err := self .ramRequest ("CreateUser" , params )
217+ resp , err := self .imsRequest ("CreateUser" , params )
182218 if err != nil {
183219 return nil , errors .Wrap (err , "ramRequest.CreateUser" )
184220 }
@@ -199,9 +235,9 @@ func (self *SAliyunClient) ListUsers(offset string, limit int) (*SUsers, error)
199235 if limit > 0 {
200236 params ["MaxItems" ] = fmt .Sprintf ("%d" , limit )
201237 }
202- resp , err := self .ramRequest ("ListUsers" , params )
238+ resp , err := self .imsRequest ("ListUsers" , params )
203239 if err != nil {
204- return nil , errors .Wrap (err , "ramRequest. ListUsers" )
240+ return nil , errors .Wrap (err , "ListUsers" )
205241 }
206242 users := & SUsers {}
207243 err = resp .Unmarshal (users )
@@ -217,7 +253,7 @@ func (self *SAliyunClient) CreateIClouduser(conf *cloudprovider.SClouduserCreate
217253 return nil , errors .Wrap (err , "CreateUser" )
218254 }
219255 if len (conf .Password ) > 0 {
220- _ , err := self .CreateLoginProfile (conf . Name , conf .Password )
256+ _ , err := self .CreateLoginProfile (user . UserPrincipalName , conf .Password , false , true )
221257 if err != nil {
222258 return nil , errors .Wrap (err , "CreateLoginProfile" )
223259 }
@@ -246,12 +282,19 @@ func (self *SAliyunClient) GetICloudusers() ([]cloudprovider.IClouduser, error)
246282}
247283
248284func (self * SAliyunClient ) GetUser (name string ) (* SUser , error ) {
285+ if ! strings .Contains (name , "@" ) {
286+ domain , err := self .GetDefaultDomain ()
287+ if err != nil {
288+ return nil , err
289+ }
290+ name = fmt .Sprintf ("%s@%s" , name , domain )
291+ }
249292 params := map [string ]string {
250- "UserName " : name ,
293+ "UserPrincipalName " : name ,
251294 }
252- resp , err := self .ramRequest ("GetUser" , params )
295+ resp , err := self .imsRequest ("GetUser" , params )
253296 if err != nil {
254- return nil , errors .Wrap (err , "ramRequest.CreateUser " )
297+ return nil , errors .Wrap (err , "GetUser " )
255298 }
256299 user := & SUser {client : self }
257300 err = resp .Unmarshal (user , "User" )
@@ -269,16 +312,17 @@ type SLoginProfile struct {
269312 CreateDate string
270313 MFABindRequired bool
271314 PasswordResetRequired bool
272- UserName string
315+ UserPrincipalName string
316+ Status string
273317}
274318
275319func (self * SAliyunClient ) GetLoginProfile (name string ) (* SLoginProfile , error ) {
276320 params := map [string ]string {
277- "UserName " : name ,
321+ "UserPrincipalName " : name ,
278322 }
279- resp , err := self .ramRequest ("GetLoginProfile" , params )
323+ resp , err := self .imsRequest ("GetLoginProfile" , params )
280324 if err != nil {
281- return nil , errors .Wrap (err , "ramRequest. GetLoginProfile" )
325+ return nil , errors .Wrap (err , "GetLoginProfile" )
282326 }
283327 profile := & SLoginProfile {}
284328 err = resp .Unmarshal (profile , "LoginProfile" )
@@ -296,14 +340,22 @@ func (self *SAliyunClient) DeleteLoginProfile(name string) error {
296340 return err
297341}
298342
299- func (self * SAliyunClient ) CreateLoginProfile (name , password string ) (* SLoginProfile , error ) {
343+ func (self * SAliyunClient ) CreateLoginProfile (name , password string , reset bool , mfa bool ) (* SLoginProfile , error ) {
300344 params := map [string ]string {
301- "UserName" : name ,
302- "Password" : password ,
345+ "UserPrincipalName" : name ,
346+ "Password" : password ,
347+ "PasswordResetRequired" : "false" ,
348+ "MFABindRequired" : "false" ,
303349 }
304- resp , err := self .ramRequest ("CreateLoginProfile" , params )
350+ if reset {
351+ params ["PasswordResetRequired" ] = "true"
352+ }
353+ if mfa {
354+ params ["MFABindRequired" ] = "true"
355+ }
356+ resp , err := self .imsRequest ("CreateLoginProfile" , params )
305357 if err != nil {
306- return nil , errors .Wrap (err , "ramRequest. CreateLoginProfile" )
358+ return nil , errors .Wrap (err , "CreateLoginProfile" )
307359 }
308360 profile := & SLoginProfile {}
309361 err = resp .Unmarshal (profile , "LoginProfile" )
@@ -313,28 +365,46 @@ func (self *SAliyunClient) CreateLoginProfile(name, password string) (*SLoginPro
313365 return profile , nil
314366}
315367
316- func (self * SAliyunClient ) UpdateLoginProfile (name , password string ) error {
368+ func (self * SAliyunClient ) UpdateLoginProfile (name , password string , reset * bool , mfa * bool , state string ) error {
317369 params := map [string ]string {
318- "UserName" : name ,
319- "Password" : password ,
370+ "UserPrincipalName" : name ,
371+ "Password" : password ,
372+ }
373+ if len (password ) > 0 {
374+ params ["Password" ] = password
375+ }
376+ if reset != nil {
377+ params ["PasswordResetRequired" ] = "false"
378+ if * reset {
379+ params ["PasswordResetRequired" ] = "true"
380+ }
381+ }
382+ if mfa != nil {
383+ params ["MFABindRequired" ] = "false"
384+ if * mfa {
385+ params ["MFABindRequired" ] = "true"
386+ }
387+ }
388+ if len (state ) > 0 {
389+ params ["Status" ] = state
320390 }
321- _ , err := self .ramRequest ("UpdateLoginProfile" , params )
391+ _ , err := self .imsRequest ("UpdateLoginProfile" , params )
322392 if err != nil {
323- return errors .Wrap (err , "ramRequest.CreateLoginProfile " )
393+ return errors .Wrap (err , "ramRequest.UpdateLoginProfile " )
324394 }
325395 return nil
326396}
327397
328398func (self * SAliyunClient ) ResetClouduserPassword (name , password string ) error {
329- _ , err := self .GetLoginProfile (name )
399+ profile , err := self .GetLoginProfile (name )
330400 if err != nil {
331401 if errors .Cause (err ) == cloudprovider .ErrNotFound {
332- _ , err = self .CreateLoginProfile (name , password )
402+ _ , err = self .CreateLoginProfile (name , password , profile . PasswordResetRequired , profile . MFABindRequired )
333403 return err
334404 }
335405 return errors .Wrap (err , "GetLoginProfile" )
336406 }
337- return self .UpdateLoginProfile (name , password )
407+ return self .UpdateLoginProfile (name , password , & profile . PasswordResetRequired , & profile . MFABindRequired , "" )
338408}
339409
340410func (self * SAliyunClient ) GetIamLoginUrl () string {
0 commit comments