KEYCLOAK-18590 Save Button Enabled For Empty Attributes

This commit is contained in:
Martin Bartoš 2021-08-19 15:00:29 +02:00 committed by Marek Posolda
parent fd2787ae7d
commit 7c243c8427
5 changed files with 51 additions and 12 deletions

View file

@ -474,7 +474,8 @@ public class ModelToRepresentation {
session.clientPolicy().updateRealmRepresentationFromModel(realm, rep);
rep.setAttributes(stripRealmAttributesIncludedAsFields(realm.getAttributes()));
// Append realm attributes to representation
rep.getAttributes().putAll(stripRealmAttributesIncludedAsFields(realm.getAttributes()));
if (!internal) {
rep = StripSecretsUtils.strip(rep);

View file

@ -73,6 +73,12 @@ public class TokenSettings extends RealmSettings {
@FindBy(id = "actionTokenAttributeTime")
private WebElement actionTokenAttributeTime;
@FindBy(name = "requestUriLifespanUnit")
private Select requestUriLifespanUnit;
@FindBy(id = "requestUriLifespan")
private WebElement requestUriLifespanTimeout;
@FindBy(xpath = "//button[@data-ng-click='resetToDefaultToken(actionTokenId)']")
private WebElement resetButton;
@ -84,6 +90,10 @@ public class TokenSettings extends RealmSettings {
setTimeout(sessionLifespanTimeoutUnit, sessionLifespanTimeout, time, unit);
}
public void setRequestUriLifespanTimeout(int time, TimeUnit unit) {
setTimeout(requestUriLifespanUnit, requestUriLifespanTimeout, time, unit);
}
public void setOperation(String tokenType, int time, TimeUnit unit) {
selectOperation(tokenType);
setTimeout(actionTokenAttributeUnit, actionTokenAttributeTime, time, unit);
@ -112,5 +122,13 @@ public class TokenSettings extends RealmSettings {
actionTokenAttributeSelect.selectByValue(tokenType.toLowerCase());
pause(500); // wait for the form to be updated; there isn't currently a better way
}
public int getRequestUriLifespanTimeout() {
return Integer.parseInt(requestUriLifespanTimeout.getAttribute("value"));
}
public TimeUnit getRequestUriLifespanUnits() {
return TimeUnit.valueOf(requestUriLifespanUnit.getFirstSelectedOption().getText().toUpperCase());
}
}
}

View file

@ -23,6 +23,7 @@ import org.junit.Before;
import org.junit.Test;
import org.keycloak.authentication.actiontoken.resetcred.ResetCredentialsActionToken;
import org.keycloak.authentication.actiontoken.verifyemail.VerifyEmailActionToken;
import org.keycloak.models.ParConfig;
import org.keycloak.models.jpa.entities.RealmAttributes;
import org.keycloak.testsuite.auth.page.account.Account;
import org.keycloak.testsuite.console.page.realm.TokenSettings;
@ -34,10 +35,11 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.util.UIUtils.refreshPageAndWaitForLoad;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
@ -188,6 +190,28 @@ public class TokensTest extends AbstractRealmTest {
}
@Test
public void testParRequestUriLifespan() {
int defaultMinutes = (int) TimeUnit.SECONDS.toMinutes(ParConfig.DEFAULT_PAR_REQUEST_URI_LIFESPAN);
assertThat(tokenSettingsPage.form().getRequestUriLifespanTimeout(), is(defaultMinutes));
tokenSettingsPage.form().setRequestUriLifespanTimeout(30, TimeUnit.MINUTES);
tokenSettingsPage.form().save();
assertAlertSuccess();
assertThat(tokenSettingsPage.form().getRequestUriLifespanTimeout(), is(30));
assertThat(tokenSettingsPage.form().getRequestUriLifespanUnits(), is(TimeUnit.MINUTES));
tokenSettingsPage.form().setRequestUriLifespanTimeout(20,TimeUnit.HOURS);
tokenSettingsPage.form().save();
assertAlertSuccess();
assertThat(tokenSettingsPage.form().getRequestUriLifespanTimeout(), is(20));
assertThat(tokenSettingsPage.form().getRequestUriLifespanUnits(), is(TimeUnit.HOURS));
}
private Map<String, Integer> getUserActionTokens() {
Map<String, Integer> userActionTokens = new HashMap<>();
adminClient.realm(testRealmPage.getAuthRealm()).toRepresentation().getAttributes().entrySet().stream()

View file

@ -1325,8 +1325,8 @@ module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http,
$scope.realm.actionTokenGeneratedByAdminLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByAdminLifespan);
$scope.realm.actionTokenGeneratedByUserLifespan = TimeUnit2.asUnit(realm.actionTokenGeneratedByUserLifespan);
$scope.realm.oauth2DeviceCodeLifespan = TimeUnit2.asUnit(realm.oauth2DeviceCodeLifespan);
$scope.requestUriLifespan = TimeUnit2.asUnit(realm.attributes.parRequestUriLifespan);
$scope.realm.attributes = realm.attributes
$scope.realm.attributes.parRequestUriLifespan = TimeUnit2.asUnit(realm.attributes.parRequestUriLifespan);
$scope.realm.attributes = realm.attributes;
var oldCopy = angular.copy($scope.realm);
$scope.changed = false;
@ -1337,10 +1337,6 @@ module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http,
}
}, true);
$scope.$watch('requestUriLifespan', function () {
$scope.changed = true;
}, true);
$scope.$watch('actionLifespanId', function () {
// changedActionLifespanId signals other watchers that we were merely
// changing the dropdown and we should not enable 'save' button
@ -1390,7 +1386,7 @@ module.controller('RealmTokenDetailCtrl', function($scope, Realm, realm, $http,
$scope.realm.actionTokenGeneratedByAdminLifespan = $scope.realm.actionTokenGeneratedByAdminLifespan.toSeconds();
$scope.realm.actionTokenGeneratedByUserLifespan = $scope.realm.actionTokenGeneratedByUserLifespan.toSeconds();
$scope.realm.oauth2DeviceCodeLifespan = $scope.realm.oauth2DeviceCodeLifespan.toSeconds();
$scope.realm.attributes.parRequestUriLifespan = $scope.requestUriLifespan.toSeconds().toString();
$scope.realm.attributes.parRequestUriLifespan = $scope.realm.attributes.parRequestUriLifespan.toSeconds();
Realm.update($scope.realm, function () {
$route.reload();

View file

@ -324,9 +324,9 @@
<label class="col-md-2 control-label" for="requestUriLifespan" class="two-lines">{{:: 'request-uri-lifespan' | translate}}</label>
<div class="col-md-6 time-selector">
<input class="form-control" type="number" required min="1" max="31536000" string-to-number data-ng-model="requestUriLifespan.time"
<input class="form-control" type="number" required min="1" max="31536000" string-to-number data-ng-model="realm.attributes.parRequestUriLifespan.time"
id="requestUriLifespan" name="requestUriLifespan">
<select class="form-control" name="requestUriLifespan" data-ng-model="requestUriLifespan.unit">
<select class="form-control" name="requestUriLifespanUnit" data-ng-model="realm.attributes.parRequestUriLifespan.unit">
<option value="Minutes">{{:: 'minutes' | translate}}</option>
<option value="Hours">{{:: 'hours' | translate}}</option>
</select>