Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package apiaddicts.sonar.openapi.checks.apim.wso2;

import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.regex.Pattern;

public abstract class AbstractPatternWso2ScopesCheck extends AbstractWso2ScopesCheck {

protected final String ruleKey;
protected final String messageKey;
protected final String fieldName;
protected final String defaultPatternValue;

protected Pattern pattern;
private String patternStr;

protected AbstractPatternWso2ScopesCheck(String key, String message, String fieldName, String defaultPatternValue) {
this.ruleKey = key;
this.messageKey = message;
this.fieldName = fieldName;
this.defaultPatternValue = defaultPatternValue;
}

@Override
protected void visitFile(JsonNode root) {
pattern = Pattern.compile(patternStr != null ? patternStr : defaultPatternValue);
}

@Override
protected void visitScope(JsonNode scope) {
JsonNode fieldNode = scope.propertyMap().get(fieldName);
if (fieldNode == null || fieldNode.isNull() || fieldNode.isMissing()) return;

String fieldText = fieldNode.getTokenValue();
boolean notValid = !pattern.matcher(fieldText).matches();

if (notValid) addIssue(ruleKey, translate(messageKey), fieldNode.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package apiaddicts.sonar.openapi.checks.apim.wso2;

import com.google.common.collect.ImmutableSet;
import com.sonar.sslr.api.AstNodeType;
import apiaddicts.sonar.openapi.checks.BaseCheck;
import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar;
import org.apiaddicts.apitools.dosonarapi.api.v3.OpenApi3Grammar;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.Set;

public abstract class AbstractWso2OperationCheck extends BaseCheck {

@Override
public Set<AstNodeType> subscribedKinds() {
return ImmutableSet.of(
OpenApi2Grammar.OPERATION,
OpenApi3Grammar.OPERATION
);
}

@Override
public void visitNode(JsonNode node) {
visitOperationNode(node);
}

protected abstract void visitOperationNode(JsonNode node);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,21 @@

import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.regex.Pattern;

@Rule(key = OAR004ValidWso2ScopesRolesCheck.KEY)
public class OAR004ValidWso2ScopesRolesCheck extends AbstractWso2ScopesCheck {

public static final String KEY = "OAR004";
private static final String DEFAULT_PATTERN_VALUE = "^[a-zA-Z0-9_\\-., ]+$";
private static final String MESSAGE = "OAR004.error";

@RuleProperty(
key = "pattern",
description = "Regular expression used to check the 'roles' field against.",
defaultValue = DEFAULT_PATTERN_VALUE)
public String patternStr = DEFAULT_PATTERN_VALUE;

private Pattern pattern;

@Override
protected void visitFile(JsonNode root) {
pattern = Pattern.compile(patternStr);
}

@Override
protected void visitScope(JsonNode scope) {
JsonNode roles = scope.propertyMap().get("roles");
if (roles == null || roles.isNull() || roles.isMissing()) return;
String rolesText = roles.getTokenValue();
boolean notValid = !pattern.matcher(rolesText).matches();
if (notValid) addIssue(KEY, translate(MESSAGE), roles);
}
}
public class OAR004ValidWso2ScopesRolesCheck extends AbstractPatternWso2ScopesCheck {

public static final String KEY = "OAR004";
private static final String MESSAGE = "OAR004.error";
private static final String DEFAULT_PATTERN_VALUE = "^[a-zA-Z0-9_\\-., ]+$";

@RuleProperty(
key = "pattern",
description = "Regular expression used to check the 'roles' field against.",
defaultValue = DEFAULT_PATTERN_VALUE)
private String patternStr = DEFAULT_PATTERN_VALUE;

public OAR004ValidWso2ScopesRolesCheck() {
super(KEY, MESSAGE, "roles", DEFAULT_PATTERN_VALUE);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package apiaddicts.sonar.openapi.checks.apim.wso2;

import com.google.common.collect.ImmutableSet;
import com.sonar.sslr.api.AstNode;
import com.sonar.sslr.api.AstNodeType;
import org.sonar.check.Rule;
import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar;
import org.apiaddicts.apitools.dosonarapi.api.v3.OpenApi3Grammar;
import apiaddicts.sonar.openapi.checks.BaseCheck;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.Collections;
Expand All @@ -16,47 +11,50 @@
import static java.util.Objects.isNull;

@Rule(key = OAR005UndefinedWso2ScopeUseCheck.KEY)
public class OAR005UndefinedWso2ScopeUseCheck extends BaseCheck {

public static final String KEY = "OAR005";
private static final String MESSAGE = "OAR005.error";

private Set<String> definedScopes;

@Override
protected void visitFile(JsonNode root) {
definedScopes = getScopes(root);
}

private Set<String> getScopes(JsonNode root) {
JsonNode scopes = root.get("x-wso2-security").get("apim").get("x-wso2-scopes");
if (scopes.isMissing() || scopes.isNull()) return Collections.emptySet();
return scopes
.elements()
.stream()
.map(node -> node.get("name"))
.filter(node -> !node.isMissing() && !node.isNull())
.map(AstNode::getTokenValue)
.collect(Collectors.toSet());
}

@Override
public Set<AstNodeType> subscribedKinds() {
return ImmutableSet.of(OpenApi2Grammar.OPERATION, OpenApi3Grammar.OPERATION);
}

@Override
public void visitNode(JsonNode node) {
visitV2Node(node);
}

private void visitV2Node(JsonNode node) {
JsonNode scopeNode = node.get("x-scope");
if (scopeNode.isMissing()) return;
String scope = scopeNode.isNull() ? null : scopeNode.getTokenValue();
if (isNull(scope) || !definedScopes.contains(scope)) {
addIssue(KEY, translate(MESSAGE), scopeNode);
}
}

}
public class OAR005UndefinedWso2ScopeUseCheck
extends AbstractWso2OperationCheck {

public static final String KEY = "OAR005";
private static final String MESSAGE = "OAR005.error";

private Set<String> definedScopes;

@Override
protected void visitFile(JsonNode root) {
definedScopes = getScopes(root);
}

private Set<String> getScopes(JsonNode root) {

JsonNode scopes = root
.get("x-wso2-security")
.get("apim")
.get("x-wso2-scopes");

if (scopes.isMissing() || scopes.isNull()) {
return Collections.emptySet();
}

return scopes.elements().stream()
.map(node -> node.get("name"))
.filter(node -> !node.isMissing() && !node.isNull())
.map(AstNode::getTokenValue)
.collect(Collectors.toSet());
}

@Override
protected void visitOperationNode(JsonNode node) {

JsonNode scopeNode = node.get("x-scope");

if (scopeNode.isMissing()) return;

String scope = scopeNode.isNull()
? null
: scopeNode.getTokenValue();

if (isNull(scope) || !definedScopes.contains(scope)) {
addIssue(KEY, translate(MESSAGE), scopeNode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,21 @@

import org.sonar.check.Rule;
import org.sonar.check.RuleProperty;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.regex.Pattern;

@Rule(key = OAR040StandardWso2ScopesNameCheck.KEY)
public class OAR040StandardWso2ScopesNameCheck extends AbstractWso2ScopesCheck {

public static final String KEY = "OAR040";
private static final String DEFAULT_PATTERN_VALUE = "^[a-zA-Z]{4,}_(SC|sc)_[a-zA-Z0-9]{1,}$";
private static final String MESSAGE = "OAR040.error";

@RuleProperty(
key = "pattern",
description = "Regular expression used to check the 'name' field against.",
defaultValue = DEFAULT_PATTERN_VALUE)
public String patternStr = DEFAULT_PATTERN_VALUE;

private Pattern pattern;

@Override
protected void visitFile(JsonNode root) {
pattern = Pattern.compile(patternStr);
}

@Override
protected void visitScope(JsonNode scope) {
JsonNode name = scope.propertyMap().get("name");
if (name == null || name.isNull() || name.isMissing()) return;
String nameText = name.getTokenValue();
boolean notValid = !pattern.matcher(nameText).matches();
if (notValid) addIssue(KEY, translate(MESSAGE), name.value());
}
}
public class OAR040StandardWso2ScopesNameCheck extends AbstractPatternWso2ScopesCheck {

public static final String KEY = "OAR040";
private static final String MESSAGE = "OAR040.error";
private static final String DEFAULT_PATTERN_VALUE = "^[a-zA-Z]{4,}_(SC|sc)_[a-zA-Z0-9]{1,}$";

@RuleProperty(
key = "pattern",
description = "Regular expression used to check the 'name' field against.",
defaultValue = DEFAULT_PATTERN_VALUE)
private String patternStr = DEFAULT_PATTERN_VALUE;

public OAR040StandardWso2ScopesNameCheck() {
super(KEY, MESSAGE, "name", DEFAULT_PATTERN_VALUE);
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,26 @@
package apiaddicts.sonar.openapi.checks.apim.wso2;

import com.google.common.collect.ImmutableSet;
import com.sonar.sslr.api.AstNodeType;
import org.sonar.check.Rule;
import org.apiaddicts.apitools.dosonarapi.api.v2.OpenApi2Grammar;
import org.apiaddicts.apitools.dosonarapi.api.v3.OpenApi3Grammar;
import apiaddicts.sonar.openapi.checks.BaseCheck;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

import java.util.Set;

@Rule(key = OAR041UndefinedAuthTypeForWso2ScopeCheck.KEY)
public class OAR041UndefinedAuthTypeForWso2ScopeCheck extends BaseCheck {
public class OAR041UndefinedAuthTypeForWso2ScopeCheck
extends AbstractWso2OperationCheck {

public static final String KEY = "OAR041";
private static final String MESSAGE = "OAR041.error";

@Override
public Set<AstNodeType> subscribedKinds() {
return ImmutableSet.of(OpenApi2Grammar.OPERATION, OpenApi3Grammar.OPERATION);
}

@Override
public void visitNode(JsonNode node) {
visitV2Node(node);
}
protected void visitOperationNode(JsonNode node) {

private void visitV2Node(JsonNode node) {
JsonNode scopeNode = node.get("x-scope");

if (scopeNode.isMissing()) return;

JsonNode authTypeNode = node.get("x-auth-type");

if (authTypeNode.isMissing()) {
addIssue(KEY, translate(MESSAGE), scopeNode.key());
}
}
}
}
Loading
Loading