Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.google.common.collect.Lists;
import io.jans.agama.model.EngineConfig;
import io.jans.as.model.common.*;
import io.jans.as.model.configuration.rate.RateLimitConfig;
import io.jans.as.model.crypto.signature.SignatureAlgorithm;
import io.jans.as.model.error.ErrorHandlingMethod;
import io.jans.as.model.jwk.KeySelectionStrategy;
Expand Down Expand Up @@ -746,12 +747,6 @@ public class AppConfiguration implements Configuration {
@DocProperty(description = "Authorization challenge session lifetime in seconds")
private Integer authorizationChallengeSessionLifetimeInSeconds;

@DocProperty(description = "Request count limit - for /register endpoint (Rate Limit)")
private Integer rateLimitRegistrationRequestCount;

@DocProperty(description = "Period in seconds limit - for /register endpoint (Rate Limit)")
private Integer rateLimitRegistrationPeriodInSeconds;

// Token Exchange
@DocProperty(description = "", defaultValue = "false")
private Boolean rotateDeviceSecret = false;
Expand Down Expand Up @@ -970,6 +965,9 @@ public class AppConfiguration implements Configuration {
@DocProperty(description = "DCR SSA Validation configurations used to perform validation of SSA or DCR. Only needed if softwareStatementValidationType=builtin")
private List<SsaValidationConfig> dcrSsaValidationConfigs;

@DocProperty(description = "Rate Limit Configuration")
private RateLimitConfig rateLimitConfiguration;

@DocProperty(description = "SSA Configuration")
private SsaConfiguration ssaConfiguration;

Expand Down Expand Up @@ -1115,24 +1113,6 @@ public void setReturnDeviceSecretFromAuthzEndpoint(Boolean returnDeviceSecretFro
this.returnDeviceSecretFromAuthzEndpoint = returnDeviceSecretFromAuthzEndpoint;
}

public Integer getRateLimitRegistrationRequestCount() {
return rateLimitRegistrationRequestCount;
}

public AppConfiguration setRateLimitRegistrationRequestCount(Integer rateLimitRegistrationRequestCount) {
this.rateLimitRegistrationRequestCount = rateLimitRegistrationRequestCount;
return this;
}

public Integer getRateLimitRegistrationPeriodInSeconds() {
return rateLimitRegistrationPeriodInSeconds;
}

public AppConfiguration setRateLimitRegistrationPeriodInSeconds(Integer rateLimitRegistrationPeriodInSeconds) {
this.rateLimitRegistrationPeriodInSeconds = rateLimitRegistrationPeriodInSeconds;
return this;
}

public Integer getAuthorizationChallengeSessionLifetimeInSeconds() {
if (authorizationChallengeSessionLifetimeInSeconds == null) {
authorizationChallengeSessionLifetimeInSeconds = DEFAULT_AUTHORIZATION_CHALLENGE_SESSION_LIFETIME;
Expand Down Expand Up @@ -3803,6 +3783,14 @@ public void setSsaConfiguration(SsaConfiguration ssaConfiguration) {
this.ssaConfiguration = ssaConfiguration;
}

public RateLimitConfig getRateLimitConfiguration() {
return rateLimitConfiguration;
}

public void setRateLimitConfiguration(RateLimitConfig rateLimitConfiguration) {
this.rateLimitConfiguration = rateLimitConfiguration;
}

public Boolean getAuthorizationChallengeShouldGenerateSession() {
if (authorizationChallengeShouldGenerateSession == null) authorizationChallengeShouldGenerateSession = false;
return authorizationChallengeShouldGenerateSession;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package io.jans.as.model.configuration.rate;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class KeyExtractor {

private KeySource source;
private List<String> parameterNames = new ArrayList<>();

public KeyExtractor() {
}

@JsonCreator
public KeyExtractor(@JsonProperty("source") KeySource source, @JsonProperty("parameterNames") List<String> parameterNames) {
setSource(source);
setParameterNames(parameterNames);
}

@JsonProperty("source")
public KeySource getSource() {
return source;
}

@JsonProperty("source")
public void setSource(KeySource source) {
this.source = source;
}

@JsonProperty("parameterNames")
public List<String> getParameterNames() {
return parameterNames == null ? Collections.emptyList() : Collections.unmodifiableList(parameterNames);
}

@JsonProperty("parameterNames")
public void setParameterNames(List<String> parameterNames) {
// Defensive copy + filter null/blank
List<String> safe = new ArrayList<>();
if (parameterNames != null) {
for (String p : parameterNames) {
if (p == null) continue;
String v = p.trim();
if (!v.isEmpty()) safe.add(v);
}
}
this.parameterNames = safe;
}

public boolean isWellFormed() {
return source != null && !getParameterNames().isEmpty();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof KeyExtractor)) return false;
KeyExtractor that = (KeyExtractor) o;
return source == that.source && Objects.equals(getParameterNames(), that.getParameterNames());
}

@Override
public int hashCode() {
return Objects.hash(source, getParameterNames());
}

@Override
public String toString() {
return "KeyExtractor{" +
"source=" + source +
", parameterNames=" + getParameterNames() +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.jans.as.model.configuration.rate;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

/**
* Where to extract the key from.
* <p>
* Defensive behavior:
* - Unknown values deserialize to {@link #UNKNOWN} instead of failing.
* - Serialization uses the json value (lower-case).
*/
public enum KeySource {
BODY("body"),
HEADER("header"),
QUERY("query"),
UNKNOWN("unknown");

private final String jsonValue;

KeySource(String jsonValue) {
this.jsonValue = jsonValue;
}

@JsonCreator
public static KeySource fromJson(String value) {
if (value == null) return null; // preserve null if field absent
String v = value.trim();
if (v.isEmpty()) return null;

for (KeySource s : values()) {
if (s.jsonValue.equalsIgnoreCase(v)) {
return s;
}
}
// Defensive: don't hard-fail on new/typo values
return UNKNOWN;
}

@JsonValue
public String toJson() {
return jsonValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.jans.as.model.configuration.rate;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RateLimitConfig {

private List<RateLimitRule> rateLimitRules = new ArrayList<>();
private boolean rateLoggingEnabled = false;

public RateLimitConfig() {
}

@JsonCreator
public RateLimitConfig(@JsonProperty("rateLimitRules") List<RateLimitRule> rateLimitRules) {
setRateLimitRules(rateLimitRules);
}

@JsonProperty("rateLoggingEnabled")
public boolean isRateLoggingEnabled() {
return rateLoggingEnabled;
}

@JsonProperty("rateLoggingEnabled")
public void setRateLoggingEnabled(boolean rateLoggingEnabled) {
this.rateLoggingEnabled = rateLoggingEnabled;
}

@JsonProperty("rateLimitRules")
public List<RateLimitRule> getRateLimitRules() {
return rateLimitRules == null ? Collections.emptyList() : Collections.unmodifiableList(rateLimitRules);
}

@JsonProperty("rateLimitRules")
public void setRateLimitRules(List<RateLimitRule> rateLimitRules) {
this.rateLimitRules = (rateLimitRules == null) ? new ArrayList<>() : new ArrayList<>(rateLimitRules);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RateLimitConfig)) return false;
RateLimitConfig that = (RateLimitConfig) o;
return Objects.equals(getRateLimitRules(), that.getRateLimitRules());
}

@Override
public int hashCode() {
return Objects.hash(getRateLimitRules());
}

@Override
public String toString() {
return "RateLimitConfig{" +
"rateLimitRules=" + getRateLimitRules() +
"rateLoggingEnabled=" + rateLoggingEnabled +
'}';
}
}
Loading
Loading