From 742e1d474677fba57ea2df3690f9288bfb4c1115 Mon Sep 17 00:00:00 2001 From: Alan Quillin Date: Fri, 8 Feb 2013 15:41:21 -0600 Subject: [PATCH] [Delivers #43559413 #43555603 #43555605 #43555607] Added User Agent header and new IdentityProvider tests --- lib/SimpleRestServices.dll | Bin 32256 -> 32768 bytes lib/SimpleRestServices.pdb | Bin 69120 -> 69120 bytes src/corelib/Core/Domain/NewUser.cs | 23 +++ src/corelib/Core/Domain/User.cs | 10 +- src/corelib/Core/IIdentityProvider.cs | 2 +- .../Rackspace/GeographicalIdentityProvider.cs | 18 +- .../Providers/Rackspace/IdentityProvider.cs | 6 +- .../Objects/Request/AddUserRequest.cs | 2 +- .../Objects/Request/UpdateUserRequest.cs | 3 + .../Objects/Response/NewUserResponse.cs | 12 ++ .../Objects/Response/UserResponse.cs | 3 + .../Providers/Rackspace/ProviderBase.cs | 18 +- src/corelib/corelib.csproj | 2 + .../Providers/Rackspace/ComputeTests.cs | 16 +- .../Rackspace/IdentityFull.orderedtest | 26 ++- .../Providers/Rackspace/IdentityTests.cs | 164 +++++++++++++++++- 16 files changed, 280 insertions(+), 25 deletions(-) create mode 100644 src/corelib/Core/Domain/NewUser.cs create mode 100644 src/corelib/Providers/Rackspace/Objects/Response/NewUserResponse.cs diff --git a/lib/SimpleRestServices.dll b/lib/SimpleRestServices.dll index b3543a6d20113017b85eb28ff5ba41b291eb0f3d..72fbc3e4cadfc533b47814b65886af205f8e46a4 100644 GIT binary patch delta 12499 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 delta 12298 zcmb_i34B!5x&O|&%iLKqnL9I?$pU19FiA*&07ev*C5nhB2nYx$AXGqLaH0r=a1&Vs zWs4UqDrkgSwbCjNtQJMFD(HK-wpOgNSjDX>+NahP-~XI@GZ|2Sw*9?<`JeCqec$=c za?f^8rm2ZHeaqIZDB1K$WCXdNBgBjS%pjTvh3+U9Z)o|=#lg-Sh{gy-E74e`r8pAU zLlgktxSptkUCg`L<5*YU(rch9!grp11FK~7?ccMmY>|D4mE=uA1o1f+Urri@&LLWH z0THvWnqRwPIG@k#_mmp@FG|=Bs72}xJQ22stNqyuyG6~hrAJ zUa8Gw3Hvjx3ou_Vh2~5>W;JtJHIsNlH~1$?iG0^oqa>fs8>*mLJIzn!*EZ)!^ngnX^t7LJR@mxwk z=W{Gc)XEpojWsi7Cea48B{{POX%=~n7_`Y=LP>|h-nOcHyy@Z+y6V5aYU;7%DZ*Q;%;pVfjcV$N3VVPN8{Ag;LlYw&GCj%KpN|#)iC9)T7Lijq z!zt|K=jJ@wS0Yo3_$tZtRbc3{{$luENqt%=8x-<46!NpMBll*#r!zcvp>JWmpLS%T zGImK5n}}X!ksca72YVL6)^A32e7e#ohN-SLqV=k-HHz-ngKA@UvV@>Dijk)WJ&mGS zI&T!cFUBltrs{Ht2lXUFC?}3=J)Sn27%-}`^!m6kiM*ACq)Y2H8Y&n)uE6e3p^bCv z`=Ox=(Gg;v>Bsfkk){3&>OwvzLlVPOcSX3giKu~|Jk!qe6Ebk50$`0-wut8ig-;WfrI25zW-90IVS)ci0XAk*10i^tP8wq5^0qWn65_qg7QQ1xd+PI!na6KF|*;^R$d;~?{p{h#r%e|UoriNUmPq8T=85)t+KG}wWiX9u%maPE>lBYT{P5j2CzOCTi1 z+nclV*a-Wf?2eN~^W^hHo5X5>(kLRHq*(Fv#dzvYXPzNCa{`>3gbJN0k^~-gCHAq! z;WoE3(|s;fa0}agLJ3QBc6?k?G$j>6uj=u50t=t+_rz|MBea{MV+4Z9K9im91LKKH zkwpv;)l{o4BB)a5h^KNH)H$xYxIKtk84^Lbl9&Vs=h^Yfyy{F3pY(8Tr~{92IT+mf z6(lFyKJ%25tEZk^y%5LdFPx{FJ!4`FY%$fitUUyuW4hlgED%i}=T|*WA!CzMz(ZVB zMArAsjO3dzXy3C2a=3mO$=c0+S=uSM*2|ZI0>A^|ts2xN<^9Gz}u&-PJ3q|ED5)Yv> z>>XjRzY|%-hAO;>V76*I-KS_h`Y(Ak zT(BVvPiJ$)?x<4?!=y;GHE|6L;@~NU5u!vqrl+dJpn>ze7A z)8=WanXaY^-?fE#){pyY8NMg9Bi>%mBJ84WGb#gIGIvxTno~x{^W|yy$HVLC@V!s! zr_AU4Svo#XU4$88>dEWSPE3*UMVF6X0@0_Zeg^|jE(PJqWx|Sq#w52N^`e80`e*TH_j zxX{8h#ky9USt~&*@UEAx2d0yZS1(gdOac+N8db#ULX4)08mvhPoT4OYs~KhuVwYsb z7Np_=w8_cHYn8-8C)#;Dv8JuzuBxIK#0f)F=XKdCjSQ-9H~x>>>Qg;!`|YHS^ij{(3@Mo7S)IZ%s?!b>J9(II&iRf zs;-^IW2tj9Sll^kIi9(()Wz+#+<0ngJIjlurf0AdVp{pJ)Vy|MemoVx(ZDUfAeL%s zw-v-w>)Kg|SnB2sc0y%3#!|m(w{<+Bz)rE$1MRj>o#QESmT?Qra<*;fi1-0UhI>TZ z)p>&6f*whZusd`qI$Iopyrw6Xkh+_|#QrYc;yV)bajB0v=R~~z;Z!+pEM9YS@h&UQ zkfz5QOWJmGmmbCAkQYZuuY0Bw4ATqmh1IEDsAW^B{c@Kww%q=zOM!PitUg^$TyJ+Q zD`y+*!DW?frCndv9k{iuv;cFVeQpYpF*lzmE5wDyn?P=}uJN+pIa{Her#HCs0}}@G zL=)o}X;4k9voGx$x6npR7tG)GR|M>$m>C;IeZ*UYSPKNHn1X2(RD+smKk^{fEl?xx zOs*)aObj@=%BUKG-zqIs@iAAr;Y5TLN3UctDc>mNs4B_n;^n52MJ2%~6>>WBiBq*a zvjYUNvlGSk@I<%MHWd+-V*fF)ID8g^Jo4()j5$|eMIidNmgo&^tEHny(t$xlc)_63 z!J~)NA$@O<{rf~s9^SI)SNP)nLiPpfj(wVFg3Zb!T0W%yc3$}yi?n9$qp;@Dbm|3J zryF#EK9A5>d$K(`4TKz|R?h~Hk6!Qy&tYESbDMWN@RY31SA==+$s}NT*vOqCa*=ZjXd%OZ1CuoeoDupnpot%Q15DsU>Ft z@GfAG4(5p7dOv4pFrP|d3vzVo9TP<^iZ%0mS}!#Z#hOio*awwP&&3Ql9g5k{c+7O6Xe2w!3VB zWY0-fN{c1?yUQ%e0$dbWN=>pdWxO{hoLrYk+hAS=TW7MC5i1JOIG3)JYzo*UN{}tt zY-uZ}jij&;{RT5Y!}#7TSuNfHHL9UIB-7IxJlFjN?;4WY>9Z?stV){^B2K-E2$zn876V@r(XXxQ1(4<8YLy=c?lZHl) z0=q;TJtj3okLtQUN1sC%H_g+l`Nd5OC0Y`f02y88ISQQP`3Puvtk02@8~qhVb%rR$ zk(U?~pmF3wh6VXc<2qoicPq73=uckJnq$x~^7u@&ugE9l*}jpGw@LX4pia9(i!k0} z{w83)zZyeulz%DYV*l0>n9KZYL8|?~1Wxo%)L{<0E9~;>9oEv^ z!@Pom^kFf^740>S@@g;z2M@tM=QUsfmn~DOaqCs;vUN%gSU1U*%P3+c6Q8}>%j&N& z=A4gUPojzK>`n0|BtLsC7{9|nbSYRq!%L|Ah>X2hbp{*8aKDhYO=YLi@O1I3S$}Gk z>>VbGA4Jcj*^@Mc)KZaA*xsZIsm^7VD1J1}PaE^ucxp|vUTiYGk!Hi#6{KRLbHYqz zc)RKZesP6D{J0NCE9MbkX}r)r&t3OVSf;w{j?X^BI+h%Hq&}5G(x*hSn%1a zjnodZr49ibqa9;wXsOJ&*Sl8xlC7mpF1thf4(uM6-4EM3+T*gvVOvN0CA-;pK~s1O zz2&l_ngKRkY_8~wF`9LZ-9#J3Iz=t?jTYoKee1G_9^vch)b5V0hn~-WNq@%PMdUo~ zP4uA*+CpE2pVu}~t_<2jwUNX6W}4(i(W3J`chG#7ogY1{w^FEwjG6mM^mWU#MacN< z&ALTDhqtqBU|Ss%Y=6{;bFm|e&)%$8!R~Sh*fISQ{_8aR2JG%Oh7mNC-;=@S@Ov}Z zLT=rcL09l?X*R+$mH#e-ZRGc7u&sQ123yE?X0QkNgBk2`{t$IORVd!^iU#hYNiGu& ze8i$nE)^|&ln%H|v~V{?`#Kp#3m>E5E)y+$oK{J;mx+q*p-pMFkv~D((rhb#lA@=H zD8h3g-%GvI>;b-ytl??;IDeKNcA4n5{q$j)&Ed~c2i%{EFfXeM`3p2F%~tRiNyYn# z7~R)`^fLu(p>3WV<BQ3F=w*svt^RsKr-Tu%|@4I1fsiYRZ; zgtIIsOwt&l9He^JxWKpoY>|@@VMZy3XrseqWscDOuBQldgdTQnt;RIvO?tt#{nnTP zcEGjmGUh0MqhqdZzmWp_@+|y$#FF$rIRT{;jaEyISYX%WMj_nv- zCs~V_v7TeXfR9+7Z&fnc-O4{`qx2NZ>@MXCdNj@UDPK`;oygZhqr9&v-_dlzEVqd7 zX|6ObH?Hv3()V<|WX;Ar@9ALcT-!3Vp4i>4Z5>)q>;c!d)%&)>*gn^GzxN}s7hT&U z$j8~cu5BOkarTL1mT2KW6@_&;ThvW3RrRn_9cGO8m8d>;p=8a*R9{!Hv1!jL)z7X< zvwmubtxB_@YLq?WFk^+Unqus*%hvg7z}|D1Wo(2o&c1hzTVRYczv7Y zIE?m%ZqstvYjOi}9#bxR+hKHGc(R_$o|4novE{M-4xDm3Ir`U9_; z=reIL77ysh`|MxyvHrgT{fBX^lRE!jtM$(nHVS>CVoZo068)she)70uYa%oZ$6|rj z6eOHx0Tr4HR0%gg$hH!QH&&qI%4rJ@w2U5vrp^B`$SUmxYV;CNoV$rUbO313dq6LJ z3-nPiAoAu)JYl|AFf-~X4GwmO%&7{fP;aR}S)lOKj7~@$ZmPGMqq86Vo!oo5PQ5W~Y5P30e7(TtDU0Ry@}KpI$&REA&%={#~Dw z8)jv;wM||mTPEtr<qaZEY4>IOvV*)EZS<{C2e8+&ZM8QY$*!e-@cb`z z2+ImR41F~8IxsJE6j&09a4)PCG(yH1!KQ?IXp`B}P_1^p%r%1@3AJio`XW?KGuZc` z8sO&^3ciYocj4ZYW8R}prBd@zZ3f%weMY;A2AS)XsWjLuP*$=DW(5skQ_bhK7PiX# z6L5q18a!_|Q_2kXgn3xIg}rPZ)yB~Q^CRewng2k+-lev72Jk9+w=#mJg^#g2*|p)r+IF;Nj{XOBCors|X!^3RBSF5& z4fjxV74*+WKSq(SMt4Fk2_2U5A0WRK`ESpsjB*ZpzG7W+{tmehWJ^5V(Z;XP6^Aem$!`o-P>7eiYXSu zP?edRX&~fgx=3m!#tOa7G(A@4y^5;s_xpFZ?ulLMeS@~eM9)1C!|>$0W7E8g5T`^P z!T%h)-aCZ-HMZV6PDXoMUJ$)a;(YoxnpCBRX&BXT0~doexMdw7gQw+x7nZjtf^iML4HEb+Gzw@Z9b;?okJmH3>**CZa4_@>0856I=&?3SEPJU%5O^fBPo9hxfs8Qw3NctED`6XoG$UKx@gnT*W zLcWr^0PE2U)zm=qfPQ)y)`;{ekXS0QQt0jb2Wnb1olY;>I|lZ&KN#5Qj5nDmfw({> zu}EUE!~qf~Noz+wjfz!O!_mcuBMUD4aIqJ}1zw24=)_$7cp(p%4 ztXEeX+(L9VQ2edf1HBIz!jv)aZ#cdTcj{i~1Hcf5pbxr>fDC=)hdu~2XcX)rOs)X* zCUS7FEXYxKaSNS@gmPfQ+Xj&1az6sOr^H^ca9nu{>`ig#`$)V39nNu^p9jqh{E&~+ zbct8umm&;1K}Tq2;|CwOdzN?=?z%Z{_ywkLOV2PTN+H{yoD(Qqh`UNo3nZ?@j>+(A zk#cBm#LYXSRd&JPg45xODlu9w@fO^>bKKDjycJbqn1+4O@)!B5{19KR-mc!IcGfP_ zW@vM@op$5k*=KC<;0d9R+dqsxz)PagX=!Cwtz6y>XZk&FEU>$tTWs>Do@ePxeB;Kmbc(STx}EU*J-(0OyNA{q zdyrPKJG|TJ4lg>h->~G=Yi3P5(>^jJy5prG_bc|MVa@ib7YyHV(*?5wc6j_H=8*ae zu9-FK!qk}QGp?RCa_;2Icg!5$r0w`<((C@v&Dme99D1<(&{Z?{ELeW;bMx#2vzFPD zW_MD!9^A2bHrMQBsWJ^SjR$w!mwHL9YWsb@c#?DR-MJp$c|;eDtQ*;S%GMk64)(lY zefgTXk4>BRtjE6h+VSD@#VX={<_Ni{r8veXZD=Wu+5_ir+Ywy&wZfbF>@XJ}V=X;A F{|ENDuSEa= diff --git a/lib/SimpleRestServices.pdb b/lib/SimpleRestServices.pdb index 8dfbd29664ec6066e2dd4aab384797a2c3e095ff..67f679f22ed2891b06ffe74f28e1909d805c189b 100644 GIT binary patch delta 7155 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 diff --git a/src/corelib/Core/Domain/NewUser.cs b/src/corelib/Core/Domain/NewUser.cs new file mode 100644 index 000000000..63e959ba0 --- /dev/null +++ b/src/corelib/Core/Domain/NewUser.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace net.openstack.Core.Domain +{ + [DataContract] + public class NewUser + { + [DataMember(Name = "OS-KSADM:password")] + public string Password { get; set; } + + [DataMember(Name = "id", EmitDefaultValue = true)] + public string Id { get; set; } + + [DataMember(Name = "username")] + public string Username { get; set; } + + [DataMember(Name = "email")] + public string Email { get; set; } + + [DataMember(Name = "enabled")] + public bool Enabled { get; set; } + } +} diff --git a/src/corelib/Core/Domain/User.cs b/src/corelib/Core/Domain/User.cs index 0b04fa783..a82b66fb9 100644 --- a/src/corelib/Core/Domain/User.cs +++ b/src/corelib/Core/Domain/User.cs @@ -6,21 +6,19 @@ namespace net.openstack.Core.Domain [DataContract] public class User { - [DataMember(Name = "RAX-AUTH:defaultRegion")] public string DefaultRegion { get; set; } - [DataMember] + [DataMember(Name="id", EmitDefaultValue = true)] public string Id { get; set; } - [DataMember] + [DataMember(Name="username")] public string Username { get; set; } - [DataMember] + [DataMember(Name="email")] public string Email { get; set; } - [DataMember] + [DataMember(Name = "enabled")] public bool Enabled { get; set; } - } } \ No newline at end of file diff --git a/src/corelib/Core/IIdentityProvider.cs b/src/corelib/Core/IIdentityProvider.cs index 897c0a565..c19b64381 100644 --- a/src/corelib/Core/IIdentityProvider.cs +++ b/src/corelib/Core/IIdentityProvider.cs @@ -13,7 +13,7 @@ public interface IIdentityProvider User[] ListUsers(CloudIdentity identity); User GetUserByName(CloudIdentity identity, string name); User GetUser(CloudIdentity identity, string id); - User AddUser(CloudIdentity identity, User user); + NewUser AddUser(CloudIdentity identity, NewUser user); User UpdateUser(CloudIdentity identity, User user); bool DeleteUser(CloudIdentity identity, string userId); diff --git a/src/corelib/Providers/Rackspace/GeographicalIdentityProvider.cs b/src/corelib/Providers/Rackspace/GeographicalIdentityProvider.cs index c10bc68e0..13e2d0657 100644 --- a/src/corelib/Providers/Rackspace/GeographicalIdentityProvider.cs +++ b/src/corelib/Providers/Rackspace/GeographicalIdentityProvider.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SimpleRestServices.Client; @@ -215,18 +216,27 @@ public User GetUser(CloudIdentity identity, string userId) return response.Data.User; } - public User AddUser(CloudIdentity identity, User user) + public NewUser AddUser(CloudIdentity identity, NewUser newUser) { - var response = ExecuteRESTRequest(identity, "/v2.0/users", HttpMethod.POST, new AddUserRequest { User = user }); + newUser.Id = null; + + var response = ExecuteRESTRequest(identity, "/v2.0/users", HttpMethod.POST, new AddUserRequest { User = newUser }); if (response == null || response.Data == null) return null; - return response.Data.User; + // If the user specifies a password, then the password will not be in the response, so we need to fill it in on the return object. + if (string.IsNullOrWhiteSpace(response.Data.NewUser.Password)) + response.Data.NewUser.Password = newUser.Password; + + return response.Data.NewUser; } public User UpdateUser(CloudIdentity identity, User user) { + if(user == null || string.IsNullOrWhiteSpace(user.Id)) + throw new ArgumentException("The User or User.Id values cannot be null."); + var urlPath = string.Format("v2.0/users/{0}", user.Id); var updateUserRequest = new UpdateUserRequest { User = user }; @@ -378,7 +388,7 @@ protected virtual Response ExecuteRESTRequest(CloudIdentity identity, string url bodyStr = JsonConvert.SerializeObject(body, new JsonSerializerSettings{NullValueHandling = NullValueHandling.Ignore}); } - var response = _restService.Execute(url, method, bodyStr, headers, queryStringParameter, new JsonRequestSettings() { RetryCount = retryCount, RetryDelayInMS = retryDelay, Non200SuccessCodes = new[] { 401, 409 } }); + var response = _restService.Execute(url, method, bodyStr, headers, queryStringParameter, new JsonRequestSettings() { RetryCount = retryCount, RetryDelayInMS = retryDelay, Non200SuccessCodes = new[] { 401, 409 }, UserAgent = ProviderBase.GetUserAgentHeaderValue()}); // on errors try again 1 time. if (response.StatusCode == 401 && !isRetry && !isTokenRequest) diff --git a/src/corelib/Providers/Rackspace/IdentityProvider.cs b/src/corelib/Providers/Rackspace/IdentityProvider.cs index 1ecb11afa..df5b4a483 100644 --- a/src/corelib/Providers/Rackspace/IdentityProvider.cs +++ b/src/corelib/Providers/Rackspace/IdentityProvider.cs @@ -67,10 +67,10 @@ public User GetUser(CloudIdentity identity, string userId) return provider.GetUser(identity, userId); } - public User AddUser(CloudIdentity identity, User user) + public NewUser AddUser(CloudIdentity identity, NewUser newUser) { var provider = GetProvider(identity); - return provider.AddUser(identity, user); + return provider.AddUser(identity, newUser); } public User UpdateUser(CloudIdentity identity, User user) @@ -168,7 +168,7 @@ private IExtendedIdentityProvider GetProvider(CloudIdentity identity) var rackspaceCloudIdentity = identity as RackspaceCloudIdentity; if (rackspaceCloudIdentity == null) - throw new InvalidCloudIdentityException(string.Format("Invalid Identity object. Rackspace Identoty service requires an instance of type: {0}", typeof(RackspaceCloudIdentity))); + _factory.Get(CloudInstance.Default); return _factory.Get(rackspaceCloudIdentity.CloudInstance); } diff --git a/src/corelib/Providers/Rackspace/Objects/Request/AddUserRequest.cs b/src/corelib/Providers/Rackspace/Objects/Request/AddUserRequest.cs index 7db0470b9..4d1386982 100644 --- a/src/corelib/Providers/Rackspace/Objects/Request/AddUserRequest.cs +++ b/src/corelib/Providers/Rackspace/Objects/Request/AddUserRequest.cs @@ -7,6 +7,6 @@ namespace net.openstack.Providers.Rackspace.Objects.Request internal class AddUserRequest { [DataMember(Name = "user")] - public User User { get; set; } + public NewUser User { get; set; } } } diff --git a/src/corelib/Providers/Rackspace/Objects/Request/UpdateUserRequest.cs b/src/corelib/Providers/Rackspace/Objects/Request/UpdateUserRequest.cs index abc41881c..a7b7b64de 100644 --- a/src/corelib/Providers/Rackspace/Objects/Request/UpdateUserRequest.cs +++ b/src/corelib/Providers/Rackspace/Objects/Request/UpdateUserRequest.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using net.openstack.Core.Domain; namespace net.openstack.Providers.Rackspace.Objects.Request { + [DataContract] internal class UpdateUserRequest { + [DataMember(Name = "user")] public User User { get; set; } } } diff --git a/src/corelib/Providers/Rackspace/Objects/Response/NewUserResponse.cs b/src/corelib/Providers/Rackspace/Objects/Response/NewUserResponse.cs new file mode 100644 index 000000000..481340f3c --- /dev/null +++ b/src/corelib/Providers/Rackspace/Objects/Response/NewUserResponse.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; +using net.openstack.Core.Domain; + +namespace net.openstack.Providers.Rackspace.Objects.Response +{ + [DataContract] + internal class NewUserResponse + { + [DataMember(Name = "user")] + public NewUser NewUser { get; set; } + } +} \ No newline at end of file diff --git a/src/corelib/Providers/Rackspace/Objects/Response/UserResponse.cs b/src/corelib/Providers/Rackspace/Objects/Response/UserResponse.cs index 5d000d527..b75ff0007 100644 --- a/src/corelib/Providers/Rackspace/Objects/Response/UserResponse.cs +++ b/src/corelib/Providers/Rackspace/Objects/Response/UserResponse.cs @@ -1,9 +1,12 @@ +using System.Runtime.Serialization; using net.openstack.Core.Domain; namespace net.openstack.Providers.Rackspace.Objects.Response { + [DataContract] internal class UserResponse { + [DataMember(Name = "user")] public User User { get; set; } } } \ No newline at end of file diff --git a/src/corelib/Providers/Rackspace/ProviderBase.cs b/src/corelib/Providers/Rackspace/ProviderBase.cs index 479d02ba1..2787eabec 100644 --- a/src/corelib/Providers/Rackspace/ProviderBase.cs +++ b/src/corelib/Providers/Rackspace/ProviderBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SimpleRestServices.Client; @@ -16,6 +17,7 @@ public class ProviderBase { private readonly IIdentityProvider _identityProvider; private readonly IRestService _restService; + private static Version _currentVersion; protected ProviderBase(IIdentityProvider identityProvider, IRestService restService) { @@ -42,6 +44,9 @@ protected Response ExecuteRESTRequest(CloudIdentity identity, Uri absolute bodyStr = JsonConvert.SerializeObject(body, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } + if (string.IsNullOrWhiteSpace(requestSettings.UserAgent)) + requestSettings.UserAgent = GetUserAgentHeaderValue(); + var response = _restService.Execute(absoluteUri, method, bodyStr, headers, queryStringParameter, requestSettings); // on errors try again 1 time. @@ -77,6 +82,9 @@ protected Response ExecuteRESTRequest(CloudIdentity identity, Uri absoluteUri, H bodyStr = JsonConvert.SerializeObject(body, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } + if (string.IsNullOrWhiteSpace(requestSettings.UserAgent)) + requestSettings.UserAgent = GetUserAgentHeaderValue(); + var response = _restService.Execute(absoluteUri, method, bodyStr, headers, queryStringParameter, requestSettings); // on errors try again 1 time. @@ -99,7 +107,7 @@ internal JsonRequestSettings BuildDefaultRequestSettings(IEnumerable non200 if(non200SuccessCodes != null) non200SuccessCodesAggregate.AddRange(non200SuccessCodes); - return new JsonRequestSettings { RetryCount = 2, RetryDelayInMS = 200, Non200SuccessCodes = non200SuccessCodesAggregate}; + return new JsonRequestSettings { RetryCount = 2, RetryDelayInMS = 200, Non200SuccessCodes = non200SuccessCodesAggregate, UserAgent = GetUserAgentHeaderValue()}; } protected virtual string GetServiceEndpoint(CloudIdentity identity, string serviceName, string region = null) @@ -150,5 +158,13 @@ internal static void CheckResponse(Response response) throw new ServiceUnavailableException(response); } } + + internal static string GetUserAgentHeaderValue() + { + if (_currentVersion == null) + _currentVersion = Assembly.GetExecutingAssembly().GetName().Version; + + return string.Format("openstack.net/{0}", _currentVersion.ToString()); + } } } diff --git a/src/corelib/corelib.csproj b/src/corelib/corelib.csproj index 7d62c1994..3dcbca409 100644 --- a/src/corelib/corelib.csproj +++ b/src/corelib/corelib.csproj @@ -58,6 +58,7 @@ + @@ -101,6 +102,7 @@ + diff --git a/src/testing/integration/Providers/Rackspace/ComputeTests.cs b/src/testing/integration/Providers/Rackspace/ComputeTests.cs index 07d201faf..59ec45514 100644 --- a/src/testing/integration/Providers/Rackspace/ComputeTests.cs +++ b/src/testing/integration/Providers/Rackspace/ComputeTests.cs @@ -333,12 +333,22 @@ public void Test025_Should_Successfully_To_And_Login_With_New_Password() { var provider = new net.openstack.Providers.Rackspace.ComputeProvider(); var serverDetails = provider.GetDetails(_testIdentity, _testServer.Id); - using(var client = new Renci.SshNet.SshClient(serverDetails.AccessIPv4, "root", NewPassword)) + bool sucess = false; + for (int i = 0; i < 10; i++ ) { - client.Connect(); + using (var client = new Renci.SshNet.SshClient(serverDetails.AccessIPv4, "root", NewPassword)) + { + client.Connect(); - Assert.IsTrue(client.IsConnected); + sucess = client.IsConnected; + + if (sucess) + break; + } + Thread.Sleep(1000); } + + Assert.IsTrue(sucess); } [TestMethod] diff --git a/src/testing/integration/Providers/Rackspace/IdentityFull.orderedtest b/src/testing/integration/Providers/Rackspace/IdentityFull.orderedtest index 3e6a1f03b..63d214885 100644 --- a/src/testing/integration/Providers/Rackspace/IdentityFull.orderedtest +++ b/src/testing/integration/Providers/Rackspace/IdentityFull.orderedtest @@ -1,12 +1,13 @@  - + + - + @@ -16,5 +17,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/testing/integration/Providers/Rackspace/IdentityTests.cs b/src/testing/integration/Providers/Rackspace/IdentityTests.cs index 22142e8d7..bf867a5ff 100644 --- a/src/testing/integration/Providers/Rackspace/IdentityTests.cs +++ b/src/testing/integration/Providers/Rackspace/IdentityTests.cs @@ -15,7 +15,9 @@ public class IdentityTests private static RackspaceCloudIdentity _testAdminIdentity; private static User _userDetails; private static User _adminUserDetails; - private const string NewPassword = "my_new_password"; + private static NewUser _newTestUser1; + private const string NewUserPassword = "My_n3wuser2_p@$$ssw0rd"; + private const string NewPassword = "My_n3w_p@$$ssw0rd"; /// ///Gets or sets the test context which provides @@ -125,13 +127,13 @@ public void Should_Throw_Error_When_Authenticating_With_Invalid_Username() } [TestMethod] - public void Should_List_Only_Self_When_Retrieving_List_Of_Users_With_Non_Admin_Account() + public void Should_List_Only_User_In_Account_When_Retrieving_List_Of_Users_With_User_Admin_Account() { IIdentityProvider serviceProvider = new IdentityProvider(); var users = serviceProvider.ListUsers(_testIdentity); - Assert.IsTrue(users.Count() == 1); + Assert.IsTrue(users.Any()); Assert.AreEqual(_testIdentity.Username, users[0].Username); } @@ -142,7 +144,7 @@ public void Should_List_Multiple_Users_When_Retrieving_List_Of_Users_With_Admin_ var users = serviceProvider.ListUsers(_testAdminIdentity); - Assert.IsTrue(users.Count() > 1); + Assert.IsTrue(users.Any()); } [TestMethod] @@ -244,5 +246,159 @@ public void Should_Throw_Exception_When_Trying_To_Get_Details_Of_A_Different_Use Assert.IsTrue(true); } } + + [TestMethod] + public void Should_Add_New_User_Without_Specifying_A_Password_Or_Default_Region_To_Account_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + _newTestUser1 = provider.AddUser(_testIdentity, new NewUser { Username = "openstacknettestuser1", Email = "newuser@me.com", Enabled = true }); + + Assert.IsNotNull(_newTestUser1); + Assert.AreEqual("openstacknettestuser1", _newTestUser1.Username); + Assert.AreEqual("newuser@me.com", _newTestUser1.Email); + Assert.AreEqual(true, _newTestUser1.Enabled); + Assert.IsFalse(string.IsNullOrWhiteSpace(_newTestUser1.Password)); + } + + [TestMethod] + public void Should_Authenticate_NewUser() + { + Assert.IsNotNull(_newTestUser1); + + IIdentityProvider provider = new IdentityProvider(); + + var userAccess = + provider.Authenticate(new RackspaceCloudIdentity + {Username = _newTestUser1.Username, Password = _newTestUser1.Password}); + + Assert.IsNotNull(userAccess); + } + + [TestMethod] + public void Should_Update_NewUser_Username_And_Email_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + var user = new User + { + Id = _newTestUser1.Id, + Username = "openstacknettestuser12", + Email = "newuser2@me.com", + Enabled = true + }; + var updatedUser = provider.UpdateUser(_testIdentity, user); + + Assert.IsNotNull(updatedUser); + Assert.AreEqual("openstacknettestuser12", updatedUser.Username); + Assert.AreEqual("newuser2@me.com", updatedUser.Email); + Assert.AreEqual(true, updatedUser.Enabled); + Assert.IsTrue(string.IsNullOrWhiteSpace(updatedUser.DefaultRegion)); + } + + [TestMethod] + public void Should_Delete_NewUser_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + var response = provider.DeleteUser(_testIdentity, _newTestUser1.Id); + + Assert.IsTrue(response); + } + + [TestMethod] + public void Should_Throw_Exception_When_Requesting_The_NewUser_After_It_Has_Been_Deleted_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + try + { + provider.GetUser(_testIdentity, _newTestUser1.Id); + + throw new Exception("This code path is invalid, exception was expected."); + } + catch(Exception ex) + { + Assert.IsTrue(true); + } + } + + [TestMethod] + public void Should_Add_New_User_With_Specifying_A_Password_But_Not_Default_Region_To_Account_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + _newTestUser1 = provider.AddUser(_testIdentity, new NewUser { Username = "openstacknettestuser2", Email = "newuser2@me.com", Enabled = true, Password = NewUserPassword }); + + Assert.IsNotNull(_newTestUser1); + Assert.AreEqual("openstacknettestuser2", _newTestUser1.Username); + Assert.AreEqual("newuser2@me.com", _newTestUser1.Email); + Assert.AreEqual(true, _newTestUser1.Enabled); + Assert.AreEqual(NewUserPassword, _newTestUser1.Password); + Assert.IsFalse(string.IsNullOrWhiteSpace(_newTestUser1.Password)); + } + + [TestMethod] + public void Should_Update_NewUser_Username_And_Email_And_Default_Region_When_Requesting_As_User_Admin() + { + IIdentityProvider provider = new IdentityProvider(); + + var user = new User + { + Id = _newTestUser1.Id, + Username = "openstacknettestuser32", + Email = "newuser32@me.com", + Enabled = true, + DefaultRegion = "DFW" + }; + var updatedUser = provider.UpdateUser(_testIdentity, user); + + Assert.IsNotNull(updatedUser); + Assert.AreEqual("openstacknettestuser32", updatedUser.Username); + Assert.AreEqual("newuser32@me.com", updatedUser.Email); + Assert.AreEqual(true, updatedUser.Enabled); + Assert.AreEqual("DFW", updatedUser.DefaultRegion); + } + + [TestMethod] + public void Should_Get_NewUser_When_Requesting_As_Self() + { + IIdentityProvider provider = new IdentityProvider(); + + var user = provider.GetUser(new RackspaceCloudIdentity { Username = _newTestUser1.Username, Password = _newTestUser1.Password }, _newTestUser1.Id); + + Assert.IsNotNull(user); + } + + [TestMethod] + public void Should_Update_NewUser_Username_And_Email_When_Requesting_As_Self() + { + IIdentityProvider provider = new IdentityProvider(); + + var user = new User + { + Id = _newTestUser1.Id, + Username = "openstacknettestuser42", + Email = "newuser42@me.com", + Enabled = true, + }; + var updatedUser = provider.UpdateUser(new RackspaceCloudIdentity { Username = _newTestUser1.Username, Password = _newTestUser1.Password }, user); + + Assert.IsNotNull(updatedUser); + Assert.AreEqual("openstacknettestuser42", updatedUser.Username); + Assert.AreEqual("newuser42@me.com", updatedUser.Email); + Assert.AreEqual(true, updatedUser.Enabled); + } + + [TestMethod] + public void Should_List_Only_Self_When_Retrieving_List_Of_Users_With_Non_Admin_Account() + { + IIdentityProvider serviceProvider = new IdentityProvider(); + + var users = serviceProvider.ListUsers(new RackspaceCloudIdentity { Username = _newTestUser1.Username, Password = _newTestUser1.Password }); + + Assert.IsTrue(users.Count() == 1); + Assert.AreEqual(_newTestUser1.Username, users[0].Username); + } } }