Do not set empty permissions to username and email attributes

Closes #11647
This commit is contained in:
Pedro Igor 2022-05-27 16:53:43 -03:00
parent 5f349195bb
commit 243e63c9f3
4 changed files with 56 additions and 8 deletions

View file

@ -178,7 +178,7 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
if (!isBlank(upConfigJson)) { if (!isBlank(upConfigJson)) {
try { try {
UPConfig upc = readConfig(new ByteArrayInputStream(upConfigJson.getBytes("UTF-8"))); UPConfig upc = parseConfig(upConfigJson);
List<String> errors = UPConfigUtils.validate(session, upc); List<String> errors = UPConfigUtils.validate(session, upc);
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
@ -340,7 +340,8 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
AttributeGroupMetadata groupMetadata = toAttributeGroupMeta(groupsByName.get(attributeGroup)); AttributeGroupMetadata groupMetadata = toAttributeGroupMeta(groupsByName.get(attributeGroup));
if (isUsernameOrEmailAttribute(attributeName)) { if (isUsernameOrEmailAttribute(attributeName)) {
if (permissions == null) { // make sure username and email are writable if permissions are not set
if (permissions == null || permissions.isEmpty()) {
writeAllowed = AttributeMetadata.ALWAYS_TRUE; writeAllowed = AttributeMetadata.ALWAYS_TRUE;
} }
@ -407,7 +408,7 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
if (!isBlank(rawConfig)) { if (!isBlank(rawConfig)) {
try { try {
UPConfig upc = readConfig(new ByteArrayInputStream(rawConfig.getBytes("UTF-8"))); UPConfig upc = parseConfig(rawConfig);
//validate configuration to catch things like changed/removed validators etc, and warn early and clearly about this problem //validate configuration to catch things like changed/removed validators etc, and warn early and clearly about this problem
List<String> errors = UPConfigUtils.validate(session, upc); List<String> errors = UPConfigUtils.validate(session, upc);
@ -424,6 +425,10 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
return null; return null;
} }
private UPConfig parseConfig(String rawConfig) throws IOException {
return readConfig(new ByteArrayInputStream(rawConfig.getBytes("UTF-8")));
}
/** /**
* Get component to store our "per realm" configuration into. * Get component to store our "per realm" configuration into.
* *

View file

@ -18,6 +18,7 @@ package org.keycloak.userprofile.config;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** /**
* Configuration of permissions for the attribute * Configuration of permissions for the attribute
@ -51,4 +52,8 @@ public class UPAttributePermissions {
return "UPAttributePermissions [view=" + view + ", edit=" + edit + "]"; return "UPAttributePermissions [view=" + view + ", edit=" + edit + "]";
} }
@JsonIgnore
public boolean isEmpty() {
return getEdit().isEmpty() && getView().isEmpty();
}
} }

View file

@ -1306,4 +1306,37 @@ public class UserProfileTest extends AbstractUserProfileTest {
//ignore //ignore
} }
} }
@Test
public void testUsernameAndEmailPermissionNotSetIfEmpty() {
getTestingClient().server(TEST_REALM_NAME).run((RunOnServer) UserProfileTest::testUsernameAndEmailPermissionNotSetIfEmpty);
}
private static void testUsernameAndEmailPermissionNotSetIfEmpty(KeycloakSession session) throws IOException {
DeclarativeUserProfileProvider provider = getDynamicUserProfileProvider(session);
UPConfig config = JsonSerialization.readValue(provider.getConfiguration(), UPConfig.class);
for (UPAttribute attribute : config.getAttributes()) {
if (attribute.getName().equals(UserModel.USERNAME) || attribute.getName().equals(UserModel.EMAIL)) {
attribute.setPermissions(new UPAttributePermissions());
}
}
provider.setConfiguration(JsonSerialization.writeValueAsString(config));
RealmModel realm = session.getContext().getRealm();
String username = "profiled-user-profile";
UserModel user = session.users().addUser(realm, username);
Map<String, Object> attributes = new HashMap<>();
attributes.put(UserModel.EMAIL, "test@keycloak.com");
UserProfile profile = provider.create(UserProfileContext.USER_API, attributes, user);
profile.update();
user = session.users().getUserById(realm, user.getId());
assertEquals("test@keycloak.com", user.getEmail());
}
} }

View file

@ -1715,7 +1715,8 @@ module.controller('RealmUserProfileCtrl', function($scope, Realm, realm, clientS
} }
$scope.editAttribute = function(attribute) { $scope.editAttribute = function(attribute) {
if (attribute.permissions == null) { // it isn't be possible to set permissions to username and email
if (attribute.permissions == null && (attribute.name != 'username' && attribute.name != 'email')) {
attribute.permissions = { attribute.permissions = {
view: [], view: [],
edit: [] edit: []
@ -1752,10 +1753,14 @@ module.controller('RealmUserProfileCtrl', function($scope, Realm, realm, clientS
} }
$scope.isRequired = attribute.required != null; $scope.isRequired = attribute.required != null;
$scope.canUserView = attribute.permissions.view.includes('user');
$scope.canAdminView = attribute.permissions.view.includes('admin'); if (attribute.permissions != null) {
$scope.canUserEdit = attribute.permissions.edit.includes('user'); $scope.canUserView = attribute.permissions.view.includes('user');
$scope.canAdminEdit = attribute.permissions.edit.includes('admin'); $scope.canAdminView = attribute.permissions.view.includes('admin');
$scope.canUserEdit = attribute.permissions.edit.includes('user');
$scope.canAdminEdit = attribute.permissions.edit.includes('admin');
}
$scope.currentAttribute = attribute; $scope.currentAttribute = attribute;
$scope.attributeSelected = true; $scope.attributeSelected = true;
}; };