1717package com .cloud .api ;
1818
1919import com .cloud .domain .Domain ;
20+ import com .cloud .domain .DomainVO ;
21+ import com .cloud .exception .CloudAuthenticationException ;
2022import com .cloud .user .Account ;
23+ import com .cloud .user .AccountManager ;
24+ import com .cloud .user .DomainManager ;
2125import com .cloud .user .User ;
2226import com .cloud .user .UserAccount ;
27+ import com .cloud .user .UserVO ;
2328import com .cloud .utils .exception .CloudRuntimeException ;
29+
30+ import org .apache .cloudstack .api .ApiConstants ;
31+ import org .apache .cloudstack .api .ResponseObject ;
32+ import org .apache .cloudstack .api .response .LoginCmdResponse ;
2433import org .apache .cloudstack .framework .config .ConfigKey ;
34+ import org .apache .cloudstack .resourcedetail .UserDetailVO ;
2535import org .apache .cloudstack .user .UserPasswordResetManager ;
2636import org .junit .AfterClass ;
2737import org .junit .Assert ;
3545import org .mockito .junit .MockitoJUnitRunner ;
3646
3747import java .lang .reflect .Field ;
48+ import java .net .InetAddress ;
3849import java .util .ArrayList ;
50+ import java .util .Collections ;
51+ import java .util .HashMap ;
3952import java .util .List ;
53+ import java .util .Map ;
4054
55+ import static org .apache .cloudstack .api .ApiConstants .PASSWORD_CHANGE_REQUIRED ;
4156import static org .apache .cloudstack .user .UserPasswordResetManager .UserPasswordResetEnabled ;
57+ import static org .mockito .ArgumentMatchers .any ;
58+ import static org .mockito .ArgumentMatchers .anyLong ;
59+ import static org .mockito .ArgumentMatchers .anyString ;
60+ import static org .mockito .ArgumentMatchers .eq ;
61+ import static org .mockito .Mockito .mock ;
62+
63+ import javax .servlet .http .HttpSession ;
4264
4365@ RunWith (MockitoJUnitRunner .class )
4466public class ApiServerTest {
@@ -49,6 +71,15 @@ public class ApiServerTest {
4971 @ Mock
5072 UserPasswordResetManager userPasswordResetManager ;
5173
74+ @ Mock
75+ DomainManager domainManager ;
76+
77+ @ Mock
78+ AccountManager accountManager ;
79+
80+ @ Mock
81+ HttpSession session ;
82+
5283 @ BeforeClass
5384 public static void beforeClass () throws Exception {
5485 overrideDefaultConfigValue (UserPasswordResetEnabled , "_value" , true );
@@ -96,8 +127,8 @@ public void testSetupIntegrationPortListenerValidPort() {
96127
97128 @ Test
98129 public void testForgotPasswordSuccess () {
99- UserAccount userAccount = Mockito . mock (UserAccount .class );
100- Domain domain = Mockito . mock (Domain .class );
130+ UserAccount userAccount = mock (UserAccount .class );
131+ Domain domain = mock (Domain .class );
101132
102133 Mockito .when (userAccount .getEmail ()).thenReturn ("test@test.com" );
103134 Mockito .when (userAccount .getState ()).thenReturn ("ENABLED" );
@@ -110,17 +141,17 @@ public void testForgotPasswordSuccess() {
110141
111142 @ Test (expected = CloudRuntimeException .class )
112143 public void testForgotPasswordFailureNoEmail () {
113- UserAccount userAccount = Mockito . mock (UserAccount .class );
114- Domain domain = Mockito . mock (Domain .class );
144+ UserAccount userAccount = mock (UserAccount .class );
145+ Domain domain = mock (Domain .class );
115146
116147 Mockito .when (userAccount .getEmail ()).thenReturn ("" );
117148 apiServer .forgotPassword (userAccount , domain );
118149 }
119150
120151 @ Test (expected = CloudRuntimeException .class )
121152 public void testForgotPasswordFailureDisabledUser () {
122- UserAccount userAccount = Mockito . mock (UserAccount .class );
123- Domain domain = Mockito . mock (Domain .class );
153+ UserAccount userAccount = mock (UserAccount .class );
154+ Domain domain = mock (Domain .class );
124155
125156 Mockito .when (userAccount .getEmail ()).thenReturn ("test@test.com" );
126157 Mockito .when (userAccount .getState ()).thenReturn ("DISABLED" );
@@ -129,8 +160,8 @@ public void testForgotPasswordFailureDisabledUser() {
129160
130161 @ Test (expected = CloudRuntimeException .class )
131162 public void testForgotPasswordFailureDisabledAccount () {
132- UserAccount userAccount = Mockito . mock (UserAccount .class );
133- Domain domain = Mockito . mock (Domain .class );
163+ UserAccount userAccount = mock (UserAccount .class );
164+ Domain domain = mock (Domain .class );
134165
135166 Mockito .when (userAccount .getEmail ()).thenReturn ("test@test.com" );
136167 Mockito .when (userAccount .getState ()).thenReturn ("ENABLED" );
@@ -140,8 +171,8 @@ public void testForgotPasswordFailureDisabledAccount() {
140171
141172 @ Test (expected = CloudRuntimeException .class )
142173 public void testForgotPasswordFailureInactiveDomain () {
143- UserAccount userAccount = Mockito . mock (UserAccount .class );
144- Domain domain = Mockito . mock (Domain .class );
174+ UserAccount userAccount = mock (UserAccount .class );
175+ Domain domain = mock (Domain .class );
145176
146177 Mockito .when (userAccount .getEmail ()).thenReturn ("test@test.com" );
147178 Mockito .when (userAccount .getState ()).thenReturn ("ENABLED" );
@@ -153,8 +184,8 @@ public void testForgotPasswordFailureInactiveDomain() {
153184 @ Test
154185 public void testVerifyApiKeyAccessAllowed () {
155186 Long domainId = 1L ;
156- User user = Mockito . mock (User .class );
157- Account account = Mockito . mock (Account .class );
187+ User user = mock (User .class );
188+ Account account = mock (Account .class );
158189
159190 Mockito .when (user .getApiKeyAccess ()).thenReturn (true );
160191 Assert .assertEquals (true , apiServer .verifyApiKeyAccessAllowed (user , account ));
@@ -176,4 +207,73 @@ public void testVerifyApiKeyAccessAllowed() {
176207 Mockito .when (account .getApiKeyAccess ()).thenReturn (null );
177208 Assert .assertEquals (true , apiServer .verifyApiKeyAccessAllowed (user , account ));
178209 }
210+
211+ @ Test
212+ public void testLoginUserSuccess () throws Exception {
213+ String username = "user" ;
214+ String password = "password" ;
215+ Long domainId = 1L ;
216+ String domainPath = "/" ;
217+ InetAddress loginIp = InetAddress .getByName ("127.0.0.1" );
218+ Map <String , Object []> requestParams = new HashMap <>();
219+
220+ DomainVO domain = mock (DomainVO .class );
221+ Mockito .when (domain .getId ()).thenReturn (domainId );
222+ Mockito .when (domain .getUuid ()).thenReturn ("domain-uuid" );
223+
224+ Mockito .when (domainManager .findDomainByIdOrPath (domainId , domainPath )).thenReturn (domain );
225+ Mockito .when (domainManager .getDomain (domainId )).thenReturn (domain );
226+
227+ UserAccount userAccount = mock (UserAccount .class );
228+ Mockito .when (userAccount .getId ()).thenReturn (100L );
229+ Mockito .when (userAccount .getAccountId ()).thenReturn (200L );
230+ Mockito .when (userAccount .getUsername ()).thenReturn (username );
231+ Mockito .when (userAccount .getFirstname ()).thenReturn ("First" );
232+ Mockito .when (userAccount .getLastname ()).thenReturn ("Last" );
233+ Mockito .when (userAccount .getTimezone ()).thenReturn ("UTC" );
234+ Mockito .when (userAccount .getRegistrationToken ()).thenReturn ("token" );
235+ Mockito .when (userAccount .isRegistered ()).thenReturn (true );
236+ Mockito .when (userAccount .getDomainId ()).thenReturn (domainId );
237+ Map <String , String > userAccDetails = new HashMap <>();
238+ userAccDetails .put (UserDetailVO .PasswordChangeRequired , "true" );
239+ Mockito .when (userAccount .getDetails ()).thenReturn (userAccDetails );
240+
241+ Mockito .when (accountManager .authenticateUser (username , password , domainId , loginIp , requestParams )).thenReturn (userAccount );
242+ Mockito .when (accountManager .clearUserTwoFactorAuthenticationInSetupStateOnLogin (userAccount )).thenReturn (userAccount );
243+
244+ Account account = mock (Account .class );
245+ Mockito .when (account .getAccountName ()).thenReturn ("account" );
246+ Mockito .when (account .getDomainId ()).thenReturn (domainId );
247+ Mockito .when (account .getType ()).thenReturn (Account .Type .NORMAL );
248+ Mockito .when (account .getType ()).thenReturn (Account .Type .NORMAL );
249+ Mockito .when (accountManager .getAccount (200L )).thenReturn (account );
250+
251+ UserVO userVO = mock (UserVO .class );
252+ Mockito .when (userVO .getUuid ()).thenReturn ("user-uuid" );
253+ Mockito .when (accountManager .getActiveUser (100L )).thenReturn (userVO );
254+
255+ Mockito .when (session .getAttributeNames ()).thenReturn (Collections .enumeration (List .of (PASSWORD_CHANGE_REQUIRED )));
256+ Mockito .when (session .getAttribute (PASSWORD_CHANGE_REQUIRED )).thenReturn (Boolean .TRUE );
257+
258+ ResponseObject response = apiServer .loginUser (session , username , password , domainId , domainPath , loginIp , requestParams );
259+ Assert .assertNotNull (response );
260+ Assert .assertTrue (response instanceof LoginCmdResponse );
261+ Mockito .verify (session ).setAttribute (eq ("userid" ), eq (100L ));
262+ Mockito .verify (session ).setAttribute (eq (ApiConstants .SESSIONKEY ), anyString ());
263+ }
264+
265+ @ Test (expected = CloudAuthenticationException .class )
266+ public void testLoginUserDomainNotFound () throws Exception {
267+ Mockito .when (domainManager .findDomainByIdOrPath (anyLong (), anyString ())).thenReturn (null );
268+ apiServer .loginUser (session , "user" , "pass" , 1L , "/" , null , null );
269+ }
270+
271+ @ Test (expected = CloudAuthenticationException .class )
272+ public void testLoginUserAuthFailed () throws Exception {
273+ DomainVO domain = mock (DomainVO .class );
274+ Mockito .when (domain .getId ()).thenReturn (1L );
275+ Mockito .when (domainManager .findDomainByIdOrPath (anyLong (), anyString ())).thenReturn (domain );
276+ Mockito .when (accountManager .authenticateUser (anyString (), anyString (), anyLong (), any (), any ())).thenReturn (null );
277+ apiServer .loginUser (session , "user" , "pass" , 1L , "/" , null , null );
278+ }
179279}
0 commit comments