blob: 12ebbe56f5fe61d1016a0f8cdb517f785bfc33ae [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.acl;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import java.lang.reflect.Field;
import java.util.Collections;
@RunWith(MockitoJUnitRunner.class)
public class DynamicRoleBasedAPIAccessCheckerTest extends TestCase {
@Mock
private AccountService accountService;
@Mock
private RoleService roleService;
private DynamicRoleBasedAPIAccessChecker apiAccessChecker;
private User getTestUser() {
return new UserVO(12L, "some user", "password", "firstName", "lastName",
"email@gmail.com", "GMT", "uuid", User.Source.UNKNOWN);
}
private Account getTestAccount() {
return new AccountVO("some name", 1L, "network-domain", (short)0, "some-uuid");
}
private Role getTestRole() {
return new RoleVO(4L, "SomeRole", RoleType.User, "some description");
}
private void setupMockField(final Object obj, final String fieldName, final Object mock) throws NoSuchFieldException, IllegalAccessException {
Field roleDaoField = DynamicRoleBasedAPIAccessChecker.class.getDeclaredField(fieldName);
roleDaoField.setAccessible(true);
roleDaoField.set(obj, mock);
}
@Override
@Before
public void setUp() throws NoSuchFieldException, IllegalAccessException {
apiAccessChecker = Mockito.spy(new DynamicRoleBasedAPIAccessChecker());
setupMockField(apiAccessChecker, "accountService", accountService);
setupMockField(apiAccessChecker, "roleService", roleService);
Mockito.when(accountService.getAccount(Mockito.anyLong())).thenReturn(getTestAccount());
Mockito.when(roleService.findRole(Mockito.anyLong())).thenReturn((RoleVO) getTestRole());
// Enabled plugin
Mockito.doReturn(false).when(apiAccessChecker).isDisabled();
Mockito.doCallRealMethod().when(apiAccessChecker).checkAccess(Mockito.any(User.class), Mockito.anyString());
}
@Test
public void testInvalidAccountCheckAccess() {
Mockito.when(accountService.getAccount(Mockito.anyLong())).thenReturn(null);
try {
apiAccessChecker.checkAccess(getTestUser(), "someApi");
fail("Exception was expected");
} catch (PermissionDeniedException ignored) {
}
}
@Test
public void testInvalidAccountRoleCheckAccess() {
Mockito.when(roleService.findRole(Mockito.anyLong())).thenReturn(null);
try {
apiAccessChecker.checkAccess(getTestUser(), "someApi");
fail("Exception was expected");
} catch (PermissionDeniedException ignored) {
}
}
@Test
public void testDefaultRootAdminAccess() {
Mockito.when(accountService.getAccount(Mockito.anyLong())).thenReturn(new AccountVO("root admin", 1L, null, (short)1, "some-uuid"));
Mockito.when(roleService.findRole(Mockito.anyLong())).thenReturn(new RoleVO(1L, "SomeRole", RoleType.Admin, "default root admin role"));
assertTrue(apiAccessChecker.checkAccess(getTestUser(), "anyApi"));
}
@Test
public void testInvalidRolePermissionsCheckAccess() {
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.<RolePermission>emptyList());
try {
apiAccessChecker.checkAccess(getTestUser(), "someApi");
fail("Exception was expected");
} catch (PermissionDeniedException ignored) {
}
}
@Test
public void testValidAllowRolePermissionApiCheckAccess() {
final String allowedApiName = "someAllowedApi";
final RolePermission permission = new RolePermissionVO(1L, allowedApiName, RolePermission.Permission.ALLOW, null);
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
assertTrue(apiAccessChecker.checkAccess(getTestUser(), allowedApiName));
}
@Test
public void testValidAllowRolePermissionWildcardCheckAccess() {
final String allowedApiName = "someAllowedApi";
final RolePermission permission = new RolePermissionVO(1L, "some*", RolePermission.Permission.ALLOW, null);
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
assertTrue(apiAccessChecker.checkAccess(getTestUser(), allowedApiName));
}
@Test
public void testValidDenyRolePermissionApiCheckAccess() {
final String denyApiName = "someDeniedApi";
final RolePermission permission = new RolePermissionVO(1L, denyApiName, RolePermission.Permission.DENY, null);
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
try {
apiAccessChecker.checkAccess(getTestUser(), denyApiName);
fail("Exception was expected");
} catch (PermissionDeniedException ignored) {
}
}
@Test
public void testValidDenyRolePermissionWildcardCheckAccess() {
final String denyApiName = "someDenyApi";
final RolePermission permission = new RolePermissionVO(1L, "*Deny*", RolePermission.Permission.DENY, null);
Mockito.when(roleService.findAllPermissionsBy(Mockito.anyLong())).thenReturn(Collections.singletonList(permission));
try {
apiAccessChecker.checkAccess(getTestUser(), denyApiName);
fail("Exception was expected");
} catch (PermissionDeniedException ignored) {
}
}
@Test
public void testAnnotationFallbackCheckAccess() {
final String allowedApiName = "someApiWithAnnotations";
apiAccessChecker.addApiToRoleBasedAnnotationsMap(getTestRole().getRoleType(), allowedApiName);
assertTrue(apiAccessChecker.checkAccess(getTestUser(), allowedApiName));
}
}