mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 05:07:41 +00:00
GUACAMOLE-1701: Implement connection date and time before and after restrictions.
This commit is contained in:
@@ -27,6 +27,65 @@ import org.apache.guacamole.net.auth.Attributes;
|
|||||||
*/
|
*/
|
||||||
public interface Restrictable extends Attributes {
|
public interface Restrictable extends Attributes {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains the absolute date and time after
|
||||||
|
* which this restrictable object may be used. If this attribute is present
|
||||||
|
* access to to this object will be denied at any time prior to the parsed
|
||||||
|
* value of this attribute, regardless of what other restrictions may be
|
||||||
|
* present to allow access to the object at certain days/times of the week
|
||||||
|
* or from certain hosts.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_TIME_AFTER_ATTRIBUTE_NAME = "guac-restrict-time-after";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains a list of weekdays and times (UTC)
|
||||||
|
* that this restrictable object can be used. The presence of values within
|
||||||
|
* this attribute will automatically restrict use of the object at any times
|
||||||
|
* that are not specified.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-time-allowed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains the absolute date and time before
|
||||||
|
* which use of this restrictable object may be used. If this attribute is
|
||||||
|
* present use of the object will be denied at any time after the parsed
|
||||||
|
* value of this attribute, regardless of the presence of other restrictions
|
||||||
|
* that may allow access at certain days/times of the week or from certain
|
||||||
|
* hosts.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME = "guac-restrict-time-before";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains a list of weekdays and times (UTC)
|
||||||
|
* that this restrictable object cannot be used. Denied times will always take
|
||||||
|
* precedence over allowed times. The presence of this attribute without
|
||||||
|
* guac-restrict-time-allowed will deny access only during the times listed
|
||||||
|
* in this attribute, allowing access at all other times. The presence of
|
||||||
|
* this attribute along with the guac-restrict-time-allowed attribute will
|
||||||
|
* deny access at any times that overlap with the allowed times.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_TIME_DENIED_ATTRIBUTE_NAME = "guac-restrict-time-denied";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains a list of hosts from which this
|
||||||
|
* restrictable object may be used. The presence of this attribute will
|
||||||
|
* restrict use to only users accessing Guacamole from the list of hosts
|
||||||
|
* contained in the attribute, subject to further restriction by the
|
||||||
|
* guac-restrict-hosts-denied attribute.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-hosts-allowed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the attribute that contains a list of hosts from which this
|
||||||
|
* restrictable object may not be used. The presence of this attribute,
|
||||||
|
* absent the guac-restrict-hosts-allowed attribute, will allow use from
|
||||||
|
* all hosts except the ones listed in this attribute. The presence of this
|
||||||
|
* attribute coupled with the guac-restrict-hosts-allowed attribute will
|
||||||
|
* block access from any IPs in this list, overriding any that may be
|
||||||
|
* allowed.
|
||||||
|
*/
|
||||||
|
public static final String RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME = "guac-restrict-hosts-denied";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the restriction state for this restrictable object at the
|
* Return the restriction state for this restrictable object at the
|
||||||
* current date and time. By default returns an implicit denial.
|
* current date and time. By default returns an implicit denial.
|
||||||
|
@@ -23,14 +23,14 @@ import inet.ipaddr.HostName;
|
|||||||
import inet.ipaddr.HostNameException;
|
import inet.ipaddr.HostNameException;
|
||||||
import inet.ipaddr.IPAddress;
|
import inet.ipaddr.IPAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.auth.restrict.connection.RestrictedConnection;
|
import org.apache.guacamole.auth.restrict.form.DateTimeRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.user.RestrictedUser;
|
|
||||||
import org.apache.guacamole.auth.restrict.usergroup.RestrictedUserGroup;
|
|
||||||
import org.apache.guacamole.calendar.DailyRestriction;
|
import org.apache.guacamole.calendar.DailyRestriction;
|
||||||
import org.apache.guacamole.calendar.RestrictionType;
|
import org.apache.guacamole.calendar.RestrictionType;
|
||||||
import org.apache.guacamole.calendar.TimeRestrictionParser;
|
import org.apache.guacamole.calendar.TimeRestrictionParser;
|
||||||
@@ -54,6 +54,67 @@ public class RestrictionVerificationService {
|
|||||||
*/
|
*/
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RestrictionVerificationService.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(RestrictionVerificationService.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the provided strings of an absolute date after which an action is
|
||||||
|
* valid and before which an action is valid, parse the strings into Date
|
||||||
|
* objects and determine if the current date and time falls within the
|
||||||
|
* provided window, returning the appropriate restriction type.
|
||||||
|
*
|
||||||
|
* @param afterTimeString
|
||||||
|
* The string that has the date and time value after which the activity
|
||||||
|
* is allowed.
|
||||||
|
*
|
||||||
|
* @param beforeTimeString
|
||||||
|
* The string that has the date and time value before which the activity
|
||||||
|
* is allowed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The RestrictionType that represents the allowed or denied state of
|
||||||
|
* the activity.
|
||||||
|
*/
|
||||||
|
private static RestrictionType allowedByDateTimeRestrictions(
|
||||||
|
String afterTimeString, String beforeTimeString) {
|
||||||
|
|
||||||
|
// Set a default restriction.
|
||||||
|
RestrictionType dateTimeRestriction = RestrictionType.IMPLICIT_ALLOW;
|
||||||
|
|
||||||
|
// Check the after string and make sure that now is after that date.
|
||||||
|
if (afterTimeString != null && !afterTimeString.isEmpty()) {
|
||||||
|
Date now = new Date();
|
||||||
|
try {
|
||||||
|
Date afterTime = DateTimeRestrictionField.parse(afterTimeString);
|
||||||
|
if (now.before(afterTime))
|
||||||
|
return RestrictionType.EXPLICIT_DENY;
|
||||||
|
}
|
||||||
|
catch (ParseException e) {
|
||||||
|
LOGGER.warn("Failed to parse date and time string: {}:", e.getMessage());
|
||||||
|
LOGGER.debug("Parse exception while parsing date and time string.", e);
|
||||||
|
return RestrictionType.IMPLICIT_DENY;
|
||||||
|
}
|
||||||
|
dateTimeRestriction = RestrictionType.EXPLICIT_ALLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the before string and make sure that now is prior to that date.
|
||||||
|
if (beforeTimeString != null && !beforeTimeString.isEmpty()) {
|
||||||
|
Date now = new Date();
|
||||||
|
try {
|
||||||
|
Date beforeTime = DateTimeRestrictionField.parse(beforeTimeString);
|
||||||
|
if (now.after(beforeTime))
|
||||||
|
return RestrictionType.EXPLICIT_DENY;
|
||||||
|
}
|
||||||
|
catch (ParseException e) {
|
||||||
|
LOGGER.warn("Failed to parse date and time string: {}:", e.getMessage());
|
||||||
|
LOGGER.debug("Parse exception while parsing date and time string.", e);
|
||||||
|
return RestrictionType.IMPLICIT_DENY;
|
||||||
|
}
|
||||||
|
dateTimeRestriction = RestrictionType.EXPLICIT_ALLOW;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the determined RestrictionType for the given date/time strings.
|
||||||
|
return dateTimeRestriction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse out the provided strings of allowed and denied times, verifying
|
* Parse out the provided strings of allowed and denied times, verifying
|
||||||
* whether or not a login or connection should be allowed at the current
|
* whether or not a login or connection should be allowed at the current
|
||||||
@@ -251,8 +312,8 @@ public class RestrictionVerificationService {
|
|||||||
Map<String, String> userAttributes = currentUser.getAttributes();
|
Map<String, String> userAttributes = currentUser.getAttributes();
|
||||||
|
|
||||||
// Verify host-based restrictions specific to the user
|
// Verify host-based restrictions specific to the user
|
||||||
String allowedHostString = userAttributes.get(RestrictedUser.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
String allowedHostString = userAttributes.get(Restrictable.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String deniedHostString = userAttributes.get(RestrictedUser.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
String deniedHostString = userAttributes.get(Restrictable.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType hostRestrictionResult = allowedByHostRestrictions(allowedHostString, deniedHostString, remoteAddress);
|
RestrictionType hostRestrictionResult = allowedByHostRestrictions(allowedHostString, deniedHostString, remoteAddress);
|
||||||
|
|
||||||
switch (hostRestrictionResult) {
|
switch (hostRestrictionResult) {
|
||||||
@@ -284,8 +345,8 @@ public class RestrictionVerificationService {
|
|||||||
Map<String, String> grpAttributes = userGroup.getAttributes();
|
Map<String, String> grpAttributes = userGroup.getAttributes();
|
||||||
|
|
||||||
// Pull host-based restrictions for this group and verify
|
// Pull host-based restrictions for this group and verify
|
||||||
String grpAllowedHostString = grpAttributes.get(RestrictedUserGroup.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
String grpAllowedHostString = grpAttributes.get(Restrictable.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String grpDeniedHostString = grpAttributes.get(RestrictedUserGroup.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
String grpDeniedHostString = grpAttributes.get(Restrictable.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType grpRestrictionResult = allowedByHostRestrictions(grpAllowedHostString, grpDeniedHostString, remoteAddress);
|
RestrictionType grpRestrictionResult = allowedByHostRestrictions(grpAllowedHostString, grpDeniedHostString, remoteAddress);
|
||||||
|
|
||||||
// Any explicit denials are thrown immediately
|
// Any explicit denials are thrown immediately
|
||||||
@@ -344,8 +405,8 @@ public class RestrictionVerificationService {
|
|||||||
String remoteAddress) throws GuacamoleException {
|
String remoteAddress) throws GuacamoleException {
|
||||||
|
|
||||||
// Verify time-based restrictions specific to this connection.
|
// Verify time-based restrictions specific to this connection.
|
||||||
String allowedHostsString = restrictable.getAttributes().get(RestrictedConnection.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
String allowedHostsString = restrictable.getAttributes().get(Restrictable.RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String deniedHostsString = restrictable.getAttributes().get(RestrictedConnection.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
String deniedHostsString = restrictable.getAttributes().get(Restrictable.RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType hostRestrictionResult = allowedByHostRestrictions(allowedHostsString, deniedHostsString, remoteAddress);
|
RestrictionType hostRestrictionResult = allowedByHostRestrictions(allowedHostsString, deniedHostsString, remoteAddress);
|
||||||
|
|
||||||
// If the host is not allowed
|
// If the host is not allowed
|
||||||
@@ -393,8 +454,8 @@ public class RestrictionVerificationService {
|
|||||||
Map<String, String> userAttributes = currentUser.getAttributes();
|
Map<String, String> userAttributes = currentUser.getAttributes();
|
||||||
|
|
||||||
// Verify time-based restrictions specific to the user
|
// Verify time-based restrictions specific to the user
|
||||||
String allowedTimeString = userAttributes.get(RestrictedUser.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
String allowedTimeString = userAttributes.get(Restrictable.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String deniedTimeString = userAttributes.get(RestrictedUser.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
String deniedTimeString = userAttributes.get(Restrictable.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType timeRestrictionResult = allowedByTimeRestrictions(allowedTimeString, deniedTimeString);
|
RestrictionType timeRestrictionResult = allowedByTimeRestrictions(allowedTimeString, deniedTimeString);
|
||||||
|
|
||||||
// Check the time restriction for explicit results.
|
// Check the time restriction for explicit results.
|
||||||
@@ -426,8 +487,8 @@ public class RestrictionVerificationService {
|
|||||||
Map<String, String> grpAttributes = userGroup.getAttributes();
|
Map<String, String> grpAttributes = userGroup.getAttributes();
|
||||||
|
|
||||||
// Pull time-based restrictions for this group and verify
|
// Pull time-based restrictions for this group and verify
|
||||||
String grpAllowedTimeString = grpAttributes.get(RestrictedUserGroup.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
String grpAllowedTimeString = grpAttributes.get(Restrictable.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String grpDeniedTimeString = grpAttributes.get(RestrictedUserGroup.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
String grpDeniedTimeString = grpAttributes.get(Restrictable.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType grpRestrictionResult = allowedByTimeRestrictions(grpAllowedTimeString, grpDeniedTimeString);
|
RestrictionType grpRestrictionResult = allowedByTimeRestrictions(grpAllowedTimeString, grpDeniedTimeString);
|
||||||
|
|
||||||
// An explicit deny results in immediate denial of the login.
|
// An explicit deny results in immediate denial of the login.
|
||||||
@@ -463,6 +524,18 @@ public class RestrictionVerificationService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void verifyDateTimeRestrictions(Restrictable restrictable) throws GuacamoleException {
|
||||||
|
|
||||||
|
String afterTimeString = restrictable.getAttributes().get(Restrictable.RESTRICT_TIME_AFTER_ATTRIBUTE_NAME);
|
||||||
|
String beforeTimeString = restrictable.getAttributes().get(Restrictable.RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME);
|
||||||
|
RestrictionType dateRestriction = allowedByDateTimeRestrictions(afterTimeString, beforeTimeString);
|
||||||
|
if (!dateRestriction.isAllowed())
|
||||||
|
throw new TranslatableGuacamoleSecurityException(
|
||||||
|
"Use of this connection or connection group is not allowed at this time.",
|
||||||
|
"RESTRICT.ERROR_CONNECTION_NOT_ALLOWED_NOW"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the time restrictions for the given Connection object, throwing
|
* Verify the time restrictions for the given Connection object, throwing
|
||||||
* an exception if the connection should not be allowed, or silently
|
* an exception if the connection should not be allowed, or silently
|
||||||
@@ -478,8 +551,8 @@ public class RestrictionVerificationService {
|
|||||||
public static void verifyTimeRestrictions(Restrictable restrictable) throws GuacamoleException {
|
public static void verifyTimeRestrictions(Restrictable restrictable) throws GuacamoleException {
|
||||||
|
|
||||||
// Verify time-based restrictions specific to this connection.
|
// Verify time-based restrictions specific to this connection.
|
||||||
String allowedTimeString = restrictable.getAttributes().get(RestrictedConnection.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
String allowedTimeString = restrictable.getAttributes().get(Restrictable.RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME);
|
||||||
String deniedTimeString = restrictable.getAttributes().get(RestrictedConnection.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
String deniedTimeString = restrictable.getAttributes().get(Restrictable.RESTRICT_TIME_DENIED_ATTRIBUTE_NAME);
|
||||||
RestrictionType timeRestriction = allowedByTimeRestrictions(allowedTimeString, deniedTimeString);
|
RestrictionType timeRestriction = allowedByTimeRestrictions(allowedTimeString, deniedTimeString);
|
||||||
if (!timeRestriction.isAllowed())
|
if (!timeRestriction.isAllowed())
|
||||||
throw new TranslatableGuacamoleSecurityException(
|
throw new TranslatableGuacamoleSecurityException(
|
||||||
@@ -536,6 +609,7 @@ public class RestrictionVerificationService {
|
|||||||
*/
|
*/
|
||||||
public static void verifyConnectionRestrictions(Restrictable restrictable,
|
public static void verifyConnectionRestrictions(Restrictable restrictable,
|
||||||
String remoteAddress) throws GuacamoleException {
|
String remoteAddress) throws GuacamoleException {
|
||||||
|
verifyDateTimeRestrictions(restrictable);
|
||||||
verifyTimeRestrictions(restrictable);
|
verifyTimeRestrictions(restrictable);
|
||||||
verifyHostRestrictions(restrictable, remoteAddress);
|
verifyHostRestrictions(restrictable, remoteAddress);
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.auth.restrict.Restrictable;
|
import org.apache.guacamole.auth.restrict.Restrictable;
|
||||||
import org.apache.guacamole.auth.restrict.RestrictionVerificationService;
|
import org.apache.guacamole.auth.restrict.RestrictionVerificationService;
|
||||||
|
import org.apache.guacamole.auth.restrict.form.DateTimeRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
||||||
import org.apache.guacamole.calendar.RestrictionType;
|
import org.apache.guacamole.calendar.RestrictionType;
|
||||||
@@ -46,49 +47,12 @@ public class RestrictedConnection extends DelegatingConnection implements Restri
|
|||||||
*/
|
*/
|
||||||
private final String remoteAddress;
|
private final String remoteAddress;
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that this connection can be accessed. The presence of values within this
|
|
||||||
* attribute will automatically restrict use of the connections at any
|
|
||||||
* times that are not specified.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-time-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that this connection cannot be accessed. Denied times will always take
|
|
||||||
* precedence over allowed times. The presence of this attribute without
|
|
||||||
* guac-restrict-time-allowed will deny access only during the times listed
|
|
||||||
* in this attribute, allowing access at all other times. The presence of
|
|
||||||
* this attribute along with the guac-restrict-time-allowed attribute will
|
|
||||||
* deny access at any times that overlap with the allowed times.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_DENIED_ATTRIBUTE_NAME = "guac-restrict-time-denied";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of hosts from which a user
|
|
||||||
* may access this connection. The presence of this attribute will restrict
|
|
||||||
* access to only users accessing Guacamole from the list of hosts contained
|
|
||||||
* in the attribute, subject to further restriction by the
|
|
||||||
* guac-restrict-hosts-denied attribute.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-hosts-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of hosts from which
|
|
||||||
* a user may not access this connection. The presence of this attribute,
|
|
||||||
* absent the guac-restrict-hosts-allowed attribute, will allow access from
|
|
||||||
* all hosts except the ones listed in this attribute. The presence of this
|
|
||||||
* attribute coupled with the guac-restrict-hosts-allowed attribute will
|
|
||||||
* block access from any IPs in this list, overriding any that may be
|
|
||||||
* allowed.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME = "guac-restrict-hosts-denied";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all connection attributes provided by this Connection implementation.
|
* The list of all connection attributes provided by this Connection implementation.
|
||||||
*/
|
*/
|
||||||
public static final List<String> RESTRICT_CONNECTION_ATTRIBUTES = Arrays.asList(
|
public static final List<String> RESTRICT_CONNECTION_ATTRIBUTES = Arrays.asList(
|
||||||
|
RESTRICT_TIME_AFTER_ATTRIBUTE_NAME,
|
||||||
|
RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME,
|
||||||
RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME,
|
RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME,
|
||||||
RESTRICT_TIME_DENIED_ATTRIBUTE_NAME,
|
RESTRICT_TIME_DENIED_ATTRIBUTE_NAME,
|
||||||
RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME,
|
RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME,
|
||||||
@@ -101,6 +65,8 @@ public class RestrictedConnection extends DelegatingConnection implements Restri
|
|||||||
*/
|
*/
|
||||||
public static final Form RESTRICT_CONNECTION_FORM = new Form("restrict-login-form",
|
public static final Form RESTRICT_CONNECTION_FORM = new Form("restrict-login-form",
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
|
new DateTimeRestrictionField(RESTRICT_TIME_AFTER_ATTRIBUTE_NAME),
|
||||||
|
new DateTimeRestrictionField(RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME),
|
||||||
new TimeRestrictionField(RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME),
|
new TimeRestrictionField(RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME),
|
||||||
new TimeRestrictionField(RESTRICT_TIME_DENIED_ATTRIBUTE_NAME),
|
new TimeRestrictionField(RESTRICT_TIME_DENIED_ATTRIBUTE_NAME),
|
||||||
new HostRestrictionField(RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME),
|
new HostRestrictionField(RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME),
|
||||||
|
@@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
import org.apache.guacamole.auth.restrict.Restrictable;
|
import org.apache.guacamole.auth.restrict.Restrictable;
|
||||||
import org.apache.guacamole.auth.restrict.RestrictionVerificationService;
|
import org.apache.guacamole.auth.restrict.RestrictionVerificationService;
|
||||||
|
import org.apache.guacamole.auth.restrict.form.DateTimeRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
||||||
import org.apache.guacamole.calendar.RestrictionType;
|
import org.apache.guacamole.calendar.RestrictionType;
|
||||||
@@ -46,50 +47,13 @@ public class RestrictedConnectionGroup extends DelegatingConnectionGroup impleme
|
|||||||
*/
|
*/
|
||||||
private final String remoteAddress;
|
private final String remoteAddress;
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that this connection group can be accessed. The presence of values within
|
|
||||||
* this attribute will automatically restrict use of the connection group
|
|
||||||
* at any times that are not specified.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-time-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that this connection group cannot be accessed. Denied times will always
|
|
||||||
* take precedence over allowed times. The presence of this attribute without
|
|
||||||
* guac-restrict-time-allowed will deny access only during the times listed
|
|
||||||
* in this attribute, allowing access at all other times. The presence of
|
|
||||||
* this attribute along with the guac-restrict-time-allowed attribute will
|
|
||||||
* deny access at any times that overlap with the allowed times.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_DENIED_ATTRIBUTE_NAME = "guac-restrict-time-denied";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of hosts from which a user
|
|
||||||
* may access this connection group. The presence of this attribute will
|
|
||||||
* restrict access to only users accessing Guacamole from the list of hosts
|
|
||||||
* contained in the attribute, subject to further restriction by the
|
|
||||||
* guac-restrict-hosts-denied attribute.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-hosts-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of hosts from which
|
|
||||||
* a user may not access this connection group. The presence of this
|
|
||||||
* attribute, absent the guac-restrict-hosts-allowed attribute, will allow
|
|
||||||
* access from all hosts except the ones listed in this attribute. The
|
|
||||||
* presence of this attribute coupled with the guac-restrict-hosts-allowed
|
|
||||||
* attribute will block access from any hosts in this list, overriding any
|
|
||||||
* that may be allowed.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME = "guac-restrict-hosts-denied";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all connection group attributes provided by this
|
* The list of all connection group attributes provided by this
|
||||||
* ConnectionGroup implementation.
|
* ConnectionGroup implementation.
|
||||||
*/
|
*/
|
||||||
public static final List<String> RESTRICT_CONNECTIONGROUP_ATTRIBUTES = Arrays.asList(
|
public static final List<String> RESTRICT_CONNECTIONGROUP_ATTRIBUTES = Arrays.asList(
|
||||||
|
RESTRICT_TIME_AFTER_ATTRIBUTE_NAME,
|
||||||
|
RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME,
|
||||||
RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME,
|
RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME,
|
||||||
RESTRICT_TIME_DENIED_ATTRIBUTE_NAME,
|
RESTRICT_TIME_DENIED_ATTRIBUTE_NAME,
|
||||||
RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME,
|
RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME,
|
||||||
@@ -102,6 +66,8 @@ public class RestrictedConnectionGroup extends DelegatingConnectionGroup impleme
|
|||||||
*/
|
*/
|
||||||
public static final Form RESTRICT_CONNECTIONGROUP_FORM = new Form("restrict-login-form",
|
public static final Form RESTRICT_CONNECTIONGROUP_FORM = new Form("restrict-login-form",
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
|
new DateTimeRestrictionField(RESTRICT_TIME_AFTER_ATTRIBUTE_NAME),
|
||||||
|
new DateTimeRestrictionField(RESTRICT_TIME_BEFORE_ATTRIBUTE_NAME),
|
||||||
new TimeRestrictionField(RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME),
|
new TimeRestrictionField(RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME),
|
||||||
new TimeRestrictionField(RESTRICT_TIME_DENIED_ATTRIBUTE_NAME),
|
new TimeRestrictionField(RESTRICT_TIME_DENIED_ATTRIBUTE_NAME),
|
||||||
new HostRestrictionField(RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME),
|
new HostRestrictionField(RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME),
|
||||||
|
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.apache.guacamole.auth.restrict.form;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import org.apache.guacamole.form.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A field that parses a string containing an absolute date and time value.
|
||||||
|
*/
|
||||||
|
public class DateTimeRestrictionField extends Field {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field type.
|
||||||
|
*/
|
||||||
|
public static final String FIELD_TYPE = "GUAC_DATETIME_RESTRICTION";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The format of the data for this field as it will be stored in the
|
||||||
|
* underlying storage mechanism.
|
||||||
|
*/
|
||||||
|
public static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new field that tracks time restrictions.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the parameter that will be used to pass this field
|
||||||
|
* between the REST API and the web front-end.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DateTimeRestrictionField(String name) {
|
||||||
|
super(name, FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given date into a string which follows the format used by
|
||||||
|
* date fields.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* The date value to format, which may be null.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The formatted date, or null if the provided time was null.
|
||||||
|
*/
|
||||||
|
public static String format(Date date) {
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat(DateTimeRestrictionField.FORMAT);
|
||||||
|
return date == null ? null : dateFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given string into a corresponding date. The string must
|
||||||
|
* follow the standard format used by date fields, as defined by FORMAT
|
||||||
|
* and as would be produced by format().
|
||||||
|
*
|
||||||
|
* @param dateString
|
||||||
|
* The date string to parse, which may be null.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The date corresponding to the given date string, or null if the
|
||||||
|
* provided date string was null or blank.
|
||||||
|
*
|
||||||
|
* @throws ParseException
|
||||||
|
* If the given date string does not conform to the standard format
|
||||||
|
* used by date fields.
|
||||||
|
*/
|
||||||
|
public static Date parse(String dateString)
|
||||||
|
throws ParseException {
|
||||||
|
|
||||||
|
// Return null if no date provided
|
||||||
|
if (dateString == null || dateString.isEmpty())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Parse date according to format
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat(DateTimeRestrictionField.FORMAT);
|
||||||
|
return dateFormat.parse(dateString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -23,6 +23,7 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.guacamole.auth.restrict.Restrictable;
|
||||||
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.HostRestrictionField;
|
||||||
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
import org.apache.guacamole.auth.restrict.form.TimeRestrictionField;
|
||||||
import org.apache.guacamole.form.Form;
|
import org.apache.guacamole.form.Form;
|
||||||
@@ -33,48 +34,7 @@ import org.apache.guacamole.net.auth.UserGroup;
|
|||||||
* UserGroup implementation which wraps a UserGroup from another extension and
|
* UserGroup implementation which wraps a UserGroup from another extension and
|
||||||
* enforces additional restrictions for members of that group.
|
* enforces additional restrictions for members of that group.
|
||||||
*/
|
*/
|
||||||
public class RestrictedUserGroup extends DelegatingUserGroup {
|
public class RestrictedUserGroup extends DelegatingUserGroup implements Restrictable {
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that members of a group are allowed to log in. The presence of this
|
|
||||||
* attribute will restrict any users who are members of the group to logins
|
|
||||||
* only during the times that are contained within the attribute,
|
|
||||||
* subject to further restriction by the guac-restrict-time-denied attribute.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-time-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of weekdays and times (UTC)
|
|
||||||
* that members of a group are not allowed to log in. Denied times will
|
|
||||||
* always take precedence over allowed times. The presence of this attribute
|
|
||||||
* without guac-restrict-time-allowed will deny logins only during the times
|
|
||||||
* listed in this attribute, allowing logins at all other times. The
|
|
||||||
* presence of this attribute along with the guac-restrict-time-allowed
|
|
||||||
* attribute will deny logins at any times that overlap with the allowed
|
|
||||||
* times.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_TIME_DENIED_ATTRIBUTE_NAME = "guac-restrict-time-denied";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of IP addresses from which
|
|
||||||
* members of a group are allowed to log in. The presence of this attribute
|
|
||||||
* will restrict users to only the list of IP addresses contained in the
|
|
||||||
* attribute, subject to further restriction by the
|
|
||||||
* guac-restrict-hosts-denied attribute.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_ALLOWED_ATTRIBUTE_NAME = "guac-restrict-hosts-allowed";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the attribute that contains a list of IP addresses from which
|
|
||||||
* members of a group are not allowed to log in. The presence of this
|
|
||||||
* attribute, absent the guac-restrict-hosts-allowed attribute, will allow
|
|
||||||
* logins from all hosts except the ones listed in this attribute. The
|
|
||||||
* presence of this attribute coupled with the guac-restrict-hosts-allowed
|
|
||||||
* attribute will block access from any IPs in this list, overriding any
|
|
||||||
* that may be allowed.
|
|
||||||
*/
|
|
||||||
public static final String RESTRICT_HOSTS_DENIED_ATTRIBUTE_NAME = "guac-restrict-hosts-denied";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of all user attributes provided by this UserGroup implementation.
|
* The list of all user attributes provided by this UserGroup implementation.
|
||||||
|
@@ -37,4 +37,11 @@ angular.module('guacRestrict').config(['formServiceProvider',
|
|||||||
templateUrl : 'app/ext/restrict/templates/hostRestrictionField.html'
|
templateUrl : 'app/ext/restrict/templates/hostRestrictionField.html'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Define the date and time restriction field
|
||||||
|
formServiceProvider.registerFieldType('GUAC_DATETIME_RESTRICTION', {
|
||||||
|
module : 'guacRestrict',
|
||||||
|
controller : 'dateTimeRestrictionFieldController',
|
||||||
|
templateUrl : 'app/ext/restrict/templates/dateTimeRestrictionField.html'
|
||||||
|
});
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for date+time restriction fields.
|
||||||
|
*/
|
||||||
|
angular.module('form').controller('dateTimeRestrictionFieldController',
|
||||||
|
['$scope', '$injector',
|
||||||
|
function dateTimeRestrictionFieldController($scope, $injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
var $filter = $injector.get('$filter');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options which dictate the behavior of the input field model, as defined
|
||||||
|
* by https://docs.angularjs.org/api/ng/directive/ngModelOptions
|
||||||
|
*
|
||||||
|
* @type Object.<String, String>
|
||||||
|
*/
|
||||||
|
$scope.modelOptions = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Space-delimited list of events on which the model will be updated.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
updateOn : 'blur',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time zone to use when reading/writing the Date object of the
|
||||||
|
* model.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
timezone : 'UTC'
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the date and time components of the given string into a Date in
|
||||||
|
* the UTC timezone. The input string must be in the format
|
||||||
|
* YYYY-MM-DDTHH:mm:ss (zero-padded).
|
||||||
|
*
|
||||||
|
* @param {String} str
|
||||||
|
* The date+time string to parse.
|
||||||
|
*
|
||||||
|
* @returns {Date}
|
||||||
|
* A Date object, in the UTC timezone, or null if parsing the provided
|
||||||
|
* string fails.
|
||||||
|
*/
|
||||||
|
var parseDate = function parseDate(str) {
|
||||||
|
|
||||||
|
// Parse date, return null if parsing fails
|
||||||
|
var parsedDate = new Date(str);
|
||||||
|
if (isNaN(parsedDate.getTime()))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return parsedDate;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update typed value when model is changed
|
||||||
|
$scope.$watch('model', function modelChanged(model) {
|
||||||
|
$scope.typedValue = (model ? parseDate(model) : null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update string value in model when typed value is changed
|
||||||
|
$scope.$watch('typedValue', function typedValueChanged(typedValue) {
|
||||||
|
$scope.model = (typedValue ? $filter('date')(typedValue, 'yyyy-MM-ddTHH:mm:ssZ', 'UTC') : '');
|
||||||
|
});
|
||||||
|
|
||||||
|
}]);
|
@@ -22,8 +22,9 @@
|
|||||||
],
|
],
|
||||||
|
|
||||||
"resources" : {
|
"resources" : {
|
||||||
"templates/hostRestrictionField.html" : "text/html",
|
"templates/dateTimeRestrictionField.html" : "text/html",
|
||||||
"templates/timeRestrictionField.html" : "text/html"
|
"templates/hostRestrictionField.html" : "text/html",
|
||||||
|
"templates/timeRestrictionField.html" : "text/html"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="date-time-restriction-field">
|
||||||
|
<input type="datetime-local"
|
||||||
|
ng-disabled="disabled"
|
||||||
|
ng-attr-id="{{ fieldId }}"
|
||||||
|
ng-attr-name="{{ field.name }}"
|
||||||
|
ng-model="typedValue"
|
||||||
|
ng-model-options="modelOptions"
|
||||||
|
guac-focus="focused"
|
||||||
|
placeholder="{{'RESTRICT.FIELD_PLACEHOLDER_DATE_TIME_RESTRICTION' | translate}}"
|
||||||
|
autocorrect="off"
|
||||||
|
autocapitalize="off">
|
||||||
|
</div>
|
@@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_ALLOWED" : "Hosts from which connection may be accessed:",
|
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_ALLOWED" : "Hosts from which connection may be accessed:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_DENIED" : "Hosts from which connection may not be accessed:",
|
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_DENIED" : "Hosts from which connection may not be accessed:",
|
||||||
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_AFTER" : "Date and time after which this connection may be used:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_TIME_ALLOWED" : "Times connection is allowed to be used:",
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_ALLOWED" : "Times connection is allowed to be used:",
|
||||||
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_BEFORE" : "Date and time before which this connection may be used:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_TIME_DENIED" : "Times connection may not be used:",
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_DENIED" : "Times connection may not be used:",
|
||||||
|
|
||||||
"SECTION_HEADER_RESTRICT_LOGIN_FORM" : "Additional Connection Restrictions"
|
"SECTION_HEADER_RESTRICT_LOGIN_FORM" : "Additional Connection Restrictions"
|
||||||
@@ -19,7 +21,9 @@
|
|||||||
|
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_ALLOWED" : "Hosts from which connection group may be accessed:",
|
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_ALLOWED" : "Hosts from which connection group may be accessed:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_DENIED" : "Hosts from which connection group may not be accessed:",
|
"FIELD_HEADER_GUAC_RESTRICT_HOSTS_DENIED" : "Hosts from which connection group may not be accessed:",
|
||||||
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_AFTER" : "Date and time after which this connection group may be used:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_TIME_ALLOWED" : "Times connection group is allowed to be used:",
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_ALLOWED" : "Times connection group is allowed to be used:",
|
||||||
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_BEFORE" : "Date and time before which this connection group may be used:",
|
||||||
"FIELD_HEADER_GUAC_RESTRICT_TIME_DENIED" : "Times connection group may not be used:",
|
"FIELD_HEADER_GUAC_RESTRICT_TIME_DENIED" : "Times connection group may not be used:",
|
||||||
|
|
||||||
"SECTION_HEADER_RESTRICT_LOGIN_FORM" : "Additional Connection Restrictions"
|
"SECTION_HEADER_RESTRICT_LOGIN_FORM" : "Additional Connection Restrictions"
|
||||||
@@ -35,6 +39,8 @@
|
|||||||
"ERROR_USER_LOGIN_NOT_ALLOWED_NOW" : "The login for this user is not allowed at this time.",
|
"ERROR_USER_LOGIN_NOT_ALLOWED_NOW" : "The login for this user is not allowed at this time.",
|
||||||
"ERROR_USER_LOGIN_NOT_ALLOWED_FROM_HOST" : "The login for this user is not allowed from this host.",
|
"ERROR_USER_LOGIN_NOT_ALLOWED_FROM_HOST" : "The login for this user is not allowed from this host.",
|
||||||
|
|
||||||
|
"FIELD_PLACEHOLDER_DATE_TIME_RESTRICTION" : "YYYY-MM-DD HH:MM:SS",
|
||||||
|
|
||||||
"TABLE_HEADER_DAY" : "Day",
|
"TABLE_HEADER_DAY" : "Day",
|
||||||
"TABLE_HEADER_END_TIME" : "End Time",
|
"TABLE_HEADER_END_TIME" : "End Time",
|
||||||
"TABLE_HEADER_HOST" : "Host",
|
"TABLE_HEADER_HOST" : "Host",
|
||||||
|
Reference in New Issue
Block a user