package org.apereo.cas.services;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apereo.cas.util.DateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
/**
* The {@link TimeBasedRegisteredServiceAccessStrategy} is responsible for
* enforcing CAS authorization strategy based on a configured start/end time.
*
* @author Misagh Moayyed
* @since 4.2
*/
public class TimeBasedRegisteredServiceAccessStrategy extends DefaultRegisteredServiceAccessStrategy {
private static final long serialVersionUID = -6180748828025837047L;
private static final Logger LOGGER = LoggerFactory.getLogger(TimeBasedRegisteredServiceAccessStrategy.class);
private String startingDateTime;
private String endingDateTime;
/**
* Initiates the time-based access strategy.
*/
public TimeBasedRegisteredServiceAccessStrategy() {
}
/**
* Initiates the time-based access strategy.
*
* @param enabled is service access allowed?
* @param ssoEnabled is service allowed to take part in SSO?
*/
public TimeBasedRegisteredServiceAccessStrategy(final boolean enabled, final boolean ssoEnabled) {
super(enabled, ssoEnabled);
}
public String getStartingDateTime() {
return this.startingDateTime;
}
public String getEndingDateTime() {
return this.endingDateTime;
}
public void setStartingDateTime(final String startingDateTime) {
this.startingDateTime = startingDateTime;
}
public void setEndingDateTime(final String endingDateTime) {
this.endingDateTime = endingDateTime;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
final TimeBasedRegisteredServiceAccessStrategy rhs = (TimeBasedRegisteredServiceAccessStrategy) obj;
return new EqualsBuilder()
.appendSuper(super.equals(obj))
.append(this.startingDateTime, rhs.startingDateTime)
.append(this.endingDateTime, rhs.endingDateTime)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.appendSuper(super.hashCode())
.append(this.startingDateTime)
.append(this.endingDateTime)
.toHashCode();
}
@Override
public String toString() {
return new ToStringBuilder(this)
.appendSuper(super.toString())
.append("startingDateTime", this.startingDateTime)
.append("endingDateTime", this.endingDateTime)
.toString();
}
@Override
public boolean isServiceAccessAllowed() {
if (!doesStartingTimeAllowServiceAccess()) {
return false;
}
if (!doesEndingTimeAllowServiceAccess()) {
return false;
}
return super.isServiceAccessAllowed();
}
/**
* Does ending time allow service access boolean.
*
* @return true/false
*/
protected boolean doesEndingTimeAllowServiceAccess() {
if (this.endingDateTime != null) {
final ZonedDateTime et = DateTimeUtils.zonedDateTimeOf(this.endingDateTime);
if (et != null) {
if (ZonedDateTime.now().isAfter(et)) {
LOGGER.warn("Service access not allowed because it ended at [{}]. Now is [{}]", this.endingDateTime, ZonedDateTime.now());
return false;
}
} else {
final LocalDateTime etLocal = DateTimeUtils.localDateTimeOf(this.endingDateTime);
if (etLocal != null) {
if (LocalDateTime.now().isAfter(etLocal)) {
LOGGER.warn("Service access not allowed because it ended at [{}]. Now is [{}]", this.endingDateTime, LocalDateTime.now());
return false;
}
}
}
}
return true;
}
/**
* Does starting time allow service access boolean.
*
* @return true/false
*/
protected boolean doesStartingTimeAllowServiceAccess() {
if (this.startingDateTime != null) {
final ZonedDateTime st = DateTimeUtils.zonedDateTimeOf(this.startingDateTime);
if (st != null) {
if (ZonedDateTime.now().isBefore(st)) {
LOGGER.warn("Service access not allowed because it starts at [{}]. Zoned now is [{}]", this.startingDateTime, ZonedDateTime.now());
return false;
}
} else {
final LocalDateTime stLocal = DateTimeUtils.localDateTimeOf(this.startingDateTime);
if (stLocal != null) {
if (LocalDateTime.now().isBefore(stLocal)) {
LOGGER.warn("Service access not allowed because it starts at [{}]. Local now is [{}]", this.startingDateTime, ZonedDateTime.now());
return false;
}
}
}
}
return true;
}
}