[KEYCLOAK-3135] - More changes to Policy Management API
This commit is contained in:
parent
3dbd0d5063
commit
e0f753bcf5
15 changed files with 851 additions and 111 deletions
|
@ -1,30 +1,27 @@
|
||||||
package org.keycloak.authorization.policy.provider.js;
|
package org.keycloak.authorization.policy.provider.js;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineManager;
|
import javax.script.ScriptEngineManager;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.authorization.AuthorizationProvider;
|
import org.keycloak.authorization.AuthorizationProvider;
|
||||||
import org.keycloak.authorization.model.ResourceServer;
|
import org.keycloak.authorization.model.Policy;
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
public class JSPolicyProviderFactory implements PolicyProviderFactory {
|
public class JSPolicyProviderFactory implements PolicyProviderFactory<JSPolicyRepresentation> {
|
||||||
|
|
||||||
private JSPolicyProvider provider = new JSPolicyProvider(new Supplier<ScriptEngine>() {
|
private static final String ENGINE = "nashorn";
|
||||||
@Override
|
|
||||||
public ScriptEngine get() {
|
private JSPolicyProvider provider = new JSPolicyProvider(() -> new ScriptEngineManager().getEngineByName(ENGINE));
|
||||||
return new ScriptEngineManager().getEngineByName("nashorn");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -42,13 +39,40 @@ public class JSPolicyProviderFactory implements PolicyProviderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
|
public PolicyProvider create(KeycloakSession session) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PolicyProvider create(KeycloakSession session) {
|
public JSPolicyRepresentation toRepresentation(Policy policy, JSPolicyRepresentation representation) {
|
||||||
return null;
|
representation.setCode(policy.getConfig().get("code"));
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<JSPolicyRepresentation> getRepresentationType() {
|
||||||
|
return JSPolicyRepresentation.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Policy policy, JSPolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
|
updatePolicy(policy, representation.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(Policy policy, JSPolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
|
updatePolicy(policy, representation.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onImport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
|
updatePolicy(policy, representation.getConfig().get("code"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePolicy(Policy policy, String code) {
|
||||||
|
Map<String, String> config = policy.getConfig();
|
||||||
|
config.put("code", code);
|
||||||
|
policy.setConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,21 +33,20 @@ public class TimePolicyProvider implements PolicyProvider {
|
||||||
static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd hh:mm:ss";
|
static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd hh:mm:ss";
|
||||||
|
|
||||||
private final SimpleDateFormat dateFormat;
|
private final SimpleDateFormat dateFormat;
|
||||||
private final Date currentDate;
|
|
||||||
|
|
||||||
public TimePolicyProvider() {
|
public TimePolicyProvider() {
|
||||||
this.dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
|
this.dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
|
||||||
this.currentDate = new Date();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void evaluate(Evaluation evaluation) {
|
public void evaluate(Evaluation evaluation) {
|
||||||
Policy policy = evaluation.getPolicy();
|
Policy policy = evaluation.getPolicy();
|
||||||
|
Date actualDate = new Date();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String notBefore = policy.getConfig().get("nbf");
|
String notBefore = policy.getConfig().get("nbf");
|
||||||
if (notBefore != null && !"".equals(notBefore)) {
|
if (notBefore != null && !"".equals(notBefore)) {
|
||||||
if (this.currentDate.before(this.dateFormat.parse(format(notBefore)))) {
|
if (actualDate.before(this.dateFormat.parse(format(notBefore)))) {
|
||||||
evaluation.deny();
|
evaluation.deny();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -55,17 +54,17 @@ public class TimePolicyProvider implements PolicyProvider {
|
||||||
|
|
||||||
String notOnOrAfter = policy.getConfig().get("noa");
|
String notOnOrAfter = policy.getConfig().get("noa");
|
||||||
if (notOnOrAfter != null && !"".equals(notOnOrAfter)) {
|
if (notOnOrAfter != null && !"".equals(notOnOrAfter)) {
|
||||||
if (this.currentDate.after(this.dateFormat.parse(format(notOnOrAfter)))) {
|
if (actualDate.after(this.dateFormat.parse(format(notOnOrAfter)))) {
|
||||||
evaluation.deny();
|
evaluation.deny();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInvalid(Calendar.DAY_OF_MONTH, "dayMonth", policy)
|
if (isInvalid(actualDate, Calendar.DAY_OF_MONTH, "dayMonth", policy)
|
||||||
|| isInvalid(Calendar.MONTH, "month", policy)
|
|| isInvalid(actualDate, Calendar.MONTH, "month", policy)
|
||||||
|| isInvalid(Calendar.YEAR, "year", policy)
|
|| isInvalid(actualDate, Calendar.YEAR, "year", policy)
|
||||||
|| isInvalid(Calendar.HOUR_OF_DAY, "hour", policy)
|
|| isInvalid(actualDate, Calendar.HOUR_OF_DAY, "hour", policy)
|
||||||
|| isInvalid(Calendar.MINUTE, "minute", policy)) {
|
|| isInvalid(actualDate, Calendar.MINUTE, "minute", policy)) {
|
||||||
evaluation.deny();
|
evaluation.deny();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -76,10 +75,10 @@ public class TimePolicyProvider implements PolicyProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInvalid(int timeConstant, String configName, Policy policy) {
|
private boolean isInvalid(Date actualDate, int timeConstant, String configName, Policy policy) {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
|
||||||
calendar.setTime(this.currentDate);
|
calendar.setTime(actualDate);
|
||||||
|
|
||||||
int dateField = calendar.get(timeConstant);
|
int dateField = calendar.get(timeConstant);
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
package org.keycloak.authorization.policy.provider.time;
|
package org.keycloak.authorization.policy.provider.time;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.authorization.AuthorizationProvider;
|
import org.keycloak.authorization.AuthorizationProvider;
|
||||||
import org.keycloak.authorization.model.Policy;
|
import org.keycloak.authorization.model.Policy;
|
||||||
import org.keycloak.authorization.model.ResourceServer;
|
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
public class TimePolicyProviderFactory implements PolicyProviderFactory<PolicyRepresentation> {
|
public class TimePolicyProviderFactory implements PolicyProviderFactory<TimePolicyRepresentation> {
|
||||||
|
|
||||||
private TimePolicyProvider provider = new TimePolicyProvider();
|
private TimePolicyProvider provider = new TimePolicyProvider();
|
||||||
|
|
||||||
|
@ -35,46 +35,58 @@ public class TimePolicyProviderFactory implements PolicyProviderFactory<PolicyRe
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
|
|
||||||
return new TimePolicyAdminResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PolicyProvider create(KeycloakSession session) {
|
public PolicyProvider create(KeycloakSession session) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onCreate(Policy policy, TimePolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
validateConfig(policy);
|
updatePolicy(policy, representation);
|
||||||
}
|
|
||||||
|
|
||||||
private void validateConfig(Policy policy) {
|
|
||||||
String nbf = policy.getConfig().get("nbf");
|
|
||||||
String noa = policy.getConfig().get("noa");
|
|
||||||
|
|
||||||
if (nbf != null && noa != null) {
|
|
||||||
validateFormat(nbf);
|
|
||||||
validateFormat(noa);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onUpdate(Policy policy, TimePolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
validateConfig(policy);
|
updatePolicy(policy, representation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRemove(Policy policy, AuthorizationProvider authorization) {
|
public void onRemove(Policy policy, AuthorizationProvider authorization) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateFormat(String date) {
|
@Override
|
||||||
try {
|
public void onImport(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
new SimpleDateFormat(TimePolicyProvider.DEFAULT_DATE_PATTERN).parse(TimePolicyProvider.format(date));
|
policy.setConfig(representation.getConfig());
|
||||||
} catch (Exception e) {
|
}
|
||||||
throw new RuntimeException("Could not parse a date using format [" + date + "]");
|
|
||||||
}
|
@Override
|
||||||
|
public Class<TimePolicyRepresentation> getRepresentationType() {
|
||||||
|
return TimePolicyRepresentation.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePolicyRepresentation toRepresentation(Policy policy, TimePolicyRepresentation representation) {
|
||||||
|
Map<String, String> config = policy.getConfig();
|
||||||
|
|
||||||
|
representation.setDayMonth(config.get("dayMonth"));
|
||||||
|
representation.setDayMonthEnd(config.get("dayMonthEnd"));
|
||||||
|
|
||||||
|
representation.setMonth(config.get("month"));
|
||||||
|
representation.setMonthEnd(config.get("monthEnd"));
|
||||||
|
|
||||||
|
representation.setYear(config.get("year"));
|
||||||
|
representation.setYearEnd(config.get("yearEnd"));
|
||||||
|
|
||||||
|
representation.setHour(config.get("hour"));
|
||||||
|
representation.setHourEnd(config.get("hourEnd"));
|
||||||
|
|
||||||
|
representation.setMinute(config.get("minute"));
|
||||||
|
representation.setMinuteEnd(config.get("minuteEnd"));
|
||||||
|
|
||||||
|
representation.setNotBefore(config.get("nbf"));
|
||||||
|
representation.setNotOnOrAfter(config.get("noa"));
|
||||||
|
|
||||||
|
return representation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -96,4 +108,44 @@ public class TimePolicyProviderFactory implements PolicyProviderFactory<PolicyRe
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "time";
|
return "time";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updatePolicy(Policy policy, TimePolicyRepresentation representation) {
|
||||||
|
String nbf = representation.getNotBefore();
|
||||||
|
String noa = representation.getNotOnOrAfter();
|
||||||
|
|
||||||
|
if (nbf != null && noa != null) {
|
||||||
|
validateFormat(nbf);
|
||||||
|
validateFormat(noa);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> config = policy.getConfig();
|
||||||
|
|
||||||
|
config.compute("nbf", (s, s2) -> nbf != null ? nbf : null);
|
||||||
|
config.compute("noa", (s, s2) -> noa != null ? noa : null);
|
||||||
|
|
||||||
|
config.compute("dayMonth", (s, s2) -> representation.getDayMonth() != null ? representation.getDayMonth() : null);
|
||||||
|
config.compute("dayMonthEnd", (s, s2) -> representation.getDayMonthEnd() != null ? representation.getDayMonthEnd() : null);
|
||||||
|
|
||||||
|
config.compute("month", (s, s2) -> representation.getMonth() != null ? representation.getMonth() : null);
|
||||||
|
config.compute("monthEnd", (s, s2) -> representation.getMonthEnd() != null ? representation.getMonthEnd() : null);
|
||||||
|
|
||||||
|
config.compute("year", (s, s2) -> representation.getYear() != null ? representation.getYear() : null);
|
||||||
|
config.compute("yearEnd", (s, s2) -> representation.getYearEnd() != null ? representation.getYearEnd() : null);
|
||||||
|
|
||||||
|
config.compute("hour", (s, s2) -> representation.getHour() != null ? representation.getHour() : null);
|
||||||
|
config.compute("hourEnd", (s, s2) -> representation.getHourEnd() != null ? representation.getHourEnd() : null);
|
||||||
|
|
||||||
|
config.compute("minute", (s, s2) -> representation.getMinute() != null ? representation.getMinute() : null);
|
||||||
|
config.compute("minuteEnd", (s, s2) -> representation.getMinuteEnd() != null ? representation.getMinuteEnd() : null);
|
||||||
|
|
||||||
|
policy.setConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateFormat(String date) {
|
||||||
|
try {
|
||||||
|
new SimpleDateFormat(TimePolicyProvider.DEFAULT_DATE_PATTERN).parse(TimePolicyProvider.format(date));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Could not parse a date using format [" + date + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* JBoss, Home of Professional Open Source.
|
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||||
* Copyright 2016 Red Hat, Inc., and individual contributors
|
* and other contributors as indicated by the @author tags.
|
||||||
* as indicated by the @author tags.
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -15,14 +14,20 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
package org.keycloak.representations.idm.authorization;
|
||||||
package org.keycloak.authorization.policy.provider.time;
|
|
||||||
|
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
public class TimePolicyAdminResource implements PolicyProviderAdminService {
|
public class JSPolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* 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.representations.idm.authorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class TimePolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
|
private String notBefore;
|
||||||
|
private String notOnOrAfter;
|
||||||
|
private String dayMonth;
|
||||||
|
private String dayMonthEnd;
|
||||||
|
private String month;
|
||||||
|
private String monthEnd;
|
||||||
|
private String year;
|
||||||
|
private String yearEnd;
|
||||||
|
private String hour;
|
||||||
|
private String hourEnd;
|
||||||
|
private String minute;
|
||||||
|
private String minuteEnd;
|
||||||
|
|
||||||
|
public String getNotBefore() {
|
||||||
|
return notBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotBefore(String notBefore) {
|
||||||
|
this.notBefore = notBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotOnOrAfter() {
|
||||||
|
return notOnOrAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNotOnOrAfter(String notOnOrAfter) {
|
||||||
|
this.notOnOrAfter = notOnOrAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDayMonth() {
|
||||||
|
return dayMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDayMonth(String dayMonth) {
|
||||||
|
this.dayMonth = dayMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDayMonthEnd() {
|
||||||
|
return dayMonthEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDayMonthEnd(String dayMonthEnd) {
|
||||||
|
this.dayMonthEnd = dayMonthEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMonth() {
|
||||||
|
return month;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonth(String month) {
|
||||||
|
this.month = month;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMonthEnd() {
|
||||||
|
return monthEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMonthEnd(String monthEnd) {
|
||||||
|
this.monthEnd = monthEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getYear() {
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYear(String year) {
|
||||||
|
this.year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getYearEnd() {
|
||||||
|
return yearEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setYearEnd(String yearEnd) {
|
||||||
|
this.yearEnd = yearEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHour() {
|
||||||
|
return hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHour(String hour) {
|
||||||
|
this.hour = hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHourEnd() {
|
||||||
|
return hourEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHourEnd(String hourEnd) {
|
||||||
|
this.hourEnd = hourEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMinute() {
|
||||||
|
return minute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinute(String minute) {
|
||||||
|
this.minute = minute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMinuteEnd() {
|
||||||
|
return minuteEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinuteEnd(String minuteEnd) {
|
||||||
|
this.minuteEnd = minuteEnd;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.resource;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public interface JSPoliciesResource {
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
Response create(JSPolicyRepresentation representation);
|
||||||
|
|
||||||
|
@Path("{id}")
|
||||||
|
JSPolicyResource findById(@PathParam("id") String id);
|
||||||
|
|
||||||
|
@Path("/search")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
JSPolicyRepresentation findByName(@QueryParam("name") String name);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.resource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public interface JSPolicyResource {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
JSPolicyRepresentation toRepresentation();
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
void update(JSPolicyRepresentation representation);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
void remove();
|
||||||
|
|
||||||
|
@Path("/associatedPolicies")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
List<PolicyRepresentation> associatedPolicies();
|
||||||
|
|
||||||
|
@Path("/dependentPolicies")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
List<PolicyRepresentation> dependentPolicies();
|
||||||
|
|
||||||
|
@Path("/resources")
|
||||||
|
@GET
|
||||||
|
@Produces("application/json")
|
||||||
|
@NoCache
|
||||||
|
List<ResourceRepresentation> resources();
|
||||||
|
|
||||||
|
}
|
|
@ -74,4 +74,10 @@ public interface PoliciesResource {
|
||||||
|
|
||||||
@Path("user")
|
@Path("user")
|
||||||
UserPoliciesResource users();
|
UserPoliciesResource users();
|
||||||
|
|
||||||
|
@Path("js")
|
||||||
|
JSPoliciesResource js();
|
||||||
|
|
||||||
|
@Path("time")
|
||||||
|
TimePoliciesResource time();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.resource;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public interface TimePoliciesResource {
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
Response create(TimePolicyRepresentation representation);
|
||||||
|
|
||||||
|
@Path("{id}")
|
||||||
|
TimePolicyResource findById(@PathParam("id") String id);
|
||||||
|
|
||||||
|
@Path("/search")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
TimePolicyRepresentation findByName(@QueryParam("name") String name);
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.resource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public interface TimePolicyResource {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
TimePolicyRepresentation toRepresentation();
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
void update(TimePolicyRepresentation representation);
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
void remove();
|
||||||
|
|
||||||
|
@Path("/associatedPolicies")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
List<PolicyRepresentation> associatedPolicies();
|
||||||
|
|
||||||
|
@Path("/dependentPolicies")
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@NoCache
|
||||||
|
List<PolicyRepresentation> dependentPolicies();
|
||||||
|
|
||||||
|
@Path("/resources")
|
||||||
|
@GET
|
||||||
|
@Produces("application/json")
|
||||||
|
@NoCache
|
||||||
|
List<ResourceRepresentation> resources();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.JSPoliciesResource;
|
||||||
|
import org.keycloak.admin.client.resource.JSPolicyResource;
|
||||||
|
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class JSPolicyManagementTest extends AbstractPermissionManagementTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreate() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
JSPolicyRepresentation representation = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName("JS Policy");
|
||||||
|
representation.setDescription("description");
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.CONSENSUS);
|
||||||
|
representation.setLogic(Logic.NEGATIVE);
|
||||||
|
representation.setCode("$evaluation.grant();");
|
||||||
|
|
||||||
|
assertCreated(authorization, representation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
JSPolicyRepresentation representation = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName("Update JS Policy");
|
||||||
|
representation.setDescription("description");
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.CONSENSUS);
|
||||||
|
representation.setLogic(Logic.NEGATIVE);
|
||||||
|
representation.setCode("$evaluation.grant();");
|
||||||
|
|
||||||
|
assertCreated(authorization, representation);
|
||||||
|
|
||||||
|
representation.setName("changed");
|
||||||
|
representation.setDescription("changed");
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
|
||||||
|
representation.setLogic(Logic.POSITIVE);
|
||||||
|
representation.setCode("$evaluation.deny()");
|
||||||
|
|
||||||
|
JSPoliciesResource policies = authorization.policies().js();
|
||||||
|
JSPolicyResource permission = policies.findById(representation.getId());
|
||||||
|
|
||||||
|
permission.update(representation);
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelete() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
JSPolicyRepresentation representation = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName("Test Delete Policy");
|
||||||
|
representation.setCode("$evaluation.grant()");
|
||||||
|
|
||||||
|
JSPoliciesResource policies = authorization.policies().js();
|
||||||
|
Response response = policies.create(representation);
|
||||||
|
JSPolicyRepresentation created = response.readEntity(JSPolicyRepresentation.class);
|
||||||
|
|
||||||
|
policies.findById(created.getId()).remove();
|
||||||
|
|
||||||
|
JSPolicyResource removed = policies.findById(created.getId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
removed.toRepresentation();
|
||||||
|
fail("Permission not removed");
|
||||||
|
} catch (NotFoundException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCreated(AuthorizationResource authorization, JSPolicyRepresentation representation) {
|
||||||
|
JSPoliciesResource permissions = authorization.policies().js();
|
||||||
|
Response response = permissions.create(representation);
|
||||||
|
JSPolicyRepresentation created = response.readEntity(JSPolicyRepresentation.class);
|
||||||
|
JSPolicyResource permission = permissions.findById(created.getId());
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertRepresentation(JSPolicyRepresentation representation, JSPolicyResource permission) {
|
||||||
|
JSPolicyRepresentation actual = permission.toRepresentation();
|
||||||
|
assertRepresentation(representation, actual, () -> permission.resources(), () -> Collections.emptyList(), () -> permission.associatedPolicies());
|
||||||
|
assertEquals(representation.getCode(), actual.getCode());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* 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.admin.client.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.TimePoliciesResource;
|
||||||
|
import org.keycloak.admin.client.resource.TimePolicyResource;
|
||||||
|
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class TimePolicyManagementTest extends AbstractPermissionManagementTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreate() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
assertCreated(authorization, createRepresentation("Time Policy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
TimePolicyRepresentation representation = createRepresentation("Update Time Policy");
|
||||||
|
|
||||||
|
assertCreated(authorization, representation);
|
||||||
|
|
||||||
|
representation.setName("changed");
|
||||||
|
representation.setDescription("changed");
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
|
||||||
|
representation.setLogic(Logic.POSITIVE);
|
||||||
|
representation.setDayMonth("11");
|
||||||
|
representation.setDayMonthEnd("22");
|
||||||
|
representation.setMonth("7");
|
||||||
|
representation.setMonthEnd("9");
|
||||||
|
representation.setYear("2019");
|
||||||
|
representation.setYearEnd("2030");
|
||||||
|
representation.setHour("15");
|
||||||
|
representation.setHourEnd("23");
|
||||||
|
representation.setMinute("55");
|
||||||
|
representation.setMinuteEnd("58");
|
||||||
|
representation.setNotBefore("2019-01-01 00:00:00");
|
||||||
|
representation.setNotOnOrAfter("2019-02-03 00:00:00");
|
||||||
|
|
||||||
|
TimePoliciesResource policies = authorization.policies().time();
|
||||||
|
TimePolicyResource permission = policies.findById(representation.getId());
|
||||||
|
|
||||||
|
permission.update(representation);
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
|
||||||
|
representation.setDayMonth(null);
|
||||||
|
representation.setDayMonthEnd(null);
|
||||||
|
representation.setMonth(null);
|
||||||
|
representation.setMonthEnd(null);
|
||||||
|
representation.setYear(null);
|
||||||
|
representation.setYearEnd(null);
|
||||||
|
representation.setHour(null);
|
||||||
|
representation.setHourEnd(null);
|
||||||
|
representation.setMinute(null);
|
||||||
|
representation.setMinuteEnd(null);
|
||||||
|
representation.setNotBefore(null);
|
||||||
|
representation.setNotOnOrAfter("2019-02-03 00:00:00");
|
||||||
|
|
||||||
|
permission.update(representation);
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
|
||||||
|
representation.setNotOnOrAfter(null);
|
||||||
|
representation.setHour("2");
|
||||||
|
|
||||||
|
permission.update(representation);
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelete() {
|
||||||
|
AuthorizationResource authorization = getClient().authorization();
|
||||||
|
TimePolicyRepresentation representation = createRepresentation("Test Delete Policy");
|
||||||
|
TimePoliciesResource policies = authorization.policies().time();
|
||||||
|
Response response = policies.create(representation);
|
||||||
|
TimePolicyRepresentation created = response.readEntity(TimePolicyRepresentation.class);
|
||||||
|
|
||||||
|
policies.findById(created.getId()).remove();
|
||||||
|
|
||||||
|
TimePolicyResource removed = policies.findById(created.getId());
|
||||||
|
|
||||||
|
try {
|
||||||
|
removed.toRepresentation();
|
||||||
|
fail("Permission not removed");
|
||||||
|
} catch (NotFoundException ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimePolicyRepresentation createRepresentation(String name) {
|
||||||
|
TimePolicyRepresentation representation = new TimePolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(name);
|
||||||
|
representation.setDescription("description");
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.CONSENSUS);
|
||||||
|
representation.setLogic(Logic.NEGATIVE);
|
||||||
|
representation.setDayMonth("1");
|
||||||
|
representation.setDayMonthEnd("2");
|
||||||
|
representation.setMonth("3");
|
||||||
|
representation.setMonthEnd("4");
|
||||||
|
representation.setYear("5");
|
||||||
|
representation.setYearEnd("6");
|
||||||
|
representation.setHour("7");
|
||||||
|
representation.setHourEnd("8");
|
||||||
|
representation.setMinute("9");
|
||||||
|
representation.setMinuteEnd("10");
|
||||||
|
representation.setNotBefore("2017-01-01 00:00:00");
|
||||||
|
representation.setNotOnOrAfter("2017-02-01 00:00:00");
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertCreated(AuthorizationResource authorization, TimePolicyRepresentation representation) {
|
||||||
|
TimePoliciesResource permissions = authorization.policies().time();
|
||||||
|
Response response = permissions.create(representation);
|
||||||
|
TimePolicyRepresentation created = response.readEntity(TimePolicyRepresentation.class);
|
||||||
|
TimePolicyResource permission = permissions.findById(created.getId());
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertRepresentation(TimePolicyRepresentation representation, TimePolicyResource permission) {
|
||||||
|
TimePolicyRepresentation actual = permission.toRepresentation();
|
||||||
|
assertRepresentation(representation, actual, () -> permission.resources(), () -> Collections.emptyList(), () -> permission.associatedPolicies());
|
||||||
|
assertEquals(representation.getDayMonth(), actual.getDayMonth());
|
||||||
|
assertEquals(representation.getDayMonthEnd(), actual.getDayMonthEnd());
|
||||||
|
assertEquals(representation.getMonth(), actual.getMonth());
|
||||||
|
assertEquals(representation.getMonthEnd(), actual.getMonthEnd());
|
||||||
|
assertEquals(representation.getYear(), actual.getYear());
|
||||||
|
assertEquals(representation.getYearEnd(), actual.getYearEnd());
|
||||||
|
assertEquals(representation.getHour(), actual.getHour());
|
||||||
|
assertEquals(representation.getHourEnd(), actual.getHourEnd());
|
||||||
|
assertEquals(representation.getMinute(), actual.getMinute());
|
||||||
|
assertEquals(representation.getMinuteEnd(), actual.getMinuteEnd());
|
||||||
|
assertEquals(representation.getNotBefore(), actual.getNotBefore());
|
||||||
|
assertEquals(representation.getNotOnOrAfter(), actual.getNotOnOrAfter());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1636,7 +1636,6 @@ module.controller('ResourceServerPolicyJSDetailCtrl', function($scope, $route, $
|
||||||
$scope.initEditor = function(editor){
|
$scope.initEditor = function(editor){
|
||||||
editor.$blockScrolling = Infinity;
|
editor.$blockScrolling = Infinity;
|
||||||
var session = editor.getSession();
|
var session = editor.getSession();
|
||||||
|
|
||||||
session.setMode('ace/mode/javascript');
|
session.setMode('ace/mode/javascript');
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -1646,15 +1645,14 @@ module.controller('ResourceServerPolicyJSDetailCtrl', function($scope, $route, $
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdate : function() {
|
onUpdate : function() {
|
||||||
|
delete $scope.policy.config;
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitCreate : function(newPolicy) {
|
onInitCreate : function(newPolicy) {
|
||||||
newPolicy.config = {};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreate : function() {
|
onCreate : function() {
|
||||||
|
delete $scope.policy.config;
|
||||||
}
|
}
|
||||||
}, realm, client, $scope);
|
}, realm, client, $scope);
|
||||||
});
|
});
|
||||||
|
@ -1669,60 +1667,63 @@ module.controller('ResourceServerPolicyTimeDetailCtrl', function($scope, $route,
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitUpdate : function(policy) {
|
onInitUpdate : function(policy) {
|
||||||
if (policy.config.dayMonth) {
|
if (policy.dayMonth) {
|
||||||
policy.config.dayMonth = parseInt(policy.config.dayMonth);
|
policy.dayMonth = parseInt(policy.dayMonth);
|
||||||
}
|
}
|
||||||
if (policy.config.dayMonthEnd) {
|
if (policy.dayMonthEnd) {
|
||||||
policy.config.dayMonthEnd = parseInt(policy.config.dayMonthEnd);
|
policy.dayMonthEnd = parseInt(policy.dayMonthEnd);
|
||||||
}
|
}
|
||||||
if (policy.config.month) {
|
if (policy.month) {
|
||||||
policy.config.month = parseInt(policy.config.month);
|
policy.month = parseInt(policy.month);
|
||||||
}
|
}
|
||||||
if (policy.config.monthEnd) {
|
if (policy.monthEnd) {
|
||||||
policy.config.monthEnd = parseInt(policy.config.monthEnd);
|
policy.monthEnd = parseInt(policy.monthEnd);
|
||||||
}
|
}
|
||||||
if (policy.config.year) {
|
if (policy.year) {
|
||||||
policy.config.year = parseInt(policy.config.year);
|
policy.year = parseInt(policy.year);
|
||||||
}
|
}
|
||||||
if (policy.config.yearEnd) {
|
if (policy.yearEnd) {
|
||||||
policy.config.yearEnd = parseInt(policy.config.yearEnd);
|
policy.yearEnd = parseInt(policy.yearEnd);
|
||||||
}
|
}
|
||||||
if (policy.config.hour) {
|
if (policy.hour) {
|
||||||
policy.config.hour = parseInt(policy.config.hour);
|
policy.hour = parseInt(policy.hour);
|
||||||
}
|
}
|
||||||
if (policy.config.hourEnd) {
|
if (policy.hourEnd) {
|
||||||
policy.config.hourEnd = parseInt(policy.config.hourEnd);
|
policy.hourEnd = parseInt(policy.hourEnd);
|
||||||
}
|
}
|
||||||
if (policy.config.minute) {
|
if (policy.minute) {
|
||||||
policy.config.minute = parseInt(policy.config.minute);
|
policy.minute = parseInt(policy.minute);
|
||||||
}
|
}
|
||||||
if (policy.config.minuteEnd) {
|
if (policy.minuteEnd) {
|
||||||
policy.config.minuteEnd = parseInt(policy.config.minuteEnd);
|
policy.minuteEnd = parseInt(policy.minuteEnd);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onUpdate : function() {
|
onUpdate : function() {
|
||||||
|
delete $scope.policy.config;
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitCreate : function(newPolicy) {
|
onInitCreate : function(newPolicy) {
|
||||||
newPolicy.config.expirationTime = 1;
|
|
||||||
newPolicy.config.expirationUnit = 'Minutes';
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onCreate : function() {
|
onCreate : function() {
|
||||||
|
delete $scope.policy.config;
|
||||||
}
|
}
|
||||||
}, realm, client, $scope);
|
}, realm, client, $scope);
|
||||||
|
|
||||||
$scope.isRequired = function () {
|
$scope.isRequired = function () {
|
||||||
var policy = $scope.policy;
|
var policy = $scope.policy;
|
||||||
if (policy.config.noa || policy.config.nbf
|
|
||||||
|| policy.config.dayMonth
|
if (!policy) {
|
||||||
|| policy.config.month
|
return true;
|
||||||
|| policy.config.year
|
}
|
||||||
|| policy.config.hour
|
|
||||||
|| policy.config.minute) {
|
if (policy.notOnOrAfter || policy.notBefore
|
||||||
|
|| policy.dayMonth
|
||||||
|
|| policy.month
|
||||||
|
|| policy.year
|
||||||
|
|| policy.hour
|
||||||
|
|| policy.minute) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="description">{{:: 'authz-policy-js-code' | translate}} </label>
|
<label class="col-md-2 control-label" for="description">{{:: 'authz-policy-js-code' | translate}} </label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div ui-ace="{ onLoad : initEditor }" data-ng-model="policy.config.code"></div>
|
<div ui-ace="{ onLoad : initEditor }" data-ng-model="policy.code"></div>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-js-code.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-js-code.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,58 +34,58 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.nbf">{{:: 'not-before' | translate}}</label>
|
<label class="col-md-2 control-label" for="policy.notBefore">{{:: 'not-before' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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" data-ng-required="isRequired()">
|
<input class="form-control" style="width: 150px" type="text" id="policy.notBefore" name="notBefore" data-ng-model="policy.notBefore" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-not-on-after' | translate}}</label>
|
<label class="col-md-2 control-label" for="policy.notOnOrAfter">{{:: 'authz-policy-time-not-on-after' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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" data-ng-required="isRequired()">
|
<input class="form-control" style="width: 150px" type="text" id="policy.notOnOrAfter" name="policy.notOnOrAfter" data-ng-model="policy.notOnOrAfter" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-day-month' | translate}}</label>
|
<label class="col-md-2 control-label" for="dayMonth">{{:: 'authz-policy-time-day-month' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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"/>
|
<input class="form-control" type="number" min="1" max="31" data-ng-model="policy.dayMonth" id="dayMonth" name="dayMonth" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.dayMonth}}" max="31" data-ng-model="policy.dayMonthEnd" id="dayMonthEnd" name="dayMonthEnd"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-day-month.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-day-month.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-month' | translate}}</label>
|
<label class="col-md-2 control-label" for="month">{{:: 'authz-policy-time-month' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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"/>
|
<input class="form-control" type="number" min="1" max="12" data-ng-model="policy.month" id="month" name="month" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.month}}" max="12" data-ng-model="policy.monthEnd" id="monthEnd" name="monthEnd"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-month.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-month.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-year' | translate}}</label>
|
<label class="col-md-2 control-label" for="year">{{:: 'authz-policy-time-year' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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"/>
|
<input class="form-control" type="number" data-ng-model="policy.year" id="year" name="year" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.year}}" max="2050" data-ng-model="policy.yearEnd" id="yearEnd" name="yearEnd"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-year.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-year.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-hour' | translate}}</label>
|
<label class="col-md-2 control-label" for="hour">{{:: 'authz-policy-time-hour' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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"/>
|
<input class="form-control" type="number" min="0" max="23" data-ng-model="policy.hour" id="hour" name="hour" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.hour}}" max="23" data-ng-model="policy.hourEnd" id="hourEnd" name="hourEnd"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-hour.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-hour.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.config.noa">{{:: 'authz-policy-time-minute' | translate}}</label>
|
<label class="col-md-2 control-label" for="minute">{{:: 'authz-policy-time-minute' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<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"/>
|
<input class="form-control" type="number" min="0" max="59" data-ng-model="policy.minute" id="minute" name="minute" data-ng-required="isRequired()"/> to <input class="form-control" type="number" min="{{policy.minute}}" max="59" data-ng-model="policy.minuteEnd" id="minuteEnd" name="minuteEnd"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue