KEYCLOAK-17387: 403 response on localization endpoint for cross realm users
- add ForbiddenPage class for the assertion at the selenium test - add assertion to selenium test - GET requests for localization texts require at least one role for the realm - Make GET requests for localization texts public, to display the admin UI correctly, even if the role view-realm is missing
This commit is contained in:
parent
96501760e0
commit
61bdc92ad9
3 changed files with 85 additions and 3 deletions
|
@ -24,6 +24,7 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.ForbiddenException;
|
||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -46,6 +47,7 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
public class RealmLocalizationResource {
|
||||
|
@ -130,7 +132,9 @@ public class RealmLocalizationResource {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Stream<String> getRealmLocalizationLocales() {
|
||||
this.auth.realm().requireViewRealm();
|
||||
if (!AdminPermissions.realms(session, auth.adminAuth()).isAdmin()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
return realm.getRealmLocalizationTexts().keySet().stream().sorted();
|
||||
}
|
||||
|
@ -139,7 +143,10 @@ public class RealmLocalizationResource {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> getRealmLocalizationTexts(@PathParam("locale") String locale) {
|
||||
this.auth.realm().requireViewRealm();
|
||||
if (!AdminPermissions.realms(session, auth.adminAuth()).isAdmin()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
return realm.getRealmLocalizationTextsByLocale(locale);
|
||||
}
|
||||
|
||||
|
@ -147,7 +154,10 @@ public class RealmLocalizationResource {
|
|||
@GET
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
public String getRealmLocalizationText(@PathParam("locale") String locale, @PathParam("key") String key) {
|
||||
this.auth.realm().requireViewRealm();
|
||||
if (!AdminPermissions.realms(session, auth.adminAuth()).isAdmin()) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
String text = session.realms().getLocalizationTextsById(realm, locale, key);
|
||||
if (text != null) {
|
||||
return text;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.testsuite.console.page;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
public class ForbiddenPage extends AdminConsole {
|
||||
|
||||
@Override
|
||||
public UriBuilder createUriBuilder() {
|
||||
return super.createUriBuilder().path("/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUriFragment() {
|
||||
return "/forbidden";
|
||||
}
|
||||
}
|
|
@ -17,13 +17,27 @@
|
|||
*/
|
||||
package org.keycloak.testsuite.console;
|
||||
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.console.page.ForbiddenPage;
|
||||
|
||||
import org.openqa.selenium.JavascriptExecutor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.keycloak.testsuite.admin.ApiUtil.assignClientRoles;
|
||||
import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWithAdminClient;
|
||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
|
||||
|
||||
public class BasicConsoleTest extends AbstractConsoleTest {
|
||||
|
||||
@Page
|
||||
ForbiddenPage forbiddenPage;
|
||||
|
||||
private final static String TEST_USER_VIEW_USERS_NAME = "BasicConsoleTest-view-users";
|
||||
private final static String DEFAULT_PASSWORD = "Test12345!";
|
||||
|
||||
@Test
|
||||
// KEYCLOAK-4717
|
||||
public void testPostWindowMessage() throws InterruptedException {
|
||||
|
@ -37,4 +51,30 @@ public class BasicConsoleTest extends AbstractConsoleTest {
|
|||
assertEquals("Expected window not to have reloaded", "check", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
// KEYCLOAK-17387
|
||||
public void testUserWithViewUsersRoleCanOpenConsole() {
|
||||
UserRepresentation userRepresentation = createTestUserWithViewUsersRole();
|
||||
try {
|
||||
loginToTestRealmConsoleAs(userRepresentation);
|
||||
assertCurrentUrlDoesntStartWith(forbiddenPage);
|
||||
} finally {
|
||||
ApiUtil.removeUserByUsername(testRealmResource(), TEST_USER_VIEW_USERS_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
private UserRepresentation createTestUserWithViewUsersRole() {
|
||||
ApiUtil.removeUserByUsername(testRealmResource(), TEST_USER_VIEW_USERS_NAME);
|
||||
|
||||
log.debug("creating test user with view-users role");
|
||||
|
||||
UserRepresentation userRepresentation = createUserRepresentation(TEST_USER_VIEW_USERS_NAME, null, null, null, true, DEFAULT_PASSWORD);
|
||||
String id = createUserAndResetPasswordWithAdminClient(testRealmResource(), userRepresentation, DEFAULT_PASSWORD);
|
||||
|
||||
userRepresentation.setId(id);
|
||||
|
||||
assignClientRoles(testRealmResource(), id, "realm-management", "view-users");
|
||||
return userRepresentation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue