Merge pull request #3175 from pedroigor/KEYCLOAK-3337
[KEYCLOAK-3337] - Support more specific date/time periods with the Time policy provider
This commit is contained in:
commit
16bd2fb8f8
5 changed files with 137 additions and 11 deletions
|
@ -37,12 +37,10 @@ public class TimePolicyAdminResource implements PolicyProviderAdminService {
|
|||
String nbf = policy.getConfig().get("nbf");
|
||||
String noa = policy.getConfig().get("noa");
|
||||
|
||||
if (nbf == null && noa == null) {
|
||||
throw new RuntimeException("You must provide NotBefore, NotOnOrAfter or both.");
|
||||
if (nbf != null && noa != null) {
|
||||
validateFormat(nbf);
|
||||
validateFormat(noa);
|
||||
}
|
||||
|
||||
validateFormat(nbf);
|
||||
validateFormat(noa);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,8 +22,11 @@ import org.keycloak.authorization.policy.evaluation.Evaluation;
|
|||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT.value;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
|
@ -45,9 +48,7 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
public void evaluate(Evaluation evaluation) {
|
||||
try {
|
||||
String notBefore = this.policy.getConfig().get("nbf");
|
||||
|
||||
if (notBefore != null) {
|
||||
|
||||
if (this.currentDate.before(this.dateFormat.parse(format(notBefore)))) {
|
||||
evaluation.deny();
|
||||
return;
|
||||
|
@ -55,7 +56,6 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
}
|
||||
|
||||
String notOnOrAfter = this.policy.getConfig().get("noa");
|
||||
|
||||
if (notOnOrAfter != null) {
|
||||
if (this.currentDate.after(this.dateFormat.parse(format(notOnOrAfter)))) {
|
||||
evaluation.deny();
|
||||
|
@ -63,12 +63,48 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
}
|
||||
}
|
||||
|
||||
if (isInvalid(Calendar.DAY_OF_MONTH, "dayMonth")
|
||||
|| isInvalid(Calendar.MONTH, "month")
|
||||
|| isInvalid(Calendar.YEAR, "year")
|
||||
|| isInvalid(Calendar.HOUR_OF_DAY, "hour")
|
||||
|| isInvalid(Calendar.MINUTE, "minute")) {
|
||||
evaluation.deny();
|
||||
return;
|
||||
}
|
||||
|
||||
evaluation.grant();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not evaluate time-based policy [" + this.policy.getName() + "].", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInvalid(int timeConstant, String configName) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
calendar.setTime(this.currentDate);
|
||||
|
||||
int dateField = calendar.get(timeConstant);
|
||||
|
||||
if (Calendar.MONTH == timeConstant) {
|
||||
dateField++;
|
||||
}
|
||||
|
||||
String start = this.policy.getConfig().get(configName);
|
||||
if (start != null) {
|
||||
String end = this.policy.getConfig().get(configName + "End");
|
||||
if (end != null) {
|
||||
if (dateField < Integer.parseInt(start) || dateField > Integer.parseInt(end)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (dateField != Integer.parseInt(start)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static String format(String notBefore) {
|
||||
String trimmed = notBefore.trim();
|
||||
|
||||
|
|
|
@ -1055,6 +1055,16 @@ authz-add-time-policy=Add Time Policy
|
|||
authz-policy-time-not-before.tooltip=Defines the time before which the policy MUST NOT be granted. Only granted if current date/time is after or equal to this value.
|
||||
authz-policy-time-not-on-after=Not On or After
|
||||
authz-policy-time-not-on-after.tooltip=Defines the time after which the policy MUST NOT be granted. Only granted if current date/time is before or equal to this value.
|
||||
authz-policy-time-day-month=Day of Month
|
||||
authz-policy-time-day-month.tooltip=Defines the day of month before/equal which policy MUST be granted. You can also provide a range period by filling the second field with the day of month before/equal which the policy MUST be granted. In this case, the policy would be granted if current day of month is between/equal the two values you provided.
|
||||
authz-policy-time-month=Month
|
||||
authz-policy-time-month.tooltip=Defines the month before/equal which policy MUST be granted. You can also provide a range period by filling the second field with the month before/equal which the policy MUST be granted. In this case, the policy would be granted if current month is between/equal the two values you provided.
|
||||
authz-policy-time-year=Year
|
||||
authz-policy-time-year.tooltip=Defines the year before/equal which policy MUST be granted. You can also provide a range period by filling the second field with the year before/equal which the policy MUST be granted. In this case, the policy would be granted if current year is between/equal the two values you provided.
|
||||
authz-policy-time-hour=Hour
|
||||
authz-policy-time-hour.tooltip=Defines the hour before/equal which policy MUST be granted. You can also provide a range period by filling the second field with the hour before/equal which the policy MUST be granted. In this case, the policy would be granted if current hour is between/equal the two values you provided.
|
||||
authz-policy-time-minute=Minute
|
||||
authz-policy-time-minute.tooltip=Defines the minute before/equal which policy MUST be granted. You can also provide a range period by filling the second field with the minute before/equal which the policy MUST be granted. In this case, the policy would be granted if current minute is between/equal the two values you provided.
|
||||
|
||||
# Authz Drools Policy Detail
|
||||
authz-add-drools-policy=Add Drools Policy
|
||||
|
|
|
@ -1090,7 +1090,36 @@ module.controller('ResourceServerPolicyTimeDetailCtrl', function($scope, $route,
|
|||
},
|
||||
|
||||
onInitUpdate : function(policy) {
|
||||
|
||||
if (policy.config.dayMonth) {
|
||||
policy.config.dayMonth = parseInt(policy.config.dayMonth);
|
||||
}
|
||||
if (policy.config.dayMonthEnd) {
|
||||
policy.config.dayMonthEnd = parseInt(policy.config.dayMonthEnd);
|
||||
}
|
||||
if (policy.config.month) {
|
||||
policy.config.month = parseInt(policy.config.month);
|
||||
}
|
||||
if (policy.config.monthEnd) {
|
||||
policy.config.monthEnd = parseInt(policy.config.monthEnd);
|
||||
}
|
||||
if (policy.config.year) {
|
||||
policy.config.year = parseInt(policy.config.year);
|
||||
}
|
||||
if (policy.config.yearEnd) {
|
||||
policy.config.yearEnd = parseInt(policy.config.yearEnd);
|
||||
}
|
||||
if (policy.config.hour) {
|
||||
policy.config.hour = parseInt(policy.config.hour);
|
||||
}
|
||||
if (policy.config.hourEnd) {
|
||||
policy.config.hourEnd = parseInt(policy.config.hourEnd);
|
||||
}
|
||||
if (policy.config.minute) {
|
||||
policy.config.minute = parseInt(policy.config.minute);
|
||||
}
|
||||
if (policy.config.minuteEnd) {
|
||||
policy.config.minuteEnd = parseInt(policy.config.minuteEnd);
|
||||
}
|
||||
},
|
||||
|
||||
onUpdate : function() {
|
||||
|
@ -1106,6 +1135,19 @@ module.controller('ResourceServerPolicyTimeDetailCtrl', function($scope, $route,
|
|||
|
||||
}
|
||||
}, realm, client, $scope);
|
||||
|
||||
$scope.isRequired = function () {
|
||||
var policy = $scope.policy;
|
||||
if (policy.config.noa || policy.config.nbf
|
||||
|| policy.config.dayMonth
|
||||
|| policy.config.month
|
||||
|| policy.config.year
|
||||
|| policy.config.hour
|
||||
|| policy.config.minute) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $route, $location, realm, PolicyController, ResourceServerPolicy, client) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<label class="col-md-2 control-label" for="policy.config.nbf">{{:: 'not-before' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" style="width: 150px" type="text" id="policy.config.nbf" name="notBefore" data-ng-model="policy.config.nbf" placeholder="yyyy-MM-dd hh:mm:ss">
|
||||
<input class="form-control" style="width: 150px" type="text" id="policy.config.nbf" name="notBefore" data-ng-model="policy.config.nbf" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
|
@ -45,10 +45,50 @@
|
|||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-not-on-after' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" style="width: 150px" type="text" id="policy.config.noa" name="policy.config.noa" data-ng-model="policy.config.noa" placeholder="yyyy-MM-dd hh:mm:ss">
|
||||
<input class="form-control" style="width: 150px" type="text" id="policy.config.noa" name="policy.config.noa" data-ng-model="policy.config.noa" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-day-month' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" type="number" min="1" max="31" data-ng-model="policy.config.dayMonth" id="dayMonth" name="dayMonth" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.config.dayMonth}}" max="31" data-ng-model="policy.config.dayMonthEnd" id="dayMonthEnd" name="dayMonthEnd"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-day-month.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-month' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" type="number" min="1" max="12" data-ng-model="policy.config.month" id="month" name="month" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.config.month}}" max="12" data-ng-model="policy.config.monthEnd" id="monthEnd" name="monthEnd"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-month.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-year' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" type="number" min="2016" max="2050" data-ng-model="policy.config.year" id="year" name="year" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.config.year}}" max="2050" data-ng-model="policy.config.yearEnd" id="yearEnd" name="yearEnd"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-year.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-hour' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" type="number" min="0" max="23" data-ng-model="policy.config.hour" id="hour" name="hour" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.config.hour}}" max="23" data-ng-model="policy.config.hourEnd" id="hourEnd" name="hourEnd"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-hour.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-minute' | translate}}</label>
|
||||
|
||||
<div class="col-md-6 time-selector">
|
||||
<input class="form-control" type="number" min="0" max="59" data-ng-model="policy.config.minute" id="minute" name="minute" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.config.minute}}" max="59" data-ng-model="policy.config.minuteEnd" id="minuteEnd" name="minuteEnd"/>
|
||||
</div>
|
||||
<kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group clearfix">
|
||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||
|
||||
|
|
Loading…
Reference in a new issue